From 759764d13aa4dade845367dc891fae7063f9c966 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Sat, 2 Dec 2023 12:23:06 +0100 Subject: [PATCH 01/44] First commit --- README.md | 230 +----------------------------------------------------- 1 file changed, 1 insertion(+), 229 deletions(-) diff --git a/README.md b/README.md index 80e9454d..f7f80858 100644 --- a/README.md +++ b/README.md @@ -1,229 +1 @@ -<p align="center"> - <a href="https://coreui.io/"> - <img - src="https://coreui.io/images/brand/coreui-signet.svg" - alt="CoreUI logo" - width="200" - /> - </a> -</p> - -<h3 align="center">CoreUI for React.js</h3> - -<p align="center"> - React.js Components Library built on top of Bootstrap 5 and TypeScript. - <br> - <a href="https://coreui.io/react/docs/getting-started/introduction"><strong>Explore CoreUI for React.js docs »</strong></a> - <br> - <br> - <a href="https://github.com/coreui/coreui-react/issues/new?template=bug_report.md">Report bug</a> - · - <a href="https://github.com/coreui/coreui-react/issues/new?template=feature_request.md">Request feature</a> - · - <a href="https://coreui.io/blog/">Blog</a> -</p> - - -## Table of contents - -- [Quick start](#quick-start) -- [Components](#components) -- [Status](#status) -- [Bugs and feature requests](#bugs-and-feature-requests) -- [Documentation](#documentation) -- [Frameworks](#frameworks) -- [Templates](#templates) -- [Contributing](#contributing) -- [Community](#community) -- [Versioning](#versioning) -- [Creators](#creators) -- [Support CoreUI Development](#support-coreui-development) -- [Copyright and license](#copyright-and-license) - -## Quick start - -### Instalation - -Several quick start options are available: - -- [Download the latest release](https://github.com/coreui/coreui-react/archive/v5.0.0-rc.0.zip) -- Clone the repo: `git clone https://github.com/coreui/coreui-react.git` -- Install with [npm](https://www.npmjs.com/): `npm install @coreui/react` -- Install with [yarn](https://yarnpkg.com/): `yarn add @coreui/react` - -Read the [Getting started page](https://coreui.io/react/docs/getting-started/introduction/) for information on the framework contents, templates and examples, and more. - -### Stylesheets - -React components are styled using `@coreui/coreui` CSS library, but you can use them also with bootstrap CSS library. That is possible because `@coreui/coreui` library is compatible with bootstrap, it just extends its functionalities. The only exception are custom CoreUI components, which don't exist in the Bootstrap ecosystem. - -#### CoreUI CSS files - -##### Installation - -```bash -yarn add @coreui/coreui -``` - -or - -```bash -npm install @coreui/coreui --save -``` - -##### Basic usage - -```js -import '@coreui/coreui/dist/css/coreui.min.css' -``` - -#### Bootstrap CSS files - -##### Installation - -```bash -yarn add bootstrap -``` - -or - -```bash -npm install bootstrap -``` - -##### Basic usage - -```js -import "bootstrap/dist/css/bootstrap.min.css"; -``` - -## Components - -- [React Accordion](https://coreui.io/react/docs/components/accordion/) -- [React Alert](https://coreui.io/react/docs/components/alert/) -- [React Avatar](https://coreui.io/react/docs/components/avatar/) -- [React Badge](https://coreui.io/react/docs/components/badge/) -- [React Breadcrumb](https://coreui.io/react/docs/components/breadcrumb/) -- [React Button](https://coreui.io/react/docs/components/button/) -- [React Button Group](https://coreui.io/react/docs/components/button-group/) -- [React Callout](https://coreui.io/react/docs/components/callout/) -- [React Card](https://coreui.io/react/docs/components/card/) -- [React Carousel](https://coreui.io/react/docs/components/carousel/) -- [React Checkbox](https://coreui.io/react/docs/forms/checkbox/) -- [React Close Button](https://coreui.io/react/docs/components/close-button/) -- [React Collapse](https://coreui.io/react/docs/components/collapse/) -- [React Date Picker](https://coreui.io/react/docs/forms/date-picker/) **PRO** -- [React Date Range Picker](https://coreui.io/react/docs/forms/date-range-picker/) **PRO** -- [React Dropdown](https://coreui.io/react/docs/components/dropdown/) -- [React Floating Labels](https://coreui.io/react/docs/forms/floating-labels/) -- [React Footer](https://coreui.io/react/docs/components/footer/) -- [React Header](https://coreui.io/react/docs/components/header/) -- [React Image](https://coreui.io/react/docs/components/image/) -- [React Input](https://coreui.io/react/docs/forms/input/) -- [React Input Group](https://coreui.io/react/docs/forms/input-group/) -- [React List Group](https://coreui.io/react/docs/components/list-group/) -- [React Loading Button](https://coreui.io/react/docs/components/loading-button/) **PRO** -- [React Modal](https://coreui.io/react/docs/components/modal/) -- [React Multi Select](https://coreui.io/react/docs/forms/multi-select/) **PRO** -- [React Navs & Tabs](https://coreui.io/react/docs/components/navs-tabs/) -- [React Navbar](https://coreui.io/react/docs/components/navbar/) -- [React Offcanvas](https://coreui.io/react/docs/components/offcanvas/) -- [React Pagination](https://coreui.io/react/docs/components/pagination/) -- [React Placeholder](https://coreui.io/react/docs/components/placeholder/) -- [React Popover](https://coreui.io/react/docs/components/popover/) -- [React Progress](https://coreui.io/react/docs/components/progress/) -- [React Radio](https://coreui.io/react/docs/forms/radio/) -- [React Range](https://coreui.io/react/docs/forms/range/) -- [React Select](https://coreui.io/react/docs/forms/select/) -- [React Sidebar](https://coreui.io/react/docs/components/sidebar/) -- [React Smart Pagination](https://coreui.io/react/docs/components/smart-pagination/) **PRO** -- [React Smart Table](https://coreui.io/react/docs/components/smart-table/) **PRO** -- [React Spinner](https://coreui.io/react/docs/components/spinner/) -- [React Switch](https://coreui.io/react/docs/forms/switch/) -- [React Table](https://coreui.io/react/docs/components/table/) -- [React Textarea](https://coreui.io/react/docs/forms/textarea/) -- [React Time Picker](https://coreui.io/react/docs/forms/time-picker/) **PRO** -- [React Toast](https://coreui.io/react/docs/components/toast/) -- [React Tooltip](https://coreui.io/react/docs/components/tooltip/) - -## Status - -[](https://www.npmjs.com/package/@coreui/react) - -## Bugs and feature requests - -Have a bug or a feature request? Please first read the [issue guidelines](https://github.com/coreui/coreui-react/blob/v4/.github/CONTRIBUTING.md#using-the-issue-tracker) and search for existing and closed issues. If your problem or idea is not addressed yet, [please open a new issue](https://github.com/coreui/coreui-react/issues/new). - -## Documentation - -The documentation for the CoreUI & CoreUI PRO is hosted at our website [CoreUI for React](https://coreui.io/react/docs/getting-started/introduction) - -### Running documentation locally - -1. Run `yarn install` or `npm install` to install the Node.js dependencies. -2. Run `yarn bootstrap` or `npm run bootstrap` to link local packages together and install remaining package dependencies. -3. From the root directory, run `yarn docs:dev` or `npm run docs:dev` (or a specific npm script) to rebuild distributed CSS and JavaScript files, as well as our docs assets. -4. Open `http://localhost:8000/` in your browser, and voilà. - -## Frameworks - -CoreUI supports most popular frameworks. - -- [CoreUI for Angular](https://github.com/coreui/coreui-angular) -- [CoreUI for Bootstrap (Vanilla JS)](https://github.com/coreui/coreui) -- [CoreUI for React](https://github.com/coreui/coreui-react) -- [CoreUI for Vue](https://github.com/coreui/coreui-vue) - -## Templates - -Fully featured, out-of-the-box, templates for your application based on CoreUI. - -- [Angular Admin Template](https://coreui.io/angular) -- [Bootstrap Admin Template](https://coreui.io/) -- [React Admin Template](https://coreui.io/react) -- [Vue Admin Template](https://coreui.io/vue) - -## Contributing - -Please read through our [contributing guidelines](https://github.com/coreui/coreui-react/blob/v4/.github/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development. - -Editor preferences are available in the [editor config](https://github.com/coreui/coreui-react/blob/v4/.editorconfig) for easy use in common text editors. Read more and download plugins at <https://editorconfig.org/>. - -## Community - -Stay up to date on the development of CoreUI and reach out to the community with these helpful resources. - -- Read and subscribe to [The Official CoreUI Blog](https://coreui.io/blog/). - -You can also follow [@core_ui on Twitter](https://twitter.com/core_ui). - -## Versioning - -For transparency into our release cycle and in striving to maintain backward compatibility, CoreUI is maintained under [the Semantic Versioning guidelines](http://semver.org/). - -See [the Releases section of our project](https://github.com/coreui/coreui-react/releases) for changelogs for each release version. - -## Creators - -**Łukasz Holeczek** - -* <https://twitter.com/lukaszholeczek> -* <https://github.com/mrholek> - -**Andrzej Kopański** - -* <https://github.com/xidedix> - -**CoreUI Team** - -* <https://twitter.com/core_ui> -* <https://github.com/coreui> -* <https://github.com/orgs/coreui/people> - -## Support CoreUI Development - -CoreUI is an MIT-licensed open source project and is completely free to use. However, the amount of effort needed to maintain and develop new features for the project is not sustainable without proper financial backing. You can support development by buying the [CoreUI PRO](https://coreui.io/pricing/?framework=react&src=github-coreui-react) or by becoming a sponsor via [Open Collective](https://opencollective.com/coreui/). - -## Copyright and license - -Copyright 2023 creativeLabs Łukasz Holeczek. Code released under the [MIT License](https://github.com/coreui/coreui-react/blob/main/LICENSE). Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/). \ No newline at end of file +# Portico UI \ No newline at end of file From 35e53eaedd36fafa6c28268dd5c93f9cb21be973 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Sat, 2 Dec 2023 14:31:30 +0100 Subject: [PATCH 02/44] New dashboard --- LICENSE | 12 +- .../jest.config.js => jest.config.js | 9 +- jsconfig.json | 6 + lerna.json | 6 - migration.md | 3 + package.json | 100 +- packages/coreui-icons-react | 1 - packages/coreui-react-chartjs | 1 - packages/coreui-react/LICENSE | 21 - packages/coreui-react/README.md | 261 --- packages/coreui-react/package.json | 74 - packages/coreui-react/rollup.config.mjs | 49 - .../src/components/accordion/CAccordion.tsx | 58 - .../components/accordion/CAccordionBody.tsx | 35 - .../components/accordion/CAccordionButton.tsx | 38 - .../components/accordion/CAccordionHeader.tsx | 29 - .../components/accordion/CAccordionItem.tsx | 64 - .../accordion/__tests__/CAccordion.spec.tsx | 36 - .../__tests__/CAccordionBody.spec.tsx | 15 - .../__tests__/CAccordionButton.spec.tsx | 16 - .../__tests__/CAccordionHeader.spec.tsx | 16 - .../__tests__/CAccordionItem.spec.tsx | 16 - .../__snapshots__/CAccordion.spec.tsx.snap | 21 - .../CAccordionBody.spec.tsx.snap | 29 - .../CAccordionButton.spec.tsx.snap | 25 - .../CAccordionHeader.spec.tsx.snap | 33 - .../CAccordionItem.spec.tsx.snap | 21 - .../src/components/accordion/index.ts | 7 - .../src/components/alert/CAlert.tsx | 106 - .../src/components/alert/CAlertHeading.tsx | 32 - .../src/components/alert/CAlertLink.tsx | 29 - .../alert/__tests__/CAlert.spec.tsx | 41 - .../alert/__tests__/CAlertHeading.spec.tsx | 20 - .../alert/__tests__/CAlertLink.spec.tsx | 20 - .../__snapshots__/CAlert.spec.tsx.snap | 28 - .../__snapshots__/CAlertHeading.spec.tsx.snap | 21 - .../__snapshots__/CAlertLink.spec.tsx.snap | 22 - .../src/components/alert/index.ts | 5 - .../src/components/avatar/CAvatar.tsx | 84 - .../avatar/__tests__/CAvatar.spec.tsx | 54 - .../__snapshots__/CAvatar.spec.tsx.snap | 40 - .../src/components/avatar/index.ts | 3 - .../src/components/backdrop/CBackdrop.tsx | 45 - .../backdrop/__tests__/CBackdrop.spec.tsx | 31 - .../__snapshots__/CBackdrop.spec.tsx.snap | 23 - .../src/components/backdrop/index.ts | 3 - .../src/components/badge/CBadge.tsx | 96 - .../badge/__tests__/CBadge.spec.tsx | 22 - .../__snapshots__/CBadge.spec.tsx.snap | 21 - .../src/components/badge/index.ts | 3 - .../src/components/breadcrumb/CBreadcrumb.tsx | 29 - .../components/breadcrumb/CBreadcrumbItem.tsx | 50 - .../breadcrumb/__tests__/CBreadcrumb.spec.tsx | 22 - .../__tests__/CBreadcrumbItem.spec.tsx | 21 - .../__snapshots__/CBreadcrumb.spec.tsx.snap | 42 - .../CBreadcrumbItem.spec.tsx.snap | 22 - .../src/components/breadcrumb/index.ts | 4 - .../components/button-group/CButtonGroup.tsx | 45 - .../button-group/CButtonToolbar.tsx | 27 - .../__tests__/CButtonGroup.spec.tsx | 37 - .../__tests__/CButtonToolbar.spec.tsx | 29 - .../__snapshots__/CButtonGroup.spec.tsx.snap | 63 - .../CButtonToolbar.spec.tsx.snap | 66 - .../src/components/button-group/index.ts | 4 - .../src/components/button/CButton.tsx | 108 - .../button/__tests__/CButton.spec.tsx | 44 - .../button/__tests__/CButtonClose.spec.tsx | 23 - .../__snapshots__/CButton.spec.tsx.snap | 37 - .../__snapshots__/CButtonClose.spec.tsx.snap | 26 - .../src/components/button/index.ts | 3 - .../src/components/callout/CCallout.tsx | 47 - .../callout/__tests__/CCallout.spec.tsx | 21 - .../__snapshots__/CCallout.spec.tsx.snap | 21 - .../src/components/callout/index.ts | 3 - .../src/components/card/CCard.tsx | 55 - .../src/components/card/CCardBody.tsx | 27 - .../src/components/card/CCardFooter.tsx | 27 - .../src/components/card/CCardGroup.tsx | 27 - .../src/components/card/CCardHeader.tsx | 32 - .../src/components/card/CCardImage.tsx | 43 - .../src/components/card/CCardImageOverlay.tsx | 27 - .../src/components/card/CCardLink.tsx | 33 - .../src/components/card/CCardSubtitle.tsx | 31 - .../src/components/card/CCardText.tsx | 32 - .../src/components/card/CCardTitle.tsx | 32 - .../components/card/__tests__/CCard.spec.tsx | 22 - .../card/__tests__/CCardBody.spec.tsx | 16 - .../card/__tests__/CCardFooter.spec.tsx | 16 - .../card/__tests__/CCardGroup.spec.tsx | 51 - .../card/__tests__/CCardHeader.spec.tsx | 20 - .../card/__tests__/CCardImage.spec.tsx | 18 - .../card/__tests__/CCardImageOverlay.spec.tsx | 17 - .../card/__tests__/CCardLink.spec.tsx | 20 - .../card/__tests__/CCardSubtitle.spec.tsx | 20 - .../card/__tests__/CCardText.spec.tsx | 20 - .../card/__tests__/CCardTitle.spec.tsx | 20 - .../__snapshots__/CCard.spec.tsx.snap | 21 - .../__snapshots__/CCardBody.spec.tsx.snap | 21 - .../__snapshots__/CCardFooter.spec.tsx.snap | 21 - .../__snapshots__/CCardGroup.spec.tsx.snap | 86 - .../__snapshots__/CCardHeader.spec.tsx.snap | 21 - .../__snapshots__/CCardImage.spec.tsx.snap | 17 - .../CCardImageOverlay.spec.tsx.snap | 19 - .../__snapshots__/CCardLink.spec.tsx.snap | 22 - .../__snapshots__/CCardSubtitle.spec.tsx.snap | 21 - .../__snapshots__/CCardText.spec.tsx.snap | 21 - .../__snapshots__/CCardTitle.spec.tsx.snap | 21 - .../coreui-react/src/components/card/index.ts | 25 - .../src/components/carousel/CCarousel.tsx | 310 --- .../components/carousel/CCarouselCaption.tsx | 22 - .../src/components/carousel/CCarouselItem.tsx | 123 -- .../carousel/__tests__/CCarousel.spec.tsx | 149 -- .../__snapshots__/CCarousel.spec.tsx.snap | 80 - .../src/components/carousel/index.ts | 5 - .../components/close-button/CCloseButton.tsx | 57 - .../__tests__/CCloseButton.spec.tsx | 24 - .../__snapshots__/CCloseButton.spec.tsx.snap | 22 - .../src/components/close-button/index.ts | 3 - .../src/components/collapse/CCollapse.tsx | 126 -- .../collapse/__tests__/CCollapse.spec.tsx | 40 - .../__snapshots__/CCollapse.spec.tsx.snap | 21 - .../src/components/collapse/index.ts | 3 - .../conditional-portal/CConditionalPortal.tsx | 54 - .../components/conditional-portal/index.ts | 3 - .../src/components/dropdown/CDropdown.tsx | 301 --- .../components/dropdown/CDropdownDivider.tsx | 22 - .../components/dropdown/CDropdownHeader.tsx | 32 - .../src/components/dropdown/CDropdownItem.tsx | 39 - .../dropdown/CDropdownItemPlain.tsx | 32 - .../src/components/dropdown/CDropdownMenu.tsx | 68 - .../components/dropdown/CDropdownToggle.tsx | 119 -- .../dropdown/__tests__/CDropdown.spec.tsx | 92 - .../__tests__/CDropdownDivider.spec.tsx | 16 - .../__tests__/CDropdownHeader.spec.tsx | 20 - .../dropdown/__tests__/CDropdownItem.spec.tsx | 20 - .../__tests__/CDropdownItemPlain.spec.tsx | 20 - .../dropdown/__tests__/CDropdownMenu.spec.tsx | 23 - .../__tests__/CDropdownToggle.spec.tsx | 20 - .../__snapshots__/CDropdown.spec.tsx.snap | 77 - .../CDropdownDivider.spec.tsx.snap | 17 - .../CDropdownHeader.spec.tsx.snap | 21 - .../__snapshots__/CDropdownItem.spec.tsx.snap | 21 - .../CDropdownItemPlain.spec.tsx.snap | 21 - .../__snapshots__/CDropdownMenu.spec.tsx.snap | 28 - .../CDropdownToggle.spec.tsx.snap | 30 - .../src/components/dropdown/index.ts | 17 - .../src/components/dropdown/types.ts | 11 - .../src/components/dropdown/utils.ts | 73 - .../src/components/footer/CFooter.tsx | 36 - .../footer/__tests__/CFooter.spec.tsx | 21 - .../__snapshots__/CFooter.spec.tsx.snap | 21 - .../src/components/footer/index.ts | 3 - .../src/components/form/CForm.tsx | 36 - .../src/components/form/CFormCheck.tsx | 227 --- .../form/CFormControlValidation.tsx | 96 - .../components/form/CFormControlWrapper.tsx | 97 - .../src/components/form/CFormFeedback.tsx | 60 - .../src/components/form/CFormFloating.tsx | 27 - .../src/components/form/CFormInput.tsx | 141 -- .../src/components/form/CFormLabel.tsx | 32 - .../src/components/form/CFormRange.tsx | 65 - .../src/components/form/CFormSelect.tsx | 128 -- .../src/components/form/CFormSwitch.tsx | 90 - .../src/components/form/CFormText.tsx | 32 - .../src/components/form/CFormTextarea.tsx | 101 - .../src/components/form/CInputGroup.tsx | 42 - .../src/components/form/CInputGroupText.tsx | 33 - .../components/form/__tests__/CForm.spec.tsx | 35 - .../form/__tests__/CFormCheck.spec.tsx | 33 - .../form/__tests__/CFormControl.spec.tsx | 44 - .../form/__tests__/CFormFeedback.spec.tsx | 29 - .../form/__tests__/CFormFloating.spec.tsx | 17 - .../form/__tests__/CFormInput.spec.tsx | 42 - .../form/__tests__/CFormLabel.spec.tsx | 25 - .../form/__tests__/CFormRange.spec.tsx | 33 - .../form/__tests__/CFormSelect.spec.tsx | 22 - .../form/__tests__/CFormSwitch.spec.tsx | 42 - .../form/__tests__/CFormText.spec.tsx | 20 - .../form/__tests__/CFormTextarea.spec.tsx | 33 - .../form/__tests__/CInputGroup.spec.tsx | 21 - .../form/__tests__/CInputGroupText.spec.tsx | 25 - .../__snapshots__/CForm.spec.tsx.snap | 60 - .../__snapshots__/CFormCheck.spec.tsx.snap | 46 - .../__snapshots__/CFormControl.spec.tsx.snap | 22 - .../__snapshots__/CFormFeedback.spec.tsx.snap | 25 - .../__snapshots__/CFormFloating.spec.tsx.snap | 19 - .../__snapshots__/CFormInput.spec.tsx.snap | 31 - .../__snapshots__/CFormLabel.spec.tsx.snap | 32 - .../__snapshots__/CFormRange.spec.tsx.snap | 26 - .../__snapshots__/CFormSelect.spec.tsx.snap | 26 - .../__snapshots__/CFormSwitch.spec.tsx.snap | 34 - .../__snapshots__/CFormText.spec.tsx.snap | 21 - .../__snapshots__/CFormTextarea.spec.tsx.snap | 24 - .../__snapshots__/CInputGroup.spec.tsx.snap | 21 - .../CInputGroupText.spec.tsx.snap | 32 - .../coreui-react/src/components/form/index.ts | 33 - .../coreui-react/src/components/grid/CCol.tsx | 150 -- .../src/components/grid/CContainer.tsx | 82 - .../coreui-react/src/components/grid/CRow.tsx | 119 -- .../components/grid/__tests__/CCol.spec.tsx | 42 - .../grid/__tests__/CContainer.spec.tsx | 31 - .../components/grid/__tests__/CRow.spec.tsx | 116 -- .../__snapshots__/CCol.spec.tsx.snap | 31 - .../__snapshots__/CContainer.spec.tsx.snap | 31 - .../__snapshots__/CRow.spec.tsx.snap | 61 - .../coreui-react/src/components/grid/index.ts | 5 - .../src/components/header/CHeader.tsx | 57 - .../src/components/header/CHeaderBrand.tsx | 33 - .../src/components/header/CHeaderDivider.tsx | 22 - .../src/components/header/CHeaderNav.tsx | 37 - .../src/components/header/CHeaderText.tsx | 27 - .../src/components/header/CHeaderToggler.tsx | 27 - .../header/__tests__/CHeader.spec.tsx | 21 - .../header/__tests__/CHeaderBrand.spec.tsx | 20 - .../header/__tests__/CHeaderDivider.spec.tsx | 16 - .../header/__tests__/CHeaderNav.spec.tsx | 20 - .../header/__tests__/CHeaderText.spec.tsx | 16 - .../header/__tests__/CHeaderToggler.spec.tsx | 16 - .../__snapshots__/CHeader.spec.tsx.snap | 25 - .../__snapshots__/CHeaderBrand.spec.tsx.snap | 21 - .../CHeaderDivider.spec.tsx.snap | 21 - .../__snapshots__/CHeaderNav.spec.tsx.snap | 23 - .../__snapshots__/CHeaderText.spec.tsx.snap | 21 - .../CHeaderToggler.spec.tsx.snap | 23 - .../src/components/header/index.ts | 8 - .../src/components/image/CImage.tsx | 59 - .../image/__tests__/CImage.spec.tsx | 28 - .../__snapshots__/CImage.spec.tsx.snap | 23 - .../src/components/image/index.ts | 3 - packages/coreui-react/src/components/index.ts | 37 - .../src/components/link/CLink.tsx | 60 - .../components/link/__tests__/CLink.spec.tsx | 51 - .../__snapshots__/CLink.spec.tsx.snap | 24 - .../coreui-react/src/components/link/index.ts | 3 - .../src/components/list-group/CListGroup.tsx | 65 - .../components/list-group/CListGroupItem.tsx | 82 - .../list-group/__tests__/CListGroup.spec.tsx | 33 - .../__tests__/CListGroupItem.spec.tsx | 29 - .../__snapshots__/CListGroup.spec.tsx.snap | 45 - .../CListGroupItem.spec.tsx.snap | 24 - .../src/components/list-group/index.ts | 4 - .../src/components/modal/CModal.tsx | 297 --- .../src/components/modal/CModalBody.tsx | 27 - .../src/components/modal/CModalContent.tsx | 27 - .../src/components/modal/CModalDialog.tsx | 65 - .../src/components/modal/CModalFooter.tsx | 27 - .../src/components/modal/CModalHeader.tsx | 38 - .../src/components/modal/CModalTitle.tsx | 32 - .../modal/__tests__/CModal.spec.tsx | 66 - .../modal/__tests__/CModalBody.spec.tsx | 16 - .../modal/__tests__/CModalContent.spec.tsx | 16 - .../modal/__tests__/CModalDialog.spec.tsx | 30 - .../modal/__tests__/CModalFooter.spec.tsx | 16 - .../modal/__tests__/CModalHeader.spec.tsx | 24 - .../modal/__tests__/CModalTitle.spec.tsx | 20 - .../__snapshots__/CModal.spec.tsx.snap | 5 - .../__snapshots__/CModalBody.spec.tsx.snap | 21 - .../__snapshots__/CModalContent.spec.tsx.snap | 21 - .../__snapshots__/CModalDialog.spec.tsx.snap | 21 - .../__snapshots__/CModalFooter.spec.tsx.snap | 21 - .../__snapshots__/CModalHeader.spec.tsx.snap | 31 - .../__snapshots__/CModalTitle.spec.tsx.snap | 21 - .../src/components/modal/index.ts | 9 - .../coreui-react/src/components/nav/CNav.tsx | 55 - .../src/components/nav/CNavGroup.tsx | 159 -- .../src/components/nav/CNavGroupItems.tsx | 27 - .../src/components/nav/CNavItem.tsx | 28 - .../src/components/nav/CNavLink.tsx | 64 - .../src/components/nav/CNavTitle.tsx | 27 - .../components/nav/__tests__/CNav.spec.tsx | 62 - .../nav/__tests__/CNavGroup.spec.tsx | 25 - .../nav/__tests__/CNavGroupItems.spec.tsx | 16 - .../nav/__tests__/CNavItem.spec.tsx | 22 - .../nav/__tests__/CNavLink.spec.tsx | 25 - .../nav/__tests__/CNavTitle.spec.tsx | 16 - .../__snapshots__/CNav.spec.tsx.snap | 119 -- .../__snapshots__/CNavGroup.spec.tsx.snap | 36 - .../CNavGroupItems.spec.tsx.snap | 21 - .../__snapshots__/CNavItem.spec.tsx.snap | 45 - .../__snapshots__/CNavLink.spec.tsx.snap | 35 - .../__snapshots__/CNavTitle.spec.tsx.snap | 21 - .../coreui-react/src/components/nav/index.ts | 8 - .../src/components/navbar/CNavbar.tsx | 107 - .../src/components/navbar/CNavbarBrand.tsx | 39 - .../src/components/navbar/CNavbarNav.tsx | 37 - .../src/components/navbar/CNavbarText.tsx | 27 - .../src/components/navbar/CNavbarToggler.tsx | 27 - .../navbar/__tests__/CNavbar.spec.tsx | 46 - .../navbar/__tests__/CNavbarBrand.spec.tsx | 25 - .../navbar/__tests__/CNavbarNav.spec.tsx | 21 - .../navbar/__tests__/CNavbarText.spec.tsx | 16 - .../navbar/__tests__/CNavbarToggler.spec.tsx | 23 - .../__snapshots__/CNavbar.spec.tsx.snap | 40 - .../__snapshots__/CNavbarBrand.spec.tsx.snap | 33 - .../__snapshots__/CNavbarNav.spec.tsx.snap | 23 - .../__snapshots__/CNavbarText.spec.tsx.snap | 21 - .../CNavbarToggler.spec.tsx.snap | 38 - .../src/components/navbar/index.ts | 7 - .../src/components/offcanvas/COffcanvas.tsx | 185 -- .../components/offcanvas/COffcanvasBody.tsx | 27 - .../components/offcanvas/COffcanvasHeader.tsx | 27 - .../components/offcanvas/COffcanvasTitle.tsx | 32 - .../offcanvas/__tests__/COffcanvas.spec.tsx | 102 - .../__tests__/COffcanvasBody.spec.tsx | 17 - .../__tests__/COffcanvasHeader.spec.tsx | 17 - .../__tests__/COffcanvasTitle.spec.tsx | 21 - .../__snapshots__/COffcanvas.spec.tsx.snap | 53 - .../COffcanvasBody.spec.tsx.snap | 19 - .../COffcanvasHeader.spec.tsx.snap | 19 - .../COffcanvasTitle.spec.tsx.snap | 19 - .../src/components/offcanvas/index.ts | 6 - .../src/components/pagination/CPagination.tsx | 48 - .../components/pagination/CPaginationItem.tsx | 58 - .../pagination/__tests__/CPagination.spec.tsx | 38 - .../__tests__/CPaginationItem.spec.tsx | 29 - .../__snapshots__/CPagination.spec.tsx.snap | 65 - .../CPaginationItem.spec.tsx.snap | 30 - .../src/components/pagination/index.ts | 4 - .../components/placeholder/CPlaceholder.tsx | 117 -- .../__tests__/CPlaceholder.spec.tsx | 21 - .../__snapshots__/CPlaceholder.spec.tsx.snap | 17 - .../src/components/placeholder/index.ts | 3 - .../src/components/popover/CPopover.tsx | 236 --- .../popover/__tests__/CPopover.spec.tsx | 84 - .../__snapshots__/CPopover.spec.tsx.snap | 23 - .../src/components/popover/index.ts | 3 - .../src/components/progress/CProgress.tsx | 104 - .../src/components/progress/CProgressBar.tsx | 67 - .../components/progress/CProgressStacked.tsx | 39 - .../progress/__tests__/CProgress.spec.tsx | 21 - .../progress/__tests__/CProgressBar.spec.tsx | 25 - .../__snapshots__/CProgress.spec.tsx.snap | 36 - .../__snapshots__/CProgressBar.spec.tsx.snap | 23 - .../src/components/progress/index.ts | 5 - .../src/components/sidebar/CSidebar.tsx | 234 --- .../src/components/sidebar/CSidebarBrand.tsx | 27 - .../src/components/sidebar/CSidebarFooter.tsx | 27 - .../src/components/sidebar/CSidebarHeader.tsx | 27 - .../src/components/sidebar/CSidebarNav.tsx | 50 - .../components/sidebar/CSidebarToggler.tsx | 27 - .../sidebar/__tests__/CSidebar.spec.tsx | 46 - .../sidebar/__tests__/CSidebarBrand.spec.tsx | 16 - .../sidebar/__tests__/CSidebarFooter.spec.tsx | 16 - .../sidebar/__tests__/CSidebarHeader.spec.tsx | 16 - .../sidebar/__tests__/CSidebarNav.spec.tsx | 16 - .../__tests__/CSidebarToggler.spec.tsx | 17 - .../__snapshots__/CSidebar.spec.tsx.snap | 31 - .../__snapshots__/CSidebarBrand.spec.tsx.snap | 22 - .../CSidebarFooter.spec.tsx.snap | 21 - .../CSidebarHeader.spec.tsx.snap | 21 - .../__snapshots__/CSidebarNav.spec.tsx.snap | 17 - .../CSidebarToggler.spec.tsx.snap | 19 - .../src/components/sidebar/index.ts | 8 - .../src/components/spinner/CSpinner.tsx | 79 - .../spinner/__tests__/CSpinner.spec.tsx | 22 - .../__snapshots__/CSpinner.spec.tsx.snap | 31 - .../src/components/spinner/index.ts | 3 - .../src/components/table/CTable.tsx | 267 --- .../src/components/table/CTableBody.tsx | 48 - .../src/components/table/CTableCaption.tsx | 19 - .../src/components/table/CTableDataCell.tsx | 68 - .../src/components/table/CTableFoot.tsx | 48 - .../src/components/table/CTableHead.tsx | 48 - .../src/components/table/CTableHeaderCell.tsx | 48 - .../table/CTableResponsiveWrapper.tsx | 38 - .../src/components/table/CTableRow.tsx | 60 - .../table/__tests__/CTable.spec.tsx | 150 -- .../table/__tests__/CTableBody.spec.tsx | 30 - .../table/__tests__/CTableCaption.spec.tsx | 21 - .../table/__tests__/CTableDataCell.spec.tsx | 43 - .../table/__tests__/CTableFoot.spec.tsx | 30 - .../table/__tests__/CTableHead.spec.tsx | 30 - .../table/__tests__/CTableHeaderCell.spec.tsx | 39 - .../table/__tests__/CTableRow.spec.tsx | 37 - .../__snapshots__/CTable.spec.tsx.snap | 197 -- .../__snapshots__/CTableBody.spec.tsx.snap | 21 - .../__snapshots__/CTableCaption.spec.tsx.snap | 15 - .../CTableDataCell.spec.tsx.snap | 25 - .../__snapshots__/CTableFoot.spec.tsx.snap | 21 - .../__snapshots__/CTableHead.spec.tsx.snap | 21 - .../CTableHeaderCell.spec.tsx.snap | 25 - .../__snapshots__/CTableRow.spec.tsx.snap | 23 - .../src/components/table/index.ts | 19 - .../src/components/table/types.ts | 20 - .../src/components/table/utils.ts | 24 - .../src/components/tabs/CTabContent.tsx | 27 - .../src/components/tabs/CTabPane.tsx | 64 - .../tabs/__tests__/CTabContent.spec.tsx | 16 - .../tabs/__tests__/CTabPane.spec.tsx | 48 - .../__snapshots__/CTabContent.spec.tsx.snap | 21 - .../__snapshots__/CTabPane.spec.tsx.snap | 21 - .../coreui-react/src/components/tabs/index.ts | 4 - .../src/components/toast/CToast.tsx | 172 -- .../src/components/toast/CToastBody.tsx | 27 - .../src/components/toast/CToastClose.tsx | 36 - .../src/components/toast/CToastHeader.tsx | 35 - .../src/components/toast/CToaster.tsx | 104 - .../toast/__tests__/CToast.spec.tsx | 99 - .../toast/__tests__/CToastBody.spec.tsx | 16 - .../toast/__tests__/CToastHeader.spec.tsx | 16 - .../toast/__tests__/CToaster.spec.tsx | 47 - .../__snapshots__/CToast.spec.tsx.snap | 16 - .../__snapshots__/CToastBody.spec.tsx.snap | 21 - .../__snapshots__/CToastHeader.spec.tsx.snap | 21 - .../__snapshots__/CToaster.spec.tsx.snap | 25 - .../src/components/toast/index.ts | 7 - .../src/components/tooltip/CTooltip.tsx | 227 --- .../tooltip/__tests__/CTooltip.spec.tsx | 63 - .../__snapshots__/CTooltip.spec.tsx.snap | 21 - .../src/components/tooltip/index.ts | 3 - .../src/components/widgets/CWidgetStatsA.tsx | 69 - .../src/components/widgets/CWidgetStatsB.tsx | 80 - .../src/components/widgets/CWidgetStatsC.tsx | 95 - .../src/components/widgets/CWidgetStatsD.tsx | 83 - .../src/components/widgets/CWidgetStatsE.tsx | 50 - .../src/components/widgets/CWidgetStatsF.tsx | 69 - .../widgets/__tests__/CWidgetStatsA.spec.tsx | 47 - .../widgets/__tests__/CWidgetStatsB.spec.tsx | 38 - .../widgets/__tests__/CWidgetStatsC.spec.tsx | 39 - .../widgets/__tests__/CWidgetStatsD.spec.tsx | 49 - .../widgets/__tests__/CWidgetStatsE.spec.tsx | 30 - .../widgets/__tests__/CWidgetStatsF.spec.tsx | 59 - .../__snapshots__/CWidgetStatsA.spec.tsx.snap | 40 - .../__snapshots__/CWidgetStatsB.spec.tsx.snap | 62 - .../__snapshots__/CWidgetStatsC.spec.tsx.snap | 64 - .../__snapshots__/CWidgetStatsD.spec.tsx.snap | 63 - .../__snapshots__/CWidgetStatsE.spec.tsx.snap | 36 - .../__snapshots__/CWidgetStatsF.spec.tsx.snap | 60 - .../src/components/widgets/index.ts | 8 - packages/coreui-react/src/hooks/index.ts | 5 - .../coreui-react/src/hooks/useColorModes.ts | 67 - .../coreui-react/src/hooks/useForkedRef.ts | 50 - packages/coreui-react/src/hooks/usePopper.ts | 39 - packages/coreui-react/src/index.ts | 2 - packages/coreui-react/src/props.ts | 68 - packages/coreui-react/src/types.ts | 65 - .../src/utils/executeAfterTransition.ts | 46 - .../coreui-react/src/utils/getRTLPlacement.ts | 18 - .../utils/getTransitionDurationFromElement.ts | 24 - packages/coreui-react/src/utils/index.ts | 13 - .../coreui-react/src/utils/isInViewport.ts | 11 - packages/coreui-react/src/utils/isRTL.ts | 13 - packages/coreui-react/tsconfig.json | 4 - packages/docs/build/api.js | 129 -- packages/docs/content/api/CAccordion.api.mdx | 13 - .../docs/content/api/CAccordionBody.api.mdx | 10 - .../docs/content/api/CAccordionButton.api.mdx | 10 - .../content/api/CAccordionCollapse.api.mdx | 13 - .../docs/content/api/CAccordionHeader.api.mdx | 10 - .../docs/content/api/CAccordionItem.api.mdx | 11 - packages/docs/content/api/CAlert.api.mdx | 15 - .../docs/content/api/CAlertHeading.api.mdx | 11 - packages/docs/content/api/CAlertLink.api.mdx | 10 - packages/docs/content/api/CAvatar.api.mdx | 16 - packages/docs/content/api/CBackdrop.api.mdx | 11 - packages/docs/content/api/CBadge.api.mdx | 16 - packages/docs/content/api/CBreadcrumb.api.mdx | 10 - .../docs/content/api/CBreadcrumbItem.api.mdx | 12 - packages/docs/content/api/CButton.api.mdx | 20 - .../docs/content/api/CButtonGroup.api.mdx | 12 - .../docs/content/api/CButtonToolbar.api.mdx | 10 - packages/docs/content/api/CCallout.api.mdx | 11 - packages/docs/content/api/CCard.api.mdx | 12 - packages/docs/content/api/CCardBody.api.mdx | 10 - packages/docs/content/api/CCardFooter.api.mdx | 10 - packages/docs/content/api/CCardGroup.api.mdx | 10 - packages/docs/content/api/CCardHeader.api.mdx | 11 - packages/docs/content/api/CCardImage.api.mdx | 12 - .../content/api/CCardImageOverlay.api.mdx | 10 - packages/docs/content/api/CCardLink.api.mdx | 11 - .../docs/content/api/CCardSubtitle.api.mdx | 11 - packages/docs/content/api/CCardText.api.mdx | 11 - packages/docs/content/api/CCardTitle.api.mdx | 11 - packages/docs/content/api/CCarousel.api.mdx | 21 - .../docs/content/api/CCarouselCaption.api.mdx | 10 - .../docs/content/api/CCarouselItem.api.mdx | 11 - packages/docs/content/api/CChart.api.mdx | 24 - packages/docs/content/api/CCharts.api.mdx | 23 - .../docs/content/api/CCloseButton.api.mdx | 13 - packages/docs/content/api/CCol.api.mdx | 16 - packages/docs/content/api/CCollapse.api.mdx | 14 - .../content/api/CConditionalPortal.api.mdx | 11 - packages/docs/content/api/CContainer.api.mdx | 16 - packages/docs/content/api/CDropdown.api.mdx | 24 - .../docs/content/api/CDropdownDivider.api.mdx | 10 - .../docs/content/api/CDropdownHeader.api.mdx | 11 - .../docs/content/api/CDropdownItem.api.mdx | 14 - .../content/api/CDropdownItemPlain.api.mdx | 11 - .../docs/content/api/CDropdownMenu.api.mdx | 11 - .../docs/content/api/CDropdownToggle.api.mdx | 24 - packages/docs/content/api/CFooter.api.mdx | 11 - packages/docs/content/api/CForm.api.mdx | 11 - packages/docs/content/api/CFormCheck.api.mdx | 25 - .../api/CFormControlValidation.api.mdx | 16 - .../content/api/CFormControlWrapper.api.mdx | 19 - .../docs/content/api/CFormFeedback.api.mdx | 14 - .../docs/content/api/CFormFloating.api.mdx | 10 - packages/docs/content/api/CFormInput.api.mdx | 28 - packages/docs/content/api/CFormLabel.api.mdx | 11 - packages/docs/content/api/CFormRange.api.mdx | 18 - packages/docs/content/api/CFormSelect.api.mdx | 25 - packages/docs/content/api/CFormSwitch.api.mdx | 17 - packages/docs/content/api/CFormText.api.mdx | 11 - .../docs/content/api/CFormTextarea.api.mdx | 25 - packages/docs/content/api/CHeader.api.mdx | 12 - .../docs/content/api/CHeaderBrand.api.mdx | 11 - .../docs/content/api/CHeaderDivider.api.mdx | 10 - packages/docs/content/api/CHeaderNav.api.mdx | 11 - packages/docs/content/api/CHeaderText.api.mdx | 10 - .../docs/content/api/CHeaderToggler.api.mdx | 10 - packages/docs/content/api/CIcon.api.mdx | 20 - packages/docs/content/api/CImage.api.mdx | 14 - packages/docs/content/api/CInputGroup.api.mdx | 11 - .../docs/content/api/CInputGroupText.api.mdx | 11 - packages/docs/content/api/CLink.api.mdx | 14 - packages/docs/content/api/CListGroup.api.mdx | 13 - .../docs/content/api/CListGroupItem.api.mdx | 14 - packages/docs/content/api/CModal.api.mdx | 24 - packages/docs/content/api/CModalBody.api.mdx | 10 - .../docs/content/api/CModalContent.api.mdx | 10 - .../docs/content/api/CModalDialog.api.mdx | 14 - .../docs/content/api/CModalFooter.api.mdx | 10 - .../docs/content/api/CModalHeader.api.mdx | 11 - packages/docs/content/api/CModalTitle.api.mdx | 11 - packages/docs/content/api/CNav.api.mdx | 13 - packages/docs/content/api/CNavGroup.api.mdx | 13 - .../docs/content/api/CNavGroupItems.api.mdx | 10 - packages/docs/content/api/CNavItem.api.mdx | 14 - packages/docs/content/api/CNavLink.api.mdx | 14 - packages/docs/content/api/CNavTitle.api.mdx | 10 - packages/docs/content/api/CNavbar.api.mdx | 16 - .../docs/content/api/CNavbarBrand.api.mdx | 12 - packages/docs/content/api/CNavbarNav.api.mdx | 11 - packages/docs/content/api/CNavbarText.api.mdx | 10 - .../docs/content/api/CNavbarToggler.api.mdx | 10 - packages/docs/content/api/COffcanvas.api.mdx | 20 - .../docs/content/api/COffcanvasBody.api.mdx | 10 - .../docs/content/api/COffcanvasHeader.api.mdx | 10 - .../docs/content/api/COffcanvasTitle.api.mdx | 11 - packages/docs/content/api/CPagination.api.mdx | 12 - .../docs/content/api/CPaginationItem.api.mdx | 12 - .../docs/content/api/CPlaceholder.api.mdx | 20 - packages/docs/content/api/CPopover.api.mdx | 22 - packages/docs/content/api/CProgress.api.mdx | 18 - .../docs/content/api/CProgressBar.api.mdx | 14 - .../docs/content/api/CProgressStacked.api.mdx | 10 - packages/docs/content/api/CRow.api.mdx | 16 - packages/docs/content/api/CSidebar.api.mdx | 19 - .../docs/content/api/CSidebarBrand.api.mdx | 10 - .../docs/content/api/CSidebarFooter.api.mdx | 10 - .../docs/content/api/CSidebarHeader.api.mdx | 10 - packages/docs/content/api/CSidebarNav.api.mdx | 10 - .../docs/content/api/CSidebarToggler.api.mdx | 10 - packages/docs/content/api/CSpinner.api.mdx | 15 - packages/docs/content/api/CTabContent.api.mdx | 10 - packages/docs/content/api/CTabPane.api.mdx | 13 - packages/docs/content/api/CTable.api.mdx | 27 - packages/docs/content/api/CTableBody.api.mdx | 11 - .../docs/content/api/CTableCaption.api.mdx | 7 - .../docs/content/api/CTableDataCell.api.mdx | 13 - packages/docs/content/api/CTableFoot.api.mdx | 11 - packages/docs/content/api/CTableHead.api.mdx | 11 - .../docs/content/api/CTableHeaderCell.api.mdx | 11 - .../api/CTableResponsiveWrapper.api.mdx | 10 - packages/docs/content/api/CTableRow.api.mdx | 13 - packages/docs/content/api/CToast.api.mdx | 17 - packages/docs/content/api/CToastBody.api.mdx | 10 - packages/docs/content/api/CToastClose.api.mdx | 20 - .../docs/content/api/CToastHeader.api.mdx | 11 - packages/docs/content/api/CToaster.api.mdx | 12 - packages/docs/content/api/CTooltip.api.mdx | 21 - .../docs/content/api/CWidgetStatsA.api.mdx | 15 - .../docs/content/api/CWidgetStatsB.api.mdx | 16 - .../docs/content/api/CWidgetStatsC.api.mdx | 16 - .../docs/content/api/CWidgetStatsD.api.mdx | 14 - .../docs/content/api/CWidgetStatsE.api.mdx | 13 - .../docs/content/api/CWidgetStatsF.api.mdx | 16 - .../assets/images/brand/coreui-signet.svg | 10 - .../docs/content/assets/images/react400.jpg | Bin 5700 -> 0 bytes .../docs/content/components/accordion.mdx | 185 -- packages/docs/content/components/alert.mdx | 262 --- packages/docs/content/components/avatar.mdx | 75 - packages/docs/content/components/badge.mdx | 146 -- .../docs/content/components/breadcrumb.mdx | 113 -- .../docs/content/components/button-group.mdx | 332 --- packages/docs/content/components/button.mdx | 216 -- packages/docs/content/components/callout.mdx | 84 - packages/docs/content/components/card.mdx | 1035 ---------- packages/docs/content/components/carousel.mdx | 232 --- packages/docs/content/components/chart.mdx | 847 -------- .../docs/content/components/close-button.mdx | 41 - packages/docs/content/components/collapse.mdx | 263 --- packages/docs/content/components/dropdown.mdx | 615 ------ packages/docs/content/components/footer.mdx | 53 - packages/docs/content/components/header.mdx | 193 -- packages/docs/content/components/icon.mdx | 320 --- packages/docs/content/components/image.mdx | 58 - .../docs/content/components/list-group.mdx | 345 ---- packages/docs/content/components/modal.mdx | 1375 ------------- packages/docs/content/components/navbar.mdx | 1475 -------------- .../docs/content/components/navs-tabs.mdx | 707 ------- .../docs/content/components/offcanvas.mdx | 467 ----- .../docs/content/components/pagination.mdx | 144 -- .../docs/content/components/placeholder.mdx | 145 -- packages/docs/content/components/popover.mdx | 214 -- packages/docs/content/components/progress.mdx | 184 -- packages/docs/content/components/sidebar.mdx | 305 --- packages/docs/content/components/spinner.mdx | 193 -- packages/docs/content/components/table.mdx | 1663 --------------- packages/docs/content/components/toast.mdx | 281 --- packages/docs/content/components/tooltip.mdx | 191 -- packages/docs/content/components/widgets.mdx | 1450 ------------- .../docs/content/customize/css-variables.mdx | 116 -- packages/docs/content/customize/options.mdx | 32 - packages/docs/content/customize/sass.mdx | 325 --- packages/docs/content/forms/checkbox.mdx | 127 -- packages/docs/content/forms/checks-radios.mdx | 190 -- .../docs/content/forms/floating-labels.mdx | 159 -- packages/docs/content/forms/form-control.mdx | 136 -- packages/docs/content/forms/input-group.mdx | 356 ---- packages/docs/content/forms/input-mask.mdx | 126 -- packages/docs/content/forms/input.mdx | 192 -- packages/docs/content/forms/layout.mdx | 290 --- packages/docs/content/forms/overview.mdx | 204 -- packages/docs/content/forms/radio.mdx | 103 - packages/docs/content/forms/range.mdx | 54 - packages/docs/content/forms/select.mdx | 109 - packages/docs/content/forms/switch.mdx | 59 - packages/docs/content/forms/textarea.mdx | 99 - packages/docs/content/forms/validation.mdx | 697 ------- .../content/getting-started/accessibility.mdx | 61 - .../content/getting-started/introduction.mdx | 72 - packages/docs/content/layout/breakpoints.mdx | 178 -- packages/docs/content/layout/columns.mdx | 273 --- packages/docs/content/layout/containers.mdx | 70 - packages/docs/content/layout/grid.mdx | 351 ---- packages/docs/content/layout/gutters.mdx | 181 -- packages/docs/content/migration/v4.mdx | 408 ---- packages/docs/content/migration/v5.mdx | 45 - .../content/templates/admin-dashboard.mdx | 91 - packages/docs/content/templates/contents.mdx | 40 - packages/docs/content/templates/customize.mdx | 69 - packages/docs/content/templates/download.mdx | 27 - .../docs/content/templates/installation.mdx | 54 - packages/docs/gatsby-browser.js | 8 - packages/docs/gatsby-config.js | 101 - packages/docs/gatsby-node.js | 66 - packages/docs/gatsby-ssr.js | 8 - packages/docs/package.json | 67 - packages/docs/src/AppContext.tsx | 13 - packages/docs/src/assets/coreui-react.svg | 28 - .../docs/src/assets/images/brand/icon.png | Bin 18140 -> 0 bytes packages/docs/src/components/Ads.tsx | 27 - packages/docs/src/components/Banner.tsx | 55 - packages/docs/src/components/Callout.tsx | 19 - packages/docs/src/components/CodeBlock.tsx | 39 - packages/docs/src/components/Example.tsx | 20 - packages/docs/src/components/Footer.tsx | 56 - packages/docs/src/components/Header.tsx | 143 -- packages/docs/src/components/ScssDocs.tsx | 82 - packages/docs/src/components/Seo.tsx | 101 - packages/docs/src/components/Sidebar.tsx | 77 - packages/docs/src/components/SidebarNav.tsx | 75 - packages/docs/src/components/Toc.tsx | 46 - packages/docs/src/components/index.ts | 27 - packages/docs/src/data/other_frameworks.json | 241 --- packages/docs/src/images/gatsby-astronaut.png | Bin 167273 -> 0 bytes packages/docs/src/images/gatsby-icon.png | Bin 21212 -> 0 bytes packages/docs/src/index.ts | 1 - packages/docs/src/nav.tsx | 378 ---- packages/docs/src/pages/404.tsx | 30 - packages/docs/src/styles/_ads.scss | 38 - packages/docs/src/styles/_anchor.scss | 23 - packages/docs/src/styles/_callouts.scss | 39 - .../docs/src/styles/_component-examples.scss | 436 ---- packages/docs/src/styles/_footer.scss | 19 - packages/docs/src/styles/_prism.scss | 172 -- packages/docs/src/styles/_scrolling.scss | 13 - packages/docs/src/styles/_search.scss | 152 -- packages/docs/src/styles/_sidebar.scss | 32 - packages/docs/src/styles/_table-api.scss | 24 - packages/docs/src/styles/_toc.scss | 42 - packages/docs/src/styles/_variables.scss | 25 - packages/docs/src/styles/styles.scss | 18 - packages/docs/src/templates/DefaultLayout.tsx | 75 - packages/docs/src/templates/DocsLayout.tsx | 88 - packages/docs/src/templates/MdxLayout.tsx | 91 - packages/docs/static/index.html | 3 - .../gatsby-remark-import-markdown/index.js | 52 - .../package.json | 31 - packages/gatsby-remark-jsx-preview/index.js | 48 - .../gatsby-remark-jsx-preview/package.json | 26 - src/App.js | 38 + src/App.test.js | 9 + src/_nav.js | 305 +++ src/assets/brand/logo-negative.js | 33 + src/assets/brand/logo.js | 32 + src/assets/brand/sygnet.js | 12 + .../content => src}/assets/images/angular.jpg | Bin .../assets/images/avatars/1.jpg | Bin .../assets/images/avatars/2.jpg | Bin .../assets/images/avatars/3.jpg | Bin .../assets/images/avatars/4.jpg | Bin .../assets/images/avatars/5.jpg | Bin .../assets/images/avatars/6.jpg | Bin .../assets/images/avatars/7.jpg | Bin .../assets/images/avatars/8.jpg | Bin .../assets/images/avatars/9.jpg | Bin .../content => src}/assets/images/react.jpg | Bin .../content => src}/assets/images/vue.jpg | Bin src/components/AppBreadcrumb.js | 51 + src/components/AppContent.js | 33 + src/components/AppFooter.js | 23 + src/components/AppHeader.js | 79 + src/components/AppSidebar.js | 49 + src/components/AppSidebarNav.js | 67 + src/components/DocsCallout.js | 38 + src/components/DocsExample.js | 42 + src/components/DocsLink.js | 31 + src/components/header/AppHeaderDropdown.js | 96 + src/components/header/index.js | 3 + src/components/index.js | 21 + src/index.js | 19 + src/layout/DefaultLayout.js | 19 + src/reportWebVitals.js | 13 + src/routes.js | 100 + src/scss/_custom.scss | 1 + src/scss/_example.scss | 109 + .../docs/src/styles => src/scss}/_layout.scss | 0 src/scss/_variables.scss | 1791 +++++++++++++++++ src/scss/style.scss | 17 + src/setupTests.js | 5 + src/store.js | 17 + src/views/base/accordion/Accordion.js | 177 ++ src/views/base/breadcrumbs/Breadcrumbs.js | 74 + src/views/base/cards/Cards.js | 906 +++++++++ src/views/base/carousels/Carousels.js | 212 ++ src/views/base/collapses/Collapses.js | 126 ++ src/views/base/index.js | 31 + src/views/base/jumbotrons/Jumbotrons.js | 56 + src/views/base/list-groups/ListGroups.js | 346 ++++ src/views/base/navbars/Navbars.js | 174 ++ src/views/base/navs/Navs.js | 397 ++++ src/views/base/paginations/Paginations.js | 174 ++ src/views/base/placeholders/Placeholders.js | 193 ++ src/views/base/popovers/Popovers.js | 71 + src/views/base/progress/Progress.js | 186 ++ src/views/base/spinners/Spinners.js | 120 ++ src/views/base/tables/Tables.js | 986 +++++++++ src/views/base/tooltips/Tooltips.js | 79 + .../buttons/button-groups/ButtonGroups.js | 439 ++++ src/views/buttons/buttons/Buttons.js | 401 ++++ src/views/buttons/dropdowns/Dropdowns.js | 338 ++++ src/views/buttons/index.js | 5 + src/views/charts/Charts.js | 176 ++ src/views/dashboard/Dashboard.js | 461 +++++ src/views/forms/checks-radios/ChecksRadios.js | 392 ++++ .../forms/floating-labels/FloatingLabels.js | 170 ++ src/views/forms/form-control/FormControl.js | 248 +++ src/views/forms/input-group/InputGroup.js | 503 +++++ src/views/forms/layout/Layout.js | 414 ++++ src/views/forms/range/Range.js | 82 + src/views/forms/select/Select.js | 99 + src/views/forms/validation/Validation.js | 503 +++++ src/views/icons/brands/Brands.js | 38 + src/views/icons/coreui-icons/CoreUIIcons.js | 25 + src/views/icons/flags/Flags.js | 25 + src/views/icons/index.js | 5 + src/views/notifications/alerts/Alerts.js | 147 ++ src/views/notifications/badges/Badges.js | 122 ++ src/views/notifications/index.js | 6 + src/views/notifications/modals/Modals.js | 720 +++++++ src/views/notifications/toasts/Toasts.js | 252 +++ src/views/pages/login/Login.js | 86 + src/views/pages/page404/Page404.js | 41 + src/views/pages/page500/Page500.js | 41 + src/views/pages/register/Register.js | 71 + src/views/theme/colors/Colors.js | 91 + src/views/theme/typography/Typography.js | 229 +++ src/views/widgets/Widgets.js | 936 +++++++++ src/views/widgets/WidgetsBrand.js | 188 ++ src/views/widgets/WidgetsDropdown.js | 361 ++++ tsconfig.json | 30 - 783 files changed, 15060 insertions(+), 42734 deletions(-) rename packages/coreui-react/jest.config.js => jest.config.js (64%) create mode 100644 jsconfig.json delete mode 100644 lerna.json create mode 100644 migration.md delete mode 160000 packages/coreui-icons-react delete mode 160000 packages/coreui-react-chartjs delete mode 100644 packages/coreui-react/LICENSE delete mode 100644 packages/coreui-react/README.md delete mode 100644 packages/coreui-react/package.json delete mode 100644 packages/coreui-react/rollup.config.mjs delete mode 100644 packages/coreui-react/src/components/accordion/CAccordion.tsx delete mode 100644 packages/coreui-react/src/components/accordion/CAccordionBody.tsx delete mode 100644 packages/coreui-react/src/components/accordion/CAccordionButton.tsx delete mode 100644 packages/coreui-react/src/components/accordion/CAccordionHeader.tsx delete mode 100644 packages/coreui-react/src/components/accordion/CAccordionItem.tsx delete mode 100644 packages/coreui-react/src/components/accordion/__tests__/CAccordion.spec.tsx delete mode 100644 packages/coreui-react/src/components/accordion/__tests__/CAccordionBody.spec.tsx delete mode 100644 packages/coreui-react/src/components/accordion/__tests__/CAccordionButton.spec.tsx delete mode 100644 packages/coreui-react/src/components/accordion/__tests__/CAccordionHeader.spec.tsx delete mode 100644 packages/coreui-react/src/components/accordion/__tests__/CAccordionItem.spec.tsx delete mode 100644 packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordion.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionBody.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionItem.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/accordion/index.ts delete mode 100644 packages/coreui-react/src/components/alert/CAlert.tsx delete mode 100644 packages/coreui-react/src/components/alert/CAlertHeading.tsx delete mode 100644 packages/coreui-react/src/components/alert/CAlertLink.tsx delete mode 100644 packages/coreui-react/src/components/alert/__tests__/CAlert.spec.tsx delete mode 100644 packages/coreui-react/src/components/alert/__tests__/CAlertHeading.spec.tsx delete mode 100644 packages/coreui-react/src/components/alert/__tests__/CAlertLink.spec.tsx delete mode 100644 packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlert.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlertHeading.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlertLink.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/alert/index.ts delete mode 100644 packages/coreui-react/src/components/avatar/CAvatar.tsx delete mode 100644 packages/coreui-react/src/components/avatar/__tests__/CAvatar.spec.tsx delete mode 100644 packages/coreui-react/src/components/avatar/__tests__/__snapshots__/CAvatar.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/avatar/index.ts delete mode 100644 packages/coreui-react/src/components/backdrop/CBackdrop.tsx delete mode 100644 packages/coreui-react/src/components/backdrop/__tests__/CBackdrop.spec.tsx delete mode 100644 packages/coreui-react/src/components/backdrop/__tests__/__snapshots__/CBackdrop.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/backdrop/index.ts delete mode 100644 packages/coreui-react/src/components/badge/CBadge.tsx delete mode 100644 packages/coreui-react/src/components/badge/__tests__/CBadge.spec.tsx delete mode 100644 packages/coreui-react/src/components/badge/__tests__/__snapshots__/CBadge.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/badge/index.ts delete mode 100644 packages/coreui-react/src/components/breadcrumb/CBreadcrumb.tsx delete mode 100644 packages/coreui-react/src/components/breadcrumb/CBreadcrumbItem.tsx delete mode 100644 packages/coreui-react/src/components/breadcrumb/__tests__/CBreadcrumb.spec.tsx delete mode 100644 packages/coreui-react/src/components/breadcrumb/__tests__/CBreadcrumbItem.spec.tsx delete mode 100644 packages/coreui-react/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumb.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumbItem.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/breadcrumb/index.ts delete mode 100644 packages/coreui-react/src/components/button-group/CButtonGroup.tsx delete mode 100644 packages/coreui-react/src/components/button-group/CButtonToolbar.tsx delete mode 100644 packages/coreui-react/src/components/button-group/__tests__/CButtonGroup.spec.tsx delete mode 100644 packages/coreui-react/src/components/button-group/__tests__/CButtonToolbar.spec.tsx delete mode 100644 packages/coreui-react/src/components/button-group/__tests__/__snapshots__/CButtonGroup.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/button-group/__tests__/__snapshots__/CButtonToolbar.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/button-group/index.ts delete mode 100644 packages/coreui-react/src/components/button/CButton.tsx delete mode 100644 packages/coreui-react/src/components/button/__tests__/CButton.spec.tsx delete mode 100644 packages/coreui-react/src/components/button/__tests__/CButtonClose.spec.tsx delete mode 100644 packages/coreui-react/src/components/button/__tests__/__snapshots__/CButton.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/button/__tests__/__snapshots__/CButtonClose.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/button/index.ts delete mode 100644 packages/coreui-react/src/components/callout/CCallout.tsx delete mode 100644 packages/coreui-react/src/components/callout/__tests__/CCallout.spec.tsx delete mode 100644 packages/coreui-react/src/components/callout/__tests__/__snapshots__/CCallout.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/callout/index.ts delete mode 100644 packages/coreui-react/src/components/card/CCard.tsx delete mode 100644 packages/coreui-react/src/components/card/CCardBody.tsx delete mode 100644 packages/coreui-react/src/components/card/CCardFooter.tsx delete mode 100644 packages/coreui-react/src/components/card/CCardGroup.tsx delete mode 100644 packages/coreui-react/src/components/card/CCardHeader.tsx delete mode 100644 packages/coreui-react/src/components/card/CCardImage.tsx delete mode 100644 packages/coreui-react/src/components/card/CCardImageOverlay.tsx delete mode 100644 packages/coreui-react/src/components/card/CCardLink.tsx delete mode 100644 packages/coreui-react/src/components/card/CCardSubtitle.tsx delete mode 100644 packages/coreui-react/src/components/card/CCardText.tsx delete mode 100644 packages/coreui-react/src/components/card/CCardTitle.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/CCard.spec.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/CCardBody.spec.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/CCardFooter.spec.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/CCardGroup.spec.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/CCardHeader.spec.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/CCardImage.spec.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/CCardImageOverlay.spec.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/CCardLink.spec.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/CCardSubtitle.spec.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/CCardText.spec.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/CCardTitle.spec.tsx delete mode 100644 packages/coreui-react/src/components/card/__tests__/__snapshots__/CCard.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardBody.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardFooter.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardGroup.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardHeader.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardImage.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardImageOverlay.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardLink.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardSubtitle.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardText.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardTitle.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/card/index.ts delete mode 100644 packages/coreui-react/src/components/carousel/CCarousel.tsx delete mode 100644 packages/coreui-react/src/components/carousel/CCarouselCaption.tsx delete mode 100644 packages/coreui-react/src/components/carousel/CCarouselItem.tsx delete mode 100644 packages/coreui-react/src/components/carousel/__tests__/CCarousel.spec.tsx delete mode 100644 packages/coreui-react/src/components/carousel/__tests__/__snapshots__/CCarousel.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/carousel/index.ts delete mode 100644 packages/coreui-react/src/components/close-button/CCloseButton.tsx delete mode 100644 packages/coreui-react/src/components/close-button/__tests__/CCloseButton.spec.tsx delete mode 100644 packages/coreui-react/src/components/close-button/__tests__/__snapshots__/CCloseButton.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/close-button/index.ts delete mode 100644 packages/coreui-react/src/components/collapse/CCollapse.tsx delete mode 100644 packages/coreui-react/src/components/collapse/__tests__/CCollapse.spec.tsx delete mode 100644 packages/coreui-react/src/components/collapse/__tests__/__snapshots__/CCollapse.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/collapse/index.ts delete mode 100644 packages/coreui-react/src/components/conditional-portal/CConditionalPortal.tsx delete mode 100644 packages/coreui-react/src/components/conditional-portal/index.ts delete mode 100644 packages/coreui-react/src/components/dropdown/CDropdown.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/CDropdownDivider.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/CDropdownHeader.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/CDropdownItem.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/CDropdownItemPlain.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/CDropdownMenu.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/CDropdownToggle.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/CDropdown.spec.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/CDropdownDivider.spec.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/CDropdownHeader.spec.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/CDropdownItem.spec.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/CDropdownItemPlain.spec.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/CDropdownMenu.spec.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/CDropdownToggle.spec.tsx delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownDivider.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownHeader.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownItem.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownItemPlain.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownToggle.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/dropdown/index.ts delete mode 100644 packages/coreui-react/src/components/dropdown/types.ts delete mode 100644 packages/coreui-react/src/components/dropdown/utils.ts delete mode 100644 packages/coreui-react/src/components/footer/CFooter.tsx delete mode 100644 packages/coreui-react/src/components/footer/__tests__/CFooter.spec.tsx delete mode 100644 packages/coreui-react/src/components/footer/__tests__/__snapshots__/CFooter.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/footer/index.ts delete mode 100644 packages/coreui-react/src/components/form/CForm.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormCheck.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormControlValidation.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormControlWrapper.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormFeedback.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormFloating.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormInput.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormLabel.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormRange.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormSelect.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormSwitch.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormText.tsx delete mode 100644 packages/coreui-react/src/components/form/CFormTextarea.tsx delete mode 100644 packages/coreui-react/src/components/form/CInputGroup.tsx delete mode 100644 packages/coreui-react/src/components/form/CInputGroupText.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CForm.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CFormCheck.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CFormControl.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CFormFeedback.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CFormFloating.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CFormInput.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CFormLabel.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CFormRange.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CFormSelect.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CFormSwitch.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CFormText.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CFormTextarea.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CInputGroup.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/CInputGroupText.spec.tsx delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CForm.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormCheck.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormControl.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormFeedback.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormFloating.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormInput.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormLabel.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormRange.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormSelect.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormSwitch.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormText.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormTextarea.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CInputGroup.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/__tests__/__snapshots__/CInputGroupText.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/form/index.ts delete mode 100644 packages/coreui-react/src/components/grid/CCol.tsx delete mode 100644 packages/coreui-react/src/components/grid/CContainer.tsx delete mode 100644 packages/coreui-react/src/components/grid/CRow.tsx delete mode 100644 packages/coreui-react/src/components/grid/__tests__/CCol.spec.tsx delete mode 100644 packages/coreui-react/src/components/grid/__tests__/CContainer.spec.tsx delete mode 100644 packages/coreui-react/src/components/grid/__tests__/CRow.spec.tsx delete mode 100644 packages/coreui-react/src/components/grid/__tests__/__snapshots__/CCol.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/grid/__tests__/__snapshots__/CContainer.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/grid/__tests__/__snapshots__/CRow.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/grid/index.ts delete mode 100644 packages/coreui-react/src/components/header/CHeader.tsx delete mode 100644 packages/coreui-react/src/components/header/CHeaderBrand.tsx delete mode 100644 packages/coreui-react/src/components/header/CHeaderDivider.tsx delete mode 100644 packages/coreui-react/src/components/header/CHeaderNav.tsx delete mode 100644 packages/coreui-react/src/components/header/CHeaderText.tsx delete mode 100644 packages/coreui-react/src/components/header/CHeaderToggler.tsx delete mode 100644 packages/coreui-react/src/components/header/__tests__/CHeader.spec.tsx delete mode 100644 packages/coreui-react/src/components/header/__tests__/CHeaderBrand.spec.tsx delete mode 100644 packages/coreui-react/src/components/header/__tests__/CHeaderDivider.spec.tsx delete mode 100644 packages/coreui-react/src/components/header/__tests__/CHeaderNav.spec.tsx delete mode 100644 packages/coreui-react/src/components/header/__tests__/CHeaderText.spec.tsx delete mode 100644 packages/coreui-react/src/components/header/__tests__/CHeaderToggler.spec.tsx delete mode 100644 packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeader.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderBrand.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderDivider.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderNav.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderText.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderToggler.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/header/index.ts delete mode 100644 packages/coreui-react/src/components/image/CImage.tsx delete mode 100644 packages/coreui-react/src/components/image/__tests__/CImage.spec.tsx delete mode 100644 packages/coreui-react/src/components/image/__tests__/__snapshots__/CImage.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/image/index.ts delete mode 100644 packages/coreui-react/src/components/index.ts delete mode 100644 packages/coreui-react/src/components/link/CLink.tsx delete mode 100644 packages/coreui-react/src/components/link/__tests__/CLink.spec.tsx delete mode 100644 packages/coreui-react/src/components/link/__tests__/__snapshots__/CLink.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/link/index.ts delete mode 100644 packages/coreui-react/src/components/list-group/CListGroup.tsx delete mode 100644 packages/coreui-react/src/components/list-group/CListGroupItem.tsx delete mode 100644 packages/coreui-react/src/components/list-group/__tests__/CListGroup.spec.tsx delete mode 100644 packages/coreui-react/src/components/list-group/__tests__/CListGroupItem.spec.tsx delete mode 100644 packages/coreui-react/src/components/list-group/__tests__/__snapshots__/CListGroup.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/list-group/__tests__/__snapshots__/CListGroupItem.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/list-group/index.ts delete mode 100644 packages/coreui-react/src/components/modal/CModal.tsx delete mode 100644 packages/coreui-react/src/components/modal/CModalBody.tsx delete mode 100644 packages/coreui-react/src/components/modal/CModalContent.tsx delete mode 100644 packages/coreui-react/src/components/modal/CModalDialog.tsx delete mode 100644 packages/coreui-react/src/components/modal/CModalFooter.tsx delete mode 100644 packages/coreui-react/src/components/modal/CModalHeader.tsx delete mode 100644 packages/coreui-react/src/components/modal/CModalTitle.tsx delete mode 100644 packages/coreui-react/src/components/modal/__tests__/CModal.spec.tsx delete mode 100644 packages/coreui-react/src/components/modal/__tests__/CModalBody.spec.tsx delete mode 100644 packages/coreui-react/src/components/modal/__tests__/CModalContent.spec.tsx delete mode 100644 packages/coreui-react/src/components/modal/__tests__/CModalDialog.spec.tsx delete mode 100644 packages/coreui-react/src/components/modal/__tests__/CModalFooter.spec.tsx delete mode 100644 packages/coreui-react/src/components/modal/__tests__/CModalHeader.spec.tsx delete mode 100644 packages/coreui-react/src/components/modal/__tests__/CModalTitle.spec.tsx delete mode 100644 packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModal.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalBody.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalContent.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalDialog.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalFooter.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalHeader.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalTitle.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/modal/index.ts delete mode 100644 packages/coreui-react/src/components/nav/CNav.tsx delete mode 100644 packages/coreui-react/src/components/nav/CNavGroup.tsx delete mode 100644 packages/coreui-react/src/components/nav/CNavGroupItems.tsx delete mode 100644 packages/coreui-react/src/components/nav/CNavItem.tsx delete mode 100644 packages/coreui-react/src/components/nav/CNavLink.tsx delete mode 100644 packages/coreui-react/src/components/nav/CNavTitle.tsx delete mode 100644 packages/coreui-react/src/components/nav/__tests__/CNav.spec.tsx delete mode 100644 packages/coreui-react/src/components/nav/__tests__/CNavGroup.spec.tsx delete mode 100644 packages/coreui-react/src/components/nav/__tests__/CNavGroupItems.spec.tsx delete mode 100644 packages/coreui-react/src/components/nav/__tests__/CNavItem.spec.tsx delete mode 100644 packages/coreui-react/src/components/nav/__tests__/CNavLink.spec.tsx delete mode 100644 packages/coreui-react/src/components/nav/__tests__/CNavTitle.spec.tsx delete mode 100644 packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNav.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavGroupItems.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavItem.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavLink.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavTitle.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/nav/index.ts delete mode 100644 packages/coreui-react/src/components/navbar/CNavbar.tsx delete mode 100644 packages/coreui-react/src/components/navbar/CNavbarBrand.tsx delete mode 100644 packages/coreui-react/src/components/navbar/CNavbarNav.tsx delete mode 100644 packages/coreui-react/src/components/navbar/CNavbarText.tsx delete mode 100644 packages/coreui-react/src/components/navbar/CNavbarToggler.tsx delete mode 100644 packages/coreui-react/src/components/navbar/__tests__/CNavbar.spec.tsx delete mode 100644 packages/coreui-react/src/components/navbar/__tests__/CNavbarBrand.spec.tsx delete mode 100644 packages/coreui-react/src/components/navbar/__tests__/CNavbarNav.spec.tsx delete mode 100644 packages/coreui-react/src/components/navbar/__tests__/CNavbarText.spec.tsx delete mode 100644 packages/coreui-react/src/components/navbar/__tests__/CNavbarToggler.spec.tsx delete mode 100644 packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbar.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarBrand.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarNav.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarText.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarToggler.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/navbar/index.ts delete mode 100644 packages/coreui-react/src/components/offcanvas/COffcanvas.tsx delete mode 100644 packages/coreui-react/src/components/offcanvas/COffcanvasBody.tsx delete mode 100644 packages/coreui-react/src/components/offcanvas/COffcanvasHeader.tsx delete mode 100644 packages/coreui-react/src/components/offcanvas/COffcanvasTitle.tsx delete mode 100644 packages/coreui-react/src/components/offcanvas/__tests__/COffcanvas.spec.tsx delete mode 100644 packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasBody.spec.tsx delete mode 100644 packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasHeader.spec.tsx delete mode 100644 packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasTitle.spec.tsx delete mode 100644 packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvas.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasBody.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasHeader.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasTitle.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/offcanvas/index.ts delete mode 100644 packages/coreui-react/src/components/pagination/CPagination.tsx delete mode 100644 packages/coreui-react/src/components/pagination/CPaginationItem.tsx delete mode 100644 packages/coreui-react/src/components/pagination/__tests__/CPagination.spec.tsx delete mode 100644 packages/coreui-react/src/components/pagination/__tests__/CPaginationItem.spec.tsx delete mode 100644 packages/coreui-react/src/components/pagination/__tests__/__snapshots__/CPagination.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/pagination/__tests__/__snapshots__/CPaginationItem.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/pagination/index.ts delete mode 100644 packages/coreui-react/src/components/placeholder/CPlaceholder.tsx delete mode 100644 packages/coreui-react/src/components/placeholder/__tests__/CPlaceholder.spec.tsx delete mode 100644 packages/coreui-react/src/components/placeholder/__tests__/__snapshots__/CPlaceholder.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/placeholder/index.ts delete mode 100644 packages/coreui-react/src/components/popover/CPopover.tsx delete mode 100644 packages/coreui-react/src/components/popover/__tests__/CPopover.spec.tsx delete mode 100644 packages/coreui-react/src/components/popover/__tests__/__snapshots__/CPopover.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/popover/index.ts delete mode 100644 packages/coreui-react/src/components/progress/CProgress.tsx delete mode 100644 packages/coreui-react/src/components/progress/CProgressBar.tsx delete mode 100644 packages/coreui-react/src/components/progress/CProgressStacked.tsx delete mode 100644 packages/coreui-react/src/components/progress/__tests__/CProgress.spec.tsx delete mode 100644 packages/coreui-react/src/components/progress/__tests__/CProgressBar.spec.tsx delete mode 100644 packages/coreui-react/src/components/progress/__tests__/__snapshots__/CProgress.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/progress/__tests__/__snapshots__/CProgressBar.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/progress/index.ts delete mode 100644 packages/coreui-react/src/components/sidebar/CSidebar.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/CSidebarBrand.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/CSidebarFooter.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/CSidebarHeader.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/CSidebarNav.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/CSidebarToggler.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/CSidebar.spec.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/CSidebarBrand.spec.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/CSidebarFooter.spec.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/CSidebarHeader.spec.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/CSidebarNav.spec.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/CSidebarToggler.spec.tsx delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebar.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarBrand.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarFooter.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarHeader.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarNav.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarToggler.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/sidebar/index.ts delete mode 100644 packages/coreui-react/src/components/spinner/CSpinner.tsx delete mode 100644 packages/coreui-react/src/components/spinner/__tests__/CSpinner.spec.tsx delete mode 100644 packages/coreui-react/src/components/spinner/__tests__/__snapshots__/CSpinner.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/spinner/index.ts delete mode 100644 packages/coreui-react/src/components/table/CTable.tsx delete mode 100644 packages/coreui-react/src/components/table/CTableBody.tsx delete mode 100644 packages/coreui-react/src/components/table/CTableCaption.tsx delete mode 100644 packages/coreui-react/src/components/table/CTableDataCell.tsx delete mode 100644 packages/coreui-react/src/components/table/CTableFoot.tsx delete mode 100644 packages/coreui-react/src/components/table/CTableHead.tsx delete mode 100644 packages/coreui-react/src/components/table/CTableHeaderCell.tsx delete mode 100644 packages/coreui-react/src/components/table/CTableResponsiveWrapper.tsx delete mode 100644 packages/coreui-react/src/components/table/CTableRow.tsx delete mode 100644 packages/coreui-react/src/components/table/__tests__/CTable.spec.tsx delete mode 100644 packages/coreui-react/src/components/table/__tests__/CTableBody.spec.tsx delete mode 100644 packages/coreui-react/src/components/table/__tests__/CTableCaption.spec.tsx delete mode 100644 packages/coreui-react/src/components/table/__tests__/CTableDataCell.spec.tsx delete mode 100644 packages/coreui-react/src/components/table/__tests__/CTableFoot.spec.tsx delete mode 100644 packages/coreui-react/src/components/table/__tests__/CTableHead.spec.tsx delete mode 100644 packages/coreui-react/src/components/table/__tests__/CTableHeaderCell.spec.tsx delete mode 100644 packages/coreui-react/src/components/table/__tests__/CTableRow.spec.tsx delete mode 100644 packages/coreui-react/src/components/table/__tests__/__snapshots__/CTable.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableBody.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableCaption.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableDataCell.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableFoot.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableHead.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableHeaderCell.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableRow.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/table/index.ts delete mode 100644 packages/coreui-react/src/components/table/types.ts delete mode 100644 packages/coreui-react/src/components/table/utils.ts delete mode 100644 packages/coreui-react/src/components/tabs/CTabContent.tsx delete mode 100644 packages/coreui-react/src/components/tabs/CTabPane.tsx delete mode 100644 packages/coreui-react/src/components/tabs/__tests__/CTabContent.spec.tsx delete mode 100644 packages/coreui-react/src/components/tabs/__tests__/CTabPane.spec.tsx delete mode 100644 packages/coreui-react/src/components/tabs/__tests__/__snapshots__/CTabContent.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/tabs/__tests__/__snapshots__/CTabPane.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/tabs/index.ts delete mode 100644 packages/coreui-react/src/components/toast/CToast.tsx delete mode 100644 packages/coreui-react/src/components/toast/CToastBody.tsx delete mode 100644 packages/coreui-react/src/components/toast/CToastClose.tsx delete mode 100644 packages/coreui-react/src/components/toast/CToastHeader.tsx delete mode 100644 packages/coreui-react/src/components/toast/CToaster.tsx delete mode 100644 packages/coreui-react/src/components/toast/__tests__/CToast.spec.tsx delete mode 100644 packages/coreui-react/src/components/toast/__tests__/CToastBody.spec.tsx delete mode 100644 packages/coreui-react/src/components/toast/__tests__/CToastHeader.spec.tsx delete mode 100644 packages/coreui-react/src/components/toast/__tests__/CToaster.spec.tsx delete mode 100644 packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToast.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToastBody.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToastHeader.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToaster.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/toast/index.ts delete mode 100644 packages/coreui-react/src/components/tooltip/CTooltip.tsx delete mode 100644 packages/coreui-react/src/components/tooltip/__tests__/CTooltip.spec.tsx delete mode 100644 packages/coreui-react/src/components/tooltip/__tests__/__snapshots__/CTooltip.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/tooltip/index.ts delete mode 100644 packages/coreui-react/src/components/widgets/CWidgetStatsA.tsx delete mode 100644 packages/coreui-react/src/components/widgets/CWidgetStatsB.tsx delete mode 100644 packages/coreui-react/src/components/widgets/CWidgetStatsC.tsx delete mode 100644 packages/coreui-react/src/components/widgets/CWidgetStatsD.tsx delete mode 100644 packages/coreui-react/src/components/widgets/CWidgetStatsE.tsx delete mode 100644 packages/coreui-react/src/components/widgets/CWidgetStatsF.tsx delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsA.spec.tsx delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsB.spec.tsx delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsC.spec.tsx delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsD.spec.tsx delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsE.spec.tsx delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsF.spec.tsx delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsA.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsB.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsC.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsD.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsE.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsF.spec.tsx.snap delete mode 100644 packages/coreui-react/src/components/widgets/index.ts delete mode 100644 packages/coreui-react/src/hooks/index.ts delete mode 100644 packages/coreui-react/src/hooks/useColorModes.ts delete mode 100644 packages/coreui-react/src/hooks/useForkedRef.ts delete mode 100644 packages/coreui-react/src/hooks/usePopper.ts delete mode 100644 packages/coreui-react/src/index.ts delete mode 100644 packages/coreui-react/src/props.ts delete mode 100644 packages/coreui-react/src/types.ts delete mode 100644 packages/coreui-react/src/utils/executeAfterTransition.ts delete mode 100644 packages/coreui-react/src/utils/getRTLPlacement.ts delete mode 100644 packages/coreui-react/src/utils/getTransitionDurationFromElement.ts delete mode 100644 packages/coreui-react/src/utils/index.ts delete mode 100644 packages/coreui-react/src/utils/isInViewport.ts delete mode 100644 packages/coreui-react/src/utils/isRTL.ts delete mode 100644 packages/coreui-react/tsconfig.json delete mode 100644 packages/docs/build/api.js delete mode 100644 packages/docs/content/api/CAccordion.api.mdx delete mode 100644 packages/docs/content/api/CAccordionBody.api.mdx delete mode 100644 packages/docs/content/api/CAccordionButton.api.mdx delete mode 100644 packages/docs/content/api/CAccordionCollapse.api.mdx delete mode 100644 packages/docs/content/api/CAccordionHeader.api.mdx delete mode 100644 packages/docs/content/api/CAccordionItem.api.mdx delete mode 100644 packages/docs/content/api/CAlert.api.mdx delete mode 100644 packages/docs/content/api/CAlertHeading.api.mdx delete mode 100644 packages/docs/content/api/CAlertLink.api.mdx delete mode 100644 packages/docs/content/api/CAvatar.api.mdx delete mode 100644 packages/docs/content/api/CBackdrop.api.mdx delete mode 100644 packages/docs/content/api/CBadge.api.mdx delete mode 100644 packages/docs/content/api/CBreadcrumb.api.mdx delete mode 100644 packages/docs/content/api/CBreadcrumbItem.api.mdx delete mode 100644 packages/docs/content/api/CButton.api.mdx delete mode 100644 packages/docs/content/api/CButtonGroup.api.mdx delete mode 100644 packages/docs/content/api/CButtonToolbar.api.mdx delete mode 100644 packages/docs/content/api/CCallout.api.mdx delete mode 100644 packages/docs/content/api/CCard.api.mdx delete mode 100644 packages/docs/content/api/CCardBody.api.mdx delete mode 100644 packages/docs/content/api/CCardFooter.api.mdx delete mode 100644 packages/docs/content/api/CCardGroup.api.mdx delete mode 100644 packages/docs/content/api/CCardHeader.api.mdx delete mode 100644 packages/docs/content/api/CCardImage.api.mdx delete mode 100644 packages/docs/content/api/CCardImageOverlay.api.mdx delete mode 100644 packages/docs/content/api/CCardLink.api.mdx delete mode 100644 packages/docs/content/api/CCardSubtitle.api.mdx delete mode 100644 packages/docs/content/api/CCardText.api.mdx delete mode 100644 packages/docs/content/api/CCardTitle.api.mdx delete mode 100644 packages/docs/content/api/CCarousel.api.mdx delete mode 100644 packages/docs/content/api/CCarouselCaption.api.mdx delete mode 100644 packages/docs/content/api/CCarouselItem.api.mdx delete mode 100644 packages/docs/content/api/CChart.api.mdx delete mode 100644 packages/docs/content/api/CCharts.api.mdx delete mode 100644 packages/docs/content/api/CCloseButton.api.mdx delete mode 100644 packages/docs/content/api/CCol.api.mdx delete mode 100644 packages/docs/content/api/CCollapse.api.mdx delete mode 100644 packages/docs/content/api/CConditionalPortal.api.mdx delete mode 100644 packages/docs/content/api/CContainer.api.mdx delete mode 100644 packages/docs/content/api/CDropdown.api.mdx delete mode 100644 packages/docs/content/api/CDropdownDivider.api.mdx delete mode 100644 packages/docs/content/api/CDropdownHeader.api.mdx delete mode 100644 packages/docs/content/api/CDropdownItem.api.mdx delete mode 100644 packages/docs/content/api/CDropdownItemPlain.api.mdx delete mode 100644 packages/docs/content/api/CDropdownMenu.api.mdx delete mode 100644 packages/docs/content/api/CDropdownToggle.api.mdx delete mode 100644 packages/docs/content/api/CFooter.api.mdx delete mode 100644 packages/docs/content/api/CForm.api.mdx delete mode 100644 packages/docs/content/api/CFormCheck.api.mdx delete mode 100644 packages/docs/content/api/CFormControlValidation.api.mdx delete mode 100644 packages/docs/content/api/CFormControlWrapper.api.mdx delete mode 100644 packages/docs/content/api/CFormFeedback.api.mdx delete mode 100644 packages/docs/content/api/CFormFloating.api.mdx delete mode 100644 packages/docs/content/api/CFormInput.api.mdx delete mode 100644 packages/docs/content/api/CFormLabel.api.mdx delete mode 100644 packages/docs/content/api/CFormRange.api.mdx delete mode 100644 packages/docs/content/api/CFormSelect.api.mdx delete mode 100644 packages/docs/content/api/CFormSwitch.api.mdx delete mode 100644 packages/docs/content/api/CFormText.api.mdx delete mode 100644 packages/docs/content/api/CFormTextarea.api.mdx delete mode 100644 packages/docs/content/api/CHeader.api.mdx delete mode 100644 packages/docs/content/api/CHeaderBrand.api.mdx delete mode 100644 packages/docs/content/api/CHeaderDivider.api.mdx delete mode 100644 packages/docs/content/api/CHeaderNav.api.mdx delete mode 100644 packages/docs/content/api/CHeaderText.api.mdx delete mode 100644 packages/docs/content/api/CHeaderToggler.api.mdx delete mode 100644 packages/docs/content/api/CIcon.api.mdx delete mode 100644 packages/docs/content/api/CImage.api.mdx delete mode 100644 packages/docs/content/api/CInputGroup.api.mdx delete mode 100644 packages/docs/content/api/CInputGroupText.api.mdx delete mode 100644 packages/docs/content/api/CLink.api.mdx delete mode 100644 packages/docs/content/api/CListGroup.api.mdx delete mode 100644 packages/docs/content/api/CListGroupItem.api.mdx delete mode 100644 packages/docs/content/api/CModal.api.mdx delete mode 100644 packages/docs/content/api/CModalBody.api.mdx delete mode 100644 packages/docs/content/api/CModalContent.api.mdx delete mode 100644 packages/docs/content/api/CModalDialog.api.mdx delete mode 100644 packages/docs/content/api/CModalFooter.api.mdx delete mode 100644 packages/docs/content/api/CModalHeader.api.mdx delete mode 100644 packages/docs/content/api/CModalTitle.api.mdx delete mode 100644 packages/docs/content/api/CNav.api.mdx delete mode 100644 packages/docs/content/api/CNavGroup.api.mdx delete mode 100644 packages/docs/content/api/CNavGroupItems.api.mdx delete mode 100644 packages/docs/content/api/CNavItem.api.mdx delete mode 100644 packages/docs/content/api/CNavLink.api.mdx delete mode 100644 packages/docs/content/api/CNavTitle.api.mdx delete mode 100644 packages/docs/content/api/CNavbar.api.mdx delete mode 100644 packages/docs/content/api/CNavbarBrand.api.mdx delete mode 100644 packages/docs/content/api/CNavbarNav.api.mdx delete mode 100644 packages/docs/content/api/CNavbarText.api.mdx delete mode 100644 packages/docs/content/api/CNavbarToggler.api.mdx delete mode 100644 packages/docs/content/api/COffcanvas.api.mdx delete mode 100644 packages/docs/content/api/COffcanvasBody.api.mdx delete mode 100644 packages/docs/content/api/COffcanvasHeader.api.mdx delete mode 100644 packages/docs/content/api/COffcanvasTitle.api.mdx delete mode 100644 packages/docs/content/api/CPagination.api.mdx delete mode 100644 packages/docs/content/api/CPaginationItem.api.mdx delete mode 100644 packages/docs/content/api/CPlaceholder.api.mdx delete mode 100644 packages/docs/content/api/CPopover.api.mdx delete mode 100644 packages/docs/content/api/CProgress.api.mdx delete mode 100644 packages/docs/content/api/CProgressBar.api.mdx delete mode 100644 packages/docs/content/api/CProgressStacked.api.mdx delete mode 100644 packages/docs/content/api/CRow.api.mdx delete mode 100644 packages/docs/content/api/CSidebar.api.mdx delete mode 100644 packages/docs/content/api/CSidebarBrand.api.mdx delete mode 100644 packages/docs/content/api/CSidebarFooter.api.mdx delete mode 100644 packages/docs/content/api/CSidebarHeader.api.mdx delete mode 100644 packages/docs/content/api/CSidebarNav.api.mdx delete mode 100644 packages/docs/content/api/CSidebarToggler.api.mdx delete mode 100644 packages/docs/content/api/CSpinner.api.mdx delete mode 100644 packages/docs/content/api/CTabContent.api.mdx delete mode 100644 packages/docs/content/api/CTabPane.api.mdx delete mode 100644 packages/docs/content/api/CTable.api.mdx delete mode 100644 packages/docs/content/api/CTableBody.api.mdx delete mode 100644 packages/docs/content/api/CTableCaption.api.mdx delete mode 100644 packages/docs/content/api/CTableDataCell.api.mdx delete mode 100644 packages/docs/content/api/CTableFoot.api.mdx delete mode 100644 packages/docs/content/api/CTableHead.api.mdx delete mode 100644 packages/docs/content/api/CTableHeaderCell.api.mdx delete mode 100644 packages/docs/content/api/CTableResponsiveWrapper.api.mdx delete mode 100644 packages/docs/content/api/CTableRow.api.mdx delete mode 100644 packages/docs/content/api/CToast.api.mdx delete mode 100644 packages/docs/content/api/CToastBody.api.mdx delete mode 100644 packages/docs/content/api/CToastClose.api.mdx delete mode 100644 packages/docs/content/api/CToastHeader.api.mdx delete mode 100644 packages/docs/content/api/CToaster.api.mdx delete mode 100644 packages/docs/content/api/CTooltip.api.mdx delete mode 100644 packages/docs/content/api/CWidgetStatsA.api.mdx delete mode 100644 packages/docs/content/api/CWidgetStatsB.api.mdx delete mode 100644 packages/docs/content/api/CWidgetStatsC.api.mdx delete mode 100644 packages/docs/content/api/CWidgetStatsD.api.mdx delete mode 100644 packages/docs/content/api/CWidgetStatsE.api.mdx delete mode 100644 packages/docs/content/api/CWidgetStatsF.api.mdx delete mode 100644 packages/docs/content/assets/images/brand/coreui-signet.svg delete mode 100644 packages/docs/content/assets/images/react400.jpg delete mode 100644 packages/docs/content/components/accordion.mdx delete mode 100644 packages/docs/content/components/alert.mdx delete mode 100644 packages/docs/content/components/avatar.mdx delete mode 100644 packages/docs/content/components/badge.mdx delete mode 100644 packages/docs/content/components/breadcrumb.mdx delete mode 100644 packages/docs/content/components/button-group.mdx delete mode 100644 packages/docs/content/components/button.mdx delete mode 100644 packages/docs/content/components/callout.mdx delete mode 100644 packages/docs/content/components/card.mdx delete mode 100644 packages/docs/content/components/carousel.mdx delete mode 100644 packages/docs/content/components/chart.mdx delete mode 100644 packages/docs/content/components/close-button.mdx delete mode 100644 packages/docs/content/components/collapse.mdx delete mode 100644 packages/docs/content/components/dropdown.mdx delete mode 100644 packages/docs/content/components/footer.mdx delete mode 100644 packages/docs/content/components/header.mdx delete mode 100644 packages/docs/content/components/icon.mdx delete mode 100644 packages/docs/content/components/image.mdx delete mode 100644 packages/docs/content/components/list-group.mdx delete mode 100644 packages/docs/content/components/modal.mdx delete mode 100644 packages/docs/content/components/navbar.mdx delete mode 100644 packages/docs/content/components/navs-tabs.mdx delete mode 100644 packages/docs/content/components/offcanvas.mdx delete mode 100644 packages/docs/content/components/pagination.mdx delete mode 100644 packages/docs/content/components/placeholder.mdx delete mode 100644 packages/docs/content/components/popover.mdx delete mode 100644 packages/docs/content/components/progress.mdx delete mode 100644 packages/docs/content/components/sidebar.mdx delete mode 100644 packages/docs/content/components/spinner.mdx delete mode 100644 packages/docs/content/components/table.mdx delete mode 100644 packages/docs/content/components/toast.mdx delete mode 100644 packages/docs/content/components/tooltip.mdx delete mode 100644 packages/docs/content/components/widgets.mdx delete mode 100644 packages/docs/content/customize/css-variables.mdx delete mode 100644 packages/docs/content/customize/options.mdx delete mode 100644 packages/docs/content/customize/sass.mdx delete mode 100644 packages/docs/content/forms/checkbox.mdx delete mode 100644 packages/docs/content/forms/checks-radios.mdx delete mode 100644 packages/docs/content/forms/floating-labels.mdx delete mode 100644 packages/docs/content/forms/form-control.mdx delete mode 100644 packages/docs/content/forms/input-group.mdx delete mode 100644 packages/docs/content/forms/input-mask.mdx delete mode 100644 packages/docs/content/forms/input.mdx delete mode 100644 packages/docs/content/forms/layout.mdx delete mode 100644 packages/docs/content/forms/overview.mdx delete mode 100644 packages/docs/content/forms/radio.mdx delete mode 100644 packages/docs/content/forms/range.mdx delete mode 100644 packages/docs/content/forms/select.mdx delete mode 100644 packages/docs/content/forms/switch.mdx delete mode 100644 packages/docs/content/forms/textarea.mdx delete mode 100644 packages/docs/content/forms/validation.mdx delete mode 100644 packages/docs/content/getting-started/accessibility.mdx delete mode 100644 packages/docs/content/getting-started/introduction.mdx delete mode 100644 packages/docs/content/layout/breakpoints.mdx delete mode 100644 packages/docs/content/layout/columns.mdx delete mode 100644 packages/docs/content/layout/containers.mdx delete mode 100644 packages/docs/content/layout/grid.mdx delete mode 100644 packages/docs/content/layout/gutters.mdx delete mode 100644 packages/docs/content/migration/v4.mdx delete mode 100644 packages/docs/content/migration/v5.mdx delete mode 100644 packages/docs/content/templates/admin-dashboard.mdx delete mode 100644 packages/docs/content/templates/contents.mdx delete mode 100644 packages/docs/content/templates/customize.mdx delete mode 100644 packages/docs/content/templates/download.mdx delete mode 100644 packages/docs/content/templates/installation.mdx delete mode 100644 packages/docs/gatsby-browser.js delete mode 100644 packages/docs/gatsby-config.js delete mode 100644 packages/docs/gatsby-node.js delete mode 100644 packages/docs/gatsby-ssr.js delete mode 100644 packages/docs/package.json delete mode 100644 packages/docs/src/AppContext.tsx delete mode 100755 packages/docs/src/assets/coreui-react.svg delete mode 100644 packages/docs/src/assets/images/brand/icon.png delete mode 100644 packages/docs/src/components/Ads.tsx delete mode 100644 packages/docs/src/components/Banner.tsx delete mode 100644 packages/docs/src/components/Callout.tsx delete mode 100644 packages/docs/src/components/CodeBlock.tsx delete mode 100644 packages/docs/src/components/Example.tsx delete mode 100644 packages/docs/src/components/Footer.tsx delete mode 100644 packages/docs/src/components/Header.tsx delete mode 100644 packages/docs/src/components/ScssDocs.tsx delete mode 100644 packages/docs/src/components/Seo.tsx delete mode 100644 packages/docs/src/components/Sidebar.tsx delete mode 100644 packages/docs/src/components/SidebarNav.tsx delete mode 100644 packages/docs/src/components/Toc.tsx delete mode 100644 packages/docs/src/components/index.ts delete mode 100644 packages/docs/src/data/other_frameworks.json delete mode 100644 packages/docs/src/images/gatsby-astronaut.png delete mode 100644 packages/docs/src/images/gatsby-icon.png delete mode 100644 packages/docs/src/index.ts delete mode 100644 packages/docs/src/nav.tsx delete mode 100644 packages/docs/src/pages/404.tsx delete mode 100644 packages/docs/src/styles/_ads.scss delete mode 100644 packages/docs/src/styles/_anchor.scss delete mode 100644 packages/docs/src/styles/_callouts.scss delete mode 100644 packages/docs/src/styles/_component-examples.scss delete mode 100644 packages/docs/src/styles/_footer.scss delete mode 100644 packages/docs/src/styles/_prism.scss delete mode 100644 packages/docs/src/styles/_scrolling.scss delete mode 100644 packages/docs/src/styles/_search.scss delete mode 100644 packages/docs/src/styles/_sidebar.scss delete mode 100644 packages/docs/src/styles/_table-api.scss delete mode 100644 packages/docs/src/styles/_toc.scss delete mode 100644 packages/docs/src/styles/_variables.scss delete mode 100644 packages/docs/src/styles/styles.scss delete mode 100644 packages/docs/src/templates/DefaultLayout.tsx delete mode 100644 packages/docs/src/templates/DocsLayout.tsx delete mode 100644 packages/docs/src/templates/MdxLayout.tsx delete mode 100644 packages/docs/static/index.html delete mode 100755 packages/gatsby-remark-import-markdown/index.js delete mode 100644 packages/gatsby-remark-import-markdown/package.json delete mode 100755 packages/gatsby-remark-jsx-preview/index.js delete mode 100644 packages/gatsby-remark-jsx-preview/package.json create mode 100644 src/App.js create mode 100644 src/App.test.js create mode 100644 src/_nav.js create mode 100644 src/assets/brand/logo-negative.js create mode 100644 src/assets/brand/logo.js create mode 100644 src/assets/brand/sygnet.js rename {packages/docs/content => src}/assets/images/angular.jpg (100%) rename {packages/docs/content => src}/assets/images/avatars/1.jpg (100%) rename {packages/docs/content => src}/assets/images/avatars/2.jpg (100%) rename {packages/docs/content => src}/assets/images/avatars/3.jpg (100%) rename {packages/docs/content => src}/assets/images/avatars/4.jpg (100%) rename {packages/docs/content => src}/assets/images/avatars/5.jpg (100%) rename {packages/docs/content => src}/assets/images/avatars/6.jpg (100%) rename {packages/docs/content => src}/assets/images/avatars/7.jpg (100%) rename {packages/docs/content => src}/assets/images/avatars/8.jpg (100%) rename {packages/docs/content => src}/assets/images/avatars/9.jpg (100%) rename {packages/docs/content => src}/assets/images/react.jpg (100%) rename {packages/docs/content => src}/assets/images/vue.jpg (100%) create mode 100644 src/components/AppBreadcrumb.js create mode 100644 src/components/AppContent.js create mode 100644 src/components/AppFooter.js create mode 100644 src/components/AppHeader.js create mode 100644 src/components/AppSidebar.js create mode 100644 src/components/AppSidebarNav.js create mode 100644 src/components/DocsCallout.js create mode 100644 src/components/DocsExample.js create mode 100644 src/components/DocsLink.js create mode 100644 src/components/header/AppHeaderDropdown.js create mode 100644 src/components/header/index.js create mode 100644 src/components/index.js create mode 100644 src/index.js create mode 100644 src/layout/DefaultLayout.js create mode 100644 src/reportWebVitals.js create mode 100644 src/routes.js create mode 100644 src/scss/_custom.scss create mode 100644 src/scss/_example.scss rename {packages/docs/src/styles => src/scss}/_layout.scss (100%) create mode 100644 src/scss/_variables.scss create mode 100644 src/scss/style.scss create mode 100644 src/setupTests.js create mode 100644 src/store.js create mode 100644 src/views/base/accordion/Accordion.js create mode 100644 src/views/base/breadcrumbs/Breadcrumbs.js create mode 100644 src/views/base/cards/Cards.js create mode 100644 src/views/base/carousels/Carousels.js create mode 100644 src/views/base/collapses/Collapses.js create mode 100644 src/views/base/index.js create mode 100644 src/views/base/jumbotrons/Jumbotrons.js create mode 100644 src/views/base/list-groups/ListGroups.js create mode 100644 src/views/base/navbars/Navbars.js create mode 100644 src/views/base/navs/Navs.js create mode 100644 src/views/base/paginations/Paginations.js create mode 100644 src/views/base/placeholders/Placeholders.js create mode 100644 src/views/base/popovers/Popovers.js create mode 100644 src/views/base/progress/Progress.js create mode 100644 src/views/base/spinners/Spinners.js create mode 100644 src/views/base/tables/Tables.js create mode 100644 src/views/base/tooltips/Tooltips.js create mode 100644 src/views/buttons/button-groups/ButtonGroups.js create mode 100644 src/views/buttons/buttons/Buttons.js create mode 100644 src/views/buttons/dropdowns/Dropdowns.js create mode 100644 src/views/buttons/index.js create mode 100644 src/views/charts/Charts.js create mode 100644 src/views/dashboard/Dashboard.js create mode 100644 src/views/forms/checks-radios/ChecksRadios.js create mode 100644 src/views/forms/floating-labels/FloatingLabels.js create mode 100644 src/views/forms/form-control/FormControl.js create mode 100644 src/views/forms/input-group/InputGroup.js create mode 100644 src/views/forms/layout/Layout.js create mode 100644 src/views/forms/range/Range.js create mode 100644 src/views/forms/select/Select.js create mode 100644 src/views/forms/validation/Validation.js create mode 100644 src/views/icons/brands/Brands.js create mode 100644 src/views/icons/coreui-icons/CoreUIIcons.js create mode 100644 src/views/icons/flags/Flags.js create mode 100644 src/views/icons/index.js create mode 100644 src/views/notifications/alerts/Alerts.js create mode 100644 src/views/notifications/badges/Badges.js create mode 100644 src/views/notifications/index.js create mode 100644 src/views/notifications/modals/Modals.js create mode 100644 src/views/notifications/toasts/Toasts.js create mode 100644 src/views/pages/login/Login.js create mode 100644 src/views/pages/page404/Page404.js create mode 100644 src/views/pages/page500/Page500.js create mode 100644 src/views/pages/register/Register.js create mode 100644 src/views/theme/colors/Colors.js create mode 100644 src/views/theme/typography/Typography.js create mode 100644 src/views/widgets/Widgets.js create mode 100644 src/views/widgets/WidgetsBrand.js create mode 100644 src/views/widgets/WidgetsDropdown.js delete mode 100644 tsconfig.json diff --git a/LICENSE b/LICENSE index 027b8813..b4870dd9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -MIT License +The MIT License (MIT) -Copyright (c) 2023 creativeLabs Łukasz Holeczek +Copyright (c) 2023 creativeLabs Łukasz Holeczek. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -9,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/packages/coreui-react/jest.config.js b/jest.config.js similarity index 64% rename from packages/coreui-react/jest.config.js rename to jest.config.js index f3aed54d..abf16ab9 100644 --- a/packages/coreui-react/jest.config.js +++ b/jest.config.js @@ -8,7 +8,10 @@ 'use strict' module.exports = { - preset: 'ts-jest', - testEnvironment: 'jsdom', - testPathIgnorePatterns: ['dist/'], + collectCoverageFrom: [ + 'src/**/*.{js,jsx}', + '!**/*index.js', + '!src/serviceWorker.js', + '!src/polyfill.js', + ], } diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 00000000..63f923e4 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "baseUrl": "." + }, + "include": ["src"] +} \ No newline at end of file diff --git a/lerna.json b/lerna.json deleted file mode 100644 index 7aa00b6e..00000000 --- a/lerna.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "npmClient": "yarn", - "packages": ["packages/*"], - "version": "5.0.0-rc.0", - "$schema": "node_modules/lerna/schemas/lerna-schema.json" -} diff --git a/migration.md b/migration.md new file mode 100644 index 00000000..11a3528f --- /dev/null +++ b/migration.md @@ -0,0 +1,3 @@ +# Migration from version 3 + +https://coreui.io/react/docs/4.0/migration/v4/ diff --git a/package.json b/package.json index 79b53bf8..0dc80f3b 100644 --- a/package.json +++ b/package.json @@ -1,45 +1,71 @@ { - "private": true, - "workspaces": [ - "packages/*" - ], + "name": "@coreui/coreui-free-react-admin-template", + "version": "4.5.0", + "description": "CoreUI Free React Admin Template", + "homepage": ".", + "bugs": { + "url": "https://github.com/coreui/coreui-free-react-admin-template/issues" + }, + "repository": { + "type": "git", + "url": "git@github.com:coreui/coreui-free-react-admin-template.git" + }, + "license": "MIT", + "author": "The CoreUI Team (https://github.com/orgs/coreui/people)", "scripts": { - "charts:build": "lerna run --scope \"@coreui/react-chartjs\" build --stream", - "charts:test": "lerna run --scope \"@coreui/react-chartjs\" test --stream", - "charts:test:update": "lerna run --scope \"@coreui/react-chartjs\" test:update --stream", - "docs:api": "lerna run --scope \"@coreui/react-docs\" api --stream", - "docs:dev": "lerna run --scope \"@coreui/react-docs\" develop --stream", - "docs:build": "lerna run --scope \"@coreui/react-docs\" build --stream", - "docs:clean": "lerna run --scope \"@coreui/react-docs\" clean", - "icons:build": "lerna run --scope \"@coreui/icons-react\" build --stream", - "icons:test": "lerna run --scope \"@coreui/icons-react\" test --stream", - "icons:test:update": "lerna run --scope \"@coreui/icons-react\" test:update --stream", - "lib:build": "lerna run --scope \"@coreui/react\" build --stream", - "lib:test": "lerna run --scope \"@coreui/react\" test --stream", - "lib:test:update": "lerna run --scope \"@coreui/react\" test:update --stream", - "lint": "eslint \"packages/**/src/**/*.{js,ts,tsx}\"", - "test": "npm-run-all charts:test icons:test lib:test", - "test:update": "npm-run-all charts:test:update icons:test:update lib:test:update" + "build": "react-scripts build", + "eject": "react-scripts eject", + "lint": "eslint \"src/**/*.js\"", + "start": "react-scripts start", + "test": "react-scripts test", + "test:cov": "npm test -- --coverage --watchAll=false", + "test:debug": "react-scripts --inspect-brk test --runInBand" + }, + "dependencies": { + "@coreui/chartjs": "^3.1.2", + "@coreui/coreui": "^4.2.6", + "@coreui/icons": "^3.0.1", + "@coreui/icons-react": "^2.1.0", + "@coreui/react": "^4.9.0-rc.0", + "@coreui/react-chartjs": "^2.1.3", + "@coreui/utils": "^2.0.2", + "chart.js": "^3.9.1", + "classnames": "^2.3.2", + "core-js": "^3.31.0", + "prop-types": "^15.8.1", + "react": "^18.2.0", + "react-app-polyfill": "^3.0.0", + "react-dom": "^18.2.0", + "react-redux": "^8.1.1", + "react-router-dom": "^6.14.0", + "redux": "4.2.1", + "simplebar-react": "^2.4.3" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^6.11.0", - "@typescript-eslint/parser": "^6.11.0", - "eslint": "8.53.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-prettier": "^5.0.1", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-unicorn": "^49.0.0", - "lerna": "^7.4.2", - "npm-run-all": "^4.1.5", - "prettier": "^3.1.0" + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^14.0.0", + "@testing-library/user-event": "^14.4.3", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-prettier": "^4.2.1", + "prettier": "2.8.8", + "react-scripts": "5.0.1", + "sass": "^1.63.6", + "web-vitals": "^3.3.2" }, - "overrides": { - "gatsby-remark-external-links": { - "unist-util-find": "1.0.2" - } + "engines": { + "node": ">=10", + "npm": ">=6" }, - "resolutions": { - "**/gatsby-remark-external-links/unist-util-find": "1.0.2" + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] } } diff --git a/packages/coreui-icons-react b/packages/coreui-icons-react deleted file mode 160000 index 6c88b4ed..00000000 --- a/packages/coreui-icons-react +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6c88b4ed928e99a6a3358bcbcab82b5049774de8 diff --git a/packages/coreui-react-chartjs b/packages/coreui-react-chartjs deleted file mode 160000 index d49b6340..00000000 --- a/packages/coreui-react-chartjs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d49b6340fa630265af7e1377b5f086f172a73529 diff --git a/packages/coreui-react/LICENSE b/packages/coreui-react/LICENSE deleted file mode 100644 index 027b8813..00000000 --- a/packages/coreui-react/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 creativeLabs Łukasz Holeczek - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/coreui-react/README.md b/packages/coreui-react/README.md deleted file mode 100644 index aac91c84..00000000 --- a/packages/coreui-react/README.md +++ /dev/null @@ -1,261 +0,0 @@ -<p align="center"> - <a href="https://coreui.io/"> - <img - src="https://coreui.io/images/brand/coreui-signet.svg" - alt="CoreUI logo" - width="200" - /> - </a> -</p> - -<h3 align="center">CoreUI for React.js</h3> - -<p align="center"> - React.js Components Library built on top of Bootstrap 5 and TypeScript. - <br> - <a href="https://coreui.io/react/docs/getting-started/introduction"><strong>Explore CoreUI for React.js docs »</strong></a> - <br> - <br> - <a href="https://github.com/coreui/coreui-react/issues/new?template=bug_report.md">Report bug</a> - · - <a href="https://github.com/coreui/coreui-react/issues/new?template=feature_request.md">Request feature</a> - · - <a href="https://coreui.io/blog/">Blog</a> -</p> - - -## Table of contents - -- [Quick start](#quick-start) -- [Components](#components) -- [Status](#status) -- [Bugs and feature requests](#bugs-and-feature-requests) -- [Documentation](#documentation) -- [Frameworks](#frameworks) -- [Templates](#templates) -- [Contributing](#contributing) -- [Community](#community) -- [Versioning](#versioning) -- [Creators](#creators) -- [Support CoreUI Development](#support-coreui-development) -- [Copyright and license](#copyright-and-license) - -## Quick start - -### Instalation - -Several quick start options are available: - -- [Download the latest release](https://github.com/coreui/coreui-react/archive/v5.0.0-rc.0.zip) -- Clone the repo: `git clone https://github.com/coreui/coreui-react.git` -- Install with [npm](https://www.npmjs.com/): `npm install @coreui/react` -- Install with [yarn](https://yarnpkg.com/): `yarn add @coreui/react` - -Read the [Getting started page](https://coreui.io/react/docs/getting-started/introduction/) for information on the framework contents, templates and examples, and more. - -### Stylesheets - -React components are styled using `@coreui/coreui` CSS library, but you can use them also with bootstrap CSS library. That is possible because `@coreui/coreui` library is compatible with bootstrap, it just extends its functionalities. The only exception are custom CoreUI components, which don't exist in the Bootstrap ecosystem. - -#### CoreUI CSS files - -##### Installation - -```bash -yarn add @coreui/coreui -``` - -or - -```bash -npm install @coreui/coreui --save -``` - -##### Basic usage - -```js -import '@coreui/coreui/dist/css/coreui.min.css' -``` - -#### Bootstrap CSS files - -##### Installation - -```bash -yarn add bootstrap -``` - -or - -```bash -npm install bootstrap -``` - -##### Basic usage - -```js -import "bootstrap/dist/css/bootstrap.min.css"; -``` - -## Components - -- [React Accordion](https://coreui.io/react/docs/components/accordion/) -- [React Alert](https://coreui.io/react/docs/components/alert/) -- [React Avatar](https://coreui.io/react/docs/components/avatar/) -- [React Badge](https://coreui.io/react/docs/components/badge/) -- [React Breadcrumb](https://coreui.io/react/docs/components/breadcrumb/) -- [React Button](https://coreui.io/react/docs/components/button/) -- [React Button Group](https://coreui.io/react/docs/components/button-group/) -- [React Callout](https://coreui.io/react/docs/components/callout/) -- [React Card](https://coreui.io/react/docs/components/card/) -- [React Carousel](https://coreui.io/react/docs/components/carousel/) -- [React Checkbox](https://coreui.io/react/docs/forms/checkbox/) -- [React Close Button](https://coreui.io/react/docs/components/close-button/) -- [React Collapse](https://coreui.io/react/docs/components/collapse/) -- [React Date Picker](https://coreui.io/react/docs/forms/date-picker/) **PRO** -- [React Date Range Picker](https://coreui.io/react/docs/forms/date-range-picker/) **PRO** -- [React Dropdown](https://coreui.io/react/docs/components/dropdown/) -- [React Floating Labels](https://coreui.io/react/docs/forms/floating-labels/) -- [React Footer](https://coreui.io/react/docs/components/footer/) -- [React Header](https://coreui.io/react/docs/components/header/) -- [React Image](https://coreui.io/react/docs/components/image/) -- [React Input](https://coreui.io/react/docs/forms/input/) -- [React Input Group](https://coreui.io/react/docs/forms/input-group/) -- [React List Group](https://coreui.io/react/docs/components/list-group/) -- [React Loading Button](https://coreui.io/react/docs/components/loading-button/) **PRO** -- [React Modal](https://coreui.io/react/docs/components/modal/) -- [React Multi Select](https://coreui.io/react/docs/forms/multi-select/) **PRO** -- [React Navs & Tabs](https://coreui.io/react/docs/components/navs-tabs/) -- [React Navbar](https://coreui.io/react/docs/components/navbar/) -- [React Offcanvas](https://coreui.io/react/docs/components/offcanvas/) -- [React Pagination](https://coreui.io/react/docs/components/pagination/) -- [React Placeholder](https://coreui.io/react/docs/components/placeholder/) -- [React Popover](https://coreui.io/react/docs/components/popover/) -- [React Progress](https://coreui.io/react/docs/components/progress/) -- [React Radio](https://coreui.io/react/docs/forms/radio/) -- [React Range](https://coreui.io/react/docs/forms/range/) -- [React Select](https://coreui.io/react/docs/forms/select/) -- [React Sidebar](https://coreui.io/react/docs/components/sidebar/) -- [React Smart Pagination](https://coreui.io/react/docs/components/smart-pagination/) **PRO** -- [React Smart Table](https://coreui.io/react/docs/components/smart-table/) **PRO** -- [React Spinner](https://coreui.io/react/docs/components/spinner/) -- [React Switch](https://coreui.io/react/docs/forms/switch/) -- [React Table](https://coreui.io/react/docs/components/table/) -- [React Textarea](https://coreui.io/react/docs/forms/textarea/) -- [React Time Picker](https://coreui.io/react/docs/forms/time-picker/) **PRO** -- [React Toast](https://coreui.io/react/docs/components/toast/) -- [React Tooltip](https://coreui.io/react/docs/components/tooltip/) - -## Status - -[](https://www.npmjs.com/package/@coreui/react) - -## Bugs and feature requests - -Have a bug or a feature request? Please first read the [issue guidelines](https://github.com/coreui/coreui-react/blob/v4/.github/CONTRIBUTING.md#using-the-issue-tracker) and search for existing and closed issues. If your problem or idea is not addressed yet, [please open a new issue](https://github.com/coreui/coreui-react/issues/new). - -## Documentation - -The documentation for the CoreUI & CoreUI PRO is hosted at our website [CoreUI for React](https://coreui.io/react/docs/getting-started/introduction) - -### Running documentation locally - -1. Run `yarn install` or `npm install` to install the Node.js dependencies. -2. Run `yarn bootstrap` or `npm run bootstrap` to link local packages together and install remaining package dependencies. -3. From the root directory, run `yarn docs:dev` or `npm run docs:dev` (or a specific npm script) to rebuild distributed CSS and JavaScript files, as well as our docs assets. -4. Open `http://localhost:8000/` in your browser, and voilà. - -## Frameworks - -CoreUI supports most popular frameworks. - -- [CoreUI for Angular](https://github.com/coreui/coreui-angular) -- [CoreUI for Bootstrap (Vanilla JS)](https://github.com/coreui/coreui) -- [CoreUI for React](https://github.com/coreui/coreui-react) -- [CoreUI for Vue](https://github.com/coreui/coreui-vue) - -## Templates - -Fully featured, out-of-the-box, templates for your application based on CoreUI. - -- [Angular Admin Template](https://coreui.io/angular) -- [Bootstrap Admin Template](https://coreui.io/) -- [React Admin Template](https://coreui.io/react) -- [Vue Admin Template](https://coreui.io/vue) - -## Contributing - -Please read through our [contributing guidelines](https://github.com/coreui/coreui-react/blob/v4/.github/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development. - -Editor preferences are available in the [editor config](https://github.com/coreui/coreui-react/blob/v4/.editorconfig) for easy use in common text editors. Read more and download plugins at <https://editorconfig.org/>. - -## Community - -Stay up to date on the development of CoreUI and reach out to the community with these helpful resources. - -- Read and subscribe to [The Official CoreUI Blog](https://coreui.io/blog/). - -You can also follow [@core_ui on Twitter](https://twitter.com/core_ui). - -## Versioning - -For transparency into our release cycle and in striving to maintain backward compatibility, CoreUI is maintained under [the Semantic Versioning guidelines](http://semver.org/). - -See [the Releases section of our project](https://github.com/coreui/coreui-react/releases) for changelogs for each release version. - -## Creators - -**Łukasz Holeczek** - -- <https://twitter.com/lukaszholeczek> -- <https://github.com/mrholek> - -**Andrzej Kopański** - -- <https://github.com/xidedix> - -**The CoreUI Team** - -- <https://github.com/orgs/coreui/people> - -## Support CoreUI Development - -CoreUI is an MIT-licensed open source project and is completely free to use. However, the amount of effort needed to maintain and develop new features for the project is not sustainable without proper financial backing. You can support development by buying the [CoreUI PRO](https://coreui.io/pricing/) or by becoming a sponsor via [Open Collective](https://opencollective.com/coreui/). - -<!--- StartOpenCollectiveBackers --> - -### Platinum Sponsors - -Support this project by [becoming a Platinum Sponsor](https://opencollective.com/coreui/contribute/platinum-sponsor-40959/). A large company logo will be added here with a link to your website. - -<a href="https://opencollective.com/coreui/contribute/platinum-sponsor-40959/checkout"><img src="https://opencollective.com/coreui/tiers/platinum-sponsor/0/avatar.svg?avatarHeight=100"></a> - -### Gold Sponsors - -Support this project by [becoming a Gold Sponsor](https://opencollective.com/coreui/contribute/gold-sponsor-40960/). A big company logo will be added here with a link to your website. - -<a href="https://opencollective.com/coreui/contribute/gold-sponsor-40960/checkout"><img src="https://opencollective.com/coreui/tiers/gold-sponsor/0/avatar.svg?avatarHeight=100"></a> - -### Silver Sponsors - -Support this project by [becoming a Silver Sponsor](https://opencollective.com/coreui/contribute/silver-sponsor-40967/). A medium company logo will be added here with a link to your website. - -<a href="https://opencollective.com/coreui/contribute/silver-sponsor-40967/checkout"><img src="https://opencollective.com/coreui/tiers/gold-sponsor/0/avatar.svg?avatarHeight=100"></a> - -### Bronze Sponsors - -Support this project by [becoming a Bronze Sponsor](https://opencollective.com/coreui/contribute/bronze-sponsor-40966/). The company avatar will show up here with a link to your OpenCollective Profile. - -<a href="https://opencollective.com/coreui/contribute/bronze-sponsor-40966/checkout"><img src="https://opencollective.com/coreui/tiers/bronze-sponsor/0/avatar.svg?avatarHeight=100"></a> - -### Backers - -Thanks to all the backers and sponsors! Support this project by [becoming a backer](https://opencollective.com/coreui/contribute/backer-40965/). - -<a href="https://opencollective.com/coreui/contribute/backer-40965/checkout" target="_blank" rel="noopener"><img src="https://opencollective.com/coreui/backers.svg?width=890"></a> - -<!--- EndOpenCollectiveBackers --> - -## Copyright and license - -Copyright 2023 creativeLabs Łukasz Holeczek. Code released under the [MIT License](https://github.com/coreui/coreui-react/blob/main/LICENSE). Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/). diff --git a/packages/coreui-react/package.json b/packages/coreui-react/package.json deleted file mode 100644 index 79597dff..00000000 --- a/packages/coreui-react/package.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "name": "@coreui/react", - "version": "5.0.0-rc.0", - "description": "UI Components Library for React.js", - "keywords": [ - "react", - "react-component", - "react component", - "react bootstrap", - "bootstrap react", - "ui library", - "ui components", - "component library", - "components" - ], - "homepage": "https://coreui.io/react/", - "bugs": { - "url": "https://github.com/coreui/coreui-react/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/coreui/coreui-react.git" - }, - "license": "MIT", - "author": "The CoreUI Team (https://github.com/orgs/coreui/people)", - "main": "dist/cjs/index.js", - "module": "dist/esm/index.js", - "jsnext:main": "dist/esm/index.js", - "types": "dist/esm/index.d.ts", - "files": [ - "dist/", - "src/" - ], - "sideEffects": false, - "scripts": { - "build": "npm-run-all clean build-*", - "build-cjs": "rollup --environment ESM:false --config", - "build-esm": "rollup --environment ESM:true --config", - "clean": "cross-env-shell \"rm -rf dist\"", - "test": "jest --coverage", - "test:update": "jest --coverage --updateSnapshot" - }, - "dependencies": { - "@coreui/coreui": "^5.0.0-rc.0", - "@popperjs/core": "^2.11.8", - "prop-types": "^15.8.1" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^25.0.7", - "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-typescript": "^11.1.5", - "@testing-library/jest-dom": "^6.1.4", - "@testing-library/react": "^14.1.0", - "@types/jest": "^29.5.8", - "@types/react": "18.2.37", - "@types/react-dom": "^18.2.15", - "@types/react-transition-group": "^4.4.9", - "classnames": "^2.3.2", - "cross-env": "^7.0.3", - "jest": "^29.7.0", - "jest-environment-jsdom": "^29.7.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-transition-group": "^4.4.5", - "rollup": "^4.4.1", - "ts-jest": "^29.1.1", - "tslib": "^2.6.2", - "typescript": "^5.2.2" - }, - "peerDependencies": { - "react": ">=17", - "react-dom": ">=17" - } -} diff --git a/packages/coreui-react/rollup.config.mjs b/packages/coreui-react/rollup.config.mjs deleted file mode 100644 index 1b55718e..00000000 --- a/packages/coreui-react/rollup.config.mjs +++ /dev/null @@ -1,49 +0,0 @@ -import commonjs from '@rollup/plugin-commonjs' -import resolve from '@rollup/plugin-node-resolve' -import typescript from '@rollup/plugin-typescript' -import { readFileSync } from 'node:fs' -import { dirname } from 'node:path' - -const pkg = JSON.parse(readFileSync(new URL('./package.json', import.meta.url))) - -const DIR_CJS = dirname(pkg.main) -const DIR_ESM = dirname(pkg.module) -const ESM = process.env.ESM === 'true' - -const plugins = [ - resolve(), - typescript({ - exclude: ['**/__tests__/**'], - tsconfig: './tsconfig.json', - compilerOptions: { - declarationDir: ESM ? DIR_ESM : DIR_CJS, - outDir: ESM ? DIR_ESM : DIR_CJS, - }, - }), - commonjs({ - include: ['../../node_modules/**'], - }), -] - -const external = ['@popperjs/core', 'prop-types', 'react', 'react-dom'] - -const rollupConfig = { - input: 'src/index.ts', - output: { - dir: ESM ? DIR_ESM : DIR_CJS, - format: ESM ? 'esm' : 'cjs', - exports: 'named', - preserveModules: true, - preserveModulesRoot: 'src', - sourcemap: true, - sourcemapPathTransform: (relativeSourcePath) => { - return relativeSourcePath - .replace('../../node_modules/', '../') - .replace('../src/', 'src/') - }, - }, - external, - plugins, -} - -export default rollupConfig diff --git a/packages/coreui-react/src/components/accordion/CAccordion.tsx b/packages/coreui-react/src/components/accordion/CAccordion.tsx deleted file mode 100644 index 9fe4c634..00000000 --- a/packages/coreui-react/src/components/accordion/CAccordion.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React, { createContext, forwardRef, HTMLAttributes, useState } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CAccordionProps extends HTMLAttributes<HTMLDivElement> { - /** - * The active item key. - */ - activeItemKey?: number | string - /** - * Make accordion items stay open when another item is opened - */ - alwaysOpen?: boolean - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Removes the default background-color, some borders, and some rounded corners to render accordions edge-to-edge with their parent container. - */ - flush?: boolean -} - -export interface CAccordionContextProps { - _activeItemKey?: number | string - alwaysOpen?: boolean - setActiveKey: React.Dispatch<React.SetStateAction<number | string | undefined>> -} - -export const CAccordionContext = createContext({} as CAccordionContextProps) - -export const CAccordion = forwardRef<HTMLDivElement, CAccordionProps>( - ({ children, activeItemKey, alwaysOpen = false, className, flush, ...rest }, ref) => { - const [_activeItemKey, setActiveKey] = useState(activeItemKey) - - return ( - <div - className={classNames('accordion', { 'accordion-flush': flush }, className)} - {...rest} - ref={ref} - > - <CAccordionContext.Provider value={{ _activeItemKey, alwaysOpen, setActiveKey }}> - {children} - </CAccordionContext.Provider> - </div> - ) - }, -) - -CAccordion.propTypes = { - alwaysOpen: PropTypes.bool, - activeItemKey: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - children: PropTypes.node, - className: PropTypes.string, - flush: PropTypes.bool, -} - -CAccordion.displayName = 'CAccordion' diff --git a/packages/coreui-react/src/components/accordion/CAccordionBody.tsx b/packages/coreui-react/src/components/accordion/CAccordionBody.tsx deleted file mode 100644 index 532f3ff6..00000000 --- a/packages/coreui-react/src/components/accordion/CAccordionBody.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useContext } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CAccordionItemContext } from './CAccordionItem' - -import { CCollapse } from './../collapse/CCollapse' - -export interface CAccordionBodyProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CAccordionBody = forwardRef<HTMLDivElement, CAccordionBodyProps>( - ({ children, className, ...rest }, ref) => { - const { visible } = useContext(CAccordionItemContext) - - return ( - <CCollapse className="accordion-collapse" visible={visible}> - <div className={classNames('accordion-body', className)} {...rest} ref={ref}> - {children} - </div> - </CCollapse> - ) - }, -) - -CAccordionBody.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CAccordionBody.displayName = 'CAccordionBody' diff --git a/packages/coreui-react/src/components/accordion/CAccordionButton.tsx b/packages/coreui-react/src/components/accordion/CAccordionButton.tsx deleted file mode 100644 index 4235ca6e..00000000 --- a/packages/coreui-react/src/components/accordion/CAccordionButton.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useContext } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CAccordionItemContext } from './CAccordionItem' - -export interface CAccordionButtonProps extends HTMLAttributes<HTMLButtonElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CAccordionButton = forwardRef<HTMLButtonElement, CAccordionButtonProps>( - ({ children, className, ...rest }, ref) => { - const { visible, setVisible } = useContext(CAccordionItemContext) - - return ( - <button - type="button" - className={classNames('accordion-button', { collapsed: !visible }, className)} - aria-expanded={!visible} - onClick={() => setVisible(!visible)} - {...rest} - ref={ref} - > - {children} - </button> - ) - }, -) - -CAccordionButton.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CAccordionButton.displayName = 'CAccordionButton' diff --git a/packages/coreui-react/src/components/accordion/CAccordionHeader.tsx b/packages/coreui-react/src/components/accordion/CAccordionHeader.tsx deleted file mode 100644 index b11650f4..00000000 --- a/packages/coreui-react/src/components/accordion/CAccordionHeader.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CAccordionButton } from './CAccordionButton' - -export interface CAccordionHeaderProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CAccordionHeader = forwardRef<HTMLDivElement, CAccordionHeaderProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('accordion-header', className)} {...rest} ref={ref}> - <CAccordionButton>{children}</CAccordionButton> - </div> - ) - }, -) - -CAccordionHeader.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CAccordionHeader.displayName = 'CAccordionHeader' diff --git a/packages/coreui-react/src/components/accordion/CAccordionItem.tsx b/packages/coreui-react/src/components/accordion/CAccordionItem.tsx deleted file mode 100644 index eb26bdcd..00000000 --- a/packages/coreui-react/src/components/accordion/CAccordionItem.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React, { - createContext, - forwardRef, - HTMLAttributes, - useContext, - useEffect, - useRef, - useState, -} from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CAccordionContext } from './CAccordion' - -export interface CAccordionItemContextProps { - setVisible: (a: boolean) => void - visible?: boolean -} - -export const CAccordionItemContext = createContext({} as CAccordionItemContextProps) - -export interface CAccordionItemProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Item key. - */ - itemKey?: number | string -} - -export const CAccordionItem = forwardRef<HTMLDivElement, CAccordionItemProps>( - ({ children, className, itemKey, ...rest }, ref) => { - const _itemKey = useRef(itemKey ?? Math.random().toString(36).slice(2, 11)) - - const { _activeItemKey, alwaysOpen, setActiveKey } = useContext(CAccordionContext) - const [visible, setVisible] = useState(Boolean(_activeItemKey === _itemKey.current)) - - useEffect(() => { - !alwaysOpen && visible && setActiveKey(_itemKey.current) - }, [visible]) - - useEffect(() => { - setVisible(Boolean(_activeItemKey === _itemKey.current)) - }, [_activeItemKey]) - - return ( - <div className={classNames('accordion-item', className)} {...rest} ref={ref}> - <CAccordionItemContext.Provider value={{ setVisible, visible }}> - {children} - </CAccordionItemContext.Provider> - </div> - ) - }, -) - -CAccordionItem.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - itemKey: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), -} - -CAccordionItem.displayName = 'CAccordionItem' diff --git a/packages/coreui-react/src/components/accordion/__tests__/CAccordion.spec.tsx b/packages/coreui-react/src/components/accordion/__tests__/CAccordion.spec.tsx deleted file mode 100644 index 761cd0ea..00000000 --- a/packages/coreui-react/src/components/accordion/__tests__/CAccordion.spec.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' -import { render, screen } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CAccordion } from '../../../index' - -test('loads and displays CAccordion component', async () => { - const { container } = render(<CAccordion>Test</CAccordion>) - expect(container).toMatchSnapshot() -}) - -test('CAccordion customize', async () => { - const { container } = render(<CAccordion className="bazinga">Test</CAccordion>) - expect(container.firstChild).toHaveClass('bazinga') - expect(container).toMatchSnapshot() -}) - -test('CAccordion use case test', async () => { - jest.useFakeTimers() - const { rerender } = render(<CAccordion flush={false}>Test</CAccordion>) - expect(screen.getByText('Test')).toHaveClass('accordion') - expect(screen.getByText('Test')).not.toHaveClass('accordion-flush') - rerender(<CAccordion flush={true}>Test</CAccordion>) - expect(screen.getByText('Test')).toHaveClass('accordion') - expect(screen.getByText('Test')).toHaveClass('accordion-flush') - jest.runAllTimers() - expect(screen.getByText('Test')).toHaveClass('accordion') - expect(screen.getByText('Test')).toHaveClass('accordion-flush') - rerender(<CAccordion flush={false}>Test</CAccordion>) - expect(screen.getByText('Test')).toHaveClass('accordion') - expect(screen.getByText('Test')).not.toHaveClass('accordion-flush') - jest.runAllTimers() - expect(screen.getByText('Test')).toHaveClass('accordion') - expect(screen.getByText('Test')).not.toHaveClass('accordion-flush') - jest.runAllTimers() - jest.useRealTimers() -}) diff --git a/packages/coreui-react/src/components/accordion/__tests__/CAccordionBody.spec.tsx b/packages/coreui-react/src/components/accordion/__tests__/CAccordionBody.spec.tsx deleted file mode 100644 index 519f0f13..00000000 --- a/packages/coreui-react/src/components/accordion/__tests__/CAccordionBody.spec.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CAccordionBody } from '../../../index' - -test('loads and displays CAccordionBody component', async () => { - const { container } = render(<CAccordionBody>Test</CAccordionBody>) - expect(container).toMatchSnapshot() -}) - -test('CAccordionBody customize', async () => { - const { container } = render(<CAccordionBody>Test</CAccordionBody>) - expect(container.firstChild?.firstChild).toHaveClass('accordion-body') - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/accordion/__tests__/CAccordionButton.spec.tsx b/packages/coreui-react/src/components/accordion/__tests__/CAccordionButton.spec.tsx deleted file mode 100644 index 1d40548c..00000000 --- a/packages/coreui-react/src/components/accordion/__tests__/CAccordionButton.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CAccordionButton } from '../../../index' - -test('loads and displays CAccordionButton component', async () => { - const { container } = render(<CAccordionButton>Test</CAccordionButton>) - expect(container).toMatchSnapshot() -}) - -test('CAccordionButton customize', async () => { - const { container } = render(<CAccordionButton className="bazinga">Test</CAccordionButton>) - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('accordion-button') - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/accordion/__tests__/CAccordionHeader.spec.tsx b/packages/coreui-react/src/components/accordion/__tests__/CAccordionHeader.spec.tsx deleted file mode 100644 index ac833186..00000000 --- a/packages/coreui-react/src/components/accordion/__tests__/CAccordionHeader.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CAccordionHeader } from '../../../index' - -test('loads and displays CAccordionHeader component', async () => { - const { container } = render(<CAccordionHeader>Test</CAccordionHeader>) - expect(container).toMatchSnapshot() -}) - -test('CAccordionHeader customize', async () => { - const { container } = render(<CAccordionHeader className="bazinga">Test</CAccordionHeader>) - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('accordion-header') - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/accordion/__tests__/CAccordionItem.spec.tsx b/packages/coreui-react/src/components/accordion/__tests__/CAccordionItem.spec.tsx deleted file mode 100644 index 10f693f3..00000000 --- a/packages/coreui-react/src/components/accordion/__tests__/CAccordionItem.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CAccordionItem } from '../../../index' - -test('loads and displays CAccordionItem component', async () => { - const { container } = render(<CAccordionItem>Test</CAccordionItem>) - expect(container).toMatchSnapshot() -}) - -test('CAccordionItem customize', async () => { - const { container } = render(<CAccordionItem className="bazinga">Test</CAccordionItem>) - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('accordion-item') - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordion.spec.tsx.snap b/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordion.spec.tsx.snap deleted file mode 100644 index 237b2c04..00000000 --- a/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordion.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CAccordion customize 1`] = ` -<div> - <div - class="accordion bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CAccordion component 1`] = ` -<div> - <div - class="accordion" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionBody.spec.tsx.snap b/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionBody.spec.tsx.snap deleted file mode 100644 index fa723f46..00000000 --- a/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionBody.spec.tsx.snap +++ /dev/null @@ -1,29 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CAccordionBody customize 1`] = ` -<div> - <div - class="accordion-collapse collapse" - > - <div - class="accordion-body" - > - Test - </div> - </div> -</div> -`; - -exports[`loads and displays CAccordionBody component 1`] = ` -<div> - <div - class="accordion-collapse collapse" - > - <div - class="accordion-body" - > - Test - </div> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.tsx.snap b/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.tsx.snap deleted file mode 100644 index b8bd2e1c..00000000 --- a/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.tsx.snap +++ /dev/null @@ -1,25 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CAccordionButton customize 1`] = ` -<div> - <button - aria-expanded="true" - class="accordion-button collapsed bazinga" - type="button" - > - Test - </button> -</div> -`; - -exports[`loads and displays CAccordionButton component 1`] = ` -<div> - <button - aria-expanded="true" - class="accordion-button collapsed" - type="button" - > - Test - </button> -</div> -`; diff --git a/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.tsx.snap b/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.tsx.snap deleted file mode 100644 index dfea0a55..00000000 --- a/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.tsx.snap +++ /dev/null @@ -1,33 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CAccordionHeader customize 1`] = ` -<div> - <div - class="accordion-header bazinga" - > - <button - aria-expanded="true" - class="accordion-button collapsed" - type="button" - > - Test - </button> - </div> -</div> -`; - -exports[`loads and displays CAccordionHeader component 1`] = ` -<div> - <div - class="accordion-header" - > - <button - aria-expanded="true" - class="accordion-button collapsed" - type="button" - > - Test - </button> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionItem.spec.tsx.snap b/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionItem.spec.tsx.snap deleted file mode 100644 index 721a013b..00000000 --- a/packages/coreui-react/src/components/accordion/__tests__/__snapshots__/CAccordionItem.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CAccordionItem customize 1`] = ` -<div> - <div - class="accordion-item bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CAccordionItem component 1`] = ` -<div> - <div - class="accordion-item" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/accordion/index.ts b/packages/coreui-react/src/components/accordion/index.ts deleted file mode 100644 index e1cc95ee..00000000 --- a/packages/coreui-react/src/components/accordion/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { CAccordion } from './CAccordion' -import { CAccordionBody } from './CAccordionBody' -import { CAccordionButton } from './CAccordionButton' -import { CAccordionHeader } from './CAccordionHeader' -import { CAccordionItem } from './CAccordionItem' - -export { CAccordion, CAccordionBody, CAccordionButton, CAccordionHeader, CAccordionItem } diff --git a/packages/coreui-react/src/components/alert/CAlert.tsx b/packages/coreui-react/src/components/alert/CAlert.tsx deleted file mode 100644 index 3efdb78f..00000000 --- a/packages/coreui-react/src/components/alert/CAlert.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useEffect, useState, useRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' -import { Transition } from 'react-transition-group' - -import { CCloseButton } from '../close-button/CCloseButton' - -import { useForkedRef } from '../../hooks' -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CAlertProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color: Colors - /** - * Optionally add a close button to alert and allow it to self dismiss. - */ - dismissible?: boolean - /** - * Callback fired when the component requests to be closed. - */ - onClose?: () => void - /** - * Set the alert variant to a solid. - */ - variant?: 'solid' | string - /** - * Toggle the visibility of component. - */ - visible?: boolean -} - -export const CAlert = forwardRef<HTMLDivElement, CAlertProps>( - ( - { - children, - className, - color = 'primary', - dismissible, - variant, - visible = true, - onClose, - ...rest - }, - ref, - ) => { - const alertRef = useRef<HTMLDivElement>(null) - const forkedRef = useForkedRef(ref, alertRef) - const [_visible, setVisible] = useState(visible) - - useEffect(() => { - setVisible(visible) - }, [visible]) - - return ( - <Transition - in={_visible} - mountOnEnter - nodeRef={alertRef} - onExit={onClose} - timeout={150} - unmountOnExit - > - {(state) => ( - <div - className={classNames( - 'alert', - variant === 'solid' ? `bg-${color} text-white` : `alert-${color}`, - { - 'alert-dismissible fade': dismissible, - show: state === 'entered', - }, - className, - )} - role="alert" - {...rest} - ref={forkedRef} - > - {children} - {dismissible && <CCloseButton onClick={() => setVisible(false)} />} - </div> - )} - </Transition> - ) - }, -) - -CAlert.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType.isRequired, - dismissible: PropTypes.bool, - onClose: PropTypes.func, - variant: PropTypes.string, - visible: PropTypes.bool, -} - -CAlert.displayName = 'CAlert' diff --git a/packages/coreui-react/src/components/alert/CAlertHeading.tsx b/packages/coreui-react/src/components/alert/CAlertHeading.tsx deleted file mode 100644 index f63556d8..00000000 --- a/packages/coreui-react/src/components/alert/CAlertHeading.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CAlertHeadingProps extends HTMLAttributes<HTMLHeadingElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CAlertHeading = forwardRef<HTMLHeadingElement, CAlertHeadingProps>( - ({ children, className, component: Component = 'h4', ...rest }, ref) => { - return ( - <Component className={classNames('alert-heading', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CAlertHeading.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CAlertHeading.displayName = 'CAlertHeading' diff --git a/packages/coreui-react/src/components/alert/CAlertLink.tsx b/packages/coreui-react/src/components/alert/CAlertLink.tsx deleted file mode 100644 index dacfa081..00000000 --- a/packages/coreui-react/src/components/alert/CAlertLink.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React, { AnchorHTMLAttributes, forwardRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CLink } from '../link/CLink' - -export interface CAlertLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CAlertLink = forwardRef<HTMLAnchorElement, CAlertLinkProps>( - ({ children, className, ...rest }, ref) => { - return ( - <CLink className={classNames('alert-link', className)} {...rest} ref={ref}> - {children} - </CLink> - ) - }, -) - -CAlertLink.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CAlertLink.displayName = 'CAlertLink' diff --git a/packages/coreui-react/src/components/alert/__tests__/CAlert.spec.tsx b/packages/coreui-react/src/components/alert/__tests__/CAlert.spec.tsx deleted file mode 100644 index a9581d0a..00000000 --- a/packages/coreui-react/src/components/alert/__tests__/CAlert.spec.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import * as React from 'react' -import { render, fireEvent } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CAlert } from '../../../index' - -test('loads and displays CAlert component', async () => { - const { container } = render(<CAlert color="primary">Test</CAlert>) - expect(container).toMatchSnapshot() -}) - -test('CAlert customize', async () => { - const { container } = render( - <CAlert color="secondary" className="bazinga" dismissible={true} variant="solid" visible={true}> - Test - </CAlert>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('bg-secondary') - expect(container.firstChild).toHaveClass('text-white') - expect(container.firstChild).toHaveClass('alert-dismissible') -}) - -test('CAlert click close button', async () => { - jest.useFakeTimers() - const onClose = jest.fn() - render( - <CAlert color="primary" dismissible onClose={onClose}> - Test - </CAlert>, - ) - expect(onClose).toHaveBeenCalledTimes(0) - const btn = document.querySelector('.btn-close') - if (btn !== null) { - fireEvent.click(btn) - } - expect(onClose).toHaveBeenCalledTimes(1) - jest.runAllTimers() - expect(onClose).toHaveBeenCalledTimes(1) - jest.useRealTimers() -}) diff --git a/packages/coreui-react/src/components/alert/__tests__/CAlertHeading.spec.tsx b/packages/coreui-react/src/components/alert/__tests__/CAlertHeading.spec.tsx deleted file mode 100644 index 8e33113a..00000000 --- a/packages/coreui-react/src/components/alert/__tests__/CAlertHeading.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CAlertHeading } from '../../../index' - -test('loads and displays CAlertHeading component', async () => { - const { container } = render(<CAlertHeading>Test</CAlertHeading>) - expect(container).toMatchSnapshot() -}) - -test('CAlertHeading customize', async () => { - const { container } = render( - <CAlertHeading component="h3" className="bazinga"> - Test - </CAlertHeading>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('alert-heading') -}) diff --git a/packages/coreui-react/src/components/alert/__tests__/CAlertLink.spec.tsx b/packages/coreui-react/src/components/alert/__tests__/CAlertLink.spec.tsx deleted file mode 100644 index 47dc0afe..00000000 --- a/packages/coreui-react/src/components/alert/__tests__/CAlertLink.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CAlertLink } from '../../../index' - -test('loads and displays CAlertLink component', async () => { - const { container } = render(<CAlertLink>Test</CAlertLink>) - expect(container).toMatchSnapshot() -}) - -test('CAlertLink customize', async () => { - const { container } = render( - <CAlertLink className="bazinga" href="/bazinga"> - Test - </CAlertLink>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('alert-link') -}) diff --git a/packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlert.spec.tsx.snap b/packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlert.spec.tsx.snap deleted file mode 100644 index 56496343..00000000 --- a/packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlert.spec.tsx.snap +++ /dev/null @@ -1,28 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CAlert customize 1`] = ` -<div> - <div - class="alert bg-secondary text-white alert-dismissible fade show bazinga" - role="alert" - > - Test - <button - aria-label="Close" - class="btn btn-close" - type="button" - /> - </div> -</div> -`; - -exports[`loads and displays CAlert component 1`] = ` -<div> - <div - class="alert alert-primary show" - role="alert" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlertHeading.spec.tsx.snap b/packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlertHeading.spec.tsx.snap deleted file mode 100644 index 02417c99..00000000 --- a/packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlertHeading.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CAlertHeading customize 1`] = ` -<div> - <h3 - class="alert-heading bazinga" - > - Test - </h3> -</div> -`; - -exports[`loads and displays CAlertHeading component 1`] = ` -<div> - <h4 - class="alert-heading" - > - Test - </h4> -</div> -`; diff --git a/packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlertLink.spec.tsx.snap b/packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlertLink.spec.tsx.snap deleted file mode 100644 index 33d4eac7..00000000 --- a/packages/coreui-react/src/components/alert/__tests__/__snapshots__/CAlertLink.spec.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CAlertLink customize 1`] = ` -<div> - <a - class="alert-link bazinga" - href="/bazinga" - > - Test - </a> -</div> -`; - -exports[`loads and displays CAlertLink component 1`] = ` -<div> - <a - class="alert-link" - > - Test - </a> -</div> -`; diff --git a/packages/coreui-react/src/components/alert/index.ts b/packages/coreui-react/src/components/alert/index.ts deleted file mode 100644 index 7e182023..00000000 --- a/packages/coreui-react/src/components/alert/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { CAlert } from './CAlert' -import { CAlertHeading } from './CAlertHeading' -import { CAlertLink } from './CAlertLink' - -export { CAlert, CAlertHeading, CAlertLink } diff --git a/packages/coreui-react/src/components/avatar/CAvatar.tsx b/packages/coreui-react/src/components/avatar/CAvatar.tsx deleted file mode 100644 index facdeec3..00000000 --- a/packages/coreui-react/src/components/avatar/CAvatar.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType, shapePropType, textColorsPropType } from '../../props' -import type { Colors, Shapes, TextColors } from '../../types' - -export interface CAvatarProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Select the shape of the component. - * - * @type 'rounded' | 'rounded-top' | 'rounded-end' | 'rounded-bottom' | 'rounded-start' | 'rounded-circle' | 'rounded-pill' | 'rounded-0' | 'rounded-1' | 'rounded-2' | 'rounded-3' | string - */ - shape?: Shapes - /** - * Size the component small, large, or extra large. - */ - size?: string - /** - * The src attribute for the img element. - */ - src?: string - /** - * Sets the color context of the status indicator to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - status?: Colors - /** - * Sets the text color of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | 'primary-emphasis' | 'secondary-emphasis' | 'success-emphasis' | 'danger-emphasis' | 'warning-emphasis' | 'info-emphasis' | 'light-emphasis' | 'body' | 'body-emphasis' | 'body-secondary' | 'body-tertiary' | 'black' | 'black-50' | 'white' | 'white-50' | string - */ - textColor?: TextColors -} - -export const CAvatar = forwardRef<HTMLDivElement, CAvatarProps>( - ({ children, className, color, shape, size, src, status, textColor, ...rest }, ref) => { - const statusClassName = status && classNames('avatar-status', `bg-${status}`) - - return ( - <div - className={classNames( - 'avatar', - { - [`bg-${color}`]: color, - [`avatar-${size}`]: size, - [`text-${textColor}`]: textColor, - }, - shape, - className, - )} - {...rest} - ref={ref} - > - {src ? <img src={src} className="avatar-img" /> : children} - {status && <span className={statusClassName}></span>} - </div> - ) - }, -) - -CAvatar.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, - shape: shapePropType, - size: PropTypes.string, - src: PropTypes.string, - status: PropTypes.string, - textColor: textColorsPropType, -} - -CAvatar.displayName = 'CAvatar' diff --git a/packages/coreui-react/src/components/avatar/__tests__/CAvatar.spec.tsx b/packages/coreui-react/src/components/avatar/__tests__/CAvatar.spec.tsx deleted file mode 100644 index 3201afe4..00000000 --- a/packages/coreui-react/src/components/avatar/__tests__/CAvatar.spec.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CAvatar } from '../../../index' - -test('loads and displays CAvatar component', async () => { - const { container } = render(<CAvatar color="primary">Test</CAvatar>) - expect(container).toMatchSnapshot() -}) - -test('CAvatar customize', async () => { - let element - const { container } = render( - <CAvatar - className="bazinga" - color="secondary" - shape="rounded" - size="xl" - status="warning" - textColor="white" - > - Test - </CAvatar>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('avatar') - expect(container.firstChild).toHaveClass('bg-secondary') - expect(container.firstChild).toHaveClass('avatar-xl') - expect(container.firstChild).toHaveClass('text-white') - element = container.getElementsByClassName('avatar-status') - element = element[0] - expect(element).toHaveClass('bg-warning') -}) - -test('CAvatar customize image', async () => { - const { container } = render( - <CAvatar - className="bazinga" - color="secondary" - shape="rounded" - size="xl" - status="warning" - textColor="white" - src="/bazinga" - > - Test - </CAvatar>, - ) - expect(container).toMatchSnapshot() - - const element = container.getElementsByClassName('avatar-img') - expect(element.length).toBe(1) -}) diff --git a/packages/coreui-react/src/components/avatar/__tests__/__snapshots__/CAvatar.spec.tsx.snap b/packages/coreui-react/src/components/avatar/__tests__/__snapshots__/CAvatar.spec.tsx.snap deleted file mode 100644 index 52455e95..00000000 --- a/packages/coreui-react/src/components/avatar/__tests__/__snapshots__/CAvatar.spec.tsx.snap +++ /dev/null @@ -1,40 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CAvatar customize 1`] = ` -<div> - <div - class="avatar bg-secondary avatar-xl text-white rounded bazinga" - > - Test - <span - class="avatar-status bg-warning" - /> - </div> -</div> -`; - -exports[`CAvatar customize image 1`] = ` -<div> - <div - class="avatar bg-secondary avatar-xl text-white rounded bazinga" - > - <img - class="avatar-img" - src="/bazinga" - /> - <span - class="avatar-status bg-warning" - /> - </div> -</div> -`; - -exports[`loads and displays CAvatar component 1`] = ` -<div> - <div - class="avatar bg-primary" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/avatar/index.ts b/packages/coreui-react/src/components/avatar/index.ts deleted file mode 100644 index 87a58f4b..00000000 --- a/packages/coreui-react/src/components/avatar/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CAvatar } from './CAvatar' - -export { CAvatar } diff --git a/packages/coreui-react/src/components/backdrop/CBackdrop.tsx b/packages/coreui-react/src/components/backdrop/CBackdrop.tsx deleted file mode 100644 index 42060744..00000000 --- a/packages/coreui-react/src/components/backdrop/CBackdrop.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' -import { Transition } from 'react-transition-group' - -import { useForkedRef } from '../../hooks' - -export interface CBackdropProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Toggle the visibility of modal component. - */ - visible?: boolean -} - -export const CBackdrop = forwardRef<HTMLDivElement, CBackdropProps>( - ({ className = 'modal-backdrop', visible, ...rest }, ref) => { - const backdropRef = useRef<HTMLDivElement>(null) - const forkedRef = useForkedRef(ref, backdropRef) - - return ( - <Transition in={visible} mountOnEnter nodeRef={backdropRef} timeout={150} unmountOnExit> - {(state) => ( - <div - className={classNames(className, 'fade', { - show: state === 'entered', - })} - {...rest} - ref={forkedRef} - /> - )} - </Transition> - ) - }, -) - -CBackdrop.propTypes = { - className: PropTypes.string, - visible: PropTypes.bool, -} - -CBackdrop.displayName = 'CBackdrop' diff --git a/packages/coreui-react/src/components/backdrop/__tests__/CBackdrop.spec.tsx b/packages/coreui-react/src/components/backdrop/__tests__/CBackdrop.spec.tsx deleted file mode 100644 index a5cc0290..00000000 --- a/packages/coreui-react/src/components/backdrop/__tests__/CBackdrop.spec.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CBackdrop } from '../../../index' - -test('loads and displays CBackdrop component', async () => { - const { container } = render(<CBackdrop>Test</CBackdrop>) - expect(container).toMatchSnapshot() -}) - -test('CBackdrop customize', async () => { - jest.useFakeTimers() - const { container } = render(<CBackdrop visible={true}>Test</CBackdrop>) - jest.runAllTimers() - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('modal-backdrop') - jest.useRealTimers() -}) - -test('CBackdrop customize 2', async () => { - jest.useFakeTimers() - const { container } = render( - <CBackdrop className="bazinga" visible={true}> - Test - </CBackdrop>, - ) - jest.runAllTimers() - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - jest.useRealTimers() -}) diff --git a/packages/coreui-react/src/components/backdrop/__tests__/__snapshots__/CBackdrop.spec.tsx.snap b/packages/coreui-react/src/components/backdrop/__tests__/__snapshots__/CBackdrop.spec.tsx.snap deleted file mode 100644 index 2144ce81..00000000 --- a/packages/coreui-react/src/components/backdrop/__tests__/__snapshots__/CBackdrop.spec.tsx.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CBackdrop customize 1`] = ` -<div> - <div - class="modal-backdrop fade show" - > - Test - </div> -</div> -`; - -exports[`CBackdrop customize 2 1`] = ` -<div> - <div - class="bazinga fade show" - > - Test - </div> -</div> -`; - -exports[`loads and displays CBackdrop component 1`] = `<div />`; diff --git a/packages/coreui-react/src/components/backdrop/index.ts b/packages/coreui-react/src/components/backdrop/index.ts deleted file mode 100644 index 7bca8a8a..00000000 --- a/packages/coreui-react/src/components/backdrop/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CBackdrop } from './CBackdrop' - -export { CBackdrop } diff --git a/packages/coreui-react/src/components/badge/CBadge.tsx b/packages/coreui-react/src/components/badge/CBadge.tsx deleted file mode 100644 index cbbaa966..00000000 --- a/packages/coreui-react/src/components/badge/CBadge.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType, shapePropType, textColorsPropType } from '../../props' -import type { Colors, Shapes, TextColors } from '../../types' - -export interface CBadgeProps extends HTMLAttributes<HTMLDivElement | HTMLSpanElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Position badge in one of the corners of a link or button. - */ - position?: 'top-start' | 'top-end' | 'bottom-end' | 'bottom-start' - /** - * Select the shape of the component. - * - * @type 'rounded' | 'rounded-top' | 'rounded-end' | 'rounded-bottom' | 'rounded-start' | 'rounded-circle' | 'rounded-pill' | 'rounded-0' | 'rounded-1' | 'rounded-2' | 'rounded-3' | string - */ - shape?: Shapes - /** - * Size the component small. - */ - size?: 'sm' - /** - * Sets the text color of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | 'primary-emphasis' | 'secondary-emphasis' | 'success-emphasis' | 'danger-emphasis' | 'warning-emphasis' | 'info-emphasis' | 'light-emphasis' | 'body' | 'body-emphasis' | 'body-secondary' | 'body-tertiary' | 'black' | 'black-50' | 'white' | 'white-50' | string - */ - textColor?: TextColors -} -export const CBadge = forwardRef<HTMLDivElement | HTMLSpanElement, CBadgeProps>( - ( - { - children, - className, - color, - component: Component = 'span', - position, - shape, - size, - textColor, - ...rest - }, - ref, - ) => { - return ( - <Component - className={classNames( - 'badge', - { - [`bg-${color}`]: color, - 'position-absolute translate-middle': position, - 'top-0': position?.includes('top'), - 'top-100': position?.includes('bottom'), - 'start-100': position?.includes('end'), - 'start-0': position?.includes('start'), - [`badge-${size}`]: size, - [`text-${textColor}`]: textColor, - }, - shape, - className, - )} - {...rest} - ref={ref} - > - {children} - </Component> - ) - }, -) - -CBadge.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, - component: PropTypes.string, - position: PropTypes.oneOf(['top-start', 'top-end', 'bottom-end', 'bottom-start']), - shape: shapePropType, - size: PropTypes.oneOf(['sm']), - textColor: textColorsPropType, -} - -CBadge.displayName = 'CBadge' diff --git a/packages/coreui-react/src/components/badge/__tests__/CBadge.spec.tsx b/packages/coreui-react/src/components/badge/__tests__/CBadge.spec.tsx deleted file mode 100644 index da220932..00000000 --- a/packages/coreui-react/src/components/badge/__tests__/CBadge.spec.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CBadge } from '../../../index' - -test('loads and displays CBadge component', async () => { - const { container } = render(<CBadge color="primary">Test</CBadge>) - expect(container).toMatchSnapshot() -}) - -test('CBadge customize', async () => { - const { container } = render( - <CBadge className="bazinga" color="warning" component="div" shape="rounded" textColor="white"> - Test - </CBadge>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('badge') - expect(container.firstChild).toHaveClass('bg-warning') - expect(container.firstChild).toHaveClass('rounded') -}) diff --git a/packages/coreui-react/src/components/badge/__tests__/__snapshots__/CBadge.spec.tsx.snap b/packages/coreui-react/src/components/badge/__tests__/__snapshots__/CBadge.spec.tsx.snap deleted file mode 100644 index 909bd2b5..00000000 --- a/packages/coreui-react/src/components/badge/__tests__/__snapshots__/CBadge.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CBadge customize 1`] = ` -<div> - <div - class="badge bg-warning text-white rounded bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CBadge component 1`] = ` -<div> - <span - class="badge bg-primary" - > - Test - </span> -</div> -`; diff --git a/packages/coreui-react/src/components/badge/index.ts b/packages/coreui-react/src/components/badge/index.ts deleted file mode 100644 index 689638b2..00000000 --- a/packages/coreui-react/src/components/badge/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CBadge } from './CBadge' - -export { CBadge } diff --git a/packages/coreui-react/src/components/breadcrumb/CBreadcrumb.tsx b/packages/coreui-react/src/components/breadcrumb/CBreadcrumb.tsx deleted file mode 100644 index 4802828c..00000000 --- a/packages/coreui-react/src/components/breadcrumb/CBreadcrumb.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CBreadcrumbProps extends HTMLAttributes<HTMLOListElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -export const CBreadcrumb = forwardRef<HTMLOListElement, CBreadcrumbProps>( - ({ children, className, ...rest }, ref) => { - return ( - <nav aria-label="breadcrumb"> - <ol className={classNames('breadcrumb', className)} {...rest} ref={ref}> - {children} - </ol> - </nav> - ) - }, -) - -CBreadcrumb.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CBreadcrumb.displayName = 'CBreadcrumb' diff --git a/packages/coreui-react/src/components/breadcrumb/CBreadcrumbItem.tsx b/packages/coreui-react/src/components/breadcrumb/CBreadcrumbItem.tsx deleted file mode 100644 index 153ca479..00000000 --- a/packages/coreui-react/src/components/breadcrumb/CBreadcrumbItem.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CLink } from '../link/CLink' - -export interface CBreadcrumbItemProps extends HTMLAttributes<HTMLLIElement> { - /** - * Toggle the active state for the component. - */ - active?: boolean - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * The `href` attribute for the inner `<CLink>` component. - */ - href?: string -} - -export const CBreadcrumbItem = forwardRef<HTMLLIElement, CBreadcrumbItemProps>( - ({ children, active, className, href, ...rest }, ref) => { - return ( - <li - className={classNames( - 'breadcrumb-item', - { - active: active, - }, - className, - )} - {...(active && { 'aria-current': 'page' })} - {...rest} - ref={ref} - > - {href ? <CLink href={href}>{children}</CLink> : children} - </li> - ) - }, -) - -CBreadcrumbItem.propTypes = { - active: PropTypes.bool, - children: PropTypes.node, - className: PropTypes.string, - href: PropTypes.string, -} - -CBreadcrumbItem.displayName = 'CBreadcrumbItem' diff --git a/packages/coreui-react/src/components/breadcrumb/__tests__/CBreadcrumb.spec.tsx b/packages/coreui-react/src/components/breadcrumb/__tests__/CBreadcrumb.spec.tsx deleted file mode 100644 index 396a3ce7..00000000 --- a/packages/coreui-react/src/components/breadcrumb/__tests__/CBreadcrumb.spec.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CBreadcrumb, CBreadcrumbItem } from '../../../index' - -test('loads and displays CBreadcrumb component', async () => { - const { container } = render(<CBreadcrumb></CBreadcrumb>) - expect(container).toMatchSnapshot() -}) - -test('CBreadcrumb customize', async () => { - const { container } = render( - <CBreadcrumb className="bazinga"> - <CBreadcrumbItem>Test A</CBreadcrumbItem> - <CBreadcrumbItem active={false}>Test B</CBreadcrumbItem> - <CBreadcrumbItem active={true}>Test C</CBreadcrumbItem> - </CBreadcrumb>, - ) - const ol = container.querySelector('ol') - expect(container).toMatchSnapshot() - expect(ol).toHaveClass('bazinga') -}) diff --git a/packages/coreui-react/src/components/breadcrumb/__tests__/CBreadcrumbItem.spec.tsx b/packages/coreui-react/src/components/breadcrumb/__tests__/CBreadcrumbItem.spec.tsx deleted file mode 100644 index 08c3c874..00000000 --- a/packages/coreui-react/src/components/breadcrumb/__tests__/CBreadcrumbItem.spec.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CBreadcrumbItem } from '../../../index' - -test('loads and displays CBreadcrumbItem component', async () => { - const { container } = render(<CBreadcrumbItem>Test</CBreadcrumbItem>) - expect(container).toMatchSnapshot() -}) - -test('CBreadcrumbItem customize', async () => { - const { container } = render( - <CBreadcrumbItem active={true} className="bazinga"> - Test - </CBreadcrumbItem>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('breadcrumb-item') - expect(container.firstChild).toHaveClass('active') -}) diff --git a/packages/coreui-react/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumb.spec.tsx.snap b/packages/coreui-react/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumb.spec.tsx.snap deleted file mode 100644 index 347521b1..00000000 --- a/packages/coreui-react/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumb.spec.tsx.snap +++ /dev/null @@ -1,42 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CBreadcrumb customize 1`] = ` -<div> - <nav - aria-label="breadcrumb" - > - <ol - class="breadcrumb bazinga" - > - <li - class="breadcrumb-item" - > - Test A - </li> - <li - class="breadcrumb-item" - > - Test B - </li> - <li - aria-current="page" - class="breadcrumb-item active" - > - Test C - </li> - </ol> - </nav> -</div> -`; - -exports[`loads and displays CBreadcrumb component 1`] = ` -<div> - <nav - aria-label="breadcrumb" - > - <ol - class="breadcrumb" - /> - </nav> -</div> -`; diff --git a/packages/coreui-react/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumbItem.spec.tsx.snap b/packages/coreui-react/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumbItem.spec.tsx.snap deleted file mode 100644 index 9b5b54cb..00000000 --- a/packages/coreui-react/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumbItem.spec.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CBreadcrumbItem customize 1`] = ` -<div> - <li - aria-current="page" - class="breadcrumb-item active bazinga" - > - Test - </li> -</div> -`; - -exports[`loads and displays CBreadcrumbItem component 1`] = ` -<div> - <li - class="breadcrumb-item" - > - Test - </li> -</div> -`; diff --git a/packages/coreui-react/src/components/breadcrumb/index.ts b/packages/coreui-react/src/components/breadcrumb/index.ts deleted file mode 100644 index d402a910..00000000 --- a/packages/coreui-react/src/components/breadcrumb/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { CBreadcrumb } from './CBreadcrumb' -import { CBreadcrumbItem } from './CBreadcrumbItem' - -export { CBreadcrumb, CBreadcrumbItem } diff --git a/packages/coreui-react/src/components/button-group/CButtonGroup.tsx b/packages/coreui-react/src/components/button-group/CButtonGroup.tsx deleted file mode 100644 index 108dcbcd..00000000 --- a/packages/coreui-react/src/components/button-group/CButtonGroup.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CButtonGroupProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Size the component small or large. - */ - size?: 'sm' | 'lg' - /** - * Create a set of buttons that appear vertically stacked rather than horizontally. Split button dropdowns are not supported here. - */ - vertical?: boolean -} - -export const CButtonGroup = forwardRef<HTMLDivElement, CButtonGroupProps>( - ({ children, className, size, vertical, ...rest }, ref) => { - return ( - <div - className={classNames( - vertical ? 'btn-group-vertical' : 'btn-group', - { [`btn-group-${size}`]: size }, - className, - )} - {...rest} - ref={ref} - > - {children} - </div> - ) - }, -) - -CButtonGroup.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - size: PropTypes.oneOf(['sm', 'lg']), - vertical: PropTypes.bool, -} - -CButtonGroup.displayName = 'CButtonGroup' diff --git a/packages/coreui-react/src/components/button-group/CButtonToolbar.tsx b/packages/coreui-react/src/components/button-group/CButtonToolbar.tsx deleted file mode 100644 index fe670b85..00000000 --- a/packages/coreui-react/src/components/button-group/CButtonToolbar.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CButtonToolbarProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CButtonToolbar = forwardRef<HTMLDivElement, CButtonToolbarProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('btn-toolbar', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -CButtonToolbar.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CButtonToolbar.displayName = 'CButtonToolbar' diff --git a/packages/coreui-react/src/components/button-group/__tests__/CButtonGroup.spec.tsx b/packages/coreui-react/src/components/button-group/__tests__/CButtonGroup.spec.tsx deleted file mode 100644 index 6e286f65..00000000 --- a/packages/coreui-react/src/components/button-group/__tests__/CButtonGroup.spec.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CButtonGroup, CButton } from '../../../index' - -test('loads and displays CButtonGroup component', async () => { - const { container } = render(<CButtonGroup></CButtonGroup>) - expect(container).toMatchSnapshot() -}) - -test('CButtonGroup customize', async () => { - const { container } = render( - <CButtonGroup className="bazinga" size="lg" vertical={false}> - <CButton>Test A</CButton> - <CButton>Test B</CButton> - <CButton>Test C</CButton> - </CButtonGroup>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('btn-group') - expect(container.firstChild).toHaveClass('btn-group-lg') -}) - -test('CButtonGroup customize vertical', async () => { - const { container } = render( - <CButtonGroup className="bazinga" size="lg" vertical={true}> - <CButton>Test A</CButton> - <CButton>Test B</CButton> - <CButton>Test C</CButton> - </CButtonGroup>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('btn-group-vertical') - expect(container.firstChild).toHaveClass('btn-group-lg') -}) diff --git a/packages/coreui-react/src/components/button-group/__tests__/CButtonToolbar.spec.tsx b/packages/coreui-react/src/components/button-group/__tests__/CButtonToolbar.spec.tsx deleted file mode 100644 index 5f59d423..00000000 --- a/packages/coreui-react/src/components/button-group/__tests__/CButtonToolbar.spec.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CButtonToolbar, CButtonGroup, CButton } from '../../../index' - -test('loads and displays CButtonToolbar component', async () => { - const { container } = render(<CButtonToolbar></CButtonToolbar>) - expect(container).toMatchSnapshot() -}) - -test('CButtonToolbar customize', async () => { - const { container } = render( - <CButtonToolbar className="bazinga" role="group" aria-label="Bazinga"> - <CButtonGroup role="group"> - <CButton>1</CButton> - <CButton>2</CButton> - <CButton>3</CButton> - </CButtonGroup> - <CButtonGroup role="group"> - <CButton>A</CButton> - <CButton>B</CButton> - <CButton>C</CButton> - </CButtonGroup> - </CButtonToolbar>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('btn-toolbar') -}) diff --git a/packages/coreui-react/src/components/button-group/__tests__/__snapshots__/CButtonGroup.spec.tsx.snap b/packages/coreui-react/src/components/button-group/__tests__/__snapshots__/CButtonGroup.spec.tsx.snap deleted file mode 100644 index e6404da6..00000000 --- a/packages/coreui-react/src/components/button-group/__tests__/__snapshots__/CButtonGroup.spec.tsx.snap +++ /dev/null @@ -1,63 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CButtonGroup customize 1`] = ` -<div> - <div - class="btn-group btn-group-lg bazinga" - > - <button - class="btn btn-primary" - type="button" - > - Test A - </button> - <button - class="btn btn-primary" - type="button" - > - Test B - </button> - <button - class="btn btn-primary" - type="button" - > - Test C - </button> - </div> -</div> -`; - -exports[`CButtonGroup customize vertical 1`] = ` -<div> - <div - class="btn-group-vertical btn-group-lg bazinga" - > - <button - class="btn btn-primary" - type="button" - > - Test A - </button> - <button - class="btn btn-primary" - type="button" - > - Test B - </button> - <button - class="btn btn-primary" - type="button" - > - Test C - </button> - </div> -</div> -`; - -exports[`loads and displays CButtonGroup component 1`] = ` -<div> - <div - class="btn-group" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/button-group/__tests__/__snapshots__/CButtonToolbar.spec.tsx.snap b/packages/coreui-react/src/components/button-group/__tests__/__snapshots__/CButtonToolbar.spec.tsx.snap deleted file mode 100644 index fb8de188..00000000 --- a/packages/coreui-react/src/components/button-group/__tests__/__snapshots__/CButtonToolbar.spec.tsx.snap +++ /dev/null @@ -1,66 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CButtonToolbar customize 1`] = ` -<div> - <div - aria-label="Bazinga" - class="btn-toolbar bazinga" - role="group" - > - <div - class="btn-group" - role="group" - > - <button - class="btn btn-primary" - type="button" - > - 1 - </button> - <button - class="btn btn-primary" - type="button" - > - 2 - </button> - <button - class="btn btn-primary" - type="button" - > - 3 - </button> - </div> - <div - class="btn-group" - role="group" - > - <button - class="btn btn-primary" - type="button" - > - A - </button> - <button - class="btn btn-primary" - type="button" - > - B - </button> - <button - class="btn btn-primary" - type="button" - > - C - </button> - </div> - </div> -</div> -`; - -exports[`loads and displays CButtonToolbar component 1`] = ` -<div> - <div - class="btn-toolbar" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/button-group/index.ts b/packages/coreui-react/src/components/button-group/index.ts deleted file mode 100644 index 2168c935..00000000 --- a/packages/coreui-react/src/components/button-group/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { CButtonToolbar } from './CButtonToolbar' -import { CButtonGroup } from './CButtonGroup' - -export { CButtonToolbar, CButtonGroup } diff --git a/packages/coreui-react/src/components/button/CButton.tsx b/packages/coreui-react/src/components/button/CButton.tsx deleted file mode 100644 index 3a783725..00000000 --- a/packages/coreui-react/src/components/button/CButton.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import React, { ElementType, forwardRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CLink, CLinkProps } from '../link/CLink' - -import { colorPropType } from '../../props' -import type { Colors, Shapes } from '../../types' - -export interface CButtonProps extends Omit<CLinkProps, 'size'> { - /** - * Toggle the active state for the component. - */ - active?: boolean - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Toggle the disabled state for the component. - */ - disabled?: boolean - /** - * The href attribute specifies the URL of the page the link goes to. - */ - href?: string - /** - * The role attribute describes the role of an element in programs that can make use of it, such as screen readers or magnifiers. - */ - role?: string - /** - * Select the shape of the component. - * - * @type 'rounded' | 'rounded-top' | 'rounded-end' | 'rounded-bottom' | 'rounded-start' | 'rounded-circle' | 'rounded-pill' | 'rounded-0' | 'rounded-1' | 'rounded-2' | 'rounded-3' | string - */ - shape?: Shapes - /** - * Size the component small or large. - */ - size?: 'sm' | 'lg' - /** - * Specifies the type of button. Always specify the type attribute for the `<button>` element. - * Different browsers may use different default types for the `<button>` element. - */ - type?: 'button' | 'submit' | 'reset' - /** - * Set the button variant to an outlined button or a ghost button. - */ - variant?: 'outline' | 'ghost' -} - -export const CButton = forwardRef<HTMLButtonElement | HTMLAnchorElement, CButtonProps>( - ( - { - children, - className, - color, - component = 'button', - shape, - size, - type = 'button', - variant, - ...rest - }, - ref, - ) => { - return ( - <CLink - component={rest.href ? 'a' : component} - {...(!rest.href && { type: type })} - className={classNames( - 'btn', - variant ? `btn-${variant}-${color}` : `btn-${color}`, - { [`btn-${size}`]: size }, - shape, - className, - )} - {...rest} - ref={ref} - > - {children} - </CLink> - ) - }, -) - -CButton.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, - component: PropTypes.elementType, - shape: PropTypes.string, - size: PropTypes.oneOf(['sm', 'lg']), - type: PropTypes.oneOf(['button', 'submit', 'reset']), - variant: PropTypes.oneOf(['outline', 'ghost']), -} - -CButton.displayName = 'CButton' diff --git a/packages/coreui-react/src/components/button/__tests__/CButton.spec.tsx b/packages/coreui-react/src/components/button/__tests__/CButton.spec.tsx deleted file mode 100644 index 4c46494f..00000000 --- a/packages/coreui-react/src/components/button/__tests__/CButton.spec.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CButton } from '../../../index' - -test('loads and displays CButton component', async () => { - const { container } = render(<CButton>Test</CButton>) - expect(container).toMatchSnapshot() -}) - -test('CButton customize witch href', async () => { - const { container } = render( - <CButton color="primary" component="span" href="/bazinga"> - Test - </CButton>, - ) - expect(container).toMatchSnapshot() -}) - -test('CButton customize', async () => { - const { container } = render( - <CButton - active={true} - className="bazinga" - color="warning" - component="span" - disabled={true} - role="bazinga" - shape="rounded" - size="lg" - type="submit" - variant="ghost" - > - Test - </CButton>, - ) - expect(container).toMatchSnapshot() - - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('btn') - expect(container.firstChild).toHaveClass('btn-ghost-warning') - expect(container.firstChild).toHaveClass('btn-lg') - expect(container.firstChild).toHaveClass('rounded') -}) diff --git a/packages/coreui-react/src/components/button/__tests__/CButtonClose.spec.tsx b/packages/coreui-react/src/components/button/__tests__/CButtonClose.spec.tsx deleted file mode 100644 index 64bb591f..00000000 --- a/packages/coreui-react/src/components/button/__tests__/CButtonClose.spec.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCloseButton } from '../../../index' - -test('loads and displays CCloseButton component', async () => { - const { container } = render(<CCloseButton>Test</CCloseButton>) - expect(container).toMatchSnapshot() -}) - -test('CCloseButton customize', async () => { - const { container } = render( - <CCloseButton white={true} disabled={true} className="bazinga"> - Test - </CCloseButton>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('btn') - expect(container.firstChild).toHaveClass('btn-close') - expect(container.firstChild).toHaveClass('btn-close-white') - expect(container.firstChild).toHaveAttribute('disabled') -}) diff --git a/packages/coreui-react/src/components/button/__tests__/__snapshots__/CButton.spec.tsx.snap b/packages/coreui-react/src/components/button/__tests__/__snapshots__/CButton.spec.tsx.snap deleted file mode 100644 index 3c6dc128..00000000 --- a/packages/coreui-react/src/components/button/__tests__/__snapshots__/CButton.spec.tsx.snap +++ /dev/null @@ -1,37 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CButton customize 1`] = ` -<div> - <span - aria-current="page" - class="btn btn-ghost-warning btn-lg rounded bazinga active disabled" - disabled="" - role="bazinga" - type="submit" - > - Test - </span> -</div> -`; - -exports[`CButton customize witch href 1`] = ` -<div> - <a - class="btn btn-primary" - href="/bazinga" - > - Test - </a> -</div> -`; - -exports[`loads and displays CButton component 1`] = ` -<div> - <button - class="btn btn-primary" - type="button" - > - Test - </button> -</div> -`; diff --git a/packages/coreui-react/src/components/button/__tests__/__snapshots__/CButtonClose.spec.tsx.snap b/packages/coreui-react/src/components/button/__tests__/__snapshots__/CButtonClose.spec.tsx.snap deleted file mode 100644 index 092b4a2d..00000000 --- a/packages/coreui-react/src/components/button/__tests__/__snapshots__/CButtonClose.spec.tsx.snap +++ /dev/null @@ -1,26 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCloseButton customize 1`] = ` -<div> - <button - aria-label="Close" - class="btn btn-close btn-close-white bazinga" - disabled="" - type="button" - > - Test - </button> -</div> -`; - -exports[`loads and displays CCloseButton component 1`] = ` -<div> - <button - aria-label="Close" - class="btn btn-close" - type="button" - > - Test - </button> -</div> -`; diff --git a/packages/coreui-react/src/components/button/index.ts b/packages/coreui-react/src/components/button/index.ts deleted file mode 100644 index ad90d817..00000000 --- a/packages/coreui-react/src/components/button/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CButton } from './CButton' - -export { CButton } diff --git a/packages/coreui-react/src/components/callout/CCallout.tsx b/packages/coreui-react/src/components/callout/CCallout.tsx deleted file mode 100644 index d0f65224..00000000 --- a/packages/coreui-react/src/components/callout/CCallout.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CCalloutProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors -} - -export const CCallout = forwardRef<HTMLDivElement, CCalloutProps>( - ({ children, className, color, ...rest }, ref) => { - return ( - <div - className={classNames( - 'callout', - { - [`callout-${color}`]: color, - }, - className, - )} - {...rest} - ref={ref} - > - {children} - </div> - ) - }, -) - -CCallout.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, -} - -CCallout.displayName = 'CCallout' diff --git a/packages/coreui-react/src/components/callout/__tests__/CCallout.spec.tsx b/packages/coreui-react/src/components/callout/__tests__/CCallout.spec.tsx deleted file mode 100644 index 86f63675..00000000 --- a/packages/coreui-react/src/components/callout/__tests__/CCallout.spec.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCallout } from '../../../index' - -test('loads and displays CCallout component', async () => { - const { container } = render(<CCallout>Test</CCallout>) - expect(container).toMatchSnapshot() -}) - -test('CCallout customize', async () => { - const { container } = render( - <CCallout className="bazinga" color="primary"> - Test - </CCallout>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('callout') - expect(container.firstChild).toHaveClass('callout-primary') -}) diff --git a/packages/coreui-react/src/components/callout/__tests__/__snapshots__/CCallout.spec.tsx.snap b/packages/coreui-react/src/components/callout/__tests__/__snapshots__/CCallout.spec.tsx.snap deleted file mode 100644 index f11a87de..00000000 --- a/packages/coreui-react/src/components/callout/__tests__/__snapshots__/CCallout.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCallout customize 1`] = ` -<div> - <div - class="callout callout-primary bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CCallout component 1`] = ` -<div> - <div - class="callout" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/callout/index.ts b/packages/coreui-react/src/components/callout/index.ts deleted file mode 100644 index ebf0d06e..00000000 --- a/packages/coreui-react/src/components/callout/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CCallout } from './CCallout' - -export { CCallout } diff --git a/packages/coreui-react/src/components/card/CCard.tsx b/packages/coreui-react/src/components/card/CCard.tsx deleted file mode 100644 index 81c5bce7..00000000 --- a/packages/coreui-react/src/components/card/CCard.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CCardProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Sets the text color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | 'primary-emphasis' | 'secondary-emphasis' | 'success-emphasis' | 'danger-emphasis' | 'warning-emphasis' | 'info-emphasis' | 'light-emphasis' | 'body' | 'body-emphasis' | 'body-secondary' | 'body-tertiary' | 'black' | 'black-50' | 'white' | 'white-50' | string - */ - textColor?: string -} - -export const CCard = forwardRef<HTMLDivElement, CCardProps>( - ({ children, className, color, textColor, ...rest }, ref) => { - return ( - <div - className={classNames( - 'card', - { - [`bg-${color}`]: color, - [`text-${textColor}`]: textColor, - }, - className, - )} - {...rest} - ref={ref} - > - {children} - </div> - ) - }, -) - -CCard.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, - textColor: PropTypes.string, -} - -CCard.displayName = 'CCard' diff --git a/packages/coreui-react/src/components/card/CCardBody.tsx b/packages/coreui-react/src/components/card/CCardBody.tsx deleted file mode 100644 index f977e837..00000000 --- a/packages/coreui-react/src/components/card/CCardBody.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CCardBodyProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CCardBody = forwardRef<HTMLDivElement, CCardBodyProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('card-body', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -CCardBody.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CCardBody.displayName = 'CCardBody' diff --git a/packages/coreui-react/src/components/card/CCardFooter.tsx b/packages/coreui-react/src/components/card/CCardFooter.tsx deleted file mode 100644 index 054f2851..00000000 --- a/packages/coreui-react/src/components/card/CCardFooter.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import PropTypes from 'prop-types' -import React, { forwardRef, HTMLAttributes } from 'react' -import classNames from 'classnames' - -export interface CCardFooterProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CCardFooter = forwardRef<HTMLDivElement, CCardFooterProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('card-footer', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -CCardFooter.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CCardFooter.displayName = 'CCardFooter' diff --git a/packages/coreui-react/src/components/card/CCardGroup.tsx b/packages/coreui-react/src/components/card/CCardGroup.tsx deleted file mode 100644 index 042e6ade..00000000 --- a/packages/coreui-react/src/components/card/CCardGroup.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CCardGroupProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CCardGroup = forwardRef<HTMLDivElement, CCardGroupProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('card-group', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -CCardGroup.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CCardGroup.displayName = 'CCardGroup' diff --git a/packages/coreui-react/src/components/card/CCardHeader.tsx b/packages/coreui-react/src/components/card/CCardHeader.tsx deleted file mode 100644 index 216a2934..00000000 --- a/packages/coreui-react/src/components/card/CCardHeader.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CCardHeaderProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CCardHeader = forwardRef<HTMLDivElement, CCardHeaderProps>( - ({ children, component: Component = 'div', className, ...rest }, ref) => { - return ( - <Component className={classNames('card-header', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CCardHeader.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CCardHeader.displayName = 'CCardHeader' diff --git a/packages/coreui-react/src/components/card/CCardImage.tsx b/packages/coreui-react/src/components/card/CCardImage.tsx deleted file mode 100644 index 085d7e21..00000000 --- a/packages/coreui-react/src/components/card/CCardImage.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { ElementType, forwardRef, ImgHTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CCardImageProps - extends ImgHTMLAttributes<HTMLImageElement | HTMLOrSVGElement | HTMLOrSVGImageElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Optionally orientate the image to the top, bottom, or make it overlaid across the card. - */ - orientation?: 'top' | 'bottom' -} - -export const CCardImage = forwardRef< - HTMLImageElement | HTMLOrSVGElement | HTMLOrSVGImageElement, - CCardImageProps ->(({ children, className, component: Component = 'img', orientation, ...rest }, ref) => { - return ( - <Component - className={classNames(orientation ? `card-img-${orientation}` : 'card-img', className)} - {...rest} - ref={ref} - > - {children} - </Component> - ) -}) - -CCardImage.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, - orientation: PropTypes.oneOf(['top', 'bottom']), -} - -CCardImage.displayName = 'CCardImage' diff --git a/packages/coreui-react/src/components/card/CCardImageOverlay.tsx b/packages/coreui-react/src/components/card/CCardImageOverlay.tsx deleted file mode 100644 index 7f8ba71a..00000000 --- a/packages/coreui-react/src/components/card/CCardImageOverlay.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CCardImageOverlayProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CCardImageOverlay = forwardRef<HTMLDivElement, CCardImageOverlayProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('card-img-overlay', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -CCardImageOverlay.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CCardImageOverlay.displayName = 'CCardImageOverlay' diff --git a/packages/coreui-react/src/components/card/CCardLink.tsx b/packages/coreui-react/src/components/card/CCardLink.tsx deleted file mode 100644 index 9bf10db0..00000000 --- a/packages/coreui-react/src/components/card/CCardLink.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React, { AnchorHTMLAttributes, forwardRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CLink } from '../link/CLink' - -export interface CCardLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * The href attribute specifies the URL of the page the link goes to. - */ - href?: string -} - -export const CCardLink = forwardRef<HTMLAnchorElement, CCardLinkProps>( - ({ children, className, ...rest }, ref) => { - return ( - <CLink className={classNames('card-link', className)} {...rest} ref={ref}> - {children} - </CLink> - ) - }, -) - -CCardLink.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CCardLink.displayName = 'CCardLink' diff --git a/packages/coreui-react/src/components/card/CCardSubtitle.tsx b/packages/coreui-react/src/components/card/CCardSubtitle.tsx deleted file mode 100644 index b0ac9553..00000000 --- a/packages/coreui-react/src/components/card/CCardSubtitle.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CCardSubtitleProps extends HTMLAttributes<HTMLHeadingElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} -export const CCardSubtitle = forwardRef<HTMLHeadingElement, CCardSubtitleProps>( - ({ children, component: Component = 'h6', className, ...rest }, ref) => { - return ( - <Component className={classNames('card-subtitle', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CCardSubtitle.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CCardSubtitle.displayName = 'CCardSubtitle' diff --git a/packages/coreui-react/src/components/card/CCardText.tsx b/packages/coreui-react/src/components/card/CCardText.tsx deleted file mode 100644 index 96dad0fa..00000000 --- a/packages/coreui-react/src/components/card/CCardText.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CCardTextProps extends HTMLAttributes<HTMLParagraphElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CCardText = forwardRef<HTMLParagraphElement, CCardTextProps>( - ({ children, component: Component = 'p', className, ...rest }, ref) => { - return ( - <Component className={classNames('card-text', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CCardText.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CCardText.displayName = 'CCardText' diff --git a/packages/coreui-react/src/components/card/CCardTitle.tsx b/packages/coreui-react/src/components/card/CCardTitle.tsx deleted file mode 100644 index 97e9547d..00000000 --- a/packages/coreui-react/src/components/card/CCardTitle.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CCardTitleProps extends HTMLAttributes<HTMLHeadingElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CCardTitle = forwardRef<HTMLHeadingElement, CCardTitleProps>( - ({ children, component: Component = 'h5', className, ...rest }, ref) => { - return ( - <Component className={classNames('card-title', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CCardTitle.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CCardTitle.displayName = 'CCardTitle' diff --git a/packages/coreui-react/src/components/card/__tests__/CCard.spec.tsx b/packages/coreui-react/src/components/card/__tests__/CCard.spec.tsx deleted file mode 100644 index c22e6080..00000000 --- a/packages/coreui-react/src/components/card/__tests__/CCard.spec.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCard } from '../../../index' - -test('loads and displays CCard component', async () => { - const { container } = render(<CCard>Test</CCard>) - expect(container).toMatchSnapshot() -}) - -test('CCard customize', async () => { - const { container } = render( - <CCard className="bazinga" color="primary" textColor="warning"> - Test - </CCard>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card') - expect(container.firstChild).toHaveClass('bg-primary') - expect(container.firstChild).toHaveClass('text-warning') -}) diff --git a/packages/coreui-react/src/components/card/__tests__/CCardBody.spec.tsx b/packages/coreui-react/src/components/card/__tests__/CCardBody.spec.tsx deleted file mode 100644 index 8b79b9f5..00000000 --- a/packages/coreui-react/src/components/card/__tests__/CCardBody.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCardBody } from '../../../index' - -test('loads and displays CCardBody component', async () => { - const { container } = render(<CCardBody>Test</CCardBody>) - expect(container).toMatchSnapshot() -}) - -test('CCardBody customize', async () => { - const { container } = render(<CCardBody className="bazinga">Test</CCardBody>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card-body') -}) diff --git a/packages/coreui-react/src/components/card/__tests__/CCardFooter.spec.tsx b/packages/coreui-react/src/components/card/__tests__/CCardFooter.spec.tsx deleted file mode 100644 index 0b47f51f..00000000 --- a/packages/coreui-react/src/components/card/__tests__/CCardFooter.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCardFooter } from '../../../index' - -test('loads and displays CCardFooter component', async () => { - const { container } = render(<CCardFooter>Test</CCardFooter>) - expect(container).toMatchSnapshot() -}) - -test('CCardFooter customize', async () => { - const { container } = render(<CCardFooter className="bazinga">Test</CCardFooter>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card-footer') -}) diff --git a/packages/coreui-react/src/components/card/__tests__/CCardGroup.spec.tsx b/packages/coreui-react/src/components/card/__tests__/CCardGroup.spec.tsx deleted file mode 100644 index dee87030..00000000 --- a/packages/coreui-react/src/components/card/__tests__/CCardGroup.spec.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { - CCard, - CCardBody, - CCardFooter, - CCardHeader, - CCardImage, - CCardLink, - CCardSubtitle, - CCardTitle, - CCardText, - CCardGroup, -} from '../../../index' - -test('loads and displays CCardGroup component', async () => { - const { container } = render(<CCardGroup>Test</CCardGroup>) - expect(container).toMatchSnapshot() -}) - -test('CCardGroup customize', async () => { - const { container } = render(<CCardGroup className="bazinga">Test</CCardGroup>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card-group') -}) - -test('CCardGroup full example', async () => { - const { container } = render( - <CCardGroup className="bazinga"> - <CCard> - <CCardImage component="svg">Image</CCardImage> - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>Title</CCardTitle> - <CCardSubtitle>Subtitle</CCardSubtitle> - <CCardText>Text</CCardText> - <CCardLink>Link</CCardLink> - </CCardBody> - <CCardFooter>Footer</CCardFooter> - </CCard> - <CCard> - <CCardBody> - <CCardTitle>Card Title</CCardTitle> - </CCardBody> - </CCard> - </CCardGroup>, - ) - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/card/__tests__/CCardHeader.spec.tsx b/packages/coreui-react/src/components/card/__tests__/CCardHeader.spec.tsx deleted file mode 100644 index f2b52991..00000000 --- a/packages/coreui-react/src/components/card/__tests__/CCardHeader.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCardHeader } from '../../../index' - -test('loads and displays CCardHeader component', async () => { - const { container } = render(<CCardHeader>Test</CCardHeader>) - expect(container).toMatchSnapshot() -}) - -test('CCardHeader customize', async () => { - const { container } = render( - <CCardHeader className="bazinga" component="h3"> - Test - </CCardHeader>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card-header') -}) diff --git a/packages/coreui-react/src/components/card/__tests__/CCardImage.spec.tsx b/packages/coreui-react/src/components/card/__tests__/CCardImage.spec.tsx deleted file mode 100644 index dfac7e2b..00000000 --- a/packages/coreui-react/src/components/card/__tests__/CCardImage.spec.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCardImage } from '../../../index' - -test('loads and displays CCardImage component', async () => { - const { container } = render(<CCardImage />) - expect(container).toMatchSnapshot() -}) - -test('CCardImage customize', async () => { - const { container } = render( - <CCardImage className="bazinga" component="div" orientation="bottom" />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card-img-bottom') -}) diff --git a/packages/coreui-react/src/components/card/__tests__/CCardImageOverlay.spec.tsx b/packages/coreui-react/src/components/card/__tests__/CCardImageOverlay.spec.tsx deleted file mode 100644 index d161d9c2..00000000 --- a/packages/coreui-react/src/components/card/__tests__/CCardImageOverlay.spec.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCardImageOverlay } from '../../../index' - -test('loads and displays CCardImageOverlay component', async () => { - const { container } = render(<CCardImageOverlay />) - expect(container).toMatchSnapshot() -}) - -test('CCardImageOverlay customize', async () => { - const { container } = render(<CCardImageOverlay className="bazinga">Test</CCardImageOverlay>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('card-img-overlay') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/card/__tests__/CCardLink.spec.tsx b/packages/coreui-react/src/components/card/__tests__/CCardLink.spec.tsx deleted file mode 100644 index 2251ac29..00000000 --- a/packages/coreui-react/src/components/card/__tests__/CCardLink.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCardLink } from '../../../index' - -test('loads and displays CCardLink component', async () => { - const { container } = render(<CCardLink>Test</CCardLink>) - expect(container).toMatchSnapshot() -}) - -test('CCardLink customize', async () => { - const { container } = render( - <CCardLink className="bazinga" href="/bazinga"> - Test - </CCardLink>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card-link') -}) diff --git a/packages/coreui-react/src/components/card/__tests__/CCardSubtitle.spec.tsx b/packages/coreui-react/src/components/card/__tests__/CCardSubtitle.spec.tsx deleted file mode 100644 index edc5719b..00000000 --- a/packages/coreui-react/src/components/card/__tests__/CCardSubtitle.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCardSubtitle } from '../../../index' - -test('loads and displays CCardSubtitle component', async () => { - const { container } = render(<CCardSubtitle>Test</CCardSubtitle>) - expect(container).toMatchSnapshot() -}) - -test('CCardSubtitle customize', async () => { - const { container } = render( - <CCardSubtitle className="bazinga" component="h3"> - Test - </CCardSubtitle>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card-subtitle') -}) diff --git a/packages/coreui-react/src/components/card/__tests__/CCardText.spec.tsx b/packages/coreui-react/src/components/card/__tests__/CCardText.spec.tsx deleted file mode 100644 index df946b3d..00000000 --- a/packages/coreui-react/src/components/card/__tests__/CCardText.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCardText } from '../../../index' - -test('loads and displays CCardText component', async () => { - const { container } = render(<CCardText>Test</CCardText>) - expect(container).toMatchSnapshot() -}) - -test('CCardText customize', async () => { - const { container } = render( - <CCardText className="bazinga" component="h3"> - Test - </CCardText>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card-text') -}) diff --git a/packages/coreui-react/src/components/card/__tests__/CCardTitle.spec.tsx b/packages/coreui-react/src/components/card/__tests__/CCardTitle.spec.tsx deleted file mode 100644 index cac0caa7..00000000 --- a/packages/coreui-react/src/components/card/__tests__/CCardTitle.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCardTitle } from '../../../index' - -test('loads and displays CCardTitle component', async () => { - const { container } = render(<CCardTitle>Test</CCardTitle>) - expect(container).toMatchSnapshot() -}) - -test('CCardTitle customize', async () => { - const { container } = render( - <CCardTitle className="bazinga" component="h3"> - Test - </CCardTitle>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card-title') -}) diff --git a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCard.spec.tsx.snap b/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCard.spec.tsx.snap deleted file mode 100644 index 974a299e..00000000 --- a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCard.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCard customize 1`] = ` -<div> - <div - class="card bg-primary text-warning bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CCard component 1`] = ` -<div> - <div - class="card" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardBody.spec.tsx.snap b/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardBody.spec.tsx.snap deleted file mode 100644 index 9944febc..00000000 --- a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardBody.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCardBody customize 1`] = ` -<div> - <div - class="card-body bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CCardBody component 1`] = ` -<div> - <div - class="card-body" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardFooter.spec.tsx.snap b/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardFooter.spec.tsx.snap deleted file mode 100644 index 21370454..00000000 --- a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardFooter.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCardFooter customize 1`] = ` -<div> - <div - class="card-footer bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CCardFooter component 1`] = ` -<div> - <div - class="card-footer" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardGroup.spec.tsx.snap b/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardGroup.spec.tsx.snap deleted file mode 100644 index ede6c3bb..00000000 --- a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardGroup.spec.tsx.snap +++ /dev/null @@ -1,86 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCardGroup customize 1`] = ` -<div> - <div - class="card-group bazinga" - > - Test - </div> -</div> -`; - -exports[`CCardGroup full example 1`] = ` -<div> - <div - class="card-group bazinga" - > - <div - class="card" - > - <svg - class="card-img" - > - Image - </svg> - <div - class="card-header" - > - Header - </div> - <div - class="card-body" - > - <h5 - class="card-title" - > - Title - </h5> - <h6 - class="card-subtitle" - > - Subtitle - </h6> - <p - class="card-text" - > - Text - </p> - <a - class="card-link" - > - Link - </a> - </div> - <div - class="card-footer" - > - Footer - </div> - </div> - <div - class="card" - > - <div - class="card-body" - > - <h5 - class="card-title" - > - Card Title - </h5> - </div> - </div> - </div> -</div> -`; - -exports[`loads and displays CCardGroup component 1`] = ` -<div> - <div - class="card-group" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardHeader.spec.tsx.snap b/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardHeader.spec.tsx.snap deleted file mode 100644 index a2a1b231..00000000 --- a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardHeader.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCardHeader customize 1`] = ` -<div> - <h3 - class="card-header bazinga" - > - Test - </h3> -</div> -`; - -exports[`loads and displays CCardHeader component 1`] = ` -<div> - <div - class="card-header" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardImage.spec.tsx.snap b/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardImage.spec.tsx.snap deleted file mode 100644 index 1d0e0b69..00000000 --- a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardImage.spec.tsx.snap +++ /dev/null @@ -1,17 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCardImage customize 1`] = ` -<div> - <div - class="card-img-bottom bazinga" - /> -</div> -`; - -exports[`loads and displays CCardImage component 1`] = ` -<div> - <img - class="card-img" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardImageOverlay.spec.tsx.snap b/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardImageOverlay.spec.tsx.snap deleted file mode 100644 index 5de8dbbc..00000000 --- a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardImageOverlay.spec.tsx.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCardImageOverlay customize 1`] = ` -<div> - <div - class="card-img-overlay bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CCardImageOverlay component 1`] = ` -<div> - <div - class="card-img-overlay" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardLink.spec.tsx.snap b/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardLink.spec.tsx.snap deleted file mode 100644 index 5e588fe2..00000000 --- a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardLink.spec.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCardLink customize 1`] = ` -<div> - <a - class="card-link bazinga" - href="/bazinga" - > - Test - </a> -</div> -`; - -exports[`loads and displays CCardLink component 1`] = ` -<div> - <a - class="card-link" - > - Test - </a> -</div> -`; diff --git a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardSubtitle.spec.tsx.snap b/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardSubtitle.spec.tsx.snap deleted file mode 100644 index 67eddd18..00000000 --- a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardSubtitle.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCardSubtitle customize 1`] = ` -<div> - <h3 - class="card-subtitle bazinga" - > - Test - </h3> -</div> -`; - -exports[`loads and displays CCardSubtitle component 1`] = ` -<div> - <h6 - class="card-subtitle" - > - Test - </h6> -</div> -`; diff --git a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardText.spec.tsx.snap b/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardText.spec.tsx.snap deleted file mode 100644 index 11805df4..00000000 --- a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardText.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCardText customize 1`] = ` -<div> - <h3 - class="card-text bazinga" - > - Test - </h3> -</div> -`; - -exports[`loads and displays CCardText component 1`] = ` -<div> - <p - class="card-text" - > - Test - </p> -</div> -`; diff --git a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardTitle.spec.tsx.snap b/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardTitle.spec.tsx.snap deleted file mode 100644 index e8ba2c9a..00000000 --- a/packages/coreui-react/src/components/card/__tests__/__snapshots__/CCardTitle.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCardTitle customize 1`] = ` -<div> - <h3 - class="card-title bazinga" - > - Test - </h3> -</div> -`; - -exports[`loads and displays CCardTitle component 1`] = ` -<div> - <h5 - class="card-title" - > - Test - </h5> -</div> -`; diff --git a/packages/coreui-react/src/components/card/index.ts b/packages/coreui-react/src/components/card/index.ts deleted file mode 100644 index 21c35dd8..00000000 --- a/packages/coreui-react/src/components/card/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { CCard } from './CCard' -import { CCardBody } from './CCardBody' -import { CCardFooter } from './CCardFooter' -import { CCardGroup } from './CCardGroup' -import { CCardHeader } from './CCardHeader' -import { CCardImage } from './CCardImage' -import { CCardImageOverlay } from './CCardImageOverlay' -import { CCardLink } from './CCardLink' -import { CCardSubtitle } from './CCardSubtitle' -import { CCardText } from './CCardText' -import { CCardTitle } from './CCardTitle' - -export { - CCard, - CCardBody, - CCardFooter, - CCardGroup, - CCardHeader, - CCardImage, - CCardImageOverlay, - CCardLink, - CCardSubtitle, - CCardText, - CCardTitle, -} diff --git a/packages/coreui-react/src/components/carousel/CCarousel.tsx b/packages/coreui-react/src/components/carousel/CCarousel.tsx deleted file mode 100644 index 4e7e95ca..00000000 --- a/packages/coreui-react/src/components/carousel/CCarousel.tsx +++ /dev/null @@ -1,310 +0,0 @@ -import React, { - Children, - createContext, - forwardRef, - HTMLAttributes, - TouchEvent, - useState, - useEffect, - useRef, -} from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { isInViewport } from '../../utils' -import { useForkedRef } from '../../hooks' - -export interface CCarouselProps extends HTMLAttributes<HTMLDivElement> { - /** - * index of the active item. - */ - activeIndex?: number - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Adding in the previous and next controls. - */ - controls?: boolean - /** - * Add darker controls, indicators, and captions. - */ - dark?: boolean - /** - * The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle. - */ - interval?: boolean | number - /** - * Adding indicators at the bottom of the carousel for each item. - */ - indicators?: boolean - /** - * Callback fired when a slide transition end. - */ - onSlid?: (active: number, direction: string) => void - /** - * Callback fired when a slide transition starts. - */ - onSlide?: (active: number, direction: string) => void - /** - * If set to 'hover', pauses the cycling of the carousel on mouseenter and resumes the cycling of the carousel on mouseleave. If set to false, hovering over the carousel won't pause it. - */ - pause?: boolean | 'hover' - /** - * Set whether the carousel should support left/right swipe interactions on touchscreen devices. - * - * @since 4.5.0 - */ - touch?: boolean - /** - * Set type of the transition. - */ - transition?: 'slide' | 'crossfade' - /** - * Set whether the carousel should cycle continuously or have hard stops. - */ - wrap?: boolean -} - -interface DataType { - timeout?: null | ReturnType<typeof setTimeout> -} - -export interface ContextProps { - setAnimating: (a: boolean) => void - setCustomInterval: (a: boolean | number) => void -} - -export const CCarouselContext = createContext({} as ContextProps) - -export const CCarousel = forwardRef<HTMLDivElement, CCarouselProps>( - ( - { - children, - activeIndex = 0, - className, - controls, - dark, - indicators, - interval = 5000, - onSlid, - onSlide, - pause = 'hover', - touch = true, - transition, - wrap = true, - ...rest - }, - ref, - ) => { - const carouselRef = useRef<HTMLDivElement>(null) - const forkedRef = useForkedRef(ref, carouselRef) - const data = useRef<DataType>({}).current - - const [active, setActive] = useState<number>(activeIndex) - const [animating, setAnimating] = useState<boolean>(false) - const [customInterval, setCustomInterval] = useState<boolean | number>() - const [direction, setDirection] = useState<string>('next') - const [itemsNumber, setItemsNumber] = useState<number>(0) - const [touchPosition, setTouchPosition] = useState<number | null>(null) - const [visible, setVisible] = useState<boolean>() - - useEffect(() => { - setItemsNumber(Children.toArray(children).length) - }) - - useEffect(() => { - visible && cycle() - }, [visible]) - - useEffect(() => { - !animating && cycle() - !animating && onSlid && onSlid(active, direction) - animating && onSlide && onSlide(active, direction) - }, [animating]) - - useEffect(() => { - window.addEventListener('scroll', handleScroll) - - return () => { - window.removeEventListener('scroll', handleScroll) - } - }) - - const cycle = () => { - _pause() - if (!wrap && active === itemsNumber - 1) { - return - } - - if (typeof interval === 'number') { - data.timeout = setTimeout( - () => nextItemWhenVisible(), - typeof customInterval === 'number' ? customInterval : interval, - ) - } - } - const _pause = () => pause && data.timeout && clearTimeout(data.timeout) - - const nextItemWhenVisible = () => { - // Don't call next when the page isn't visible - // or the carousel or its parent isn't visible - if (!document.hidden && carouselRef.current && isInViewport(carouselRef.current)) { - if (animating) { - return - } - handleControlClick('next') - } - } - - const handleControlClick = (direction: string) => { - if (animating) { - return - } - setDirection(direction) - if (direction === 'next') { - active === itemsNumber - 1 ? setActive(0) : setActive(active + 1) - } else { - active === 0 ? setActive(itemsNumber - 1) : setActive(active - 1) - } - } - - const handleIndicatorClick = (index: number) => { - if (active === index) { - return - } - - if (active < index) { - setDirection('next') - setActive(index) - return - } - - if (active > index) { - setDirection('prev') - setActive(index) - } - } - - const handleScroll = () => { - if (!document.hidden && carouselRef.current && isInViewport(carouselRef.current)) { - setVisible(true) - } else { - setVisible(false) - } - } - - const handleTouchMove = (e: TouchEvent) => { - const touchDown = touchPosition - - if (touchDown === null) { - return - } - - const currentTouch = e.touches[0].clientX - const diff = touchDown - currentTouch - - if (diff > 5) { - handleControlClick('next') - } - - if (diff < -5) { - handleControlClick('prev') - } - - setTouchPosition(null) - } - - const handleTouchStart = (e: TouchEvent) => { - const touchDown = e.touches[0].clientX - setTouchPosition(touchDown) - } - - return ( - <div - className={classNames( - 'carousel slide', - { - 'carousel-fade': transition === 'crossfade', - }, - className, - )} - {...(dark && { 'data-coreui-theme': 'dark' })} - onMouseEnter={_pause} - onMouseLeave={cycle} - {...(touch && { onTouchStart: handleTouchStart, onTouchMove: handleTouchMove })} - {...rest} - ref={forkedRef} - > - <CCarouselContext.Provider - value={{ - setAnimating, - setCustomInterval, - }} - > - {indicators && ( - <div className="carousel-indicators"> - {Array.from({ length: itemsNumber }, (_, i) => i).map((index) => { - return ( - <button - key={`indicator${index}`} - onClick={() => { - !animating && handleIndicatorClick(index) - }} - className={classNames({ - active: active === index, - })} - data-coreui-target="" - {...(active === index && { 'aria-current': true })} - aria-label={`Slide ${index + 1}`} - /> - ) - })} - </div> - )} - <div className="carousel-inner"> - {Children.map(children, (child, index) => { - if (React.isValidElement(child)) { - return React.cloneElement(child as React.ReactElement<any>, { - active: active === index ? true : false, - direction: direction, - key: index, - }) - } - return - })} - </div> - {controls && ( - <> - <button className="carousel-control-prev" onClick={() => handleControlClick('prev')}> - <span className={`carousel-control-prev-icon`} aria-label="prev" /> - </button> - <button className="carousel-control-next" onClick={() => handleControlClick('next')}> - <span className={`carousel-control-next-icon`} aria-label="next" /> - </button> - </> - )} - </CCarouselContext.Provider> - </div> - ) - }, -) - -CCarousel.propTypes = { - activeIndex: PropTypes.number, - children: PropTypes.node, - className: PropTypes.string, - controls: PropTypes.bool, - dark: PropTypes.bool, - indicators: PropTypes.bool, - interval: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]), - onSlid: PropTypes.func, - onSlide: PropTypes.func, - pause: PropTypes.oneOf([false, 'hover']), - touch: PropTypes.bool, - transition: PropTypes.oneOf(['slide', 'crossfade']), - wrap: PropTypes.bool, -} - -CCarousel.displayName = 'CCarousel' diff --git a/packages/coreui-react/src/components/carousel/CCarouselCaption.tsx b/packages/coreui-react/src/components/carousel/CCarouselCaption.tsx deleted file mode 100644 index 6e1cd5d1..00000000 --- a/packages/coreui-react/src/components/carousel/CCarouselCaption.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CCarouselCaptionProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CCarouselCaption = forwardRef<HTMLDivElement, CCarouselCaptionProps>( - ({ className, ...rest }, ref) => { - return <div className={classNames('carousel-caption', className)} {...rest} ref={ref} /> - }, -) - -CCarouselCaption.propTypes = { - className: PropTypes.string, -} - -CCarouselCaption.displayName = 'CCarouselCaption' diff --git a/packages/coreui-react/src/components/carousel/CCarouselItem.tsx b/packages/coreui-react/src/components/carousel/CCarouselItem.tsx deleted file mode 100644 index 3b8744cc..00000000 --- a/packages/coreui-react/src/components/carousel/CCarouselItem.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useContext, useEffect, useState, useRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { useForkedRef } from '../../hooks' -import { CCarouselContext } from './CCarousel' -export interface CCarouselItemProps extends HTMLAttributes<HTMLDivElement> { - /** - * @ignore - */ - active?: boolean - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * @ignore - */ - direction?: string - /** - * The amount of time to delay between automatically cycling an item. - */ - interval?: boolean | number -} - -export const CCarouselItem = forwardRef<HTMLDivElement, CCarouselItemProps>( - ({ children, className, active, direction, interval = false, ...rest }, ref) => { - const { setAnimating, setCustomInterval } = useContext(CCarouselContext) - const carouselItemRef = useRef<HTMLDivElement>(null) - const forkedRef = useForkedRef(ref, carouselItemRef) - - const prevActive = useRef<boolean>() - const [directionClassName, setDirectionClassName] = useState<string>() - const [orderClassName, setOrderClassName] = useState<string>() - const [activeClassName, setActiveClassName] = useState(active && 'active') - const [count, setCount] = useState(0) - - useEffect(() => { - if (active) { - setCustomInterval(interval) - if (count !== 0) setOrderClassName(`carousel-item-${direction}`) - } - - if (prevActive.current && !active) { - setActiveClassName('active') - } - - if (active || prevActive.current) { - setTimeout(() => { - if (count !== 0) { - // @ts-expect-error reflow is necessary to proper transition - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const reflow = carouselItemRef.current?.offsetHeight - setDirectionClassName(`carousel-item-${direction === 'next' ? 'start' : 'end'}`) - } - }, 0) - } - - prevActive.current = active - - if (count === 0) setCount(count + 1) - }, [active]) - - useEffect(() => { - carouselItemRef.current?.addEventListener('transitionstart', () => { - active && setAnimating(true) - }) - carouselItemRef.current?.addEventListener('transitionend', () => { - active && setAnimating(false) - setDirectionClassName('') - setOrderClassName('') - if (active) { - setActiveClassName('active') - } - if (!active) { - setActiveClassName('') - } - }) - return () => { - carouselItemRef.current?.removeEventListener('transitionstart', () => { - active && setAnimating(true) - }) - carouselItemRef.current?.removeEventListener('transitionend', () => { - active && setAnimating(false) - setDirectionClassName('') - setOrderClassName('') - if (active) { - setActiveClassName('active') - } - if (!active) { - setActiveClassName('') - } - }) - } - }) - - return ( - <div - className={classNames( - 'carousel-item', - activeClassName, - directionClassName, - orderClassName, - className, - )} - ref={forkedRef} - {...rest} - > - {children} - </div> - ) - }, -) - -CCarouselItem.propTypes = { - active: PropTypes.bool, - children: PropTypes.node, - className: PropTypes.string, - direction: PropTypes.string, - interval: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]), -} - -CCarouselItem.displayName = 'CCarouselItem' diff --git a/packages/coreui-react/src/components/carousel/__tests__/CCarousel.spec.tsx b/packages/coreui-react/src/components/carousel/__tests__/CCarousel.spec.tsx deleted file mode 100644 index 4abb647b..00000000 --- a/packages/coreui-react/src/components/carousel/__tests__/CCarousel.spec.tsx +++ /dev/null @@ -1,149 +0,0 @@ -import React from 'react' -import { render, fireEvent } from '@testing-library/react' -import { getByText } from '@testing-library/dom' -import '@testing-library/jest-dom' -import { CCarousel, CCarouselCaption, CCarouselItem } from '../../../index' - -test('loads and displays CCarousel component', async () => { - const { container } = render( - <CCarousel controls indicators> - <CCarouselItem> - Item-1 - <CCarouselCaption>Caption-1</CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - Item-2 - <CCarouselCaption>Caption-2</CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - Item-3 - <CCarouselCaption>Caption-3</CCarouselCaption> - </CCarouselItem> - </CCarousel>, - ) - - const carousel = document.querySelector('.carousel') - expect(carousel).toHaveClass('slide') - if (carousel === null) { - expect(true).toBe(false) - } else { - expect(carousel.children[0]).toHaveClass('carousel-indicators') - expect(carousel.children[1]).toHaveClass('carousel-inner') - } - - let caption = getByText(container, 'Caption-1') - expect(caption).toHaveClass('carousel-caption') - caption = getByText(container, 'Caption-2') - expect(caption).toHaveClass('carousel-caption') - caption = getByText(container, 'Caption-3') - expect(caption).toHaveClass('carousel-caption') - let item = getByText(container, 'Item-1') - expect(item).toHaveClass('carousel-item') - item = getByText(container, 'Item-2') - expect(item).toHaveClass('carousel-item') - item = getByText(container, 'Item-3') - expect(item).toHaveClass('carousel-item') - - let button = document.querySelector('.carousel-control-next') - if (button === null) { - expect(true).toBe(false) - } else { - expect(button.firstChild).toHaveClass('carousel-control-next-icon') - } - button = document.querySelector('.carousel-control-prev') - if (button === null) { - expect(true).toBe(false) - } else { - expect(button.firstChild).toHaveClass('carousel-control-prev-icon') - } - - expect(container).toMatchSnapshot() -}) - -test('CCarousel click on indicator', async () => { - const { container } = render( - <CCarousel controls indicators> - <CCarouselItem> - Item-1 - <CCarouselCaption>Caption-1</CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - Item-2 - <CCarouselCaption>Caption-2</CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - Item-3 - <CCarouselCaption>Caption-3</CCarouselCaption> - </CCarouselItem> - </CCarousel>, - ) - const item1 = getByText(container, 'Item-1') - const item2 = getByText(container, 'Item-2') - - expect(item1).toHaveClass('active') - expect(item1).toHaveClass('carousel-item') - expect(item2).not.toHaveClass('active') - expect(item2).toHaveClass('carousel-item') - - // click - const ci = document.querySelector('.carousel-indicators') - ci && fireEvent.click(ci.children[1]) - fireEvent.transitionEnd(item1) - fireEvent.transitionEnd(item2) - - expect(item1).not.toHaveClass('active') - expect(item2).toHaveClass('active') - - // goback-click - ci && fireEvent.click(ci.children[0]) - fireEvent.transitionEnd(item1) - fireEvent.transitionEnd(item2) - - expect(item1).toHaveClass('active') - expect(item2).not.toHaveClass('active') -}) - -test('CCarousel click on button', async () => { - jest.useFakeTimers() - const { container } = render( - <CCarousel controls indicators> - <CCarouselItem> - Item-1 - <CCarouselCaption>Caption-1</CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - Item-2 - <CCarouselCaption>Caption-2</CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - Item-3 - <CCarouselCaption>Caption-3</CCarouselCaption> - </CCarouselItem> - </CCarousel>, - ) - const item1 = getByText(container, 'Item-1') - const item2 = getByText(container, 'Item-2') - - expect(item1).toHaveClass('active') - expect(item1).toHaveClass('carousel-item') - expect(item2).not.toHaveClass('active') - expect(item2).toHaveClass('carousel-item') - - // click - const buttonNext = document.querySelector('.carousel-control-next') - buttonNext && fireEvent.click(buttonNext) - fireEvent.transitionEnd(item1) - fireEvent.transitionEnd(item2) - - expect(item1).not.toHaveClass('active') - expect(item2).toHaveClass('active') - - // goback-click - const buttonPrev = document.querySelector('.carousel-control-prev') - buttonPrev && fireEvent.click(buttonPrev) - fireEvent.transitionEnd(item1) - fireEvent.transitionEnd(item2) - - expect(item1).toHaveClass('active') - expect(item2).not.toHaveClass('active') -}) diff --git a/packages/coreui-react/src/components/carousel/__tests__/__snapshots__/CCarousel.spec.tsx.snap b/packages/coreui-react/src/components/carousel/__tests__/__snapshots__/CCarousel.spec.tsx.snap deleted file mode 100644 index 5d9045b1..00000000 --- a/packages/coreui-react/src/components/carousel/__tests__/__snapshots__/CCarousel.spec.tsx.snap +++ /dev/null @@ -1,80 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`loads and displays CCarousel component 1`] = ` -<div> - <div - class="carousel slide" - > - <div - class="carousel-indicators" - > - <button - aria-current="true" - aria-label="Slide 1" - class="active" - data-coreui-target="" - /> - <button - aria-label="Slide 2" - class="" - data-coreui-target="" - /> - <button - aria-label="Slide 3" - class="" - data-coreui-target="" - /> - </div> - <div - class="carousel-inner" - > - <div - class="carousel-item active" - > - Item-1 - <div - class="carousel-caption" - > - Caption-1 - </div> - </div> - <div - class="carousel-item" - > - Item-2 - <div - class="carousel-caption" - > - Caption-2 - </div> - </div> - <div - class="carousel-item" - > - Item-3 - <div - class="carousel-caption" - > - Caption-3 - </div> - </div> - </div> - <button - class="carousel-control-prev" - > - <span - aria-label="prev" - class="carousel-control-prev-icon" - /> - </button> - <button - class="carousel-control-next" - > - <span - aria-label="next" - class="carousel-control-next-icon" - /> - </button> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/carousel/index.ts b/packages/coreui-react/src/components/carousel/index.ts deleted file mode 100644 index 7a5e23f5..00000000 --- a/packages/coreui-react/src/components/carousel/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { CCarousel } from './CCarousel' -import { CCarouselCaption } from './CCarouselCaption' -import { CCarouselItem } from './CCarouselItem' - -export { CCarousel, CCarouselCaption, CCarouselItem } diff --git a/packages/coreui-react/src/components/close-button/CCloseButton.tsx b/packages/coreui-react/src/components/close-button/CCloseButton.tsx deleted file mode 100644 index 18c49fed..00000000 --- a/packages/coreui-react/src/components/close-button/CCloseButton.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CCloseButtonProps extends HTMLAttributes<HTMLButtonElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Invert the default color. - */ - dark?: boolean - /** - * Toggle the disabled state for the component. - */ - disabled?: boolean - /** - * Change the default color to white. - * - * @deprecated 5.0.0 - */ - white?: boolean -} - -export const CCloseButton = forwardRef<HTMLButtonElement, CCloseButtonProps>( - ({ className, dark, disabled, white, ...rest }, ref) => { - return ( - <button - type="button" - className={classNames( - 'btn', - 'btn-close', - { - 'btn-close-white': white, - }, - disabled, - className, - )} - aria-label="Close" - disabled={disabled} - {...(dark && { 'data-coreui-theme': 'dark' })} - {...rest} - ref={ref} - /> - ) - }, -) - -CCloseButton.propTypes = { - className: PropTypes.string, - dark: PropTypes.bool, - disabled: PropTypes.bool, - white: PropTypes.bool, -} - -CCloseButton.displayName = 'CCloseButton' diff --git a/packages/coreui-react/src/components/close-button/__tests__/CCloseButton.spec.tsx b/packages/coreui-react/src/components/close-button/__tests__/CCloseButton.spec.tsx deleted file mode 100644 index a70c90ea..00000000 --- a/packages/coreui-react/src/components/close-button/__tests__/CCloseButton.spec.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCloseButton } from '../../../index' - -test('loads and displays CCloseButton component', async () => { - const { container } = render(<CCloseButton />) - const button = document.querySelector('button') - expect(button).toHaveClass('btn') - expect(button).toHaveClass('btn-close') - expect(button).toHaveAttribute('aria-label', 'Close') - expect(container).toMatchSnapshot() -}) - -test('CCloseButton customize', async () => { - const { container } = render(<CCloseButton white={true} disabled={true} className="bazinga" />) - const button = document.querySelector('button') - expect(button).toHaveClass('btn') - expect(button).toHaveClass('btn-close') - expect(button).toHaveClass('btn-close-white') - expect(button).toHaveClass('bazinga') - expect(button).toHaveAttribute('aria-label', 'Close') - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/close-button/__tests__/__snapshots__/CCloseButton.spec.tsx.snap b/packages/coreui-react/src/components/close-button/__tests__/__snapshots__/CCloseButton.spec.tsx.snap deleted file mode 100644 index 6b584a17..00000000 --- a/packages/coreui-react/src/components/close-button/__tests__/__snapshots__/CCloseButton.spec.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCloseButton customize 1`] = ` -<div> - <button - aria-label="Close" - class="btn btn-close btn-close-white bazinga" - disabled="" - type="button" - /> -</div> -`; - -exports[`loads and displays CCloseButton component 1`] = ` -<div> - <button - aria-label="Close" - class="btn btn-close" - type="button" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/close-button/index.ts b/packages/coreui-react/src/components/close-button/index.ts deleted file mode 100644 index 27d5574c..00000000 --- a/packages/coreui-react/src/components/close-button/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CCloseButton } from './CCloseButton' - -export { CCloseButton } diff --git a/packages/coreui-react/src/components/collapse/CCollapse.tsx b/packages/coreui-react/src/components/collapse/CCollapse.tsx deleted file mode 100644 index 4cb2773c..00000000 --- a/packages/coreui-react/src/components/collapse/CCollapse.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useRef, useState } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' -import { CSSTransition } from 'react-transition-group' - -import { useForkedRef } from '../../hooks' - -export interface CCollapseProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Set horizontal collapsing to transition the width instead of height. - */ - horizontal?: boolean - /** - * Callback fired when the component requests to be hidden. - */ - onHide?: () => void - /** - * Callback fired when the component requests to be shown. - */ - onShow?: () => void - /** - * Toggle the visibility of component. - */ - visible?: boolean -} - -export const CCollapse = forwardRef<HTMLDivElement, CCollapseProps>( - ({ children, className, horizontal, onHide, onShow, visible, ...rest }, ref) => { - const collapseRef = useRef<HTMLDivElement>(null) - const forkedRef = useForkedRef(ref, collapseRef) - - const [height, setHeight] = useState<number>() - const [width, setWidth] = useState<number>() - - const onEntering = () => { - onShow && onShow() - - if (horizontal) { - collapseRef.current && setWidth(collapseRef.current.scrollWidth) - return - } - collapseRef.current && setHeight(collapseRef.current.scrollHeight) - } - - const onEntered = () => { - if (horizontal) { - setWidth(0) - return - } - setHeight(0) - } - - const onExit = () => { - if (horizontal) { - collapseRef.current && setWidth(collapseRef.current.scrollWidth) - return - } - collapseRef.current && setHeight(collapseRef.current.scrollHeight) - } - - const onExiting = () => { - onHide && onHide() - if (horizontal) { - setWidth(0) - return - } - setHeight(0) - } - - const onExited = () => { - if (horizontal) { - setWidth(0) - return - } - setHeight(0) - } - - return ( - <CSSTransition - in={visible} - nodeRef={collapseRef} - onEntering={onEntering} - onEntered={onEntered} - onExit={onExit} - onExiting={onExiting} - onExited={onExited} - timeout={350} - > - {(state) => { - const currentHeight = height === 0 ? null : { height } - const currentWidth = width === 0 ? null : { width } - return ( - <div - className={classNames(className, { - 'collapse-horizontal': horizontal, - collapsing: state === 'entering' || state === 'exiting', - 'collapse show': state === 'entered', - collapse: state === 'exited', - })} - style={{ ...currentHeight, ...currentWidth }} - {...rest} - ref={forkedRef} - > - {children} - </div> - ) - }} - </CSSTransition> - ) - }, -) - -CCollapse.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - horizontal: PropTypes.bool, - onHide: PropTypes.func, - onShow: PropTypes.func, - visible: PropTypes.bool, -} - -CCollapse.displayName = 'CCollapse' diff --git a/packages/coreui-react/src/components/collapse/__tests__/CCollapse.spec.tsx b/packages/coreui-react/src/components/collapse/__tests__/CCollapse.spec.tsx deleted file mode 100644 index 7d701afe..00000000 --- a/packages/coreui-react/src/components/collapse/__tests__/CCollapse.spec.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react' -import { render, screen } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCollapse } from '../../../index' - -test('loads and displays CCollapse component', async () => { - const { container } = render(<CCollapse>Test</CCollapse>) - expect(container).toMatchSnapshot() -}) - -test('CCollapse customize', async () => { - const { container } = render(<CCollapse className="bazinga">Test</CCollapse>) - expect(container.firstChild).toHaveClass('bazinga') - expect(container).toMatchSnapshot() -}) - -test('CCollapse use case test', async () => { - const { rerender } = render(<CCollapse visible={false}>Test</CCollapse>) - expect(screen.getByText('Test')).toHaveClass('collapse') - expect(screen.getByText('Test')).not.toHaveClass('show') - expect(screen.getByText('Test')).not.toHaveClass('collapsing') - rerender(<CCollapse visible={true}>Test</CCollapse>) - expect(screen.getByText('Test')).not.toHaveClass('collapse') - expect(screen.getByText('Test')).not.toHaveClass('show') - expect(screen.getByText('Test')).toHaveClass('collapsing') - await new Promise((r) => setTimeout(r, 1000)) - expect(screen.getByText('Test')).toHaveClass('collapse') - expect(screen.getByText('Test')).toHaveClass('show') - expect(screen.getByText('Test')).not.toHaveClass('collapsing') - rerender(<CCollapse visible={false}>Test</CCollapse>) - expect(screen.getByText('Test')).not.toHaveClass('collapse') - expect(screen.getByText('Test')).not.toHaveClass('show') - expect(screen.getByText('Test')).toHaveClass('collapsing') - await new Promise((r) => setTimeout(r, 1000)) - expect(screen.getByText('Test')).toHaveClass('collapse') - expect(screen.getByText('Test')).not.toHaveClass('show') - expect(screen.getByText('Test')).not.toHaveClass('collapsing') - jest.runAllTimers() - jest.useRealTimers() -}) diff --git a/packages/coreui-react/src/components/collapse/__tests__/__snapshots__/CCollapse.spec.tsx.snap b/packages/coreui-react/src/components/collapse/__tests__/__snapshots__/CCollapse.spec.tsx.snap deleted file mode 100644 index b9a9df74..00000000 --- a/packages/coreui-react/src/components/collapse/__tests__/__snapshots__/CCollapse.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCollapse customize 1`] = ` -<div> - <div - class="bazinga collapse" - > - Test - </div> -</div> -`; - -exports[`loads and displays CCollapse component 1`] = ` -<div> - <div - class="collapse" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/collapse/index.ts b/packages/coreui-react/src/components/collapse/index.ts deleted file mode 100644 index f277ff21..00000000 --- a/packages/coreui-react/src/components/collapse/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CCollapse } from './CCollapse' - -export { CCollapse } diff --git a/packages/coreui-react/src/components/conditional-portal/CConditionalPortal.tsx b/packages/coreui-react/src/components/conditional-portal/CConditionalPortal.tsx deleted file mode 100644 index bbbe00cd..00000000 --- a/packages/coreui-react/src/components/conditional-portal/CConditionalPortal.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React, { FC, ReactNode, useEffect, useState } from 'react' -import { createPortal } from 'react-dom' -import PropTypes from 'prop-types' - -const getContainer = (container?: Element | (() => Element | null) | null) => { - if (container) { - return typeof container === 'function' ? container() : container - } - - return document.body -} - -export interface CConditionalPortalProps { - /** - * @ignore - */ - children: ReactNode - /** - * An HTML element or function that returns a single element, with `document.body` as the default. - * - * @since v4.11.0 - */ - container?: Element | (() => Element | null) | null - /** - * Render some children into a different part of the DOM - */ - portal: boolean | any -} - -export const CConditionalPortal: FC<CConditionalPortalProps> = ({ - children, - container, - portal, -}) => { - const [_container, setContainer] = useState<ReturnType<typeof getContainer>>(null) - - useEffect(() => { - portal && setContainer(getContainer(container) || document.body) - }, [container, portal]) - - return typeof window !== 'undefined' && portal && _container ? ( - createPortal(children, _container) - ) : ( - <>{children}</> - ) -} - -CConditionalPortal.propTypes = { - children: PropTypes.node, - container: PropTypes.any, // HTMLElement - portal: PropTypes.bool, -} - -CConditionalPortal.displayName = 'CConditionalPortal' diff --git a/packages/coreui-react/src/components/conditional-portal/index.ts b/packages/coreui-react/src/components/conditional-portal/index.ts deleted file mode 100644 index ab6cc3bc..00000000 --- a/packages/coreui-react/src/components/conditional-portal/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CConditionalPortal } from './CConditionalPortal' - -export { CConditionalPortal } diff --git a/packages/coreui-react/src/components/dropdown/CDropdown.tsx b/packages/coreui-react/src/components/dropdown/CDropdown.tsx deleted file mode 100644 index a019abd4..00000000 --- a/packages/coreui-react/src/components/dropdown/CDropdown.tsx +++ /dev/null @@ -1,301 +0,0 @@ -import React, { - createContext, - ElementType, - forwardRef, - HTMLAttributes, - RefObject, - useEffect, - useRef, - useState, -} from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { useForkedRef, usePopper } from '../../hooks' -import { placementPropType } from '../../props' -import type { Placements } from '../../types' -import { isRTL } from '../../utils' - -import type { Alignments, Directions } from './types' -import { getNextActiveElement, getPlacement } from './utils' - -export interface CDropdownProps extends HTMLAttributes<HTMLDivElement | HTMLLIElement> { - /** - * Set aligment of dropdown menu. - * - * @type 'start' | 'end' | { xs: 'start' | 'end' } | { sm: 'start' | 'end' } | { md: 'start' | 'end' } | { lg: 'start' | 'end' } | { xl: 'start' | 'end'} | { xxl: 'start' | 'end'} - */ - alignment?: Alignments - /** - * Configure the auto close behavior of the dropdown: - * - `true` - the dropdown will be closed by clicking outside or inside the dropdown menu. - * - `false` - the dropdown will be closed by clicking the toggle button and manually calling hide or toggle method. (Also will not be closed by pressing esc key) - * - `'inside'` - the dropdown will be closed (only) by clicking inside the dropdown menu. - * - `'outside'` - the dropdown will be closed (only) by clicking outside the dropdown menu. - */ - autoClose?: 'inside' | 'outside' | boolean - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Appends the react dropdown menu to a specific element. You can pass an HTML element or function that returns a single element. By default `document.body`. - * - * @since v4.11.0 - */ - container?: Element | (() => Element | null) | null - /** - * Sets a darker color scheme to match a dark navbar. - */ - dark?: boolean - /** - * Sets a specified direction and location of the dropdown menu. - */ - direction?: 'center' | 'dropup' | 'dropup-center' | 'dropend' | 'dropstart' - /** - * Offset of the dropdown menu relative to its target. - */ - offset?: [number, number] - /** - * Callback fired when the component requests to be hidden. - * - * @since 4.9.0 - */ - onHide?: () => void - /** - * Callback fired when the component requests to be shown. - */ - onShow?: () => void - /** - * Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. - * - * @type 'auto' | 'top-end' | 'top' | 'top-start' | 'bottom-end' | 'bottom' | 'bottom-start' | 'right-start' | 'right' | 'right-end' | 'left-start' | 'left' | 'left-end' - */ - placement?: Placements - /** - * If you want to disable dynamic positioning set this property to `true`. - */ - popper?: boolean - /** - * Generates dropdown menu using createPortal. - * - * @since 4.8.0 - */ - portal?: boolean - /** - * Set the dropdown variant to an btn-group, dropdown, input-group, and nav-item. - */ - variant?: 'btn-group' | 'dropdown' | 'input-group' | 'nav-item' - /** - * Toggle the visibility of dropdown menu component. - */ - visible?: boolean -} - -interface ContextProps extends CDropdownProps { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - dropdownToggleRef: RefObject<any | undefined> - dropdownMenuRef: RefObject<HTMLDivElement | HTMLUListElement | undefined> - setVisible: React.Dispatch<React.SetStateAction<boolean | undefined>> - portal: boolean -} - -export const CDropdownContext = createContext({} as ContextProps) - -export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownProps>( - ( - { - children, - alignment, - autoClose = true, - className, - container, - dark, - direction, - offset = [0, 2], - onHide, - onShow, - placement = 'bottom-start', - popper = true, - portal = false, - variant = 'btn-group', - component = 'div', - visible = false, - ...rest - }, - ref, - ) => { - const dropdownRef = useRef<HTMLDivElement>(null) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const dropdownToggleRef = useRef<any>(null) - const dropdownMenuRef = useRef<HTMLDivElement | HTMLUListElement>(null) - const forkedRef = useForkedRef(ref, dropdownRef) - const [_visible, setVisible] = useState(visible) - const { initPopper, destroyPopper } = usePopper() - - const Component = variant === 'nav-item' ? 'li' : component - - // Disable popper if responsive aligment is set. - if (typeof alignment === 'object') { - popper = false - } - - const contextValues = { - alignment, - container, - dark, - dropdownToggleRef, - dropdownMenuRef, - popper, - portal, - variant, - visible: _visible, - setVisible, - } - - const popperConfig = { - modifiers: [ - { - name: 'offset', - options: { - offset: offset, - }, - }, - ], - placement: getPlacement(placement, direction, alignment, isRTL(dropdownMenuRef.current)), - } - - useEffect(() => { - setVisible(visible) - }, [visible]) - - useEffect(() => { - if (_visible && dropdownToggleRef.current && dropdownMenuRef.current) { - dropdownToggleRef.current.focus() - popper && initPopper(dropdownToggleRef.current, dropdownMenuRef.current, popperConfig) - window.addEventListener('mouseup', handleMouseUp) - window.addEventListener('keyup', handleKeyup) - dropdownToggleRef.current.addEventListener('keydown', handleKeydown) - dropdownMenuRef.current.addEventListener('keydown', handleKeydown) - onShow && onShow() - } - - return () => { - popper && destroyPopper() - window.removeEventListener('mouseup', handleMouseUp) - window.removeEventListener('keyup', handleKeyup) - dropdownToggleRef.current && - dropdownToggleRef.current.removeEventListener('keydown', handleKeydown) - dropdownMenuRef.current && - dropdownMenuRef.current.removeEventListener('keydown', handleKeydown) - onHide && onHide() - } - }, [_visible]) - - const handleKeydown = (event: KeyboardEvent) => { - if ( - _visible && - dropdownMenuRef.current && - (event.key === 'ArrowDown' || event.key === 'ArrowUp') - ) { - event.preventDefault() - const target = event.target as HTMLElement - const items: HTMLElement[] = Array.from( - dropdownMenuRef.current.querySelectorAll('.dropdown-item:not(.disabled):not(:disabled)'), - ) - getNextActiveElement(items, target, event.key === 'ArrowDown', true).focus() - } - } - - const handleKeyup = (event: KeyboardEvent) => { - if (autoClose === false) { - return - } - - if (event.key === 'Escape') { - setVisible(false) - } - } - - const handleMouseUp = (event: Event) => { - if (!dropdownToggleRef.current || !dropdownMenuRef.current) { - return - } - - if (dropdownToggleRef.current.contains(event.target as HTMLElement)) { - return - } - - if ( - autoClose === true || - (autoClose === 'inside' && dropdownMenuRef.current.contains(event.target as HTMLElement)) || - (autoClose === 'outside' && !dropdownMenuRef.current.contains(event.target as HTMLElement)) - ) { - setTimeout(() => setVisible(false), 1) - return - } - } - - return ( - <CDropdownContext.Provider value={contextValues}> - {variant === 'input-group' ? ( - <>{children}</> - ) : ( - <Component - className={classNames( - variant === 'nav-item' ? 'nav-item dropdown' : variant, - { - 'dropdown-center': direction === 'center', - 'dropup dropup-center': direction === 'dropup-center', - [`${direction}`]: - direction && direction !== 'center' && direction !== 'dropup-center', - }, - className, - )} - {...rest} - ref={forkedRef} - > - {children} - </Component> - )} - </CDropdownContext.Provider> - ) - }, -) - -const alignmentDirection = PropTypes.oneOf<Directions>(['start', 'end']) - -CDropdown.propTypes = { - alignment: PropTypes.oneOfType([ - alignmentDirection, - PropTypes.shape({ xs: alignmentDirection.isRequired }), - PropTypes.shape({ sm: alignmentDirection.isRequired }), - PropTypes.shape({ md: alignmentDirection.isRequired }), - PropTypes.shape({ lg: alignmentDirection.isRequired }), - PropTypes.shape({ xl: alignmentDirection.isRequired }), - PropTypes.shape({ xxl: alignmentDirection.isRequired }), - ]), - autoClose: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.oneOf<'inside' | 'outside'>(['inside', 'outside']), - ]), - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, - dark: PropTypes.bool, - direction: PropTypes.oneOf(['center', 'dropup', 'dropup-center', 'dropend', 'dropstart']), - offset: PropTypes.any, // TODO: find good proptype - onHide: PropTypes.func, - onShow: PropTypes.func, - placement: placementPropType, - popper: PropTypes.bool, - portal: PropTypes.bool, - variant: PropTypes.oneOf(['btn-group', 'dropdown', 'input-group', 'nav-item']), - visible: PropTypes.bool, -} - -CDropdown.displayName = 'CDropdown' diff --git a/packages/coreui-react/src/components/dropdown/CDropdownDivider.tsx b/packages/coreui-react/src/components/dropdown/CDropdownDivider.tsx deleted file mode 100644 index c9fa58de..00000000 --- a/packages/coreui-react/src/components/dropdown/CDropdownDivider.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CDropdownDividerProps extends HTMLAttributes<HTMLHRElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -export const CDropdownDivider = forwardRef<HTMLHRElement, CDropdownDividerProps>( - ({ className, ...rest }, ref) => { - return <hr className={classNames('dropdown-divider', className)} {...rest} ref={ref} /> - }, -) - -CDropdownDivider.propTypes = { - className: PropTypes.string, -} - -CDropdownDivider.displayName = 'CDropdownDivider' diff --git a/packages/coreui-react/src/components/dropdown/CDropdownHeader.tsx b/packages/coreui-react/src/components/dropdown/CDropdownHeader.tsx deleted file mode 100644 index e91fb2c5..00000000 --- a/packages/coreui-react/src/components/dropdown/CDropdownHeader.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CDropdownHeaderProps extends HTMLAttributes<HTMLHeadingElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CDropdownHeader = forwardRef<HTMLHeadingElement, CDropdownHeaderProps>( - ({ children, className, component: Component = 'h6', ...rest }, ref) => { - return ( - <Component className={classNames('dropdown-header', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CDropdownHeader.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CDropdownHeader.displayName = 'CDropdownHeader' diff --git a/packages/coreui-react/src/components/dropdown/CDropdownItem.tsx b/packages/coreui-react/src/components/dropdown/CDropdownItem.tsx deleted file mode 100644 index b2a27697..00000000 --- a/packages/coreui-react/src/components/dropdown/CDropdownItem.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { ElementType, forwardRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CLink, CLinkProps } from '../link/CLink' - -export interface CDropdownItemProps extends CLinkProps { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CDropdownItem = forwardRef<HTMLButtonElement | HTMLAnchorElement, CDropdownItemProps>( - ({ children, className, component = 'a', ...rest }, ref) => { - return ( - <CLink - className={classNames('dropdown-item', className)} - component={component} - {...rest} - ref={ref} - > - {children} - </CLink> - ) - }, -) - -CDropdownItem.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CDropdownItem.displayName = 'CDropdownItem' diff --git a/packages/coreui-react/src/components/dropdown/CDropdownItemPlain.tsx b/packages/coreui-react/src/components/dropdown/CDropdownItemPlain.tsx deleted file mode 100644 index 53fdcd97..00000000 --- a/packages/coreui-react/src/components/dropdown/CDropdownItemPlain.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CDropdownItemPlainProps extends HTMLAttributes<HTMLSpanElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CDropdownItemPlain = forwardRef<HTMLSpanElement, CDropdownItemPlainProps>( - ({ children, className, component: Component = 'span', ...rest }, ref) => { - return ( - <Component className={classNames('dropdown-item-text', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CDropdownItemPlain.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CDropdownItemPlain.displayName = 'CDropdownItemPlain' diff --git a/packages/coreui-react/src/components/dropdown/CDropdownMenu.tsx b/packages/coreui-react/src/components/dropdown/CDropdownMenu.tsx deleted file mode 100644 index 983c13e0..00000000 --- a/packages/coreui-react/src/components/dropdown/CDropdownMenu.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes, useContext } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CDropdownContext } from './CDropdown' -import { CConditionalPortal } from '../conditional-portal' - -import { useForkedRef } from '../../hooks' - -import { getAlignmentClassNames } from './utils' - -export interface CDropdownMenuProps extends HTMLAttributes<HTMLDivElement | HTMLUListElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CDropdownMenu = forwardRef<HTMLDivElement | HTMLUListElement, CDropdownMenuProps>( - ({ children, className, component: Component = 'ul', ...rest }, ref) => { - const { alignment, container, dark, dropdownMenuRef, popper, portal, visible } = - useContext(CDropdownContext) - - const forkedRef = useForkedRef(ref, dropdownMenuRef) - - return ( - <CConditionalPortal container={container} portal={portal ?? false}> - <Component - className={classNames( - 'dropdown-menu', - { - show: visible, - }, - alignment && getAlignmentClassNames(alignment), - className, - )} - ref={forkedRef} - role="menu" - aria-hidden={!visible} - {...(!popper && { 'data-coreui-popper': 'static' })} - {...(dark && { 'data-coreui-theme': 'dark' })} - {...rest} - > - {Component === 'ul' - ? React.Children.map(children, (child, index) => { - if (React.isValidElement(child)) { - return <li key={index}>{React.cloneElement(child)}</li> - } - return - }) - : children} - </Component> - </CConditionalPortal> - ) - }, -) - -CDropdownMenu.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CDropdownMenu.displayName = 'CDropdownMenu' diff --git a/packages/coreui-react/src/components/dropdown/CDropdownToggle.tsx b/packages/coreui-react/src/components/dropdown/CDropdownToggle.tsx deleted file mode 100644 index a69e8602..00000000 --- a/packages/coreui-react/src/components/dropdown/CDropdownToggle.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import React, { FC, useContext } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CButton, CButtonProps } from '../button/CButton' - -import { CDropdownContext } from './CDropdown' - -import { triggerPropType } from '../../props' -import type { Triggers } from '../../types' - -export interface CDropdownToggleProps extends Omit<CButtonProps, 'type'> { - /** - * Enables pseudo element caret on toggler. - */ - caret?: boolean - /** - * Create a custom toggler which accepts any content. - */ - custom?: boolean - /** - * If a dropdown `variant` is set to `nav-item` then render the toggler as a link instead of a button. - * - * @since v5.0.0-rc.0 - */ - navLink?: boolean - /** - * Similarly, create split button dropdowns with virtually the same markup as single button dropdowns, but with the addition of `.dropdown-toggle-split` className for proper spacing around the dropdown caret. - */ - split?: boolean - /** - * Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. - * - * @type 'hover' | 'focus' | 'click' - */ - trigger?: Triggers | Triggers[] -} - -export const CDropdownToggle: FC<CDropdownToggleProps> = ({ - children, - caret = true, - custom, - className, - navLink = true, - split, - trigger = 'click', - ...rest -}) => { - const { dropdownToggleRef, variant, visible, setVisible } = useContext(CDropdownContext) - - const triggers = { - ...((trigger === 'click' || trigger.includes('click')) && { - onClick: (event: React.MouseEvent<HTMLElement>) => { - event.preventDefault() - setVisible(!visible) - }, - }), - ...((trigger === 'focus' || trigger.includes('focus')) && { - onFocus: () => setVisible(true), - onBlur: () => setVisible(false), - }), - } - - const togglerProps = { - className: classNames( - { - 'nav-link': variant === 'nav-item' && navLink, - 'dropdown-toggle': caret, - 'dropdown-toggle-split': split, - show: visible, - }, - className, - ), - 'aria-expanded': visible, - ...(!rest.disabled && { ...triggers }), - } - - const Toggler = () => { - if (custom && React.isValidElement(children)) { - return ( - <> - {React.cloneElement(children as React.ReactElement<any>, { - 'aria-expanded': visible, - ...(!rest.disabled && { ...triggers }), - ref: dropdownToggleRef, - })} - </> - ) - } - - if (variant === 'nav-item' && navLink) { - return ( - <a href="#" {...togglerProps} role="button" ref={dropdownToggleRef}> - {children} - </a> - ) - } - - return ( - <CButton {...togglerProps} tabIndex={0} {...rest} ref={dropdownToggleRef}> - {children} - {split && <span className="visually-hidden">Toggle Dropdown</span>} - </CButton> - ) - } - - return <Toggler /> -} - -CDropdownToggle.propTypes = { - caret: PropTypes.bool, - children: PropTypes.node, - className: PropTypes.string, - custom: PropTypes.bool, - split: PropTypes.bool, - trigger: triggerPropType, -} - -CDropdownToggle.displayName = 'CDropdownToggle' diff --git a/packages/coreui-react/src/components/dropdown/__tests__/CDropdown.spec.tsx b/packages/coreui-react/src/components/dropdown/__tests__/CDropdown.spec.tsx deleted file mode 100644 index 0824c536..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/CDropdown.spec.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import * as React from 'react' -import { render, screen, fireEvent } from '@testing-library/react' -import '@testing-library/jest-dom' -import { - CDropdown, - CDropdownToggle, - CDropdownMenu, - CDropdownItem, - CDropdownItemPlain, - CDropdownHeader, - CDropdownDivider, -} from '../../../index' - -test('loads and displays CDropdown component', async () => { - const { container } = render(<CDropdown>Test</CDropdown>) - expect(container).toMatchSnapshot() -}) - -test('CDropdown customize', async () => { - const { container } = render( - <CDropdown - alignment={{ lg: 'start' }} - className="bazinga" - component="h3" - dark={true} - direction="dropstart" - placement="right-end" - popper={true} - variant="nav-item" - visible={true} - > - Test - </CDropdown>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('nav-item') - expect(container.firstChild).toHaveClass('dropdown') - expect(container.firstChild).toHaveClass('dropstart') -}) - -// test('CDropdown change visible prop', async () => { -// jest.useFakeTimers() -// const { rerender } = render(<CDropdown visible={false}>Test</CDropdown>) -// expect(screen.getByText('Test')).not.toHaveClass('show') -// rerender(<CDropdown visible={true}>Test</CDropdown>) -// jest.runAllTimers() -// expect(screen.getByText('Test')).toHaveClass('show') -// rerender(<CDropdown visible={false}>Test</CDropdown>) -// expect(screen.getByText('Test')).not.toHaveClass('show') -// jest.runAllTimers() -// jest.useRealTimers() -// }) - -test('CDropdown click', async () => { - render( - <CDropdown> - <CDropdownToggle>Test</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>A</CDropdownItem> - <CDropdownItem>B</CDropdownItem> - </CDropdownMenu> - </CDropdown>, - ) - expect(screen.getByText('Test')).not.toHaveClass('show') - const el = screen.getByText('Test') - if (el !== null) { - fireEvent.click(el) //click on element - } - jest.runAllTimers() - expect(screen.getByText('Test').closest('div')).toHaveClass('show') - fireEvent.mouseUp(document.body) //click outside - await new Promise((r) => setTimeout(r, 1000)) - expect(screen.getByText('Test').closest('div')).not.toHaveClass('show') -}) - -test('CDropdown example', async () => { - jest.useFakeTimers() - const { container } = render( - <CDropdown> - <CDropdownToggle>Test</CDropdownToggle> - <CDropdownMenu> - <CDropdownHeader>A</CDropdownHeader> - <CDropdownItem>B</CDropdownItem> - <CDropdownItemPlain>C</CDropdownItemPlain> - <CDropdownDivider /> - <CDropdownItem>D</CDropdownItem> - </CDropdownMenu> - </CDropdown>, - ) - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownDivider.spec.tsx b/packages/coreui-react/src/components/dropdown/__tests__/CDropdownDivider.spec.tsx deleted file mode 100644 index bc5f6667..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownDivider.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CDropdownDivider } from '../../../index' - -test('loads and displays CDropdownDivider component', async () => { - const { container } = render(<CDropdownDivider />) - expect(container).toMatchSnapshot() -}) - -test('CDropdownDivider customize', async () => { - const { container } = render(<CDropdownDivider className="bazinga" />) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('dropdown-divider') -}) diff --git a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownHeader.spec.tsx b/packages/coreui-react/src/components/dropdown/__tests__/CDropdownHeader.spec.tsx deleted file mode 100644 index d568aaf5..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownHeader.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CDropdownHeader } from '../../../index' - -test('loads and displays CDropdownHeader component', async () => { - const { container } = render(<CDropdownHeader>Test</CDropdownHeader>) - expect(container).toMatchSnapshot() -}) - -test('CDropdownHeader customize', async () => { - const { container } = render( - <CDropdownHeader className="bazinga" component="h3"> - Test - </CDropdownHeader>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('dropdown-header') -}) diff --git a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownItem.spec.tsx b/packages/coreui-react/src/components/dropdown/__tests__/CDropdownItem.spec.tsx deleted file mode 100644 index e779e929..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownItem.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CDropdownItem } from '../../../index' - -test('loads and displays CDropdownItem component', async () => { - const { container } = render(<CDropdownItem>Test</CDropdownItem>) - expect(container).toMatchSnapshot() -}) - -test('CDropdownItem customize', async () => { - const { container } = render( - <CDropdownItem className="bazinga" component="div"> - Test - </CDropdownItem>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('dropdown-item') -}) diff --git a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownItemPlain.spec.tsx b/packages/coreui-react/src/components/dropdown/__tests__/CDropdownItemPlain.spec.tsx deleted file mode 100644 index 22c04522..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownItemPlain.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CDropdownItemPlain } from '../../../index' - -test('loads and displays CDropdownItemPlain component', async () => { - const { container } = render(<CDropdownItemPlain>Test</CDropdownItemPlain>) - expect(container).toMatchSnapshot() -}) - -test('CDropdownItemPlain customize', async () => { - const { container } = render( - <CDropdownItemPlain className="bazinga" component="div"> - Test - </CDropdownItemPlain>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('dropdown-item-text') -}) diff --git a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownMenu.spec.tsx b/packages/coreui-react/src/components/dropdown/__tests__/CDropdownMenu.spec.tsx deleted file mode 100644 index 5dd27500..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownMenu.spec.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CDropdown, CDropdownMenu } from '../../../index' - -test('loads and displays CDropdownMenu component', async () => { - const { container } = render(<CDropdownMenu>Test</CDropdownMenu>) - expect(container).toMatchSnapshot() -}) - -test('CDropdownMenu customize', async () => { - const { container } = render( - <CDropdown visible={true}> - <CDropdownMenu className="bazinga" component="div"> - Test - </CDropdownMenu> - </CDropdown>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild?.firstChild).toHaveClass('bazinga') - expect(container.firstChild?.firstChild).toHaveClass('dropdown-menu') - expect(container.firstChild?.firstChild).toHaveClass('show') -}) diff --git a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownToggle.spec.tsx b/packages/coreui-react/src/components/dropdown/__tests__/CDropdownToggle.spec.tsx deleted file mode 100644 index 99c20985..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/CDropdownToggle.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CDropdownToggle } from '../../../index' - -test('loads and displays CDropdownToggle component', async () => { - const { container } = render(<CDropdownToggle>Test</CDropdownToggle>) - expect(container).toMatchSnapshot() -}) - -test('CDropdownToggle customize', async () => { - const { container } = render( - <CDropdownToggle caret={true} split={true} trigger="focus"> - Test - </CDropdownToggle>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('dropdown-toggle') - expect(container.firstChild).toHaveClass('dropdown-toggle-split') -}) diff --git a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.tsx.snap b/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.tsx.snap deleted file mode 100644 index 315f0287..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.tsx.snap +++ /dev/null @@ -1,77 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CDropdown customize 1`] = ` -<div> - <li - class="nav-item dropdown dropstart bazinga" - > - Test - </li> -</div> -`; - -exports[`CDropdown example 1`] = ` -<div> - <div - class="btn-group" - > - <button - aria-expanded="false" - class="btn btn-primary dropdown-toggle" - tabindex="0" - type="button" - > - Test - </button> - <ul - aria-hidden="true" - class="dropdown-menu" - role="menu" - > - <li> - <h6 - class="dropdown-header" - > - A - </h6> - </li> - <li> - <a - class="dropdown-item" - > - B - </a> - </li> - <li> - <span - class="dropdown-item-text" - > - C - </span> - </li> - <li> - <hr - class="dropdown-divider" - /> - </li> - <li> - <a - class="dropdown-item" - > - D - </a> - </li> - </ul> - </div> -</div> -`; - -exports[`loads and displays CDropdown component 1`] = ` -<div> - <div - class="btn-group" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownDivider.spec.tsx.snap b/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownDivider.spec.tsx.snap deleted file mode 100644 index ed032fe0..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownDivider.spec.tsx.snap +++ /dev/null @@ -1,17 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CDropdownDivider customize 1`] = ` -<div> - <hr - class="dropdown-divider bazinga" - /> -</div> -`; - -exports[`loads and displays CDropdownDivider component 1`] = ` -<div> - <hr - class="dropdown-divider" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownHeader.spec.tsx.snap b/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownHeader.spec.tsx.snap deleted file mode 100644 index c17e6a2b..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownHeader.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CDropdownHeader customize 1`] = ` -<div> - <h3 - class="dropdown-header bazinga" - > - Test - </h3> -</div> -`; - -exports[`loads and displays CDropdownHeader component 1`] = ` -<div> - <h6 - class="dropdown-header" - > - Test - </h6> -</div> -`; diff --git a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownItem.spec.tsx.snap b/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownItem.spec.tsx.snap deleted file mode 100644 index 09aa5375..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownItem.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CDropdownItem customize 1`] = ` -<div> - <div - class="dropdown-item bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CDropdownItem component 1`] = ` -<div> - <a - class="dropdown-item" - > - Test - </a> -</div> -`; diff --git a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownItemPlain.spec.tsx.snap b/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownItemPlain.spec.tsx.snap deleted file mode 100644 index 5ea47dd2..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownItemPlain.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CDropdownItemPlain customize 1`] = ` -<div> - <div - class="dropdown-item-text bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CDropdownItemPlain component 1`] = ` -<div> - <span - class="dropdown-item-text" - > - Test - </span> -</div> -`; diff --git a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.tsx.snap b/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.tsx.snap deleted file mode 100644 index 0034410a..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.tsx.snap +++ /dev/null @@ -1,28 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CDropdownMenu customize 1`] = ` -<div> - <div - class="btn-group" - > - <div - aria-hidden="false" - class="dropdown-menu show bazinga" - role="menu" - > - Test - </div> - </div> -</div> -`; - -exports[`loads and displays CDropdownMenu component 1`] = ` -<div> - <ul - aria-hidden="true" - class="dropdown-menu" - data-coreui-popper="static" - role="menu" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownToggle.spec.tsx.snap b/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownToggle.spec.tsx.snap deleted file mode 100644 index cb0745bb..00000000 --- a/packages/coreui-react/src/components/dropdown/__tests__/__snapshots__/CDropdownToggle.spec.tsx.snap +++ /dev/null @@ -1,30 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CDropdownToggle customize 1`] = ` -<div> - <button - class="btn btn-primary dropdown-toggle dropdown-toggle-split" - tabindex="0" - type="button" - > - Test - <span - class="visually-hidden" - > - Toggle Dropdown - </span> - </button> -</div> -`; - -exports[`loads and displays CDropdownToggle component 1`] = ` -<div> - <button - class="btn btn-primary dropdown-toggle" - tabindex="0" - type="button" - > - Test - </button> -</div> -`; diff --git a/packages/coreui-react/src/components/dropdown/index.ts b/packages/coreui-react/src/components/dropdown/index.ts deleted file mode 100644 index 0ffdaf0c..00000000 --- a/packages/coreui-react/src/components/dropdown/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { CDropdown } from './CDropdown' -import { CDropdownDivider } from './CDropdownDivider' -import { CDropdownHeader } from './CDropdownHeader' -import { CDropdownItem } from './CDropdownItem' -import { CDropdownItemPlain } from './CDropdownItemPlain' -import { CDropdownMenu } from './CDropdownMenu' -import { CDropdownToggle } from './CDropdownToggle' - -export { - CDropdown, - CDropdownDivider, - CDropdownHeader, - CDropdownItem, - CDropdownItemPlain, - CDropdownMenu, - CDropdownToggle, -} diff --git a/packages/coreui-react/src/components/dropdown/types.ts b/packages/coreui-react/src/components/dropdown/types.ts deleted file mode 100644 index 7135b68a..00000000 --- a/packages/coreui-react/src/components/dropdown/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -export type Directions = 'start' | 'end' - -export type Breakpoints = - | { xs: Directions } - | { sm: Directions } - | { md: Directions } - | { lg: Directions } - | { xl: Directions } - | { xxl: Directions } - -export type Alignments = Directions | Breakpoints \ No newline at end of file diff --git a/packages/coreui-react/src/components/dropdown/utils.ts b/packages/coreui-react/src/components/dropdown/utils.ts deleted file mode 100644 index edddb0db..00000000 --- a/packages/coreui-react/src/components/dropdown/utils.ts +++ /dev/null @@ -1,73 +0,0 @@ -import type { Placement } from '@popperjs/core' -import type { Placements } from '../../types' -import type { Alignments, Breakpoints } from './types' - -export const getAlignmentClassNames = (alignment: Alignments) => { - const classNames: string[] = [] - if (typeof alignment === 'object') { - for (const key in alignment) { - classNames.push( - `dropdown-menu${key === 'xs' ? '' : `-${key}`}-${alignment[key as keyof Breakpoints]}`, - ) - } - } - - if (typeof alignment === 'string') { - classNames.push(`dropdown-menu-${alignment}`) - } - - return classNames -} - -export const getNextActiveElement = ( - list: HTMLElement[], - activeElement: HTMLElement, - shouldGetNext: boolean, - isCycleAllowed: boolean, -) => { - const listLength = list.length - let index = list.indexOf(activeElement) - - if (index === -1) { - return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0] - } - - index += shouldGetNext ? 1 : -1 - - if (isCycleAllowed) { - index = (index + listLength) % listLength - } - - return list[Math.max(0, Math.min(index, listLength - 1))] -} - -export const getPlacement = ( - placement: Placement, - direction: string | undefined, - alignment: Alignments | string | undefined, - isRTL: boolean, -): Placements => { - let _placement = placement - - if (direction === 'dropup') { - _placement = isRTL ? 'top-end' : 'top-start' - } - - if (direction === 'dropup-center') { - _placement = 'top' - } - - if (direction === 'dropend') { - _placement = isRTL ? 'left-start' : 'right-start' - } - - if (direction === 'dropstart') { - _placement = isRTL ? 'right-start' : 'left-start' - } - - if (alignment === 'end') { - _placement = isRTL ? 'bottom-start' : 'bottom-end' - } - - return _placement -} diff --git a/packages/coreui-react/src/components/footer/CFooter.tsx b/packages/coreui-react/src/components/footer/CFooter.tsx deleted file mode 100644 index 5a73788f..00000000 --- a/packages/coreui-react/src/components/footer/CFooter.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CFooterProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Place footer in non-static positions. - */ - position?: 'fixed' | 'sticky' -} - -export const CFooter = forwardRef<HTMLDivElement, CFooterProps>( - ({ children, className, position, ...rest }, ref) => { - return ( - <div - className={classNames('footer', { [`footer-${position}`]: position }, className)} - {...rest} - ref={ref} - > - {children} - </div> - ) - }, -) - -CFooter.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - position: PropTypes.oneOf(['fixed', 'sticky']), -} - -CFooter.displayName = 'CFooter' diff --git a/packages/coreui-react/src/components/footer/__tests__/CFooter.spec.tsx b/packages/coreui-react/src/components/footer/__tests__/CFooter.spec.tsx deleted file mode 100644 index 5174ba5d..00000000 --- a/packages/coreui-react/src/components/footer/__tests__/CFooter.spec.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFooter } from '../../../index' - -test('loads and displays CFooter component', async () => { - const { container } = render(<CFooter>Test</CFooter>) - expect(container).toMatchSnapshot() -}) - -test('CFooter customize', async () => { - const { container } = render( - <CFooter className="bazinga" position="fixed"> - Test - </CFooter>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('footer') - expect(container.firstChild).toHaveClass('footer-fixed') -}) diff --git a/packages/coreui-react/src/components/footer/__tests__/__snapshots__/CFooter.spec.tsx.snap b/packages/coreui-react/src/components/footer/__tests__/__snapshots__/CFooter.spec.tsx.snap deleted file mode 100644 index 95397d70..00000000 --- a/packages/coreui-react/src/components/footer/__tests__/__snapshots__/CFooter.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFooter customize 1`] = ` -<div> - <div - class="footer footer-fixed bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CFooter component 1`] = ` -<div> - <div - class="footer" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/footer/index.ts b/packages/coreui-react/src/components/footer/index.ts deleted file mode 100644 index 4913ac71..00000000 --- a/packages/coreui-react/src/components/footer/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CFooter } from './CFooter' - -export { CFooter } diff --git a/packages/coreui-react/src/components/form/CForm.tsx b/packages/coreui-react/src/components/form/CForm.tsx deleted file mode 100644 index 5bcd7dac..00000000 --- a/packages/coreui-react/src/components/form/CForm.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { forwardRef, FormHTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CFormProps extends FormHTMLAttributes<HTMLFormElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Mark a form as validated. If you set it `true`, all validation styles will be applied to the forms component. - */ - validated?: boolean -} - -export const CForm = forwardRef<HTMLFormElement, CFormProps>( - ({ children, className, validated, ...rest }, ref) => { - return ( - <form - className={classNames({ 'was-validated': validated }, className) || undefined} - {...rest} - ref={ref} - > - {children} - </form> - ) - }, -) - -CForm.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - validated: PropTypes.bool, -} - -CForm.displayName = 'CForm' diff --git a/packages/coreui-react/src/components/form/CFormCheck.tsx b/packages/coreui-react/src/components/form/CFormCheck.tsx deleted file mode 100644 index 7f770d4f..00000000 --- a/packages/coreui-react/src/components/form/CFormCheck.tsx +++ /dev/null @@ -1,227 +0,0 @@ -import React, { forwardRef, InputHTMLAttributes, ReactNode, useEffect, useRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CFormControlValidation, CFormControlValidationProps } from './CFormControlValidation' -import { CFormLabel } from './CFormLabel' - -import { useForkedRef } from '../../hooks' -import type { Colors, Shapes } from '../../types' - -export type ButtonObject = { - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Select the shape of the component. - * - * @type 'rounded' | 'rounded-top' | 'rounded-end' | 'rounded-bottom' | 'rounded-start' | 'rounded-circle' | 'rounded-pill' | 'rounded-0' | 'rounded-1' | 'rounded-2' | 'rounded-3' | string - */ - shape?: Shapes - /** - * Size the component small or large. - */ - size?: 'sm' | 'lg' - /** - * Set the button variant to an outlined button or a ghost button. - */ - variant?: 'outline' | 'ghost' -} - -export interface CFormCheckProps - extends CFormControlValidationProps, - InputHTMLAttributes<HTMLInputElement> { - /** - * Create button-like checkboxes and radio buttons. - */ - button?: ButtonObject - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets hit area to the full area of the component. - */ - hitArea?: 'full' - /** - * The id global attribute defines an identifier (ID) that must be unique in the whole document. - */ - id?: string - /** - * Input Checkbox indeterminate Property. - */ - indeterminate?: boolean - /** - * Group checkboxes or radios on the same horizontal row. - */ - inline?: boolean - /** - * Set component validation state to invalid. - */ - invalid?: boolean - /** - * The element represents a caption for a component. - */ - label?: string | ReactNode - /** - * Put checkboxes or radios on the opposite side. - * - * @sinve 4.7.0 - */ - reverse?: boolean - /** - * Specifies the type of component. - */ - type?: 'checkbox' | 'radio' - /** - * Set component validation state to valid. - */ - valid?: boolean -} - -export const CFormCheck = forwardRef<HTMLInputElement, CFormCheckProps>( - ( - { - className, - button, - feedback, - feedbackInvalid, - feedbackValid, - floatingLabel, - tooltipFeedback, - hitArea, - id, - indeterminate, - inline, - invalid, - label, - reverse, - type = 'checkbox', - valid, - ...rest - }, - ref, - ) => { - const inputRef = useRef<HTMLInputElement>(null) - const forkedRef = useForkedRef(ref, inputRef) - - useEffect(() => { - if (inputRef.current && indeterminate) { - inputRef.current.indeterminate = indeterminate - } - }, [indeterminate, inputRef.current]) - - const FormControl = () => ( - <input - type={type} - className={classNames(button ? 'btn-check' : 'form-check-input', { - 'is-invalid': invalid, - 'is-valid': valid, - 'me-2': hitArea, - })} - id={id} - {...rest} - ref={forkedRef} - /> - ) - - const FormValidation = () => ( - <CFormControlValidation - describedby={rest['aria-describedby']} - feedback={feedback} - feedbackInvalid={feedbackInvalid} - feedbackValid={feedbackValid} - floatingLabel={floatingLabel} - invalid={invalid} - tooltipFeedback={tooltipFeedback} - valid={valid} - /> - ) - - const FormLabel = () => ( - <CFormLabel - customClassName={classNames( - button - ? classNames( - 'btn', - button.variant ? `btn-${button.variant}-${button.color}` : `btn-${button.color}`, - { - [`btn-${button.size}`]: button.size, - }, - `${button.shape}`, - ) - : 'form-check-label', - )} - {...(id && { htmlFor: id })} - > - {label} - </CFormLabel> - ) - - const FormCheck = () => { - if (button) { - return ( - <> - <FormControl /> - {label && <FormLabel />} - <FormValidation /> - </> - ) - } - - if (label) { - return hitArea ? ( - <> - <FormControl /> - <CFormLabel - customClassName={classNames('form-check-label stretched-link', className)} - {...(id && { htmlFor: id })} - > - {label} - </CFormLabel> - <FormValidation /> - </> - ) : ( - <div - className={classNames( - 'form-check', - { - 'form-check-inline': inline, - 'form-check-reverse': reverse, - 'is-invalid': invalid, - 'is-valid': valid, - }, - className, - )} - > - <FormControl /> - <FormLabel /> - <FormValidation /> - </div> - ) - } - - return <FormControl /> - } - - return <FormCheck /> - }, -) - -CFormCheck.propTypes = { - button: PropTypes.object, - className: PropTypes.string, - hitArea: PropTypes.oneOf(['full']), - id: PropTypes.string, - indeterminate: PropTypes.bool, - inline: PropTypes.bool, - label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - reverse: PropTypes.bool, - type: PropTypes.oneOf(['checkbox', 'radio']), - ...CFormControlValidation.propTypes, -} - -CFormCheck.displayName = 'CFormCheck' diff --git a/packages/coreui-react/src/components/form/CFormControlValidation.tsx b/packages/coreui-react/src/components/form/CFormControlValidation.tsx deleted file mode 100644 index d280f9f3..00000000 --- a/packages/coreui-react/src/components/form/CFormControlValidation.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import React, { FC, ReactNode } from 'react' -import PropTypes from 'prop-types' - -import { CFormFeedback } from './CFormFeedback' - -export interface CFormControlValidationProps { - /** - * @ignore - */ - describedby?: string - /** - * Provide valuable, actionable feedback. - * - * @since 4.2.0 - */ - feedback?: ReactNode | string - /** - * Provide valuable, actionable feedback. - * - * @since 4.2.0 - */ - feedbackInvalid?: ReactNode | string - /** - * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. - * - * @since 4.2.0 - */ - feedbackValid?: ReactNode | string - /** - * Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. - * - * @since 4.2.0 - */ - floatingLabel?: ReactNode | string - /** - * Set component validation state to invalid. - */ - invalid?: boolean - /** - * Display validation feedback in a styled tooltip. - * - * @since 4.2.0 - */ - tooltipFeedback?: boolean - /** - * Set component validation state to valid. - */ - valid?: boolean -} - -export const CFormControlValidation: FC<CFormControlValidationProps> = ({ - describedby, - feedback, - feedbackInvalid, - feedbackValid, - invalid, - tooltipFeedback, - valid, -}) => { - return ( - <> - {feedback && (valid || invalid) && ( - <CFormFeedback - {...(invalid && { id: describedby })} - invalid={invalid} - tooltip={tooltipFeedback} - valid={valid} - > - {feedback} - </CFormFeedback> - )} - {feedbackInvalid && ( - <CFormFeedback id={describedby} invalid tooltip={tooltipFeedback}> - {feedbackInvalid} - </CFormFeedback> - )} - {feedbackValid && ( - <CFormFeedback valid tooltip={tooltipFeedback}> - {feedbackValid} - </CFormFeedback> - )} - </> - ) -} - -CFormControlValidation.propTypes = { - describedby: PropTypes.string, - feedback: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), - feedbackValid: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), - feedbackInvalid: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), - invalid: PropTypes.bool, - tooltipFeedback: PropTypes.bool, - valid: PropTypes.bool, -} - -CFormControlValidation.displayName = 'CFormControlValidation' diff --git a/packages/coreui-react/src/components/form/CFormControlWrapper.tsx b/packages/coreui-react/src/components/form/CFormControlWrapper.tsx deleted file mode 100644 index 01b32351..00000000 --- a/packages/coreui-react/src/components/form/CFormControlWrapper.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import React, { FC, ReactNode } from 'react' -import PropTypes from 'prop-types' - -import { CFormControlValidation, CFormControlValidationProps } from './CFormControlValidation' -import { CFormFloating } from './CFormFloating' -import { CFormLabel } from './CFormLabel' -import { CFormText } from './CFormText' - -export interface CFormControlWrapperProps extends CFormControlValidationProps { - /** - * @ignore - */ - children?: ReactNode - /** - * A string of all className you want applied to the floating label wrapper. - * - * @since 4.5.0 - */ - floatingClassName?: string - /** - * Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. - * - * @since 4.2.0 - */ - floatingLabel?: ReactNode | string - /** - * @ignore - */ - id?: string - /** - * Add a caption for a component. - * - * @since 4.2.0 - */ - label?: ReactNode | string - /** - * Add helper text to the component. - * - * @since 4.2.0 - */ - text?: ReactNode | string -} - -export const CFormControlWrapper: FC<CFormControlWrapperProps> = ({ - children, - describedby, - feedback, - feedbackInvalid, - feedbackValid, - floatingClassName, - floatingLabel, - id, - invalid, - label, - text, - tooltipFeedback, - valid, -}) => { - const FormControlValidation = () => ( - <CFormControlValidation - describedby={describedby} - feedback={feedback} - feedbackInvalid={feedbackInvalid} - feedbackValid={feedbackValid} - floatingLabel={floatingLabel} - invalid={invalid} - tooltipFeedback={tooltipFeedback} - valid={valid} - /> - ) - return floatingLabel ? ( - <CFormFloating className={floatingClassName}> - {children} - <CFormLabel htmlFor={id}>{label || floatingLabel}</CFormLabel> - {text && <CFormText id={describedby}>{text}</CFormText>} - <FormControlValidation /> - </CFormFloating> - ) : ( - <> - {label && <CFormLabel htmlFor={id}>{label}</CFormLabel>} - {children} - {text && <CFormText id={describedby}>{text}</CFormText>} - <FormControlValidation /> - </> - ) -} - -CFormControlWrapper.propTypes = { - children: PropTypes.node, - floatingClassName: PropTypes.string, - floatingLabel: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), - label: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), - text: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), - ...CFormControlValidation.propTypes, -} - -CFormControlWrapper.displayName = 'CFormControlWrapper' diff --git a/packages/coreui-react/src/components/form/CFormFeedback.tsx b/packages/coreui-react/src/components/form/CFormFeedback.tsx deleted file mode 100644 index 17a81dca..00000000 --- a/packages/coreui-react/src/components/form/CFormFeedback.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CFormFeedbackProps extends HTMLAttributes<HTMLDivElement | HTMLSpanElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Method called immediately after the `value` prop changes. - */ - invalid?: boolean - /** - * If your form layout allows it, you can display validation feedback in a styled tooltip. - */ - tooltip?: boolean - /** - * Set component validation state to valid. - */ - valid?: boolean -} - -export const CFormFeedback = forwardRef<HTMLDivElement | HTMLSpanElement, CFormFeedbackProps>( - ( - { children, className, component: Component = 'div', invalid, tooltip, valid, ...rest }, - ref, - ) => { - return ( - <Component - className={classNames( - { - [`invalid-${tooltip ? 'tooltip' : 'feedback'}`]: invalid, - [`valid-${tooltip ? 'tooltip' : 'feedback'}`]: valid, - }, - className, - )} - {...rest} - ref={ref} - > - {children} - </Component> - ) - }, -) - -CFormFeedback.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, - invalid: PropTypes.bool, - tooltip: PropTypes.bool, - valid: PropTypes.bool, -} - -CFormFeedback.displayName = 'CFormFeedback' diff --git a/packages/coreui-react/src/components/form/CFormFloating.tsx b/packages/coreui-react/src/components/form/CFormFloating.tsx deleted file mode 100644 index 5d2ec950..00000000 --- a/packages/coreui-react/src/components/form/CFormFloating.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CFormFloatingProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -export const CFormFloating = forwardRef<HTMLDivElement, CFormFloatingProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('form-floating', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -CFormFloating.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CFormFloating.displayName = 'CFormFloating' diff --git a/packages/coreui-react/src/components/form/CFormInput.tsx b/packages/coreui-react/src/components/form/CFormInput.tsx deleted file mode 100644 index 82bdc27e..00000000 --- a/packages/coreui-react/src/components/form/CFormInput.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import React, { - ChangeEventHandler, - forwardRef, - InputHTMLAttributes, - useEffect, - useState, -} from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CFormControlWrapper, CFormControlWrapperProps } from './CFormControlWrapper' - -export interface CFormInputProps - extends CFormControlWrapperProps, - Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Delay onChange event while typing. If set to true onChange event will be delayed 500ms, you can also provide the number of milliseconds you want to delay the onChange event. - */ - delay?: boolean | number - /** - * Toggle the disabled state for the component. - */ - disabled?: boolean - /** - * Method called immediately after the `value` prop changes. - */ - onChange?: ChangeEventHandler<HTMLInputElement> - /** - * Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`. - */ - plainText?: boolean - /** - * Toggle the readonly state for the component. - */ - readOnly?: boolean - /** - * Size the component small or large. - */ - size?: 'sm' | 'lg' - /** - * Specifies the type of component. - */ - type?: 'color' | 'file' | 'text' | string - /** - * The `value` attribute of component. - * - * @controllable onChange - * */ - value?: string | string[] | number -} - -export const CFormInput = forwardRef<HTMLInputElement, CFormInputProps>( - ( - { - children, - className, - delay = false, - feedback, - feedbackInvalid, - feedbackValid, - floatingClassName, - floatingLabel, - id, - invalid, - label, - onChange, - plainText, - size, - text, - tooltipFeedback, - type = 'text', - valid, - ...rest - }, - ref, - ) => { - const [value, setValue] = useState<React.ChangeEvent<HTMLInputElement>>() - - useEffect(() => { - const timeOutId = setTimeout( - () => value && onChange && onChange(value), - typeof delay === 'number' ? delay : 500, - ) - - return () => clearTimeout(timeOutId) - }, [value]) - - return ( - <CFormControlWrapper - describedby={rest['aria-describedby']} - feedback={feedback} - feedbackInvalid={feedbackInvalid} - feedbackValid={feedbackValid} - floatingClassName={floatingClassName} - floatingLabel={floatingLabel} - id={id} - invalid={invalid} - label={label} - text={text} - tooltipFeedback={tooltipFeedback} - valid={valid} - > - <input - className={classNames( - plainText ? 'form-control-plaintext' : 'form-control', - { - [`form-control-${size}`]: size, - 'form-control-color': type === 'color', - 'is-invalid': invalid, - 'is-valid': valid, - }, - className, - )} - id={id} - type={type} - onChange={(event) => (delay ? setValue(event) : onChange && onChange(event))} - {...rest} - ref={ref} - > - {children} - </input> - </CFormControlWrapper> - ) - }, -) - -CFormInput.propTypes = { - className: PropTypes.string, - id: PropTypes.string, - delay: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]), - plainText: PropTypes.bool, - size: PropTypes.oneOf(['sm', 'lg']), - type: PropTypes.oneOfType([PropTypes.oneOf(['color', 'file', 'text']), PropTypes.string]), - ...CFormControlWrapper.propTypes, -} - -CFormInput.displayName = 'CFormInput' diff --git a/packages/coreui-react/src/components/form/CFormLabel.tsx b/packages/coreui-react/src/components/form/CFormLabel.tsx deleted file mode 100644 index 5e8e06f0..00000000 --- a/packages/coreui-react/src/components/form/CFormLabel.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { forwardRef, LabelHTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CFormLabelProps extends LabelHTMLAttributes<HTMLLabelElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * A string of all className you want to be applied to the component, and override standard className value. - */ - customClassName?: string -} - -export const CFormLabel = forwardRef<HTMLLabelElement, CFormLabelProps>( - ({ children, className, customClassName, ...rest }, ref) => { - return ( - <label className={customClassName ?? classNames('form-label', className)} {...rest} ref={ref}> - {children} - </label> - ) - }, -) - -CFormLabel.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - customClassName: PropTypes.string, -} - -CFormLabel.displayName = 'CFormLabel' diff --git a/packages/coreui-react/src/components/form/CFormRange.tsx b/packages/coreui-react/src/components/form/CFormRange.tsx deleted file mode 100644 index 583f5713..00000000 --- a/packages/coreui-react/src/components/form/CFormRange.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React, { ChangeEventHandler, forwardRef, InputHTMLAttributes, ReactNode } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CFormLabel } from './CFormLabel' -export interface CFormRangeProps extends InputHTMLAttributes<HTMLInputElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Toggle the disabled state for the component. - */ - disabled?: boolean - /** - * Add a caption for a component. - * - * @since 4.2.0 - */ - label?: ReactNode | string - /** - * Specifies the maximum value for the component. - */ - max?: number - /** - * Specifies the minimum value for the component. - */ - min?: number - /** - * Method called immediately after the `value` prop changes. - */ - onChange?: ChangeEventHandler<HTMLInputElement> - /** - * Toggle the readonly state for the component. - */ - readOnly?: boolean - /** - * Specifies the interval between legal numbers in the component. - */ - step?: number - /** - * The `value` attribute of component. - * - * @controllable onChange - * */ - value?: string | string[] | number -} - -export const CFormRange = forwardRef<HTMLInputElement, CFormRangeProps>( - ({ className, label, ...rest }, ref) => { - return ( - <> - {label && <CFormLabel htmlFor={rest.id}>{label}</CFormLabel>} - <input type="range" className={classNames('form-range', className)} {...rest} ref={ref} /> - </> - ) - }, -) - -CFormRange.propTypes = { - className: PropTypes.string, - label: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), -} - -CFormRange.displayName = 'CFormRange' diff --git a/packages/coreui-react/src/components/form/CFormSelect.tsx b/packages/coreui-react/src/components/form/CFormSelect.tsx deleted file mode 100644 index af0b2d72..00000000 --- a/packages/coreui-react/src/components/form/CFormSelect.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import React, { ChangeEventHandler, forwardRef, InputHTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CFormControlWrapper, CFormControlWrapperProps } from './CFormControlWrapper' - -type Option = { - disabled?: boolean - label?: string - value?: string -} - -export interface CFormSelectProps - extends CFormControlWrapperProps, - Omit<InputHTMLAttributes<HTMLSelectElement>, 'size'> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Specifies the number of visible options in a drop-down list. - */ - htmlSize?: number - /** - * Method called immediately after the `value` prop changes. - */ - onChange?: ChangeEventHandler<HTMLSelectElement> - /** - * Options list of the select component. Available keys: `label`, `value`, `disabled`. - * Examples: - * - `options={[{ value: 'js', label: 'JavaScript' }, { value: 'html', label: 'HTML', disabled: true }]}` - * - `options={['js', 'html']}` - */ - options?: Option[] | string[] - /** - * Size the component small or large. - */ - size?: 'sm' | 'lg' - /** - * The `value` attribute of component. - * - * @controllable onChange - */ - value?: string | string[] | number -} - -export const CFormSelect = forwardRef<HTMLSelectElement, CFormSelectProps>( - ( - { - children, - className, - feedback, - feedbackInvalid, - feedbackValid, - floatingClassName, - floatingLabel, - htmlSize, - id, - invalid, - label, - options, - size, - text, - tooltipFeedback, - valid, - ...rest - }, - ref, - ) => { - return ( - <CFormControlWrapper - describedby={rest['aria-describedby']} - feedback={feedback} - feedbackInvalid={feedbackInvalid} - feedbackValid={feedbackValid} - floatingClassName={floatingClassName} - floatingLabel={floatingLabel} - id={id} - invalid={invalid} - label={label} - text={text} - tooltipFeedback={tooltipFeedback} - valid={valid} - > - <select - id={id} - className={classNames( - 'form-select', - { - [`form-select-${size}`]: size, - 'is-invalid': invalid, - 'is-valid': valid, - }, - className, - )} - size={htmlSize} - {...rest} - ref={ref} - > - {options - ? options.map((option, index) => { - return ( - <option - {...(typeof option === 'object' && - option.disabled && { disabled: option.disabled })} - {...(typeof option === 'object' && - option.value !== undefined && { value: option.value })} - key={index} - > - {typeof option === 'string' ? option : option.label} - </option> - ) - }) - : children} - </select> - </CFormControlWrapper> - ) - }, -) - -CFormSelect.propTypes = { - className: PropTypes.string, - htmlSize: PropTypes.number, - options: PropTypes.array, - ...CFormControlWrapper.propTypes, -} - -CFormSelect.displayName = 'CFormSelect' diff --git a/packages/coreui-react/src/components/form/CFormSwitch.tsx b/packages/coreui-react/src/components/form/CFormSwitch.tsx deleted file mode 100644 index cbb0e9e4..00000000 --- a/packages/coreui-react/src/components/form/CFormSwitch.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import React, { forwardRef, InputHTMLAttributes, ReactNode } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CFormLabel } from './CFormLabel' - -export interface CFormSwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * The id global attribute defines an identifier (ID) that must be unique in the whole document. - */ - id?: string - /** - * Set component validation state to invalid. - */ - invalid?: boolean - /** - * The element represents a caption for a component. - */ - label?: string | ReactNode - /** - * Put switch on the opposite side. - * - * @sinve 4.7.0 - */ - reverse?: boolean - /** - * Size the component large or extra large. Works only with `switch`. - */ - size?: 'lg' | 'xl' - /** - * Specifies the type of component. - */ - type?: 'checkbox' | 'radio' - /** - * Set component validation state to valid. - */ - valid?: boolean -} - -export const CFormSwitch = forwardRef<HTMLInputElement, CFormSwitchProps>( - ({ className, id, invalid, label, reverse, size, type = 'checkbox', valid, ...rest }, ref) => { - return ( - <div - className={classNames( - 'form-check form-switch', - { - 'form-check-reverse': reverse, - [`form-switch-${size}`]: size, - 'is-invalid': invalid, - 'is-valid': valid, - }, - className, - )} - > - <input - type={type} - className={classNames('form-check-input', { - 'is-invalid': invalid, - 'is-valid': valid, - })} - id={id} - {...rest} - ref={ref} - /> - {label && ( - <CFormLabel customClassName="form-check-label" {...(id && { htmlFor: id })}> - {label} - </CFormLabel> - )} - </div> - ) - }, -) - -CFormSwitch.propTypes = { - className: PropTypes.string, - id: PropTypes.string, - invalid: PropTypes.bool, - label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - reverse: PropTypes.bool, - size: PropTypes.oneOf(['lg', 'xl']), - type: PropTypes.oneOf(['checkbox', 'radio']), - valid: PropTypes.bool, -} - -CFormSwitch.displayName = 'CFormSwitch' diff --git a/packages/coreui-react/src/components/form/CFormText.tsx b/packages/coreui-react/src/components/form/CFormText.tsx deleted file mode 100644 index 79c2844f..00000000 --- a/packages/coreui-react/src/components/form/CFormText.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CFormTextProps extends HTMLAttributes<HTMLDivElement | HTMLSpanElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CFormText = forwardRef<HTMLDivElement | HTMLSpanElement, CFormTextProps>( - ({ children, className, component: Component = 'div', ...rest }, ref) => { - return ( - <Component className={classNames('form-text', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CFormText.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CFormText.displayName = 'CFormText' diff --git a/packages/coreui-react/src/components/form/CFormTextarea.tsx b/packages/coreui-react/src/components/form/CFormTextarea.tsx deleted file mode 100644 index fa47f6e1..00000000 --- a/packages/coreui-react/src/components/form/CFormTextarea.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import React, { ChangeEventHandler, forwardRef, TextareaHTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CFormControlWrapper, CFormControlWrapperProps } from './CFormControlWrapper' - -export interface CFormTextareaProps - extends CFormControlWrapperProps, - TextareaHTMLAttributes<HTMLTextAreaElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Toggle the disabled state for the component. - */ - disabled?: boolean - /** - * Method called immediately after the `value` prop changes. - */ - onChange?: ChangeEventHandler<HTMLTextAreaElement> - /** - * Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`. - */ - plainText?: boolean - /** - * Toggle the readonly state for the component. - */ - readOnly?: boolean - /** - * The `value` attribute of component. - * - * @controllable onChange - * */ - value?: string | string[] | number -} - -export const CFormTextarea = forwardRef<HTMLTextAreaElement, CFormTextareaProps>( - ( - { - children, - className, - feedback, - feedbackInvalid, - feedbackValid, - floatingClassName, - floatingLabel, - id, - invalid, - label, - plainText, - text, - tooltipFeedback, - valid, - ...rest - }, - ref, - ) => { - return ( - <CFormControlWrapper - describedby={rest['aria-describedby']} - feedback={feedback} - feedbackInvalid={feedbackInvalid} - feedbackValid={feedbackValid} - floatingClassName={floatingClassName} - floatingLabel={floatingLabel} - id={id} - invalid={invalid} - label={label} - text={text} - tooltipFeedback={tooltipFeedback} - valid={valid} - > - <textarea - className={classNames( - plainText ? 'form-control-plaintext' : 'form-control', - { - 'is-invalid': invalid, - 'is-valid': valid, - }, - className, - )} - id={id} - {...rest} - ref={ref} - > - {children} - </textarea> - </CFormControlWrapper> - ) - }, -) - -CFormTextarea.propTypes = { - className: PropTypes.string, - id: PropTypes.string, - plainText: PropTypes.bool, - ...CFormControlWrapper.propTypes, -} - -CFormTextarea.displayName = 'CFormTextarea' diff --git a/packages/coreui-react/src/components/form/CInputGroup.tsx b/packages/coreui-react/src/components/form/CInputGroup.tsx deleted file mode 100644 index eedd5169..00000000 --- a/packages/coreui-react/src/components/form/CInputGroup.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CInputGroupProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Size the component small or large. - */ - size?: 'sm' | 'lg' -} - -export const CInputGroup = forwardRef<HTMLDivElement, CInputGroupProps>( - ({ children, className, size, ...rest }, ref) => { - return ( - <div - className={classNames( - 'input-group', - { - [`input-group-${size}`]: size, - }, - className, - )} - {...rest} - ref={ref} - > - {children} - </div> - ) - }, -) - -CInputGroup.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - size: PropTypes.oneOf(['sm', 'lg']), -} - -CInputGroup.displayName = 'CInputGroup' diff --git a/packages/coreui-react/src/components/form/CInputGroupText.tsx b/packages/coreui-react/src/components/form/CInputGroupText.tsx deleted file mode 100644 index 8f65c1da..00000000 --- a/packages/coreui-react/src/components/form/CInputGroupText.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React, { ElementType, forwardRef, LabelHTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CInputGroupTextProps - extends LabelHTMLAttributes<HTMLLabelElement | HTMLSpanElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CInputGroupText = forwardRef<HTMLLabelElement | HTMLSpanElement, CInputGroupTextProps>( - ({ children, className, component: Component = 'span', ...rest }, ref) => { - return ( - <Component className={classNames('input-group-text', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CInputGroupText.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CInputGroupText.displayName = 'CInputGroupText' diff --git a/packages/coreui-react/src/components/form/__tests__/CForm.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CForm.spec.tsx deleted file mode 100644 index abe65bc9..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CForm.spec.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CForm, CFormLabel, CFormInput, CFormText, CFormCheck, CButton } from '../../../index' - -test('loads and displays CForm component', async () => { - const { container } = render(<CForm>Test</CForm>) - expect(container).toMatchSnapshot() -}) - -test('CForm customize', async () => { - const { container } = render( - <CForm className="bazinga" validated={true}> - Test - </CForm>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('was-validated') -}) - -test('CForm example', async () => { - const { container } = render( - <CForm> - <CFormLabel>A</CFormLabel> - <CFormInput type="email" aria-describedby="B" /> - <CFormText>C</CFormText> - <CFormCheck label="D" /> - <CButton type="submit" color="primary"> - E - </CButton> - </CForm>, - ) - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CFormCheck.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CFormCheck.spec.tsx deleted file mode 100644 index eae30412..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CFormCheck.spec.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFormCheck } from '../../../index' - -test('loads and displays CFormCheck component', async () => { - const { container } = render(<CFormCheck />) - expect(container).toMatchSnapshot() -}) - -test('CFormCheck customize button=false', async () => { - const { container } = render( - <CFormCheck className="bazinga" id="id" inline={true} label="label" type="radio" />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('form-check') - expect(container.firstChild).toHaveClass('form-check-inline') -}) - -test('CFormCheck customize button=true', async () => { - const { container } = render( - <CFormCheck - button={{ color: 'primary', size: 'lg', shape: 'rounded', variant: 'ghost' }} - className="bazinga" - id="id" - inline={true} - label="label" - type="radio" - />, - ) - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CFormControl.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CFormControl.spec.tsx deleted file mode 100644 index 905ce975..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CFormControl.spec.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import * as React from 'react' -import { render, fireEvent } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFormInput } from '../../../index' - -test('loads and displays CFormInput component', async () => { - const { container } = render(<CFormInput />) - expect(container).toMatchSnapshot() -}) - -test('CFormInput customize', async () => { - const { container } = render( - <CFormInput - className="bazinga" - disabled={true} - plainText={true} - readOnly={true} - size="lg" - type="color" - value="value" - />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('form-control-plaintext') - expect(container.firstChild).toHaveClass('form-control-color') - expect(container.firstChild).toHaveClass('form-control-lg') -}) - -test('CFormInput change input', async () => { - jest.useFakeTimers() - const onChange = jest.fn() - render(<CFormInput onChange={onChange} />) - expect(onChange).toHaveBeenCalledTimes(0) - const input = document.querySelector('input') - if (input !== null) { - fireEvent.change(input, { target: { value: 'bazinga' } }) - } - expect(onChange).toHaveBeenCalledTimes(1) - if (input !== null) { - fireEvent.change(input, { target: { value: '2' } }) - } - expect(onChange).toHaveBeenCalledTimes(2) -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CFormFeedback.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CFormFeedback.spec.tsx deleted file mode 100644 index 9287b480..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CFormFeedback.spec.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFormFeedback } from '../../../index' - -test('loads and displays CFormFeedback component', async () => { - const { container } = render(<CFormFeedback />) - expect(container).toMatchSnapshot() -}) - -test('CFormFeedback customize one', async () => { - const { container } = render( - <CFormFeedback className="bazinga" invalid={true} valid={true} tooltip={true} />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('invalid-tooltip') - expect(container.firstChild).toHaveClass('valid-tooltip') - expect(container.firstChild).toHaveClass('bazinga') -}) - -test('CFormFeedback customize two', async () => { - const { container } = render( - <CFormFeedback className="bazinga" invalid={true} valid={true} tooltip={false} />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('invalid-feedback') - expect(container.firstChild).toHaveClass('valid-feedback') - expect(container.firstChild).toHaveClass('bazinga') -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CFormFloating.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CFormFloating.spec.tsx deleted file mode 100644 index 8faa698c..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CFormFloating.spec.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFormFloating } from '../../../index' - -test('loads and displays CFormFloating component', async () => { - const { container } = render(<CFormFloating />) - expect(container).toMatchSnapshot() -}) - -test('CFormFloating customize', async () => { - const { container } = render(<CFormFloating className="bazinga">Test</CFormFloating>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('form-floating') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CFormInput.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CFormInput.spec.tsx deleted file mode 100644 index 529f79b9..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CFormInput.spec.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFormInput } from '../../../index' - -test('loads and displays CFormInput component', async () => { - const { container } = render(<CFormInput />) - expect(container).toMatchSnapshot() -}) - -test('CFormInput customize one', async () => { - const { container } = render(<CFormInput />) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('form-control') -}) - -test('CFormInput customize two', async () => { - const { container } = render( - <CFormInput - className="bazinga" - disabled={true} - invalid={true} - plainText={true} - readOnly={true} - size="lg" - type="color" - valid={true} - value="#888888" - />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('form-control-lg') - expect(container.firstChild).toHaveClass('form-control-color') - expect(container.firstChild).toHaveClass('is-invalid') - expect(container.firstChild).toHaveClass('is-valid') - expect(container.firstChild).toHaveClass('form-control-plaintext') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveAttribute('value', '#888888') - expect(container.firstChild).toHaveAttribute('type', 'color') - expect(container.firstChild).toHaveAttribute('disabled', '') - expect(container.firstChild).toHaveAttribute('readonly', '') -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CFormLabel.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CFormLabel.spec.tsx deleted file mode 100644 index 991ba5b2..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CFormLabel.spec.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFormLabel } from '../../../index' - -test('loads and displays CFormLabel component', async () => { - const { container } = render(<CFormLabel>Test</CFormLabel>) - expect(container).toMatchSnapshot() -}) - -test('CFormLabel customize className', async () => { - const { container } = render(<CFormLabel className="bazinga">Test</CFormLabel>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('form-label') - expect(container.firstChild).toHaveTextContent('Test') -}) - -test('CFormLabel customize htmlFor', async () => { - const { container } = render(<CFormLabel htmlFor="bazinga">Test</CFormLabel>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveAttribute('for', 'bazinga') - expect(container.firstChild).toHaveClass('form-label') - expect(container.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CFormRange.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CFormRange.spec.tsx deleted file mode 100644 index 522797f7..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CFormRange.spec.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFormRange } from '../../../index' - -test('loads and displays CFormRange component', async () => { - const { container } = render(<CFormRange step={3} />) - expect(container).toMatchSnapshot() -}) - -test('CFormRange customize', async () => { - const { container } = render( - <CFormRange - className="bazinga" - step={2} - disabled={true} - max={150} - min={20} - readOnly={true} - value={80} - />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('form-range') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveAttribute('disabled', '') - expect(container.firstChild).toHaveAttribute('max', '150') - expect(container.firstChild).toHaveAttribute('min', '20') - expect(container.firstChild).toHaveAttribute('readonly', '') - expect(container.firstChild).toHaveAttribute('step', '2') - expect(container.firstChild).toHaveAttribute('type', 'range') - expect(container.firstChild).toHaveAttribute('value', '80') -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CFormSelect.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CFormSelect.spec.tsx deleted file mode 100644 index a166a432..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CFormSelect.spec.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFormSelect } from '../../../index' - -test('loads and displays CFormSelect component', async () => { - const { container } = render(<CFormSelect></CFormSelect>) - expect(container).toMatchSnapshot() -}) - -test('CFormSelect customize', async () => { - const { container } = render( - <CFormSelect className="bazinga" size="lg"> - <option value="A">B</option> - <option>C</option> - </CFormSelect>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('form-select') - expect(container.firstChild).toHaveClass('form-select-lg') -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CFormSwitch.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CFormSwitch.spec.tsx deleted file mode 100644 index 7451a891..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CFormSwitch.spec.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFormSwitch } from '../../../index' - -test('loads and displays CFormSwitch component', async () => { - const { container } = render(<CFormSwitch />) - expect(container).toMatchSnapshot() -}) - -test('CFormSwitch customize', async () => { - const { container } = render( - <CFormSwitch - className="bazinga" - id="2" - invalid={true} - label="Some label" - size="xl" - type="radio" - valid={true} - />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('form-check') - expect(container.firstChild).toHaveClass('form-switch') - expect(container.firstChild).toHaveClass('form-switch-xl') - expect(container.firstChild).toHaveClass('is-invalid') - expect(container.firstChild).toHaveClass('is-valid') - expect(container.firstChild).toHaveClass('bazinga') - if (container.firstChild === null) { - expect(true).toBe(false) - } else { - expect(container.firstChild.firstChild).toHaveClass('form-check-input') - expect(container.firstChild.firstChild).toHaveClass('is-invalid') - expect(container.firstChild.firstChild).toHaveClass('is-valid') - expect(container.firstChild.firstChild).toHaveAttribute('id', '2') - expect(container.firstChild.firstChild).toHaveAttribute('type', 'radio') - expect(container.firstChild.lastChild).toHaveClass('form-check-label') - expect(container.firstChild.lastChild).toHaveTextContent('Some label') - expect(container.firstChild.lastChild).toHaveAttribute('for', '2') - } -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CFormText.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CFormText.spec.tsx deleted file mode 100644 index b2a7ea81..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CFormText.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFormText } from '../../../index' - -test('loads and displays CFormText component', async () => { - const { container } = render(<CFormText>Test</CFormText>) - expect(container).toMatchSnapshot() -}) - -test('CFormText customize', async () => { - const { container } = render( - <CFormText className="bazinga" component="h3"> - Test - </CFormText>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('form-text') -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CFormTextarea.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CFormTextarea.spec.tsx deleted file mode 100644 index ebfbc64b..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CFormTextarea.spec.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CFormTextarea } from '../../../index' - -test('loads and displays CFormTextarea component', async () => { - const { container } = render(<CFormTextarea defaultValue="Some value" />) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('form-control') -}) - -test('CFormTextarea customize', async () => { - const { container } = render( - <CFormTextarea - className="bazinga" - disabled={true} - invalid={true} - plainText={true} - readOnly={true} - valid={true} - defaultValue="Some value" - rows={2} - />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('form-control-plaintext') - expect(container.firstChild).toHaveClass('is-invalid') - expect(container.firstChild).toHaveClass('is-valid') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveTextContent('Some value') - expect(container.firstChild).toHaveAttribute('disabled', '') - expect(container.firstChild).toHaveAttribute('readonly', '') -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CInputGroup.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CInputGroup.spec.tsx deleted file mode 100644 index 537740d1..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CInputGroup.spec.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CInputGroup } from '../../../index' - -test('loads and displays CInputGroup component', async () => { - const { container } = render(<CInputGroup>Test</CInputGroup>) - expect(container).toMatchSnapshot() -}) - -test('CInputGroup customize', async () => { - const { container } = render( - <CInputGroup className="bazinga" size="lg"> - Test - </CInputGroup>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('input-group') - expect(container.firstChild).toHaveClass('input-group-lg') -}) diff --git a/packages/coreui-react/src/components/form/__tests__/CInputGroupText.spec.tsx b/packages/coreui-react/src/components/form/__tests__/CInputGroupText.spec.tsx deleted file mode 100644 index de6c978d..00000000 --- a/packages/coreui-react/src/components/form/__tests__/CInputGroupText.spec.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CInputGroupText } from '../../../index' - -test('loads and displays CInputGroupText component', async () => { - const { container } = render(<CInputGroupText>Test</CInputGroupText>) - expect(container).toMatchSnapshot() -}) - -test('renders CInputGroupText component as a label', async () => { - const { container } = render( - <CInputGroupText component="label" htmlFor="input"> - Test - </CInputGroupText>, - ) - expect(container).toMatchSnapshot() -}) - -test('CInputGroupText customize', async () => { - const { container } = render(<CInputGroupText className="bazinga">Test</CInputGroupText>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('input-group-text') -}) diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CForm.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CForm.spec.tsx.snap deleted file mode 100644 index 518a05bf..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CForm.spec.tsx.snap +++ /dev/null @@ -1,60 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CForm customize 1`] = ` -<div> - <form - class="was-validated bazinga" - > - Test - </form> -</div> -`; - -exports[`CForm example 1`] = ` -<div> - <form> - <label - class="form-label" - > - A - </label> - <input - aria-describedby="B" - class="form-control" - type="email" - /> - <div - class="form-text" - > - C - </div> - <div - class="form-check" - > - <input - class="form-check-input" - type="checkbox" - /> - <label - class="form-check-label" - > - D - </label> - </div> - <button - class="btn btn-primary" - type="submit" - > - E - </button> - </form> -</div> -`; - -exports[`loads and displays CForm component 1`] = ` -<div> - <form> - Test - </form> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormCheck.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormCheck.spec.tsx.snap deleted file mode 100644 index 42a5bac3..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormCheck.spec.tsx.snap +++ /dev/null @@ -1,46 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFormCheck customize button=false 1`] = ` -<div> - <div - class="form-check form-check-inline bazinga" - > - <input - class="form-check-input" - id="id" - type="radio" - /> - <label - class="form-check-label" - for="id" - > - label - </label> - </div> -</div> -`; - -exports[`CFormCheck customize button=true 1`] = ` -<div> - <input - class="btn-check" - id="id" - type="radio" - /> - <label - class="btn btn-ghost-primary btn-lg rounded" - for="id" - > - label - </label> -</div> -`; - -exports[`loads and displays CFormCheck component 1`] = ` -<div> - <input - class="form-check-input" - type="checkbox" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormControl.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormControl.spec.tsx.snap deleted file mode 100644 index af969a06..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormControl.spec.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFormInput customize 1`] = ` -<div> - <input - class="form-control-plaintext form-control-lg form-control-color bazinga" - disabled="" - readonly="" - type="color" - value="value" - /> -</div> -`; - -exports[`loads and displays CFormInput component 1`] = ` -<div> - <input - class="form-control" - type="text" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormFeedback.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormFeedback.spec.tsx.snap deleted file mode 100644 index ec5c3b48..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormFeedback.spec.tsx.snap +++ /dev/null @@ -1,25 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFormFeedback customize one 1`] = ` -<div> - <div - class="invalid-tooltip valid-tooltip bazinga" - /> -</div> -`; - -exports[`CFormFeedback customize two 1`] = ` -<div> - <div - class="invalid-feedback valid-feedback bazinga" - /> -</div> -`; - -exports[`loads and displays CFormFeedback component 1`] = ` -<div> - <div - class="" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormFloating.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormFloating.spec.tsx.snap deleted file mode 100644 index 69dc47eb..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormFloating.spec.tsx.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFormFloating customize 1`] = ` -<div> - <div - class="form-floating bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CFormFloating component 1`] = ` -<div> - <div - class="form-floating" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormInput.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormInput.spec.tsx.snap deleted file mode 100644 index f73155fa..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormInput.spec.tsx.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFormInput customize one 1`] = ` -<div> - <input - class="form-control" - type="text" - /> -</div> -`; - -exports[`CFormInput customize two 1`] = ` -<div> - <input - class="form-control-plaintext form-control-lg form-control-color is-invalid is-valid bazinga" - disabled="" - readonly="" - type="color" - value="#888888" - /> -</div> -`; - -exports[`loads and displays CFormInput component 1`] = ` -<div> - <input - class="form-control" - type="text" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormLabel.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormLabel.spec.tsx.snap deleted file mode 100644 index 6bc2378d..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormLabel.spec.tsx.snap +++ /dev/null @@ -1,32 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFormLabel customize className 1`] = ` -<div> - <label - class="form-label bazinga" - > - Test - </label> -</div> -`; - -exports[`CFormLabel customize htmlFor 1`] = ` -<div> - <label - class="form-label" - for="bazinga" - > - Test - </label> -</div> -`; - -exports[`loads and displays CFormLabel component 1`] = ` -<div> - <label - class="form-label" - > - Test - </label> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormRange.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormRange.spec.tsx.snap deleted file mode 100644 index 990ec53a..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormRange.spec.tsx.snap +++ /dev/null @@ -1,26 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFormRange customize 1`] = ` -<div> - <input - class="form-range bazinga" - disabled="" - max="150" - min="20" - readonly="" - step="2" - type="range" - value="80" - /> -</div> -`; - -exports[`loads and displays CFormRange component 1`] = ` -<div> - <input - class="form-range" - step="3" - type="range" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormSelect.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormSelect.spec.tsx.snap deleted file mode 100644 index 3dd06df6..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormSelect.spec.tsx.snap +++ /dev/null @@ -1,26 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFormSelect customize 1`] = ` -<div> - <select - class="form-select form-select-lg bazinga" - > - <option - value="A" - > - B - </option> - <option> - C - </option> - </select> -</div> -`; - -exports[`loads and displays CFormSelect component 1`] = ` -<div> - <select - class="form-select" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormSwitch.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormSwitch.spec.tsx.snap deleted file mode 100644 index 8c6825d5..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormSwitch.spec.tsx.snap +++ /dev/null @@ -1,34 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFormSwitch customize 1`] = ` -<div> - <div - class="form-check form-switch form-switch-xl is-invalid is-valid bazinga" - > - <input - class="form-check-input is-invalid is-valid" - id="2" - type="radio" - /> - <label - class="form-check-label" - for="2" - > - Some label - </label> - </div> -</div> -`; - -exports[`loads and displays CFormSwitch component 1`] = ` -<div> - <div - class="form-check form-switch" - > - <input - class="form-check-input" - type="checkbox" - /> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormText.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormText.spec.tsx.snap deleted file mode 100644 index 8cdf34a3..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormText.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFormText customize 1`] = ` -<div> - <h3 - class="form-text bazinga" - > - Test - </h3> -</div> -`; - -exports[`loads and displays CFormText component 1`] = ` -<div> - <div - class="form-text" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormTextarea.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormTextarea.spec.tsx.snap deleted file mode 100644 index d94413db..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CFormTextarea.spec.tsx.snap +++ /dev/null @@ -1,24 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CFormTextarea customize 1`] = ` -<div> - <textarea - class="form-control-plaintext is-invalid is-valid bazinga" - disabled="" - readonly="" - rows="2" - > - Some value - </textarea> -</div> -`; - -exports[`loads and displays CFormTextarea component 1`] = ` -<div> - <textarea - class="form-control" - > - Some value - </textarea> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CInputGroup.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CInputGroup.spec.tsx.snap deleted file mode 100644 index 33b1b5e1..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CInputGroup.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CInputGroup customize 1`] = ` -<div> - <div - class="input-group input-group-lg bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CInputGroup component 1`] = ` -<div> - <div - class="input-group" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CInputGroupText.spec.tsx.snap b/packages/coreui-react/src/components/form/__tests__/__snapshots__/CInputGroupText.spec.tsx.snap deleted file mode 100644 index 00ae0e56..00000000 --- a/packages/coreui-react/src/components/form/__tests__/__snapshots__/CInputGroupText.spec.tsx.snap +++ /dev/null @@ -1,32 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CInputGroupText customize 1`] = ` -<div> - <span - class="input-group-text bazinga" - > - Test - </span> -</div> -`; - -exports[`loads and displays CInputGroupText component 1`] = ` -<div> - <span - class="input-group-text" - > - Test - </span> -</div> -`; - -exports[`renders CInputGroupText component as a label 1`] = ` -<div> - <label - class="input-group-text" - for="input" - > - Test - </label> -</div> -`; diff --git a/packages/coreui-react/src/components/form/index.ts b/packages/coreui-react/src/components/form/index.ts deleted file mode 100644 index 7e609487..00000000 --- a/packages/coreui-react/src/components/form/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { CForm } from './CForm' -import { CFormCheck } from './CFormCheck' -import { CFormControlValidation } from './CFormControlValidation' -import { CFormControlWrapper } from './CFormControlWrapper' -import { CFormFeedback } from './CFormFeedback' -import { CFormFloating } from './CFormFloating' -import { CFormInput } from './CFormInput' -import { CFormLabel } from './CFormLabel' -import { CFormRange } from './CFormRange' -import { CFormSelect } from './CFormSelect' -import { CFormSwitch } from './CFormSwitch' -import { CFormText } from './CFormText' -import { CFormTextarea } from './CFormTextarea' -import { CInputGroup } from './CInputGroup' -import { CInputGroupText } from './CInputGroupText' - -export { - CForm, - CFormCheck, - CFormControlValidation, - CFormControlWrapper, - CFormFeedback, - CFormFloating, - CFormInput, - CFormLabel, - CFormRange, - CFormSelect, - CFormSwitch, - CFormText, - CFormTextarea, - CInputGroup, - CInputGroupText, -} diff --git a/packages/coreui-react/src/components/grid/CCol.tsx b/packages/coreui-react/src/components/grid/CCol.tsx deleted file mode 100644 index 2aad123d..00000000 --- a/packages/coreui-react/src/components/grid/CCol.tsx +++ /dev/null @@ -1,150 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -type Span = 'auto' | number | string | boolean | null - -type BPObject = { - span?: Span - offset?: number | string | null - order?: 'first' | 'last' | number | string | null -} - -type Col = Span | BPObject - -export interface CColProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * The number of columns/offset/order on extra small devices (<576px). - * - * @type { 'auto' | number | string | boolean | { span: 'auto' | number | string | boolean } | { offset: number | string } | { order: 'first' | 'last' | number | string }} - */ - xs?: Col - /** - * The number of columns/offset/order on small devices (<768px). - * - * @type { 'auto' | number | string | boolean | { span: 'auto' | number | string | boolean } | { offset: number | string } | { order: 'first' | 'last' | number | string }} - */ - sm?: Col - /** - * The number of columns/offset/order on medium devices (<992px). - * - * @type { 'auto' | number | string | boolean | { span: 'auto' | number | string | boolean } | { offset: number | string } | { order: 'first' | 'last' | number | string }} - */ - md?: Col - /** - * The number of columns/offset/order on large devices (<1200px). - * - * @type { 'auto' | number | string | boolean | { span: 'auto' | number | string | boolean } | { offset: number | string } | { order: 'first' | 'last' | number | string }} - */ - lg?: Col - /** - * The number of columns/offset/order on X-Large devices (<1400px). - * - * @type { 'auto' | number | string | boolean | { span: 'auto' | number | string | boolean } | { offset: number | string } | { order: 'first' | 'last' | number | string }} - */ - xl?: Col - /** - * The number of columns/offset/order on XX-Large devices (≥1400px). - * - * @type { 'auto' | number | string | boolean | { span: 'auto' | number | string | boolean } | { offset: number | string } | { order: 'first' | 'last' | number | string }} - */ - xxl?: Col -} - -const BREAKPOINTS = [ - 'xxl' as const, - 'xl' as const, - 'lg' as const, - 'md' as const, - 'sm' as const, - 'xs' as const, -] - -export const CCol = forwardRef<HTMLDivElement, CColProps>( - ({ children, className, ...rest }, ref) => { - const repsonsiveClassNames: string[] = [] - - BREAKPOINTS.forEach((bp) => { - const breakpoint = rest[bp] - delete rest[bp] - - const infix = bp === 'xs' ? '' : `-${bp}` - - if (typeof breakpoint === 'number' || typeof breakpoint === 'string') { - repsonsiveClassNames.push(`col${infix}-${breakpoint}`) - } - - if (typeof breakpoint === 'boolean') { - repsonsiveClassNames.push(`col${infix}`) - } - - if (breakpoint && typeof breakpoint === 'object') { - if (typeof breakpoint.span === 'number' || typeof breakpoint.span === 'string') { - repsonsiveClassNames.push(`col${infix}-${breakpoint.span}`) - } - - if (typeof breakpoint.span === 'boolean') { - repsonsiveClassNames.push(`col${infix}`) - } - - if (typeof breakpoint.order === 'number' || typeof breakpoint.order === 'string') { - repsonsiveClassNames.push(`order${infix}-${breakpoint.order}`) - } - - if (typeof breakpoint.offset === 'number') { - repsonsiveClassNames.push(`offset${infix}-${breakpoint.offset}`) - } - } - }) - - return ( - <div - className={classNames( - repsonsiveClassNames.length > 0 ? repsonsiveClassNames : 'col', - className, - )} - {...rest} - ref={ref} - > - {children} - </div> - ) - }, -) - -const span = PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.number, - PropTypes.string, - PropTypes.oneOf(['auto']), -]) - -const col = PropTypes.oneOfType([ - span, - PropTypes.shape({ - span: span, - offset: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - order: PropTypes.oneOfType([ - PropTypes.oneOf(['first', 'last']), - PropTypes.number, - PropTypes.string, - ]), - }), -]) - -CCol.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - xs: col, - sm: col, - md: col, - lg: col, - xl: col, - xxl: col, -} - -CCol.displayName = 'CCol' diff --git a/packages/coreui-react/src/components/grid/CContainer.tsx b/packages/coreui-react/src/components/grid/CContainer.tsx deleted file mode 100644 index c665f727..00000000 --- a/packages/coreui-react/src/components/grid/CContainer.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CContainerProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Set container 100% wide until small breakpoint. - */ - sm?: boolean - /** - * Set container 100% wide until medium breakpoint. - */ - md?: boolean - /** - * Set container 100% wide until large breakpoint. - */ - lg?: boolean - /** - * Set container 100% wide until X-large breakpoint. - */ - xl?: boolean - /** - * Set container 100% wide until XX-large breakpoint. - */ - xxl?: boolean - /** - * Set container 100% wide, spanning the entire width of the viewport. - */ - fluid?: boolean -} - -const BREAKPOINTS = [ - 'xxl' as const, - 'xl' as const, - 'lg' as const, - 'md' as const, - 'sm' as const, - 'fluid' as const, -] - -export const CContainer = forwardRef<HTMLDivElement, CContainerProps>( - ({ children, className, ...rest }, ref) => { - const repsonsiveClassNames: string[] = [] - - BREAKPOINTS.forEach((bp) => { - const breakpoint = rest[bp] - delete rest[bp] - - breakpoint && repsonsiveClassNames.push(`container-${bp}`) - }) - - return ( - <div - className={classNames( - repsonsiveClassNames.length > 0 ? repsonsiveClassNames : 'container', - className, - )} - {...rest} - ref={ref} - > - {children} - </div> - ) - }, -) - -CContainer.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - sm: PropTypes.bool, - md: PropTypes.bool, - lg: PropTypes.bool, - xl: PropTypes.bool, - xxl: PropTypes.bool, - fluid: PropTypes.bool, -} - -CContainer.displayName = 'CContainer' diff --git a/packages/coreui-react/src/components/grid/CRow.tsx b/packages/coreui-react/src/components/grid/CRow.tsx deleted file mode 100644 index 14800d5e..00000000 --- a/packages/coreui-react/src/components/grid/CRow.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export type BPObject = { - cols?: 'auto' | number | string | null - gutter?: number | string | null - gutterX?: number | string | null - gutterY?: number | string | null -} - -export interface CRowProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * The number of columns/offset/order on extra small devices (<576px). - * - * @type {{ cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }} - */ - xs?: BPObject - /** - * The number of columns/offset/order on small devices (<768px). - * - * @type {{ cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }} - */ - sm?: BPObject - /** - * The number of columns/offset/order on medium devices (<992px). - * - * @type {{ cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }} - */ - md?: BPObject - /** - * The number of columns/offset/order on large devices (<1200px). - * - * @type {{ cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }} - */ - lg?: BPObject - /** - * The number of columns/offset/order on X-Large devices (<1400px). - * - * @type {{ cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }} - */ - xl?: BPObject - /** - * The number of columns/offset/order on XX-Large devices (≥1400px). - * - * @type {{ cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }} - */ - xxl?: BPObject -} - -const BREAKPOINTS = [ - 'xxl' as const, - 'xl' as const, - 'lg' as const, - 'md' as const, - 'sm' as const, - 'xs' as const, -] - -export const CRow = forwardRef<HTMLDivElement, CRowProps>( - ({ children, className, ...rest }, ref) => { - const repsonsiveClassNames: string[] = [] - - BREAKPOINTS.forEach((bp) => { - const breakpoint = rest[bp] - delete rest[bp] - - const infix = bp === 'xs' ? '' : `-${bp}` - - if (typeof breakpoint === 'object') { - if (breakpoint.cols) { - repsonsiveClassNames.push(`row-cols${infix}-${breakpoint.cols}`) - } - - if (typeof breakpoint.gutter === 'number') { - repsonsiveClassNames.push(`g${infix}-${breakpoint.gutter}`) - } - - if (typeof breakpoint.gutterX === 'number') { - repsonsiveClassNames.push(`gx${infix}-${breakpoint.gutterX}`) - } - - if (typeof breakpoint.gutterY === 'number') { - repsonsiveClassNames.push(`gy${infix}-${breakpoint.gutterY}`) - } - } - }) - - return ( - <div className={classNames('row', repsonsiveClassNames, className)} ref={ref}> - {children} - </div> - ) - }, -) - -const bp = PropTypes.shape({ - cols: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.number, PropTypes.string]), - gutter: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - gutterX: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - gutterY: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), -}) - -CRow.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - xs: bp, - sm: bp, - md: bp, - lg: bp, - xl: bp, - xxl: bp, -} - -CRow.displayName = 'CRow' diff --git a/packages/coreui-react/src/components/grid/__tests__/CCol.spec.tsx b/packages/coreui-react/src/components/grid/__tests__/CCol.spec.tsx deleted file mode 100644 index f7e91c4d..00000000 --- a/packages/coreui-react/src/components/grid/__tests__/CCol.spec.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CCol } from '../../../index' - -test('CCol no-breakpoints', async () => { - const { container } = render(<CCol>Test</CCol>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('col') -}) - -test('CCol customize breakpoints are numbers', async () => { - const { container } = render( - <CCol className="bazinga" xs={1} sm={2} md={3} lg={4} xl={5} xxl={6}> - Test - </CCol>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('col-1') - expect(container.firstChild).toHaveClass('col-sm-2') - expect(container.firstChild).toHaveClass('col-md-3') - expect(container.firstChild).toHaveClass('col-lg-4') - expect(container.firstChild).toHaveClass('col-xl-5') - expect(container.firstChild).toHaveClass('col-xxl-6') -}) - -test('CCol customize breakpoints are boolean', async () => { - const { container } = render( - <CCol className="bazinga" xs={true} sm={true} md={true} lg={true} xl={true} xxl={true}> - Test - </CCol>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('col') - expect(container.firstChild).toHaveClass('col-sm') - expect(container.firstChild).toHaveClass('col-md') - expect(container.firstChild).toHaveClass('col-lg') - expect(container.firstChild).toHaveClass('col-xl') - expect(container.firstChild).toHaveClass('col-xxl') -}) diff --git a/packages/coreui-react/src/components/grid/__tests__/CContainer.spec.tsx b/packages/coreui-react/src/components/grid/__tests__/CContainer.spec.tsx deleted file mode 100644 index f491d3e1..00000000 --- a/packages/coreui-react/src/components/grid/__tests__/CContainer.spec.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CContainer } from '../../../index' - -test('loads and displays CContainer component', async () => { - const { container } = render(<CContainer>Test</CContainer>) - expect(container).toMatchSnapshot() -}) - -test('CContainer customize fluid', async () => { - const { container } = render( - <CContainer className="bazinga" fluid> - Test - </CContainer>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('container-fluid') -}) - -test('CContainer customize', async () => { - const { container } = render( - <CContainer md className="bazinga"> - Test - </CContainer>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('container-md') -}) diff --git a/packages/coreui-react/src/components/grid/__tests__/CRow.spec.tsx b/packages/coreui-react/src/components/grid/__tests__/CRow.spec.tsx deleted file mode 100644 index e1d651e6..00000000 --- a/packages/coreui-react/src/components/grid/__tests__/CRow.spec.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CRow } from '../../../index' - -test('CRow not-customize', async () => { - const { container } = render(<CRow>Test</CRow>) - expect(container).toMatchSnapshot() -}) - -test('CRow customize cols', async () => { - const { container } = render( - <CRow - className="bazinga" - xs={{ cols: 1 }} - sm={{ cols: 2 }} - md={{ cols: 3 }} - lg={{ cols: 4 }} - xl={{ cols: 5 }} - xxl={{ cols: 6 }} - > - Test - </CRow>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('row-cols-1') - expect(container.firstChild).toHaveClass('row-cols-sm-2') - expect(container.firstChild).toHaveClass('row-cols-md-3') - expect(container.firstChild).toHaveClass('row-cols-lg-4') - expect(container.firstChild).toHaveClass('row-cols-xl-5') - expect(container.firstChild).toHaveClass('row-cols-xxl-6') -}) - -test('CRow customize gutter single gutter', async () => { - const { container } = render( - <CRow className="bazinga" xs={{ gutter: 7 }}> - Test - </CRow>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('g-7') -}) - -test('CRow customize gutter', async () => { - const { container } = render( - <CRow - className="bazinga" - xs={{ gutter: 1 }} - sm={{ gutter: 2 }} - md={{ gutter: 3 }} - lg={{ gutter: 4 }} - xl={{ gutter: 5 }} - xxl={{ gutter: 6 }} - > - Test - </CRow>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('g-1') - expect(container.firstChild).toHaveClass('g-sm-2') - expect(container.firstChild).toHaveClass('g-md-3') - expect(container.firstChild).toHaveClass('g-lg-4') - expect(container.firstChild).toHaveClass('g-xl-5') - expect(container.firstChild).toHaveClass('g-xxl-6') -}) - -test('CRow customize gutterX', async () => { - const { container } = render( - <CRow - className="bazinga" - xs={{ gutterX: 1 }} - sm={{ gutterX: 2 }} - md={{ gutterX: 3 }} - lg={{ gutterX: 4 }} - xl={{ gutterX: 5 }} - xxl={{ gutterX: 6 }} - > - Test - </CRow>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('gx-1') - expect(container.firstChild).toHaveClass('gx-sm-2') - expect(container.firstChild).toHaveClass('gx-md-3') - expect(container.firstChild).toHaveClass('gx-lg-4') - expect(container.firstChild).toHaveClass('gx-xl-5') - expect(container.firstChild).toHaveClass('gx-xxl-6') -}) - -test('CRow customize gutterY', async () => { - const { container } = render( - <CRow - className="bazinga" - xs={{ gutterY: 1 }} - sm={{ gutterY: 2 }} - md={{ gutterY: 3 }} - lg={{ gutterY: 4 }} - xl={{ gutterY: 5 }} - xxl={{ gutterY: 6 }} - > - Test - </CRow>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('gy-1') - expect(container.firstChild).toHaveClass('gy-sm-2') - expect(container.firstChild).toHaveClass('gy-md-3') - expect(container.firstChild).toHaveClass('gy-lg-4') - expect(container.firstChild).toHaveClass('gy-xl-5') - expect(container.firstChild).toHaveClass('gy-xxl-6') -}) diff --git a/packages/coreui-react/src/components/grid/__tests__/__snapshots__/CCol.spec.tsx.snap b/packages/coreui-react/src/components/grid/__tests__/__snapshots__/CCol.spec.tsx.snap deleted file mode 100644 index 6ecf10d3..00000000 --- a/packages/coreui-react/src/components/grid/__tests__/__snapshots__/CCol.spec.tsx.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CCol customize breakpoints are boolean 1`] = ` -<div> - <div - class="col-xxl col-xl col-lg col-md col-sm col bazinga" - > - Test - </div> -</div> -`; - -exports[`CCol customize breakpoints are numbers 1`] = ` -<div> - <div - class="col-xxl-6 col-xl-5 col-lg-4 col-md-3 col-sm-2 col-1 bazinga" - > - Test - </div> -</div> -`; - -exports[`CCol no-breakpoints 1`] = ` -<div> - <div - class="col" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/grid/__tests__/__snapshots__/CContainer.spec.tsx.snap b/packages/coreui-react/src/components/grid/__tests__/__snapshots__/CContainer.spec.tsx.snap deleted file mode 100644 index f0de3fa5..00000000 --- a/packages/coreui-react/src/components/grid/__tests__/__snapshots__/CContainer.spec.tsx.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CContainer customize 1`] = ` -<div> - <div - class="container-md bazinga" - > - Test - </div> -</div> -`; - -exports[`CContainer customize fluid 1`] = ` -<div> - <div - class="container-fluid bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CContainer component 1`] = ` -<div> - <div - class="container" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/grid/__tests__/__snapshots__/CRow.spec.tsx.snap b/packages/coreui-react/src/components/grid/__tests__/__snapshots__/CRow.spec.tsx.snap deleted file mode 100644 index 5df4af5e..00000000 --- a/packages/coreui-react/src/components/grid/__tests__/__snapshots__/CRow.spec.tsx.snap +++ /dev/null @@ -1,61 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CRow customize cols 1`] = ` -<div> - <div - class="row row-cols-xxl-6 row-cols-xl-5 row-cols-lg-4 row-cols-md-3 row-cols-sm-2 row-cols-1 bazinga" - > - Test - </div> -</div> -`; - -exports[`CRow customize gutter 1`] = ` -<div> - <div - class="row g-xxl-6 g-xl-5 g-lg-4 g-md-3 g-sm-2 g-1 bazinga" - > - Test - </div> -</div> -`; - -exports[`CRow customize gutter single gutter 1`] = ` -<div> - <div - class="row g-7 bazinga" - > - Test - </div> -</div> -`; - -exports[`CRow customize gutterX 1`] = ` -<div> - <div - class="row gx-xxl-6 gx-xl-5 gx-lg-4 gx-md-3 gx-sm-2 gx-1 bazinga" - > - Test - </div> -</div> -`; - -exports[`CRow customize gutterY 1`] = ` -<div> - <div - class="row gy-xxl-6 gy-xl-5 gy-lg-4 gy-md-3 gy-sm-2 gy-1 bazinga" - > - Test - </div> -</div> -`; - -exports[`CRow not-customize 1`] = ` -<div> - <div - class="row" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/grid/index.ts b/packages/coreui-react/src/components/grid/index.ts deleted file mode 100644 index c0ed3d8b..00000000 --- a/packages/coreui-react/src/components/grid/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { CCol } from './CCol' -import { CContainer } from './CContainer' -import { CRow } from './CRow' - -export { CCol, CContainer, CRow } diff --git a/packages/coreui-react/src/components/header/CHeader.tsx b/packages/coreui-react/src/components/header/CHeader.tsx deleted file mode 100644 index eecd0393..00000000 --- a/packages/coreui-react/src/components/header/CHeader.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CHeaderProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Defines optional container wrapping children elements. - */ - container?: boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'fluid' - /** - * Place header in non-static positions. - */ - position?: 'fixed' | 'sticky' -} - -export const CHeader = forwardRef<HTMLDivElement, CHeaderProps>( - ({ children, className, container, position, ...rest }, ref) => { - return ( - <div - className={classNames('header', { [`header-${position}`]: position }, className)} - {...rest} - ref={ref} - > - {container ? ( - <div className={typeof container === 'string' ? `container-${container}` : 'container'}> - {children} - </div> - ) : ( - <>{children}</> - )} - </div> - ) - }, -) - -CHeader.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - container: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.oneOf<'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'fluid'>([ - 'sm', - 'md', - 'lg', - 'xl', - 'xxl', - 'fluid', - ]), - ]), - position: PropTypes.oneOf(['fixed', 'sticky']), -} - -CHeader.displayName = 'CHeader' diff --git a/packages/coreui-react/src/components/header/CHeaderBrand.tsx b/packages/coreui-react/src/components/header/CHeaderBrand.tsx deleted file mode 100644 index f72cd314..00000000 --- a/packages/coreui-react/src/components/header/CHeaderBrand.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React, { ElementType, forwardRef, AnchorHTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CHeaderBrandProps - extends AnchorHTMLAttributes<HTMLAnchorElement | HTMLSpanElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CHeaderBrand = forwardRef<HTMLAnchorElement | HTMLSpanElement, CHeaderBrandProps>( - ({ children, component: Component = 'a', className, ...rest }, ref) => { - return ( - <Component className={classNames('header-brand', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CHeaderBrand.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CHeaderBrand.displayName = 'CHeaderBrand' diff --git a/packages/coreui-react/src/components/header/CHeaderDivider.tsx b/packages/coreui-react/src/components/header/CHeaderDivider.tsx deleted file mode 100644 index bfea9d97..00000000 --- a/packages/coreui-react/src/components/header/CHeaderDivider.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CHeaderDividerProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -export const CHeaderDivider = forwardRef<HTMLDivElement, CHeaderDividerProps>( - ({ className, ...rest }, ref) => { - return <div className={classNames('header-divider', className)} {...rest} ref={ref} /> - }, -) - -CHeaderDivider.propTypes = { - className: PropTypes.string, -} - -CHeaderDivider.displayName = 'CHeaderDivider' diff --git a/packages/coreui-react/src/components/header/CHeaderNav.tsx b/packages/coreui-react/src/components/header/CHeaderNav.tsx deleted file mode 100644 index 2dea1852..00000000 --- a/packages/coreui-react/src/components/header/CHeaderNav.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CHeaderNavProps extends HTMLAttributes<HTMLDivElement | HTMLUListElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CHeaderNav = forwardRef<HTMLDivElement | HTMLUListElement, CHeaderNavProps>( - ({ children, component: Component = 'ul', className, ...rest }, ref) => { - return ( - <Component - className={classNames('header-nav', className)} - role="navigation" - {...rest} - ref={ref} - > - {children} - </Component> - ) - }, -) - -CHeaderNav.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CHeaderNav.displayName = 'CHeaderNav' diff --git a/packages/coreui-react/src/components/header/CHeaderText.tsx b/packages/coreui-react/src/components/header/CHeaderText.tsx deleted file mode 100644 index 7db38b16..00000000 --- a/packages/coreui-react/src/components/header/CHeaderText.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CHeaderTextProps extends HTMLAttributes<HTMLSpanElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CHeaderText = forwardRef<HTMLSpanElement, CHeaderTextProps>( - ({ children, className, ...rest }, ref) => { - return ( - <span className={classNames('header-text', className)} {...rest} ref={ref}> - {children} - </span> - ) - }, -) - -CHeaderText.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CHeaderText.displayName = 'CHeaderText' diff --git a/packages/coreui-react/src/components/header/CHeaderToggler.tsx b/packages/coreui-react/src/components/header/CHeaderToggler.tsx deleted file mode 100644 index d4eec4e9..00000000 --- a/packages/coreui-react/src/components/header/CHeaderToggler.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CHeaderTogglerProps extends HTMLAttributes<HTMLButtonElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CHeaderToggler = forwardRef<HTMLButtonElement, CHeaderTogglerProps>( - ({ children, className, ...rest }, ref) => { - return ( - <button type="button" className={classNames('header-toggler', className)} {...rest} ref={ref}> - {children ?? <span className="header-toggler-icon"></span>} - </button> - ) - }, -) - -CHeaderToggler.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CHeaderToggler.displayName = 'CHeaderToggler' diff --git a/packages/coreui-react/src/components/header/__tests__/CHeader.spec.tsx b/packages/coreui-react/src/components/header/__tests__/CHeader.spec.tsx deleted file mode 100644 index 2691ca8e..00000000 --- a/packages/coreui-react/src/components/header/__tests__/CHeader.spec.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CHeader } from '../../../index' - -test('loads and displays CHeader component', async () => { - const { container } = render(<CHeader>Test</CHeader>) - expect(container).toMatchSnapshot() -}) - -test('CHeader customize', async () => { - const { container } = render( - <CHeader className="bazinga" container="lg" position="sticky"> - Test - </CHeader>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('header') - expect(container.firstChild).toHaveClass('header-sticky') -}) diff --git a/packages/coreui-react/src/components/header/__tests__/CHeaderBrand.spec.tsx b/packages/coreui-react/src/components/header/__tests__/CHeaderBrand.spec.tsx deleted file mode 100644 index ed6f5044..00000000 --- a/packages/coreui-react/src/components/header/__tests__/CHeaderBrand.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CHeaderBrand } from '../../../index' - -test('loads and displays CHeaderBrand component', async () => { - const { container } = render(<CHeaderBrand>Test</CHeaderBrand>) - expect(container).toMatchSnapshot() -}) - -test('CHeaderBrand customize', async () => { - const { container } = render( - <CHeaderBrand className="bazinga" component="h3"> - Test - </CHeaderBrand>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('header-brand') -}) diff --git a/packages/coreui-react/src/components/header/__tests__/CHeaderDivider.spec.tsx b/packages/coreui-react/src/components/header/__tests__/CHeaderDivider.spec.tsx deleted file mode 100644 index 663a5df1..00000000 --- a/packages/coreui-react/src/components/header/__tests__/CHeaderDivider.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CHeaderDivider } from '../../../index' - -test('loads and displays CHeaderDivider component', async () => { - const { container } = render(<CHeaderDivider>Test</CHeaderDivider>) - expect(container).toMatchSnapshot() -}) - -test('CHeaderDivider customize', async () => { - const { container } = render(<CHeaderDivider className="bazinga">Test</CHeaderDivider>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('header-divider') -}) diff --git a/packages/coreui-react/src/components/header/__tests__/CHeaderNav.spec.tsx b/packages/coreui-react/src/components/header/__tests__/CHeaderNav.spec.tsx deleted file mode 100644 index 44c3f599..00000000 --- a/packages/coreui-react/src/components/header/__tests__/CHeaderNav.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CHeaderNav } from '../../../index' - -test('loads and displays CHeaderNav component', async () => { - const { container } = render(<CHeaderNav>Test</CHeaderNav>) - expect(container).toMatchSnapshot() -}) - -test('CHeaderNav customize', async () => { - const { container } = render( - <CHeaderNav className="bazinga" component="h3"> - Test - </CHeaderNav>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('header-nav') -}) diff --git a/packages/coreui-react/src/components/header/__tests__/CHeaderText.spec.tsx b/packages/coreui-react/src/components/header/__tests__/CHeaderText.spec.tsx deleted file mode 100644 index cf4af9e2..00000000 --- a/packages/coreui-react/src/components/header/__tests__/CHeaderText.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CHeaderText } from '../../../index' - -test('loads and displays CHeaderText component', async () => { - const { container } = render(<CHeaderText>Test</CHeaderText>) - expect(container).toMatchSnapshot() -}) - -test('CHeaderText customize', async () => { - const { container } = render(<CHeaderText className="bazinga">Test</CHeaderText>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('header-text') -}) diff --git a/packages/coreui-react/src/components/header/__tests__/CHeaderToggler.spec.tsx b/packages/coreui-react/src/components/header/__tests__/CHeaderToggler.spec.tsx deleted file mode 100644 index 09091e51..00000000 --- a/packages/coreui-react/src/components/header/__tests__/CHeaderToggler.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CHeaderToggler } from '../../../index' - -test('loads and displays CHeaderToggler component', async () => { - const { container } = render(<CHeaderToggler>Test</CHeaderToggler>) - expect(container).toMatchSnapshot() -}) - -test('CHeaderToggler customize', async () => { - const { container } = render(<CHeaderToggler className="bazinga">Test</CHeaderToggler>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('header-toggler') -}) diff --git a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeader.spec.tsx.snap b/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeader.spec.tsx.snap deleted file mode 100644 index 206dfdc0..00000000 --- a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeader.spec.tsx.snap +++ /dev/null @@ -1,25 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CHeader customize 1`] = ` -<div> - <div - class="header header-sticky bazinga" - > - <div - class="container-lg" - > - Test - </div> - </div> -</div> -`; - -exports[`loads and displays CHeader component 1`] = ` -<div> - <div - class="header" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderBrand.spec.tsx.snap b/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderBrand.spec.tsx.snap deleted file mode 100644 index b1ee3bf8..00000000 --- a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderBrand.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CHeaderBrand customize 1`] = ` -<div> - <h3 - class="header-brand bazinga" - > - Test - </h3> -</div> -`; - -exports[`loads and displays CHeaderBrand component 1`] = ` -<div> - <a - class="header-brand" - > - Test - </a> -</div> -`; diff --git a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderDivider.spec.tsx.snap b/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderDivider.spec.tsx.snap deleted file mode 100644 index 7a19a2ce..00000000 --- a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderDivider.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CHeaderDivider customize 1`] = ` -<div> - <div - class="header-divider bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CHeaderDivider component 1`] = ` -<div> - <div - class="header-divider" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderNav.spec.tsx.snap b/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderNav.spec.tsx.snap deleted file mode 100644 index e6cfd03c..00000000 --- a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderNav.spec.tsx.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CHeaderNav customize 1`] = ` -<div> - <h3 - class="header-nav bazinga" - role="navigation" - > - Test - </h3> -</div> -`; - -exports[`loads and displays CHeaderNav component 1`] = ` -<div> - <ul - class="header-nav" - role="navigation" - > - Test - </ul> -</div> -`; diff --git a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderText.spec.tsx.snap b/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderText.spec.tsx.snap deleted file mode 100644 index c28c7920..00000000 --- a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderText.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CHeaderText customize 1`] = ` -<div> - <span - class="header-text bazinga" - > - Test - </span> -</div> -`; - -exports[`loads and displays CHeaderText component 1`] = ` -<div> - <span - class="header-text" - > - Test - </span> -</div> -`; diff --git a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderToggler.spec.tsx.snap b/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderToggler.spec.tsx.snap deleted file mode 100644 index 09acb6a2..00000000 --- a/packages/coreui-react/src/components/header/__tests__/__snapshots__/CHeaderToggler.spec.tsx.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CHeaderToggler customize 1`] = ` -<div> - <button - class="header-toggler bazinga" - type="button" - > - Test - </button> -</div> -`; - -exports[`loads and displays CHeaderToggler component 1`] = ` -<div> - <button - class="header-toggler" - type="button" - > - Test - </button> -</div> -`; diff --git a/packages/coreui-react/src/components/header/index.ts b/packages/coreui-react/src/components/header/index.ts deleted file mode 100644 index 26053518..00000000 --- a/packages/coreui-react/src/components/header/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { CHeader } from './CHeader' -import { CHeaderBrand } from './CHeaderBrand' -import { CHeaderDivider } from './CHeaderDivider' -import { CHeaderNav } from './CHeaderNav' -import { CHeaderText } from './CHeaderText' -import { CHeaderToggler } from './CHeaderToggler' - -export { CHeader, CHeaderBrand, CHeaderDivider, CHeaderNav, CHeaderText, CHeaderToggler } diff --git a/packages/coreui-react/src/components/image/CImage.tsx b/packages/coreui-react/src/components/image/CImage.tsx deleted file mode 100644 index ecce5bdf..00000000 --- a/packages/coreui-react/src/components/image/CImage.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import React, { forwardRef, ImgHTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CImageProps extends ImgHTMLAttributes<HTMLOrSVGImageElement> { - /** - * Set the horizontal aligment. - */ - align?: 'start' | 'center' | 'end' - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Make image responsive. - */ - fluid?: boolean - /** - * Make image rounded. - */ - rounded?: boolean - /** - * Give an image a rounded 1px border appearance. - */ - thumbnail?: boolean -} - -export const CImage = forwardRef<HTMLImageElement, CImageProps>( - ({ align, className, fluid, rounded, thumbnail, ...rest }, ref) => { - return ( - <img - className={ - classNames( - { - [`float-${align}`]: align && (align === 'start' || align === 'end'), - 'd-block mx-auto': align && align === 'center', - 'img-fluid': fluid, - rounded: rounded, - 'img-thumbnail': thumbnail, - }, - className, - ) || undefined - } - {...rest} - ref={ref} - /> - ) - }, -) - -CImage.propTypes = { - align: PropTypes.oneOf(['start', 'center', 'end']), - className: PropTypes.string, - fluid: PropTypes.bool, - rounded: PropTypes.bool, - thumbnail: PropTypes.bool, -} - -CImage.displayName = 'CImage' diff --git a/packages/coreui-react/src/components/image/__tests__/CImage.spec.tsx b/packages/coreui-react/src/components/image/__tests__/CImage.spec.tsx deleted file mode 100644 index ae73b9b2..00000000 --- a/packages/coreui-react/src/components/image/__tests__/CImage.spec.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CImage } from '../../../index' - -test('loads and displays CImage component', async () => { - const { container } = render(<CImage />) - expect(container).toMatchSnapshot() -}) - -test('CImage customize one', async () => { - const { container } = render(<CImage align="end" />) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('float-end') -}) - -test('CImage customize two', async () => { - const { container } = render( - <CImage className="bazinga" align="center" fluid={true} rounded={true} thumbnail={true} />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('d-block') - expect(container.firstChild).toHaveClass('mx-auto') - expect(container.firstChild).toHaveClass('img-fluid') - expect(container.firstChild).toHaveClass('rounded') - expect(container.firstChild).toHaveClass('img-thumbnail') - expect(container.firstChild).toHaveClass('bazinga') -}) diff --git a/packages/coreui-react/src/components/image/__tests__/__snapshots__/CImage.spec.tsx.snap b/packages/coreui-react/src/components/image/__tests__/__snapshots__/CImage.spec.tsx.snap deleted file mode 100644 index 0f302c77..00000000 --- a/packages/coreui-react/src/components/image/__tests__/__snapshots__/CImage.spec.tsx.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CImage customize one 1`] = ` -<div> - <img - class="float-end" - /> -</div> -`; - -exports[`CImage customize two 1`] = ` -<div> - <img - class="d-block mx-auto img-fluid rounded img-thumbnail bazinga" - /> -</div> -`; - -exports[`loads and displays CImage component 1`] = ` -<div> - <img /> -</div> -`; diff --git a/packages/coreui-react/src/components/image/index.ts b/packages/coreui-react/src/components/image/index.ts deleted file mode 100644 index a2bc30ae..00000000 --- a/packages/coreui-react/src/components/image/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CImage } from './CImage' - -export { CImage } diff --git a/packages/coreui-react/src/components/index.ts b/packages/coreui-react/src/components/index.ts deleted file mode 100644 index 0f233ef7..00000000 --- a/packages/coreui-react/src/components/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -export * from './accordion' -export * from './alert' -export * from './avatar' -export * from './backdrop' -export * from './badge' -export * from './breadcrumb' -export * from './button' -export * from './button-group' -export * from './callout' -export * from './card' -export * from './carousel' -export * from './close-button' -export * from './collapse' -export * from './conditional-portal' -export * from './dropdown' -export * from './footer' -export * from './form' -export * from './grid' -export * from './header' -export * from './image' -export * from './link' -export * from './list-group' -export * from './modal' -export * from './nav' -export * from './navbar' -export * from './offcanvas' -export * from './pagination' -export * from './placeholder' -export * from './progress' -export * from './popover' -export * from './sidebar' -export * from './spinner' -export * from './table' -export * from './tabs' -export * from './toast' -export * from './tooltip' -export * from './widgets' diff --git a/packages/coreui-react/src/components/link/CLink.tsx b/packages/coreui-react/src/components/link/CLink.tsx deleted file mode 100644 index 502c0c5d..00000000 --- a/packages/coreui-react/src/components/link/CLink.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React, { AllHTMLAttributes, ElementType, forwardRef, MouseEvent } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CLinkProps extends AllHTMLAttributes<HTMLButtonElement | HTMLAnchorElement> { - /** - * Toggle the active state for the component. - */ - active?: boolean - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Toggle the disabled state for the component. - */ - disabled?: boolean - /** - * The href attribute specifies the URL of the page the link goes to. - */ - href?: string -} - -export const CLink = forwardRef<HTMLButtonElement | HTMLAnchorElement, CLinkProps>( - ({ children, active, className, component: Component = 'a', disabled, ...rest }, ref) => { - return ( - <Component - // TODO: remove duplicated classes ex. `active active` in `<CListGroupItem>` - className={classNames(className, { active, disabled })} - {...(active && { 'aria-current': 'page' })} - {...(Component === 'a' && disabled && { 'aria-disabled': true, tabIndex: -1 })} - {...((Component === 'a' || Component === 'button') && { - onClick: (event: MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => { - event.preventDefault - !disabled && rest.onClick && rest.onClick(event) - }, - })} - disabled={disabled} - {...rest} - ref={ref} - > - {children} - </Component> - ) - }, -) - -CLink.propTypes = { - active: PropTypes.bool, - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, - disabled: PropTypes.bool, -} - -CLink.displayName = 'CLink' diff --git a/packages/coreui-react/src/components/link/__tests__/CLink.spec.tsx b/packages/coreui-react/src/components/link/__tests__/CLink.spec.tsx deleted file mode 100644 index a918ace2..00000000 --- a/packages/coreui-react/src/components/link/__tests__/CLink.spec.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import * as React from 'react' -import { render, fireEvent } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CLink } from '../../../index' - -test('loads and displays CLink component', async () => { - const { container } = render(<CLink>Test</CLink>) - expect(container).toMatchSnapshot() -}) - -test('CLink customize', async () => { - const { container } = render( - <CLink className="bazinga" active={true} component="button" disabled type="submit"> - Test - </CLink>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('active') - expect(container.firstChild).toHaveAttribute('disabled') -}) - -test('CLink click on button', async () => { - const onClick = jest.fn() - render( - <CLink onClick={onClick} className="bazinga"> - Test - </CLink>, - ) - expect(onClick).toHaveBeenCalledTimes(0) - const link = document.querySelector('.bazinga') - if (link !== null) { - fireEvent.click(link) - } - expect(onClick).toHaveBeenCalledTimes(1) -}) - -test('CLink click on disabled button', async () => { - const click = jest.fn() - render( - <CLink onClick={click} className="bazinga" component="button" disabled> - Test - </CLink>, - ) - expect(click).toHaveBeenCalledTimes(0) - const link = document.querySelector('.bazinga') - if (link !== null) { - fireEvent.click(link) - } - expect(click).toHaveBeenCalledTimes(0) -}) diff --git a/packages/coreui-react/src/components/link/__tests__/__snapshots__/CLink.spec.tsx.snap b/packages/coreui-react/src/components/link/__tests__/__snapshots__/CLink.spec.tsx.snap deleted file mode 100644 index 0ce3412c..00000000 --- a/packages/coreui-react/src/components/link/__tests__/__snapshots__/CLink.spec.tsx.snap +++ /dev/null @@ -1,24 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CLink customize 1`] = ` -<div> - <button - aria-current="page" - class="bazinga active disabled" - disabled="" - type="submit" - > - Test - </button> -</div> -`; - -exports[`loads and displays CLink component 1`] = ` -<div> - <a - class="" - > - Test - </a> -</div> -`; diff --git a/packages/coreui-react/src/components/link/index.ts b/packages/coreui-react/src/components/link/index.ts deleted file mode 100644 index 3b5241b6..00000000 --- a/packages/coreui-react/src/components/link/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CLink } from './CLink' - -export { CLink } diff --git a/packages/coreui-react/src/components/list-group/CListGroup.tsx b/packages/coreui-react/src/components/list-group/CListGroup.tsx deleted file mode 100644 index 31ca93f2..00000000 --- a/packages/coreui-react/src/components/list-group/CListGroup.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CListGroupProps extends HTMLAttributes<HTMLDivElement | HTMLUListElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Remove some borders and rounded corners to render list group items edge-to-edge in a parent component (e.g., `<CCard>`). - */ - flush?: boolean - /** - * Specify a layout type. - */ - layout?: - | 'horizontal' - | 'horizontal-sm' - | 'horizontal-md' - | 'horizontal-lg' - | 'horizontal-xl' - | 'horizontal-xxl' -} - -export const CListGroup = forwardRef<HTMLDivElement | HTMLUListElement, CListGroupProps>( - ({ children, className, component: Component = 'ul', flush, layout }, ref) => { - return ( - <Component - className={classNames( - 'list-group', - { - 'list-group-flush': flush, - [`list-group-${layout}`]: layout, - }, - className, - )} - ref={ref} - > - {children} - </Component> - ) - }, -) - -CListGroup.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, - flush: PropTypes.bool, - layout: PropTypes.oneOf([ - 'horizontal', - 'horizontal-sm', - 'horizontal-md', - 'horizontal-lg', - 'horizontal-xl', - 'horizontal-xxl', - ]), -} - -CListGroup.displayName = 'CListGroup' diff --git a/packages/coreui-react/src/components/list-group/CListGroupItem.tsx b/packages/coreui-react/src/components/list-group/CListGroupItem.tsx deleted file mode 100644 index a8dc0113..00000000 --- a/packages/coreui-react/src/components/list-group/CListGroupItem.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React, { ElementType, AnchorHTMLAttributes, forwardRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CLink } from '../link/CLink' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CListGroupItemProps - extends AnchorHTMLAttributes<HTMLLIElement | HTMLAnchorElement | HTMLButtonElement> { - /** - * Toggle the active state for the component. - */ - active?: boolean - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Toggle the disabled state for the component. - */ - disabled?: boolean - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CListGroupItem = forwardRef< - HTMLLIElement | HTMLAnchorElement | HTMLButtonElement, - CListGroupItemProps ->(({ children, active, className, disabled, color, component = 'li', ...rest }, ref) => { - const Component = component === 'a' || component === 'button' ? CLink : component - - rest = { - ...((component === 'a' || component === 'button') && { - active, - disabled, - component, - ref: ref, - }), - ...(active && { 'aria-current': true }), - ...(disabled && { 'aria-disabled': true }), - ...rest, - } - - return ( - <Component - className={classNames( - 'list-group-item', - { - [`list-group-item-${color}`]: color, - 'list-group-item-action': component === 'a' || component === 'button', - active, - disabled, - }, - className, - )} - {...rest} - > - {children} - </Component> - ) -}) - -CListGroupItem.propTypes = { - active: PropTypes.bool, - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, - component: PropTypes.elementType, - disabled: PropTypes.bool, -} - -CListGroupItem.displayName = 'CListGroupItem' diff --git a/packages/coreui-react/src/components/list-group/__tests__/CListGroup.spec.tsx b/packages/coreui-react/src/components/list-group/__tests__/CListGroup.spec.tsx deleted file mode 100644 index 0210e21b..00000000 --- a/packages/coreui-react/src/components/list-group/__tests__/CListGroup.spec.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CListGroup, CListGroupItem } from '../../../index' - -test('loads and displays CListGroup component', async () => { - const { container } = render(<CListGroup>Test</CListGroup>) - expect(container).toMatchSnapshot() -}) - -test('CListGroup customize', async () => { - const { container } = render( - <CListGroup className="bazinga" component="h3" flush={true} layout="horizontal-xl"> - Test - </CListGroup>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('list-group') - expect(container.firstChild).toHaveClass('list-group-flush') - expect(container.firstChild).toHaveClass('list-group-horizontal-xl') -}) - -test('CListGroup example', async () => { - const { container } = render( - <CListGroup> - <CListGroupItem>A</CListGroupItem> - <CListGroupItem>B</CListGroupItem> - <CListGroupItem>C</CListGroupItem> - </CListGroup>, - ) - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/list-group/__tests__/CListGroupItem.spec.tsx b/packages/coreui-react/src/components/list-group/__tests__/CListGroupItem.spec.tsx deleted file mode 100644 index ab5ac616..00000000 --- a/packages/coreui-react/src/components/list-group/__tests__/CListGroupItem.spec.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CListGroupItem } from '../../../index' - -test('loads and displays CListGroupItem component', async () => { - const { container } = render(<CListGroupItem>Test</CListGroupItem>) - expect(container).toMatchSnapshot() -}) - -test('CListGroupItem customize', async () => { - const { container } = render( - <CListGroupItem - className="bazinga" - active={true} - color="warning" - disabled={true} - component="button" - > - Test - </CListGroupItem>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('list-group-item') - expect(container.firstChild).toHaveClass('list-group-item-action') - expect(container.firstChild).toHaveClass('active') - expect(container.firstChild).toHaveClass('disabled') -}) diff --git a/packages/coreui-react/src/components/list-group/__tests__/__snapshots__/CListGroup.spec.tsx.snap b/packages/coreui-react/src/components/list-group/__tests__/__snapshots__/CListGroup.spec.tsx.snap deleted file mode 100644 index 806b3c69..00000000 --- a/packages/coreui-react/src/components/list-group/__tests__/__snapshots__/CListGroup.spec.tsx.snap +++ /dev/null @@ -1,45 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CListGroup customize 1`] = ` -<div> - <h3 - class="list-group list-group-flush list-group-horizontal-xl bazinga" - > - Test - </h3> -</div> -`; - -exports[`CListGroup example 1`] = ` -<div> - <ul - class="list-group" - > - <li - class="list-group-item" - > - A - </li> - <li - class="list-group-item" - > - B - </li> - <li - class="list-group-item" - > - C - </li> - </ul> -</div> -`; - -exports[`loads and displays CListGroup component 1`] = ` -<div> - <ul - class="list-group" - > - Test - </ul> -</div> -`; diff --git a/packages/coreui-react/src/components/list-group/__tests__/__snapshots__/CListGroupItem.spec.tsx.snap b/packages/coreui-react/src/components/list-group/__tests__/__snapshots__/CListGroupItem.spec.tsx.snap deleted file mode 100644 index 511bdada..00000000 --- a/packages/coreui-react/src/components/list-group/__tests__/__snapshots__/CListGroupItem.spec.tsx.snap +++ /dev/null @@ -1,24 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CListGroupItem customize 1`] = ` -<div> - <button - aria-current="true" - aria-disabled="true" - class="list-group-item list-group-item-warning list-group-item-action active disabled bazinga active disabled" - disabled="" - > - Test - </button> -</div> -`; - -exports[`loads and displays CListGroupItem component 1`] = ` -<div> - <li - class="list-group-item" - > - Test - </li> -</div> -`; diff --git a/packages/coreui-react/src/components/list-group/index.ts b/packages/coreui-react/src/components/list-group/index.ts deleted file mode 100644 index 802b3330..00000000 --- a/packages/coreui-react/src/components/list-group/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { CListGroup } from './CListGroup' -import { CListGroupItem } from './CListGroupItem' - -export { CListGroup, CListGroupItem } diff --git a/packages/coreui-react/src/components/modal/CModal.tsx b/packages/coreui-react/src/components/modal/CModal.tsx deleted file mode 100644 index 2c8ed10e..00000000 --- a/packages/coreui-react/src/components/modal/CModal.tsx +++ /dev/null @@ -1,297 +0,0 @@ -import React, { - createContext, - forwardRef, - HTMLAttributes, - useEffect, - useLayoutEffect, - useRef, - useState, -} from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' -import { Transition } from 'react-transition-group' - -import { CBackdrop } from '../backdrop' -import { CConditionalPortal } from '../conditional-portal' -import { CModalContent } from './CModalContent' -import { CModalDialog } from './CModalDialog' - -import { useForkedRef } from '../../hooks' - -export interface CModalProps extends HTMLAttributes<HTMLDivElement> { - /** - * Align the modal in the center or top of the screen. - */ - alignment?: 'top' | 'center' - /** - * Apply a backdrop on body while modal is open. - */ - backdrop?: boolean | 'static' - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * @ignore - */ - duration?: number - /** - * Puts the focus on the modal when shown. - * - * @since v4.10.0 - */ - focus?: boolean - /** - * Set modal to covers the entire user viewport. - */ - fullscreen?: boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' - /** - * Closes the modal when escape key is pressed. - */ - keyboard?: boolean - /** - * Callback fired when the component requests to be closed. - */ - onClose?: () => void - /** - * Callback fired when the component requests to be closed. - */ - onClosePrevented?: () => void - /** - * Callback fired when the modal is shown, its backdrop is static and a click outside the modal or an escape key press is performed with the keyboard option set to false. - */ - onShow?: () => void - /** - * Generates modal using createPortal. - */ - portal?: boolean - /** - * Create a scrollable modal that allows scrolling the modal body. - */ - scrollable?: boolean - /** - * Size the component small, large, or extra large. - */ - size?: 'sm' | 'lg' | 'xl' - /** - * Remove animation to create modal that simply appear rather than fade in to view. - */ - transition?: boolean - /** - * By default the component is unmounted after close animation, if you want to keep the component mounted set this property to false. - */ - unmountOnClose?: boolean - /** - * Toggle the visibility of modal component. - */ - visible?: boolean -} - -interface ModalContextProps { - visible?: boolean - setVisible: React.Dispatch<React.SetStateAction<boolean | undefined>> -} - -export const CModalContext = createContext({} as ModalContextProps) - -export const CModal = forwardRef<HTMLDivElement, CModalProps>( - ( - { - children, - alignment, - backdrop = true, - className, - duration = 150, - focus = true, - fullscreen, - keyboard = true, - onClose, - onClosePrevented, - onShow, - portal = true, - scrollable, - size, - transition = true, - unmountOnClose = true, - visible, - ...rest - }, - ref, - ) => { - const activeElementRef = useRef<HTMLElement | null>(null) - const modalRef = useRef<HTMLDivElement>(null) - const modalContentRef = useRef<HTMLDivElement>(null) - const forkedRef = useForkedRef(ref, modalRef) - - const [_visible, setVisible] = useState(visible) - const [staticBackdrop, setStaticBackdrop] = useState(false) - - const contextValues = { - visible: _visible, - setVisible, - } - - useEffect(() => { - setVisible(visible) - }, [visible]) - - useEffect(() => { - if (_visible) { - activeElementRef.current = document.activeElement as HTMLElement | null - document.addEventListener('mouseup', handleClickOutside) - document.addEventListener('keydown', handleKeyDown) - } else { - activeElementRef.current?.focus() - } - - return () => { - document.removeEventListener('mouseup', handleClickOutside) - document.removeEventListener('keydown', handleKeyDown) - } - }, [_visible]) - - const handleDismiss = () => { - if (backdrop === 'static') { - return setStaticBackdrop(true) - } - - setVisible(false) - - return onClose && onClose() - } - - useLayoutEffect(() => { - onClosePrevented && onClosePrevented() - setTimeout(() => setStaticBackdrop(false), duration) - }, [staticBackdrop]) - - // Set focus to modal after open - useLayoutEffect(() => { - if (_visible) { - document.body.classList.add('modal-open') - - if (backdrop) { - document.body.style.overflow = 'hidden' - document.body.style.paddingRight = '0px' - } - - setTimeout( - () => { - focus && modalRef.current?.focus() - }, - transition ? duration : 0, - ) - } else { - document.body.classList.remove('modal-open') - - if (backdrop) { - document.body.style.removeProperty('overflow') - document.body.style.removeProperty('padding-right') - } - } - - return () => { - document.body.classList.remove('modal-open') - if (backdrop) { - document.body.style.removeProperty('overflow') - document.body.style.removeProperty('padding-right') - } - } - }, [_visible]) - - const handleClickOutside = (event: Event) => { - if ( - modalContentRef.current && - !modalContentRef.current.contains(event.target as HTMLElement) - ) { - handleDismiss() - } - } - - const handleKeyDown = (event: KeyboardEvent) => { - if (event.key === 'Escape' && keyboard) { - handleDismiss() - } - } - - return ( - <> - <Transition - in={_visible} - mountOnEnter - nodeRef={modalRef} - onEnter={onShow} - onExit={onClose} - unmountOnExit={unmountOnClose} - timeout={transition ? duration : 0} - > - {(state) => ( - <CConditionalPortal portal={portal}> - <CModalContext.Provider value={contextValues}> - <div - className={classNames( - 'modal', - { - 'modal-static': staticBackdrop, - fade: transition, - show: state === 'entered', - }, - className, - )} - tabIndex={-1} - {...(_visible - ? { 'aria-modal': true, role: 'dialog' } - : { 'aria-hidden': 'true' })} - style={{ - ...(state !== 'exited' && { display: 'block' }), - }} - {...rest} - ref={forkedRef} - > - <CModalDialog - alignment={alignment} - fullscreen={fullscreen} - scrollable={scrollable} - size={size} - > - <CModalContent ref={modalContentRef}>{children}</CModalContent> - </CModalDialog> - </div> - </CModalContext.Provider> - </CConditionalPortal> - )} - </Transition> - {backdrop && ( - <CConditionalPortal portal={portal}> - <CBackdrop visible={_visible} /> - </CConditionalPortal> - )} - </> - ) - }, -) - -CModal.propTypes = { - alignment: PropTypes.oneOf(['top', 'center']), - backdrop: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf<'static'>(['static'])]), - children: PropTypes.node, - className: PropTypes.string, - duration: PropTypes.number, - focus: PropTypes.bool, - fullscreen: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.oneOf<'sm' | 'md' | 'lg' | 'xl' | 'xxl'>(['sm', 'md', 'lg', 'xl', 'xxl']), - ]), - keyboard: PropTypes.bool, - onClose: PropTypes.func, - onClosePrevented: PropTypes.func, - onShow: PropTypes.func, - portal: PropTypes.bool, - scrollable: PropTypes.bool, - size: PropTypes.oneOf(['sm', 'lg', 'xl']), - transition: PropTypes.bool, - unmountOnClose: PropTypes.bool, - visible: PropTypes.bool, -} - -CModal.displayName = 'CModal' diff --git a/packages/coreui-react/src/components/modal/CModalBody.tsx b/packages/coreui-react/src/components/modal/CModalBody.tsx deleted file mode 100644 index 55de449f..00000000 --- a/packages/coreui-react/src/components/modal/CModalBody.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CModalBodyProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CModalBody = forwardRef<HTMLDivElement, CModalBodyProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('modal-body', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -CModalBody.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CModalBody.displayName = 'CModalBody' diff --git a/packages/coreui-react/src/components/modal/CModalContent.tsx b/packages/coreui-react/src/components/modal/CModalContent.tsx deleted file mode 100644 index 3c9e3db9..00000000 --- a/packages/coreui-react/src/components/modal/CModalContent.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CModalContentProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CModalContent = forwardRef<HTMLDivElement, CModalContentProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('modal-content', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -CModalContent.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CModalContent.displayName = 'CModalContent' diff --git a/packages/coreui-react/src/components/modal/CModalDialog.tsx b/packages/coreui-react/src/components/modal/CModalDialog.tsx deleted file mode 100644 index d1c013c9..00000000 --- a/packages/coreui-react/src/components/modal/CModalDialog.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CModalDialogProps extends HTMLAttributes<HTMLDivElement> { - /** - * Align the modal in the center or top of the screen. - */ - alignment?: 'top' | 'center' - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Set modal to covers the entire user viewport. - */ - fullscreen?: boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' - /** - * Does the modal dialog itself scroll, or does the whole dialog scroll within the window. - */ - scrollable?: boolean - /** - * Size the component small, large, or extra large. - */ - size?: 'sm' | 'lg' | 'xl' -} - -export const CModalDialog = forwardRef<HTMLDivElement, CModalDialogProps>( - ({ children, alignment, className, fullscreen, scrollable, size, ...rest }, ref) => { - return ( - <div - className={classNames( - 'modal-dialog', - { - 'modal-dialog-centered': alignment === 'center', - [typeof fullscreen === 'boolean' - ? 'modal-fullscreen' - : `modal-fullscreen-${fullscreen}-down`]: fullscreen, - 'modal-dialog-scrollable': scrollable, - [`modal-${size}`]: size, - }, - className, - )} - {...rest} - ref={ref} - > - {children} - </div> - ) - }, -) - -CModalDialog.propTypes = { - alignment: PropTypes.oneOf(['top', 'center']), - children: PropTypes.node, - className: PropTypes.string, - fullscreen: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.oneOf<'sm' | 'md' | 'lg' | 'xl' | 'xxl'>(['sm', 'md', 'lg', 'xl', 'xxl']), - ]), - scrollable: PropTypes.bool, - size: PropTypes.oneOf(['sm', 'lg', 'xl']), -} - -CModalDialog.displayName = 'CModalDialog' diff --git a/packages/coreui-react/src/components/modal/CModalFooter.tsx b/packages/coreui-react/src/components/modal/CModalFooter.tsx deleted file mode 100644 index 8f925a07..00000000 --- a/packages/coreui-react/src/components/modal/CModalFooter.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CModalFooterProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CModalFooter = forwardRef<HTMLDivElement, CModalFooterProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('modal-footer', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -CModalFooter.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CModalFooter.displayName = 'CModalFooter' diff --git a/packages/coreui-react/src/components/modal/CModalHeader.tsx b/packages/coreui-react/src/components/modal/CModalHeader.tsx deleted file mode 100644 index 2aa085b9..00000000 --- a/packages/coreui-react/src/components/modal/CModalHeader.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useContext } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CCloseButton } from '../close-button/CCloseButton' -import { CModalContext } from './CModal' - -export interface CModalHeaderProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Add a close button component to the header. - */ - closeButton?: boolean -} - -export const CModalHeader = forwardRef<HTMLDivElement, CModalHeaderProps>( - ({ children, className, closeButton = true, ...rest }, ref) => { - const { setVisible } = useContext(CModalContext) - - return ( - <div className={classNames('modal-header', className)} {...rest} ref={ref}> - {children} - {closeButton && <CCloseButton onClick={() => setVisible(false)} />} - </div> - ) - }, -) - -CModalHeader.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - closeButton: PropTypes.bool, -} - -CModalHeader.displayName = 'CModalHeader' diff --git a/packages/coreui-react/src/components/modal/CModalTitle.tsx b/packages/coreui-react/src/components/modal/CModalTitle.tsx deleted file mode 100644 index d81ffacf..00000000 --- a/packages/coreui-react/src/components/modal/CModalTitle.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CModalTitleProps extends HTMLAttributes<HTMLHeadingElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CModalTitle = forwardRef<HTMLHeadElement, CModalTitleProps>( - ({ children, component: Component = 'h5', className, ...rest }, ref) => { - return ( - <Component className={classNames('modal-title', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CModalTitle.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CModalTitle.displayName = 'CModalTitle' diff --git a/packages/coreui-react/src/components/modal/__tests__/CModal.spec.tsx b/packages/coreui-react/src/components/modal/__tests__/CModal.spec.tsx deleted file mode 100644 index 0ad365cb..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/CModal.spec.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import * as React from 'react' -import { render, fireEvent } from '@testing-library/react' -import '@testing-library/jest-dom/extend-expect' -import { CModal } from '../../../index' - -test('loads and displays CModal component', async () => { - const { container } = render(<CModal portal={false}>Test</CModal>) - expect(container).toMatchSnapshot() -}) - -test('CModal customize', async () => { - const { container } = render( - <CModal - alignment="center" - className="bazinga" - duration={100} - fullscreen="xl" - scrollable={true} - size="xl" - visible={true} - > - Test - </CModal>, - ) - expect(container).toMatchSnapshot() -}) - -test('CModal dialog close on press ESC', async () => { - const onClose = jest.fn() - render( - <CModal onClose={onClose} portal={false} visible> - Test - </CModal>, - ) - expect(onClose).toHaveBeenCalledTimes(0) - const modal = document.querySelector('.modal') - if (modal !== null) { - fireEvent.keyDown(modal, { - key: 'Escape', - code: 'Escape', - keyCode: 27, - charCode: 27, - }) - } - await new Promise((r) => setTimeout(r, 1000)) - console.log(modal) - expect(onClose).toHaveBeenCalledTimes(1) -}) - -test('CModal dialog close on backdrop', async () => { - jest.useFakeTimers() - const onClose = jest.fn() - render( - <CModal onClose={onClose} portal={false} visible={true}> - Test - </CModal>, - ) - expect(onClose).toHaveBeenCalledTimes(0) - const backdrop = document.querySelector('.modal-backdrop') - if (backdrop !== null) { - fireEvent.click(backdrop) - } - jest.runAllTimers() - expect(onClose).toHaveBeenCalledTimes(1) - jest.useRealTimers() -}) diff --git a/packages/coreui-react/src/components/modal/__tests__/CModalBody.spec.tsx b/packages/coreui-react/src/components/modal/__tests__/CModalBody.spec.tsx deleted file mode 100644 index 6e14ce16..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/CModalBody.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CModalBody } from '../../../index' - -test('loads and displays CModalBody component', async () => { - const { container } = render(<CModalBody>Test</CModalBody>) - expect(container).toMatchSnapshot() -}) - -test('CModalBody customize', async () => { - const { container } = render(<CModalBody className="bazinga">Test</CModalBody>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('modal-body') -}) diff --git a/packages/coreui-react/src/components/modal/__tests__/CModalContent.spec.tsx b/packages/coreui-react/src/components/modal/__tests__/CModalContent.spec.tsx deleted file mode 100644 index 15cb52bb..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/CModalContent.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CModalContent } from '../../../index' - -test('loads and displays CModalContent component', async () => { - const { container } = render(<CModalContent>Test</CModalContent>) - expect(container).toMatchSnapshot() -}) - -test('CModalContent customize', async () => { - const { container } = render(<CModalContent className="bazinga">Test</CModalContent>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('modal-content') -}) diff --git a/packages/coreui-react/src/components/modal/__tests__/CModalDialog.spec.tsx b/packages/coreui-react/src/components/modal/__tests__/CModalDialog.spec.tsx deleted file mode 100644 index 32c4a6a5..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/CModalDialog.spec.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CModalDialog } from '../../../index' - -test('loads and displays CModalDialog component', async () => { - const { container } = render(<CModalDialog>Test</CModalDialog>) - expect(container).toMatchSnapshot() -}) - -test('CModalDialog customize', async () => { - const { container } = render( - <CModalDialog - className="bazinga" - alignment="center" - fullscreen="lg" - scrollable={true} - size="xl" - > - Test - </CModalDialog>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('modal-dialog') - expect(container.firstChild).toHaveClass('modal-dialog-centered') - expect(container.firstChild).toHaveClass('modal-fullscreen-lg-down') - expect(container.firstChild).toHaveClass('modal-dialog-scrollable') - expect(container.firstChild).toHaveClass('modal-xl') -}) diff --git a/packages/coreui-react/src/components/modal/__tests__/CModalFooter.spec.tsx b/packages/coreui-react/src/components/modal/__tests__/CModalFooter.spec.tsx deleted file mode 100644 index c68d915e..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/CModalFooter.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CModalFooter } from '../../../index' - -test('loads and displays CModalFooter component', async () => { - const { container } = render(<CModalFooter>Test</CModalFooter>) - expect(container).toMatchSnapshot() -}) - -test('CModalFooter customize', async () => { - const { container } = render(<CModalFooter className="bazinga">Test</CModalFooter>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('modal-footer') -}) diff --git a/packages/coreui-react/src/components/modal/__tests__/CModalHeader.spec.tsx b/packages/coreui-react/src/components/modal/__tests__/CModalHeader.spec.tsx deleted file mode 100644 index 08b41930..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/CModalHeader.spec.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CModalHeader } from '../../../index' - -test('loads and displays CModalHeader component', async () => { - const { container } = render(<CModalHeader>Test</CModalHeader>) - expect(container).toMatchSnapshot() -}) - -test('CModalHeader customize', async () => { - const { container } = render(<CModalHeader className="bazinga">Test</CModalHeader>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('modal-header') -}) - -test('CModalHeader has a close button', async () => { - const onDismiss = jest.fn() - render(<CModalHeader className="bazinga">Test</CModalHeader>) - expect(onDismiss).toHaveBeenCalledTimes(0) - const btn = document.querySelector('.btn-close') - expect(btn).toBeTruthy() -}) diff --git a/packages/coreui-react/src/components/modal/__tests__/CModalTitle.spec.tsx b/packages/coreui-react/src/components/modal/__tests__/CModalTitle.spec.tsx deleted file mode 100644 index ca194340..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/CModalTitle.spec.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CModalTitle } from '../../../index' - -test('loads and displays CModalTitle component', async () => { - const { container } = render(<CModalTitle>Test</CModalTitle>) - expect(container).toMatchSnapshot() -}) - -test('CModalTitle customize', async () => { - const { container } = render( - <CModalTitle className="bazinga" component="h3"> - Test - </CModalTitle>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('modal-title') -}) diff --git a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModal.spec.tsx.snap b/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModal.spec.tsx.snap deleted file mode 100644 index 66995bec..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModal.spec.tsx.snap +++ /dev/null @@ -1,5 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CModal customize 1`] = `<div />`; - -exports[`loads and displays CModal component 1`] = `<div />`; diff --git a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalBody.spec.tsx.snap b/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalBody.spec.tsx.snap deleted file mode 100644 index d1724ab2..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalBody.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CModalBody customize 1`] = ` -<div> - <div - class="modal-body bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CModalBody component 1`] = ` -<div> - <div - class="modal-body" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalContent.spec.tsx.snap b/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalContent.spec.tsx.snap deleted file mode 100644 index a235c501..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalContent.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CModalContent customize 1`] = ` -<div> - <div - class="modal-content bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CModalContent component 1`] = ` -<div> - <div - class="modal-content" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalDialog.spec.tsx.snap b/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalDialog.spec.tsx.snap deleted file mode 100644 index b73b263b..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalDialog.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CModalDialog customize 1`] = ` -<div> - <div - class="modal-dialog modal-dialog-centered modal-fullscreen-lg-down modal-dialog-scrollable modal-xl bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CModalDialog component 1`] = ` -<div> - <div - class="modal-dialog" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalFooter.spec.tsx.snap b/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalFooter.spec.tsx.snap deleted file mode 100644 index 2ea03aea..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalFooter.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CModalFooter customize 1`] = ` -<div> - <div - class="modal-footer bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CModalFooter component 1`] = ` -<div> - <div - class="modal-footer" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalHeader.spec.tsx.snap b/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalHeader.spec.tsx.snap deleted file mode 100644 index 27af1fa6..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalHeader.spec.tsx.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CModalHeader customize 1`] = ` -<div> - <div - class="modal-header bazinga" - > - Test - <button - aria-label="Close" - class="btn btn-close" - type="button" - /> - </div> -</div> -`; - -exports[`loads and displays CModalHeader component 1`] = ` -<div> - <div - class="modal-header" - > - Test - <button - aria-label="Close" - class="btn btn-close" - type="button" - /> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalTitle.spec.tsx.snap b/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalTitle.spec.tsx.snap deleted file mode 100644 index 7332ff34..00000000 --- a/packages/coreui-react/src/components/modal/__tests__/__snapshots__/CModalTitle.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CModalTitle customize 1`] = ` -<div> - <h3 - class="modal-title bazinga" - > - Test - </h3> -</div> -`; - -exports[`loads and displays CModalTitle component 1`] = ` -<div> - <h5 - class="modal-title" - > - Test - </h5> -</div> -`; diff --git a/packages/coreui-react/src/components/modal/index.ts b/packages/coreui-react/src/components/modal/index.ts deleted file mode 100644 index 182bc116..00000000 --- a/packages/coreui-react/src/components/modal/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { CModal } from './CModal' -import { CModalBody } from './CModalBody' -import { CModalContent } from './CModalContent' -import { CModalDialog } from './CModalDialog' -import { CModalFooter } from './CModalFooter' -import { CModalHeader } from './CModalHeader' -import { CModalTitle } from './CModalTitle' - -export { CModal, CModalBody, CModalContent, CModalDialog, CModalFooter, CModalHeader, CModalTitle } diff --git a/packages/coreui-react/src/components/nav/CNav.tsx b/packages/coreui-react/src/components/nav/CNav.tsx deleted file mode 100644 index 6f5bd4f9..00000000 --- a/packages/coreui-react/src/components/nav/CNav.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CNavProps - extends HTMLAttributes<HTMLDivElement | HTMLUListElement | HTMLOListElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Specify a layout type for component. - */ - layout?: 'fill' | 'justified' - /** - * Set the nav variant to tabs or pills. - */ - variant?: 'pills' | 'tabs' | 'underline' | 'underline-border' -} - -export const CNav = forwardRef<HTMLDivElement | HTMLUListElement | HTMLOListElement, CNavProps>( - ({ children, className, component: Component = 'ul', layout, variant, ...rest }, ref) => { - return ( - <Component - className={classNames( - 'nav', - { - [`nav-${layout}`]: layout, - [`nav-${variant}`]: variant, - }, - className, - )} - role="navigation" - {...rest} - ref={ref} - > - {children} - </Component> - ) - }, -) - -CNav.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, - layout: PropTypes.oneOf(['fill', 'justified']), - variant: PropTypes.oneOf(['pills', 'tabs', 'underline', 'underline-border']), -} - -CNav.displayName = 'CNav' diff --git a/packages/coreui-react/src/components/nav/CNavGroup.tsx b/packages/coreui-react/src/components/nav/CNavGroup.tsx deleted file mode 100644 index 3921055c..00000000 --- a/packages/coreui-react/src/components/nav/CNavGroup.tsx +++ /dev/null @@ -1,159 +0,0 @@ -import React, { - CSSProperties, - forwardRef, - ReactNode, - useContext, - useEffect, - useRef, - useState, -} from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' -import { Transition } from 'react-transition-group' -import type { TransitionStatus } from 'react-transition-group' - -import { CNavContext } from '../sidebar/CSidebarNav' -export interface CNavGroupProps { - children?: ReactNode - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Make nav group more compact by cutting all `padding` in half. - */ - compact?: boolean - /** - * Set group toggler label. - */ - toggler?: string | ReactNode - /** - * Show nav group items. - */ - visible?: boolean - /** - * @ignore - */ - idx?: string -} - -const isInVisibleGroup = (el1: string, el2: string) => { - const array1 = el1.toString().split('.') - const array2 = el2.toString().split('.') - - return array2.every((item, index) => item === array1[index]) -} - -export const CNavGroup = forwardRef<HTMLLIElement, CNavGroupProps>( - ({ children, className, compact, idx, toggler, visible, ...rest }, ref) => { - const [height, setHeight] = useState<number | string>() - const navItemsRef = useRef<HTMLUListElement>(null) - - const { visibleGroup, setVisibleGroup } = useContext(CNavContext) - - const [_visible, setVisible] = useState( - Boolean(visible || (idx && visibleGroup && isInVisibleGroup(visibleGroup, idx))), - ) - - useEffect(() => { - setVisible(Boolean(idx && visibleGroup && isInVisibleGroup(visibleGroup, idx))) - }, [visibleGroup]) - - const handleTogglerOnCLick = (event: React.MouseEvent<HTMLElement>) => { - event.preventDefault() - setVisibleGroup( - _visible ? (idx?.toString().includes('.') ? idx.slice(0, idx.lastIndexOf('.')) : '') : idx, - ) - setVisible(!_visible) - } - - const style: CSSProperties = { - height: 0, - } - - const onEntering = () => { - navItemsRef.current && setHeight(navItemsRef.current.scrollHeight) - } - - const onEntered = () => { - setHeight('auto') - } - - const onExit = () => { - navItemsRef.current && setHeight(navItemsRef.current.scrollHeight) - } - - const onExiting = () => { - // @ts-expect-error reflow is necessary to get correct height of the element - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const reflow = navItemsRef.current?.offsetHeight - setHeight(0) - } - - const onExited = () => { - setHeight(0) - } - - const transitionStyles = { - entering: { display: 'block', height: height }, - entered: { display: 'block', height: height }, - exiting: { display: 'block', height: height }, - exited: { height: height }, - unmounted: {} - } - - return ( - <li className={classNames('nav-group', { show: _visible }, className)} {...rest} ref={ref}> - {toggler && ( - <a className="nav-link nav-group-toggle" onClick={(event) => handleTogglerOnCLick(event)}> - {toggler} - </a> - )} - <Transition - in={_visible} - nodeRef={navItemsRef} - onEntering={onEntering} - onEntered={onEntered} - onExit={onExit} - onExiting={onExiting} - onExited={onExited} - timeout={300} - > - {(state) => ( - <ul - className={classNames('nav-group-items', { - compact: compact, - })} - style={{ - ...style, - ...transitionStyles[state as TransitionStatus], - }} - ref={navItemsRef} - > - {React.Children.map(children, (child, index) => { - if (React.isValidElement(child)) { - return React.cloneElement(child as React.ReactElement<any>, { - key: index, - idx: `${idx}.${index}`, - }) - } - return - })} - </ul> - )} - </Transition> - </li> - ) - }, -) - -CNavGroup.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - compact: PropTypes.bool, - idx: PropTypes.string, - toggler: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - visible: PropTypes.bool, -} - -CNavGroup.displayName = 'CNavGroup' diff --git a/packages/coreui-react/src/components/nav/CNavGroupItems.tsx b/packages/coreui-react/src/components/nav/CNavGroupItems.tsx deleted file mode 100644 index 6a213713..00000000 --- a/packages/coreui-react/src/components/nav/CNavGroupItems.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CNavGroupItemsProps extends HTMLAttributes<HTMLUListElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -export const CNavGroupItems = forwardRef<HTMLUListElement, CNavGroupItemsProps>( - ({ children, className, ...rest }, ref) => { - return ( - <ul className={classNames('nav-group-items', className)} {...rest} ref={ref}> - {children} - </ul> - ) - }, -) - -CNavGroupItems.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CNavGroupItems.displayName = 'CNavGroupItems' diff --git a/packages/coreui-react/src/components/nav/CNavItem.tsx b/packages/coreui-react/src/components/nav/CNavItem.tsx deleted file mode 100644 index a5f789d5..00000000 --- a/packages/coreui-react/src/components/nav/CNavItem.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React, { forwardRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CNavLink, CNavLinkProps } from './CNavLink' - -export const CNavItem = forwardRef<HTMLLIElement, CNavLinkProps>( - ({ children, className, ...rest }, ref) => { - return ( - <li className={classNames('nav-item', className)} ref={ref}> - {rest.href || rest.to ? ( - <CNavLink className={className} {...rest}> - {children} - </CNavLink> - ) : ( - children - )} - </li> - ) - }, -) - -CNavItem.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CNavItem.displayName = 'CNavItem' diff --git a/packages/coreui-react/src/components/nav/CNavLink.tsx b/packages/coreui-react/src/components/nav/CNavLink.tsx deleted file mode 100644 index 00440c36..00000000 --- a/packages/coreui-react/src/components/nav/CNavLink.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React, { ElementType, forwardRef, useContext, useEffect, useRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CLinkProps, CLink } from '../link/CLink' -import { CNavContext } from '../sidebar/CSidebarNav' - -import { useForkedRef } from '../../hooks' - -export interface CNavLinkProps extends Omit<CLinkProps, 'idx'> { - /** - * Toggle the active state for the component. - */ - active?: boolean - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Toggle the disabled state for the component. - */ - disabled?: boolean - /** - * @ignore - */ - idx?: string - /** - * @ignore - */ - to?: string -} - -export const CNavLink = forwardRef< - HTMLButtonElement | HTMLAnchorElement | HTMLLIElement, - CNavLinkProps ->(({ children, className, idx, ...rest }, ref) => { - const navLinkRef = useRef<HTMLAnchorElement>(null) - const forkedRef = useForkedRef(ref, navLinkRef) - - const { setVisibleGroup } = useContext(CNavContext) - - useEffect(() => { - rest.active = navLinkRef.current?.classList.contains('active') - idx && rest.active && setVisibleGroup(idx) - }, [rest.active, className]) - - return ( - <CLink className={classNames('nav-link', className)} {...rest} ref={forkedRef}> - {children} - </CLink> - ) -}) - -CNavLink.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - idx: PropTypes.string, -} - -CNavLink.displayName = 'CNavLink' diff --git a/packages/coreui-react/src/components/nav/CNavTitle.tsx b/packages/coreui-react/src/components/nav/CNavTitle.tsx deleted file mode 100644 index 18e87a73..00000000 --- a/packages/coreui-react/src/components/nav/CNavTitle.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CNavTitleProps extends HTMLAttributes<HTMLLIElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -export const CNavTitle = forwardRef<HTMLLIElement, CNavTitleProps>( - ({ children, className, ...rest }, ref) => { - return ( - <li className={classNames('nav-title', className)} {...rest} ref={ref}> - {children} - </li> - ) - }, -) - -CNavTitle.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CNavTitle.displayName = 'CNavTitle' diff --git a/packages/coreui-react/src/components/nav/__tests__/CNav.spec.tsx b/packages/coreui-react/src/components/nav/__tests__/CNav.spec.tsx deleted file mode 100644 index 85ecb5b8..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/CNav.spec.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { - CNav, - CNavItem, - CNavLink, - CDropdown, - CDropdownToggle, - CDropdownMenu, - CDropdownItem, -} from '../../../index' - -test('loads and displays CNav component', async () => { - const { container } = render(<CNav>Test</CNav>) - expect(container).toMatchSnapshot() -}) - -test('CNav customize', async () => { - const { container } = render( - <CNav className="bazinga" component="h3" layout="justified" variant="pills"> - Test - </CNav>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('nav') - expect(container.firstChild).toHaveClass('nav-justified') - expect(container.firstChild).toHaveClass('nav-pills') - expect(container.firstChild).toHaveClass('bazinga') -}) - -test('CNav example', async () => { - const { container } = render( - <CNav> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item"> - <CDropdownToggle>A</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">B</CDropdownItem> - <CDropdownItem href="#">C</CDropdownItem> - <CDropdownItem href="#">D</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav>, - ) - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/nav/__tests__/CNavGroup.spec.tsx b/packages/coreui-react/src/components/nav/__tests__/CNavGroup.spec.tsx deleted file mode 100644 index d3082288..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/CNavGroup.spec.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CNavGroup } from '../../../index' - -test('loads and displays CNavGroup component', async () => { - const { container } = render(<CNavGroup toggler="anchorText" />) - expect(container).toMatchSnapshot() -}) - -test('CNavGroup customize', async () => { - const { container } = render( - <CNavGroup className="bazinga" toggler="anchorText" visible={true} idx="1" />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('nav-group') - expect(container.firstChild).toHaveClass('bazinga') - const arr = container.getElementsByClassName('nav-link') - if (arr.length > 0) { - //expect(arr[0].innerText).toHaveTextContent('anchorText') - expect(arr[0].innerHTML).toBe('anchorText') - } else { - expect(true).toBe(false) - } -}) diff --git a/packages/coreui-react/src/components/nav/__tests__/CNavGroupItems.spec.tsx b/packages/coreui-react/src/components/nav/__tests__/CNavGroupItems.spec.tsx deleted file mode 100644 index 8794739a..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/CNavGroupItems.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CNavGroupItems } from '../../../index' - -test('loads and displays CNavGroupItems component', async () => { - const { container } = render(<CNavGroupItems>Test</CNavGroupItems>) - expect(container).toMatchSnapshot() -}) - -test('CNavGroupItems customize', async () => { - const { container } = render(<CNavGroupItems className="bazinga">Test</CNavGroupItems>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('nav-group-items') - expect(container.firstChild).toHaveClass('bazinga') -}) diff --git a/packages/coreui-react/src/components/nav/__tests__/CNavItem.spec.tsx b/packages/coreui-react/src/components/nav/__tests__/CNavItem.spec.tsx deleted file mode 100644 index 2fb806bb..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/CNavItem.spec.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CNavItem } from '../../../index' - -test('loads and displays CNavItem component', async () => { - const { container } = render(<CNavItem>Test</CNavItem>) - expect(container).toMatchSnapshot() -}) - -test('CNavItem customize', async () => { - const { container } = render( - <CNavItem active={true} className="bazinga" component="h3" disabled={true} href="/bazinga"> - Test - </CNavItem>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild?.firstChild).toHaveClass('nav-link') - expect(container.firstChild).toHaveClass('nav-item') - expect(container.firstChild).toHaveClass('bazinga') - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/nav/__tests__/CNavLink.spec.tsx b/packages/coreui-react/src/components/nav/__tests__/CNavLink.spec.tsx deleted file mode 100644 index 833cc443..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/CNavLink.spec.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CNavLink } from '../../../index' - -test('loads and displays CNavLink component', async () => { - const { container } = render(<CNavLink>Test</CNavLink>) - expect(container).toMatchSnapshot() -}) - -test('CNavLink customize', async () => { - const { container } = render( - <CNavLink active={true} className="bazinga" component="h3" disabled={true} href="/bazinga"> - Test - </CNavLink>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('nav-link') - expect(container.firstChild).toHaveClass('bazinga') -}) - -test('CNavLink witch "to" prop', async () => { - const { container } = render(<CNavLink to="/bazinga">Test</CNavLink>) - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/nav/__tests__/CNavTitle.spec.tsx b/packages/coreui-react/src/components/nav/__tests__/CNavTitle.spec.tsx deleted file mode 100644 index 00a11946..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/CNavTitle.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CNavTitle } from '../../../index' - -test('loads and displays CNavTitle component', async () => { - const { container } = render(<CNavTitle>Test</CNavTitle>) - expect(container).toMatchSnapshot() -}) - -test('CNavTitle customize', async () => { - const { container } = render(<CNavTitle className="bazinga">Test</CNavTitle>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('nav-title') - expect(container.firstChild).toHaveClass('bazinga') -}) diff --git a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNav.spec.tsx.snap b/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNav.spec.tsx.snap deleted file mode 100644 index 0a6129ee..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNav.spec.tsx.snap +++ /dev/null @@ -1,119 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CNav customize 1`] = ` -<div> - <h3 - class="nav nav-justified nav-pills bazinga" - role="navigation" - > - Test - </h3> -</div> -`; - -exports[`CNav example 1`] = ` -<div> - <ul - class="nav" - role="navigation" - > - <li - class="nav-item" - > - <a - aria-current="page" - class="nav-link active" - href="#" - > - Active - </a> - </li> - <li - class="nav-item" - > - <a - class="nav-link" - href="#" - > - Link - </a> - </li> - <li - class="nav-item dropdown" - > - <a - aria-expanded="false" - class="nav-link dropdown-toggle" - href="#" - role="button" - > - A - </a> - <ul - aria-hidden="true" - class="dropdown-menu" - role="menu" - > - <li> - <a - class="dropdown-item" - href="#" - > - B - </a> - </li> - <li> - <a - class="dropdown-item" - href="#" - > - C - </a> - </li> - <li> - <a - class="dropdown-item" - href="#" - > - D - </a> - </li> - </ul> - </li> - <li - class="nav-item" - > - <a - class="nav-link" - href="#" - > - Link - </a> - </li> - <li - class="nav-item" - > - <a - aria-disabled="true" - class="nav-link disabled" - disabled="" - href="#" - tabindex="-1" - > - Disabled - </a> - </li> - </ul> -</div> -`; - -exports[`loads and displays CNav component 1`] = ` -<div> - <ul - class="nav" - role="navigation" - > - Test - </ul> -</div> -`; diff --git a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.tsx.snap b/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.tsx.snap deleted file mode 100644 index 93e40a81..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.tsx.snap +++ /dev/null @@ -1,36 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CNavGroup customize 1`] = ` -<div> - <li - class="nav-group bazinga" - > - <a - class="nav-link nav-group-toggle" - > - anchorText - </a> - <ul - class="nav-group-items" - style="display: block; height: 0px;" - /> - </li> -</div> -`; - -exports[`loads and displays CNavGroup component 1`] = ` -<div> - <li - class="nav-group" - > - <a - class="nav-link nav-group-toggle" - > - anchorText - </a> - <ul - class="nav-group-items" - /> - </li> -</div> -`; diff --git a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavGroupItems.spec.tsx.snap b/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavGroupItems.spec.tsx.snap deleted file mode 100644 index 0799b190..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavGroupItems.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CNavGroupItems customize 1`] = ` -<div> - <ul - class="nav-group-items bazinga" - > - Test - </ul> -</div> -`; - -exports[`loads and displays CNavGroupItems component 1`] = ` -<div> - <ul - class="nav-group-items" - > - Test - </ul> -</div> -`; diff --git a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavItem.spec.tsx.snap b/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavItem.spec.tsx.snap deleted file mode 100644 index 4a8940f6..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavItem.spec.tsx.snap +++ /dev/null @@ -1,45 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CNavItem customize 1`] = ` -<div> - <li - class="nav-item bazinga" - > - <h3 - aria-current="page" - class="nav-link bazinga active disabled" - disabled="" - href="/bazinga" - > - Test - </h3> - </li> -</div> -`; - -exports[`CNavItem customize 2`] = ` -<div> - <li - class="nav-item bazinga" - > - <h3 - aria-current="page" - class="nav-link bazinga active disabled" - disabled="" - href="/bazinga" - > - Test - </h3> - </li> -</div> -`; - -exports[`loads and displays CNavItem component 1`] = ` -<div> - <li - class="nav-item" - > - Test - </li> -</div> -`; diff --git a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavLink.spec.tsx.snap b/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavLink.spec.tsx.snap deleted file mode 100644 index 23a2910a..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavLink.spec.tsx.snap +++ /dev/null @@ -1,35 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CNavLink customize 1`] = ` -<div> - <h3 - aria-current="page" - class="nav-link bazinga active disabled" - disabled="" - href="/bazinga" - > - Test - </h3> -</div> -`; - -exports[`CNavLink witch "to" prop 1`] = ` -<div> - <a - class="nav-link" - to="/bazinga" - > - Test - </a> -</div> -`; - -exports[`loads and displays CNavLink component 1`] = ` -<div> - <a - class="nav-link" - > - Test - </a> -</div> -`; diff --git a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavTitle.spec.tsx.snap b/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavTitle.spec.tsx.snap deleted file mode 100644 index 887159fc..00000000 --- a/packages/coreui-react/src/components/nav/__tests__/__snapshots__/CNavTitle.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CNavTitle customize 1`] = ` -<div> - <li - class="nav-title bazinga" - > - Test - </li> -</div> -`; - -exports[`loads and displays CNavTitle component 1`] = ` -<div> - <li - class="nav-title" - > - Test - </li> -</div> -`; diff --git a/packages/coreui-react/src/components/nav/index.ts b/packages/coreui-react/src/components/nav/index.ts deleted file mode 100644 index dc83561a..00000000 --- a/packages/coreui-react/src/components/nav/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { CNav } from './CNav' -import { CNavGroupItems } from './CNavGroupItems' -import { CNavGroup } from './CNavGroup' -import { CNavItem } from './CNavItem' -import { CNavLink } from './CNavLink' -import { CNavTitle } from './CNavTitle' - -export { CNav, CNavGroup, CNavGroupItems, CNavItem, CNavLink, CNavTitle } diff --git a/packages/coreui-react/src/components/navbar/CNavbar.tsx b/packages/coreui-react/src/components/navbar/CNavbar.tsx deleted file mode 100644 index b569887f..00000000 --- a/packages/coreui-react/src/components/navbar/CNavbar.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CNavbarProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Sets if the color of text should be colored for a light or dark background. - */ - colorScheme?: 'dark' | 'light' - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Defines optional container wrapping children elements. - */ - container?: boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'fluid' - /** - * Defines the responsive breakpoint to determine when content collapses. - */ - expand?: boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' - /** - * Place component in non-static positions. - */ - placement?: 'fixed-top' | 'fixed-bottom' | 'sticky-top' -} - -export const CNavbar = forwardRef<HTMLDivElement, CNavbarProps>( - ( - { - children, - className, - color, - colorScheme, - component: Component = 'nav', - container, - expand, - placement, - ...rest - }, - ref, - ) => { - return ( - <Component - className={classNames( - 'navbar', - { - [`bg-${color}`]: color, - [typeof expand === 'boolean' ? 'navbar-expand' : `navbar-expand-${expand}`]: expand, - }, - placement, - className, - )} - {...(colorScheme && { 'data-coreui-theme': colorScheme })} - {...rest} - ref={ref} - > - {container ? ( - <div className={typeof container === 'string' ? `container-${container}` : 'container'}> - {children} - </div> - ) : ( - <>{children}</> - )} - </Component> - ) - }, -) - -CNavbar.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, - colorScheme: PropTypes.oneOf(['dark', 'light']), - component: PropTypes.elementType, - container: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.oneOf<'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'fluid'>([ - 'sm', - 'md', - 'lg', - 'xl', - 'xxl', - 'fluid', - ]), - ]), - expand: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.oneOf<'sm' | 'md' | 'lg' | 'xl' | 'xxl'>(['sm', 'md', 'lg', 'xl', 'xxl']), - ]), - placement: PropTypes.oneOf(['fixed-top', 'fixed-bottom', 'sticky-top']), -} - -CNavbar.displayName = 'CNavbar' diff --git a/packages/coreui-react/src/components/navbar/CNavbarBrand.tsx b/packages/coreui-react/src/components/navbar/CNavbarBrand.tsx deleted file mode 100644 index 1d1ca739..00000000 --- a/packages/coreui-react/src/components/navbar/CNavbarBrand.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CNavbarBrandProps extends HTMLAttributes<HTMLAnchorElement | HTMLSpanElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - * - */ - component?: string | ElementType - /** - * The href attribute specifies the URL of the page the link goes to. - */ - href?: string -} - -export const CNavbarBrand = forwardRef<HTMLAnchorElement | HTMLSpanElement, CNavbarBrandProps>( - ({ children, component, className, ...rest }, ref) => { - const Component = component ?? (rest.href ? 'a' : 'span') - - return ( - <Component className={classNames('navbar-brand', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -CNavbarBrand.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CNavbarBrand.displayName = 'CNavbarBrand' diff --git a/packages/coreui-react/src/components/navbar/CNavbarNav.tsx b/packages/coreui-react/src/components/navbar/CNavbarNav.tsx deleted file mode 100644 index babbe5e5..00000000 --- a/packages/coreui-react/src/components/navbar/CNavbarNav.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CNavbarNavProps extends HTMLAttributes<HTMLDivElement | HTMLUListElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CNavbarNav = forwardRef<HTMLDivElement | HTMLUListElement, CNavbarNavProps>( - ({ children, component: Component = 'ul', className, ...rest }, ref) => { - return ( - <Component - className={classNames('navbar-nav', className)} - role="navigation" - {...rest} - ref={ref} - > - {children} - </Component> - ) - }, -) - -CNavbarNav.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CNavbarNav.displayName = 'CNavbarNav' diff --git a/packages/coreui-react/src/components/navbar/CNavbarText.tsx b/packages/coreui-react/src/components/navbar/CNavbarText.tsx deleted file mode 100644 index 45752738..00000000 --- a/packages/coreui-react/src/components/navbar/CNavbarText.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CNavbarTextProps extends HTMLAttributes<HTMLSpanElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CNavbarText = forwardRef<HTMLSpanElement, CNavbarTextProps>( - ({ children, className, ...rest }, ref) => { - return ( - <span className={classNames('navbar-text', className)} {...rest} ref={ref}> - {children} - </span> - ) - }, -) - -CNavbarText.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CNavbarText.displayName = 'CNavbarText' diff --git a/packages/coreui-react/src/components/navbar/CNavbarToggler.tsx b/packages/coreui-react/src/components/navbar/CNavbarToggler.tsx deleted file mode 100644 index 296740a3..00000000 --- a/packages/coreui-react/src/components/navbar/CNavbarToggler.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CNavbarTogglerProps extends HTMLAttributes<HTMLButtonElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CNavbarToggler = forwardRef<HTMLButtonElement, CNavbarTogglerProps>( - ({ children, className, ...rest }, ref) => { - return ( - <button type="button" className={classNames('navbar-toggler', className)} {...rest} ref={ref}> - {children ?? <span className="navbar-toggler-icon"></span>} - </button> - ) - }, -) - -CNavbarToggler.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CNavbarToggler.displayName = 'CNavbarToggler' diff --git a/packages/coreui-react/src/components/navbar/__tests__/CNavbar.spec.tsx b/packages/coreui-react/src/components/navbar/__tests__/CNavbar.spec.tsx deleted file mode 100644 index 1b248452..00000000 --- a/packages/coreui-react/src/components/navbar/__tests__/CNavbar.spec.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CNavbar } from '../../../index' - -test('loads and displays CNavbar component', async () => { - const { container } = render(<CNavbar>Test</CNavbar>) - expect(container).toMatchSnapshot() -}) - -test('CNavbar customize', async () => { - const { container } = render( - <CNavbar - className="bazinga" - color="warning" - colorScheme="dark" - component="h3" - container="xl" - expand="lg" - placement="fixed-bottom" - > - Test - </CNavbar>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('navbar') - expect(container.firstChild).toHaveClass('bg-warning') - expect(container.firstChild).toHaveClass('navbar-expand-lg') - expect(container.firstChild).toHaveClass('fixed-bottom') - expect(container.firstChild).toHaveAttribute('data-coreui-theme', 'dark') - const arrLength = container.getElementsByClassName('container-xl').length - expect(arrLength).toBe(1) -}) - -test('CNavbar customize - container and expand are boolean', async () => { - const { container } = render( - <CNavbar container={true} expand={true}> - Test - </CNavbar>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('navbar-expand') - const arrLength = container.getElementsByClassName('container').length - expect(arrLength).toBe(1) -}) diff --git a/packages/coreui-react/src/components/navbar/__tests__/CNavbarBrand.spec.tsx b/packages/coreui-react/src/components/navbar/__tests__/CNavbarBrand.spec.tsx deleted file mode 100644 index 87624016..00000000 --- a/packages/coreui-react/src/components/navbar/__tests__/CNavbarBrand.spec.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CNavbarBrand } from '../../../index' - -test('loads and displays CNavbarBrand component', async () => { - const { container } = render(<CNavbarBrand>Test</CNavbarBrand>) - expect(container).toMatchSnapshot() -}) - -test('CNavbarBrand witch href', async () => { - const { container } = render(<CNavbarBrand href="/bazinga">Test</CNavbarBrand>) - expect(container).toMatchSnapshot() -}) - -test('CNavbarBrand customize', async () => { - const { container } = render( - <CNavbarBrand className="bazinga" component="h3" href="/bazinga"> - Test - </CNavbarBrand>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('navbar-brand') - expect(container.firstChild).toHaveClass('bazinga') -}) diff --git a/packages/coreui-react/src/components/navbar/__tests__/CNavbarNav.spec.tsx b/packages/coreui-react/src/components/navbar/__tests__/CNavbarNav.spec.tsx deleted file mode 100644 index 644198ee..00000000 --- a/packages/coreui-react/src/components/navbar/__tests__/CNavbarNav.spec.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CNavbarNav } from '../../../index' - -test('loads and displays CNavbarNav component', async () => { - const { container } = render(<CNavbarNav>Test</CNavbarNav>) - expect(container).toMatchSnapshot() -}) - -test('CNavbarNav customize', async () => { - const { container } = render( - <CNavbarNav className="bazinga" component="h3"> - Test - </CNavbarNav>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('navbar-nav') - expect(container.firstChild).toHaveAttribute('role', 'navigation') -}) diff --git a/packages/coreui-react/src/components/navbar/__tests__/CNavbarText.spec.tsx b/packages/coreui-react/src/components/navbar/__tests__/CNavbarText.spec.tsx deleted file mode 100644 index 39fe2640..00000000 --- a/packages/coreui-react/src/components/navbar/__tests__/CNavbarText.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CNavbarText } from '../../../index' - -test('loads and displays CNavbarText component', async () => { - const { container } = render(<CNavbarText>Test</CNavbarText>) - expect(container).toMatchSnapshot() -}) - -test('CNavbarText customize', async () => { - const { container } = render(<CNavbarText className="bazinga">Test</CNavbarText>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('navbar-text') - expect(container.firstChild).toHaveClass('bazinga') -}) diff --git a/packages/coreui-react/src/components/navbar/__tests__/CNavbarToggler.spec.tsx b/packages/coreui-react/src/components/navbar/__tests__/CNavbarToggler.spec.tsx deleted file mode 100644 index 7964c4ac..00000000 --- a/packages/coreui-react/src/components/navbar/__tests__/CNavbarToggler.spec.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CNavbarToggler } from '../../../index' - -test('CNavbarToggler witch children', async () => { - const { container } = render(<CNavbarToggler>Test</CNavbarToggler>) - expect(container).toMatchSnapshot() -}) - -test('CNavbarToggler witch no children', async () => { - const { container } = render(<CNavbarToggler />) - expect(container).toMatchSnapshot() - const arrLength = container.getElementsByClassName('navbar-toggler-icon').length - expect(arrLength).toBe(1) -}) - -test('CNavbarToggler customize', async () => { - const { container } = render(<CNavbarToggler className="bazinga" />) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('navbar-toggler') -}) diff --git a/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbar.spec.tsx.snap b/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbar.spec.tsx.snap deleted file mode 100644 index 8540d749..00000000 --- a/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbar.spec.tsx.snap +++ /dev/null @@ -1,40 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CNavbar customize - container and expand are boolean 1`] = ` -<div> - <nav - class="navbar navbar-expand" - > - <div - class="container" - > - Test - </div> - </nav> -</div> -`; - -exports[`CNavbar customize 1`] = ` -<div> - <h3 - class="navbar bg-warning navbar-expand-lg fixed-bottom bazinga" - data-coreui-theme="dark" - > - <div - class="container-xl" - > - Test - </div> - </h3> -</div> -`; - -exports[`loads and displays CNavbar component 1`] = ` -<div> - <nav - class="navbar" - > - Test - </nav> -</div> -`; diff --git a/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarBrand.spec.tsx.snap b/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarBrand.spec.tsx.snap deleted file mode 100644 index 7dc5581f..00000000 --- a/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarBrand.spec.tsx.snap +++ /dev/null @@ -1,33 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CNavbarBrand customize 1`] = ` -<div> - <h3 - class="navbar-brand bazinga" - href="/bazinga" - > - Test - </h3> -</div> -`; - -exports[`CNavbarBrand witch href 1`] = ` -<div> - <a - class="navbar-brand" - href="/bazinga" - > - Test - </a> -</div> -`; - -exports[`loads and displays CNavbarBrand component 1`] = ` -<div> - <span - class="navbar-brand" - > - Test - </span> -</div> -`; diff --git a/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarNav.spec.tsx.snap b/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarNav.spec.tsx.snap deleted file mode 100644 index a2c087da..00000000 --- a/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarNav.spec.tsx.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CNavbarNav customize 1`] = ` -<div> - <h3 - class="navbar-nav bazinga" - role="navigation" - > - Test - </h3> -</div> -`; - -exports[`loads and displays CNavbarNav component 1`] = ` -<div> - <ul - class="navbar-nav" - role="navigation" - > - Test - </ul> -</div> -`; diff --git a/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarText.spec.tsx.snap b/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarText.spec.tsx.snap deleted file mode 100644 index d30324c0..00000000 --- a/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarText.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CNavbarText customize 1`] = ` -<div> - <span - class="navbar-text bazinga" - > - Test - </span> -</div> -`; - -exports[`loads and displays CNavbarText component 1`] = ` -<div> - <span - class="navbar-text" - > - Test - </span> -</div> -`; diff --git a/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarToggler.spec.tsx.snap b/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarToggler.spec.tsx.snap deleted file mode 100644 index 145f8d7f..00000000 --- a/packages/coreui-react/src/components/navbar/__tests__/__snapshots__/CNavbarToggler.spec.tsx.snap +++ /dev/null @@ -1,38 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CNavbarToggler customize 1`] = ` -<div> - <button - class="navbar-toggler bazinga" - type="button" - > - <span - class="navbar-toggler-icon" - /> - </button> -</div> -`; - -exports[`CNavbarToggler witch children 1`] = ` -<div> - <button - class="navbar-toggler" - type="button" - > - Test - </button> -</div> -`; - -exports[`CNavbarToggler witch no children 1`] = ` -<div> - <button - class="navbar-toggler" - type="button" - > - <span - class="navbar-toggler-icon" - /> - </button> -</div> -`; diff --git a/packages/coreui-react/src/components/navbar/index.ts b/packages/coreui-react/src/components/navbar/index.ts deleted file mode 100644 index 690bc9cc..00000000 --- a/packages/coreui-react/src/components/navbar/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { CNavbar } from './CNavbar' -import { CNavbarBrand } from './CNavbarBrand' -import { CNavbarNav } from './CNavbarNav' -import { CNavbarText } from './CNavbarText' -import { CNavbarToggler } from './CNavbarToggler' - -export { CNavbar, CNavbarBrand, CNavbarNav, CNavbarText, CNavbarToggler } diff --git a/packages/coreui-react/src/components/offcanvas/COffcanvas.tsx b/packages/coreui-react/src/components/offcanvas/COffcanvas.tsx deleted file mode 100644 index 702b27c6..00000000 --- a/packages/coreui-react/src/components/offcanvas/COffcanvas.tsx +++ /dev/null @@ -1,185 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useEffect, useRef, useState } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' -import { Transition } from 'react-transition-group' - -import { CBackdrop } from '../backdrop' -import { CConditionalPortal } from '../conditional-portal' - -import { useForkedRef } from '../../hooks' - -export interface COffcanvasProps extends HTMLAttributes<HTMLDivElement> { - /** - * Apply a backdrop on body while offcanvas is open. - */ - backdrop?: boolean | 'static' - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Sets a darker color scheme. - */ - dark?: boolean - /** - * Closes the offcanvas when escape key is pressed. - */ - keyboard?: boolean - /** - * Callback fired when the component requests to be hidden. - */ - onHide?: () => void - /** - * Callback fired when the component requests to be shown. - */ - onShow?: () => void - /** - * Components placement, there’s no default placement. - */ - placement: 'start' | 'end' | 'top' | 'bottom' - /** - * Generates modal using createPortal. - */ - portal?: boolean - /** - * Responsive offcanvas property hide content outside the viewport from a specified breakpoint and down. - * - * @since 4.6.0 - */ - responsive?: boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' - /** - * Allow body scrolling while offcanvas is open - */ - scroll?: boolean - /** - * Toggle the visibility of offcanvas component. - */ - visible?: boolean -} - -export const COffcanvas = forwardRef<HTMLDivElement, COffcanvasProps>( - ( - { - children, - backdrop = true, - className, - dark, - keyboard = true, - onHide, - onShow, - placement, - portal = false, - responsive = true, - scroll = false, - visible = false, - ...rest - }, - ref, - ) => { - const [_visible, setVisible] = useState<boolean>(visible) - const offcanvasRef = useRef<HTMLDivElement>(null) - const forkedRef = useForkedRef(ref, offcanvasRef) - - useEffect(() => { - setVisible(visible) - }, [visible]) - - useEffect(() => { - if (_visible && !scroll) { - document.body.style.overflow = 'hidden' - document.body.style.paddingRight = '0px' - return - } - - if (!scroll) { - document.body.style.removeProperty('overflow') - document.body.style.removeProperty('padding-right') - } - }, [_visible]) - - const handleDismiss = () => { - setVisible(false) - } - - const handleBackdropDismiss = () => { - if (backdrop !== 'static') { - setVisible(false) - } - } - - const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => { - if (event.key === 'Escape' && keyboard) { - return handleDismiss() - } - } - - return ( - <> - <Transition - in={_visible} - nodeRef={offcanvasRef} - onEnter={onShow} - onEntered={() => offcanvasRef.current?.focus()} - onExit={onHide} - timeout={300} - > - {(state) => ( - <CConditionalPortal portal={portal}> - <div - className={classNames( - { - [`offcanvas${typeof responsive === 'string' ? '-' + responsive : ''}`]: - responsive, - [`offcanvas-${placement}`]: placement, - showing: state === 'entering', - show: state === 'entered', - 'show hiding': state === 'exiting', - }, - className, - )} - role="dialog" - tabIndex={-1} - onKeyDown={handleKeyDown} - {...(dark && { 'data-coreui-theme': 'dark' })} - {...rest} - ref={forkedRef} - > - {children} - </div> - </CConditionalPortal> - )} - </Transition> - {backdrop && ( - <CConditionalPortal portal={portal}> - <CBackdrop - className="offcanvas-backdrop" - onClick={handleBackdropDismiss} - visible={_visible} - /> - </CConditionalPortal> - )} - </> - ) - }, -) - -COffcanvas.propTypes = { - backdrop: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf<'static'>(['static'])]), - children: PropTypes.node, - className: PropTypes.string, - dark: PropTypes.bool, - keyboard: PropTypes.bool, - onHide: PropTypes.func, - onShow: PropTypes.func, - placement: PropTypes.oneOf<'start' | 'end' | 'top' | 'bottom'>(['start', 'end', 'top', 'bottom']) - .isRequired, - portal: PropTypes.bool, - responsive: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.oneOf<'sm' | 'md' | 'lg' | 'xl' | 'xxl'>(['sm', 'md', 'lg', 'xl', 'xxl']), - ]), - scroll: PropTypes.bool, - visible: PropTypes.bool, -} - -COffcanvas.displayName = 'COffcanvas' diff --git a/packages/coreui-react/src/components/offcanvas/COffcanvasBody.tsx b/packages/coreui-react/src/components/offcanvas/COffcanvasBody.tsx deleted file mode 100644 index 0b74fd99..00000000 --- a/packages/coreui-react/src/components/offcanvas/COffcanvasBody.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface COffcanvasBodyProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const COffcanvasBody = forwardRef<HTMLDivElement, COffcanvasBodyProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('offcanvas-body', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -COffcanvasBody.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -COffcanvasBody.displayName = 'COffcanvasBody' diff --git a/packages/coreui-react/src/components/offcanvas/COffcanvasHeader.tsx b/packages/coreui-react/src/components/offcanvas/COffcanvasHeader.tsx deleted file mode 100644 index 6b9a649c..00000000 --- a/packages/coreui-react/src/components/offcanvas/COffcanvasHeader.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface COffcanvasHeaderProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const COffcanvasHeader = forwardRef<HTMLDivElement, COffcanvasHeaderProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('offcanvas-header', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -COffcanvasHeader.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -COffcanvasHeader.displayName = 'COffcanvasHeader' diff --git a/packages/coreui-react/src/components/offcanvas/COffcanvasTitle.tsx b/packages/coreui-react/src/components/offcanvas/COffcanvasTitle.tsx deleted file mode 100644 index 81859afa..00000000 --- a/packages/coreui-react/src/components/offcanvas/COffcanvasTitle.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface COffcanvasTitleProps extends HTMLAttributes<HTMLHeadingElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const COffcanvasTitle = forwardRef<HTMLHeadingElement, COffcanvasTitleProps>( - ({ children, component: Component = 'h5', className, ...rest }, ref) => { - return ( - <Component className={classNames('offcanvas-title', className)} {...rest} ref={ref}> - {children} - </Component> - ) - }, -) - -COffcanvasTitle.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -COffcanvasTitle.displayName = 'COffcanvasTitle' diff --git a/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvas.spec.tsx b/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvas.spec.tsx deleted file mode 100644 index d6b6b865..00000000 --- a/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvas.spec.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import * as React from 'react' -import { render, fireEvent } from '@testing-library/react' -import '@testing-library/jest-dom' -import { COffcanvas } from '../../../index' - -test('loads and displays COffcanvas component', async () => { - const { container } = render(<COffcanvas placement="top" />) - expect(container).toMatchSnapshot() -}) - -test('COffcanvas customize one', async () => { - const { container } = render( - <COffcanvas - className="bazinga" - backdrop={false} - keyboard={false} - placement="start" - portal={false} - visible={false} - > - Test - </COffcanvas>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('offcanvas') - expect(container.firstChild).toHaveClass('offcanvas-start') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveTextContent('Test') -}) - -test('COffcanvas customize and event on click backdrop', async () => { - // jest.useFakeTimers() - const onHide = jest.fn() - const { container } = render( - <COffcanvas - className="bazinga" - backdrop={true} - keyboard={true} - placement="end" - portal={false} - visible={true} - onHide={onHide} - > - Test - </COffcanvas>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('offcanvas') - expect(container.firstChild).toHaveClass('offcanvas-end') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('show') - expect(container.firstChild).toHaveTextContent('Test') - expect(onHide).toHaveBeenCalledTimes(0) - const backdrop = document.querySelector('.offcanvas-backdrop') - if (backdrop !== null) { - fireEvent.click(backdrop) - } - expect(onHide).toHaveBeenCalledTimes(1) - expect(container.firstChild).toHaveClass('show') - expect(container.firstChild).toHaveClass('hiding') - await new Promise((r) => setTimeout(r, 1000)) - expect(container.firstChild).not.toHaveClass('show') -}) - -test('COffcanvas customize and event on keypress', async () => { - const onHide = jest.fn() - const { container } = render( - <COffcanvas - className="bazinga" - backdrop={true} - keyboard={true} - placement="end" - portal={false} - visible={true} - onHide={onHide} - > - Test - </COffcanvas>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('offcanvas') - expect(container.firstChild).toHaveClass('offcanvas-end') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('show') - expect(onHide).toHaveBeenCalledTimes(0) - const canvas = document.querySelector('.offcanvas') - if (canvas === null) { - expect(true).toBe(false) - } else { - fireEvent.keyDown(canvas, { - key: 'Escape', - code: 'Escape', - keyCode: 27, - charCode: 27, - }) - } - expect(onHide).toHaveBeenCalledTimes(1) - expect(container.firstChild).toHaveClass('show') - expect(container.firstChild).toHaveClass('hiding') - await new Promise((r) => setTimeout(r, 1000)) - expect(container.firstChild).not.toHaveClass('show') -}) diff --git a/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasBody.spec.tsx b/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasBody.spec.tsx deleted file mode 100644 index f4db901c..00000000 --- a/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasBody.spec.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { COffcanvasBody } from '../../../index' - -test('loads and displays COffcanvasBody component', async () => { - const { container } = render(<COffcanvasBody />) - expect(container).toMatchSnapshot() -}) - -test('COffcanvasBody customize', async () => { - const { container } = render(<COffcanvasBody className="bazinga">Test</COffcanvasBody>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('offcanvas-body') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasHeader.spec.tsx b/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasHeader.spec.tsx deleted file mode 100644 index 44a66f04..00000000 --- a/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasHeader.spec.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { COffcanvasHeader } from '../../../index' - -test('loads and displays COffcanvasHeader component', async () => { - const { container } = render(<COffcanvasHeader />) - expect(container).toMatchSnapshot() -}) - -test('COffcanvasHeader customize', async () => { - const { container } = render(<COffcanvasHeader className="bazinga">Test</COffcanvasHeader>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('offcanvas-header') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasTitle.spec.tsx b/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasTitle.spec.tsx deleted file mode 100644 index f37bf5df..00000000 --- a/packages/coreui-react/src/components/offcanvas/__tests__/COffcanvasTitle.spec.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { COffcanvasTitle } from '../../../index' - -test('loads and displays COffcanvasTitle component', async () => { - const { container } = render(<COffcanvasTitle />) - expect(container).toMatchSnapshot() -}) - -test('COffcanvasTitle customize', async () => { - const { container } = render( - <COffcanvasTitle className="bazinga" component="div"> - Test - </COffcanvasTitle>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('offcanvas-title') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvas.spec.tsx.snap b/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvas.spec.tsx.snap deleted file mode 100644 index 796fb15f..00000000 --- a/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvas.spec.tsx.snap +++ /dev/null @@ -1,53 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`COffcanvas customize and event on click backdrop 1`] = ` -<div> - <div - class="offcanvas offcanvas-end show bazinga" - role="dialog" - tabindex="-1" - > - Test - </div> - <div - class="offcanvas-backdrop fade show" - /> -</div> -`; - -exports[`COffcanvas customize and event on keypress 1`] = ` -<div> - <div - class="offcanvas offcanvas-end show bazinga" - role="dialog" - tabindex="-1" - > - Test - </div> - <div - class="offcanvas-backdrop fade show" - /> -</div> -`; - -exports[`COffcanvas customize one 1`] = ` -<div> - <div - class="offcanvas offcanvas-start bazinga" - role="dialog" - tabindex="-1" - > - Test - </div> -</div> -`; - -exports[`loads and displays COffcanvas component 1`] = ` -<div> - <div - class="offcanvas offcanvas-top" - role="dialog" - tabindex="-1" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasBody.spec.tsx.snap b/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasBody.spec.tsx.snap deleted file mode 100644 index 4aab05e6..00000000 --- a/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasBody.spec.tsx.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`COffcanvasBody customize 1`] = ` -<div> - <div - class="offcanvas-body bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays COffcanvasBody component 1`] = ` -<div> - <div - class="offcanvas-body" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasHeader.spec.tsx.snap b/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasHeader.spec.tsx.snap deleted file mode 100644 index cced2188..00000000 --- a/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasHeader.spec.tsx.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`COffcanvasHeader customize 1`] = ` -<div> - <div - class="offcanvas-header bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays COffcanvasHeader component 1`] = ` -<div> - <div - class="offcanvas-header" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasTitle.spec.tsx.snap b/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasTitle.spec.tsx.snap deleted file mode 100644 index a38e77a1..00000000 --- a/packages/coreui-react/src/components/offcanvas/__tests__/__snapshots__/COffcanvasTitle.spec.tsx.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`COffcanvasTitle customize 1`] = ` -<div> - <div - class="offcanvas-title bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays COffcanvasTitle component 1`] = ` -<div> - <h5 - class="offcanvas-title" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/offcanvas/index.ts b/packages/coreui-react/src/components/offcanvas/index.ts deleted file mode 100644 index c3084cf9..00000000 --- a/packages/coreui-react/src/components/offcanvas/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { COffcanvas } from './COffcanvas' -import { COffcanvasBody } from './COffcanvasBody' -import { COffcanvasHeader } from './COffcanvasHeader' -import { COffcanvasTitle } from './COffcanvasTitle' - -export { COffcanvas, COffcanvasBody, COffcanvasHeader, COffcanvasTitle } diff --git a/packages/coreui-react/src/components/pagination/CPagination.tsx b/packages/coreui-react/src/components/pagination/CPagination.tsx deleted file mode 100644 index 05e797b5..00000000 --- a/packages/coreui-react/src/components/pagination/CPagination.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CPaginationProps extends HTMLAttributes<HTMLUListElement> { - /** - * Set the alignment of pagination components. - */ - align?: 'start' | 'center' | 'end' - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Size the component small or large. - */ - size?: 'sm' | 'lg' -} - -export const CPagination = forwardRef<HTMLUListElement, CPaginationProps>( - ({ children, align, className, size, ...rest }, ref) => { - return ( - <nav ref={ref} {...rest}> - <ul - className={classNames( - 'pagination', - { - [`justify-content-${align}`]: align, - [`pagination-${size}`]: size, - }, - className, - )} - > - {children} - </ul> - </nav> - ) - }, -) - -CPagination.propTypes = { - align: PropTypes.oneOf(['start', 'center', 'end']), - children: PropTypes.node, - className: PropTypes.string, - size: PropTypes.oneOf(['sm', 'lg']), -} - -CPagination.displayName = 'CPagination' diff --git a/packages/coreui-react/src/components/pagination/CPaginationItem.tsx b/packages/coreui-react/src/components/pagination/CPaginationItem.tsx deleted file mode 100644 index 0dc35888..00000000 --- a/packages/coreui-react/src/components/pagination/CPaginationItem.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CLink } from '../link/CLink' - -export interface CPaginationItemProps extends HTMLAttributes<HTMLAnchorElement> { - /** - * Toggle the active state for the component. - */ - active?: boolean - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Toggle the disabled state for the component. - */ - disabled?: boolean -} - -export const CPaginationItem = forwardRef<HTMLAnchorElement, CPaginationItemProps>( - ({ children, className, component, ...rest }, ref) => { - const Component = component ?? (rest.active ? 'span' : 'a') - - return ( - <li - className={classNames( - 'page-item', - { - active: rest.active, - disabled: rest.disabled, - }, - className, - )} - {...(rest.active && { 'aria-current': 'page' })} - > - {Component === 'a' ? ( - <CLink className="page-link" component={Component} {...rest} ref={ref}> - {children} - </CLink> - ) : ( - <Component className="page-link" ref={ref}> - {children} - </Component> - )} - </li> - ) - }, -) - -CPaginationItem.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - component: PropTypes.elementType, -} - -CPaginationItem.displayName = 'CPaginationItem' diff --git a/packages/coreui-react/src/components/pagination/__tests__/CPagination.spec.tsx b/packages/coreui-react/src/components/pagination/__tests__/CPagination.spec.tsx deleted file mode 100644 index 78a484d9..00000000 --- a/packages/coreui-react/src/components/pagination/__tests__/CPagination.spec.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CPagination, CPaginationItem } from '../../../index' - -test('loads and displays CPagination component', async () => { - const { container } = render(<CPagination>Test</CPagination>) - expect(container).toMatchSnapshot() -}) - -test('CPagination customize', async () => { - const { container } = render( - <CPagination className="bazinga" aria-label="ariaLabel" size="lg"> - Test - </CPagination>, - ) - expect(container).toMatchSnapshot() - let element = container.firstChild - if (element === null) { - expect(true).toBe(false) - } else { - element = element.firstChild - expect(element).toHaveClass('bazinga') - expect(element).toHaveClass('pagination') - expect(element).toHaveClass('pagination-lg') - } -}) - -test('CPagination example', async () => { - const { container } = render( - <CPagination> - <CPaginationItem>A</CPaginationItem> - <CPaginationItem>B</CPaginationItem> - <CPaginationItem>C</CPaginationItem> - </CPagination>, - ) - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/pagination/__tests__/CPaginationItem.spec.tsx b/packages/coreui-react/src/components/pagination/__tests__/CPaginationItem.spec.tsx deleted file mode 100644 index 0ae5dc3e..00000000 --- a/packages/coreui-react/src/components/pagination/__tests__/CPaginationItem.spec.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CPaginationItem } from '../../../index' - -test('loads and displays CPaginationItem component', async () => { - const { container } = render(<CPaginationItem>Test</CPaginationItem>) - expect(container).toMatchSnapshot() -}) - -test('CPaginationItem customize', async () => { - const { container } = render( - <CPaginationItem className="bazinga" active={true} component="h3" disabled={true}> - Test - </CPaginationItem>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('page-item') - expect(container.firstChild).toHaveClass('active') - expect(container.firstChild).toHaveClass('disabled') - let element = container.firstChild - if (element === null) { - expect(true).toBe(false) - } else { - element = element.firstChild - expect(element).toHaveClass('page-link') - } -}) diff --git a/packages/coreui-react/src/components/pagination/__tests__/__snapshots__/CPagination.spec.tsx.snap b/packages/coreui-react/src/components/pagination/__tests__/__snapshots__/CPagination.spec.tsx.snap deleted file mode 100644 index 00d53c98..00000000 --- a/packages/coreui-react/src/components/pagination/__tests__/__snapshots__/CPagination.spec.tsx.snap +++ /dev/null @@ -1,65 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CPagination customize 1`] = ` -<div> - <nav - aria-label="ariaLabel" - > - <ul - class="pagination pagination-lg bazinga" - > - Test - </ul> - </nav> -</div> -`; - -exports[`CPagination example 1`] = ` -<div> - <nav> - <ul - class="pagination" - > - <li - class="page-item" - > - <a - class="page-link" - > - A - </a> - </li> - <li - class="page-item" - > - <a - class="page-link" - > - B - </a> - </li> - <li - class="page-item" - > - <a - class="page-link" - > - C - </a> - </li> - </ul> - </nav> -</div> -`; - -exports[`loads and displays CPagination component 1`] = ` -<div> - <nav> - <ul - class="pagination" - > - Test - </ul> - </nav> -</div> -`; diff --git a/packages/coreui-react/src/components/pagination/__tests__/__snapshots__/CPaginationItem.spec.tsx.snap b/packages/coreui-react/src/components/pagination/__tests__/__snapshots__/CPaginationItem.spec.tsx.snap deleted file mode 100644 index a3ba0f37..00000000 --- a/packages/coreui-react/src/components/pagination/__tests__/__snapshots__/CPaginationItem.spec.tsx.snap +++ /dev/null @@ -1,30 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CPaginationItem customize 1`] = ` -<div> - <li - aria-current="page" - class="page-item active disabled bazinga" - > - <h3 - class="page-link" - > - Test - </h3> - </li> -</div> -`; - -exports[`loads and displays CPaginationItem component 1`] = ` -<div> - <li - class="page-item" - > - <a - class="page-link" - > - Test - </a> - </li> -</div> -`; diff --git a/packages/coreui-react/src/components/pagination/index.ts b/packages/coreui-react/src/components/pagination/index.ts deleted file mode 100644 index 5c09daf0..00000000 --- a/packages/coreui-react/src/components/pagination/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { CPagination } from './CPagination' -import { CPaginationItem } from './CPaginationItem' - -export { CPagination, CPaginationItem } diff --git a/packages/coreui-react/src/components/placeholder/CPlaceholder.tsx b/packages/coreui-react/src/components/placeholder/CPlaceholder.tsx deleted file mode 100644 index 0016c506..00000000 --- a/packages/coreui-react/src/components/placeholder/CPlaceholder.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CPlaceholderProps extends HTMLAttributes<HTMLSpanElement> { - /** - * Set animation type to better convey the perception of something being actively loaded. - */ - animation?: 'glow' | 'wave' - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Size the component extra small, small, or large. - */ - size?: 'xs' | 'sm' | 'lg' - /** - * The number of columns on extra small devices (<576px). - */ - xs?: number - /** - * The number of columns on small devices (<768px). - */ - sm?: number - /** - * The number of columns on medium devices (<992px). - */ - md?: number - /** - * The number of columns on large devices (<1200px). - */ - lg?: number - /** - * The number of columns on X-Large devices (<1400px). - */ - xl?: number - /** - * The number of columns on XX-Large devices (≥1400px). - */ - xxl?: number -} - -const BREAKPOINTS = [ - 'xxl' as const, - 'xl' as const, - 'lg' as const, - 'md' as const, - 'sm' as const, - 'xs' as const, -] - -export const CPlaceholder = forwardRef<HTMLSpanElement, CPlaceholderProps>( - ( - { children, animation, className, color, component: Component = 'span', size, ...rest }, - ref, - ) => { - const repsonsiveClassNames: string[] = [] - - BREAKPOINTS.forEach((bp) => { - const breakpoint = rest[bp] - delete rest[bp] - - const infix = bp === 'xs' ? '' : `-${bp}` - - if (typeof breakpoint === 'number') { - repsonsiveClassNames.push(`col${infix}-${breakpoint}`) - } - - if (typeof breakpoint === 'boolean') { - repsonsiveClassNames.push(`col${infix}`) - } - }) - - return ( - <Component - className={classNames( - animation ? `placeholder-${animation}` : 'placeholder', - { - [`bg-${color}`]: color, - [`placeholder-${size}`]: size, - }, - repsonsiveClassNames, - className, - )} - {...rest} - ref={ref} - > - {children} - </Component> - ) - }, -) - -CPlaceholder.propTypes = { - animation: PropTypes.oneOf(['glow', 'wave']), - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, - component: PropTypes.elementType, - size: PropTypes.oneOf(['xs', 'sm', 'lg']), -} - -CPlaceholder.displayName = 'CPlaceholder' diff --git a/packages/coreui-react/src/components/placeholder/__tests__/CPlaceholder.spec.tsx b/packages/coreui-react/src/components/placeholder/__tests__/CPlaceholder.spec.tsx deleted file mode 100644 index 1e4466d7..00000000 --- a/packages/coreui-react/src/components/placeholder/__tests__/CPlaceholder.spec.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CPlaceholder } from '../../../index' - -test('loads and displays CPlaceholder component', async () => { - const { container } = render(<CPlaceholder color="primary" />) - expect(container).toMatchSnapshot() -}) - -test('CPlaceholder customize', async () => { - const { container } = render( - <CPlaceholder animation="glow" className="bazinga" color="secondary" size="lg" sm={7} />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('bg-secondary') - expect(container.firstChild).toHaveClass('col-sm-7') - expect(container.firstChild).toHaveClass('placeholder-lg') - expect(container.firstChild).toHaveClass('placeholder-glow') -}) diff --git a/packages/coreui-react/src/components/placeholder/__tests__/__snapshots__/CPlaceholder.spec.tsx.snap b/packages/coreui-react/src/components/placeholder/__tests__/__snapshots__/CPlaceholder.spec.tsx.snap deleted file mode 100644 index 53def94c..00000000 --- a/packages/coreui-react/src/components/placeholder/__tests__/__snapshots__/CPlaceholder.spec.tsx.snap +++ /dev/null @@ -1,17 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CPlaceholder customize 1`] = ` -<div> - <span - class="placeholder-glow bg-secondary placeholder-lg col-sm-7 bazinga" - /> -</div> -`; - -exports[`loads and displays CPlaceholder component 1`] = ` -<div> - <span - class="placeholder bg-primary" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/placeholder/index.ts b/packages/coreui-react/src/components/placeholder/index.ts deleted file mode 100644 index 2d8d709f..00000000 --- a/packages/coreui-react/src/components/placeholder/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CPlaceholder } from './CPlaceholder' - -export { CPlaceholder } diff --git a/packages/coreui-react/src/components/popover/CPopover.tsx b/packages/coreui-react/src/components/popover/CPopover.tsx deleted file mode 100644 index 0c620304..00000000 --- a/packages/coreui-react/src/components/popover/CPopover.tsx +++ /dev/null @@ -1,236 +0,0 @@ -import React, { forwardRef, HTMLAttributes, ReactNode, useRef, useEffect, useState } from 'react' -// import { createPortal } from 'react-dom' -import classNames from 'classnames' -import PropTypes from 'prop-types' -import { Transition } from 'react-transition-group' - -import { CConditionalPortal } from '../conditional-portal' -import { useForkedRef, usePopper } from '../../hooks' -import { fallbackPlacementsPropType, triggerPropType } from '../../props' -import type { Placements, Triggers } from '../../types' -import { getRTLPlacement, getTransitionDurationFromElement } from '../../utils' - -export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title' | 'content'> { - /** - * Apply a CSS fade transition to the popover. - * - * @since 4.9.0 - */ - animation?: boolean - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Appends the react popover to a specific element. You can pass an HTML element or function that returns a single element. By default `document.body`. - * - * @since v4.11.0 - */ - container?: Element | (() => Element | null) | null - /** - * Content node for your component. - */ - content: ReactNode | string - /** - * Offset of the popover relative to its target. - */ - offset?: [number, number] - /** - * The delay for displaying and hiding the popover (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`. - * - * @since 4.9.0 - */ - delay?: number | { show: number; hide: number } - /** - * Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference. - * - * @since 4.9.0 - */ - fallbackPlacements?: Placements | Placements[] - /** - * Callback fired when the component requests to be hidden. - */ - onHide?: () => void - /** - * Callback fired when the component requests to be shown. - */ - onShow?: () => void - /** - * Title node for your component. - */ - title?: ReactNode | string - /** - * Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. - * - * @type 'hover' | 'focus' | 'click' - */ - trigger?: Triggers | Triggers[] - /** - * Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. - */ - placement?: 'auto' | 'top' | 'right' | 'bottom' | 'left' - /** - * Toggle the visibility of popover component. - */ - visible?: boolean -} - -export const CPopover = forwardRef<HTMLDivElement, CPopoverProps>( - ( - { - children, - animation = true, - className, - container, - content, - delay = 0, - fallbackPlacements = ['top', 'right', 'bottom', 'left'], - offset = [0, 8], - onHide, - onShow, - placement = 'top', - title, - trigger = 'click', - visible, - ...rest - }, - ref, - ) => { - const popoverRef = useRef(null) - const togglerRef = useRef(null) - const forkedRef = useForkedRef(ref, popoverRef) - - const { initPopper, destroyPopper } = usePopper() - const [_visible, setVisible] = useState(visible) - - const _delay = typeof delay === 'number' ? { show: delay, hide: delay } : delay - - const popperConfig = { - modifiers: [ - { - name: 'arrow', - options: { - element: '.popover-arrow', - }, - }, - { - name: 'flip', - options: { - fallbackPlacements: fallbackPlacements, - }, - }, - { - name: 'offset', - options: { - offset: offset, - }, - }, - ], - placement: getRTLPlacement(placement, togglerRef.current), - } - - useEffect(() => { - setVisible(visible) - }, [visible]) - - useEffect(() => { - if (_visible && togglerRef.current && popoverRef.current) { - initPopper(togglerRef.current, popoverRef.current, popperConfig) - } - - return () => { - destroyPopper() - } - }, [_visible]) - - const toggleVisible = (visible: boolean) => { - if (visible) { - setTimeout(() => setVisible(true), _delay.show) - return - } - - setTimeout(() => setVisible(false), _delay.hide) - } - - return ( - <> - {React.cloneElement(children as React.ReactElement<any>, { - ref: togglerRef, - ...((trigger === 'click' || trigger.includes('click')) && { - onClick: () => toggleVisible(!_visible), - }), - ...((trigger === 'focus' || trigger.includes('focus')) && { - onFocus: () => toggleVisible(true), - onBlur: () => toggleVisible(false), - }), - ...((trigger === 'hover' || trigger.includes('hover')) && { - onMouseEnter: () => toggleVisible(true), - onMouseLeave: () => toggleVisible(false), - }), - })} - <CConditionalPortal container={container} portal={true}> - <Transition - in={_visible} - mountOnEnter - nodeRef={popoverRef} - onEnter={onShow} - onExit={onHide} - timeout={{ - enter: 0, - exit: popoverRef.current - ? getTransitionDurationFromElement(popoverRef.current) + 50 - : 200, - }} - unmountOnExit - > - {(state) => ( - <div - className={classNames( - 'popover', - 'bs-popover-auto', - { - fade: animation, - show: state === 'entered', - }, - className, - )} - ref={forkedRef} - role="tooltip" - {...rest} - > - <div className="popover-arrow"></div> - <div className="popover-header">{title}</div> - <div className="popover-body">{content}</div> - </div> - )} - </Transition> - </CConditionalPortal> - </> - ) - }, -) - -CPopover.propTypes = { - animation: PropTypes.bool, - children: PropTypes.node, - className: PropTypes.string, - container: PropTypes.any, - content: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - delay: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.shape({ - show: PropTypes.number.isRequired, - hide: PropTypes.number.isRequired, - }), - ]), - fallbackPlacements: fallbackPlacementsPropType, - offset: PropTypes.any, // TODO: find good proptype - onHide: PropTypes.func, - onShow: PropTypes.func, - placement: PropTypes.oneOf(['auto', 'top', 'right', 'bottom', 'left']), - title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - trigger: triggerPropType, - visible: PropTypes.bool, -} - -CPopover.displayName = 'CPopover' diff --git a/packages/coreui-react/src/components/popover/__tests__/CPopover.spec.tsx b/packages/coreui-react/src/components/popover/__tests__/CPopover.spec.tsx deleted file mode 100644 index 0005c7aa..00000000 --- a/packages/coreui-react/src/components/popover/__tests__/CPopover.spec.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import * as React from 'react' -import { act, render, fireEvent } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CPopover, CButton } from '../../../index' - -test('loads and displays CPopover component', async () => { - const { container } = render( - <CPopover content="A"> - <CButton>Test</CButton> - </CPopover>, - ) - expect(container).toMatchSnapshot() -}) - -test('CPopover customize', async () => { - jest.useFakeTimers() - let arr, element - const { container } = render( - <CPopover content="content" title="title" trigger="click" placement="right"> - <CButton>Test</CButton> - </CPopover>, - { container: document.body }, - ) - const btn = document.querySelector('.btn') - act(() => { - if (btn !== null) { - fireEvent.click(btn) - } - }) - jest.runAllTimers() - expect(container).toMatchSnapshot() - let arrLength = container.getElementsByClassName('popover').length - expect(arrLength).toBe(1) - arrLength = container.getElementsByClassName('bs-popover-end').length - expect(arrLength).toBe(1) - arrLength = container.getElementsByClassName('popover-arrow').length - expect(arrLength).toBe(1) - arrLength = container.getElementsByClassName('popover-header').length - expect(arrLength).toBe(1) - arrLength = container.getElementsByClassName('popover-body').length - expect(arrLength).toBe(1) - arr = container.getElementsByClassName('popover-header') - if (arr.length > 0) { - element = arr[0] - expect(element.innerHTML).toBe('title') - } else { - expect(true).toBe(false) - } - arr = container.getElementsByClassName('popover-body') - if (arr.length > 0) { - element = arr[0] - expect(element.innerHTML).toBe('content') - } else { - expect(true).toBe(false) - } - jest.useRealTimers() -}) - -// test('CPopover onToggle', async () => { -// let btn -// jest.useFakeTimers() -// const onToggle = jest.fn() -// render( -// <CPopover onToggle={onToggle} content="content" trigger="click"> -// <CButton>Test</CButton> -// </CPopover>, -// ) -// expect(onToggle).toHaveBeenCalledTimes(0) -// btn = document.querySelector('.btn') -// if (btn !== null) { -// fireEvent.click(btn) -// } -// jest.runAllTimers() -// expect(onToggle).toHaveBeenCalledTimes(1) -// btn = document.querySelector('.btn') -// if (btn !== null) { -// fireEvent.click(btn) -// } -// jest.runAllTimers() -// expect(onToggle).toHaveBeenCalledTimes(2) -// jest.useRealTimers() -// }) - -//TODO: test visible on focus, click and mouseEnter diff --git a/packages/coreui-react/src/components/popover/__tests__/__snapshots__/CPopover.spec.tsx.snap b/packages/coreui-react/src/components/popover/__tests__/__snapshots__/CPopover.spec.tsx.snap deleted file mode 100644 index e57f1613..00000000 --- a/packages/coreui-react/src/components/popover/__tests__/__snapshots__/CPopover.spec.tsx.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CPopover customize 1`] = ` -<body> - <button - class="btn btn-primary" - type="button" - > - Test - </button> -</body> -`; - -exports[`loads and displays CPopover component 1`] = ` -<div> - <button - class="btn btn-primary" - type="button" - > - Test - </button> -</div> -`; diff --git a/packages/coreui-react/src/components/popover/index.ts b/packages/coreui-react/src/components/popover/index.ts deleted file mode 100644 index af7ef771..00000000 --- a/packages/coreui-react/src/components/popover/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CPopover } from './CPopover' - -export { CPopover } diff --git a/packages/coreui-react/src/components/progress/CProgress.tsx b/packages/coreui-react/src/components/progress/CProgress.tsx deleted file mode 100644 index 62aab13d..00000000 --- a/packages/coreui-react/src/components/progress/CProgress.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useContext } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CProgressStackedContext } from './CProgressStacked' -import { CProgressBar, CProgressBarProps } from './CProgressBar' - -export interface CProgressProps - extends Omit<HTMLAttributes<HTMLDivElement>, 'color'>, - CProgressBarProps { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the height of the component. If you set that value the inner `<CProgressBar>` will automatically resize accordingly. - */ - height?: number - /** - * A string of all className you want applied to the <CProgressBar/> component. - * - * @since 4.9.0 - */ - progressBarClassName?: string - /** - * Makes progress bar thinner. - */ - thin?: boolean - /** - * The percent to progress the ProgressBar (out of 100). - */ - value?: number - /** - * Change the default color to white. - */ - white?: boolean -} - -export const CProgress = forwardRef<HTMLDivElement, CProgressProps>( - ({ children, className, height, progressBarClassName, thin, value, white, ...rest }, ref) => { - const { stacked } = useContext(CProgressStackedContext) - - return ( - <div - className={classNames( - 'progress', - { - 'progress-thin': thin, - 'progress-white': white, - }, - className, - )} - {...(value !== undefined && { - role: 'progressbar', - 'aria-valuenow': value, - 'aria-valuemin': 0, - 'aria-valuemax': 100, - })} - style={{ - ...(height ? { height: `${height}px` } : {}), - ...(stacked ? { width: `${value}%` } : {}), - }} - ref={ref} - > - {React.Children.toArray(children).some( - // @ts-expect-error displayName is set in the CProgressBar component - (child) => child.type && child.type.displayName === 'CProgressBar', - ) ? ( - React.Children.map(children, (child) => { - // @ts-expect-error displayName is set in the CProgressBar component - if (React.isValidElement(child) && child.type.displayName === 'CProgressBar') { - return React.cloneElement(child, { - ...(value && { value: value }), - ...rest, - }) - } - - return - }) - ) : ( - <CProgressBar - {...(progressBarClassName && { className: progressBarClassName })} - value={value} - {...rest} - > - {children} - </CProgressBar> - )} - </div> - ) - }, -) - -CProgress.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - height: PropTypes.number, - progressBarClassName: PropTypes.string, - thin: PropTypes.bool, - value: PropTypes.number, - white: PropTypes.bool, -} - -CProgress.displayName = 'CProgress' diff --git a/packages/coreui-react/src/components/progress/CProgressBar.tsx b/packages/coreui-react/src/components/progress/CProgressBar.tsx deleted file mode 100644 index 0af619f4..00000000 --- a/packages/coreui-react/src/components/progress/CProgressBar.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useContext } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CProgressStackedContext } from './CProgressStacked' -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CProgressBarProps extends HTMLAttributes<HTMLDivElement> { - /** - * Use to animate the stripes right to left via CSS3 animations. - */ - animated?: boolean - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * The percent to progress the ProgressBar. - */ - value?: number - /** - * Set the progress bar variant to optional striped. - */ - variant?: 'striped' -} - -export const CProgressBar = forwardRef<HTMLDivElement, CProgressBarProps>( - ({ children, animated, className, color, value = 0, variant, ...rest }, ref) => { - const { stacked } = useContext(CProgressStackedContext) - - return ( - <div - className={classNames( - 'progress-bar', - { - [`bg-${color}`]: color, - [`progress-bar-${variant}`]: variant, - 'progress-bar-animated': animated, - }, - className, - )} - {...(!stacked && { style: { width: `${value}%` } })} - {...rest} - ref={ref} - > - {children} - </div> - ) - }, -) -CProgressBar.propTypes = { - animated: PropTypes.bool, - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, - value: PropTypes.number, - variant: PropTypes.oneOf(['striped']), -} - -CProgressBar.displayName = 'CProgressBar' diff --git a/packages/coreui-react/src/components/progress/CProgressStacked.tsx b/packages/coreui-react/src/components/progress/CProgressStacked.tsx deleted file mode 100644 index b5e0a309..00000000 --- a/packages/coreui-react/src/components/progress/CProgressStacked.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { createContext, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CProgressStackedProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -export interface CProgressStackedContextProps { - stacked?: boolean -} - -export const CProgressStackedContext = createContext({} as CProgressStackedContextProps) - -export const CProgressStacked = forwardRef<HTMLDivElement, CProgressStackedProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('progress-stacked', className)} ref={ref} {...rest}> - <CProgressStackedContext.Provider - value={{ - stacked: true, - }} - > - {children} - </CProgressStackedContext.Provider> - </div> - ) - }, -) - -CProgressStacked.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CProgressStacked.displayName = 'CProgressStacked' diff --git a/packages/coreui-react/src/components/progress/__tests__/CProgress.spec.tsx b/packages/coreui-react/src/components/progress/__tests__/CProgress.spec.tsx deleted file mode 100644 index b5c4c2c6..00000000 --- a/packages/coreui-react/src/components/progress/__tests__/CProgress.spec.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CProgress } from '../../../index' - -test('loads and displays CProgress component', async () => { - const { container } = render(<CProgress color="warning">Test</CProgress>) - expect(container).toMatchSnapshot() -}) - -test('CProgress customize', async () => { - const { container } = render( - <CProgress className="bazinga" height={100} color="warning" value={50}> - Test - </CProgress>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('progress') - expect(container.firstChild).toHaveStyle(`height: 100px`) -}) diff --git a/packages/coreui-react/src/components/progress/__tests__/CProgressBar.spec.tsx b/packages/coreui-react/src/components/progress/__tests__/CProgressBar.spec.tsx deleted file mode 100644 index c63b5798..00000000 --- a/packages/coreui-react/src/components/progress/__tests__/CProgressBar.spec.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CProgressBar } from '../../../index' - -test('loads and displays CProgressBar component', async () => { - const { container } = render(<CProgressBar color="warning">Test</CProgressBar>) - expect(container).toMatchSnapshot() -}) - -test('CProgressBar customize', async () => { - const { container } = render( - <CProgressBar color="warning" className="bazinga" animated={true} value={50} variant="striped"> - Test - </CProgressBar>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('progress-bar') - - expect(container.firstChild).toHaveClass('bg-warning') - expect(container.firstChild).toHaveClass('progress-bar-striped') - expect(container.firstChild).toHaveClass('progress-bar-animated') - expect(container.firstChild).toHaveStyle(`width: 50%`) -}) diff --git a/packages/coreui-react/src/components/progress/__tests__/__snapshots__/CProgress.spec.tsx.snap b/packages/coreui-react/src/components/progress/__tests__/__snapshots__/CProgress.spec.tsx.snap deleted file mode 100644 index 6d566948..00000000 --- a/packages/coreui-react/src/components/progress/__tests__/__snapshots__/CProgress.spec.tsx.snap +++ /dev/null @@ -1,36 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CProgress customize 1`] = ` -<div> - <div - aria-valuemax="100" - aria-valuemin="0" - aria-valuenow="50" - class="progress bazinga" - role="progressbar" - style="height: 100px;" - > - <div - class="progress-bar bg-warning" - style="width: 50%;" - > - Test - </div> - </div> -</div> -`; - -exports[`loads and displays CProgress component 1`] = ` -<div> - <div - class="progress" - > - <div - class="progress-bar bg-warning" - style="width: 0%;" - > - Test - </div> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/progress/__tests__/__snapshots__/CProgressBar.spec.tsx.snap b/packages/coreui-react/src/components/progress/__tests__/__snapshots__/CProgressBar.spec.tsx.snap deleted file mode 100644 index bd11157d..00000000 --- a/packages/coreui-react/src/components/progress/__tests__/__snapshots__/CProgressBar.spec.tsx.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CProgressBar customize 1`] = ` -<div> - <div - class="progress-bar bg-warning progress-bar-striped progress-bar-animated bazinga" - style="width: 50%;" - > - Test - </div> -</div> -`; - -exports[`loads and displays CProgressBar component 1`] = ` -<div> - <div - class="progress-bar bg-warning" - style="width: 0%;" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/progress/index.ts b/packages/coreui-react/src/components/progress/index.ts deleted file mode 100644 index 29b68ae2..00000000 --- a/packages/coreui-react/src/components/progress/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { CProgress } from './CProgress' -import { CProgressBar } from './CProgressBar' -import { CProgressStacked } from './CProgressStacked' - -export { CProgress, CProgressBar, CProgressStacked } diff --git a/packages/coreui-react/src/components/sidebar/CSidebar.tsx b/packages/coreui-react/src/components/sidebar/CSidebar.tsx deleted file mode 100644 index 4e22affd..00000000 --- a/packages/coreui-react/src/components/sidebar/CSidebar.tsx +++ /dev/null @@ -1,234 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useEffect, useRef, useState } from 'react' -import { createPortal } from 'react-dom' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CBackdrop } from '../backdrop' - -import { isInViewport } from '../../utils' -import { useForkedRef } from '../../hooks' - -export interface CSidebarProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets if the color of text should be colored for a light or dark dark background. - * - * @type 'dark' | 'light' - */ - colorScheme?: 'dark' | 'light' - /** - * Make sidebar narrow. - */ - narrow?: boolean - /** - * Callback fired when the component requests to be hidden. - */ - onHide?: () => void - /** - * Callback fired when the component requests to be shown. - */ - onShow?: () => void - /** - * Event emitted after visibility of component changed. - */ - onVisibleChange?: (visible: boolean) => void - /** - * Set sidebar to overlaid variant. - */ - overlaid?: boolean - /** - * Components placement, there’s no default placement. - * @type 'start' | 'end' - */ - placement?: 'start' | 'end' - /** - * Place sidebar in non-static positions. - */ - position?: 'fixed' | 'sticky' - /** - * Size the component small, large, or extra large. - */ - size?: 'sm' | 'lg' | 'xl' - /** - * Expand narrowed sidebar on hover. - */ - unfoldable?: boolean - /** - * Toggle the visibility of sidebar component. - */ - visible?: boolean -} - -const isOnMobile = (element: HTMLDivElement) => - Boolean(getComputedStyle(element).getPropertyValue('--cui-is-mobile')) - -export const CSidebar = forwardRef<HTMLDivElement, CSidebarProps>( - ( - { - children, - className, - colorScheme, - narrow, - onHide, - onShow, - onVisibleChange, - overlaid, - placement, - position, - size, - unfoldable, - visible, - ...rest - }, - ref, - ) => { - const sidebarRef = useRef<HTMLDivElement>(null) - const forkedRef = useForkedRef(ref, sidebarRef) - - const [inViewport, setInViewport] = useState<boolean>() - const [mobile, setMobile] = useState(false) - const [visibleMobile, setVisibleMobile] = useState<boolean>(false) - const [visibleDesktop, setVisibleDesktop] = useState<boolean>( - visible !== undefined ? visible : overlaid ? false : true, - ) - - useEffect(() => { - sidebarRef.current && setMobile(isOnMobile(sidebarRef.current)) - visible !== undefined && handleVisibleChange(visible) - }, [visible]) - - useEffect(() => { - inViewport !== undefined && onVisibleChange && onVisibleChange(inViewport) - !inViewport && onHide && onHide() - inViewport && onShow && onShow() - }, [inViewport]) - - useEffect(() => { - mobile && setVisibleMobile(false) - }, [mobile]) - - useEffect(() => { - sidebarRef.current && setMobile(isOnMobile(sidebarRef.current)) - sidebarRef.current && setInViewport(isInViewport(sidebarRef.current)) - - window.addEventListener('resize', handleResize) - window.addEventListener('mouseup', handleClickOutside) - window.addEventListener('keyup', handleKeyup) - - sidebarRef.current?.addEventListener('mouseup', handleOnClick) - sidebarRef.current?.addEventListener('transitionend', () => { - sidebarRef.current && setInViewport(isInViewport(sidebarRef.current)) - }) - - return () => { - window.removeEventListener('resize', handleResize) - window.removeEventListener('mouseup', handleClickOutside) - window.removeEventListener('keyup', handleKeyup) - - sidebarRef.current?.removeEventListener('mouseup', handleOnClick) - sidebarRef.current?.removeEventListener('transitionend', () => { - sidebarRef.current && setInViewport(isInViewport(sidebarRef.current)) - }) - } - }) - - const handleVisibleChange = (visible: boolean) => { - if (mobile) { - setVisibleMobile(visible) - return - } - - setVisibleDesktop(visible) - } - - const handleHide = () => { - handleVisibleChange(false) - } - - const handleResize = () => { - sidebarRef.current && setMobile(isOnMobile(sidebarRef.current)) - sidebarRef.current && setInViewport(isInViewport(sidebarRef.current)) - } - - const handleKeyup = (event: Event) => { - if ( - mobile && - sidebarRef.current && - !sidebarRef.current.contains(event.target as HTMLElement) - ) { - handleHide() - } - } - const handleClickOutside = (event: Event) => { - if ( - mobile && - sidebarRef.current && - !sidebarRef.current.contains(event.target as HTMLElement) - ) { - handleHide() - } - } - - const handleOnClick = (event: Event) => { - const target = event.target as HTMLAnchorElement - target && - target.classList.contains('nav-link') && - !target.classList.contains('nav-group-toggle') && - mobile && - handleHide() - } - - return ( - <> - <div - className={classNames( - 'sidebar', - { - [`sidebar-${colorScheme}`]: colorScheme, - 'sidebar-narrow': narrow, - 'sidebar-overlaid': overlaid, - [`sidebar-${placement}`]: placement, - [`sidebar-${position}`]: position, - [`sidebar-${size}`]: size, - 'sidebar-narrow-unfoldable': unfoldable, - show: (mobile && visibleMobile) || (overlaid && visibleDesktop), - hide: visibleDesktop === false && !mobile && !overlaid, - }, - className, - )} - {...rest} - ref={forkedRef} - > - {children} - </div> - {typeof window !== 'undefined' && - mobile && - createPortal( - <CBackdrop className="sidebar-backdrop" visible={mobile && visibleMobile} />, - document.body, - )} - </> - ) - }, -) - -CSidebar.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - colorScheme: PropTypes.oneOf(['dark', 'light']), - narrow: PropTypes.bool, - onHide: PropTypes.func, - onShow: PropTypes.func, - onVisibleChange: PropTypes.func, - overlaid: PropTypes.bool, - placement: PropTypes.oneOf(['start', 'end']), - position: PropTypes.oneOf(['fixed', 'sticky']), - size: PropTypes.oneOf(['sm', 'lg', 'xl']), - unfoldable: PropTypes.bool, - visible: PropTypes.bool, -} - -CSidebar.displayName = 'CSidebar' diff --git a/packages/coreui-react/src/components/sidebar/CSidebarBrand.tsx b/packages/coreui-react/src/components/sidebar/CSidebarBrand.tsx deleted file mode 100644 index 3aa34c7a..00000000 --- a/packages/coreui-react/src/components/sidebar/CSidebarBrand.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CSidebarBrandProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -export const CSidebarBrand = forwardRef<HTMLDivElement, CSidebarBrandProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('sidebar-brand', className)} ref={ref} {...rest}> - {children} - </div> - ) - }, -) - -CSidebarBrand.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CSidebarBrand.displayName = 'CSidebarBrand' diff --git a/packages/coreui-react/src/components/sidebar/CSidebarFooter.tsx b/packages/coreui-react/src/components/sidebar/CSidebarFooter.tsx deleted file mode 100644 index 34e2f15c..00000000 --- a/packages/coreui-react/src/components/sidebar/CSidebarFooter.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CSidebarFooterProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -export const CSidebarFooter = forwardRef<HTMLDivElement, CSidebarFooterProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('sidebar-footer', className)} ref={ref} {...rest}> - {children} - </div> - ) - }, -) - -CSidebarFooter.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CSidebarFooter.displayName = 'CSidebarFooter' diff --git a/packages/coreui-react/src/components/sidebar/CSidebarHeader.tsx b/packages/coreui-react/src/components/sidebar/CSidebarHeader.tsx deleted file mode 100644 index a18bfff1..00000000 --- a/packages/coreui-react/src/components/sidebar/CSidebarHeader.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CSidebarHeaderProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -export const CSidebarHeader = forwardRef<HTMLDivElement, CSidebarHeaderProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('sidebar-header', className)} ref={ref} {...rest}> - {children} - </div> - ) - }, -) - -CSidebarHeader.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CSidebarHeader.displayName = 'CSidebarHeader' diff --git a/packages/coreui-react/src/components/sidebar/CSidebarNav.tsx b/packages/coreui-react/src/components/sidebar/CSidebarNav.tsx deleted file mode 100644 index 7fedaa86..00000000 --- a/packages/coreui-react/src/components/sidebar/CSidebarNav.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, { createContext, forwardRef, HTMLAttributes, useState } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CSidebarNavProps extends HTMLAttributes<HTMLUListElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -interface ContextProps { - visibleGroup: string - setVisibleGroup: React.Dispatch<React.SetStateAction<string | undefined>> -} - -export const CNavContext = createContext({} as ContextProps) - -export const CSidebarNav = forwardRef<HTMLUListElement, CSidebarNavProps>( - ({ children, className, ...rest }, ref) => { - const [visibleGroup, setVisibleGroup] = useState('') - const CNavContextValues = { - visibleGroup, - setVisibleGroup, - } - - return ( - <ul className={classNames('sidebar-nav', className)} ref={ref} {...rest}> - <CNavContext.Provider value={CNavContextValues}> - {React.Children.map(children, (child, index) => { - if (React.isValidElement(child)) { - return React.cloneElement(child as React.ReactElement<any>, { - key: index, - idx: `${index}`, - }) - } - return - })} - </CNavContext.Provider> - </ul> - ) - }, -) - -CSidebarNav.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CSidebarNav.displayName = 'CSidebarNav' diff --git a/packages/coreui-react/src/components/sidebar/CSidebarToggler.tsx b/packages/coreui-react/src/components/sidebar/CSidebarToggler.tsx deleted file mode 100644 index 487275b8..00000000 --- a/packages/coreui-react/src/components/sidebar/CSidebarToggler.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CSidebarTogglerProps extends HTMLAttributes<HTMLButtonElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string -} - -export const CSidebarToggler = forwardRef<HTMLButtonElement, CSidebarTogglerProps>( - ({ children, className, ...rest }, ref) => { - return ( - <button className={classNames('sidebar-toggler', className)} ref={ref} {...rest}> - {children} - </button> - ) - }, -) - -CSidebarToggler.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CSidebarToggler.displayName = 'CSidebarToggler' diff --git a/packages/coreui-react/src/components/sidebar/__tests__/CSidebar.spec.tsx b/packages/coreui-react/src/components/sidebar/__tests__/CSidebar.spec.tsx deleted file mode 100644 index b4102a6b..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/CSidebar.spec.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { - CSidebar /* , CSidebarNav, CNavLink, CNavGroup, CNavGroupItems, CNavItem */, -} from '../../../index' - -test('loads and displays CSidebar component', async () => { - const { container } = render(<CSidebar>Test</CSidebar>) - expect(container).toMatchSnapshot() -}) - -test('CSidebar customize show', async () => { - const { container } = render( - <CSidebar - className="bazinga" - narrow={true} - position="fixed" - visible={true} - unfoldable={true} - overlaid={true} - > - Test - </CSidebar>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('sidebar') - expect(container.firstChild).toHaveClass('sidebar-narrow') - expect(container.firstChild).toHaveClass('sidebar-overlaid') - expect(container.firstChild).toHaveClass('sidebar-fixed') - expect(container.firstChild).toHaveClass('sidebar-narrow-unfoldable') - // expect(container.firstChild).toHaveClass('show') -}) - -test('CSidebar customize hide', async () => { - const { container } = render( - <CSidebar className="bazinga" position="sticky" visible={false} overlaid={false}> - Test - </CSidebar>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('sidebar') - expect(container.firstChild).toHaveClass('sidebar-sticky') -}) diff --git a/packages/coreui-react/src/components/sidebar/__tests__/CSidebarBrand.spec.tsx b/packages/coreui-react/src/components/sidebar/__tests__/CSidebarBrand.spec.tsx deleted file mode 100644 index 04f92181..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/CSidebarBrand.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CSidebarBrand } from '../../../index' - -test('loads and displays CSidebarBrand component', async () => { - const { container } = render(<CSidebarBrand color="primary">Test</CSidebarBrand>) - expect(container).toMatchSnapshot() -}) - -test('CSidebarBrand customize', async () => { - const { container } = render(<CSidebarBrand className="bazinga">Test</CSidebarBrand>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('sidebar-brand') -}) diff --git a/packages/coreui-react/src/components/sidebar/__tests__/CSidebarFooter.spec.tsx b/packages/coreui-react/src/components/sidebar/__tests__/CSidebarFooter.spec.tsx deleted file mode 100644 index 4e12dd5e..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/CSidebarFooter.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CSidebarFooter } from '../../../index' - -test('loads and displays CSidebarFooter component', async () => { - const { container } = render(<CSidebarFooter>Test</CSidebarFooter>) - expect(container).toMatchSnapshot() -}) - -test('CSidebarFooter customize', async () => { - const { container } = render(<CSidebarFooter className="bazinga">Test</CSidebarFooter>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('sidebar-footer') -}) diff --git a/packages/coreui-react/src/components/sidebar/__tests__/CSidebarHeader.spec.tsx b/packages/coreui-react/src/components/sidebar/__tests__/CSidebarHeader.spec.tsx deleted file mode 100644 index dbe9f2b0..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/CSidebarHeader.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CSidebarHeader } from '../../../index' - -test('loads and displays CSidebarHeader component', async () => { - const { container } = render(<CSidebarHeader>Test</CSidebarHeader>) - expect(container).toMatchSnapshot() -}) - -test('CSidebarHeader customize', async () => { - const { container } = render(<CSidebarHeader className="bazinga">Test</CSidebarHeader>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('sidebar-header') -}) diff --git a/packages/coreui-react/src/components/sidebar/__tests__/CSidebarNav.spec.tsx b/packages/coreui-react/src/components/sidebar/__tests__/CSidebarNav.spec.tsx deleted file mode 100644 index 15732399..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/CSidebarNav.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CSidebarNav } from '../../../index' - -test('loads and displays CSidebarNav component', async () => { - const { container } = render(<CSidebarNav>Test</CSidebarNav>) - expect(container).toMatchSnapshot() -}) - -test('CSidebarNav customize', async () => { - const { container } = render(<CSidebarNav className="bazinga">Test</CSidebarNav>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('sidebar-nav') -}) diff --git a/packages/coreui-react/src/components/sidebar/__tests__/CSidebarToggler.spec.tsx b/packages/coreui-react/src/components/sidebar/__tests__/CSidebarToggler.spec.tsx deleted file mode 100644 index 44561696..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/CSidebarToggler.spec.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CSidebarToggler } from '../../../index' - -test('loads and displays CSidebarToggler component', async () => { - const { container } = render(<CSidebarToggler />) - expect(container).toMatchSnapshot() -}) - -test('CSidebarToggler customize', async () => { - const { container } = render(<CSidebarToggler className="bazinga">Test</CSidebarToggler>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('sidebar-toggler') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebar.spec.tsx.snap b/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebar.spec.tsx.snap deleted file mode 100644 index 045e4f95..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebar.spec.tsx.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CSidebar customize hide 1`] = ` -<div> - <div - class="sidebar sidebar-sticky hide bazinga" - > - Test - </div> -</div> -`; - -exports[`CSidebar customize show 1`] = ` -<div> - <div - class="sidebar sidebar-narrow sidebar-overlaid sidebar-fixed sidebar-narrow-unfoldable show bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CSidebar component 1`] = ` -<div> - <div - class="sidebar" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarBrand.spec.tsx.snap b/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarBrand.spec.tsx.snap deleted file mode 100644 index 7a6430f1..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarBrand.spec.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CSidebarBrand customize 1`] = ` -<div> - <div - class="sidebar-brand bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CSidebarBrand component 1`] = ` -<div> - <div - class="sidebar-brand" - color="primary" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarFooter.spec.tsx.snap b/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarFooter.spec.tsx.snap deleted file mode 100644 index fa15ad34..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarFooter.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CSidebarFooter customize 1`] = ` -<div> - <div - class="sidebar-footer bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CSidebarFooter component 1`] = ` -<div> - <div - class="sidebar-footer" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarHeader.spec.tsx.snap b/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarHeader.spec.tsx.snap deleted file mode 100644 index 09d19bfd..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarHeader.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CSidebarHeader customize 1`] = ` -<div> - <div - class="sidebar-header bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CSidebarHeader component 1`] = ` -<div> - <div - class="sidebar-header" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarNav.spec.tsx.snap b/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarNav.spec.tsx.snap deleted file mode 100644 index db0872b0..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarNav.spec.tsx.snap +++ /dev/null @@ -1,17 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CSidebarNav customize 1`] = ` -<div> - <ul - class="sidebar-nav bazinga" - /> -</div> -`; - -exports[`loads and displays CSidebarNav component 1`] = ` -<div> - <ul - class="sidebar-nav" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarToggler.spec.tsx.snap b/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarToggler.spec.tsx.snap deleted file mode 100644 index 269f7b73..00000000 --- a/packages/coreui-react/src/components/sidebar/__tests__/__snapshots__/CSidebarToggler.spec.tsx.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CSidebarToggler customize 1`] = ` -<div> - <button - class="sidebar-toggler bazinga" - > - Test - </button> -</div> -`; - -exports[`loads and displays CSidebarToggler component 1`] = ` -<div> - <button - class="sidebar-toggler" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/sidebar/index.ts b/packages/coreui-react/src/components/sidebar/index.ts deleted file mode 100644 index 12a076d2..00000000 --- a/packages/coreui-react/src/components/sidebar/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { CSidebar } from './CSidebar' -import { CSidebarBrand } from './CSidebarBrand' -import { CSidebarFooter } from './CSidebarFooter' -import { CSidebarToggler } from './CSidebarToggler' -import { CSidebarHeader } from './CSidebarHeader' -import { CSidebarNav } from './CSidebarNav' - -export { CSidebar, CSidebarBrand, CSidebarFooter, CSidebarToggler, CSidebarHeader, CSidebarNav } diff --git a/packages/coreui-react/src/components/spinner/CSpinner.tsx b/packages/coreui-react/src/components/spinner/CSpinner.tsx deleted file mode 100644 index 81fb7c1e..00000000 --- a/packages/coreui-react/src/components/spinner/CSpinner.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import React, { ElementType, forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CSpinnerProps extends HTMLAttributes<HTMLDivElement | HTMLSpanElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType - /** - * Size the component small. - */ - size?: 'sm' - /** - * Set the button variant to an outlined button or a ghost button. - */ - variant?: 'border' | 'grow' - /** - * Set visually hidden label for accessibility purposes. - */ - visuallyHiddenLabel?: string -} - -export const CSpinner = forwardRef<HTMLDivElement | HTMLSpanElement, CSpinnerProps>( - ( - { - className, - color, - component: Component = 'div', - size, - variant = 'border', - visuallyHiddenLabel = 'Loading...', - ...rest - }, - ref, - ) => { - return ( - <Component - className={classNames( - `spinner-${variant}`, - { - [`spinner-${variant}-${size}`]: size, - [`text-${color}`]: color, - }, - className, - )} - role="status" - {...rest} - ref={ref} - > - <span className="visually-hidden">{visuallyHiddenLabel}</span> - </Component> - ) - }, -) - -CSpinner.propTypes = { - className: PropTypes.string, - color: colorPropType, - component: PropTypes.string, - size: PropTypes.oneOf(['sm']), - variant: PropTypes.oneOf(['border', 'grow']), - visuallyHiddenLabel: PropTypes.string, -} - -CSpinner.displayName = 'CSpinner' diff --git a/packages/coreui-react/src/components/spinner/__tests__/CSpinner.spec.tsx b/packages/coreui-react/src/components/spinner/__tests__/CSpinner.spec.tsx deleted file mode 100644 index 677aec32..00000000 --- a/packages/coreui-react/src/components/spinner/__tests__/CSpinner.spec.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CSpinner } from '../../../index' - -test('loads and displays CSpinner component', async () => { - const { container } = render(<CSpinner>Test</CSpinner>) - expect(container).toMatchSnapshot() -}) - -test('CSpinner customize', async () => { - const { container } = render( - <CSpinner className="bazinga" color="warning" component="h3" size="sm" variant="grow"> - Test - </CSpinner>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('spinner-grow') - expect(container.firstChild).toHaveClass('text-warning') - expect(container.firstChild).toHaveClass('spinner-grow-sm') -}) diff --git a/packages/coreui-react/src/components/spinner/__tests__/__snapshots__/CSpinner.spec.tsx.snap b/packages/coreui-react/src/components/spinner/__tests__/__snapshots__/CSpinner.spec.tsx.snap deleted file mode 100644 index 44888fc5..00000000 --- a/packages/coreui-react/src/components/spinner/__tests__/__snapshots__/CSpinner.spec.tsx.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CSpinner customize 1`] = ` -<div> - <h3 - class="spinner-grow spinner-grow-sm text-warning bazinga" - role="status" - > - <span - class="visually-hidden" - > - Loading... - </span> - </h3> -</div> -`; - -exports[`loads and displays CSpinner component 1`] = ` -<div> - <div - class="spinner-border" - role="status" - > - <span - class="visually-hidden" - > - Loading... - </span> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/spinner/index.ts b/packages/coreui-react/src/components/spinner/index.ts deleted file mode 100644 index 2c23f866..00000000 --- a/packages/coreui-react/src/components/spinner/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CSpinner } from './CSpinner' - -export { CSpinner } diff --git a/packages/coreui-react/src/components/table/CTable.tsx b/packages/coreui-react/src/components/table/CTable.tsx deleted file mode 100644 index 580b9514..00000000 --- a/packages/coreui-react/src/components/table/CTable.tsx +++ /dev/null @@ -1,267 +0,0 @@ -import React, { forwardRef, TableHTMLAttributes, useMemo } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CTableHead, CTableHeadProps } from './CTableHead' -import { CTableHeaderCell } from './CTableHeaderCell' -import { CTableBody } from './CTableBody' -import { CTableDataCell } from './CTableDataCell' -import { CTableRow } from './CTableRow' -import { CTableFoot, CTableFootProps } from './CTableFoot' -import { CTableCaption } from './CTableCaption' -import { CTableResponsiveWrapper } from './CTableResponsiveWrapper' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' -import { getColumnLabel, getColumnNames } from './utils' -import type { Column, FooterItem, Item } from './types' - -export interface CTableProps extends Omit<TableHTMLAttributes<HTMLTableElement>, 'align'> { - /** - * Set the vertical aligment. - */ - align?: 'bottom' | 'middle' | 'top' | string - /** - * Sets the border color of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - borderColor?: Colors - /** - * Add borders on all sides of the table and cells. - */ - bordered?: boolean - /** - * Remove borders on all sides of the table and cells. - */ - borderless?: boolean - /** - * Put the caption on the top if you set `caption="top"` of the table or set the text of the table caption. - */ - caption?: 'top' | string - /** - * Set the text of the table caption and the caption on the top of the table. - * - * @since 4.3.0 - */ - captionTop?: string - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Prop for table columns configuration. If prop is not defined, table will display columns based on the first item keys, omitting keys that begins with underscore (e.g. '_props') - * - * In columns prop each array item represents one column. Item might be specified in two ways: - * String: each item define column name equal to item value. - * Object: item is object with following keys available as column configuration: - * - key (required)(String) - define column name equal to item key. - * - label (String) - define visible label of column. If not defined, label will be generated automatically based on column name, by converting kebab-case and snake_case to individual words and capitalization of each word. - * - _props (Object) - adds classes to all cels in column, ex. `_props: { scope: 'col', className: 'custom-class' }`, - * - _style (Object) - adds styles to the column header (useful for defining widths) - * - * @since 4.3.0 - */ - columns?: (string | Column)[] - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Array of objects or strings, where each element represents one cell in the table footer. - * - * Example items: - * `['FooterCell', 'FooterCell', 'FooterCell']` - * or - * `[{ label: 'FooterCell', _props: { color: 'success' }, ...]` - * - * @since 4.3.0 - */ - footer?: (FooterItem | string)[] - /** - * Enable a hover state on table rows within a `<CTableBody>`. - */ - hover?: boolean - /** - * Array of objects, where each object represents one item - row in table. Additionally, you can add style classes to each row by passing them by '_props' key and to single cell by '_cellProps'. - * - * Example item: - * `{ name: 'John' , age: 12, _props: { color: 'success' }, _cellProps: { age: { className: 'fw-bold'}}}` - * - * @since 4.3.0 - */ - items?: Item[] - /** - * Make any table responsive across all viewports or pick a maximum breakpoint with which to have a responsive table up to. - */ - responsive?: boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' - /** - * Make table more compact by cutting all cell `padding` in half. - */ - small?: boolean - /** - * Add zebra-striping to any table row within the `<CTableBody>`. - */ - striped?: boolean - /** - * Add zebra-striping to any table column. - * - * @since 4.3.0 - */ - stripedColumns?: boolean - /** - * Properties that will be passed to the table footer component. - * - * @link https://coreui.io/react/docs/components/table/#ctablefoot - * @since 4.3.0 - */ - tableFootProps?: CTableFootProps - /** - * Properties that will be passed to the table head component. - * - * @link https://coreui.io/react/docs/components/table/#ctablehead - * @since 4.3.0 - */ - tableHeadProps?: CTableHeadProps -} - -export const CTable = forwardRef<HTMLTableElement, CTableProps>( - ( - { - children, - align, - borderColor, - bordered, - borderless, - caption, - captionTop, - className, - color, - columns, - footer, - hover, - items, - responsive, - small, - striped, - stripedColumns, - tableFootProps, - tableHeadProps, - ...rest - }, - ref, - ) => { - const columnNames = useMemo(() => getColumnNames(columns, items), [columns, items]) - - return ( - <CTableResponsiveWrapper responsive={responsive}> - <table - className={classNames( - 'table', - { - [`align-${align}`]: align, - [`border-${borderColor}`]: borderColor, - [`caption-top`]: captionTop || caption === 'top', - 'table-bordered': bordered, - 'table-borderless': borderless, - [`table-${color}`]: color, - 'table-hover': hover, - 'table-sm': small, - 'table-striped': striped, - 'table-striped-columns': stripedColumns, - }, - className, - )} - {...rest} - ref={ref} - > - {((caption && caption !== 'top') || captionTop) && ( - <CTableCaption>{caption || captionTop}</CTableCaption> - )} - {columns && ( - <CTableHead {...tableHeadProps}> - <CTableRow> - {columns.map((column: Column, index: number) => ( - <CTableHeaderCell - {...(column._props && { ...column._props })} - {...(column._style && { style: { ...column._style } })} - key={index} - > - {getColumnLabel(column)} - </CTableHeaderCell> - ))} - </CTableRow> - </CTableHead> - )} - {items && ( - <CTableBody> - {items.map((item: Item, index: number) => ( - <CTableRow {...(item._props && { ...item._props })} key={index}> - {columnNames && - columnNames.map((colName: string, index: number) => { - // eslint-disable-next-line unicorn/no-negated-condition - return item[colName] !== undefined ? ( - <CTableDataCell - {...(item._cellProps && { - ...(item._cellProps['all'] && { ...item._cellProps['all'] }), - ...(item._cellProps[colName] && { ...item._cellProps[colName] }), - })} - key={index} - > - {item[colName]} - </CTableDataCell> - ) : null - })} - </CTableRow> - ))} - </CTableBody> - )} - {children} - {footer && ( - <CTableFoot {...tableFootProps}> - <CTableRow> - {footer.map((item: FooterItem | string, index: number) => ( - <CTableDataCell - {...(typeof item === 'object' && item._props && { ...item._props })} - key={index} - > - {typeof item === 'object' ? item.label : item} - </CTableDataCell> - ))} - </CTableRow> - </CTableFoot> - )} - </table> - </CTableResponsiveWrapper> - ) - }, -) - -CTable.propTypes = { - align: PropTypes.oneOf(['bottom', 'middle', 'top']), - borderColor: PropTypes.string, - bordered: PropTypes.bool, - borderless: PropTypes.bool, - caption: PropTypes.oneOfType([PropTypes.string, PropTypes.oneOf(['top'])]), - captionTop: PropTypes.string, - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, - columns: PropTypes.array, - footer: PropTypes.array, - hover: PropTypes.bool, - items: PropTypes.array, - responsive: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.oneOf<'sm' | 'md' | 'lg' | 'xl' | 'xxl'>(['sm', 'md', 'lg', 'xl', 'xxl']), - ]), - small: PropTypes.bool, - striped: PropTypes.bool, - stripedColumns: PropTypes.bool, - tableFootProps: PropTypes.shape({ ...CTableFoot.propTypes }), - tableHeadProps: PropTypes.shape({ ...CTableHead.propTypes }), -} - -CTable.displayName = 'CTable' diff --git a/packages/coreui-react/src/components/table/CTableBody.tsx b/packages/coreui-react/src/components/table/CTableBody.tsx deleted file mode 100644 index 893cd5f1..00000000 --- a/packages/coreui-react/src/components/table/CTableBody.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CTableBodyProps extends HTMLAttributes<HTMLTableSectionElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors -} - -export const CTableBody = forwardRef<HTMLTableSectionElement, CTableBodyProps>( - ({ children, className, color, ...rest }, ref) => { - return ( - <tbody - className={ - classNames( - { - [`table-${color}`]: color, - }, - className, - ) || undefined - } - {...rest} - ref={ref} - > - {children} - </tbody> - ) - }, -) - -CTableBody.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, -} - -CTableBody.displayName = 'CTableBody' diff --git a/packages/coreui-react/src/components/table/CTableCaption.tsx b/packages/coreui-react/src/components/table/CTableCaption.tsx deleted file mode 100644 index 3d2401f4..00000000 --- a/packages/coreui-react/src/components/table/CTableCaption.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' - -export const CTableCaption = forwardRef< - HTMLTableCaptionElement, - HTMLAttributes<HTMLTableCaptionElement> ->(({ children, ...props }, ref) => { - return ( - <caption {...props} ref={ref}> - {children} - </caption> - ) -}) - -CTableCaption.propTypes = { - children: PropTypes.node, -} - -CTableCaption.displayName = 'CTableCaption' diff --git a/packages/coreui-react/src/components/table/CTableDataCell.tsx b/packages/coreui-react/src/components/table/CTableDataCell.tsx deleted file mode 100644 index 02a040aa..00000000 --- a/packages/coreui-react/src/components/table/CTableDataCell.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, { forwardRef, TdHTMLAttributes, ThHTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CTableDataCellProps - extends Omit<TdHTMLAttributes<HTMLTableCellElement>, 'align'>, - Omit<ThHTMLAttributes<HTMLTableCellElement>, 'align'> { - /** - * Highlight a table row or cell. - */ - active?: boolean - /** - * Set the vertical aligment. - */ - align?: 'bottom' | 'middle' | 'top' | string - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * @ignore - */ - colSpan?: number -} - -export const CTableDataCell = forwardRef<HTMLTableCellElement, CTableDataCellProps>( - ({ children, active, align, className, color, ...rest }, ref) => { - const Component = rest.scope ? 'th' : 'td' - - return ( - <Component - className={ - classNames( - { - [`align-${align}`]: align, - 'table-active': active, - [`table-${color}`]: color, - }, - className, - ) || undefined - } - {...rest} - ref={ref} - > - {children} - </Component> - ) - }, -) - -CTableDataCell.propTypes = { - active: PropTypes.bool, - align: PropTypes.oneOf(['bottom', 'middle', 'top']), - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, -} - -CTableDataCell.displayName = 'CTableDataCell' diff --git a/packages/coreui-react/src/components/table/CTableFoot.tsx b/packages/coreui-react/src/components/table/CTableFoot.tsx deleted file mode 100644 index dbbf8b50..00000000 --- a/packages/coreui-react/src/components/table/CTableFoot.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import PropTypes from 'prop-types' -import React, { forwardRef, HTMLAttributes } from 'react' -import classNames from 'classnames' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CTableFootProps extends HTMLAttributes<HTMLTableSectionElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors -} - -export const CTableFoot = forwardRef<HTMLTableSectionElement, CTableFootProps>( - ({ children, className, color, ...rest }, ref) => { - return ( - <tfoot - className={ - classNames( - { - [`table-${color}`]: color, - }, - className, - ) || undefined - } - {...rest} - ref={ref} - > - {children} - </tfoot> - ) - }, -) - -CTableFoot.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, -} - -CTableFoot.displayName = 'CTableFoot' diff --git a/packages/coreui-react/src/components/table/CTableHead.tsx b/packages/coreui-react/src/components/table/CTableHead.tsx deleted file mode 100644 index a8cff525..00000000 --- a/packages/coreui-react/src/components/table/CTableHead.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CTableHeadProps extends HTMLAttributes<HTMLTableSectionElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors -} - -export const CTableHead = forwardRef<HTMLTableSectionElement, CTableHeadProps>( - ({ children, className, color, ...rest }, ref) => { - return ( - <thead - className={ - classNames( - { - [`table-${color}`]: color, - }, - className, - ) || undefined - } - {...rest} - ref={ref} - > - {children} - </thead> - ) - }, -) - -CTableHead.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, -} - -CTableHead.displayName = 'CTableHead' diff --git a/packages/coreui-react/src/components/table/CTableHeaderCell.tsx b/packages/coreui-react/src/components/table/CTableHeaderCell.tsx deleted file mode 100644 index cf13571c..00000000 --- a/packages/coreui-react/src/components/table/CTableHeaderCell.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React, { forwardRef, ThHTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CTableHeaderCellProps extends ThHTMLAttributes<HTMLTableCellElement> { - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors -} - -export const CTableHeaderCell = forwardRef<HTMLTableCellElement, CTableHeaderCellProps>( - ({ children, className, color, ...rest }, ref) => { - return ( - <th - className={ - classNames( - { - [`table-${color}`]: color, - }, - className, - ) || undefined - } - {...rest} - ref={ref} - > - {children} - </th> - ) - }, -) - -CTableHeaderCell.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, -} - -CTableHeaderCell.displayName = 'CTableHeaderCell' diff --git a/packages/coreui-react/src/components/table/CTableResponsiveWrapper.tsx b/packages/coreui-react/src/components/table/CTableResponsiveWrapper.tsx deleted file mode 100644 index 321c5d2f..00000000 --- a/packages/coreui-react/src/components/table/CTableResponsiveWrapper.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React, { FC, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' - -export interface CTableResponsiveWrapperProps extends HTMLAttributes<HTMLDivElement> { - /** - * Make any table responsive across all viewports or pick a maximum breakpoint with which to have a responsive table up to. - */ - responsive?: boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' -} - -export const CTableResponsiveWrapper: FC<CTableResponsiveWrapperProps> = ({ - children, - responsive, - ...rest -}) => { - return responsive ? ( - <div - className={ - typeof responsive === 'boolean' ? 'table-responsive' : `table-responsive-${responsive}` - } - {...rest} - > - {children} - </div> - ) : ( - <>{children}</> - ) -} - -CTableResponsiveWrapper.propTypes = { - children: PropTypes.node, - responsive: PropTypes.oneOfType([ - PropTypes.bool, - PropTypes.oneOf<'sm' | 'md' | 'lg' | 'xl' | 'xxl'>(['sm', 'md', 'lg', 'xl', 'xxl']), - ]), -} - -CTableResponsiveWrapper.displayName = 'CTableResponsiveWrapper' diff --git a/packages/coreui-react/src/components/table/CTableRow.tsx b/packages/coreui-react/src/components/table/CTableRow.tsx deleted file mode 100644 index 9130ee17..00000000 --- a/packages/coreui-react/src/components/table/CTableRow.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CTableRowProps extends HTMLAttributes<HTMLTableRowElement> { - /** - * Highlight a table row or cell.. - */ - active?: boolean - /** - * Set the vertical aligment. - */ - align?: 'bottom' | 'middle' | 'top' | string - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors -} - -export const CTableRow = forwardRef<HTMLTableRowElement, CTableRowProps>( - ({ children, active, align, className, color, ...rest }, ref) => { - return ( - <tr - className={ - classNames( - { - [`align-${align}`]: align, - 'table-active': active, - [`table-${color}`]: color, - }, - className, - ) || undefined - } - {...rest} - ref={ref} - > - {children} - </tr> - ) - }, -) - -CTableRow.propTypes = { - active: PropTypes.bool, - align: PropTypes.oneOf(['bottom', 'middle', 'top']), - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, -} - -CTableRow.displayName = 'CTableRow' diff --git a/packages/coreui-react/src/components/table/__tests__/CTable.spec.tsx b/packages/coreui-react/src/components/table/__tests__/CTable.spec.tsx deleted file mode 100644 index 916895e4..00000000 --- a/packages/coreui-react/src/components/table/__tests__/CTable.spec.tsx +++ /dev/null @@ -1,150 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { - CTable, - CTableCaption, - CTableHead, - CTableRow, - CTableHeaderCell, - CTableBody, - CTableDataCell, - CTableFoot, -} from '../../../index' - -test('loads and displays CTable component', async () => { - const { container } = render(<CTable />) - expect(container).toMatchSnapshot() -}) - -test('loads and displays CTable component - new way', async () => { - const columns = [ - { - key: 'id', - label: '#', - _props: { scope: 'col' }, - }, - 'class', - { - key: 'heading_1', - label: 'Heading', - _props: { scope: 'col' }, - }, - { - key: 'heading_2', - label: 'Heading', - _props: { scope: 'col' }, - }, - ] - const items = [ - { - id: 1, - class: 'Mark', - heading_1: 'Otto', - heading_2: '@mdo', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 2, - class: 'Jacob', - heading_1: 'Thornton', - heading_2: '@fat', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 3, - class: 'Larry the Bird', - heading_2: '@twitter', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - }, - ] - const { container } = render(<CTable columns={columns} items={items} />) - expect(container).toMatchSnapshot() -}) - -test('CTable customize', async () => { - const { container } = render( - <CTable - className="bazinga" - align="middle" - borderColor="primary" - bordered={true} - borderless={true} - caption="top" - color="info" - hover={true} - responsive="xl" - small={true} - striped={true} - > - <CTableBody> - <CTableRow> - <CTableDataCell>Test</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('table-responsive-xl') - if (container.firstChild === null) { - expect(true).toBe(false) - } else { - expect(container.firstChild.firstChild).toHaveClass('table') - expect(container.firstChild.firstChild).toHaveClass('align-middle') - expect(container.firstChild.firstChild).toHaveClass('caption-top') - expect(container.firstChild.firstChild).toHaveClass('border-primary') - expect(container.firstChild.firstChild).toHaveClass('table-bordered') - expect(container.firstChild.firstChild).toHaveClass('table-borderless') - expect(container.firstChild.firstChild).toHaveClass('table-info') - expect(container.firstChild.firstChild).toHaveClass('table-hover') - expect(container.firstChild.firstChild).toHaveClass('table-sm') - expect(container.firstChild.firstChild).toHaveClass('table-striped') - expect(container.firstChild.firstChild).toHaveClass('bazinga') - expect(container.firstChild.firstChild).toHaveTextContent('Test') - } -}) - -test('CTable full example test', async () => { - const { container } = render( - <CTable caption="top"> - <CTableCaption>List of users</CTableCaption> - <CTableHead> - <CTableRow> - <CTableHeaderCell>#</CTableHeaderCell> - <CTableHeaderCell>Class</CTableHeaderCell> - <CTableHeaderCell>Heading</CTableHeaderCell> - <CTableHeaderCell>Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell>1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell>2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell>3</CTableHeaderCell> - <CTableDataCell>Larry</CTableDataCell> - <CTableDataCell>the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - <CTableFoot> - <CTableRow> - <CTableHeaderCell>#</CTableHeaderCell> - <CTableHeaderCell>Class</CTableHeaderCell> - <CTableHeaderCell>Heading</CTableHeaderCell> - <CTableHeaderCell>Heading</CTableHeaderCell> - </CTableRow> - </CTableFoot> - </CTable>, - ) - expect(container).toMatchSnapshot() -}) diff --git a/packages/coreui-react/src/components/table/__tests__/CTableBody.spec.tsx b/packages/coreui-react/src/components/table/__tests__/CTableBody.spec.tsx deleted file mode 100644 index 626c9879..00000000 --- a/packages/coreui-react/src/components/table/__tests__/CTableBody.spec.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CTableBody, CTableDataCell, CTableRow } from '../../../index' - -test('loads and displays CTableBody component', async () => { - const table = document.createElement('table') - const { container } = render(<CTableBody />, { - container: document.body.appendChild(table), - }) - expect(container).toMatchSnapshot() -}) - -test('CTableBody customize', async () => { - const table = document.createElement('table') - const { container } = render( - <CTableBody className="bazinga" color="info"> - <CTableRow> - <CTableDataCell> Test</CTableDataCell> - </CTableRow> - </CTableBody>, - { - container: document.body.appendChild(table), - }, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('table-info') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/table/__tests__/CTableCaption.spec.tsx b/packages/coreui-react/src/components/table/__tests__/CTableCaption.spec.tsx deleted file mode 100644 index ec27253b..00000000 --- a/packages/coreui-react/src/components/table/__tests__/CTableCaption.spec.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CTableCaption } from '../../../index' - -test('loads and displays CTableCaption component', async () => { - const table = document.createElement('table') - const { container } = render(<CTableCaption />, { - container: document.body.appendChild(table), - }) - expect(container).toMatchSnapshot() -}) - -test('CTableCaption customize', async () => { - const table = document.createElement('table') - const { container } = render(<CTableCaption>Test</CTableCaption>, { - container: document.body.appendChild(table), - }) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/table/__tests__/CTableDataCell.spec.tsx b/packages/coreui-react/src/components/table/__tests__/CTableDataCell.spec.tsx deleted file mode 100644 index c939f3d1..00000000 --- a/packages/coreui-react/src/components/table/__tests__/CTableDataCell.spec.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CTableDataCell } from '../../../index' -import { CTableBody } from '../CTableBody' -import { CTableRow } from '../CTableRow' - -test('loads and displays CTableDataCell component', async () => { - const table = document.createElement('table') - const { container } = render( - <CTableBody> - <CTableRow> - <CTableDataCell /> - </CTableRow> - </CTableBody>, - { - container: document.body.appendChild(table), - }, - ) - expect(container).toMatchSnapshot() -}) - -test('CTableDataCell customize', async () => { - const table = document.createElement('table') - const { container } = render( - <CTableBody> - <CTableRow> - <CTableDataCell className="bazinga" active={true} align="middle" color="info"> - Test - </CTableDataCell> - </CTableRow> - </CTableBody>, - { - container: document.body.appendChild(table), - }, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild?.firstChild?.firstChild).toHaveClass('align-middle') - expect(container.firstChild?.firstChild?.firstChild).toHaveClass('table-active') - expect(container.firstChild?.firstChild?.firstChild).toHaveClass('table-info') - expect(container.firstChild?.firstChild?.firstChild).toHaveClass('bazinga') - expect(container.firstChild?.firstChild?.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/table/__tests__/CTableFoot.spec.tsx b/packages/coreui-react/src/components/table/__tests__/CTableFoot.spec.tsx deleted file mode 100644 index 8f4f2972..00000000 --- a/packages/coreui-react/src/components/table/__tests__/CTableFoot.spec.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CTableFoot, CTableHeaderCell, CTableRow } from '../../../index' - -test('loads and displays CTableFoot component', async () => { - const table = document.createElement('table') - const { container } = render(<CTableFoot />, { - container: document.body.appendChild(table), - }) - expect(container).toMatchSnapshot() -}) - -test('CTableFoot customize', async () => { - const table = document.createElement('table') - const { container } = render( - <CTableFoot className="bazinga" color="info"> - <CTableRow> - <CTableHeaderCell>Test</CTableHeaderCell> - </CTableRow> - </CTableFoot>, - { - container: document.body.appendChild(table), - }, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('table-info') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild?.firstChild?.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/table/__tests__/CTableHead.spec.tsx b/packages/coreui-react/src/components/table/__tests__/CTableHead.spec.tsx deleted file mode 100644 index 0802198e..00000000 --- a/packages/coreui-react/src/components/table/__tests__/CTableHead.spec.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CTableHead, CTableHeaderCell, CTableRow } from '../../../index' - -test('loads and displays CTableHead component', async () => { - const table = document.createElement('table') - const { container } = render(<CTableHead />, { - container: document.body.appendChild(table), - }) - expect(container).toMatchSnapshot() -}) - -test('CTableHead customize', async () => { - const table = document.createElement('table') - const { container } = render( - <CTableHead className="bazinga" color="info"> - <CTableRow> - <CTableHeaderCell>Test</CTableHeaderCell> - </CTableRow> - </CTableHead>, - { - container: document.body.appendChild(table), - }, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('table-info') - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild?.firstChild?.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/table/__tests__/CTableHeaderCell.spec.tsx b/packages/coreui-react/src/components/table/__tests__/CTableHeaderCell.spec.tsx deleted file mode 100644 index b2aba0c6..00000000 --- a/packages/coreui-react/src/components/table/__tests__/CTableHeaderCell.spec.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CTableHead, CTableHeaderCell, CTableRow } from '../../../index' - -test('loads and displays CTableHeaderCell component', async () => { - const table = document.createElement('table') - const { container } = render( - <CTableHead> - <CTableRow> - <CTableHeaderCell /> - </CTableRow> - </CTableHead>, - { - container: document.body.appendChild(table), - }, - ) - expect(container).toMatchSnapshot() -}) - -test('CTableHeaderCell customize', async () => { - const table = document.createElement('table') - const { container } = render( - <CTableHead> - <CTableRow> - <CTableHeaderCell className="bazinga" color="info"> - Test - </CTableHeaderCell> - </CTableRow> - </CTableHead>, - { - container: document.body.appendChild(table), - }, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild?.firstChild?.firstChild).toHaveClass('table-info') - expect(container.firstChild?.firstChild?.firstChild).toHaveClass('bazinga') - expect(container.firstChild?.firstChild?.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/table/__tests__/CTableRow.spec.tsx b/packages/coreui-react/src/components/table/__tests__/CTableRow.spec.tsx deleted file mode 100644 index cfbeabc1..00000000 --- a/packages/coreui-react/src/components/table/__tests__/CTableRow.spec.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CTableBody, CTableHeaderCell, CTableRow } from '../../../index' - -test('loads and displays CTableRow component', async () => { - const table = document.createElement('table') - const { container } = render( - <CTableBody> - <CTableRow /> - </CTableBody>, - { - container: document.body.appendChild(table), - }, - ) - expect(container).toMatchSnapshot() -}) - -test('CTableRow customize', async () => { - const table = document.createElement('table') - const { container } = render( - <CTableBody> - <CTableRow className="bazinga" active={true} align="middle" color="info"> - <CTableHeaderCell>Test</CTableHeaderCell> - </CTableRow> - </CTableBody>, - { - container: document.body.appendChild(table), - }, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild?.firstChild).toHaveClass('align-middle') - expect(container.firstChild?.firstChild).toHaveClass('table-active') - expect(container.firstChild?.firstChild).toHaveClass('table-info') - expect(container.firstChild?.firstChild).toHaveClass('bazinga') - expect(container.firstChild?.firstChild?.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTable.spec.tsx.snap b/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTable.spec.tsx.snap deleted file mode 100644 index 7ca926fe..00000000 --- a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTable.spec.tsx.snap +++ /dev/null @@ -1,197 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CTable customize 1`] = ` -<div> - <div - class="table-responsive-xl" - > - <table - class="table align-middle border-primary caption-top table-bordered table-borderless table-info table-hover table-sm table-striped bazinga" - > - <tbody> - <tr> - <td> - Test - </td> - </tr> - </tbody> - </table> - </div> -</div> -`; - -exports[`CTable full example test 1`] = ` -<div> - <table - class="table caption-top" - > - <caption> - List of users - </caption> - <thead> - <tr> - <th> - # - </th> - <th> - Class - </th> - <th> - Heading - </th> - <th> - Heading - </th> - </tr> - </thead> - <tbody> - <tr> - <th> - 1 - </th> - <td> - Mark - </td> - <td> - Otto - </td> - <td> - @mdo - </td> - </tr> - <tr> - <th> - 2 - </th> - <td> - Jacob - </td> - <td> - Thornton - </td> - <td> - @fat - </td> - </tr> - <tr> - <th> - 3 - </th> - <td> - Larry - </td> - <td> - the Bird - </td> - <td> - @twitter - </td> - </tr> - </tbody> - <tfoot> - <tr> - <th> - # - </th> - <th> - Class - </th> - <th> - Heading - </th> - <th> - Heading - </th> - </tr> - </tfoot> - </table> -</div> -`; - -exports[`loads and displays CTable component - new way 1`] = ` -<div> - <table - class="table" - > - <thead> - <tr> - <th - scope="col" - > - # - </th> - <th> - Class - </th> - <th - scope="col" - > - Heading - </th> - <th - scope="col" - > - Heading - </th> - </tr> - </thead> - <tbody> - <tr> - <th - scope="row" - > - 1 - </th> - <td> - Mark - </td> - <td> - Otto - </td> - <td> - @mdo - </td> - </tr> - <tr> - <th - scope="row" - > - 2 - </th> - <td> - Jacob - </td> - <td> - Thornton - </td> - <td> - @fat - </td> - </tr> - <tr> - <th - scope="row" - > - 3 - </th> - <td - colspan="2" - > - Larry the Bird - </td> - <td> - @twitter - </td> - </tr> - </tbody> - </table> -</div> -`; - -exports[`loads and displays CTable component 1`] = ` -<div> - <table - class="table" - /> -</div> -`; diff --git a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableBody.spec.tsx.snap b/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableBody.spec.tsx.snap deleted file mode 100644 index 78a587ba..00000000 --- a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableBody.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CTableBody customize 1`] = ` -<table> - <tbody - class="table-info bazinga" - > - <tr> - <td> - Test - </td> - </tr> - </tbody> -</table> -`; - -exports[`loads and displays CTableBody component 1`] = ` -<table> - <tbody /> -</table> -`; diff --git a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableCaption.spec.tsx.snap b/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableCaption.spec.tsx.snap deleted file mode 100644 index f18f9542..00000000 --- a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableCaption.spec.tsx.snap +++ /dev/null @@ -1,15 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CTableCaption customize 1`] = ` -<table> - <caption> - Test - </caption> -</table> -`; - -exports[`loads and displays CTableCaption component 1`] = ` -<table> - <caption /> -</table> -`; diff --git a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableDataCell.spec.tsx.snap b/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableDataCell.spec.tsx.snap deleted file mode 100644 index 980aef89..00000000 --- a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableDataCell.spec.tsx.snap +++ /dev/null @@ -1,25 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CTableDataCell customize 1`] = ` -<table> - <tbody> - <tr> - <td - class="align-middle table-active table-info bazinga" - > - Test - </td> - </tr> - </tbody> -</table> -`; - -exports[`loads and displays CTableDataCell component 1`] = ` -<table> - <tbody> - <tr> - <td /> - </tr> - </tbody> -</table> -`; diff --git a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableFoot.spec.tsx.snap b/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableFoot.spec.tsx.snap deleted file mode 100644 index 61e932a2..00000000 --- a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableFoot.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CTableFoot customize 1`] = ` -<table> - <tfoot - class="table-info bazinga" - > - <tr> - <th> - Test - </th> - </tr> - </tfoot> -</table> -`; - -exports[`loads and displays CTableFoot component 1`] = ` -<table> - <tfoot /> -</table> -`; diff --git a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableHead.spec.tsx.snap b/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableHead.spec.tsx.snap deleted file mode 100644 index 40222dad..00000000 --- a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableHead.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CTableHead customize 1`] = ` -<table> - <thead - class="table-info bazinga" - > - <tr> - <th> - Test - </th> - </tr> - </thead> -</table> -`; - -exports[`loads and displays CTableHead component 1`] = ` -<table> - <thead /> -</table> -`; diff --git a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableHeaderCell.spec.tsx.snap b/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableHeaderCell.spec.tsx.snap deleted file mode 100644 index 8db8ce9b..00000000 --- a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableHeaderCell.spec.tsx.snap +++ /dev/null @@ -1,25 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CTableHeaderCell customize 1`] = ` -<table> - <thead> - <tr> - <th - class="table-info bazinga" - > - Test - </th> - </tr> - </thead> -</table> -`; - -exports[`loads and displays CTableHeaderCell component 1`] = ` -<table> - <thead> - <tr> - <th /> - </tr> - </thead> -</table> -`; diff --git a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableRow.spec.tsx.snap b/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableRow.spec.tsx.snap deleted file mode 100644 index b787bec4..00000000 --- a/packages/coreui-react/src/components/table/__tests__/__snapshots__/CTableRow.spec.tsx.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CTableRow customize 1`] = ` -<table> - <tbody> - <tr - class="align-middle table-active table-info bazinga" - > - <th> - Test - </th> - </tr> - </tbody> -</table> -`; - -exports[`loads and displays CTableRow component 1`] = ` -<table> - <tbody> - <tr /> - </tbody> -</table> -`; diff --git a/packages/coreui-react/src/components/table/index.ts b/packages/coreui-react/src/components/table/index.ts deleted file mode 100644 index 8263b6b5..00000000 --- a/packages/coreui-react/src/components/table/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { CTable } from './CTable' -import { CTableBody } from './CTableBody' -import { CTableCaption } from './CTableCaption' -import { CTableDataCell } from './CTableDataCell' -import { CTableFoot } from './CTableFoot' -import { CTableHead } from './CTableHead' -import { CTableHeaderCell } from './CTableHeaderCell' -import { CTableRow } from './CTableRow' - -export { - CTable, - CTableBody, - CTableCaption, - CTableDataCell, - CTableFoot, - CTableHead, - CTableHeaderCell, - CTableRow, -} diff --git a/packages/coreui-react/src/components/table/types.ts b/packages/coreui-react/src/components/table/types.ts deleted file mode 100644 index c8262797..00000000 --- a/packages/coreui-react/src/components/table/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { CTableDataCellProps } from '../table/CTableDataCell' -import { CTableHeaderCellProps } from '../table/CTableHeaderCell' -import { CTableRowProps } from '../table/CTableRow' - -export type Column = { - label?: string - key: string - _style?: any - _props?: CTableHeaderCellProps -} - -export type FooterItem = { - label?: string - _props?: CTableDataCellProps -} - -export type Item = { - [key: string]: number | string | any - _props?: CTableRowProps -} diff --git a/packages/coreui-react/src/components/table/utils.ts b/packages/coreui-react/src/components/table/utils.ts deleted file mode 100644 index 9c55ade1..00000000 --- a/packages/coreui-react/src/components/table/utils.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { Column, Item } from './types' - -export const pretifyName = (name: string) => { - return name - .replace(/[-_.]/g, ' ') - .replace(/ +/g, ' ') - .replace(/([a-z0-9])([A-Z])/g, '$1 $2') - .split(' ') - .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) - .join(' ') -} - -export const getColumnLabel = (column: Column | string) => - typeof column === 'object' ? column.label ?? pretifyName(column.key) : pretifyName(column) - -export const getColumnNames = (columns: (string | Column)[] | undefined, items?: Item[]) => - columns - ? columns.map((column: Column | string) => { - return typeof column === 'object' ? column.key : column - }) - : items && getColumnNamesFromItems(items) - -export const getColumnNamesFromItems = (items: Item[]) => - Object.keys(items[0] || {}).filter((el) => el.charAt(0) !== '_') diff --git a/packages/coreui-react/src/components/tabs/CTabContent.tsx b/packages/coreui-react/src/components/tabs/CTabContent.tsx deleted file mode 100644 index 860ad22c..00000000 --- a/packages/coreui-react/src/components/tabs/CTabContent.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { HTMLAttributes, forwardRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CTabContentProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CTabContent = forwardRef<HTMLDivElement, CTabContentProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('tab-content', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -CTabContent.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CTabContent.displayName = 'CTabContent' diff --git a/packages/coreui-react/src/components/tabs/CTabPane.tsx b/packages/coreui-react/src/components/tabs/CTabPane.tsx deleted file mode 100644 index 7d66be7f..00000000 --- a/packages/coreui-react/src/components/tabs/CTabPane.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React, { HTMLAttributes, forwardRef, useRef } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' -import { Transition } from 'react-transition-group' - -import { useForkedRef } from '../../hooks' - -export interface CTabPaneProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Callback fired when the component requests to be hidden. - */ - onHide?: () => void - /** - * Callback fired when the component requests to be shown. - */ - onShow?: () => void - /** - * Toggle the visibility of component. - */ - visible?: boolean -} - -export const CTabPane = forwardRef<HTMLDivElement, CTabPaneProps>( - ({ children, className, onHide, onShow, visible, ...rest }, ref) => { - const tabPaneRef = useRef() - const forkedRef = useForkedRef(ref, tabPaneRef) - - return ( - <Transition in={visible} nodeRef={tabPaneRef} onEnter={onShow} onExit={onHide} timeout={150}> - {(state) => ( - <div - className={classNames( - 'tab-pane', - 'fade', - { - active: visible, - show: state === 'entered', - }, - className, - )} - {...rest} - ref={forkedRef} - > - {children} - </div> - )} - </Transition> - ) - }, -) - -CTabPane.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - onHide: PropTypes.func, - onShow: PropTypes.func, - visible: PropTypes.bool, -} - -CTabPane.displayName = 'CTabPane' diff --git a/packages/coreui-react/src/components/tabs/__tests__/CTabContent.spec.tsx b/packages/coreui-react/src/components/tabs/__tests__/CTabContent.spec.tsx deleted file mode 100644 index 5e465cc4..00000000 --- a/packages/coreui-react/src/components/tabs/__tests__/CTabContent.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CTabContent } from '../../../index' - -test('loads and displays CTabContent component', async () => { - const { container } = render(<CTabContent>Test</CTabContent>) - expect(container).toMatchSnapshot() -}) - -test('CTabContent customize', async () => { - const { container } = render(<CTabContent className="bazinga">Test</CTabContent>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('tab-content') -}) diff --git a/packages/coreui-react/src/components/tabs/__tests__/CTabPane.spec.tsx b/packages/coreui-react/src/components/tabs/__tests__/CTabPane.spec.tsx deleted file mode 100644 index 92a6e688..00000000 --- a/packages/coreui-react/src/components/tabs/__tests__/CTabPane.spec.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import * as React from 'react' -import { render, screen } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CTabPane, CTabContent } from '../../../index' - -test('loads and displays CTabPane component', async () => { - const { container } = render(<CTabPane>Test</CTabPane>) - expect(container).toMatchSnapshot() -}) - -test('CTabPane customize', async () => { - const { container } = render( - <CTabPane className="bazinga" visible={true}> - Test - </CTabPane>, - ) - expect(container).toMatchSnapshot() -}) - -test('CTabContent use case test', async () => { - const { rerender } = render( - <CTabContent> - <CTabPane visible={false}>Test</CTabPane> - </CTabContent>, - ) - expect(screen.getByText('Test')).not.toHaveClass('show') - expect(screen.getByText('Test')).not.toHaveClass('active') - rerender( - <CTabContent> - <CTabPane visible={true}>Test</CTabPane> - </CTabContent>, - ) - expect(screen.getByText('Test')).not.toHaveClass('show') - expect(screen.getByText('Test')).toHaveClass('active') - await new Promise((r) => setTimeout(r, 1000)) - expect(screen.getByText('Test')).toHaveClass('show') - expect(screen.getByText('Test')).toHaveClass('active') - rerender( - <CTabContent> - <CTabPane visible={false}>Test</CTabPane> - </CTabContent>, - ) - expect(screen.getByText('Test')).not.toHaveClass('show') - expect(screen.getByText('Test')).not.toHaveClass('active') - await new Promise((r) => setTimeout(r, 1000)) - expect(screen.getByText('Test')).not.toHaveClass('show') - expect(screen.getByText('Test')).not.toHaveClass('active') -}) diff --git a/packages/coreui-react/src/components/tabs/__tests__/__snapshots__/CTabContent.spec.tsx.snap b/packages/coreui-react/src/components/tabs/__tests__/__snapshots__/CTabContent.spec.tsx.snap deleted file mode 100644 index b756cf73..00000000 --- a/packages/coreui-react/src/components/tabs/__tests__/__snapshots__/CTabContent.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CTabContent customize 1`] = ` -<div> - <div - class="tab-content bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CTabContent component 1`] = ` -<div> - <div - class="tab-content" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/tabs/__tests__/__snapshots__/CTabPane.spec.tsx.snap b/packages/coreui-react/src/components/tabs/__tests__/__snapshots__/CTabPane.spec.tsx.snap deleted file mode 100644 index a1127e85..00000000 --- a/packages/coreui-react/src/components/tabs/__tests__/__snapshots__/CTabPane.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CTabPane customize 1`] = ` -<div> - <div - class="tab-pane fade active show bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CTabPane component 1`] = ` -<div> - <div - class="tab-pane fade" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/tabs/index.ts b/packages/coreui-react/src/components/tabs/index.ts deleted file mode 100644 index 1962780c..00000000 --- a/packages/coreui-react/src/components/tabs/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { CTabContent } from './CTabContent' -import { CTabPane } from './CTabPane' - -export { CTabContent, CTabPane } diff --git a/packages/coreui-react/src/components/toast/CToast.tsx b/packages/coreui-react/src/components/toast/CToast.tsx deleted file mode 100644 index 449daaea..00000000 --- a/packages/coreui-react/src/components/toast/CToast.tsx +++ /dev/null @@ -1,172 +0,0 @@ -import React, { - createContext, - forwardRef, - HTMLAttributes, - useEffect, - useRef, - useState, -} from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' -import { Transition } from 'react-transition-group' - -import { useForkedRef } from '../../hooks' -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> { - /** - * Apply a CSS fade transition to the toast. - */ - animation?: boolean - /** - * Auto hide the toast. - */ - autohide?: boolean - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Delay hiding the toast (ms). - */ - delay?: number - /** - * @ignore - */ - index?: number - /** - * @ignore - */ - key?: number - /** - * Callback fired when the component requests to be closed. - */ - onClose?: (index: number | null) => void - /** - * Callback fired when the component requests to be shown. - */ - onShow?: (index: number | null) => void - /** - * Toggle the visibility of component. - */ - visible?: boolean -} - -interface ContextProps extends CToastProps { - visible?: boolean - setVisible: React.Dispatch<React.SetStateAction<boolean | undefined>> -} - -export const CToastContext = createContext({} as ContextProps) - -export const CToast = forwardRef<HTMLDivElement, CToastProps>( - ( - { - children, - animation = true, - autohide = true, - className, - color, - delay = 5000, - index, - key, - visible = false, - onClose, - onShow, - ...rest - }, - ref, - ) => { - const toastRef = useRef() - const forkedRef = useForkedRef(ref, toastRef) - const [_visible, setVisible] = useState(false) - const timeout = useRef<number>() - - useEffect(() => { - setVisible(visible) - }, [visible]) - - const contextValues = { - visible: _visible, - setVisible, - } - - // triggered on mount and destroy - useEffect(() => () => clearTimeout(timeout.current), []) - - useEffect(() => { - _autohide() - }, [_visible]) - - const _autohide = () => { - if (autohide) { - clearTimeout(timeout.current) - timeout.current = window.setTimeout(() => { - setVisible(false) - }, delay) - } - } - - return ( - <Transition - in={_visible} - nodeRef={toastRef} - onEnter={() => onShow && onShow(index ?? null)} - onExited={() => onClose && onClose(index ?? null)} - timeout={250} - unmountOnExit - > - {(state) => ( - <CToastContext.Provider value={contextValues}> - <div - className={classNames( - 'toast', - { - fade: animation, - [`bg-${color}`]: color, - 'border-0': color, - 'show showing': state === 'entering' || state === 'exiting', - show: state === 'entered', - }, - className, - )} - aria-live="assertive" - aria-atomic="true" - role="alert" - onMouseEnter={() => clearTimeout(timeout.current)} - onMouseLeave={() => _autohide()} - {...rest} - key={key} - ref={forkedRef} - > - {children} - </div> - </CToastContext.Provider> - )} - </Transition> - ) - }, -) - -CToast.propTypes = { - animation: PropTypes.bool, - autohide: PropTypes.bool, - children: PropTypes.node, - className: PropTypes.string, - color: colorPropType, - delay: PropTypes.number, - index: PropTypes.number, - key: PropTypes.number, - onClose: PropTypes.func, - onShow: PropTypes.func, - visible: PropTypes.bool, -} - -CToast.displayName = 'CToast' diff --git a/packages/coreui-react/src/components/toast/CToastBody.tsx b/packages/coreui-react/src/components/toast/CToastBody.tsx deleted file mode 100644 index 7bd332e7..00000000 --- a/packages/coreui-react/src/components/toast/CToastBody.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -export interface CToastBodyProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string -} - -export const CToastBody = forwardRef<HTMLDivElement, CToastBodyProps>( - ({ children, className, ...rest }, ref) => { - return ( - <div className={classNames('toast-body', className)} {...rest} ref={ref}> - {children} - </div> - ) - }, -) - -CToastBody.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -} - -CToastBody.displayName = 'CToastBody' diff --git a/packages/coreui-react/src/components/toast/CToastClose.tsx b/packages/coreui-react/src/components/toast/CToastClose.tsx deleted file mode 100644 index 6efb6f69..00000000 --- a/packages/coreui-react/src/components/toast/CToastClose.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { ElementType, forwardRef, useContext } from 'react' -import PropTypes from 'prop-types' - -import { CButtonProps } from '../button/CButton' -import { CCloseButton, CCloseButtonProps } from '../close-button/CCloseButton' - -import { CToastContext } from './CToast' - -type CombineButtonProps = CCloseButtonProps & CButtonProps - -export interface CToastCloseProps extends CombineButtonProps { - /** - * Component used for the root node. Either a string to use a HTML element or a component. - */ - component?: string | ElementType -} - -export const CToastClose = forwardRef<HTMLButtonElement, CToastCloseProps>( - ({ children, component: Component, ...rest }, ref) => { - const { setVisible } = useContext(CToastContext) - return Component ? ( - <Component onClick={() => setVisible(false)} {...rest} ref={ref}> - {children} - </Component> - ) : ( - <CCloseButton onClick={() => setVisible(false)} {...rest} ref={ref} /> - ) - }, -) - -CToastClose.propTypes = { - ...CCloseButton.propTypes, - component: PropTypes.elementType, -} - -CToastClose.displayName = 'CToastClose' diff --git a/packages/coreui-react/src/components/toast/CToastHeader.tsx b/packages/coreui-react/src/components/toast/CToastHeader.tsx deleted file mode 100644 index 01cb8e84..00000000 --- a/packages/coreui-react/src/components/toast/CToastHeader.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React, { forwardRef, HTMLAttributes } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CToastClose } from './CToastClose' - -export interface CToastHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Automatically add a close button to the header. - */ - closeButton?: boolean -} - -export const CToastHeader = forwardRef<HTMLDivElement, CToastHeaderProps>( - ({ children, className, closeButton, ...rest }, ref) => { - return ( - <div className={classNames('toast-header', className)} {...rest} ref={ref}> - {children} - {closeButton && <CToastClose />} - </div> - ) - }, -) - -CToastHeader.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - closeButton: PropTypes.bool, -} - -CToastHeader.displayName = 'CToastHeader' diff --git a/packages/coreui-react/src/components/toast/CToaster.tsx b/packages/coreui-react/src/components/toast/CToaster.tsx deleted file mode 100644 index e7d41e76..00000000 --- a/packages/coreui-react/src/components/toast/CToaster.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import React, { forwardRef, HTMLAttributes, useEffect, useState, useRef, ReactElement } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' -import { CConditionalPortal } from '../conditional-portal' - -export interface CToasterProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Describes the placement of your component. - * - * @type 'top-start' | 'top' | 'top-end' | 'middle-start' | 'middle' | 'middle-end' | 'bottom-start' | 'bottom' | 'bottom-end' | string - */ - placement?: - | 'top-start' - | 'top-center' - | 'top-end' - | 'middle-start' - | 'middle-center' - | 'middle-end' - | 'bottom-start' - | 'bottom-center' - | 'bottom-end' - | string - /** - * Adds new `CToast` to `CToaster`. - */ - push?: ReactElement -} - -export const CToaster = forwardRef<HTMLDivElement, CToasterProps>( - ({ children, className, placement, push, ...rest }, ref) => { - const [toasts, setToasts] = useState<ReactElement[]>([]) - const index = useRef<number>(0) - - useEffect(() => { - index.current++ - push && addToast(push) - }, [push]) - - const addToast = (push: ReactElement) => { - setToasts((state) => [ - ...state, - React.cloneElement(push, { - index: index.current, - key: index.current, - onClose: (index: number) => - setToasts((state) => state.filter((i) => i.props.index !== index)), - }), - ]) - } - - return ( - <CConditionalPortal portal={typeof placement === 'string'}> - {toasts.length > 0 || children ? ( - <div - className={classNames( - 'toaster toast-container', - { - 'position-fixed': placement, - 'top-0': placement && placement.includes('top'), - 'top-50 translate-middle-y': placement && placement.includes('middle'), - 'bottom-0': placement && placement.includes('bottom'), - 'start-0': placement && placement.includes('start'), - 'start-50 translate-middle-x': placement && placement.includes('center'), - 'end-0': placement && placement.includes('end'), - }, - className, - )} - {...rest} - ref={ref} - > - {children} - {toasts.map((toast) => React.cloneElement(toast, { visible: true }))} - </div> - ) : null} - </CConditionalPortal> - ) - }, -) - -CToaster.propTypes = { - children: PropTypes.node, - className: PropTypes.string, - placement: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.oneOf([ - 'top-start', - 'top-center', - 'top-end', - 'middle-start', - 'middle-center', - 'middle-end', - 'bottom-start', - 'bottom-center', - 'bottom-end', - ]), - ]), - push: PropTypes.any, -} - -CToaster.displayName = 'CToaster' diff --git a/packages/coreui-react/src/components/toast/__tests__/CToast.spec.tsx b/packages/coreui-react/src/components/toast/__tests__/CToast.spec.tsx deleted file mode 100644 index ba387d70..00000000 --- a/packages/coreui-react/src/components/toast/__tests__/CToast.spec.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import * as React from 'react' -import { render, fireEvent, waitFor } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CToast, CToastBody, CToastHeader } from '../../../index' - -test('loads and displays CToast component', async () => { - const { container } = render(<CToast>Test</CToast>) - expect(container).toMatchSnapshot() -}) - -test('CToast customize', async () => { - const { container } = render( - <CToast - className="bazinga" - autohide={false} - color="warning" - delay={100} - visible={true} - //onClose - > - Test - </CToast>, - ) - await waitFor(() => { - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('toast') - expect(container.firstChild).toHaveClass('fade') - expect(container.firstChild).toHaveClass('bg-warning') - expect(container.firstChild).toHaveClass('show') - }) -}) - -test('CToast click on dismiss button', async () => { - // jest.useFakeTimers() - const onClose = jest.fn() - const { container } = render( - <CToast - className="bazinga" - autohide={false} - color="warning" - delay={100} - visible={true} - onClose={onClose} - > - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <strong className="me-auto">CoreUI for React.js</strong> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - </CToast>, - ) - await waitFor(() => { - expect(container.firstChild).toHaveClass('show') - }) - - expect(onClose).toHaveBeenCalledTimes(0) - const btn = document.querySelector('.btn-close') - if (btn !== null) { - fireEvent.click(btn) - } - jest.runAllTimers() - await new Promise((r) => setTimeout(r, 1000)) - expect(onClose).toHaveBeenCalledTimes(1) - expect(container.firstChild).toBeNull() - jest.useRealTimers() -}) - -test('CToast test autohide', async () => { - const { container } = render( - <CToast autohide={true} delay={1000} visible={true}> - Test - </CToast>, - ) - - await waitFor(() => { - expect(container.firstChild).toHaveClass('show') - }) - - await waitFor( - () => { - expect(container.firstChild).toBeNull() - }, - { - timeout: 5000, - }, - ) -}) diff --git a/packages/coreui-react/src/components/toast/__tests__/CToastBody.spec.tsx b/packages/coreui-react/src/components/toast/__tests__/CToastBody.spec.tsx deleted file mode 100644 index 804b98ca..00000000 --- a/packages/coreui-react/src/components/toast/__tests__/CToastBody.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CToastBody } from '../../../index' - -test('loads and displays CToastBody component', async () => { - const { container } = render(<CToastBody>Test</CToastBody>) - expect(container).toMatchSnapshot() -}) - -test('CToastBody customize', async () => { - const { container } = render(<CToastBody className="bazinga">Test</CToastBody>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('toast-body') -}) diff --git a/packages/coreui-react/src/components/toast/__tests__/CToastHeader.spec.tsx b/packages/coreui-react/src/components/toast/__tests__/CToastHeader.spec.tsx deleted file mode 100644 index 5939f62d..00000000 --- a/packages/coreui-react/src/components/toast/__tests__/CToastHeader.spec.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CToastHeader } from '../../../index' - -test('loads and displays CToastHeader component', async () => { - const { container } = render(<CToastHeader>Test</CToastHeader>) - expect(container).toMatchSnapshot() -}) - -test('CToastHeader customize', async () => { - const { container } = render(<CToastHeader className="bazinga">Test</CToastHeader>) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('toast-header') -}) diff --git a/packages/coreui-react/src/components/toast/__tests__/CToaster.spec.tsx b/packages/coreui-react/src/components/toast/__tests__/CToaster.spec.tsx deleted file mode 100644 index 342edd39..00000000 --- a/packages/coreui-react/src/components/toast/__tests__/CToaster.spec.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react' // useState, -import { render, fireEvent } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CToast, CToaster, CToastBody, CToastHeader, CButton } from '../../../index' - -test('loads and displays CToaster component', async () => { - const { container } = render(<CToaster>Test</CToaster>) - expect(container).toMatchSnapshot() -}) - -test('CToaster customize', async () => { - jest.useFakeTimers() - let toast = <></> - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const addToast = function (t: any) { - toast = t - } - const { container } = render( - <> - <CToaster push={toast} className="bazinga" /> - <CButton - onClick={() => - addToast( - <> - <CToast autohide={false}> - <CToastHeader closeButton>Lorem ipsum</CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - </CToast> - </>, - ) - } - > - Send a toast - </CButton> - </>, - ) - expect(container).toMatchSnapshot() - const btn = document.querySelector('.btn') - if (btn !== null) { - fireEvent.click(btn) - } - jest.runAllTimers() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('toaster') - expect(container.firstChild).toHaveClass('toast-container') - jest.useRealTimers() -}) diff --git a/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToast.spec.tsx.snap b/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToast.spec.tsx.snap deleted file mode 100644 index 77934504..00000000 --- a/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToast.spec.tsx.snap +++ /dev/null @@ -1,16 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CToast customize 1`] = ` -<div> - <div - aria-atomic="true" - aria-live="assertive" - class="toast fade bg-warning border-0 show showing bazinga" - role="alert" - > - Test - </div> -</div> -`; - -exports[`loads and displays CToast component 1`] = `<div />`; diff --git a/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToastBody.spec.tsx.snap b/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToastBody.spec.tsx.snap deleted file mode 100644 index 17be4222..00000000 --- a/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToastBody.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CToastBody customize 1`] = ` -<div> - <div - class="toast-body bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CToastBody component 1`] = ` -<div> - <div - class="toast-body" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToastHeader.spec.tsx.snap b/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToastHeader.spec.tsx.snap deleted file mode 100644 index d6346d24..00000000 --- a/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToastHeader.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CToastHeader customize 1`] = ` -<div> - <div - class="toast-header bazinga" - > - Test - </div> -</div> -`; - -exports[`loads and displays CToastHeader component 1`] = ` -<div> - <div - class="toast-header" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToaster.spec.tsx.snap b/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToaster.spec.tsx.snap deleted file mode 100644 index f4c8f07d..00000000 --- a/packages/coreui-react/src/components/toast/__tests__/__snapshots__/CToaster.spec.tsx.snap +++ /dev/null @@ -1,25 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CToaster customize 1`] = ` -<div> - <div - class="toaster toast-container bazinga" - /> - <button - class="btn btn-primary" - type="button" - > - Send a toast - </button> -</div> -`; - -exports[`loads and displays CToaster component 1`] = ` -<div> - <div - class="toaster toast-container" - > - Test - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/toast/index.ts b/packages/coreui-react/src/components/toast/index.ts deleted file mode 100644 index 8a28699a..00000000 --- a/packages/coreui-react/src/components/toast/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { CToast } from './CToast' -import { CToastBody } from './CToastBody' -import { CToastClose } from './CToastClose' -import { CToastHeader } from './CToastHeader' -import { CToaster } from './CToaster' - -export { CToast, CToastBody, CToastClose, CToastHeader, CToaster } diff --git a/packages/coreui-react/src/components/tooltip/CTooltip.tsx b/packages/coreui-react/src/components/tooltip/CTooltip.tsx deleted file mode 100644 index fd29fccc..00000000 --- a/packages/coreui-react/src/components/tooltip/CTooltip.tsx +++ /dev/null @@ -1,227 +0,0 @@ -import React, { forwardRef, HTMLAttributes, ReactNode, useRef, useEffect, useState } from 'react' -import classNames from 'classnames' -import PropTypes from 'prop-types' -import { Transition } from 'react-transition-group' - -import { CConditionalPortal } from '../conditional-portal' -import { useForkedRef, usePopper } from '../../hooks' -import { fallbackPlacementsPropType, triggerPropType } from '../../props' -import type { Placements, Triggers } from '../../types' -import { getRTLPlacement, getTransitionDurationFromElement } from '../../utils' - -export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'content'> { - /** - * Apply a CSS fade transition to the tooltip. - * - * @since 4.9.0 - */ - animation?: boolean - /** - * A string of all className you want applied to the component. - */ - className?: string - /** - * Appends the react tooltip to a specific element. You can pass an HTML element or function that returns a single element. By default `document.body`. - * - * @since v4.11.0 - */ - container?: Element | (() => Element | null) | null - /** - * Content node for your component. - */ - content: ReactNode | string - /** - * The delay for displaying and hiding the tooltip (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`. - * - * @since 4.9.0 - */ - delay?: number | { show: number; hide: number } - /** - * Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference. - * - * @since 4.9.0 - */ - fallbackPlacements?: Placements | Placements[] - /** - * Offset of the tooltip relative to its target. - */ - offset?: [number, number] - /** - * Callback fired when the component requests to be hidden. - */ - onHide?: () => void - /** - * Callback fired when the component requests to be shown. - */ - onShow?: () => void - /** - * Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. - * - * @type 'hover' | 'focus' | 'click' - */ - trigger?: Triggers | Triggers[] - /** - * Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. - */ - placement?: 'auto' | 'top' | 'right' | 'bottom' | 'left' - /** - * Toggle the visibility of tooltip component. - */ - visible?: boolean -} - -export const CTooltip = forwardRef<HTMLDivElement, CTooltipProps>( - ( - { - children, - animation = true, - className, - container, - content, - delay = 0, - fallbackPlacements = ['top', 'right', 'bottom', 'left'], - offset = [0, 6], - onHide, - onShow, - placement = 'top', - trigger = ['hover', 'focus'], - visible, - ...rest - }, - ref, - ) => { - const tooltipRef = useRef(null) - const togglerRef = useRef(null) - const forkedRef = useForkedRef(ref, tooltipRef) - - const { initPopper, destroyPopper } = usePopper() - const [_visible, setVisible] = useState(visible) - - const _delay = typeof delay === 'number' ? { show: delay, hide: delay } : delay - - const popperConfig = { - modifiers: [ - { - name: 'arrow', - options: { - element: '.tooltip-arrow', - }, - }, - { - name: 'flip', - options: { - fallbackPlacements: fallbackPlacements, - }, - }, - { - name: 'offset', - options: { - offset: offset, - }, - }, - ], - placement: getRTLPlacement(placement, togglerRef.current), - } - - useEffect(() => { - setVisible(visible) - }, [visible]) - - useEffect(() => { - if (_visible && togglerRef.current && tooltipRef.current) { - initPopper(togglerRef.current, tooltipRef.current, popperConfig) - } - - return () => { - destroyPopper() - } - }, [_visible]) - - const toggleVisible = (visible: boolean) => { - if (visible) { - setTimeout(() => setVisible(true), _delay.show) - return - } - - setTimeout(() => setVisible(false), _delay.hide) - } - - return ( - <> - {React.cloneElement(children as React.ReactElement<any>, { - ref: togglerRef, - ...((trigger === 'click' || trigger.includes('click')) && { - onClick: () => toggleVisible(!_visible), - }), - ...((trigger === 'focus' || trigger.includes('focus')) && { - onFocus: () => toggleVisible(true), - onBlur: () => toggleVisible(false), - }), - ...((trigger === 'hover' || trigger.includes('hover')) && { - onMouseEnter: () => toggleVisible(true), - onMouseLeave: () => toggleVisible(false), - }), - })} - <CConditionalPortal container={container} portal={true}> - <Transition - in={_visible} - mountOnEnter - nodeRef={tooltipRef} - onEnter={onShow} - onExit={onHide} - timeout={{ - enter: 0, - exit: tooltipRef.current - ? getTransitionDurationFromElement(tooltipRef.current) + 50 - : 200, - }} - unmountOnExit - > - {(state) => ( - <div - className={classNames( - 'tooltip', - 'bs-tooltip-auto', - { - fade: animation, - show: state === 'entered', - }, - className, - )} - ref={forkedRef} - role="tooltip" - {...rest} - > - <div className="tooltip-arrow"></div> - <div className="tooltip-inner">{content}</div> - </div> - )} - </Transition> - </CConditionalPortal> - </> - ) - }, -) - -CTooltip.propTypes = { - animation: PropTypes.bool, - children: PropTypes.node, - container: PropTypes.any, - content: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - delay: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.shape({ - show: PropTypes.number.isRequired, - hide: PropTypes.number.isRequired, - }), - ]), - fallbackPlacements: fallbackPlacementsPropType, - offset: PropTypes.any, // TODO: find good proptype - onHide: PropTypes.func, - onShow: PropTypes.func, - placement: PropTypes.oneOf(['auto', 'top', 'right', 'bottom', 'left']), - trigger: triggerPropType, - visible: PropTypes.bool, -} - -CTooltip.displayName = 'CTooltip' diff --git a/packages/coreui-react/src/components/tooltip/__tests__/CTooltip.spec.tsx b/packages/coreui-react/src/components/tooltip/__tests__/CTooltip.spec.tsx deleted file mode 100644 index fa58d995..00000000 --- a/packages/coreui-react/src/components/tooltip/__tests__/CTooltip.spec.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import * as React from 'react' -import { act } from 'react-dom/test-utils' -import { fireEvent, render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CTooltip, CLink } from '../../../index' - -let container: HTMLDivElement | null - -beforeEach(() => { - container = document.createElement('div') - document.body.appendChild(container) -}) - -afterEach(() => { - container && container.remove() - container = null -}) - -test('loads and displays CTooltip component', async () => { - const { container } = render( - <CTooltip content="content"> - <CLink>Test</CLink> - </CTooltip>, - ) - expect(container).toMatchSnapshot() -}) - -test('CTooltip customize', async () => { - const { container } = render( - <CTooltip trigger="hover" placement="right" content="content"> - <CLink className="link">Test</CLink> - </CTooltip>, - ) - const link = document.querySelector('.link') - act(() => { - if (link !== null) { - fireEvent.mouseOver(link) - } - }) - expect(container).toMatchSnapshot() -}) - -// test('CTooltip on toggle', async () => { -// jest.useFakeTimers() -// const onToggle = jest.fn() -// render( -// <CTooltip -// trigger="click" -// placement="right-end" -// content="content" -// visible={true} -// onToggle={onToggle} -// > -// <CButton>Test</CButton> -// </CTooltip>, -// ) -// expect(onToggle).toHaveBeenCalledTimes(0) -// const btn = document.querySelector('.btn') -// if (btn !== null) { -// fireEvent.click(btn) -// } -// expect(onToggle).toHaveBeenCalledTimes(1) -// }) diff --git a/packages/coreui-react/src/components/tooltip/__tests__/__snapshots__/CTooltip.spec.tsx.snap b/packages/coreui-react/src/components/tooltip/__tests__/__snapshots__/CTooltip.spec.tsx.snap deleted file mode 100644 index ad0c7594..00000000 --- a/packages/coreui-react/src/components/tooltip/__tests__/__snapshots__/CTooltip.spec.tsx.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CTooltip customize 1`] = ` -<div> - <a - class="link" - > - Test - </a> -</div> -`; - -exports[`loads and displays CTooltip component 1`] = ` -<div> - <a - class="" - > - Test - </a> -</div> -`; diff --git a/packages/coreui-react/src/components/tooltip/index.ts b/packages/coreui-react/src/components/tooltip/index.ts deleted file mode 100644 index b3af8166..00000000 --- a/packages/coreui-react/src/components/tooltip/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CTooltip } from './CTooltip' - -export { CTooltip } diff --git a/packages/coreui-react/src/components/widgets/CWidgetStatsA.tsx b/packages/coreui-react/src/components/widgets/CWidgetStatsA.tsx deleted file mode 100644 index c19a5023..00000000 --- a/packages/coreui-react/src/components/widgets/CWidgetStatsA.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React, { forwardRef, HTMLAttributes, ReactNode } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CCard, CCardBody } from '../card' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CWidgetStatsAProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> { - /** - * Action node for your component. - */ - action?: ReactNode - /** - * Chart node for your component. - */ - chart?: string | ReactNode - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Title node for your component. - */ - title?: string | ReactNode - /** - * Value node for your component. - */ - value?: string | number | ReactNode -} - -export const CWidgetStatsA = forwardRef<HTMLDivElement, CWidgetStatsAProps>( - ({ action, chart, className, color, title, value, ...rest }, ref) => { - return ( - <CCard - className={classNames({ [`bg-${color}`]: color, 'text-white': color }, className)} - {...rest} - ref={ref} - > - <CCardBody className="pb-0 d-flex justify-content-between align-items-start"> - <div> - {value && <div className="fs-4 fw-semibold">{value}</div>} - {title && <div>{title}</div>} - </div> - {action} - </CCardBody> - {chart} - </CCard> - ) - }, -) - -CWidgetStatsA.propTypes = { - action: PropTypes.node, - chart: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - className: PropTypes.string, - color: colorPropType, - title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - value: PropTypes.oneOfType([PropTypes.string, PropTypes.node, PropTypes.number]), -} - -CWidgetStatsA.displayName = 'CWidgetStatsA' diff --git a/packages/coreui-react/src/components/widgets/CWidgetStatsB.tsx b/packages/coreui-react/src/components/widgets/CWidgetStatsB.tsx deleted file mode 100644 index 0308c901..00000000 --- a/packages/coreui-react/src/components/widgets/CWidgetStatsB.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import React, { forwardRef, HTMLAttributes, ReactNode } from 'react' -import PropTypes from 'prop-types' - -import { CCard, CCardBody } from '../card' -import { CProgress, CProgressProps } from '../progress/CProgress' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CWidgetStatsBProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Colors have been inverted from their default dark shade. - */ - inverse?: boolean - /** - * Sets the color context of the progress bar to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - progress?: CProgressProps - /** - * Title node for your component. - */ - title?: string | ReactNode - /** - * Helper text for your component. - */ - text?: string - /** - * Value node for your component. - */ - value?: string | number | ReactNode -} - -export const CWidgetStatsB = forwardRef<HTMLDivElement, CWidgetStatsBProps>( - ({ className, color, inverse, progress, text, title, value, ...rest }, ref) => { - return ( - <CCard - className={className} - color={color} - {...(inverse && { textColor: 'white' })} - {...rest} - ref={ref} - > - <CCardBody> - {value && <div className="fs-4 fw-semibold">{value}</div>} - {title && <div>{title}</div>} - <CProgress className="my-2" height={4} {...(inverse && { white: true })} {...progress} /> - {text && ( - <small className={inverse ? 'text-white text-opacity-75' : 'text-body-secondary'}> - {text} - </small> - )} - </CCardBody> - </CCard> - ) - }, -) - -CWidgetStatsB.propTypes = { - className: PropTypes.string, - color: colorPropType, - inverse: PropTypes.bool, - progress: PropTypes.object, - text: PropTypes.string, - title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - value: PropTypes.oneOfType([PropTypes.string, PropTypes.node, PropTypes.number]), -} - -CWidgetStatsB.displayName = 'CWidgetCWidgetStatsB' diff --git a/packages/coreui-react/src/components/widgets/CWidgetStatsC.tsx b/packages/coreui-react/src/components/widgets/CWidgetStatsC.tsx deleted file mode 100644 index f8cca9a7..00000000 --- a/packages/coreui-react/src/components/widgets/CWidgetStatsC.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import React, { forwardRef, HTMLAttributes, ReactNode } from 'react' -import PropTypes from 'prop-types' - -import { CCard, CCardBody } from '../card' -import { CProgress, CProgressProps } from '../progress/CProgress' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' -import classNames from 'classnames' - -export interface CWidgetStatsCProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Icon node for your component. - */ - icon?: string | ReactNode - /** - * Colors have been inverted from their default dark shade. - */ - inverse?: boolean - /** - * Sets the color context of the progress bar to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - progress?: CProgressProps - /** - * Title node for your component. - */ - title?: string | ReactNode - /** - * Value node for your component. - */ - value?: string | number | ReactNode -} - -export const CWidgetStatsC = forwardRef<HTMLDivElement, CWidgetStatsCProps>( - ({ className, color, icon, inverse, progress, title, value, ...rest }, ref) => { - return ( - <CCard - className={className} - color={color} - {...(inverse && { textColor: 'white' })} - {...rest} - ref={ref} - > - <CCardBody> - {icon && ( - <div - className={classNames( - 'text-end mb-4', - inverse ? 'text-white text-opacity-75' : 'text-body-secondary', - )} - > - {icon} - </div> - )} - {value && <div className="fs-4 fw-semibold">{value}</div>} - {title && ( - <div className={inverse ? 'text-white text-opacity-75' : 'text-body-secondary'}> - {title} - </div> - )} - <CProgress - className="mt-3 mb-0" - height={4} - {...(inverse && { white: true })} - {...progress} - /> - </CCardBody> - </CCard> - ) - }, -) - -CWidgetStatsC.propTypes = { - className: PropTypes.string, - color: colorPropType, - icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - inverse: PropTypes.bool, - progress: PropTypes.object, - title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - value: PropTypes.oneOfType([PropTypes.string, PropTypes.node, PropTypes.number]), -} - -CWidgetStatsC.displayName = 'CWidgetStatsCWidgetStatsC' diff --git a/packages/coreui-react/src/components/widgets/CWidgetStatsD.tsx b/packages/coreui-react/src/components/widgets/CWidgetStatsD.tsx deleted file mode 100644 index 44e089a7..00000000 --- a/packages/coreui-react/src/components/widgets/CWidgetStatsD.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import React, { forwardRef, HTMLAttributes, ReactNode } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CCard, CCardBody, CCardHeader } from '../card' -import { CCol } from '../grid/CCol' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -type Value = { - title?: string | ReactNode - value?: number | string | ReactNode -} - -export interface CWidgetStatsDProps extends HTMLAttributes<HTMLDivElement> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Chart node for your component. - */ - chart?: string | ReactNode - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Icon node for your component. - */ - icon?: string | ReactNode - /** - * Values and titles for your component. - */ - values?: Value[] -} - -export const CWidgetStatsD = forwardRef<HTMLDivElement, CWidgetStatsDProps>( - ({ className, chart, color, icon, values, ...rest }, ref) => { - return ( - <CCard className={className} {...rest} ref={ref}> - <CCardHeader - className={classNames( - 'position-relative d-flex justify-content-center align-items-center', - { - [`bg-${color}`]: color, - }, - )} - > - {icon} - {chart} - </CCardHeader> - <CCardBody className="row text-center"> - {values && - values.map((value: Value, index: number) => { - return ( - <React.Fragment key={index}> - {index % 2 !== 0 && <div className="vr"></div>} - <CCol> - <div className="fs-5 fw-semibold">{value.value}</div> - <div className="text-uppercase text-body-secondary small">{value.title}</div> - </CCol> - </React.Fragment> - ) - })} - </CCardBody> - </CCard> - ) - }, -) - -CWidgetStatsD.propTypes = { - chart: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - className: PropTypes.string, - color: colorPropType, - icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - values: PropTypes.arrayOf(PropTypes.any), -} - -CWidgetStatsD.displayName = 'CWidgetStatsD' diff --git a/packages/coreui-react/src/components/widgets/CWidgetStatsE.tsx b/packages/coreui-react/src/components/widgets/CWidgetStatsE.tsx deleted file mode 100644 index 7e04e0c3..00000000 --- a/packages/coreui-react/src/components/widgets/CWidgetStatsE.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, { forwardRef, HTMLAttributes, ReactNode } from 'react' -import PropTypes from 'prop-types' -import classNames from 'classnames' - -import { CCard, CCardBody } from '../card' - -export interface CWidgetStatsEProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Chart node for your component. - */ - chart?: string | ReactNode - /** - * Title node for your component. - */ - title?: string | ReactNode - /** - * Value node for your component. - */ - value?: string | number | ReactNode -} - -export const CWidgetStatsE = forwardRef<HTMLDivElement, CWidgetStatsEProps>( - ({ chart, className, title, value, ...rest }, ref) => { - return ( - <CCard className={classNames(className)} {...rest} ref={ref}> - <CCardBody className="text-center"> - {title && ( - <div className="text-body-secondary small text-uppercase fw-semibold">{title}</div> - )} - {value && <div className="fs-6 fw-semibold py-3">{value}</div>} - {chart} - </CCardBody> - </CCard> - ) - }, -) - -CWidgetStatsE.propTypes = { - children: PropTypes.node, - chart: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - className: PropTypes.string, - title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - value: PropTypes.oneOfType([PropTypes.string, PropTypes.node, PropTypes.number]), -} - -CWidgetStatsE.displayName = 'CWidgetStatsE' diff --git a/packages/coreui-react/src/components/widgets/CWidgetStatsF.tsx b/packages/coreui-react/src/components/widgets/CWidgetStatsF.tsx deleted file mode 100644 index 6684b286..00000000 --- a/packages/coreui-react/src/components/widgets/CWidgetStatsF.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React, { forwardRef, HTMLAttributes, ReactNode } from 'react' -import PropTypes from 'prop-types' - -import { CCard, CCardBody, CCardFooter } from '../card' - -import { colorPropType } from '../../props' -import type { Colors } from '../../types' - -export interface CWidgetStatsFProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> { - /** - * A string of all className you want applied to the base component. - */ - className?: string - /** - * Sets the color context of the component to one of CoreUI’s themed colors. - * - * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string - */ - color?: Colors - /** - * Footer node for your component. - */ - footer?: string | ReactNode - /** - * Icon node for your component. - */ - icon?: string | ReactNode - /** - * Set padding of your component. - */ - padding?: boolean - /** - * Title node for your component. - */ - title?: string | ReactNode - /** - * Value node for your component. - */ - value?: string | number | ReactNode -} - -export const CWidgetStatsF = forwardRef<HTMLDivElement, CWidgetStatsFProps>( - ({ className, color, footer, icon, padding = true, title, value, ...rest }, ref) => { - return ( - <CCard className={className} {...rest} ref={ref}> - <CCardBody className={`d-flex align-items-center ${padding === false && 'p-0'}`}> - <div className={`me-3 text-white bg-${color} ${padding ? 'p-3' : 'p-4'}`}>{icon}</div> - <div> - <div className={`fs-6 fw-semibold text-${color}`}>{value}</div> - <div className="text-body-secondary text-uppercase fw-semibold small">{title}</div> - </div> - </CCardBody> - {footer && <CCardFooter>{footer}</CCardFooter>} - </CCard> - ) - }, -) - -CWidgetStatsF.propTypes = { - className: PropTypes.string, - color: colorPropType, - footer: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - padding: PropTypes.bool, - title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), - value: PropTypes.oneOfType([PropTypes.string, PropTypes.node, PropTypes.number]), -} - -CWidgetStatsF.displayName = 'CWidgetStatsF' diff --git a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsA.spec.tsx b/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsA.spec.tsx deleted file mode 100644 index 1b59149d..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsA.spec.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CWidgetStatsA } from '../../../index' - -test('loads and displays CWidgetStatsA component', async () => { - const { container } = render(<CWidgetStatsA />) - expect(container).toMatchSnapshot() -}) - -test('CWidgetStatsA customize', async () => { - const { container } = render( - <CWidgetStatsA - className="bazinga" - action="action" - chart="chart" - color="info" - title="title" - value="value" - > - Test - </CWidgetStatsA>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bg-info') - expect(container.firstChild).toHaveClass('text-white') - expect(container.firstChild).toHaveClass('bazinga') - if (container.firstChild === null) { - expect(true).toBe(false) - } else { - expect(container.firstChild.firstChild).toHaveClass('pb-0') - expect(container.firstChild.firstChild).toHaveClass('d-flex') - expect(container.firstChild.firstChild).toHaveClass('justify-content-between') - expect(container.firstChild.firstChild).toHaveClass('align-items-start') - if ( - container.firstChild.firstChild === null || - container.firstChild.firstChild.firstChild === null - ) { - expect(true).toBe(false) - } else { - expect(container.firstChild.firstChild.firstChild.firstChild).toHaveClass('fs-4') - expect(container.firstChild.firstChild.firstChild.firstChild).toHaveClass('fw-semibold') - } - } - - //expect(container.firstChild).toHaveTextContent('Test') -}) diff --git a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsB.spec.tsx b/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsB.spec.tsx deleted file mode 100644 index 1fc159c3..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsB.spec.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CWidgetStatsB } from '../../../index' - -test('loads and displays CWidgetStatsB component', async () => { - const { container } = render(<CWidgetStatsB />) - expect(container).toMatchSnapshot() -}) - -test('CWidgetStatsB customize', async () => { - const { container } = render( - <CWidgetStatsB - className="bazinga" - color="info" - inverse - progress={{ color: 'warning', value: 75, white: true }} - text="text" - title="title" - value="value" - > - Test - </CWidgetStatsB>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card') - if (container.firstChild === null || container.firstChild.firstChild === null) { - expect(true).toBe(false) - } else { - expect(container.firstChild.firstChild).toHaveClass('card-body') - expect(container.firstChild.firstChild.firstChild).toHaveClass('fs-4') - expect(container.firstChild.firstChild.firstChild).toHaveClass('fw-semibold') - expect(container.firstChild.firstChild.firstChild).toHaveTextContent('value') - expect(container.firstChild.firstChild.lastChild).toHaveClass('text-white') - expect(container.firstChild.firstChild.lastChild).toHaveTextContent('text') - } -}) diff --git a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsC.spec.tsx b/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsC.spec.tsx deleted file mode 100644 index 16377474..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsC.spec.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CWidgetStatsC } from '../../../index' - -test('loads and displays CWidgetStatsC component', async () => { - const { container } = render(<CWidgetStatsC />) - expect(container).toMatchSnapshot() -}) - -test('CWidgetStatsC customize', async () => { - const { container } = render( - <CWidgetStatsC - className="bazinga" - color="info" - icon="icon" - inverse - progress={{ color: 'warning', value: 75, white: true }} - title="title" - value="value" - > - Test - </CWidgetStatsC>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card') - expect(container.firstChild).toHaveClass('text-white') - if (container.firstChild === null || container.firstChild.firstChild === null) { - expect(true).toBe(false) - } else { - expect(container.firstChild.firstChild).toHaveClass('card-body') - expect(container.firstChild.firstChild.firstChild).toHaveClass('text-end') - expect(container.firstChild.firstChild.firstChild).toHaveClass('mb-4') - expect(container.firstChild.firstChild.firstChild).toHaveTextContent('icon') - expect(container.firstChild.firstChild.lastChild).toHaveClass('mt-3') - expect(container.firstChild.firstChild.lastChild).toHaveClass('mb-0') - } -}) diff --git a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsD.spec.tsx b/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsD.spec.tsx deleted file mode 100644 index 50cf479d..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsD.spec.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CWidgetStatsD } from '../../../index' - -test('loads and displays CWidgetStatsD component', async () => { - const { container } = render(<CWidgetStatsD />) - expect(container).toMatchSnapshot() -}) - -test('CWidgetStatsD customize', async () => { - const { container } = render( - <CWidgetStatsD - className="bazinga" - color="info" - values={[ - { title: 'friends', value: '89K' }, - { title: 'feeds', value: '459' }, - ]} - />, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - if (container.firstChild === null) { - expect(true).toBe(false) - } else { - expect(container.firstChild.firstChild).toHaveClass('position-relative') - expect(container.firstChild.firstChild).toHaveClass('d-flex') - expect(container.firstChild.firstChild).toHaveClass('justify-content-center') - expect(container.firstChild.firstChild).toHaveClass('align-items-center') - expect(container.firstChild.firstChild).toHaveClass('bg-info') - expect(container.firstChild.lastChild).toHaveClass('row') - expect(container.firstChild.lastChild).toHaveClass('text-center') - if ( - container.firstChild.lastChild === null || - container.firstChild.lastChild.firstChild === null - ) { - expect(true).toBe(false) - } else { - expect(container.firstChild.lastChild.firstChild.firstChild).toHaveClass('fs-5') - expect(container.firstChild.lastChild.firstChild.firstChild).toHaveClass('fw-semibold') - expect(container.firstChild.lastChild.firstChild.firstChild).toHaveTextContent('89K') - expect(container.firstChild.lastChild.firstChild.lastChild).toHaveClass('text-uppercase') - expect(container.firstChild.lastChild.firstChild.lastChild).toHaveClass('text-body-secondary') - expect(container.firstChild.lastChild.firstChild.lastChild).toHaveClass('small') - expect(container.firstChild.lastChild.firstChild.lastChild).toHaveTextContent('friends') - } - } -}) diff --git a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsE.spec.tsx b/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsE.spec.tsx deleted file mode 100644 index ae041e76..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsE.spec.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CWidgetStatsE } from '../../../index' - -test('loads and displays CWidgetStatsE component', async () => { - const { container } = render(<CWidgetStatsE />) - expect(container).toMatchSnapshot() -}) - -test('CWidgetStatsE customize', async () => { - const { container } = render( - <CWidgetStatsE className="bazinga" title="title" value="value"> - Test - </CWidgetStatsE>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card') - if (container.firstChild === null || container.firstChild.firstChild === null) { - expect(true).toBe(false) - } else { - expect(container.firstChild.firstChild).toHaveClass('card-body') - expect(container.firstChild.firstChild.firstChild).toHaveClass('text-body-secondary') - expect(container.firstChild.firstChild.firstChild).toHaveClass('small') - expect(container.firstChild.firstChild.firstChild).toHaveClass('text-uppercase') - expect(container.firstChild.firstChild.firstChild).toHaveClass('fw-semibold') - expect(container.firstChild.firstChild.firstChild).toHaveTextContent('title') - } -}) diff --git a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsF.spec.tsx b/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsF.spec.tsx deleted file mode 100644 index ac828b8f..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/CWidgetStatsF.spec.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import * as React from 'react' -import { render } from '@testing-library/react' -import '@testing-library/jest-dom' -import { CWidgetStatsF } from '../../../index' - -test('loads and displays CWidgetStatsF component', async () => { - const { container } = render(<CWidgetStatsF />) - expect(container).toMatchSnapshot() -}) - -test('CWidgetStatsF customize', async () => { - const { container } = render( - <CWidgetStatsF - className="bazinga" - color="info" - footer="footer" - icon="icon" - padding={true} - title="title" - value="value" - > - Test - </CWidgetStatsF>, - ) - expect(container).toMatchSnapshot() - expect(container.firstChild).toHaveClass('bazinga') - expect(container.firstChild).toHaveClass('card') - if (container.firstChild === null) { - expect(true).toBe(false) - } else { - expect(container.firstChild.firstChild).toHaveClass('card-body') - expect(container.firstChild.firstChild).toHaveClass('d-flex') - expect(container.firstChild.firstChild).toHaveClass('align-items-center') - if (container.firstChild.firstChild === null) { - expect(true).toBe(false) - } else { - expect(container.firstChild.firstChild.firstChild).toHaveClass('me-3') - expect(container.firstChild.firstChild.firstChild).toHaveClass('text-white') - expect(container.firstChild.firstChild.firstChild).toHaveClass('bg-info') - expect(container.firstChild.firstChild.firstChild).toHaveClass('p-3') - expect(container.firstChild.firstChild.firstChild).toHaveTextContent('icon') - if (container.firstChild.firstChild.lastChild === null) { - expect(true).toBe(false) - } else { - expect(container.firstChild.firstChild.lastChild.firstChild).toHaveClass('fs-6') - expect(container.firstChild.firstChild.lastChild.firstChild).toHaveClass('fw-semibold') - expect(container.firstChild.firstChild.lastChild.firstChild).toHaveClass('text-info') - expect(container.firstChild.firstChild.lastChild.firstChild).toHaveTextContent('value') - expect(container.firstChild.firstChild.lastChild.lastChild).toHaveClass( - 'text-body-secondary', - ) - expect(container.firstChild.firstChild.lastChild.lastChild).toHaveClass('text-uppercase') - expect(container.firstChild.firstChild.lastChild.lastChild).toHaveClass('fw-semibold ') - expect(container.firstChild.firstChild.lastChild.lastChild).toHaveClass('small') - expect(container.firstChild.firstChild.lastChild.lastChild).toHaveTextContent('title') - } - } - } -}) diff --git a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsA.spec.tsx.snap b/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsA.spec.tsx.snap deleted file mode 100644 index 3fab5bf1..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsA.spec.tsx.snap +++ /dev/null @@ -1,40 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CWidgetStatsA customize 1`] = ` -<div> - <div - class="card bg-info text-white bazinga" - > - <div - class="card-body pb-0 d-flex justify-content-between align-items-start" - > - <div> - <div - class="fs-4 fw-semibold" - > - value - </div> - <div> - title - </div> - </div> - action - </div> - chart - </div> -</div> -`; - -exports[`loads and displays CWidgetStatsA component 1`] = ` -<div> - <div - class="card" - > - <div - class="card-body pb-0 d-flex justify-content-between align-items-start" - > - <div /> - </div> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsB.spec.tsx.snap b/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsB.spec.tsx.snap deleted file mode 100644 index 3caaf042..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsB.spec.tsx.snap +++ /dev/null @@ -1,62 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CWidgetStatsB customize 1`] = ` -<div> - <div - class="card bg-info text-white bazinga" - > - <div - class="card-body" - > - <div - class="fs-4 fw-semibold" - > - value - </div> - <div> - title - </div> - <div - aria-valuemax="100" - aria-valuemin="0" - aria-valuenow="75" - class="progress progress-white my-2" - role="progressbar" - style="height: 4px;" - > - <div - class="progress-bar bg-warning" - style="width: 75%;" - /> - </div> - <small - class="text-white text-opacity-75" - > - text - </small> - </div> - </div> -</div> -`; - -exports[`loads and displays CWidgetStatsB component 1`] = ` -<div> - <div - class="card" - > - <div - class="card-body" - > - <div - class="progress my-2" - style="height: 4px;" - > - <div - class="progress-bar" - style="width: 0%;" - /> - </div> - </div> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsC.spec.tsx.snap b/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsC.spec.tsx.snap deleted file mode 100644 index 9559d000..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsC.spec.tsx.snap +++ /dev/null @@ -1,64 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CWidgetStatsC customize 1`] = ` -<div> - <div - class="card bg-info text-white bazinga" - > - <div - class="card-body" - > - <div - class="text-end mb-4" - > - icon - </div> - <div - class="fs-4 fw-semibold" - > - value - </div> - <div - class="text-white text-opacity-75" - > - title - </div> - <div - aria-valuemax="100" - aria-valuemin="0" - aria-valuenow="75" - class="progress progress-white mt-3 mb-0" - role="progressbar" - style="height: 4px;" - > - <div - class="progress-bar bg-warning" - style="width: 75%;" - /> - </div> - </div> - </div> -</div> -`; - -exports[`loads and displays CWidgetStatsC component 1`] = ` -<div> - <div - class="card" - > - <div - class="card-body" - > - <div - class="progress mt-3 mb-0" - style="height: 4px;" - > - <div - class="progress-bar" - style="width: 0%;" - /> - </div> - </div> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsD.spec.tsx.snap b/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsD.spec.tsx.snap deleted file mode 100644 index e0abfd9c..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsD.spec.tsx.snap +++ /dev/null @@ -1,63 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CWidgetStatsD customize 1`] = ` -<div> - <div - class="card bazinga" - > - <div - class="card-header position-relative d-flex justify-content-center align-items-center bg-info" - /> - <div - class="card-body row text-center" - > - <div - class="col" - > - <div - class="fs-5 fw-semibold" - > - 89K - </div> - <div - class="text-uppercase text-body-secondary small" - > - friends - </div> - </div> - <div - class="vr" - /> - <div - class="col" - > - <div - class="fs-5 fw-semibold" - > - 459 - </div> - <div - class="text-uppercase text-body-secondary small" - > - feeds - </div> - </div> - </div> - </div> -</div> -`; - -exports[`loads and displays CWidgetStatsD component 1`] = ` -<div> - <div - class="card" - > - <div - class="card-header position-relative d-flex justify-content-center align-items-center" - /> - <div - class="card-body row text-center" - /> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsE.spec.tsx.snap b/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsE.spec.tsx.snap deleted file mode 100644 index 56ad3540..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsE.spec.tsx.snap +++ /dev/null @@ -1,36 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CWidgetStatsE customize 1`] = ` -<div> - <div - class="card bazinga" - > - <div - class="card-body text-center" - > - <div - class="text-body-secondary small text-uppercase fw-semibold" - > - title - </div> - <div - class="fs-6 fw-semibold py-3" - > - value - </div> - </div> - </div> -</div> -`; - -exports[`loads and displays CWidgetStatsE component 1`] = ` -<div> - <div - class="card" - > - <div - class="card-body text-center" - /> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsF.spec.tsx.snap b/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsF.spec.tsx.snap deleted file mode 100644 index 8dab9d52..00000000 --- a/packages/coreui-react/src/components/widgets/__tests__/__snapshots__/CWidgetStatsF.spec.tsx.snap +++ /dev/null @@ -1,60 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CWidgetStatsF customize 1`] = ` -<div> - <div - class="card bazinga" - > - <div - class="card-body d-flex align-items-center false" - > - <div - class="me-3 text-white bg-info p-3" - > - icon - </div> - <div> - <div - class="fs-6 fw-semibold text-info" - > - value - </div> - <div - class="text-body-secondary text-uppercase fw-semibold small" - > - title - </div> - </div> - </div> - <div - class="card-footer" - > - footer - </div> - </div> -</div> -`; - -exports[`loads and displays CWidgetStatsF component 1`] = ` -<div> - <div - class="card" - > - <div - class="card-body d-flex align-items-center false" - > - <div - class="me-3 text-white bg-undefined p-3" - /> - <div> - <div - class="fs-6 fw-semibold text-undefined" - /> - <div - class="text-body-secondary text-uppercase fw-semibold small" - /> - </div> - </div> - </div> -</div> -`; diff --git a/packages/coreui-react/src/components/widgets/index.ts b/packages/coreui-react/src/components/widgets/index.ts deleted file mode 100644 index 03c85346..00000000 --- a/packages/coreui-react/src/components/widgets/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { CWidgetStatsA } from './CWidgetStatsA' -import { CWidgetStatsB } from './CWidgetStatsB' -import { CWidgetStatsC } from './CWidgetStatsC' -import { CWidgetStatsD } from './CWidgetStatsD' -import { CWidgetStatsE } from './CWidgetStatsE' -import { CWidgetStatsF } from './CWidgetStatsF' - -export { CWidgetStatsA, CWidgetStatsB, CWidgetStatsC, CWidgetStatsD, CWidgetStatsE, CWidgetStatsF } diff --git a/packages/coreui-react/src/hooks/index.ts b/packages/coreui-react/src/hooks/index.ts deleted file mode 100644 index 5ee1b5e3..00000000 --- a/packages/coreui-react/src/hooks/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { useColorModes } from './useColorModes' -import { useForkedRef } from './useForkedRef' -import { usePopper } from './usePopper' - -export { useColorModes, useForkedRef, usePopper } diff --git a/packages/coreui-react/src/hooks/useColorModes.ts b/packages/coreui-react/src/hooks/useColorModes.ts deleted file mode 100644 index b6c63a80..00000000 --- a/packages/coreui-react/src/hooks/useColorModes.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Dispatch, SetStateAction, useEffect, useState } from 'react' - -interface UseColorModesOutput { - colorMode: string | undefined - isColorModeSet: () => boolean - setColorMode: Dispatch<SetStateAction<string>> -} - -const getStoredTheme = (localStorageItemName: string) => - typeof window !== 'undefined' && localStorage.getItem(localStorageItemName) - -const setStoredTheme = (localStorageItemName: string, colorMode: string) => - localStorage.setItem(localStorageItemName, colorMode) - -const getPreferredColorScheme = (localStorageItemName: string) => { - if (typeof window === 'undefined') { - return 'light' - } - - const storedTheme = getStoredTheme(localStorageItemName) - - if (storedTheme) { - return storedTheme - } - - return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' -} - -const setTheme = (colorMode: string) => { - document.documentElement.dataset.coreuiTheme = - colorMode === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches - ? 'dark' - : colorMode - - const event = new Event('ColorSchemeChange') - document.documentElement.dispatchEvent(event) -} - -export const useColorModes = ( - localStorageItemName = 'coreui-react-color-scheme', -): UseColorModesOutput => { - const [colorMode, setColorMode] = useState<string | undefined>( - getPreferredColorScheme(localStorageItemName), - ) - - useEffect(() => { - if (colorMode) { - setStoredTheme(localStorageItemName, colorMode) - setTheme(colorMode) - } - }, [colorMode]) - - useEffect(() => { - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { - const storedTheme = getStoredTheme(localStorageItemName) - if (storedTheme !== 'light' && storedTheme !== 'dark' && colorMode) { - setTheme(colorMode) - } - }) - }) - - return { - colorMode, - isColorModeSet: () => Boolean(getStoredTheme(localStorageItemName)), - setColorMode, - } -} diff --git a/packages/coreui-react/src/hooks/useForkedRef.ts b/packages/coreui-react/src/hooks/useForkedRef.ts deleted file mode 100644 index 0eb7b77a..00000000 --- a/packages/coreui-react/src/hooks/useForkedRef.ts +++ /dev/null @@ -1,50 +0,0 @@ -// code borrowed from https://github.com/reach/reach-ui -// problem described https://github.com/facebook/react/issues/13029 - -import { useMemo } from 'react' - -export type AssignableRef<ValueType> = - | { - bivarianceHack(instance: ValueType | null): void - }['bivarianceHack'] - | React.MutableRefObject<ValueType | null> - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function useForkedRef<RefValueType = any>( - ...refs: (AssignableRef<RefValueType> | null | undefined)[] -) { - return useMemo(() => { - if (refs.every((ref) => ref == null)) { - return null - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return (node: any) => { - refs.forEach((ref) => { - assignRef(ref, node) - }) - } - }, refs) -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function assignRef<RefValueType = any>( - ref: AssignableRef<RefValueType> | null | undefined, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - value: any, -) { - if (ref == null) return - if (isFunction(ref)) { - ref(value) - } else { - try { - ref.current = value - } catch { - throw new Error(`Cannot assign value "${value}" to ref "${ref}"`) - } - } -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types -export function isFunction(value: any): value is Function { - return !!(value && {}.toString.call(value) == '[object Function]') -} diff --git a/packages/coreui-react/src/hooks/usePopper.ts b/packages/coreui-react/src/hooks/usePopper.ts deleted file mode 100644 index 898a402e..00000000 --- a/packages/coreui-react/src/hooks/usePopper.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { useRef } from 'react' -import { createPopper } from '@popperjs/core' -import type { Instance, Options } from '@popperjs/core' - -import { executeAfterTransition } from '../utils' - -interface UsePopperOutput { - popper: Instance | undefined - initPopper: (reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => void - destroyPopper: () => void -} - -export const usePopper = (): UsePopperOutput => { - const _popper = useRef<Instance>() - const el = useRef<HTMLElement>() - - const initPopper = (reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => { - _popper.current = createPopper(reference, popper, options) - el.current = popper - } - - const destroyPopper = () => { - const popperInstance = _popper.current - - if (popperInstance && el.current) { - executeAfterTransition(() => { - popperInstance.destroy() - }, el.current) - } - - _popper.current = undefined - } - - return { - popper: _popper.current, - initPopper, - destroyPopper, - } -} diff --git a/packages/coreui-react/src/index.ts b/packages/coreui-react/src/index.ts deleted file mode 100644 index 9c5450c8..00000000 --- a/packages/coreui-react/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './components/' -export * from './hooks/' diff --git a/packages/coreui-react/src/props.ts b/packages/coreui-react/src/props.ts deleted file mode 100644 index ccce445a..00000000 --- a/packages/coreui-react/src/props.ts +++ /dev/null @@ -1,68 +0,0 @@ -import PropTypes from 'prop-types' - -import type { Placements, Triggers } from './types' - -export const colorPropType = PropTypes.oneOfType([ - PropTypes.oneOf([ - 'primary', - 'secondary', - 'success', - 'danger', - 'warning', - 'info', - 'dark', - 'light', - ]), - PropTypes.string, -]) - -export const fallbackPlacementsPropType = PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.oneOf<Placements>(['top', 'bottom', 'right', 'left']).isRequired), - PropTypes.oneOf<Placements>(['top', 'bottom', 'right', 'left']), -]) - -export const placementPropType = PropTypes.oneOf<Placements>([ - 'auto', - 'auto-start', - 'auto-end', - 'top-end', - 'top', - 'top-start', - 'bottom-end', - 'bottom', - 'bottom-start', - 'right-start', - 'right', - 'right-end', - 'left-start', - 'left', - 'left-end', -]) - -export const shapePropType = PropTypes.oneOfType([ - PropTypes.oneOf([ - 'rounded', - 'rounded-top', - 'rounded-end', - 'rounded-bottom', - 'rounded-start', - 'rounded-circle', - 'rounded-pill', - 'rounded-0', - 'rounded-1', - 'rounded-2', - 'rounded-3', - ]), - PropTypes.string, -]) - -export const textColorsPropType = PropTypes.oneOfType([ - colorPropType, - PropTypes.oneOf(['white', 'muted']), - PropTypes.string, -]) - -export const triggerPropType = PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.oneOf<Triggers>(['hover', 'focus', 'click']).isRequired), - PropTypes.oneOf<Triggers>(['hover', 'focus', 'click']), -]) diff --git a/packages/coreui-react/src/types.ts b/packages/coreui-react/src/types.ts deleted file mode 100644 index 860fa90c..00000000 --- a/packages/coreui-react/src/types.ts +++ /dev/null @@ -1,65 +0,0 @@ -export type Breakpoints = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' - -export type Colors = - | 'primary' - | 'secondary' - | 'success' - | 'danger' - | 'warning' - | 'info' - | 'dark' - | 'light' - | string - -export type Placements = - | 'auto' - | 'auto-start' - | 'auto-end' - | 'top-end' - | 'top' - | 'top-start' - | 'bottom-end' - | 'bottom' - | 'bottom-start' - | 'right-start' - | 'right' - | 'right-end' - | 'left-start' - | 'left' - | 'left-end' - | undefined - -export type Shapes = - | 'rounded' - | 'rounded-top' - | 'rounded-end' - | 'rounded-bottom' - | 'rounded-start' - | 'rounded-circle' - | 'rounded-pill' - | 'rounded-0' - | 'rounded-1' - | 'rounded-2' - | 'rounded-3' - | string - -export type TextColors = - | Colors - | 'primary-emphasis' - | 'secondary-emphasis' - | 'success-emphasis' - | 'danger-emphasis' - | 'warning-emphasis' - | 'info-emphasis' - | 'light-emphasis' - | 'body' - | 'body-emphasis' - | 'body-secondary' - | 'body-tertiary' - | 'black' - | 'black-50' - | 'white' - | 'white-50' - | string - -export type Triggers = 'hover' | 'focus' | 'click' diff --git a/packages/coreui-react/src/utils/executeAfterTransition.ts b/packages/coreui-react/src/utils/executeAfterTransition.ts deleted file mode 100644 index 7b0bed80..00000000 --- a/packages/coreui-react/src/utils/executeAfterTransition.ts +++ /dev/null @@ -1,46 +0,0 @@ -import getTransitionDurationFromElement from './getTransitionDurationFromElement' - -const execute = (callback: () => void) => { - if (typeof callback === 'function') { - callback() - } -} - -const triggerTransitionEnd = (element: HTMLElement) => { - element.dispatchEvent(new Event('transitionend')) -} - -const executeAfterTransition = ( - callback: () => void, - transitionElement: HTMLElement, - waitForTransition = true, -) => { - if (!waitForTransition) { - execute(callback) - return - } - - const durationPadding = 5 - const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding - - let called = false - - const handler = ({ target }: { target: any }) => { - if (target !== transitionElement) { - return - } - - called = true - transitionElement.removeEventListener('transitionend', handler) - execute(callback) - } - - transitionElement.addEventListener('transitionend', handler) - setTimeout(() => { - if (!called) { - triggerTransitionEnd(transitionElement) - } - }, emulatedDuration) -} - -export default executeAfterTransition diff --git a/packages/coreui-react/src/utils/getRTLPlacement.ts b/packages/coreui-react/src/utils/getRTLPlacement.ts deleted file mode 100644 index 87c38517..00000000 --- a/packages/coreui-react/src/utils/getRTLPlacement.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Placement } from '@popperjs/core' -import isRTL from './isRTL' - -const getRTLPlacement = (placement: string, element: HTMLDivElement | null): Placement => { - switch (placement) { - case 'right': { - return isRTL(element) ? 'left' : 'right' - } - case 'left': { - return isRTL(element) ? 'right' : 'left' - } - default: { - return placement as Placement - } - } -} - -export default getRTLPlacement diff --git a/packages/coreui-react/src/utils/getTransitionDurationFromElement.ts b/packages/coreui-react/src/utils/getTransitionDurationFromElement.ts deleted file mode 100644 index a62b32fb..00000000 --- a/packages/coreui-react/src/utils/getTransitionDurationFromElement.ts +++ /dev/null @@ -1,24 +0,0 @@ -const getTransitionDurationFromElement = (element: HTMLElement) => { - if (!element) { - return 0 - } - - // Get transition-duration of the element - let { transitionDuration, transitionDelay } = window.getComputedStyle(element) - - const floatTransitionDuration = Number.parseFloat(transitionDuration) - const floatTransitionDelay = Number.parseFloat(transitionDelay) - - // Return 0 if element or transition duration is not found - if (!floatTransitionDuration && !floatTransitionDelay) { - return 0 - } - - // If multiple durations are defined, take the first - transitionDuration = transitionDuration.split(',')[0] - transitionDelay = transitionDelay.split(',')[0] - - return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * 1000 -} - -export default getTransitionDurationFromElement diff --git a/packages/coreui-react/src/utils/index.ts b/packages/coreui-react/src/utils/index.ts deleted file mode 100644 index 10dbd154..00000000 --- a/packages/coreui-react/src/utils/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import executeAfterTransition from './executeAfterTransition' -import getRTLPlacement from './getRTLPlacement' -import getTransitionDurationFromElement from './getTransitionDurationFromElement' -import isInViewport from './isInViewport' -import isRTL from './isRTL' - -export { - executeAfterTransition, - getRTLPlacement, - getTransitionDurationFromElement, - isInViewport, - isRTL, -} diff --git a/packages/coreui-react/src/utils/isInViewport.ts b/packages/coreui-react/src/utils/isInViewport.ts deleted file mode 100644 index 7aae5391..00000000 --- a/packages/coreui-react/src/utils/isInViewport.ts +++ /dev/null @@ -1,11 +0,0 @@ -const isInViewport = (element: HTMLElement) => { - const rect = element.getBoundingClientRect() - return ( - Math.floor(rect.top) >= 0 && - Math.floor(rect.left) >= 0 && - Math.floor(rect.bottom) <= (window.innerHeight || document.documentElement.clientHeight) && - Math.floor(rect.right) <= (window.innerWidth || document.documentElement.clientWidth) - ) -} - -export default isInViewport diff --git a/packages/coreui-react/src/utils/isRTL.ts b/packages/coreui-react/src/utils/isRTL.ts deleted file mode 100644 index 17180d80..00000000 --- a/packages/coreui-react/src/utils/isRTL.ts +++ /dev/null @@ -1,13 +0,0 @@ -const isRTL = (element?: HTMLElement | HTMLDivElement | null) => { - if (typeof document !== 'undefined' && document.documentElement.dir === 'rtl') { - return true - } - - if (element) { - return element.closest('[dir="rtl"]') !== null - } - - return false -} - -export default isRTL diff --git a/packages/coreui-react/tsconfig.json b/packages/coreui-react/tsconfig.json deleted file mode 100644 index d8b90788..00000000 --- a/packages/coreui-react/tsconfig.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "../../tsconfig", - "include": ["src/**/*"] -} \ No newline at end of file diff --git a/packages/docs/build/api.js b/packages/docs/build/api.js deleted file mode 100644 index 084599da..00000000 --- a/packages/docs/build/api.js +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env node - -'use strict' - -const fs = require('node:fs').promises -const path = require('node:path') -const globby = require('globby') -const docgen = require('react-docgen-typescript') - -const GLOB = [ - '**/src/**/*.tsx', - '../node_modules/@coreui/icons-react/src/**/*.tsx', - '../node_modules/@coreui/react-chartjs/src/**/*.tsx', -] -const GLOBBY_OPTIONS = { - absolute: true, - cwd: path.join(__dirname, '..', '..'), - gitignore: false, - ignore: ['**/docs/**', '**/__tests__/**'], -} -const EXCLUDED_FILES = [] - -const options = { - savePropValueAsString: true, - shouldIncludePropTagMap: true, -} - -const PRO_COMPONENTS = [] - -const replace = (text) => - text - .replaceAll('(<', '(\\<') - .replace(/<C(.*)\/>/g, '`<C$1/>`') - .replaceAll('\n', '<br/>') - -async function createMdx(file, filename, name, props) { - if (typeof props === 'undefined') { - return - } - - const pro = PRO_COMPONENTS.some((v) => file.includes(v)) - let relativeFilename - if (file.includes('node_modules')) { - relativeFilename = file.replace(path.join(file, '..', '..', '..'), '').replace('coreui-', '') - } else { - relativeFilename = file.replace(GLOBBY_OPTIONS.cwd, '').replace('coreui-', '') - } - - if (!pro) { - relativeFilename = relativeFilename.replace('-pro', '') - } - - let content = `\n` - content += `\`\`\`jsx\n` - content += `import { ${name} } from '@coreui/${relativeFilename.split('/')[1]}'\n` - content += `// or\n` - content += `import ${name} from '@coreui${relativeFilename.replace('.tsx', '')}'\n` - content += `\`\`\`\n\n` - - let index = 0 - for (const [key, value] of Object.entries(props).sort()) { - if ( - value.parent.fileName.includes('@types/react/index.d.ts') || - value.parent.fileName.includes('@types/react/ts5.0/index.d.ts') - ) { - continue - } - - if (value.tags.ignore === '') { - continue - } - - if (index === 0) { - content += `| Property | Description | Type | Default |\n` - content += `| --- | --- | --- | --- |\n` - } - let name = value.name || '' - const since = value.tags.since ? ` **_${value.tags.since}+_**` : '' - const deprecated = value.tags.deprecated ? ` **_Deprecated ${value.tags.deprecated}+_**` : '' - const description = value.description || '-' - const type = value.type - ? (value.type.name.includes('ReactElement') - ? 'ReactElement' - : value.type.name) - : '' - const defaultValue = value.defaultValue - ? value.defaultValue.value.replace('undefined', '-') - : '-' - const types = [] - type.split(' | ').map((element) => { - types.push(`\`${element.replace(/"/g, "'")}\``) - }) - - content += `| **${name}**${since}${deprecated} | ${replace(description)} | ${types.join( - ' \\| ', - )} | ${replace(defaultValue)} |\n` - index++ - } - - await fs - .writeFile(`content/api/${filename}.api.mdx`, content, { - encoding: 'utf8', - }) - .then(() => { - console.log(`File created: ${filename}.api.mdx`) - }) -} - -async function main() { - try { - const files = await globby(GLOB, GLOBBY_OPTIONS, EXCLUDED_FILES) - - await Promise.all( - files.map((file) => { - console.log(file) - const props = docgen.parse(file, options) - if (props && typeof props[0] !== 'undefined') { - const filename = path.basename(file, '.tsx') - createMdx(file, filename, props[0].displayName, props[0].props) - } - }), - ) - } catch (error) { - console.error(error) - process.exit(1) - } -} - -main() diff --git a/packages/docs/content/api/CAccordion.api.mdx b/packages/docs/content/api/CAccordion.api.mdx deleted file mode 100644 index 0a27911d..00000000 --- a/packages/docs/content/api/CAccordion.api.mdx +++ /dev/null @@ -1,13 +0,0 @@ - -```jsx -import { CAccordion } from '@coreui/react' -// or -import CAccordion from '@coreui/react/src/components/accordion/CAccordion' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **activeItemKey** | The active item key. | `string` \| `number` | - | -| **alwaysOpen** | Make accordion items stay open when another item is opened | `boolean` | false | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **flush** | Removes the default background-color, some borders, and some rounded corners to render accordions edge-to-edge with their parent container. | `boolean` | - | diff --git a/packages/docs/content/api/CAccordionBody.api.mdx b/packages/docs/content/api/CAccordionBody.api.mdx deleted file mode 100644 index 9665e4d0..00000000 --- a/packages/docs/content/api/CAccordionBody.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CAccordionBody } from '@coreui/react' -// or -import CAccordionBody from '@coreui/react/src/components/accordion/CAccordionBody' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CAccordionButton.api.mdx b/packages/docs/content/api/CAccordionButton.api.mdx deleted file mode 100644 index 885e6448..00000000 --- a/packages/docs/content/api/CAccordionButton.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CAccordionButton } from '@coreui/react' -// or -import CAccordionButton from '@coreui/react/src/components/accordion/CAccordionButton' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CAccordionCollapse.api.mdx b/packages/docs/content/api/CAccordionCollapse.api.mdx deleted file mode 100644 index 55fdfd01..00000000 --- a/packages/docs/content/api/CAccordionCollapse.api.mdx +++ /dev/null @@ -1,13 +0,0 @@ - -```jsx -import { CAccordionCollapse } from '@coreui/react' -// or -import CAccordionCollapse from '@coreui/react/src/components/accordion/CAccordionCollapse' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **onHide** | Callback fired when the component requests to be hidden. | `() => void` | - | -| **onShow** | Callback fired when the component requests to be shown. | `() => void` | - | -| **visible** | Toggle the visibility of component. | `boolean` | - | diff --git a/packages/docs/content/api/CAccordionHeader.api.mdx b/packages/docs/content/api/CAccordionHeader.api.mdx deleted file mode 100644 index ac19753c..00000000 --- a/packages/docs/content/api/CAccordionHeader.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CAccordionHeader } from '@coreui/react' -// or -import CAccordionHeader from '@coreui/react/src/components/accordion/CAccordionHeader' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CAccordionItem.api.mdx b/packages/docs/content/api/CAccordionItem.api.mdx deleted file mode 100644 index 5ef85d86..00000000 --- a/packages/docs/content/api/CAccordionItem.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CAccordionItem } from '@coreui/react' -// or -import CAccordionItem from '@coreui/react/src/components/accordion/CAccordionItem' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **itemKey** | Item key. | `string` \| `number` | - | diff --git a/packages/docs/content/api/CAlert.api.mdx b/packages/docs/content/api/CAlert.api.mdx deleted file mode 100644 index f2ed443c..00000000 --- a/packages/docs/content/api/CAlert.api.mdx +++ /dev/null @@ -1,15 +0,0 @@ - -```jsx -import { CAlert } from '@coreui/react' -// or -import CAlert from '@coreui/react/src/components/alert/CAlert' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | primary | -| **dismissible** | Optionally add a close button to alert and allow it to self dismiss. | `boolean` | - | -| **onClose** | Callback fired when the component requests to be closed. | `() => void` | - | -| **variant** | Set the alert variant to a solid. | `string` | - | -| **visible** | Toggle the visibility of component. | `boolean` | true | diff --git a/packages/docs/content/api/CAlertHeading.api.mdx b/packages/docs/content/api/CAlertHeading.api.mdx deleted file mode 100644 index 5e052158..00000000 --- a/packages/docs/content/api/CAlertHeading.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CAlertHeading } from '@coreui/react' -// or -import CAlertHeading from '@coreui/react/src/components/alert/CAlertHeading' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CAlertLink.api.mdx b/packages/docs/content/api/CAlertLink.api.mdx deleted file mode 100644 index 027b3254..00000000 --- a/packages/docs/content/api/CAlertLink.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CAlertLink } from '@coreui/react' -// or -import CAlertLink from '@coreui/react/src/components/alert/CAlertLink' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CAvatar.api.mdx b/packages/docs/content/api/CAvatar.api.mdx deleted file mode 100644 index 5e6f6399..00000000 --- a/packages/docs/content/api/CAvatar.api.mdx +++ /dev/null @@ -1,16 +0,0 @@ - -```jsx -import { CAvatar } from '@coreui/react' -// or -import CAvatar from '@coreui/react/src/components/avatar/CAvatar' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **shape** | Select the shape of the component. | `'rounded'` \| `'rounded-top'` \| `'rounded-end'` \| `'rounded-bottom'` \| `'rounded-start'` \| `'rounded-circle'` \| `'rounded-pill'` \| `'rounded-0'` \| `'rounded-1'` \| `'rounded-2'` \| `'rounded-3'` \| `string` | - | -| **size** | Size the component small, large, or extra large. | `string` | - | -| **src** | The src attribute for the img element. | `string` | - | -| **status** | Sets the color context of the status indicator to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **textColor** | Sets the text color of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `'primary-emphasis'` \| `'secondary-emphasis'` \| `'success-emphasis'` \| `'danger-emphasis'` \| `'warning-emphasis'` \| `'info-emphasis'` \| `'light-emphasis'` \| `'body'` \| `'body-emphasis'` \| `'body-secondary'` \| `'body-tertiary'` \| `'black'` \| `'black-50'` \| `'white'` \| `'white-50'` \| `string` | - | diff --git a/packages/docs/content/api/CBackdrop.api.mdx b/packages/docs/content/api/CBackdrop.api.mdx deleted file mode 100644 index 0e202b4e..00000000 --- a/packages/docs/content/api/CBackdrop.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CBackdrop } from '@coreui/react' -// or -import CBackdrop from '@coreui/react/src/components/backdrop/CBackdrop' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | modal-backdrop | -| **visible** | Toggle the visibility of modal component. | `boolean` | - | diff --git a/packages/docs/content/api/CBadge.api.mdx b/packages/docs/content/api/CBadge.api.mdx deleted file mode 100644 index d719a93d..00000000 --- a/packages/docs/content/api/CBadge.api.mdx +++ /dev/null @@ -1,16 +0,0 @@ - -```jsx -import { CBadge } from '@coreui/react' -// or -import CBadge from '@coreui/react/src/components/badge/CBadge' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **position** | Position badge in one of the corners of a link or button. | `'top-start'` \| `'top-end'` \| `'bottom-end'` \| `'bottom-start'` | - | -| **shape** | Select the shape of the component. | `'rounded'` \| `'rounded-top'` \| `'rounded-end'` \| `'rounded-bottom'` \| `'rounded-start'` \| `'rounded-circle'` \| `'rounded-pill'` \| `'rounded-0'` \| `'rounded-1'` \| `'rounded-2'` \| `'rounded-3'` \| `string` | - | -| **size** | Size the component small. | `'sm'` | - | -| **textColor** | Sets the text color of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `'primary-emphasis'` \| `'secondary-emphasis'` \| `'success-emphasis'` \| `'danger-emphasis'` \| `'warning-emphasis'` \| `'info-emphasis'` \| `'light-emphasis'` \| `'body'` \| `'body-emphasis'` \| `'body-secondary'` \| `'body-tertiary'` \| `'black'` \| `'black-50'` \| `'white'` \| `'white-50'` \| `string` | - | diff --git a/packages/docs/content/api/CBreadcrumb.api.mdx b/packages/docs/content/api/CBreadcrumb.api.mdx deleted file mode 100644 index 51e20bf3..00000000 --- a/packages/docs/content/api/CBreadcrumb.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CBreadcrumb } from '@coreui/react' -// or -import CBreadcrumb from '@coreui/react/src/components/breadcrumb/CBreadcrumb' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CBreadcrumbItem.api.mdx b/packages/docs/content/api/CBreadcrumbItem.api.mdx deleted file mode 100644 index 431f6fb3..00000000 --- a/packages/docs/content/api/CBreadcrumbItem.api.mdx +++ /dev/null @@ -1,12 +0,0 @@ - -```jsx -import { CBreadcrumbItem } from '@coreui/react' -// or -import CBreadcrumbItem from '@coreui/react/src/components/breadcrumb/CBreadcrumbItem' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Toggle the active state for the component. | `boolean` | - | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **href** | The `href` attribute for the inner `<CLink>` component. | `string` | - | diff --git a/packages/docs/content/api/CButton.api.mdx b/packages/docs/content/api/CButton.api.mdx deleted file mode 100644 index b49510c6..00000000 --- a/packages/docs/content/api/CButton.api.mdx +++ /dev/null @@ -1,20 +0,0 @@ - -```jsx -import { CButton } from '@coreui/react' -// or -import CButton from '@coreui/react/src/components/button/CButton' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Toggle the active state for the component. | `boolean` | - | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | primary | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | button | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | -| **href** | The href attribute specifies the URL of the page the link goes to. | `string` | - | -| **role** | The role attribute describes the role of an element in programs that can make use of it, such as screen readers or magnifiers. | `string` | - | -| **shape** | Select the shape of the component. | `'rounded'` \| `'rounded-top'` \| `'rounded-end'` \| `'rounded-bottom'` \| `'rounded-start'` \| `'rounded-circle'` \| `'rounded-pill'` \| `'rounded-0'` \| `'rounded-1'` \| `'rounded-2'` \| `'rounded-3'` \| `string` | - | -| **size** | Size the component small or large. | `'sm'` \| `'lg'` | - | -| **type** | Specifies the type of button. Always specify the type attribute for the `<button>` element.<br/>Different browsers may use different default types for the `<button>` element. | `'button'` \| `'submit'` \| `'reset'` | button | -| **variant** | Set the button variant to an outlined button or a ghost button. | `'outline'` \| `'ghost'` | - | diff --git a/packages/docs/content/api/CButtonGroup.api.mdx b/packages/docs/content/api/CButtonGroup.api.mdx deleted file mode 100644 index 6b5018ff..00000000 --- a/packages/docs/content/api/CButtonGroup.api.mdx +++ /dev/null @@ -1,12 +0,0 @@ - -```jsx -import { CButtonGroup } from '@coreui/react' -// or -import CButtonGroup from '@coreui/react/src/components/button-group/CButtonGroup' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **size** | Size the component small or large. | `'sm'` \| `'lg'` | - | -| **vertical** | Create a set of buttons that appear vertically stacked rather than horizontally. Split button dropdowns are not supported here. | `boolean` | - | diff --git a/packages/docs/content/api/CButtonToolbar.api.mdx b/packages/docs/content/api/CButtonToolbar.api.mdx deleted file mode 100644 index ecaca63e..00000000 --- a/packages/docs/content/api/CButtonToolbar.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CButtonToolbar } from '@coreui/react' -// or -import CButtonToolbar from '@coreui/react/src/components/button-group/CButtonToolbar' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CCallout.api.mdx b/packages/docs/content/api/CCallout.api.mdx deleted file mode 100644 index c76930c5..00000000 --- a/packages/docs/content/api/CCallout.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CCallout } from '@coreui/react' -// or -import CCallout from '@coreui/react/src/components/callout/CCallout' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | diff --git a/packages/docs/content/api/CCard.api.mdx b/packages/docs/content/api/CCard.api.mdx deleted file mode 100644 index 098188b4..00000000 --- a/packages/docs/content/api/CCard.api.mdx +++ /dev/null @@ -1,12 +0,0 @@ - -```jsx -import { CCard } from '@coreui/react' -// or -import CCard from '@coreui/react/src/components/card/CCard' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **textColor** | Sets the text color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `'primary-emphasis'` \| `'secondary-emphasis'` \| `'success-emphasis'` \| `'danger-emphasis'` \| `'warning-emphasis'` \| `'info-emphasis'` \| `'light-emphasis'` \| `'body'` \| `'body-emphasis'` \| `'body-secondary'` \| `'body-tertiary'` \| `'black'` \| `'black-50'` \| `'white'` \| `'white-50'` \| `string` | - | diff --git a/packages/docs/content/api/CCardBody.api.mdx b/packages/docs/content/api/CCardBody.api.mdx deleted file mode 100644 index 88022993..00000000 --- a/packages/docs/content/api/CCardBody.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CCardBody } from '@coreui/react' -// or -import CCardBody from '@coreui/react/src/components/card/CCardBody' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CCardFooter.api.mdx b/packages/docs/content/api/CCardFooter.api.mdx deleted file mode 100644 index 184f37ee..00000000 --- a/packages/docs/content/api/CCardFooter.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CCardFooter } from '@coreui/react' -// or -import CCardFooter from '@coreui/react/src/components/card/CCardFooter' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CCardGroup.api.mdx b/packages/docs/content/api/CCardGroup.api.mdx deleted file mode 100644 index 359d7032..00000000 --- a/packages/docs/content/api/CCardGroup.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CCardGroup } from '@coreui/react' -// or -import CCardGroup from '@coreui/react/src/components/card/CCardGroup' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CCardHeader.api.mdx b/packages/docs/content/api/CCardHeader.api.mdx deleted file mode 100644 index 546ef016..00000000 --- a/packages/docs/content/api/CCardHeader.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CCardHeader } from '@coreui/react' -// or -import CCardHeader from '@coreui/react/src/components/card/CCardHeader' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CCardImage.api.mdx b/packages/docs/content/api/CCardImage.api.mdx deleted file mode 100644 index 29853288..00000000 --- a/packages/docs/content/api/CCardImage.api.mdx +++ /dev/null @@ -1,12 +0,0 @@ - -```jsx -import { CCardImage } from '@coreui/react' -// or -import CCardImage from '@coreui/react/src/components/card/CCardImage' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **orientation** | Optionally orientate the image to the top, bottom, or make it overlaid across the card. | `'top'` \| `'bottom'` | - | diff --git a/packages/docs/content/api/CCardImageOverlay.api.mdx b/packages/docs/content/api/CCardImageOverlay.api.mdx deleted file mode 100644 index 4716925b..00000000 --- a/packages/docs/content/api/CCardImageOverlay.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CCardImageOverlay } from '@coreui/react' -// or -import CCardImageOverlay from '@coreui/react/src/components/card/CCardImageOverlay' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CCardLink.api.mdx b/packages/docs/content/api/CCardLink.api.mdx deleted file mode 100644 index 609a003d..00000000 --- a/packages/docs/content/api/CCardLink.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CCardLink } from '@coreui/react' -// or -import CCardLink from '@coreui/react/src/components/card/CCardLink' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **href** | The href attribute specifies the URL of the page the link goes to. | `string` | - | diff --git a/packages/docs/content/api/CCardSubtitle.api.mdx b/packages/docs/content/api/CCardSubtitle.api.mdx deleted file mode 100644 index 73b62a27..00000000 --- a/packages/docs/content/api/CCardSubtitle.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CCardSubtitle } from '@coreui/react' -// or -import CCardSubtitle from '@coreui/react/src/components/card/CCardSubtitle' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CCardText.api.mdx b/packages/docs/content/api/CCardText.api.mdx deleted file mode 100644 index baaed254..00000000 --- a/packages/docs/content/api/CCardText.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CCardText } from '@coreui/react' -// or -import CCardText from '@coreui/react/src/components/card/CCardText' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CCardTitle.api.mdx b/packages/docs/content/api/CCardTitle.api.mdx deleted file mode 100644 index 7270b46f..00000000 --- a/packages/docs/content/api/CCardTitle.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CCardTitle } from '@coreui/react' -// or -import CCardTitle from '@coreui/react/src/components/card/CCardTitle' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CCarousel.api.mdx b/packages/docs/content/api/CCarousel.api.mdx deleted file mode 100644 index 6a2f8cdf..00000000 --- a/packages/docs/content/api/CCarousel.api.mdx +++ /dev/null @@ -1,21 +0,0 @@ - -```jsx -import { CCarousel } from '@coreui/react' -// or -import CCarousel from '@coreui/react/src/components/carousel/CCarousel' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **activeIndex** | index of the active item. | `number` | 0 | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **controls** | Adding in the previous and next controls. | `boolean` | - | -| **dark** | Add darker controls, indicators, and captions. | `boolean` | - | -| **indicators** | Adding indicators at the bottom of the carousel for each item. | `boolean` | - | -| **interval** | The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle. | `number` \| `boolean` | 5000 | -| **onSlid** | Callback fired when a slide transition end. | `(active: number, direction: string) => void` | - | -| **onSlide** | Callback fired when a slide transition starts. | `(active: number, direction: string) => void` | - | -| **pause** | If set to 'hover', pauses the cycling of the carousel on mouseenter and resumes the cycling of the carousel on mouseleave. If set to false, hovering over the carousel won't pause it. | `boolean` \| `'hover'` | hover | -| **touch** **_4.5.0+_** | Set whether the carousel should support left/right swipe interactions on touchscreen devices. | `boolean` | true | -| **transition** | Set type of the transition. | `'slide'` \| `'crossfade'` | - | -| **wrap** | Set whether the carousel should cycle continuously or have hard stops. | `boolean` | true | diff --git a/packages/docs/content/api/CCarouselCaption.api.mdx b/packages/docs/content/api/CCarouselCaption.api.mdx deleted file mode 100644 index 97c68639..00000000 --- a/packages/docs/content/api/CCarouselCaption.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CCarouselCaption } from '@coreui/react' -// or -import CCarouselCaption from '@coreui/react/src/components/carousel/CCarouselCaption' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CCarouselItem.api.mdx b/packages/docs/content/api/CCarouselItem.api.mdx deleted file mode 100644 index e7c469d1..00000000 --- a/packages/docs/content/api/CCarouselItem.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CCarouselItem } from '@coreui/react' -// or -import CCarouselItem from '@coreui/react/src/components/carousel/CCarouselItem' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **interval** | The amount of time to delay between automatically cycling an item. | `number` \| `boolean` | false | diff --git a/packages/docs/content/api/CChart.api.mdx b/packages/docs/content/api/CChart.api.mdx deleted file mode 100644 index 4a328e1c..00000000 --- a/packages/docs/content/api/CChart.api.mdx +++ /dev/null @@ -1,24 +0,0 @@ - -```jsx -import { CChart } from '@coreui/react-chartjs' -// or -import CChart from '@coreui/react-chartjs/src/CChart' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **customTooltips** | Enables custom html based tooltips instead of standard tooltips. | `boolean` | true | -| **data** | The data object that is passed into the Chart.js chart (more info). | `ChartData<keyof ChartTypeRegistry, (number` \| `[number, number]` \| `Point` \| `BubbleDataPoint)[], unknown>` \| `((canvas: HTMLCanvasElement) => ChartData<...>)` | - | -| **fallbackContent** | A fallback for when the canvas cannot be rendered. Can be used for accessible chart descriptions. | `React.ReactNode` | - | -| **getDatasetAtEvent** | Proxy for Chart.js getDatasetAtEvent. Calls with dataset and triggering event. | `(dataset: InteractionItem[], event: React.MouseEvent<HTMLCanvasElement>) => void` | - | -| **getElementAtEvent** | Proxy for Chart.js getElementAtEvent. Calls with single element array and triggering event. | `(element: InteractionItem[], event: React.MouseEvent<HTMLCanvasElement>) => void` | - | -| **getElementsAtEvent** | Proxy for Chart.js getElementsAtEvent. Calls with element array and triggering event. | `(elements: InteractionItem[], event: React.MouseEvent<HTMLCanvasElement>) => void` | - | -| **height** | Height attribute applied to the rendered canvas. | `number` | 150 | -| **id** | ID attribute applied to the rendered canvas. | `string` | - | -| **options** | The options object that is passed into the Chart.js chart. | `_DeepPartialObject<CoreChartOptions<keyof ChartTypeRegistry> & ElementChartOptions<keyof ChartTypeRegistry> & PluginChartOptions<...> & DatasetChartOptions<...> & ScaleChartOptions<...>>` | - | -| **plugins** | The plugins array that is passed into the Chart.js chart (more info) | `Plugin<keyof ChartTypeRegistry, AnyObject>[]` | [] | -| **redraw** | If true, will tear down and redraw chart on all updates. | `boolean` | false | -| **type** | Chart.js chart type. | `{'line'` \| `'bar'` \| `'radar'` \| `'doughnut'` \| `'polarArea'` \| `'bubble'` \| `'pie'` \| `'scatter'}` | bar | -| **width** | Width attribute applied to the rendered canvas. | `number` | 300 | -| **wrapper** | Put the chart into the wrapper div element. | `boolean` | true | diff --git a/packages/docs/content/api/CCharts.api.mdx b/packages/docs/content/api/CCharts.api.mdx deleted file mode 100644 index 8ab5082b..00000000 --- a/packages/docs/content/api/CCharts.api.mdx +++ /dev/null @@ -1,23 +0,0 @@ - -```jsx -import { CChartBar } from '@coreui/react-chartjs' -// or -import CChartBar from '@coreui/react-chartjs/src/CCharts' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **customTooltips** | Enables custom html based tooltips instead of standard tooltips. | `boolean` | true | -| **data** | The data object that is passed into the Chart.js chart (more info). | `ChartData<keyof ChartTypeRegistry, (number` \| `[number, number]` \| `Point` \| `BubbleDataPoint)[], unknown>` \| `((canvas: HTMLCanvasElement) => ChartData<...>)` | - | -| **fallbackContent** | A fallback for when the canvas cannot be rendered. Can be used for accessible chart descriptions. | `React.ReactNode` | - | -| **getDatasetAtEvent** | Proxy for Chart.js getDatasetAtEvent. Calls with dataset and triggering event. | `(dataset: InteractionItem[], event: React.MouseEvent<HTMLCanvasElement>) => void` | - | -| **getElementAtEvent** | Proxy for Chart.js getElementAtEvent. Calls with single element array and triggering event. | `(element: InteractionItem[], event: React.MouseEvent<HTMLCanvasElement>) => void` | - | -| **getElementsAtEvent** | Proxy for Chart.js getElementsAtEvent. Calls with element array and triggering event. | `(elements: InteractionItem[], event: React.MouseEvent<HTMLCanvasElement>) => void` | - | -| **height** | Height attribute applied to the rendered canvas. | `number` | 150 | -| **id** | ID attribute applied to the rendered canvas. | `string` | - | -| **options** | The options object that is passed into the Chart.js chart. | `_DeepPartialObject<CoreChartOptions<keyof ChartTypeRegistry> & ElementChartOptions<keyof ChartTypeRegistry> & PluginChartOptions<...> & DatasetChartOptions<...> & ScaleChartOptions<...>>` | - | -| **plugins** | The plugins array that is passed into the Chart.js chart (more info) | `Plugin<keyof ChartTypeRegistry, AnyObject>[]` | - | -| **redraw** | If true, will tear down and redraw chart on all updates. | `boolean` | false | -| **width** | Width attribute applied to the rendered canvas. | `number` | 300 | -| **wrapper** | Put the chart into the wrapper div element. | `boolean` | true | diff --git a/packages/docs/content/api/CCloseButton.api.mdx b/packages/docs/content/api/CCloseButton.api.mdx deleted file mode 100644 index c7517889..00000000 --- a/packages/docs/content/api/CCloseButton.api.mdx +++ /dev/null @@ -1,13 +0,0 @@ - -```jsx -import { CCloseButton } from '@coreui/react' -// or -import CCloseButton from '@coreui/react/src/components/close-button/CCloseButton' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **dark** | Invert the default color. | `boolean` | - | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | -| **white** **_Deprecated 5.0.0+_** | Change the default color to white. | `boolean` | - | diff --git a/packages/docs/content/api/CCol.api.mdx b/packages/docs/content/api/CCol.api.mdx deleted file mode 100644 index c0c1566d..00000000 --- a/packages/docs/content/api/CCol.api.mdx +++ /dev/null @@ -1,16 +0,0 @@ - -```jsx -import { CCol } from '@coreui/react' -// or -import CCol from '@coreui/react/src/components/grid/CCol' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **lg** | The number of columns/offset/order on large devices (\<1200px). | `{ 'auto'` \| `number` \| `string` \| `boolean` \| `{ span: 'auto'` \| `number` \| `string` \| `boolean }` \| `{ offset: number` \| `string }` \| `{ order: 'first'` \| `'last'` \| `number` \| `string }}` | - | -| **md** | The number of columns/offset/order on medium devices (\<992px). | `{ 'auto'` \| `number` \| `string` \| `boolean` \| `{ span: 'auto'` \| `number` \| `string` \| `boolean }` \| `{ offset: number` \| `string }` \| `{ order: 'first'` \| `'last'` \| `number` \| `string }}` | - | -| **sm** | The number of columns/offset/order on small devices (\<768px). | `{ 'auto'` \| `number` \| `string` \| `boolean` \| `{ span: 'auto'` \| `number` \| `string` \| `boolean }` \| `{ offset: number` \| `string }` \| `{ order: 'first'` \| `'last'` \| `number` \| `string }}` | - | -| **xl** | The number of columns/offset/order on X-Large devices (\<1400px). | `{ 'auto'` \| `number` \| `string` \| `boolean` \| `{ span: 'auto'` \| `number` \| `string` \| `boolean }` \| `{ offset: number` \| `string }` \| `{ order: 'first'` \| `'last'` \| `number` \| `string }}` | - | -| **xs** | The number of columns/offset/order on extra small devices (\<576px). | `{ 'auto'` \| `number` \| `string` \| `boolean` \| `{ span: 'auto'` \| `number` \| `string` \| `boolean }` \| `{ offset: number` \| `string }` \| `{ order: 'first'` \| `'last'` \| `number` \| `string }}` | - | -| **xxl** | The number of columns/offset/order on XX-Large devices (≥1400px). | `{ 'auto'` \| `number` \| `string` \| `boolean` \| `{ span: 'auto'` \| `number` \| `string` \| `boolean }` \| `{ offset: number` \| `string }` \| `{ order: 'first'` \| `'last'` \| `number` \| `string }}` | - | diff --git a/packages/docs/content/api/CCollapse.api.mdx b/packages/docs/content/api/CCollapse.api.mdx deleted file mode 100644 index c2b78d28..00000000 --- a/packages/docs/content/api/CCollapse.api.mdx +++ /dev/null @@ -1,14 +0,0 @@ - -```jsx -import { CCollapse } from '@coreui/react' -// or -import CCollapse from '@coreui/react/src/components/collapse/CCollapse' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **horizontal** | Set horizontal collapsing to transition the width instead of height. | `boolean` | - | -| **onHide** | Callback fired when the component requests to be hidden. | `() => void` | - | -| **onShow** | Callback fired when the component requests to be shown. | `() => void` | - | -| **visible** | Toggle the visibility of component. | `boolean` | - | diff --git a/packages/docs/content/api/CConditionalPortal.api.mdx b/packages/docs/content/api/CConditionalPortal.api.mdx deleted file mode 100644 index 4a269bf2..00000000 --- a/packages/docs/content/api/CConditionalPortal.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CConditionalPortal } from '@coreui/react' -// or -import CConditionalPortal from '@coreui/react/src/components/conditional-portal/CConditionalPortal' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **container** **_v4.11.0+_** | An HTML element or function that returns a single element, with `document.body` as the default. | `Element` \| `(() => Element)` | - | -| **portal** | Render some children into a different part of the DOM | `any` | - | diff --git a/packages/docs/content/api/CContainer.api.mdx b/packages/docs/content/api/CContainer.api.mdx deleted file mode 100644 index db6dcb4a..00000000 --- a/packages/docs/content/api/CContainer.api.mdx +++ /dev/null @@ -1,16 +0,0 @@ - -```jsx -import { CContainer } from '@coreui/react' -// or -import CContainer from '@coreui/react/src/components/grid/CContainer' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **fluid** | Set container 100% wide, spanning the entire width of the viewport. | `boolean` | - | -| **lg** | Set container 100% wide until large breakpoint. | `boolean` | - | -| **md** | Set container 100% wide until medium breakpoint. | `boolean` | - | -| **sm** | Set container 100% wide until small breakpoint. | `boolean` | - | -| **xl** | Set container 100% wide until X-large breakpoint. | `boolean` | - | -| **xxl** | Set container 100% wide until XX-large breakpoint. | `boolean` | - | diff --git a/packages/docs/content/api/CDropdown.api.mdx b/packages/docs/content/api/CDropdown.api.mdx deleted file mode 100644 index 7e4c3d32..00000000 --- a/packages/docs/content/api/CDropdown.api.mdx +++ /dev/null @@ -1,24 +0,0 @@ - -```jsx -import { CDropdown } from '@coreui/react' -// or -import CDropdown from '@coreui/react/src/components/dropdown/CDropdown' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **alignment** | Set aligment of dropdown menu. | `'start'` \| `'end'` \| `{ xs: 'start'` \| `'end' }` \| `{ sm: 'start'` \| `'end' }` \| `{ md: 'start'` \| `'end' }` \| `{ lg: 'start'` \| `'end' }` \| `{ xl: 'start'` \| `'end'}` \| `{ xxl: 'start'` \| `'end'}` | - | -| **autoClose** | Configure the auto close behavior of the dropdown:<br/>- `true` - the dropdown will be closed by clicking outside or inside the dropdown menu.<br/>- `false` - the dropdown will be closed by clicking the toggle button and manually calling hide or toggle method. (Also will not be closed by pressing esc key)<br/>- `'inside'` - the dropdown will be closed (only) by clicking inside the dropdown menu.<br/>- `'outside'` - the dropdown will be closed (only) by clicking outside the dropdown menu. | `boolean` \| `'inside'` \| `'outside'` | true | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | div | -| **container** **_v4.11.0+_** | Appends the react dropdown menu to a specific element. You can pass an HTML element or function that returns a single element. By default `document.body`. | `Element` \| `(() => Element)` | - | -| **dark** | Sets a darker color scheme to match a dark navbar. | `boolean` | - | -| **direction** | Sets a specified direction and location of the dropdown menu. | `'center'` \| `'dropup'` \| `'dropup-center'` \| `'dropend'` \| `'dropstart'` | - | -| **offset** | Offset of the dropdown menu relative to its target. | `[number, number]` | [0, 2] | -| **onHide** **_4.9.0+_** | Callback fired when the component requests to be hidden. | `() => void` | - | -| **onShow** | Callback fired when the component requests to be shown. | `() => void` | - | -| **placement** | Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. | `'auto'` \| `'top-end'` \| `'top'` \| `'top-start'` \| `'bottom-end'` \| `'bottom'` \| `'bottom-start'` \| `'right-start'` \| `'right'` \| `'right-end'` \| `'left-start'` \| `'left'` \| `'left-end'` | bottom-start | -| **popper** | If you want to disable dynamic positioning set this property to `true`. | `boolean` | true | -| **portal** **_4.8.0+_** | Generates dropdown menu using createPortal. | `boolean` | false | -| **variant** | Set the dropdown variant to an btn-group, dropdown, input-group, and nav-item. | `'btn-group'` \| `'dropdown'` \| `'input-group'` \| `'nav-item'` | btn-group | -| **visible** | Toggle the visibility of dropdown menu component. | `boolean` | false | diff --git a/packages/docs/content/api/CDropdownDivider.api.mdx b/packages/docs/content/api/CDropdownDivider.api.mdx deleted file mode 100644 index 9228a01f..00000000 --- a/packages/docs/content/api/CDropdownDivider.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CDropdownDivider } from '@coreui/react' -// or -import CDropdownDivider from '@coreui/react/src/components/dropdown/CDropdownDivider' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CDropdownHeader.api.mdx b/packages/docs/content/api/CDropdownHeader.api.mdx deleted file mode 100644 index 84c57f51..00000000 --- a/packages/docs/content/api/CDropdownHeader.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CDropdownHeader } from '@coreui/react' -// or -import CDropdownHeader from '@coreui/react/src/components/dropdown/CDropdownHeader' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CDropdownItem.api.mdx b/packages/docs/content/api/CDropdownItem.api.mdx deleted file mode 100644 index b481683c..00000000 --- a/packages/docs/content/api/CDropdownItem.api.mdx +++ /dev/null @@ -1,14 +0,0 @@ - -```jsx -import { CDropdownItem } from '@coreui/react' -// or -import CDropdownItem from '@coreui/react/src/components/dropdown/CDropdownItem' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Toggle the active state for the component. | `boolean` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | a | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | -| **href** | The href attribute specifies the URL of the page the link goes to. | `string` | - | diff --git a/packages/docs/content/api/CDropdownItemPlain.api.mdx b/packages/docs/content/api/CDropdownItemPlain.api.mdx deleted file mode 100644 index 9f667026..00000000 --- a/packages/docs/content/api/CDropdownItemPlain.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CDropdownItemPlain } from '@coreui/react' -// or -import CDropdownItemPlain from '@coreui/react/src/components/dropdown/CDropdownItemPlain' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CDropdownMenu.api.mdx b/packages/docs/content/api/CDropdownMenu.api.mdx deleted file mode 100644 index 64a586fc..00000000 --- a/packages/docs/content/api/CDropdownMenu.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CDropdownMenu } from '@coreui/react' -// or -import CDropdownMenu from '@coreui/react/src/components/dropdown/CDropdownMenu' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CDropdownToggle.api.mdx b/packages/docs/content/api/CDropdownToggle.api.mdx deleted file mode 100644 index cece42db..00000000 --- a/packages/docs/content/api/CDropdownToggle.api.mdx +++ /dev/null @@ -1,24 +0,0 @@ - -```jsx -import { CDropdownToggle } from '@coreui/react' -// or -import CDropdownToggle from '@coreui/react/src/components/dropdown/CDropdownToggle' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Toggle the active state for the component. | `boolean` | - | -| **caret** | Enables pseudo element caret on toggler. | `boolean` | true | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **custom** | Create a custom toggler which accepts any content. | `boolean` | - | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | -| **href** | The href attribute specifies the URL of the page the link goes to. | `string` | - | -| **navLink** **_v5.0.0-rc.0+_** | If a dropdown `variant` is set to `nav-item` then render the toggler as a link instead of a button. | `boolean` | true | -| **role** | The role attribute describes the role of an element in programs that can make use of it, such as screen readers or magnifiers. | `string` | - | -| **shape** | Select the shape of the component. | `'rounded'` \| `'rounded-top'` \| `'rounded-end'` \| `'rounded-bottom'` \| `'rounded-start'` \| `'rounded-circle'` \| `'rounded-pill'` \| `'rounded-0'` \| `'rounded-1'` \| `'rounded-2'` \| `'rounded-3'` \| `string` | - | -| **size** | Size the component small or large. | `'sm'` \| `'lg'` | - | -| **split** | Similarly, create split button dropdowns with virtually the same markup as single button dropdowns, but with the addition of `.dropdown-toggle-split` className for proper spacing around the dropdown caret. | `boolean` | - | -| **trigger** | Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. | `'hover'` \| `'focus'` \| `'click'` | click | -| **variant** | Set the button variant to an outlined button or a ghost button. | `'outline'` \| `'ghost'` | - | diff --git a/packages/docs/content/api/CFooter.api.mdx b/packages/docs/content/api/CFooter.api.mdx deleted file mode 100644 index b6d11d4b..00000000 --- a/packages/docs/content/api/CFooter.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CFooter } from '@coreui/react' -// or -import CFooter from '@coreui/react/src/components/footer/CFooter' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **position** | Place footer in non-static positions. | `'fixed'` \| `'sticky'` | - | diff --git a/packages/docs/content/api/CForm.api.mdx b/packages/docs/content/api/CForm.api.mdx deleted file mode 100644 index 9759844f..00000000 --- a/packages/docs/content/api/CForm.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CForm } from '@coreui/react' -// or -import CForm from '@coreui/react/src/components/form/CForm' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **validated** | Mark a form as validated. If you set it `true`, all validation styles will be applied to the forms component. | `boolean` | - | diff --git a/packages/docs/content/api/CFormCheck.api.mdx b/packages/docs/content/api/CFormCheck.api.mdx deleted file mode 100644 index 43472818..00000000 --- a/packages/docs/content/api/CFormCheck.api.mdx +++ /dev/null @@ -1,25 +0,0 @@ - -```jsx -import { CFormCheck } from '@coreui/react' -// or -import CFormCheck from '@coreui/react/src/components/form/CFormCheck' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **button** | Create button-like checkboxes and radio buttons. | `ButtonObject` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **feedback** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackInvalid** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackValid** **_4.2.0+_** | Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **floatingLabel** **_4.2.0+_** | Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **hitArea** | Sets hit area to the full area of the component. | `'full'` | - | -| **id** | The id global attribute defines an identifier (ID) that must be unique in the whole document. | `string` | - | -| **indeterminate** | Input Checkbox indeterminate Property. | `boolean` | - | -| **inline** | Group checkboxes or radios on the same horizontal row. | `boolean` | - | -| **invalid** | Set component validation state to invalid. | `boolean` | - | -| **label** | The element represents a caption for a component. | `ReactNode` | - | -| **reverse** | Put checkboxes or radios on the opposite side. | `boolean` | - | -| **tooltipFeedback** **_4.2.0+_** | Display validation feedback in a styled tooltip. | `boolean` | - | -| **type** | Specifies the type of component. | `'checkbox'` \| `'radio'` | checkbox | -| **valid** | Set component validation state to valid. | `boolean` | - | diff --git a/packages/docs/content/api/CFormControlValidation.api.mdx b/packages/docs/content/api/CFormControlValidation.api.mdx deleted file mode 100644 index 371e9918..00000000 --- a/packages/docs/content/api/CFormControlValidation.api.mdx +++ /dev/null @@ -1,16 +0,0 @@ - -```jsx -import { CFormControlValidation } from '@coreui/react' -// or -import CFormControlValidation from '@coreui/react/src/components/form/CFormControlValidation' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **feedback** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackInvalid** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackValid** **_4.2.0+_** | Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **floatingLabel** **_4.2.0+_** | Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **invalid** | Set component validation state to invalid. | `boolean` | - | -| **tooltipFeedback** **_4.2.0+_** | Display validation feedback in a styled tooltip. | `boolean` | - | -| **valid** | Set component validation state to valid. | `boolean` | - | diff --git a/packages/docs/content/api/CFormControlWrapper.api.mdx b/packages/docs/content/api/CFormControlWrapper.api.mdx deleted file mode 100644 index 4f412d96..00000000 --- a/packages/docs/content/api/CFormControlWrapper.api.mdx +++ /dev/null @@ -1,19 +0,0 @@ - -```jsx -import { CFormControlWrapper } from '@coreui/react' -// or -import CFormControlWrapper from '@coreui/react/src/components/form/CFormControlWrapper' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **feedback** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackInvalid** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackValid** **_4.2.0+_** | Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **floatingClassName** **_4.5.0+_** | A string of all className you want applied to the floating label wrapper. | `string` | - | -| **floatingLabel** **_4.2.0+_** | Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **invalid** | Set component validation state to invalid. | `boolean` | - | -| **label** **_4.2.0+_** | Add a caption for a component. | `ReactNode` | - | -| **text** **_4.2.0+_** | Add helper text to the component. | `ReactNode` | - | -| **tooltipFeedback** **_4.2.0+_** | Display validation feedback in a styled tooltip. | `boolean` | - | -| **valid** | Set component validation state to valid. | `boolean` | - | diff --git a/packages/docs/content/api/CFormFeedback.api.mdx b/packages/docs/content/api/CFormFeedback.api.mdx deleted file mode 100644 index aaffca2b..00000000 --- a/packages/docs/content/api/CFormFeedback.api.mdx +++ /dev/null @@ -1,14 +0,0 @@ - -```jsx -import { CFormFeedback } from '@coreui/react' -// or -import CFormFeedback from '@coreui/react/src/components/form/CFormFeedback' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **invalid** | Method called immediately after the `value` prop changes. | `boolean` | - | -| **tooltip** | If your form layout allows it, you can display validation feedback in a styled tooltip. | `boolean` | - | -| **valid** | Set component validation state to valid. | `boolean` | - | diff --git a/packages/docs/content/api/CFormFloating.api.mdx b/packages/docs/content/api/CFormFloating.api.mdx deleted file mode 100644 index 5a7f7d76..00000000 --- a/packages/docs/content/api/CFormFloating.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CFormFloating } from '@coreui/react' -// or -import CFormFloating from '@coreui/react/src/components/form/CFormFloating' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CFormInput.api.mdx b/packages/docs/content/api/CFormInput.api.mdx deleted file mode 100644 index a48c769f..00000000 --- a/packages/docs/content/api/CFormInput.api.mdx +++ /dev/null @@ -1,28 +0,0 @@ - -```jsx -import { CFormInput } from '@coreui/react' -// or -import CFormInput from '@coreui/react/src/components/form/CFormInput' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **delay** | Delay onChange event while typing. If set to true onChange event will be delayed 500ms, you can also provide the number of milliseconds you want to delay the onChange event. | `number` \| `boolean` | false | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | -| **feedback** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackInvalid** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackValid** **_4.2.0+_** | Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **floatingClassName** **_4.5.0+_** | A string of all className you want applied to the floating label wrapper. | `string` | - | -| **floatingLabel** **_4.2.0+_** | Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **invalid** | Set component validation state to invalid. | `boolean` | - | -| **label** **_4.2.0+_** | Add a caption for a component. | `ReactNode` | - | -| **onChange** | Method called immediately after the `value` prop changes. | `ChangeEventHandler<HTMLInputElement>` | - | -| **plainText** | Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`. | `boolean` | - | -| **readOnly** | Toggle the readonly state for the component. | `boolean` | - | -| **size** | Size the component small or large. | `'sm'` \| `'lg'` | - | -| **text** **_4.2.0+_** | Add helper text to the component. | `ReactNode` | - | -| **tooltipFeedback** **_4.2.0+_** | Display validation feedback in a styled tooltip. | `boolean` | - | -| **type** | Specifies the type of component. | `string` | text | -| **valid** | Set component validation state to valid. | `boolean` | - | -| **value** | The `value` attribute of component. | `string` \| `number` \| `string[]` | - | diff --git a/packages/docs/content/api/CFormLabel.api.mdx b/packages/docs/content/api/CFormLabel.api.mdx deleted file mode 100644 index 8d6d5ffc..00000000 --- a/packages/docs/content/api/CFormLabel.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CFormLabel } from '@coreui/react' -// or -import CFormLabel from '@coreui/react/src/components/form/CFormLabel' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **customClassName** | A string of all className you want to be applied to the component, and override standard className value. | `string` | - | diff --git a/packages/docs/content/api/CFormRange.api.mdx b/packages/docs/content/api/CFormRange.api.mdx deleted file mode 100644 index f2b5a83f..00000000 --- a/packages/docs/content/api/CFormRange.api.mdx +++ /dev/null @@ -1,18 +0,0 @@ - -```jsx -import { CFormRange } from '@coreui/react' -// or -import CFormRange from '@coreui/react/src/components/form/CFormRange' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | -| **label** **_4.2.0+_** | Add a caption for a component. | `ReactNode` | - | -| **max** | Specifies the maximum value for the component. | `number` | - | -| **min** | Specifies the minimum value for the component. | `number` | - | -| **onChange** | Method called immediately after the `value` prop changes. | `ChangeEventHandler<HTMLInputElement>` | - | -| **readOnly** | Toggle the readonly state for the component. | `boolean` | - | -| **step** | Specifies the interval between legal numbers in the component. | `number` | - | -| **value** | The `value` attribute of component. | `string` \| `number` \| `string[]` | - | diff --git a/packages/docs/content/api/CFormSelect.api.mdx b/packages/docs/content/api/CFormSelect.api.mdx deleted file mode 100644 index f507ca9f..00000000 --- a/packages/docs/content/api/CFormSelect.api.mdx +++ /dev/null @@ -1,25 +0,0 @@ - -```jsx -import { CFormSelect } from '@coreui/react' -// or -import CFormSelect from '@coreui/react/src/components/form/CFormSelect' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **feedback** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackInvalid** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackValid** **_4.2.0+_** | Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **floatingClassName** **_4.5.0+_** | A string of all className you want applied to the floating label wrapper. | `string` | - | -| **floatingLabel** **_4.2.0+_** | Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **htmlSize** | Specifies the number of visible options in a drop-down list. | `number` | - | -| **invalid** | Set component validation state to invalid. | `boolean` | - | -| **label** **_4.2.0+_** | Add a caption for a component. | `ReactNode` | - | -| **onChange** | Method called immediately after the `value` prop changes. | `ChangeEventHandler<HTMLSelectElement>` | - | -| **options** | Options list of the select component. Available keys: `label`, `value`, `disabled`.<br/>Examples:<br/>- `options={[{ value: 'js', label: 'JavaScript' }, { value: 'html', label: 'HTML', disabled: true }]}`<br/>- `options={['js', 'html']}` | `Option[]` \| `string[]` | - | -| **size** | Size the component small or large. | `'sm'` \| `'lg'` | - | -| **text** **_4.2.0+_** | Add helper text to the component. | `ReactNode` | - | -| **tooltipFeedback** **_4.2.0+_** | Display validation feedback in a styled tooltip. | `boolean` | - | -| **valid** | Set component validation state to valid. | `boolean` | - | -| **value** | The `value` attribute of component. | `string` \| `number` \| `string[]` | - | diff --git a/packages/docs/content/api/CFormSwitch.api.mdx b/packages/docs/content/api/CFormSwitch.api.mdx deleted file mode 100644 index fa8e1bf0..00000000 --- a/packages/docs/content/api/CFormSwitch.api.mdx +++ /dev/null @@ -1,17 +0,0 @@ - -```jsx -import { CFormSwitch } from '@coreui/react' -// or -import CFormSwitch from '@coreui/react/src/components/form/CFormSwitch' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **id** | The id global attribute defines an identifier (ID) that must be unique in the whole document. | `string` | - | -| **invalid** | Set component validation state to invalid. | `boolean` | - | -| **label** | The element represents a caption for a component. | `ReactNode` | - | -| **reverse** | Put switch on the opposite side. | `boolean` | - | -| **size** | Size the component large or extra large. Works only with `switch`. | `'lg'` \| `'xl'` | - | -| **type** | Specifies the type of component. | `'checkbox'` \| `'radio'` | checkbox | -| **valid** | Set component validation state to valid. | `boolean` | - | diff --git a/packages/docs/content/api/CFormText.api.mdx b/packages/docs/content/api/CFormText.api.mdx deleted file mode 100644 index 218c9ea5..00000000 --- a/packages/docs/content/api/CFormText.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CFormText } from '@coreui/react' -// or -import CFormText from '@coreui/react/src/components/form/CFormText' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CFormTextarea.api.mdx b/packages/docs/content/api/CFormTextarea.api.mdx deleted file mode 100644 index 552a328a..00000000 --- a/packages/docs/content/api/CFormTextarea.api.mdx +++ /dev/null @@ -1,25 +0,0 @@ - -```jsx -import { CFormTextarea } from '@coreui/react' -// or -import CFormTextarea from '@coreui/react/src/components/form/CFormTextarea' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | -| **feedback** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackInvalid** **_4.2.0+_** | Provide valuable, actionable feedback. | `ReactNode` | - | -| **feedbackValid** **_4.2.0+_** | Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **floatingClassName** **_4.5.0+_** | A string of all className you want applied to the floating label wrapper. | `string` | - | -| **floatingLabel** **_4.2.0+_** | Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | `ReactNode` | - | -| **invalid** | Set component validation state to invalid. | `boolean` | - | -| **label** **_4.2.0+_** | Add a caption for a component. | `ReactNode` | - | -| **onChange** | Method called immediately after the `value` prop changes. | `ChangeEventHandler<HTMLTextAreaElement>` | - | -| **plainText** | Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`. | `boolean` | - | -| **readOnly** | Toggle the readonly state for the component. | `boolean` | - | -| **text** **_4.2.0+_** | Add helper text to the component. | `ReactNode` | - | -| **tooltipFeedback** **_4.2.0+_** | Display validation feedback in a styled tooltip. | `boolean` | - | -| **valid** | Set component validation state to valid. | `boolean` | - | -| **value** | The `value` attribute of component. | `string` \| `number` \| `string[]` | - | diff --git a/packages/docs/content/api/CHeader.api.mdx b/packages/docs/content/api/CHeader.api.mdx deleted file mode 100644 index ae583495..00000000 --- a/packages/docs/content/api/CHeader.api.mdx +++ /dev/null @@ -1,12 +0,0 @@ - -```jsx -import { CHeader } from '@coreui/react' -// or -import CHeader from '@coreui/react/src/components/header/CHeader' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **container** | Defines optional container wrapping children elements. | `boolean` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` \| `'xxl'` \| `'fluid'` | - | -| **position** | Place header in non-static positions. | `'fixed'` \| `'sticky'` | - | diff --git a/packages/docs/content/api/CHeaderBrand.api.mdx b/packages/docs/content/api/CHeaderBrand.api.mdx deleted file mode 100644 index 254cab74..00000000 --- a/packages/docs/content/api/CHeaderBrand.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CHeaderBrand } from '@coreui/react' -// or -import CHeaderBrand from '@coreui/react/src/components/header/CHeaderBrand' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CHeaderDivider.api.mdx b/packages/docs/content/api/CHeaderDivider.api.mdx deleted file mode 100644 index b779fdf3..00000000 --- a/packages/docs/content/api/CHeaderDivider.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CHeaderDivider } from '@coreui/react' -// or -import CHeaderDivider from '@coreui/react/src/components/header/CHeaderDivider' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CHeaderNav.api.mdx b/packages/docs/content/api/CHeaderNav.api.mdx deleted file mode 100644 index 7276d442..00000000 --- a/packages/docs/content/api/CHeaderNav.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CHeaderNav } from '@coreui/react' -// or -import CHeaderNav from '@coreui/react/src/components/header/CHeaderNav' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CHeaderText.api.mdx b/packages/docs/content/api/CHeaderText.api.mdx deleted file mode 100644 index bcae33fa..00000000 --- a/packages/docs/content/api/CHeaderText.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CHeaderText } from '@coreui/react' -// or -import CHeaderText from '@coreui/react/src/components/header/CHeaderText' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CHeaderToggler.api.mdx b/packages/docs/content/api/CHeaderToggler.api.mdx deleted file mode 100644 index 63b8d754..00000000 --- a/packages/docs/content/api/CHeaderToggler.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CHeaderToggler } from '@coreui/react' -// or -import CHeaderToggler from '@coreui/react/src/components/header/CHeaderToggler' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CIcon.api.mdx b/packages/docs/content/api/CIcon.api.mdx deleted file mode 100644 index 83244b3c..00000000 --- a/packages/docs/content/api/CIcon.api.mdx +++ /dev/null @@ -1,20 +0,0 @@ - -```jsx -import { CIcon } from '@coreui/icons-react' -// or -import CIcon from '@coreui/icons-react/src/CIcon' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **content** **_Deprecated 3.0+_** | Use `icon={...}` instead of | `string` \| `string[]` | - | -| **customClassName** | Use for replacing default CIcon component classes. Prop is overriding the 'size' prop. | `string` \| `string[]` | - | -| **height** | The height attribute defines the vertical length of an icon. | `number` | - | -| **icon** | Name of the icon placed in React object or SVG content. | `string` \| `string[]` | - | -| **name** **_Deprecated 3.0+_** | Use `icon="..."` instead of | `string` | - | -| **size** | Size of the icon. Available sizes: 'sm', 'lg', 'xl', 'xxl', '3xl...9xl', 'custom', 'custom-size'. | `'custom'` \| `'custom-size'` \| `'sm'` \| `'lg'` \| `'xl'` \| `'xxl'` \| `'3xl'` \| `'4xl'` \| `'5xl'` \| `'6xl'` \| `'7xl'` \| `'8xl'` \| `'9xl'` | - | -| **title** | Title tag content. | `string` | - | -| **use** | If defined component will be rendered using 'use' tag. | `string` | - | -| **viewBox** | The viewBox attribute defines the position and dimension of an SVG viewport. | `string` | - | -| **width** | The width attribute defines the horizontal length of an icon. | `number` | - | diff --git a/packages/docs/content/api/CImage.api.mdx b/packages/docs/content/api/CImage.api.mdx deleted file mode 100644 index 1c5a685c..00000000 --- a/packages/docs/content/api/CImage.api.mdx +++ /dev/null @@ -1,14 +0,0 @@ - -```jsx -import { CImage } from '@coreui/react' -// or -import CImage from '@coreui/react/src/components/image/CImage' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **align** | Set the horizontal aligment. | `'start'` \| `'center'` \| `'end'` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **fluid** | Make image responsive. | `boolean` | - | -| **rounded** | Make image rounded. | `boolean` | - | -| **thumbnail** | Give an image a rounded 1px border appearance. | `boolean` | - | diff --git a/packages/docs/content/api/CInputGroup.api.mdx b/packages/docs/content/api/CInputGroup.api.mdx deleted file mode 100644 index 25adc26c..00000000 --- a/packages/docs/content/api/CInputGroup.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CInputGroup } from '@coreui/react' -// or -import CInputGroup from '@coreui/react/src/components/form/CInputGroup' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **size** | Size the component small or large. | `'sm'` \| `'lg'` | - | diff --git a/packages/docs/content/api/CInputGroupText.api.mdx b/packages/docs/content/api/CInputGroupText.api.mdx deleted file mode 100644 index 26af8dd6..00000000 --- a/packages/docs/content/api/CInputGroupText.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CInputGroupText } from '@coreui/react' -// or -import CInputGroupText from '@coreui/react/src/components/form/CInputGroupText' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CLink.api.mdx b/packages/docs/content/api/CLink.api.mdx deleted file mode 100644 index 50dc418a..00000000 --- a/packages/docs/content/api/CLink.api.mdx +++ /dev/null @@ -1,14 +0,0 @@ - -```jsx -import { CLink } from '@coreui/react' -// or -import CLink from '@coreui/react/src/components/link/CLink' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Toggle the active state for the component. | `boolean` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | -| **href** | The href attribute specifies the URL of the page the link goes to. | `string` | - | diff --git a/packages/docs/content/api/CListGroup.api.mdx b/packages/docs/content/api/CListGroup.api.mdx deleted file mode 100644 index f6fe87b5..00000000 --- a/packages/docs/content/api/CListGroup.api.mdx +++ /dev/null @@ -1,13 +0,0 @@ - -```jsx -import { CListGroup } from '@coreui/react' -// or -import CListGroup from '@coreui/react/src/components/list-group/CListGroup' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **flush** | Remove some borders and rounded corners to render list group items edge-to-edge in a parent component (e.g., `<CCard>`). | `boolean` | - | -| **layout** | Specify a layout type. | `'horizontal'` \| `'horizontal-sm'` \| `'horizontal-md'` \| `'horizontal-lg'` \| `'horizontal-xl'` \| `'horizontal-xxl'` | - | diff --git a/packages/docs/content/api/CListGroupItem.api.mdx b/packages/docs/content/api/CListGroupItem.api.mdx deleted file mode 100644 index cc5850d2..00000000 --- a/packages/docs/content/api/CListGroupItem.api.mdx +++ /dev/null @@ -1,14 +0,0 @@ - -```jsx -import { CListGroupItem } from '@coreui/react' -// or -import CListGroupItem from '@coreui/react/src/components/list-group/CListGroupItem' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Toggle the active state for the component. | `boolean` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | li | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | diff --git a/packages/docs/content/api/CModal.api.mdx b/packages/docs/content/api/CModal.api.mdx deleted file mode 100644 index 635c688e..00000000 --- a/packages/docs/content/api/CModal.api.mdx +++ /dev/null @@ -1,24 +0,0 @@ - -```jsx -import { CModal } from '@coreui/react' -// or -import CModal from '@coreui/react/src/components/modal/CModal' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **alignment** | Align the modal in the center or top of the screen. | `'top'` \| `'center'` | - | -| **backdrop** | Apply a backdrop on body while modal is open. | `boolean` \| `'static'` | true | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **focus** **_v4.10.0+_** | Puts the focus on the modal when shown. | `boolean` | true | -| **fullscreen** | Set modal to covers the entire user viewport. | `boolean` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` \| `'xxl'` | - | -| **keyboard** | Closes the modal when escape key is pressed. | `boolean` | true | -| **onClose** | Callback fired when the component requests to be closed. | `() => void` | - | -| **onClosePrevented** | Callback fired when the component requests to be closed. | `() => void` | - | -| **onShow** | Callback fired when the modal is shown, its backdrop is static and a click outside the modal or an escape key press is performed with the keyboard option set to false. | `() => void` | - | -| **portal** | Generates modal using createPortal. | `boolean` | true | -| **scrollable** | Create a scrollable modal that allows scrolling the modal body. | `boolean` | - | -| **size** | Size the component small, large, or extra large. | `'sm'` \| `'lg'` \| `'xl'` | - | -| **transition** | Remove animation to create modal that simply appear rather than fade in to view. | `boolean` | true | -| **unmountOnClose** | By default the component is unmounted after close animation, if you want to keep the component mounted set this property to false. | `boolean` | true | -| **visible** | Toggle the visibility of modal component. | `boolean` | - | diff --git a/packages/docs/content/api/CModalBody.api.mdx b/packages/docs/content/api/CModalBody.api.mdx deleted file mode 100644 index be05908c..00000000 --- a/packages/docs/content/api/CModalBody.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CModalBody } from '@coreui/react' -// or -import CModalBody from '@coreui/react/src/components/modal/CModalBody' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CModalContent.api.mdx b/packages/docs/content/api/CModalContent.api.mdx deleted file mode 100644 index 3e4986c5..00000000 --- a/packages/docs/content/api/CModalContent.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CModalContent } from '@coreui/react' -// or -import CModalContent from '@coreui/react/src/components/modal/CModalContent' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CModalDialog.api.mdx b/packages/docs/content/api/CModalDialog.api.mdx deleted file mode 100644 index 4697259f..00000000 --- a/packages/docs/content/api/CModalDialog.api.mdx +++ /dev/null @@ -1,14 +0,0 @@ - -```jsx -import { CModalDialog } from '@coreui/react' -// or -import CModalDialog from '@coreui/react/src/components/modal/CModalDialog' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **alignment** | Align the modal in the center or top of the screen. | `'top'` \| `'center'` | - | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **fullscreen** | Set modal to covers the entire user viewport. | `boolean` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` \| `'xxl'` | - | -| **scrollable** | Does the modal dialog itself scroll, or does the whole dialog scroll within the window. | `boolean` | - | -| **size** | Size the component small, large, or extra large. | `'sm'` \| `'lg'` \| `'xl'` | - | diff --git a/packages/docs/content/api/CModalFooter.api.mdx b/packages/docs/content/api/CModalFooter.api.mdx deleted file mode 100644 index 3f52a784..00000000 --- a/packages/docs/content/api/CModalFooter.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CModalFooter } from '@coreui/react' -// or -import CModalFooter from '@coreui/react/src/components/modal/CModalFooter' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CModalHeader.api.mdx b/packages/docs/content/api/CModalHeader.api.mdx deleted file mode 100644 index 9c78e6e8..00000000 --- a/packages/docs/content/api/CModalHeader.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CModalHeader } from '@coreui/react' -// or -import CModalHeader from '@coreui/react/src/components/modal/CModalHeader' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **closeButton** | Add a close button component to the header. | `boolean` | true | diff --git a/packages/docs/content/api/CModalTitle.api.mdx b/packages/docs/content/api/CModalTitle.api.mdx deleted file mode 100644 index 8a579778..00000000 --- a/packages/docs/content/api/CModalTitle.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CModalTitle } from '@coreui/react' -// or -import CModalTitle from '@coreui/react/src/components/modal/CModalTitle' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CNav.api.mdx b/packages/docs/content/api/CNav.api.mdx deleted file mode 100644 index f9551c78..00000000 --- a/packages/docs/content/api/CNav.api.mdx +++ /dev/null @@ -1,13 +0,0 @@ - -```jsx -import { CNav } from '@coreui/react' -// or -import CNav from '@coreui/react/src/components/nav/CNav' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **layout** | Specify a layout type for component. | `'fill'` \| `'justified'` | - | -| **variant** | Set the nav variant to tabs or pills. | `'pills'` \| `'tabs'` \| `'underline'` \| `'underline-border'` | - | diff --git a/packages/docs/content/api/CNavGroup.api.mdx b/packages/docs/content/api/CNavGroup.api.mdx deleted file mode 100644 index 588453c6..00000000 --- a/packages/docs/content/api/CNavGroup.api.mdx +++ /dev/null @@ -1,13 +0,0 @@ - -```jsx -import { CNavGroup } from '@coreui/react' -// or -import CNavGroup from '@coreui/react/src/components/nav/CNavGroup' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **compact** | Make nav group more compact by cutting all `padding` in half. | `boolean` | - | -| **toggler** | Set group toggler label. | `ReactNode` | - | -| **visible** | Show nav group items. | `boolean` | - | diff --git a/packages/docs/content/api/CNavGroupItems.api.mdx b/packages/docs/content/api/CNavGroupItems.api.mdx deleted file mode 100644 index a8b95f41..00000000 --- a/packages/docs/content/api/CNavGroupItems.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CNavGroupItems } from '@coreui/react' -// or -import CNavGroupItems from '@coreui/react/src/components/nav/CNavGroupItems' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CNavItem.api.mdx b/packages/docs/content/api/CNavItem.api.mdx deleted file mode 100644 index 3b8694d2..00000000 --- a/packages/docs/content/api/CNavItem.api.mdx +++ /dev/null @@ -1,14 +0,0 @@ - -```jsx -import { CNavItem } from '@coreui/react' -// or -import CNavItem from '@coreui/react/src/components/nav/CNavItem' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Toggle the active state for the component. | `boolean` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | -| **href** | The href attribute specifies the URL of the page the link goes to. | `string` | - | diff --git a/packages/docs/content/api/CNavLink.api.mdx b/packages/docs/content/api/CNavLink.api.mdx deleted file mode 100644 index 2cf3d1ab..00000000 --- a/packages/docs/content/api/CNavLink.api.mdx +++ /dev/null @@ -1,14 +0,0 @@ - -```jsx -import { CNavLink } from '@coreui/react' -// or -import CNavLink from '@coreui/react/src/components/nav/CNavLink' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Toggle the active state for the component. | `boolean` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | -| **href** | The href attribute specifies the URL of the page the link goes to. | `string` | - | diff --git a/packages/docs/content/api/CNavTitle.api.mdx b/packages/docs/content/api/CNavTitle.api.mdx deleted file mode 100644 index 55e3da9f..00000000 --- a/packages/docs/content/api/CNavTitle.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CNavTitle } from '@coreui/react' -// or -import CNavTitle from '@coreui/react/src/components/nav/CNavTitle' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CNavbar.api.mdx b/packages/docs/content/api/CNavbar.api.mdx deleted file mode 100644 index 56c583bc..00000000 --- a/packages/docs/content/api/CNavbar.api.mdx +++ /dev/null @@ -1,16 +0,0 @@ - -```jsx -import { CNavbar } from '@coreui/react' -// or -import CNavbar from '@coreui/react/src/components/navbar/CNavbar' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **colorScheme** | Sets if the color of text should be colored for a light or dark background. | `'dark'` \| `'light'` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **container** | Defines optional container wrapping children elements. | `boolean` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` \| `'xxl'` \| `'fluid'` | - | -| **expand** | Defines the responsive breakpoint to determine when content collapses. | `boolean` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` \| `'xxl'` | - | -| **placement** | Place component in non-static positions. | `'fixed-top'` \| `'fixed-bottom'` \| `'sticky-top'` | - | diff --git a/packages/docs/content/api/CNavbarBrand.api.mdx b/packages/docs/content/api/CNavbarBrand.api.mdx deleted file mode 100644 index ecad53d3..00000000 --- a/packages/docs/content/api/CNavbarBrand.api.mdx +++ /dev/null @@ -1,12 +0,0 @@ - -```jsx -import { CNavbarBrand } from '@coreui/react' -// or -import CNavbarBrand from '@coreui/react/src/components/navbar/CNavbarBrand' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **href** | The href attribute specifies the URL of the page the link goes to. | `string` | - | diff --git a/packages/docs/content/api/CNavbarNav.api.mdx b/packages/docs/content/api/CNavbarNav.api.mdx deleted file mode 100644 index 654d7a0d..00000000 --- a/packages/docs/content/api/CNavbarNav.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CNavbarNav } from '@coreui/react' -// or -import CNavbarNav from '@coreui/react/src/components/navbar/CNavbarNav' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CNavbarText.api.mdx b/packages/docs/content/api/CNavbarText.api.mdx deleted file mode 100644 index 115a93b5..00000000 --- a/packages/docs/content/api/CNavbarText.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CNavbarText } from '@coreui/react' -// or -import CNavbarText from '@coreui/react/src/components/navbar/CNavbarText' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CNavbarToggler.api.mdx b/packages/docs/content/api/CNavbarToggler.api.mdx deleted file mode 100644 index 23763e4e..00000000 --- a/packages/docs/content/api/CNavbarToggler.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CNavbarToggler } from '@coreui/react' -// or -import CNavbarToggler from '@coreui/react/src/components/navbar/CNavbarToggler' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/COffcanvas.api.mdx b/packages/docs/content/api/COffcanvas.api.mdx deleted file mode 100644 index 5fc4c054..00000000 --- a/packages/docs/content/api/COffcanvas.api.mdx +++ /dev/null @@ -1,20 +0,0 @@ - -```jsx -import { COffcanvas } from '@coreui/react' -// or -import COffcanvas from '@coreui/react/src/components/offcanvas/COffcanvas' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **backdrop** | Apply a backdrop on body while offcanvas is open. | `boolean` \| `'static'` | true | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **dark** | Sets a darker color scheme. | `boolean` | - | -| **keyboard** | Closes the offcanvas when escape key is pressed. | `boolean` | true | -| **onHide** | Callback fired when the component requests to be hidden. | `() => void` | - | -| **onShow** | Callback fired when the component requests to be shown. | `() => void` | - | -| **placement** | Components placement, there’s no default placement. | `'start'` \| `'end'` \| `'top'` \| `'bottom'` | - | -| **portal** | Generates modal using createPortal. | `boolean` | false | -| **responsive** **_4.6.0+_** | Responsive offcanvas property hide content outside the viewport from a specified breakpoint and down. | `boolean` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` \| `'xxl'` | true | -| **scroll** | Allow body scrolling while offcanvas is open | `boolean` | false | -| **visible** | Toggle the visibility of offcanvas component. | `boolean` | false | diff --git a/packages/docs/content/api/COffcanvasBody.api.mdx b/packages/docs/content/api/COffcanvasBody.api.mdx deleted file mode 100644 index 07838824..00000000 --- a/packages/docs/content/api/COffcanvasBody.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { COffcanvasBody } from '@coreui/react' -// or -import COffcanvasBody from '@coreui/react/src/components/offcanvas/COffcanvasBody' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/COffcanvasHeader.api.mdx b/packages/docs/content/api/COffcanvasHeader.api.mdx deleted file mode 100644 index 6edbcc05..00000000 --- a/packages/docs/content/api/COffcanvasHeader.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { COffcanvasHeader } from '@coreui/react' -// or -import COffcanvasHeader from '@coreui/react/src/components/offcanvas/COffcanvasHeader' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/COffcanvasTitle.api.mdx b/packages/docs/content/api/COffcanvasTitle.api.mdx deleted file mode 100644 index 498aac41..00000000 --- a/packages/docs/content/api/COffcanvasTitle.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { COffcanvasTitle } from '@coreui/react' -// or -import COffcanvasTitle from '@coreui/react/src/components/offcanvas/COffcanvasTitle' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | diff --git a/packages/docs/content/api/CPagination.api.mdx b/packages/docs/content/api/CPagination.api.mdx deleted file mode 100644 index 39f9ea2d..00000000 --- a/packages/docs/content/api/CPagination.api.mdx +++ /dev/null @@ -1,12 +0,0 @@ - -```jsx -import { CPagination } from '@coreui/react' -// or -import CPagination from '@coreui/react/src/components/pagination/CPagination' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **align** | Set the alignment of pagination components. | `'start'` \| `'center'` \| `'end'` | - | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **size** | Size the component small or large. | `'sm'` \| `'lg'` | - | diff --git a/packages/docs/content/api/CPaginationItem.api.mdx b/packages/docs/content/api/CPaginationItem.api.mdx deleted file mode 100644 index cce2a3cd..00000000 --- a/packages/docs/content/api/CPaginationItem.api.mdx +++ /dev/null @@ -1,12 +0,0 @@ - -```jsx -import { CPaginationItem } from '@coreui/react' -// or -import CPaginationItem from '@coreui/react/src/components/pagination/CPaginationItem' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Toggle the active state for the component. | `boolean` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | diff --git a/packages/docs/content/api/CPlaceholder.api.mdx b/packages/docs/content/api/CPlaceholder.api.mdx deleted file mode 100644 index 85d0d399..00000000 --- a/packages/docs/content/api/CPlaceholder.api.mdx +++ /dev/null @@ -1,20 +0,0 @@ - -```jsx -import { CPlaceholder } from '@coreui/react' -// or -import CPlaceholder from '@coreui/react/src/components/placeholder/CPlaceholder' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **animation** | Set animation type to better convey the perception of something being actively loaded. | `'glow'` \| `'wave'` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **lg** | The number of columns on large devices (\<1200px). | `number` | - | -| **md** | The number of columns on medium devices (\<992px). | `number` | - | -| **size** | Size the component extra small, small, or large. | `'xs'` \| `'sm'` \| `'lg'` | - | -| **sm** | The number of columns on small devices (\<768px). | `number` | - | -| **xl** | The number of columns on X-Large devices (\<1400px). | `number` | - | -| **xs** | The number of columns on extra small devices (\<576px). | `number` | - | -| **xxl** | The number of columns on XX-Large devices (≥1400px). | `number` | - | diff --git a/packages/docs/content/api/CPopover.api.mdx b/packages/docs/content/api/CPopover.api.mdx deleted file mode 100644 index 40ad6fb7..00000000 --- a/packages/docs/content/api/CPopover.api.mdx +++ /dev/null @@ -1,22 +0,0 @@ - -```jsx -import { CPopover } from '@coreui/react' -// or -import CPopover from '@coreui/react/src/components/popover/CPopover' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **animation** **_4.9.0+_** | Apply a CSS fade transition to the popover. | `boolean` | true | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **container** **_v4.11.0+_** | Appends the react popover to a specific element. You can pass an HTML element or function that returns a single element. By default `document.body`. | `Element` \| `(() => Element)` | - | -| **content** | Content node for your component. | `ReactNode` | - | -| **delay** **_4.9.0+_** | The delay for displaying and hiding the popover (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`. | `number` \| `{ show: number; hide: number; }` | 0 | -| **fallbackPlacements** **_4.9.0+_** | Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference. | `Placements` \| `Placements[]` | ['top', 'right', 'bottom', 'left'] | -| **offset** | Offset of the popover relative to its target. | `[number, number]` | [0, 8] | -| **onHide** | Callback fired when the component requests to be hidden. | `() => void` | - | -| **onShow** | Callback fired when the component requests to be shown. | `() => void` | - | -| **placement** | Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. | `'auto'` \| `'top'` \| `'bottom'` \| `'right'` \| `'left'` | top | -| **title** | Title node for your component. | `ReactNode` | - | -| **trigger** | Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. | `'hover'` \| `'focus'` \| `'click'` | click | -| **visible** | Toggle the visibility of popover component. | `boolean` | - | diff --git a/packages/docs/content/api/CProgress.api.mdx b/packages/docs/content/api/CProgress.api.mdx deleted file mode 100644 index e7d61f16..00000000 --- a/packages/docs/content/api/CProgress.api.mdx +++ /dev/null @@ -1,18 +0,0 @@ - -```jsx -import { CProgress } from '@coreui/react' -// or -import CProgress from '@coreui/react/src/components/progress/CProgress' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **animated** | Use to animate the stripes right to left via CSS3 animations. | `boolean` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **height** | Sets the height of the component. If you set that value the inner `<CProgressBar>` will automatically resize accordingly. | `number` | - | -| **progressBarClassName** **_4.9.0+_** | A string of all className you want applied to the `<CProgressBar/>` component. | `string` | - | -| **thin** | Makes progress bar thinner. | `boolean` | - | -| **value** | The percent to progress the ProgressBar (out of 100). | `number` | - | -| **variant** | Set the progress bar variant to optional striped. | `'striped'` | - | -| **white** | Change the default color to white. | `boolean` | - | diff --git a/packages/docs/content/api/CProgressBar.api.mdx b/packages/docs/content/api/CProgressBar.api.mdx deleted file mode 100644 index 844d98e8..00000000 --- a/packages/docs/content/api/CProgressBar.api.mdx +++ /dev/null @@ -1,14 +0,0 @@ - -```jsx -import { CProgressBar } from '@coreui/react' -// or -import CProgressBar from '@coreui/react/src/components/progress/CProgressBar' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **animated** | Use to animate the stripes right to left via CSS3 animations. | `boolean` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **value** | The percent to progress the ProgressBar. | `number` | 0 | -| **variant** | Set the progress bar variant to optional striped. | `'striped'` | - | diff --git a/packages/docs/content/api/CProgressStacked.api.mdx b/packages/docs/content/api/CProgressStacked.api.mdx deleted file mode 100644 index 109af3cf..00000000 --- a/packages/docs/content/api/CProgressStacked.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CProgressStacked } from '@coreui/react' -// or -import CProgressStacked from '@coreui/react/src/components/progress/CProgressStacked' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CRow.api.mdx b/packages/docs/content/api/CRow.api.mdx deleted file mode 100644 index e0103350..00000000 --- a/packages/docs/content/api/CRow.api.mdx +++ /dev/null @@ -1,16 +0,0 @@ - -```jsx -import { CRow } from '@coreui/react' -// or -import CRow from '@coreui/react/src/components/grid/CRow' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **lg** | The number of columns/offset/order on large devices (\<1200px). | `{{ cols: 'auto'` \| `number` \| `string }` \| `{ gutter: number` \| `string }` \| `{ gutterX: number` \| `string }` \| `{ gutterY: number` \| `string }}` | - | -| **md** | The number of columns/offset/order on medium devices (\<992px). | `{{ cols: 'auto'` \| `number` \| `string }` \| `{ gutter: number` \| `string }` \| `{ gutterX: number` \| `string }` \| `{ gutterY: number` \| `string }}` | - | -| **sm** | The number of columns/offset/order on small devices (\<768px). | `{{ cols: 'auto'` \| `number` \| `string }` \| `{ gutter: number` \| `string }` \| `{ gutterX: number` \| `string }` \| `{ gutterY: number` \| `string }}` | - | -| **xl** | The number of columns/offset/order on X-Large devices (\<1400px). | `{{ cols: 'auto'` \| `number` \| `string }` \| `{ gutter: number` \| `string }` \| `{ gutterX: number` \| `string }` \| `{ gutterY: number` \| `string }}` | - | -| **xs** | The number of columns/offset/order on extra small devices (\<576px). | `{{ cols: 'auto'` \| `number` \| `string }` \| `{ gutter: number` \| `string }` \| `{ gutterX: number` \| `string }` \| `{ gutterY: number` \| `string }}` | - | -| **xxl** | The number of columns/offset/order on XX-Large devices (≥1400px). | `{{ cols: 'auto'` \| `number` \| `string }` \| `{ gutter: number` \| `string }` \| `{ gutterX: number` \| `string }` \| `{ gutterY: number` \| `string }}` | - | diff --git a/packages/docs/content/api/CSidebar.api.mdx b/packages/docs/content/api/CSidebar.api.mdx deleted file mode 100644 index 5fca3dce..00000000 --- a/packages/docs/content/api/CSidebar.api.mdx +++ /dev/null @@ -1,19 +0,0 @@ - -```jsx -import { CSidebar } from '@coreui/react' -// or -import CSidebar from '@coreui/react/src/components/sidebar/CSidebar' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **narrow** | Make sidebar narrow. | `boolean` | - | -| **onHide** | Callback fired when the component requests to be hidden. | `() => void` | - | -| **onShow** | Callback fired when the component requests to be shown. | `() => void` | - | -| **onVisibleChange** | Event emitted after visibility of component changed. | `(visible: boolean) => void` | - | -| **overlaid** | Set sidebar to overlaid variant. | `boolean` | - | -| **position** | Place sidebar in non-static positions. | `'fixed'` \| `'sticky'` | - | -| **size** | Size the component small, large, or extra large. | `'sm'` \| `'lg'` \| `'xl'` | - | -| **unfoldable** | Expand narrowed sidebar on hover. | `boolean` | - | -| **visible** | Toggle the visibility of sidebar component. | `boolean` | - | diff --git a/packages/docs/content/api/CSidebarBrand.api.mdx b/packages/docs/content/api/CSidebarBrand.api.mdx deleted file mode 100644 index c570b066..00000000 --- a/packages/docs/content/api/CSidebarBrand.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CSidebarBrand } from '@coreui/react' -// or -import CSidebarBrand from '@coreui/react/src/components/sidebar/CSidebarBrand' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CSidebarFooter.api.mdx b/packages/docs/content/api/CSidebarFooter.api.mdx deleted file mode 100644 index ec781c61..00000000 --- a/packages/docs/content/api/CSidebarFooter.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CSidebarFooter } from '@coreui/react' -// or -import CSidebarFooter from '@coreui/react/src/components/sidebar/CSidebarFooter' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CSidebarHeader.api.mdx b/packages/docs/content/api/CSidebarHeader.api.mdx deleted file mode 100644 index a854177d..00000000 --- a/packages/docs/content/api/CSidebarHeader.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CSidebarHeader } from '@coreui/react' -// or -import CSidebarHeader from '@coreui/react/src/components/sidebar/CSidebarHeader' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CSidebarNav.api.mdx b/packages/docs/content/api/CSidebarNav.api.mdx deleted file mode 100644 index 6f20b600..00000000 --- a/packages/docs/content/api/CSidebarNav.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CSidebarNav } from '@coreui/react' -// or -import CSidebarNav from '@coreui/react/src/components/sidebar/CSidebarNav' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CSidebarToggler.api.mdx b/packages/docs/content/api/CSidebarToggler.api.mdx deleted file mode 100644 index 0ff604df..00000000 --- a/packages/docs/content/api/CSidebarToggler.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CSidebarToggler } from '@coreui/react' -// or -import CSidebarToggler from '@coreui/react/src/components/sidebar/CSidebarToggler' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | diff --git a/packages/docs/content/api/CSpinner.api.mdx b/packages/docs/content/api/CSpinner.api.mdx deleted file mode 100644 index 05bf7089..00000000 --- a/packages/docs/content/api/CSpinner.api.mdx +++ /dev/null @@ -1,15 +0,0 @@ - -```jsx -import { CSpinner } from '@coreui/react' -// or -import CSpinner from '@coreui/react/src/components/spinner/CSpinner' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **size** | Size the component small. | `'sm'` | - | -| **variant** | Set the button variant to an outlined button or a ghost button. | `'border'` \| `'grow'` | border | -| **visuallyHiddenLabel** | Set visually hidden label for accessibility purposes. | `string` | Loading... | diff --git a/packages/docs/content/api/CTabContent.api.mdx b/packages/docs/content/api/CTabContent.api.mdx deleted file mode 100644 index 49ebd3b6..00000000 --- a/packages/docs/content/api/CTabContent.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CTabContent } from '@coreui/react' -// or -import CTabContent from '@coreui/react/src/components/tabs/CTabContent' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CTabPane.api.mdx b/packages/docs/content/api/CTabPane.api.mdx deleted file mode 100644 index 9b2755bc..00000000 --- a/packages/docs/content/api/CTabPane.api.mdx +++ /dev/null @@ -1,13 +0,0 @@ - -```jsx -import { CTabPane } from '@coreui/react' -// or -import CTabPane from '@coreui/react/src/components/tabs/CTabPane' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **onHide** | Callback fired when the component requests to be hidden. | `() => void` | - | -| **onShow** | Callback fired when the component requests to be shown. | `() => void` | - | -| **visible** | Toggle the visibility of component. | `boolean` | - | diff --git a/packages/docs/content/api/CTable.api.mdx b/packages/docs/content/api/CTable.api.mdx deleted file mode 100644 index 3bb76f86..00000000 --- a/packages/docs/content/api/CTable.api.mdx +++ /dev/null @@ -1,27 +0,0 @@ - -```jsx -import { CTable } from '@coreui/react' -// or -import CTable from '@coreui/react/src/components/table/CTable' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **align** | Set the vertical aligment. | `string` | - | -| **borderColor** | Sets the border color of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **bordered** | Add borders on all sides of the table and cells. | `boolean` | - | -| **borderless** | Remove borders on all sides of the table and cells. | `boolean` | - | -| **caption** | Put the caption on the top if you set `caption="top"` of the table or set the text of the table caption. | `string` | - | -| **captionTop** **_4.3.0+_** | Set the text of the table caption and the caption on the top of the table. | `string` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **columns** **_4.3.0+_** | Prop for table columns configuration. If prop is not defined, table will display columns based on the first item keys, omitting keys that begins with underscore (e.g. '_props')<br/><br/>In columns prop each array item represents one column. Item might be specified in two ways:<br/>String: each item define column name equal to item value.<br/>Object: item is object with following keys available as column configuration:<br/>- key (required)(String) - define column name equal to item key.<br/>- label (String) - define visible label of column. If not defined, label will be generated automatically based on column name, by converting kebab-case and snake_case to individual words and capitalization of each word.<br/>- _props (Object) - adds classes to all cels in column, ex. `_props: { scope: 'col', className: 'custom-class' }`,<br/>- _style (Object) - adds styles to the column header (useful for defining widths) | `(string` \| `Column)[]` | - | -| **footer** **_4.3.0+_** | Array of objects or strings, where each element represents one cell in the table footer.<br/><br/>Example items:<br/>`['FooterCell', 'FooterCell', 'FooterCell']`<br/>or<br/>`[{ label: 'FooterCell', _props: { color: 'success' }, ...]` | `(string` \| `FooterItem)[]` | - | -| **hover** | Enable a hover state on table rows within a `<CTableBody>`. | `boolean` | - | -| **items** **_4.3.0+_** | Array of objects, where each object represents one item - row in table. Additionally, you can add style classes to each row by passing them by '_props' key and to single cell by '_cellProps'.<br/><br/>Example item:<br/>`{ name: 'John' , age: 12, _props: { color: 'success' }, _cellProps: { age: { className: 'fw-bold'}}}` | `Item[]` | - | -| **responsive** | Make any table responsive across all viewports or pick a maximum breakpoint with which to have a responsive table up to. | `boolean` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` \| `'xxl'` | - | -| **small** | Make table more compact by cutting all cell `padding` in half. | `boolean` | - | -| **striped** | Add zebra-striping to any table row within the `<CTableBody>`. | `boolean` | - | -| **stripedColumns** **_4.3.0+_** | Add zebra-striping to any table column. | `boolean` | - | -| **tableFootProps** **_4.3.0+_** | Properties that will be passed to the table footer component. | `CTableFootProps` | - | -| **tableHeadProps** **_4.3.0+_** | Properties that will be passed to the table head component. | `CTableHeadProps` | - | diff --git a/packages/docs/content/api/CTableBody.api.mdx b/packages/docs/content/api/CTableBody.api.mdx deleted file mode 100644 index ad8c2c61..00000000 --- a/packages/docs/content/api/CTableBody.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CTableBody } from '@coreui/react' -// or -import CTableBody from '@coreui/react/src/components/table/CTableBody' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | diff --git a/packages/docs/content/api/CTableCaption.api.mdx b/packages/docs/content/api/CTableCaption.api.mdx deleted file mode 100644 index 3bebec25..00000000 --- a/packages/docs/content/api/CTableCaption.api.mdx +++ /dev/null @@ -1,7 +0,0 @@ - -```jsx -import { CTableCaption } from '@coreui/react' -// or -import CTableCaption from '@coreui/react/src/components/table/CTableCaption' -``` - diff --git a/packages/docs/content/api/CTableDataCell.api.mdx b/packages/docs/content/api/CTableDataCell.api.mdx deleted file mode 100644 index 5c5c2c3f..00000000 --- a/packages/docs/content/api/CTableDataCell.api.mdx +++ /dev/null @@ -1,13 +0,0 @@ - -```jsx -import { CTableDataCell } from '@coreui/react' -// or -import CTableDataCell from '@coreui/react/src/components/table/CTableDataCell' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Highlight a table row or cell. | `boolean` | - | -| **align** | Set the vertical aligment. | `string` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | diff --git a/packages/docs/content/api/CTableFoot.api.mdx b/packages/docs/content/api/CTableFoot.api.mdx deleted file mode 100644 index 9a363ce4..00000000 --- a/packages/docs/content/api/CTableFoot.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CTableFoot } from '@coreui/react' -// or -import CTableFoot from '@coreui/react/src/components/table/CTableFoot' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | diff --git a/packages/docs/content/api/CTableHead.api.mdx b/packages/docs/content/api/CTableHead.api.mdx deleted file mode 100644 index f890796d..00000000 --- a/packages/docs/content/api/CTableHead.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CTableHead } from '@coreui/react' -// or -import CTableHead from '@coreui/react/src/components/table/CTableHead' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | diff --git a/packages/docs/content/api/CTableHeaderCell.api.mdx b/packages/docs/content/api/CTableHeaderCell.api.mdx deleted file mode 100644 index ec0ce6e8..00000000 --- a/packages/docs/content/api/CTableHeaderCell.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CTableHeaderCell } from '@coreui/react' -// or -import CTableHeaderCell from '@coreui/react/src/components/table/CTableHeaderCell' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | diff --git a/packages/docs/content/api/CTableResponsiveWrapper.api.mdx b/packages/docs/content/api/CTableResponsiveWrapper.api.mdx deleted file mode 100644 index 70181df4..00000000 --- a/packages/docs/content/api/CTableResponsiveWrapper.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CTableResponsiveWrapper } from '@coreui/react' -// or -import CTableResponsiveWrapper from '@coreui/react/src/components/table/CTableResponsiveWrapper' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **responsive** | Make any table responsive across all viewports or pick a maximum breakpoint with which to have a responsive table up to. | `boolean` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` \| `'xxl'` | - | diff --git a/packages/docs/content/api/CTableRow.api.mdx b/packages/docs/content/api/CTableRow.api.mdx deleted file mode 100644 index 0b0adefc..00000000 --- a/packages/docs/content/api/CTableRow.api.mdx +++ /dev/null @@ -1,13 +0,0 @@ - -```jsx -import { CTableRow } from '@coreui/react' -// or -import CTableRow from '@coreui/react/src/components/table/CTableRow' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Highlight a table row or cell.. | `boolean` | - | -| **align** | Set the vertical aligment. | `string` | - | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | diff --git a/packages/docs/content/api/CToast.api.mdx b/packages/docs/content/api/CToast.api.mdx deleted file mode 100644 index ac0aba30..00000000 --- a/packages/docs/content/api/CToast.api.mdx +++ /dev/null @@ -1,17 +0,0 @@ - -```jsx -import { CToast } from '@coreui/react' -// or -import CToast from '@coreui/react/src/components/toast/CToast' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **animation** | Apply a CSS fade transition to the toast. | `boolean` | true | -| **autohide** | Auto hide the toast. | `boolean` | true | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **delay** | Delay hiding the toast (ms). | `number` | 5000 | -| **onClose** | Callback fired when the component requests to be closed. | `(index: number) => void` | - | -| **onShow** | Callback fired when the component requests to be shown. | `(index: number) => void` | - | -| **visible** | Toggle the visibility of component. | `boolean` | false | diff --git a/packages/docs/content/api/CToastBody.api.mdx b/packages/docs/content/api/CToastBody.api.mdx deleted file mode 100644 index b6ee2bb4..00000000 --- a/packages/docs/content/api/CToastBody.api.mdx +++ /dev/null @@ -1,10 +0,0 @@ - -```jsx -import { CToastBody } from '@coreui/react' -// or -import CToastBody from '@coreui/react/src/components/toast/CToastBody' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | diff --git a/packages/docs/content/api/CToastClose.api.mdx b/packages/docs/content/api/CToastClose.api.mdx deleted file mode 100644 index e7c31830..00000000 --- a/packages/docs/content/api/CToastClose.api.mdx +++ /dev/null @@ -1,20 +0,0 @@ - -```jsx -import { CToastClose } from '@coreui/react' -// or -import CToastClose from '@coreui/react/src/components/toast/CToastClose' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **active** | Toggle the active state for the component. | `boolean` | - | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **component** | Component used for the root node. Either a string to use a HTML element or a component. | `string` \| `ComponentClass<any, any>` \| `FunctionComponent<any>` | - | -| **dark** | Invert the default color. | `boolean` | - | -| **disabled** | Toggle the disabled state for the component. | `boolean` | - | -| **href** | The href attribute specifies the URL of the page the link goes to. | `string` | - | -| **shape** | Select the shape of the component. | `'rounded'` \| `'rounded-top'` \| `'rounded-end'` \| `'rounded-bottom'` \| `'rounded-start'` \| `'rounded-circle'` \| `'rounded-pill'` \| `'rounded-0'` \| `'rounded-1'` \| `'rounded-2'` \| `'rounded-3'` \| `string` | - | -| **size** | Size the component small or large. | `'sm'` \| `'lg'` | - | -| **type** | Specifies the type of button. Always specify the type attribute for the `<button>` element.<br/>Different browsers may use different default types for the `<button>` element. | `'button'` \| `'submit'` \| `'reset'` | - | -| **variant** | Set the button variant to an outlined button or a ghost button. | `'outline'` \| `'ghost'` | - | -| **white** **_Deprecated 5.0.0+_** | Change the default color to white. | `boolean` | - | diff --git a/packages/docs/content/api/CToastHeader.api.mdx b/packages/docs/content/api/CToastHeader.api.mdx deleted file mode 100644 index c157a9df..00000000 --- a/packages/docs/content/api/CToastHeader.api.mdx +++ /dev/null @@ -1,11 +0,0 @@ - -```jsx -import { CToastHeader } from '@coreui/react' -// or -import CToastHeader from '@coreui/react/src/components/toast/CToastHeader' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **closeButton** | Automatically add a close button to the header. | `boolean` | - | diff --git a/packages/docs/content/api/CToaster.api.mdx b/packages/docs/content/api/CToaster.api.mdx deleted file mode 100644 index 9b62fdd4..00000000 --- a/packages/docs/content/api/CToaster.api.mdx +++ /dev/null @@ -1,12 +0,0 @@ - -```jsx -import { CToaster } from '@coreui/react' -// or -import CToaster from '@coreui/react/src/components/toast/CToaster' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **placement** | Describes the placement of your component. | `'top-start'` \| `'top'` \| `'top-end'` \| `'middle-start'` \| `'middle'` \| `'middle-end'` \| `'bottom-start'` \| `'bottom'` \| `'bottom-end'` \| `string` | - | -| **push** | Adds new `CToast` to `CToaster`. | `ReactElement` | - | diff --git a/packages/docs/content/api/CTooltip.api.mdx b/packages/docs/content/api/CTooltip.api.mdx deleted file mode 100644 index 047a8ff8..00000000 --- a/packages/docs/content/api/CTooltip.api.mdx +++ /dev/null @@ -1,21 +0,0 @@ - -```jsx -import { CTooltip } from '@coreui/react' -// or -import CTooltip from '@coreui/react/src/components/tooltip/CTooltip' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **animation** **_4.9.0+_** | Apply a CSS fade transition to the tooltip. | `boolean` | true | -| **className** | A string of all className you want applied to the component. | `string` | - | -| **container** **_v4.11.0+_** | Appends the react tooltip to a specific element. You can pass an HTML element or function that returns a single element. By default `document.body`. | `Element` \| `(() => Element)` | - | -| **content** | Content node for your component. | `ReactNode` | - | -| **delay** **_4.9.0+_** | The delay for displaying and hiding the tooltip (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`. | `number` \| `{ show: number; hide: number; }` | 0 | -| **fallbackPlacements** **_4.9.0+_** | Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference. | `Placements` \| `Placements[]` | ['top', 'right', 'bottom', 'left'] | -| **offset** | Offset of the tooltip relative to its target. | `[number, number]` | [0, 6] | -| **onHide** | Callback fired when the component requests to be hidden. | `() => void` | - | -| **onShow** | Callback fired when the component requests to be shown. | `() => void` | - | -| **placement** | Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. | `'auto'` \| `'top'` \| `'bottom'` \| `'right'` \| `'left'` | top | -| **trigger** | Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. | `'hover'` \| `'focus'` \| `'click'` | ['hover', 'focus'] | -| **visible** | Toggle the visibility of tooltip component. | `boolean` | - | diff --git a/packages/docs/content/api/CWidgetStatsA.api.mdx b/packages/docs/content/api/CWidgetStatsA.api.mdx deleted file mode 100644 index c9d3d44e..00000000 --- a/packages/docs/content/api/CWidgetStatsA.api.mdx +++ /dev/null @@ -1,15 +0,0 @@ - -```jsx -import { CWidgetStatsA } from '@coreui/react' -// or -import CWidgetStatsA from '@coreui/react/src/components/widgets/CWidgetStatsA' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **action** | Action node for your component. | `ReactNode` | - | -| **chart** | Chart node for your component. | `ReactNode` | - | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **title** | Title node for your component. | `ReactNode` | - | -| **value** | Value node for your component. | `ReactNode` | - | diff --git a/packages/docs/content/api/CWidgetStatsB.api.mdx b/packages/docs/content/api/CWidgetStatsB.api.mdx deleted file mode 100644 index fd1d98ea..00000000 --- a/packages/docs/content/api/CWidgetStatsB.api.mdx +++ /dev/null @@ -1,16 +0,0 @@ - -```jsx -import { CWidgetCWidgetStatsB } from '@coreui/react' -// or -import CWidgetCWidgetStatsB from '@coreui/react/src/components/widgets/CWidgetStatsB' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **inverse** | Colors have been inverted from their default dark shade. | `boolean` | - | -| **progress** | Sets the color context of the progress bar to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **text** | Helper text for your component. | `string` | - | -| **title** | Title node for your component. | `ReactNode` | - | -| **value** | Value node for your component. | `ReactNode` | - | diff --git a/packages/docs/content/api/CWidgetStatsC.api.mdx b/packages/docs/content/api/CWidgetStatsC.api.mdx deleted file mode 100644 index 8ec1d46c..00000000 --- a/packages/docs/content/api/CWidgetStatsC.api.mdx +++ /dev/null @@ -1,16 +0,0 @@ - -```jsx -import { CWidgetStatsCWidgetStatsC } from '@coreui/react' -// or -import CWidgetStatsCWidgetStatsC from '@coreui/react/src/components/widgets/CWidgetStatsC' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **icon** | Icon node for your component. | `ReactNode` | - | -| **inverse** | Colors have been inverted from their default dark shade. | `boolean` | - | -| **progress** | Sets the color context of the progress bar to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **title** | Title node for your component. | `ReactNode` | - | -| **value** | Value node for your component. | `ReactNode` | - | diff --git a/packages/docs/content/api/CWidgetStatsD.api.mdx b/packages/docs/content/api/CWidgetStatsD.api.mdx deleted file mode 100644 index 9fffcde5..00000000 --- a/packages/docs/content/api/CWidgetStatsD.api.mdx +++ /dev/null @@ -1,14 +0,0 @@ - -```jsx -import { CWidgetStatsD } from '@coreui/react' -// or -import CWidgetStatsD from '@coreui/react/src/components/widgets/CWidgetStatsD' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **chart** | Chart node for your component. | `ReactNode` | - | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **icon** | Icon node for your component. | `ReactNode` | - | -| **values** | Values and titles for your component. | `Value[]` | - | diff --git a/packages/docs/content/api/CWidgetStatsE.api.mdx b/packages/docs/content/api/CWidgetStatsE.api.mdx deleted file mode 100644 index c8b652f3..00000000 --- a/packages/docs/content/api/CWidgetStatsE.api.mdx +++ /dev/null @@ -1,13 +0,0 @@ - -```jsx -import { CWidgetStatsE } from '@coreui/react' -// or -import CWidgetStatsE from '@coreui/react/src/components/widgets/CWidgetStatsE' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **chart** | Chart node for your component. | `ReactNode` | - | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **title** | Title node for your component. | `ReactNode` | - | -| **value** | Value node for your component. | `ReactNode` | - | diff --git a/packages/docs/content/api/CWidgetStatsF.api.mdx b/packages/docs/content/api/CWidgetStatsF.api.mdx deleted file mode 100644 index 90d5c0ce..00000000 --- a/packages/docs/content/api/CWidgetStatsF.api.mdx +++ /dev/null @@ -1,16 +0,0 @@ - -```jsx -import { CWidgetStatsF } from '@coreui/react' -// or -import CWidgetStatsF from '@coreui/react/src/components/widgets/CWidgetStatsF' -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| **className** | A string of all className you want applied to the base component. | `string` | - | -| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | `'primary'` \| `'secondary'` \| `'success'` \| `'danger'` \| `'warning'` \| `'info'` \| `'dark'` \| `'light'` \| `string` | - | -| **footer** | Footer node for your component. | `ReactNode` | - | -| **icon** | Icon node for your component. | `ReactNode` | - | -| **padding** | Set padding of your component. | `boolean` | true | -| **title** | Title node for your component. | `ReactNode` | - | -| **value** | Value node for your component. | `ReactNode` | - | diff --git a/packages/docs/content/assets/images/brand/coreui-signet.svg b/packages/docs/content/assets/images/brand/coreui-signet.svg deleted file mode 100644 index 9a4b2c5f..00000000 --- a/packages/docs/content/assets/images/brand/coreui-signet.svg +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg width="102px" height="116px" viewBox="0 0 102 116" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - <title>Untitled 3</title> - <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> - <g id="coreui-signet" fill="#3C4B64" fill-rule="nonzero"> - <path d="M96,25.091 L57,2.5743 C53.2871871,0.430706461 48.7128129,0.430706461 45,2.5743 L6,25.091 C2.292246,27.239646 0.00690676667,31.1979678 0,35.4833 L0,80.5167 C0.00688629146,84.8020377 2.29223099,88.760369 6,90.909 L45,113.4256 C48.7127742,115.569338 53.2872258,115.569338 57,113.4256 L96,90.909 C99.707769,88.760369 101.993114,84.8020377 102,80.5167 L102,35.4833 C101.993093,31.1979678 99.707754,27.239646 96,25.091 Z M94,80.5167 C94,81.9457261 93.2375729,83.266187 92,83.9807 L53,106.4974 C51.7623957,107.211931 50.2376043,107.211931 49,106.4974 L10,83.9807 C8.76242713,83.266187 8,81.9457261 8,80.5167 L8,35.4833 C8,34.0542382 8.76239619,32.7337309 10,32.0192 L49,9.5025 C50.2376043,8.78796882 51.7623957,8.78796882 53,9.5025 L92,32.0192 C93.2376038,32.7337309 94,34.0542382 94,35.4833 L94,80.5167 Z" id="Shape"></path> - <path d="M74.0216,71.0379 L71.1556,71.0379 C70.4827717,71.0379163 69.8208181,71.2076524 69.231,71.5314 L51.95,81.0167 L32,69.4981 L32,46.5206 L51.95,35.002 L69.2394,44.457 C69.8278903,44.7788245 70.4878603,44.9474965 71.1586,44.9475 L74.0218,44.9475 C75.1263695,44.9475 76.0218,44.0520695 76.0218,42.9475 L76.0218,40.2357 C76.0218,39.5046907 75.6230914,38.8318844 74.9818,38.481 L55.793,27.9854 C53.3404536,26.651551 50.3714915,26.6856213 47.9502,28.0754 L28,39.5929 C25.5282949,41.025705 24.0048155,43.6646378 24,46.5216 L24,69.4976 C24,72.3557593 25.5247614,74.9968204 28,76.4259 L47.95,87.9444 C50.3719491,89.3331078 53.3408366,89.3663802 55.7933,88.0323 L74.9833,77.5012 C75.623333,77.1499602 76.021125,76.4778764 76.0211,75.7478 L76.0211,73.0378 C76.0210448,71.9334648 75.1259352,71.0381761 74.0216,71.0379 L74.0216,71.0379 Z" id="Path"></path> - </g> - </g> -</svg> \ No newline at end of file diff --git a/packages/docs/content/assets/images/react400.jpg b/packages/docs/content/assets/images/react400.jpg deleted file mode 100644 index fdcd1039f0987354cb21bb0b6b84addbca1dc5bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5700 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 diff --git a/packages/docs/content/components/accordion.mdx b/packages/docs/content/components/accordion.mdx deleted file mode 100644 index 3dd6c723..00000000 --- a/packages/docs/content/components/accordion.mdx +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: React Accordion Component -name: Accordion -description: Build vertically collapsing accordions in combination with our React Accordion component. -menu: Components -route: /components/accordion -other_frameworks: accordion -pro_component: false ---- - -import { useState } from 'react' - -import { - CAccordion, - CAccordionBody, - CAccordionCollapse, - CAccordionHeader, - CAccordionItem, -} from '@coreui/react/src/index' - -## How to use React Accordion component. - -Click the accordions below to expand/collapse the accordion content. - -```jsx preview -<CAccordion activeItemKey={2}> - <CAccordionItem itemKey={1}> - <CAccordionHeader>Accordion Item #1</CAccordionHeader> - <CAccordionBody> - <strong>This is the first item's accordion body.</strong> It is hidden by default, until the - collapse plugin adds the appropriate classes that we use to style each element. These classes - control the overall appearance, as well as the showing and hiding via CSS transitions. You can - modify any of this with custom CSS or overriding our default variables. It's also worth noting - that just about any HTML can go within the <code>.accordion-body</code>, though the transition - does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={2}> - <CAccordionHeader>Accordion Item #2</CAccordionHeader> - <CAccordionBody> - <strong>This is the second item's accordion body.</strong> It is hidden by default, until the - collapse plugin adds the appropriate classes that we use to style each element. These classes - control the overall appearance, as well as the showing and hiding via CSS transitions. You can - modify any of this with custom CSS or overriding our default variables. It's also worth noting - that just about any HTML can go within the <code>.accordion-body</code>, though the transition - does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={3}> - <CAccordionHeader>Accordion Item #3</CAccordionHeader> - <CAccordionBody> - <strong>This is the second item's accordion body.</strong> It is hidden by default, until the - collapse plugin adds the appropriate classes that we use to style each element. These classes - control the overall appearance, as well as the showing and hiding via CSS transitions. You can - modify any of this with custom CSS or overriding our default variables. It's also worth noting - that just about any HTML can go within the <code>.accordion-body</code>, though the transition - does limit overflow. - </CAccordionBody> - </CAccordionItem> -</CAccordion> -``` - -### Flush - -Add `flush` to remove the default `background-color`, some borders, and some rounded corners to render accordions edge-to-edge with their parent container. - -```jsx preview -<CAccordion flush> - <CAccordionItem itemKey={1}> - <CAccordionHeader>Accordion Item #1</CAccordionHeader> - <CAccordionBody> - <strong>This is the first item's accordion body.</strong> It is hidden by default, until the - collapse plugin adds the appropriate classes that we use to style each element. These classes - control the overall appearance, as well as the showing and hiding via CSS transitions. You can - modify any of this with custom CSS or overriding our default variables. It's also worth noting - that just about any HTML can go within the <code>.accordion-body</code>, though the transition - does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={2}> - <CAccordionHeader>Accordion Item #2</CAccordionHeader> - <CAccordionBody> - <strong>This is the second item's accordion body.</strong> It is hidden by default, until the - collapse plugin adds the appropriate classes that we use to style each element. These classes - control the overall appearance, as well as the showing and hiding via CSS transitions. You can - modify any of this with custom CSS or overriding our default variables. It's also worth noting - that just about any HTML can go within the <code>.accordion-body</code>, though the transition - does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={3}> - <CAccordionHeader>Accordion Item #3</CAccordionHeader> - <CAccordionBody> - <strong>This is the third item's accordion body.</strong> It is hidden by default, until the - collapse plugin adds the appropriate classes that we use to style each element. These classes - control the overall appearance, as well as the showing and hiding via CSS transitions. You can - modify any of this with custom CSS or overriding our default variables. It's also worth noting - that just about any HTML can go within the <code>.accordion-body</code>, though the transition - does limit overflow. - </CAccordionBody> - </CAccordionItem> -</CAccordion> -``` - -### Always open - -Add `alwaysOpen` property to make react accordion items stay open when another item is opened. - -```jsx preview -<CAccordion alwaysOpen activeItemKey={2}> - <CAccordionItem itemKey={1}> - <CAccordionHeader>Accordion Item #1</CAccordionHeader> - <CAccordionBody> - <strong>This is the first item's accordion body.</strong> It is hidden by default, until the - collapse plugin adds the appropriate classes that we use to style each element. These classes - control the overall appearance, as well as the showing and hiding via CSS transitions. You can - modify any of this with custom CSS or overriding our default variables. It's also worth noting - that just about any HTML can go within the <code>.accordion-body</code>, though the transition - does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={2}> - <CAccordionHeader>Accordion Item #2</CAccordionHeader> - <CAccordionBody> - <strong>This is the second item's accordion body.</strong> It is hidden by default, until the - collapse plugin adds the appropriate classes that we use to style each element. These classes - control the overall appearance, as well as the showing and hiding via CSS transitions. You can - modify any of this with custom CSS or overriding our default variables. It's also worth noting - that just about any HTML can go within the <code>.accordion-body</code>, though the transition - does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={3}> - <CAccordionHeader>Accordion Item #3</CAccordionHeader> - <CAccordionBody> - <strong>This is the second item's accordion body.</strong> It is hidden by default, until the - collapse plugin adds the appropriate classes that we use to style each element. These classes - control the overall appearance, as well as the showing and hiding via CSS transitions. You can - modify any of this with custom CSS or overriding our default variables. It's also worth noting - that just about any HTML can go within the <code>.accordion-body</code>, though the transition - does limit overflow. - </CAccordionBody> - </CAccordionItem> -</CAccordion> -``` - -## Customizing - -### CSS variables - -React accordions use local CSS variables on `.accordion` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_accordion.scss" capture="accordion-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CAccordion style={vars}>...</CAccordion> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="accordion-variables"/> - -## API - -### CAccordion - -`markdown:CAccordion.api.mdx` - -### CAccordionBody - -`markdown:CAccordionBody.api.mdx` - -### CAccordionHeader - -`markdown:CAccordionHeader.api.mdx` - -### CAccordionItem - -`markdown:CAccordionItem.api.mdx` diff --git a/packages/docs/content/components/alert.mdx b/packages/docs/content/components/alert.mdx deleted file mode 100644 index dee0b432..00000000 --- a/packages/docs/content/components/alert.mdx +++ /dev/null @@ -1,262 +0,0 @@ ---- -title: React Alert Component -name: Alert -description: React alert component gives contextual feedback information for common user operations. The alert component is delivered with a bunch of usable and adjustable alert messages. -menu: Components -route: /components/alert -other_frameworks: alert ---- - -import { useState } from 'react' -import { CAlert, CAlertHeading, CAlertLink, CButton } from '@coreui/react/src/index' - -import CIcon from '@coreui/icons-react' - -import { cilBurn, cilCheckCircle, cilInfo, cilWarning } from '@coreui/icons' - -## How to use React Alert Component. - -React Alert is prepared for any length of text, as well as an optional close button. For a styling, use one of the **required** contextual `color` props (e.g., `primary`). For inline dismissal, use the [dismissing prop](#dismissing). - -```jsx preview -<CAlert color="primary"> - A simple primary alert—check it out! -</CAlert> -<CAlert color="secondary"> - A simple secondary alert—check it out! -</CAlert> -<CAlert color="success"> - A simple success alert—check it out! -</CAlert> -<CAlert color="danger"> - A simple danger alert—check it out! -</CAlert> -<CAlert color="warning"> - A simple warning alert—check it out! -</CAlert> -<CAlert color="info"> - A simple info alert—check it out! -</CAlert> -<CAlert color="light"> - A simple light alert—check it out! -</CAlert> -<CAlert color="dark"> - A simple dark alert—check it out! -</CAlert> -``` - -<Callout color="info" title="Conveying meaning to assistive technologies"> - Using color to add meaning only provides a visual indication, which will not be conveyed to - users of assistive technologies – such as screen readers. Ensure that information denoted by the - color is either obvious from the content itself (e.g. the visible text), or is included through - alternative means, such as additional text hidden with the `.visually-hidden` class. -</Callout> - -### Live example - -Click the button below to show an alert (hidden with inline styles to start), then dismiss (and destroy) it with the built-in close button. - -export const LiveExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CAlert color="primary" dismissible visible={visible} onClose={() => setVisible(false)}>A simple primary alert—check it out! - </CAlert> - <CButton color="primary" onClick={() => setVisible(true)}>Show live alert</CButton> - </> - ) -} - -<Example> - <LiveExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CAlert color="primary" dismissible visible={visible} onClose={() => setVisible(false)}> - A simple primary alert—check it out! - </CAlert> - <CButton color="primary" onClick={() => setVisible(true)}> - Show live alert - </CButton> - </> -) -``` - -### Link color - -Use the `<CAlertLink>` component to immediately give matching colored links inside any react alert component. - -```jsx preview -<CAlert color="primary"> - A simple primary alert with <CAlertLink href="#">an example link</CAlertLink>. Give it a click if you like. -</CAlert> -<CAlert color="secondary"> - A simple secondary alert with <CAlertLink href="#">an example link</CAlertLink>. Give it a click if you like. -</CAlert> -<CAlert color="success"> - A simple success alert with <CAlertLink href="#">an example link</CAlertLink>. Give it a click if you like. -</CAlert> -<CAlert color="danger"> - A simple danger alert with <CAlertLink href="#">an example link</CAlertLink>. Give it a click if you like. -</CAlert> -<CAlert color="warning"> - A simple warning alert with <CAlertLink href="#">an example link</CAlertLink>. Give it a click if you like. -</CAlert> -<CAlert color="info"> - A simple info alert with <CAlertLink href="#">an example link</CAlertLink>. Give it a click if you like. -</CAlert> -<CAlert color="light"> - A simple light alert with <CAlertLink href="#">an example link</CAlertLink>. Give it a click if you like. -</CAlert> -<CAlert color="dark"> - A simple dark alert with <CAlertLink href="#">an example link</CAlertLink>. Give it a click if you like. -</CAlert> -``` - -### Additional content - -React Alert can also incorporate supplementary components & elements like heading, paragraph, and divider. - -```jsx preview -<CAlert color="success"> - <CAlertHeading component="h4">Well done!</CAlertHeading> - <p> - Aww yeah, you successfully read this important alert message. This example text is going to run - a bit longer so that you can see how spacing within an alert works with this kind of content. - </p> - <hr /> - <p className="mb-0"> - Whenever you need to, be sure to use margin utilities to keep things nice and tidy. - </p> -</CAlert> -``` - -### Icons - -Similarly, you can use [flexbox utilities](https//coreui.io/docs/4.0/utilities/flex") and [CoreUI Icons](https://icons.coreui.io) to create react alerts with icons. Depending on your icons and content, you may want to add more utilities or custom styles. - -```jsx preview -<CAlert color="primary" className="d-flex align-items-center"> - <svg className="flex-shrink-0 me-2" width="24" height="24" viewBox="0 0 512 512"> - <rect - width="32" - height="176" - x="240" - y="176" - fill="var(--ci-primary-color, currentColor)" - className="ci-primary" - ></rect> - <rect - width="32" - height="32" - x="240" - y="384" - fill="var(--ci-primary-color, currentColor)" - className="ci-primary" - ></rect> - <path - fill="var(--ci-primary-color, currentColor)" - d="M274.014,16H237.986L16,445.174V496H496V445.174ZM464,464H48V452.959L256,50.826,464,452.959Z" - className="ci-primary" - ></path> - </svg> - <div>An example alert with an icon</div> -</CAlert> -``` - -Need more than one icon for your react alerts? Consider using [CoreUI Icons](https://icons.coreui.io). - -```jsx preview -<CAlert color="primary" className="d-flex align-items-center"> - <CIcon icon={cilInfo} className="flex-shrink-0 me-2" width={24} height={24} /> - <div>An example alert with an icon</div> -</CAlert> -<CAlert color="success" className="d-flex align-items-center"> - <CIcon icon={cilCheckCircle} className="flex-shrink-0 me-2" width={24} height={24} /> - <div>An example success alert with an icon</div> -</CAlert> -<CAlert color="warning" className="d-flex align-items-center"> - <CIcon icon={cilWarning} className="flex-shrink-0 me-2" width={24} height={24} /> - <div>An example warning alert with an icon</div> -</CAlert> -<CAlert color="danger" className="d-flex align-items-center"> - <CIcon icon={cilBurn} className="flex-shrink-0 me-2" width={24} height={24} /> - <div>An example danger alert with an icon</div> -</CAlert> -``` - -### Solid - -Use `variant="solid"` to change contextual colors to solid. - -```jsx preview -<CAlert color="primary" variant="solid">A simple solid primary alert—check it out!</CAlert> -<CAlert color="secondary" variant="solid">A simple solid secondary alert—check it out!</CAlert> -<CAlert color="success" variant="solid">A simple solid success alert—check it out!</CAlert> -<CAlert color="danger" variant="solid">A simple solid danger alert—check it out!</CAlert> -<CAlert color="warning" variant="solid">A simple solid warning alert—check it out!</CAlert> -<CAlert color="info" variant="solid">A simple solid info alert—check it out!</CAlert> -<CAlert color="light" variant="solid" className="text-high-emphasis">A simple solid light alert—check it out!</CAlert> -<CAlert color="dark" variant="solid">A simple solid dark alert—check it out!</CAlert> -``` - -### Dismissing - -React Alert component can also be easily dismissed. Just add the `dismissible` prop. - -```jsx preview -<CAlert - color="warning" - dismissible - onClose={() => { - alert('👋 Well, hi there! Thanks for dismissing me.') - }} -> - <strong>Go right ahead</strong> and click that dimiss over there on the right. -</CAlert> -``` - -<Callout color="warning"> - When an alert is dismissed, the element is completely removed from the page structure. If a - keyboard user dismisses the alert using the close button, their focus will suddenly be lost and, - depending on the browser, reset to the start of the page/document. -</Callout> - -## Customizing - -### CSS variables - -React alerts use local CSS variables on `.alert` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_alert.scss" capture="alert-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': 'red', -} -return <CAlert style={vars}>...</CAlert> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="alert-variables"/> - -## API - -### CAlert - -`markdown:CAlert.api.mdx` - -### CAlertHeading - -`markdown:CAlertHeading.api.mdx` - -### CAlertLink - -`markdown:CAlertLink.api.mdx` diff --git a/packages/docs/content/components/avatar.mdx b/packages/docs/content/components/avatar.mdx deleted file mode 100644 index 0e06b6ec..00000000 --- a/packages/docs/content/components/avatar.mdx +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: React Avatar Component -name: Avatar -description: React avatar component can be used to display circular user profile pictures. Avatar can be used to portray people or objects. It supports images, icons, or letters. -menu: Components -route: /components/avatar -other_frameworks: avatar ---- - -import { CAvatar } from '@coreui/react/src/index' - -import Avatar1 from './../assets/images/avatars/1.jpg' -import Avatar2 from './../assets/images/avatars/2.jpg' -import Avatar3 from './../assets/images/avatars/3.jpg' - -## Image avatars - -```jsx preview -<CAvatar src={Avatar1} /> -<CAvatar src={Avatar2} /> -<CAvatar src={Avatar3} /> -``` - -## Letter avatars - -```jsx preview -<CAvatar color="primary" textColor="white">CUI</CAvatar> -<CAvatar color="secondary">CUI</CAvatar> -<CAvatar color="warning" textColor="white">CUI</CAvatar> -``` - -## Rounded avatars - -Use the `shape="rounded"` prop to make react avatars squared with rounded corners. - -```jsx preview -<CAvatar color="primary" textColor="white" shape="rounded">CUI</CAvatar> -<CAvatar color="secondary" shape="rounded">CUI</CAvatar> -<CAvatar color="warning" textColor="white" shape="rounded">CUI</CAvatar> -``` - -## Square avatars - -Use the `shape="rounded-0"` prop to make react avatars squared. - -```jsx preview -<CAvatar color="primary" textColor="white" shape="rounded-0">CUI</CAvatar> -<CAvatar color="secondary" shape="rounded-0">CUI</CAvatar> -<CAvatar color="warning" textColor="white" shape="rounded-0">CUI</CAvatar> -``` - -## Sizes - -Fancy larger or smaller react avatar component? Add `size="xl"`, `size="lg"` or `size="sm"` for additional sizes. - -```jsx preview -<CAvatar color="secondary" size="xl">CUI</CAvatar> -<CAvatar color="secondary" size="lg">CUI</CAvatar> -<CAvatar color="secondary">CUI</CAvatar> -<CAvatar color="secondary" size="sm">CUI</CAvatar> -``` - -## Avatars with status - -```jsx preview -<CAvatar src={Avatar1} status="success" /> -<CAvatar color="secondary" status="danger">CUI</CAvatar> -``` - -## API - -### CAvatar - -`markdown:CAvatar.api.mdx` - diff --git a/packages/docs/content/components/badge.mdx b/packages/docs/content/components/badge.mdx deleted file mode 100644 index e7efa268..00000000 --- a/packages/docs/content/components/badge.mdx +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: React Badge Component -name: Badge -description: React badge component is small count and labeling component. -menu: Components -route: /components/badge -other_frameworks: badge ---- - -import { CBadge, CButton } from '@coreui/react/src/index' - -## How to use React Badge Component. - -React badge component scales to suit the size of the parent element by using relative font sizing and `em` units. - -```jsx preview -<h1>Example heading <CBadge color="secondary">New</CBadge></h1> -<h2>Example heading <CBadge color="secondary">New</CBadge></h2> -<h3>Example heading <CBadge color="secondary">New</CBadge></h3> -<h4>Example heading <CBadge color="secondary">New</CBadge></h4> -<h5>Example heading <CBadge color="secondary">New</CBadge></h5> -<h6>Example heading <CBadge color="secondary">New</CBadge></h6> -``` - -React badges can be used as part of links or buttons to provide a counter. - -```jsx preview -<CButton color="primary"> - Notifications <CBadge color="secondary">4</CBadge> -</CButton> -``` - -Remark that depending on how you use them, react badges may be complicated for users of screen readers and related assistive technologies. - -Unless the context is clear, consider including additional context with a visually hidden piece of additional text. - -```jsx preview -<CButton color="primary"> - Profile <CBadge color="secondary">9</CBadge> - <span className="visually-hidden">unread messages</span> -</CButton> -``` - -### Positioned - -Use `position` prop to modify a component and position it in the corner of a link or button. - -```jsx preview -<CButton color="primary" className="position-relative"> - Profile - <CBadge color="danger" position="top-start" shape="rounded-pill"> - 99+ <span className="visually-hidden">unread messages</span> - </CBadge> -</CButton> -<CButton color="primary" className="position-relative"> - Profile - <CBadge color="danger" position="top-end" shape="rounded-pill"> - 99+ <span className="visually-hidden">unread messages</span> - </CBadge> -</CButton> -<br/> -<CButton color="primary" className="position-relative"> - Profile - <CBadge color="danger" position="bottom-start" shape="rounded-pill"> - 99+ <span className="visually-hidden">unread messages</span> - </CBadge> -</CButton> -<CButton color="primary" className="position-relative"> - Profile - <CBadge color="danger" position="bottom-end" shape="rounded-pill"> - 99+ <span className="visually-hidden">unread messages</span> - </CBadge> -</CButton> -``` - -You can also create more generic indicators without a counter using a few more utilities. - -```jsx preview -<CButton color="primary" className="position-relative"> - Profile - <CBadge - className="border border-light p-2" - color="danger" - position="top-end" - shape="rounded-circle" - > - <span className="visually-hidden">New alerts</span> - </CBadge> -</CButton> -``` - -## Contextual variations - -Add any of the below-mentioned `color` props to modify the presentation of a react badge. - -```jsx preview -<CBadge color="primary">primary</CBadge> -<CBadge color="success">success</CBadge> -<CBadge color="danger">danger</CBadge> -<CBadge color="warning">warning</CBadge> -<CBadge color="info">info</CBadge> -<CBadge color="light">light</CBadge> -<CBadge color="dark">dark</CBadge> -``` - -## Pill badges - -Apply the `shape="rounded-pill"` prop to make badges rounded. - -```jsx preview -<CBadge color="primary" shape="rounded-pill">primary</CBadge> -<CBadge color="success" shape="rounded-pill">success</CBadge> -<CBadge color="danger" shape="rounded-pill">danger</CBadge> -<CBadge color="warning" shape="rounded-pill">warning</CBadge> -<CBadge color="info" shape="rounded-pill">info</CBadge> -<CBadge color="light" shape="rounded-pill">light</CBadge> -<CBadge color="dark" shape="rounded-pill">dark</CBadge> -``` - -## Customizing - -### CSS variables - -React badges use local CSS variables on `.badges` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_badge.scss" capture="badge-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': 'red', -} -return <CBadge style={vars}>...</CBadge> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="badge-variables"/> - -## API - -### CBadge - -`markdown:CBadge.api.mdx` diff --git a/packages/docs/content/components/breadcrumb.mdx b/packages/docs/content/components/breadcrumb.mdx deleted file mode 100644 index 96c0d6df..00000000 --- a/packages/docs/content/components/breadcrumb.mdx +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: React Breadcrumb Component -name: Breadcrumb -description: React breadcrumb navigation component which indicates the current location within a navigational hierarchy that automatically adds separators. -menu: Components -route: /components/breadcrumb -other_frameworks: breadcrumb ---- - -import { CBreadcrumb, CBreadcrumbItem } from '@coreui/react/src/index' - -## How to use React Breadcrumb Component. - -The react breadcrumb navigation provides links back to each previous page the user navigated through and shows the current location in a website or an application. You don’t have to add separators, because they automatically added in CSS through ::before and content. - -```jsx preview -<CBreadcrumb> - <CBreadcrumbItem active>Home</CBreadcrumbItem> -</CBreadcrumb> - -<CBreadcrumb> - <CBreadcrumbItem href="#">Home</CBreadcrumbItem> - <CBreadcrumbItem active>Library</CBreadcrumbItem> -</CBreadcrumb> - -<CBreadcrumb> - <CBreadcrumbItem href="#">Home</CBreadcrumbItem> - <CBreadcrumbItem href="#">Library</CBreadcrumbItem> - <CBreadcrumbItem active>Data</CBreadcrumbItem> -</CBreadcrumb> -``` - -## Dividers - -Dividers are automatically added in CSS through [`::before`](https://developer.mozilla.org/en-US/docs/Web/CSS/::before) and [`content`](https://developer.mozilla.org/en-US/docs/Web/CSS/content). They can be changed by modifying a local CSS custom property `--coreui-breadcrumb-divider`, or through the `$breadcrumb-divider` Sass variable — and `$breadcrumb-divider-flipped` for its RTL counterpart, if needed. We default to our Sass variable, which is set as a fallback to the custom property. This way, you get a global divider that you can override without recompiling CSS at any time. - -```jsx preview -<CBreadcrumb style={{"--cui-breadcrumb-divider": "'>'"}}> - <CBreadcrumbItem href="#">Home</CBreadcrumbItem> - <CBreadcrumbItem active>Library</CBreadcrumbItem> -</CBreadcrumb> -``` - -When modifying via Sass, the [quote](https://sass-lang.com/documentation/modules/string#quote) function is required to generate the quotes around a string. For example, using `>` as the divider, you can use this: - -```scss -$breadcrumb-divider: quote(">"); -``` - -It's also possible to use an **embedded SVG icon**. Apply it via our CSS custom property, or use the Sass variable. - -```jsx preview -<CBreadcrumb style={{"--cui-breadcrumb-divider": "url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M2.5 0L1 1.5 3.5 4 1 6.5 2.5 8l4-4-4-4z' fill='currentColor'/%3E%3C/svg%3E");"}}> - <CBreadcrumbItem href="#">Home</CBreadcrumbItem> - <CBreadcrumbItem active>Library</CBreadcrumbItem> -</CBreadcrumb> -``` - -```scss -$breadcrumb-divider: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' -width='8' height='8'%3E%3Cpath d='M2.5 0L1 1.5 3.5 4 1 6.5 2.5 8l4-4-4-4z' fill='currentColor'/%3E%3C/svg%3E"); -``` - -You can also remove the divider setting `--cui-breadcrumb-divider: '';` (empty strings in CSS custom properties counts as a value), or setting the Sass variable to `$breadcrumb-divider: none;`. - -```jsx preview -<CBreadcrumb style={{"--cui-breadcrumb-divider": "'';"}}> - <CBreadcrumbItem href="#">Home</CBreadcrumbItem> - <CBreadcrumbItem active>Library</CBreadcrumbItem> -</CBreadcrumb> -``` - -```scss -$breadcrumb-divider: none; -``` - -## Accessibility - -Since react breadcrumbs provide navigation, it's useful to add a significant label such as `aria-label="breadcrumb"` to explain the type of navigation implemented in the `<nav>` element. You should also add an `aria-current="page"` to the last item of the set to show that it represents the current page. **CoreUI for React.js automatically add all of this labels to breadcrumb's components.** - -For more information, see the [WAI-ARIA Authoring Practices for the breadcrumb pattern](https://www.w3.org/TR/wai-aria-practices/#breadcrumb). - -## Customizing - -### CSS variables - -React breadcrumbs use local CSS variables on `.breadcrumb` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_breadcrumb.scss" capture="breadcrumb-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CBreadcrumb style={vars}>...</CBreadcrumb> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="breadcrumb-variables"/> - -## API - -### CBreadcrumb - -`markdown:CBreadcrumb.api.mdx` - -### CBreadcrumbItem - -`markdown:CBreadcrumbItem.api.mdx` diff --git a/packages/docs/content/components/button-group.mdx b/packages/docs/content/components/button-group.mdx deleted file mode 100644 index d14bcb53..00000000 --- a/packages/docs/content/components/button-group.mdx +++ /dev/null @@ -1,332 +0,0 @@ ---- -title: React Button Group Component -name: Button group -description: React button group component allows to group a series of buttons and power them with JavaScript. -menu: Components -route: /components/button-group -other_frameworks: button-group ---- - -import { - CButtonGroup, - CButtonToolbar, - CButton, - CDropdown, - CDropdownDivider, - CDropdownHeader, - CDropdownItem, - CDropdownItemPlain, - CDropdownMenu, - CDropdownToggle, - CFormCheck, - CFormInput, - CInputGroup, - CInputGroupText, -} from '@coreui/react/src/index' - -## How to use React Button Group Component. - -Wrap a series of `<CButton>` components in `<CButtonGroup>`. - - -```jsx preview -<CButtonGroup role="group" aria-label="Basic example"> - <CButton color="primary">Left</CButton> - <CButton color="primary">Middle</CButton> - <CButton color="primary">Right</CButton> -</CButtonGroup> -``` - -##### Ensure the correct `role` and provide a label - -For assistive technologies (ex. screen readers) to communicate that a series of buttons are grouped, a proper `role` attribute has to be provided. For button groups, this should be `role="group"`, while toolbars should have a `role="toolbar"`. - -Besides, groups and toolbars should be provided an understandable label, as most assistive technologies will otherwise not declare them, despite the appearance of the specific role attribute. In the following examples provided here, we apply `aria-label`, but options such as `aria-labelledby` can also be used. - -These classes can also be added to groups of links, as an alternative to the `<CNav>` components. - -```jsx preview -<CButtonGroup> - <CButton href="#" color="primary" active>Active link</CButton> - <CButton href="#" color="primary">Link</CButton> - <CButton href="#" color="primary">Link</CButton> -</CButtonGroup> -``` - -## Mixed styles - -```jsx preview -<CButtonGroup role="group" aria-label="Basic mixed styles example"> - <CButton color="danger">Left</CButton> - <CButton color="warning">Middle</CButton> - <CButton color="success">Right</CButton> -</CButtonGroup> -``` - -## Outlined styles - -```jsx preview -<CButtonGroup role="group" aria-label="Basic outlined example"> - <CButton color="primary" variant="outline">Left</CButton> - <CButton color="primary" variant="outline">Middle</CButton> - <CButton color="primary" variant="outline">Right</CButton> -</CButtonGroup> -``` - -## Checkbox and radio button groups - -Combine button-like checkbox and radio toggle buttons into a seamless looking button group. - -```jsx preview -<CButtonGroup role="group" aria-label="Basic checkbox toggle button group"> - <CFormCheck - button={{ color: 'primary', variant: 'outline' }} - id="btncheck1" - autoComplete="off" - label="Checkbox 1" - /> - <CFormCheck - button={{ color: 'primary', variant: 'outline' }} - id="btncheck2" - autoComplete="off" - label="Checkbox 2" - /> - <CFormCheck - button={{ color: 'primary', variant: 'outline' }} - id="btncheck3" - autoComplete="off" - label="Checkbox 3" - /> -</CButtonGroup> -``` - -```jsx preview -<CButtonGroup role="group" aria-label="Basic checkbox toggle button group"> - <CFormCheck - type="radio" - button={{ color: 'primary', variant: 'outline' }} - name="btnradio" - id="btnradio1" - autoComplete="off" - label="Radio 1" - /> - <CFormCheck - type="radio" - button={{ color: 'primary', variant: 'outline' }} - name="btnradio" - id="btnradio2" - autoComplete="off" - label="Radio 2" - /> - <CFormCheck - type="radio" - button={{ color: 'primary', variant: 'outline' }} - name="btnradio" - id="btnradio3" - autoComplete="off" - label="Radio 3" - /> -</CButtonGroup> -``` - -## Button toolbar - -Join sets of button groups into button toolbars for more complicated components. Use utility classes as needed to space out groups, buttons, and more. - -```jsx preview -<CButtonToolbar role="group" aria-label="Toolbar with button groups"> - <CButtonGroup className="me-2" role="group" aria-label="First group"> - <CButton color="primary">1</CButton> - <CButton color="primary">2</CButton> - <CButton color="primary">3</CButton> - <CButton color="primary">4</CButton> - </CButtonGroup> - <CButtonGroup className="me-2" role="group" aria-label="Second group"> - <CButton color="secondary">5</CButton> - <CButton color="secondary">6</CButton> - <CButton color="secondary">7</CButton> - </CButtonGroup> - <CButtonGroup className="me-2" role="group" aria-label="Third group"> - <CButton color="info">8</CButton> - </CButtonGroup> -</CButtonToolbar> -``` - -Feel free to combine input groups with button groups in your toolbars. Similar to the example above, you’ll likely need some utilities through to space items correctly. - -```jsx preview -<CButtonToolbar className="mb-3" role="group" aria-label="Toolbar with button groups"> - <CButtonGroup className="me-2" role="group" aria-label="First group"> - <CButton color="secondary" variant="outline">1</CButton> - <CButton color="secondary" variant="outline">2</CButton> - <CButton color="secondary" variant="outline">3</CButton> - <CButton color="secondary" variant="outline">4</CButton> - </CButtonGroup> - <CInputGroup> - <CInputGroupText>@</CInputGroupText> - <CFormInput placeholder="Input group example" aria-label="Input group example" aria-describedby="btnGroupAddon"/> - </CInputGroup> -</CButtonToolbar> -<CButtonToolbar className="justify-content-between" role="group" aria-label="Toolbar with button groups"> - <CButtonGroup className="me-2" role="group" aria-label="First group"> - <CButton color="secondary" variant="outline">1</CButton> - <CButton color="secondary" variant="outline">2</CButton> - <CButton color="secondary" variant="outline">3</CButton> - <CButton color="secondary" variant="outline">4</CButton> - </CButtonGroup> - <CInputGroup> - <CInputGroupText>@</CInputGroupText> - <CFormInput placeholder="Input group example" aria-label="Input group example" aria-describedby="btnGroupAddon"/> - </CInputGroup> -</CButtonToolbar> -``` - -## Sizing - -Alternatively, of implementing button sizing classes to each button in a group, set `size` property to all `<CButtonGroup>`'s, including each one when nesting multiple groups. - -```jsx preview -<CButtonGroup size="lg" role="group" aria-label="Large button group"> - <CButton color="primary" variant="outline">Left</CButton> - <CButton color="primary" variant="outline">Middle</CButton> - <CButton color="primary" variant="outline">Right</CButton> -</CButtonGroup> -<br/> -<CButtonGroup role="group" aria-label="Default button group"> - <CButton color="primary" variant="outline">Left</CButton> - <CButton color="primary" variant="outline">Middle</CButton> - <CButton color="primary" variant="outline">Right</CButton> -</CButtonGroup> -<br/> -<CButtonGroup size="sm" role="group" aria-label="Small button group"> - <CButton color="primary" variant="outline">Left</CButton> - <CButton color="primary" variant="outline">Middle</CButton> - <CButton color="primary" variant="outline">Right</CButton> -</CButtonGroup> -``` - -## Nesting - -Put a `<CButtonGroup>` inside another `<CButtonGroup>` when you need dropdown menus combined with a series of buttons. - -```jsx preview -<CButtonGroup role="group" aria-label="Button group with nested dropdown"> - <CButton color="primary">1</CButton> - <CButton color="primary">2</CButton> - <CDropdown variant="btn-group"> - <CDropdownToggle color="primary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> -</CButtonGroup> -``` - -## Vertical variation - -Create a set of buttons that appear vertically stacked rather than horizontally. **Split button dropdowns are not supported here.** - -```jsx preview -<CButtonGroup vertical role="group" aria-label="Vertical button group"> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> -</CButtonGroup> -``` - -```jsx preview -<CButtonGroup vertical role="group" aria-label="Vertical button group"> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - <CDropdown variant="btn-group"> - <CDropdownToggle color="primary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - <CDropdown variant="btn-group"> - <CDropdownToggle color="primary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CDropdown variant="btn-group"> - <CDropdownToggle color="primary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CDropdown variant="btn-group"> - <CDropdownToggle color="primary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> -</CButtonGroup> -``` - -```jsx preview -<CButtonGroup vertical role="group" aria-label="Vertical button group"> - <CFormCheck - type="radio" - button={{ color: 'danger', variant: 'outline' }} - name="vbtnradio" - id="vbtnradio1" - autoComplete="off" - label="Radio 1" - defaultChecked - /> - <CFormCheck - type="radio" - button={{ color: 'danger', variant: 'outline' }} - name="vbtnradio" - id="vbtnradio2" - autoComplete="off" - label="Radio 2" - /> - <CFormCheck - type="radio" - button={{ color: 'danger', variant: 'outline' }} - name="vbtnradio" - id="vbtnradio3" - autoComplete="off" - label="Radio 3" - /> -</CButtonGroup> -``` - -## API - -### CButtonGroup - -`markdown:CButtonGroup.api.mdx` - -### CButtonToolbar - -`markdown:CButtonToolbar.api.mdx` diff --git a/packages/docs/content/components/button.mdx b/packages/docs/content/components/button.mdx deleted file mode 100644 index 4543fb55..00000000 --- a/packages/docs/content/components/button.mdx +++ /dev/null @@ -1,216 +0,0 @@ ---- -title: React Button Component -name: Buttons -description: React button component for actions in tables, forms, cards, and more. CoreUI for React.js provides various styles, states, and size. Ready to use and easy to customize. -menu: Components -route: /components/buttons -other_frameworks: button ---- - -import { CButton } from '@coreui/react/src/index' - -## How to use React Button Component. - -CoreUI includes a bunch of predefined buttons components, each serving its own semantic purpose. React buttons show what action will happen when the user clicks or touches it. CoreUI buttons are used to initialize operations, both in the background or foreground of an experience. - -```jsx preview -<CButton color="primary">Primary</CButton> -<CButton color="secondary">Secondary</CButton> -<CButton color="success">Success</CButton> -<CButton color="danger">Danger</CButton> -<CButton color="warning">Warning</CButton> -<CButton color="info">Info</CButton> -<CButton color="light">Light</CButton> -<CButton color="dark">Dark</CButton> -<CButton color="link">Link</CButton> -``` - -<Callout color="info" title="Conveying meaning to assistive technologies"> - Using color to add meaning only provides a visual indication, which will not be conveyed to - users of assistive technologies – such as screen readers. Ensure that information denoted by the - color is either obvious from the content itself (e.g. the visible text), or is included through - alternative means, such as additional text hidden with the `.visually-hidden` class. -</Callout> - -## Disable text wrapping - -If you don't want the react button text to wrap, you can add the `.text-nowrap` className to the `<CButton>`. In Sass, you can set `$btn-white-space: nowrap` to disable text wrapping for each button. - -## Button components - -The `<CButton>` component are designed for `<button>` , `<a>` or `<input>` elements (though some browsers may apply a slightly different rendering). - -If you're using `<CButton>` component as `<a>` elements that are used to trigger functionality ex. collapsing content, these links should be given a `role="button"` to adequately communicate their meaning to assistive technologies such as screen readers. - -```jsx preview -<CButton component="a" color="primary" href="#" role="button">Link</CButton> -<CButton type="submit" color="primary">Button</CButton> -<CButton component="input" type="button" color="primary" value="Input"/> -<CButton component="input" type="submit" color="primary" value="Submit"/> -<CButton component="input" type="reset" color="primary" value="Reset"/> -``` - -## Outline buttons - -If you need a button, but without the strong background colors. Set `variant="outline"` prop to remove all background colors. - -```jsx preview -<CButton color="primary" variant="outline">Primary</CButton> -<CButton color="secondary" variant="outline">Secondary</CButton> -<CButton color="success" variant="outline">Success</CButton> -<CButton color="danger" variant="outline">Danger</CButton> -<CButton color="warning" variant="outline">Warning</CButton> -<CButton color="info" variant="outline">Info</CButton> -<CButton color="light" variant="outline">Light</CButton> -<CButton color="dark" variant="outline">Dark</CButton> -``` - -## Ghost buttons - -If you need a ghost variant of react button, set `variant="ghost"` prop to remove all background colors. - -```jsx preview -<CButton color="primary" variant="ghost">Primary</CButton> -<CButton color="secondary" variant="ghost">Secondary</CButton> -<CButton color="success" variant="ghost">Success</CButton> -<CButton color="danger" variant="ghost">Danger</CButton> -<CButton color="warning" variant="ghost">Warning</CButton> -<CButton color="info" variant="ghost">Info</CButton> -<CButton color="light" variant="ghost">Light</CButton> -<CButton color="dark" variant="ghost">Dark</CButton> -``` - -<Callout color="info"> - Some of the button styles use a relatively light foreground color, and should only be used on a - dark background in order to have sufficient contrast. -</Callout> - -## Sizes - -Larger or smaller react buttons? Add `size="lg"` or `size="sm"` for additional sizes. - -```jsx preview -<CButton color="primary" size="lg">Large button</CButton> -<CButton color="secondary" size="lg">Large button</CButton> -``` - -```jsx preview -<CButton color="primary" size="sm">Small button</CButton> -<CButton color="secondary" size="sm">Small button</CButton> -``` - -## Shapes - -### Pill buttons - -```jsx preview -<CButton color="primary" shape="rounded-pill">Primary</CButton> -<CButton color="secondary" shape="rounded-pill">Secondary</CButton> -<CButton color="success" shape="rounded-pill">Success</CButton> -<CButton color="danger" shape="rounded-pill">Danger</CButton> -<CButton color="warning" shape="rounded-pill">Warning</CButton> -<CButton color="info" shape="rounded-pill">Info</CButton> -<CButton color="light" shape="rounded-pill">Light</CButton> -<CButton color="dark" shape="rounded-pill">Dark</CButton> -<CButton color="link" shape="rounded-pill">Link</CButton> -``` - -### Square buttons - -```jsx preview -<CButton color="primary" shape="rounded-0">Primary</CButton> -<CButton color="secondary" shape="rounded-0">Secondary</CButton> -<CButton color="success" shape="rounded-0">Success</CButton> -<CButton color="danger" shape="rounded-0">Danger</CButton> -<CButton color="warning" shape="rounded-0">Warning</CButton> -<CButton color="info" shape="rounded-0">Info</CButton> -<CButton color="light" shape="rounded-0">Light</CButton> -<CButton color="dark" shape="rounded-0">Dark</CButton> -<CButton color="link" shape="rounded-0">Link</CButton> -``` - -## Disabled state - -Add the `disabled` boolean prop to any `<CButton>` component to make buttons look inactive. Disabled button has `pointer-events: none` applied to, disabling hover and active states from triggering. - -```jsx preview -<CButton color="primary" size="lg" disabled>Primary button</CButton> -<CButton color="secondary" size="lg" disabled>Button</CButton> -``` - -Disabled buttons using the `<a>` component act a little different: - -`<a>`s don't support the `disabled` attribute, so CoreUI has to add `.disabled` className to make buttons look inactive. CoreUI also has to add to the disabled button component `aria-disabled="true"` attribute to show the state of the component to assistive technologies. - -```jsx preview -<CButton component="a" href="#" color="primary" size="lg" disabled>Primary link</CButton> -<CButton component="a" href="#" color="secondary" size="lg" disabled>Link</CButton> -``` - -The `.disabled` class uses `pointer-events: none` to try to disable the link functionality of `<a>`s, but that CSS property is not yet standardized. Besides, even in browsers that do support `pointer-events: none`, keyboard navigation remains unaffected, meaning that sighted keyboard users and users of assistive technologies will still be able to activate these links. So to be safe, we automatically add a `tabindex="-1"` attribute on disabled links (to prevent them from receiving keyboard focus) and use custom JavaScript to disable their functionality. - -## Block buttons - -Create buttons that span the full width of a parent—by using utilities. - -```jsx preview -<div className="d-grid gap-2"> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> -</div> -``` - -Here we create a responsive variation, starting with vertically stacked buttons until the `md` breakpoint, where `.d-md-block` replaces the `.d-grid` class, thus nullifying the `gap-2` utility. Resize your browser to see them change. - -```jsx preview -<div className="d-grid gap-2 d-md-block"> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> -</div> -``` - -You can adjust the width of your block buttons with grid column width classes. For example, for a half-width "block button", use `.col-6`. Center it horizontally with `.mx-auto`, too. - -```jsx preview -<div className="d-grid gap-2 col-6 mx-auto"> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> -</div> -``` - -Additional utilities can be used to adjust the alignment of buttons when horizontal. Here we've taken our previous responsive example and added some flex utilities and a margin utility on the button to right align the buttons when they're no longer stacked. - -```jsx preview -<div className="d-grid gap-2 d-md-flex justify-content-md-end"> - <CButton color="primary" className="me-md-2">Button</CButton> - <CButton color="primary">Button</CButton> -</div> -``` - -## Customizing - -### CSS variables - -React buttons use local CSS variables on `.btn` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_buttons.scss" capture="btn-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CButton style={vars}>...</CButton> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="btn-variables"/> - -## API - -### CButton - -`markdown:CButton.api.mdx` diff --git a/packages/docs/content/components/callout.mdx b/packages/docs/content/components/callout.mdx deleted file mode 100644 index 71ef0099..00000000 --- a/packages/docs/content/components/callout.mdx +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: React Callout Component -name: Callout -description: React callout component provides presentation of content in a visually distinct manner. Includes a heading, icon and typically text-based content. -menu: Components -route: /components/callout -other_frameworks: callout ---- - -import { CCallout } from '@coreui/react/src/index' - -## Examples - -Callout component is prepared for any length of text, as well as an optional elements like icons, headings, etc. For a styling, use one of the **required** contextual props (e.g., `color="success"`). - -```jsx preview -<CCallout color="primary"> - New to or unfamiliar with flexbox? Read this CSS Tricks flexbox guide for background, - terminology, guidelines, and code snippets. -</CCallout> -<CCallout color="secondary"> - New to or unfamiliar with flexbox? Read this CSS Tricks flexbox guide for background, - terminology, guidelines, and code snippets. -</CCallout> -<CCallout color="success"> - New to or unfamiliar with flexbox? Read this CSS Tricks flexbox guide for background, - terminology, guidelines, and code snippets. -</CCallout> -<CCallout color="danger"> - New to or unfamiliar with flexbox? Read this CSS Tricks flexbox guide for background, - terminology, guidelines, and code snippets. -</CCallout> -<CCallout color="warning"> - New to or unfamiliar with flexbox? Read this CSS Tricks flexbox guide for background, - terminology, guidelines, and code snippets. -</CCallout> -<CCallout color="info"> - New to or unfamiliar with flexbox? Read this CSS Tricks flexbox guide for background, - terminology, guidelines, and code snippets. -</CCallout> -<CCallout color="light"> - New to or unfamiliar with flexbox? Read this CSS Tricks flexbox guide for background, - terminology, guidelines, and code snippets. -</CCallout> -<CCallout color="dark"> - New to or unfamiliar with flexbox? Read this CSS Tricks flexbox guide for background, - terminology, guidelines, and code snippets. -</CCallout> -``` - -<Callout color="info" title="Conveying meaning to assistive technologies"> - Using color to add meaning only provides a visual indication, which will not be conveyed to - users of assistive technologies – such as screen readers. Ensure that information denoted by the - color is either obvious from the content itself (e.g. the visible text), or is included through - alternative means, such as additional text hidden with the `.visually-hidden` class. -</Callout> - -## Customizing - -### CSS variables - -React callouts use local CSS variables on `.callout` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_callout.scss" capture="callout-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CCallout style={vars}>...</CCallout> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="callout-variables"/> - -## API - -### CCallout - -`markdown:CCallout.api.mdx` diff --git a/packages/docs/content/components/card.mdx b/packages/docs/content/components/card.mdx deleted file mode 100644 index ce8479c5..00000000 --- a/packages/docs/content/components/card.mdx +++ /dev/null @@ -1,1035 +0,0 @@ ---- -title: React Card Component -name: Card -description: React card component provides a flexible and extensible container for displaying content. Card is delivered with a bunch of variants and options. -menu: Components -route: /components/card -other_frameworks: card ---- - -import { - CButton, - CCard, - CCardBody, - CCardFooter, - CCardGroup, - CCardHeader, - CCardImage, - CCardImageOverlay, - CCardLink, - CCardSubtitle, - CCardTitle, - CCardText, - CListGroup, - CListGroupItem, - CCol, - CNav, - CNavItem, - CNavLink, - CRow, -} from '@coreui/react/src/index' - -import ReactImg from './../assets/images/react.jpg' -import React400Img from './../assets/images/react400.jpg' - -## About - -A react card component is a content container. It incorporates options for images, headers, and footers, a wide variety of content, contextual background colors, and excellent display options. - -## Example - -Cards are built with as little markup and styles as possible but still manage to deliver a bunch of control and customization. Built with flexbox, they offer easy alignment and mix well with other CoreUI components. Cards have no top, left, and right margins by default, so use [spacing utilities](https://coreui.io/docs/utilities/spacing) as needed. They have no fixed width to start, so they'll fill the full width of its parent. - -Below is an example of a basic card with mixed content and a fixed width. Cards have no fixed width to start, so they'll naturally fill the full width of its parent element. - -```jsx preview -<CCard style={{ width: '18rem' }}> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the card's content. - </CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> -</CCard> -``` - -## Content types - -CoreUI card supports a wide variety of content, including images, text, list groups, links, and more. Below are examples of those elements. - -### Body - -The main block of a card is the `<CCardBody>`. Use it whenever you need a padded section within a card. - -```jsx preview -<CCard> - <CCardBody>This is some text within a card body.</CCardBody> -</CCard> -``` - -### Titles, text, and links - -Card titles are managed by `<CCardTitle>` component. Identically, links are attached and collected next to each other by `<CCardLink>` component. - -Subtitles are managed by `<CCardSubtitle>` component. If the `<CCardTitle>` also, the `<CCardSubtitle>` items are stored in a `<CCardBody>` item, the card title, and subtitle are arranged rightly. - -```jsx preview -<CCard style={{ width: '18rem' }}> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardSubtitle className="mb-2 text-body-secondary">Card subtitle</CCardSubtitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the card's content. - </CCardText> - <CCardLink href="#">Card link</CCardLink> - <CCardLink href="#">Another link</CCardLink> - </CCardBody> -</CCard> -``` - -### Images - -`orientation="top"` places a picture to the top of the card. With `<CCardText>`, text can be added to the card. Text within `<CCardText>` can additionally be styled with the regular HTML tags. - -```jsx preview -<CCard style={{ width: '18rem' }}> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the card's content. - </CCardText> - </CCardBody> -</CCard> -``` - -### List groups - -Create lists of content in a card with a flush list group. - -```jsx preview -<CCard style={{ width: '18rem' }}> - <CListGroup flush> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> -</CCard> -``` - -```jsx preview -<CCard style={{ width: '18rem' }}> - <CCardHeader>Header</CCardHeader> - <CListGroup flush> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> -</CCard> -``` - -```jsx preview -<CCard style={{ width: '18rem' }}> - <CListGroup flush> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> - <CCardFooter>Footer</CCardFooter> -</CCard> -``` - -### Kitchen sink - -Combine and match many content types to build the card you need, or throw everything in there. Shown below are image styles, blocks, text styles, and a list group—all wrapped in a fixed-width card. - -```jsx preview -<CCard style={{ width: '18rem' }}> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the card's content. - </CCardText> - </CCardBody> - <CListGroup flush> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> - <CCardBody> - <CCardLink href="#">Card link</CCardLink> - <CCardLink href="#">Another link</CCardLink> - </CCardBody> -</CCard> -``` - -### Header and footer - -Add an optional header and/or footer within a card. - -```jsx preview -<CCard> - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText>With supporting text below as a natural lead-in to additional content.</CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> -</CCard> -``` - -Card headers can be styled by adding ex. `component="h5"`. - -```jsx preview -<CCard> - <CCardHeader component="h5">Header</CCardHeader> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText>With supporting text below as a natural lead-in to additional content.</CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> -</CCard> -``` - -```jsx preview -<CCard> - <CCardHeader>Quote</CCardHeader> - <CCardBody> - <blockquote className="blockquote mb-0"> - <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p> - <footer className="blockquote-footer"> - Someone famous in <cite title="Source Title">Source Title</cite> - </footer> - </blockquote> - </CCardBody> -</CCard> -``` - -```jsx preview -<CCard className="text-center"> - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText>With supporting text below as a natural lead-in to additional content.</CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> - <CCardFooter className="text-body-secondary">2 days ago</CCardFooter> -</CCard> -``` - -## Sizing - -Cards assume no specific `width` to start, so they'll be 100% wide unless otherwise stated. You can adjust this as required with custom CSS, grid classes, grid Sass mixins, or services. - -### Using grid markup - -Using the grid, wrap cards in columns and rows as needed. - -```jsx preview -<CRow> - <CCol sm={6}> - <CCard> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </CCol> - <CCol sm={6}> - <CCard> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </CCol> -</CRow> -``` - -### Using utilities - -Use some of [available sizing utilities](https://coreui.io/docs/utilities/sizing/) to rapidly set a card's width. - -```jsx preview - <CCard className="w-75"> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText>With supporting text below as a natural lead-in to additional content.</CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - <CCard className="w-50"> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText>With supporting text below as a natural lead-in to additional content.</CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> - </CCard> -``` - -### Using custom CSS - -Use custom CSS in your stylesheets or as inline styles to set a width. - -```jsx preview -<CCard style={{ width: '18rem' }}> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText>With supporting text below as a natural lead-in to additional content.</CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> -</CCard> -``` - -## Text alignment - -You can instantly change the text arrangement of any card—in its whole or specific parts—with [text align classes](https://coreui.io/docs/utilities/text/#text-alignment). - -```jsx preview - <CCard style={{width: '18rem'}}> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText>With supporting text below as a natural lead-in to additional content.</CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - <CCard className="text-center" style={{width: '18rem'}}> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText>With supporting text below as a natural lead-in to additional content.</CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - <CCard className="text-end" style={{width: '18rem'}}> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText>With supporting text below as a natural lead-in to additional content.</CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> - </CCard> -``` - -## Navigation - -Add some navigation to a `<CCardHeader>` with our `<CNav>` component. - -```jsx preview -<CCard className="text-center"> - <CCardHeader> - <CNav variant="tabs" className="card-header-tabs"> - <CNavItem> - <CNavLink href="#" active>Active</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled>Disabled</CNavLink> - </CNavItem> - </CNav> - </CCardHeader> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText>With supporting text below as a natural lead-in to additional content.</CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> -</CCard> -``` - -```jsx preview -<CCard className="text-center"> - <CCardHeader> - <CNav variant="pills" className="card-header-pills"> - <CNavItem> - <CNavLink href="#" active>Active</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled>Disabled</CNavLink> - </CNavItem> - </CNav> - </CCardHeader> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText>With supporting text below as a natural lead-in to additional content.</CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> -</CCard> -``` - -## Images - -Cards introduce several options for acting with images. Pick from appending "image caps" at either end of a card, overlaying images with content, or just inserting the image in a card. - -### Image caps - -Similar to headers and footers, cards can include top and bottom "image caps"—images at the top or bottom of a card. - -```jsx preview -<CCard className="mb-3"> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText>This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</CCardText> - <CCardText><small className="text-body-secondary">Last updated 3 mins ago</small></CCardText> - </CCardBody> -</CCard> -<CCard className="mb-3"> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText>This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</CCardText> - <CCardText><small className="text-body-secondary">Last updated 3 mins ago</small></CCardText> - </CCardBody> - <CCardImage orientation="bottom" src={ReactImg} /> -</CCard> -``` - -### Image overlays - -Adapt an image into a background and overlay your text. Depending on the image, you may need additional styles or utilities. - -```jsx preview -<CCard className="mb-3 bg-dark text-white"> - <CCardImage src={ReactImg} /> - <CCardImageOverlay> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional content. - This content is a little bit longer. - </CCardText> - <CCardText>Last updated 3 mins ago</CCardText> - </CCardImageOverlay> -</CCard> -``` - -## Horizontal - -Using a combination of grid and utility classes, cards can be made horizontal in a mobile-friendly and responsive way. In the example below, we remove the grid gutters with `.g-0` and use `.col-md-*` classes to make the card horizontal at the `md` breakpoint. Further adjustments may be needed depending on your card content. - -```jsx preview -<CCard className="mb-3" style={{ maxWidth: '540px' }}> - <CRow className="g-0"> - <CCol md={4}> - <CCardImage src={React400Img} /> - </CCol> - <CCol md={8}> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional - content. This content is a little bit longer. - </CCardText> - <CCardText> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardText> - </CCardBody> - </CCol> - </CRow> -</CCard> -``` - -## Card styles - -Cards include various options for customizing their backgrounds, borders, and color. - -### Background and color - -Use `color` property to change the appearance of a card. - -<Example> - <> - {[ - { color: 'primary', textColor: 'white' }, - { color: 'secondary', textColor: 'white' }, - { color: 'success', textColor: 'white' }, - { color: 'danger', textColor: 'white' }, - { color: 'warning' }, - { color: 'info', textColor: 'white' }, - { color: 'light' }, - { color: 'dark', textColor: 'white' }, - ].map((item, index) => ( - <CCard - color={item.color} - textColor={item.textColor} - className="mb-3" - style={{ maxWidth: '18rem' }} - key={index} - > - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>{item.color} card title</CCardTitle> - <CCardText> Some quick example text to build on the card title and make up the bulk of the card's content.</CCardText> - </CCardBody> - </CCard> - ))} - </> -</Example> - -```jsx -<> - {[ - { color: 'primary', textColor: 'white' }, - { color: 'secondary', textColor: 'white' }, - { color: 'success', textColor: 'white' }, - { color: 'danger', textColor: 'white' }, - { color: 'warning' }, - { color: 'info', textColor: 'white' }, - { color: 'light' }, - { color: 'dark', textColor: 'white' }, - ].map((item, index) => ( - <CCard - color={item.color} - textColor={item.textColor} - className="mb-3" - style={{ maxWidth: '18rem' }} - key={index} - > - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>{item.color} card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the card's - content. - </CCardText> - </CCardBody> - </CCard> - ))} -</> -``` - -<Callout color="info" title="Conveying meaning to assistive technologies"> - Using color to add meaning only provides a visual indication, which will not be conveyed to - users of assistive technologies – such as screen readers. Ensure that information denoted by the - color is either obvious from the content itself (e.g. the visible text), or is included through - alternative means, such as additional text hidden with the `.visually-hidden` class. -</Callout> - -### Border - -Use [border utilities](https://coreui.io/docs/utilities/borders/) to change just the `border-color` of a card. Note that you can set `textColor` property on the `<CCard>` or a subset of the card's contents as shown below. - -<Example> - <> - {[ - { color: 'primary', textColor: 'primary' }, - { color: 'secondary', textColor: 'secondary' }, - { color: 'success', textColor: 'success' }, - { color: 'danger', textColor: 'danger' }, - { color: 'warning', textColor: 'warning' }, - { color: 'info', textColor: 'info' }, - { color: 'light' }, - { color: 'dark' }, - ].map((item, index) => ( - <CCard - textColor={item.textColor} - className={`mb-3 border-${item.color}`} - style={{ maxWidth: '18rem' }} - key={index} - > - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>{item.color} card title</CCardTitle> - <CCardText>Some quick example text to build on the card title and make up the bulk of the card's content.</CCardText> - </CCardBody> - </CCard> - ))} - </> -</Example> - -```jsx -<> - {[ - { color: 'primary', textColor: 'primary' }, - { color: 'secondary', textColor: 'secondary' }, - { color: 'success', textColor: 'success' }, - { color: 'danger', textColor: 'danger' }, - { color: 'warning', textColor: 'warning' }, - { color: 'info', textColor: 'info' }, - { color: 'light' }, - { color: 'dark' }, - ].map((item, index) => ( - <CCard - textColor={item.textColor} - className={`mb-3 border-${item.color}`} - style={{ maxWidth: '18rem' }} - key={index} - > - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>{item.color} card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the card's - content. - </CCardText> - </CCardBody> - </CCard> - ))} -</> -``` - -### Top border - -<Example> - <> - {[ - { color: 'primary', textColor: 'primary' }, - { color: 'secondary', textColor: 'secondary' }, - { color: 'success', textColor: 'success' }, - { color: 'danger', textColor: 'danger' }, - { color: 'warning', textColor: 'warning' }, - { color: 'info', textColor: 'info' }, - { color: 'light' }, - { color: 'dark' }, - ].map((item, index) => ( - <CCard - textColor={item.textColor} - className={`mb-3 border-top-${item.color} border-top-3`} - style={{ maxWidth: '18rem' }} - key={index} - > - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>{item.color} card title</CCardTitle> - <CCardText>Some quick example text to build on the card title and make up the bulk of the card's content.</CCardText> - </CCardBody> - </CCard> - ))} - </> -</Example> - -```jsx -<> - {[ - { color: 'primary', textColor: 'primary' }, - { color: 'secondary', textColor: 'secondary' }, - { color: 'success', textColor: 'success' }, - { color: 'danger', textColor: 'danger' }, - { color: 'warning', textColor: 'warning' }, - { color: 'info', textColor: 'info' }, - { color: 'light' }, - { color: 'dark' }, - ].map((item, index) => ( - <CCard - textColor={item.textColor} - className={`mb-3 border-top-${item.color} border-top-3`} - style={{ maxWidth: '18rem' }} - key={index} - > - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>{item.color} card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the card's - content. - </CCardText> - </CCardBody> - </CCard> - ))} -</> -``` - -## Card layout - -In addition to styling the content within cards, CoreUI includes a few options for laying out series of cards. For the time being, **these layout options are not yet responsive**. - -### Card groups - -Use card groups to render cards as a single, attached element with equal width and height columns. Card groups start off stacked and use `display: flex;` to become attached with uniform dimensions starting at the `sm` breakpoint. - -```jsx preview -<CCardGroup> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional content. - This content is a little bit longer. - </CCardText> - <CCardText> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardText> - </CCardBody> - </CCard> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This card has supporting text below as a natural lead-in to additional content. - </CCardText> - <CCardText> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardText> - </CCardBody> - </CCard> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional content. - This card has even longer content than the first to show that equal height action. - </CCardText> - <CCardText> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardText> - </CCardBody> - </CCard> -</CCardGroup> -``` - -When using card groups with footers, their content will automatically line up. - -```jsx preview -<CCardGroup> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional content. - This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This card has supporting text below as a natural lead-in to additional content. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional content. - This card has even longer content than the first to show that equal height action. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> -</CCardGroup> -``` - -### Grid cards - -Use the `CRow` component and set `xs|sm|md|lg|xl|xxl}={{ cols: * }}` property to control how many grid columns (wrapped around your cards) you show per row. For example, here's `xs={{cols: 1}}` laying out the cards on one column, and `md={{cols: 1}}` splitting four cards to equal width across multiple rows, from the medium breakpoint up. - -```jsx preview -<CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 2 }}> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional - content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional - content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional - content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional - content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> -</CRow> -``` - -Change it to `md={{ cols: 3}}` and you'll see the fourth card wrap. - -```jsx preview -<CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 3 }}> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText>This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText>This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText>This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText>This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> -</CRow> -``` - -When you need equal height, add `.h-100` to the cards. If you want equal heights by default, you can set `$card-height: 100%` in Sass. - -```jsx preview -<CRow xs={{ cols: 1 }} md={{ cols: 3 }} className="g-4"> - <CCol xs> - <CCard className="h-100"> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional - content. This content is a little bit longer. - </CCardText> - </CCardBody> - </CCard> - </CCol> - <CCol xs> - <CCard className="h-100"> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This card has supporting text below as a natural lead-in to additional content. - </CCardText> - </CCardBody> - </CCard> - </CCol> - <CCol xs> - <CCard className="h-100"> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional - content. This card has even longer content than the first to show that equal height - action. - </CCardText> - </CCardBody> - </CCard> - </CCol> - <CCol xs> - <CCard className="h-100"> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional - content. This content is a little bit longer. - </CCardText> - </CCardBody> - </CCard> - </CCol> -</CRow> -``` - -Just like with card groups, card footers will automatically line up. - -```jsx preview -<CRow xs={{ cols: 1 }} md={{ cols: 3 }} className="g-4"> - <CCol xs> - <CCard className="h-100"> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional - content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard className="h-100"> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This card has supporting text below as a natural lead-in to additional content. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard className="h-100"> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to additional - content. This card has even longer content than the first to show that equal height - action. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-body-secondary">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> -</CRow> -``` - - -## Customizing - -### CSS variables - -React cards use local CSS variables on `.card` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_card.scss" capture="card-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CCard style={vars}>...</CCard> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="card-variables"/> - -## API - -### CCard - -`markdown:CCard.api.mdx` - -### CCardBody - -`markdown:CCardBody.api.mdx` - -### CCardFooter - -`markdown:CCardFooter.api.mdx` - -### CCardGroup - -`markdown:CCardGroup.api.mdx` - -### CCardHeader - -`markdown:CCardHeader.api.mdx` - -### CCardImage - -`markdown:CCardImage.api.mdx` - -### CCardImageOverlay - -`markdown:CCardImageOverlay.api.mdx` - -### CCardLink - -`markdown:CCardLink.api.mdx` - -### CCardSubtitle - -`markdown:CCardSubtitle.api.mdx` - -### CCardText - -`markdown:CCardText.api.mdx` - -### CCardTitle - -`markdown:CCardTitle.api.mdx` diff --git a/packages/docs/content/components/carousel.mdx b/packages/docs/content/components/carousel.mdx deleted file mode 100644 index a79a0ed2..00000000 --- a/packages/docs/content/components/carousel.mdx +++ /dev/null @@ -1,232 +0,0 @@ ---- -title: React Carousel Component -name: Carousel -description: React carousel is a slideshow component for cycling through elements—images or slides of text—like a carousel. -menu: Components -route: /components/carousel -other_frameworks: carousel ---- - -import { - CCallout, - CCarousel, - CCarouselCaption, - CCarouselItem, - CImage, -} from '@coreui/react/src/index' - -import AngularImg from './../assets/images/angular.jpg' -import ReactImg from './../assets/images/react.jpg' -import VueImg from './../assets/images/vue.jpg' - -## How it works - -The React carousel is a slideshow for cycling within a group of content. It runs with a group of images, text, or html elements. It also incorporates support for previous/next buttons. - -In browsers where the [Page Visibility API](https://www.w3.org/TR/page-visibility/) is supported, the carousel will avoid sliding when the webpage is not visible to the user (such as when the browser tab is inactive, the browser window is minimized, etc.). - -## Example - -Carousels don't automatically normalize slide dimensions. As such, you may want to use extra utilities or custom methods to properly size content. While carousels support previous/next controls and indicators, they're not explicitly expected. Add and customize as you see fit. - -### Slides only - -```jsx preview -<CCarousel> - <CCarouselItem> - <CImage className="d-block w-100" src={ReactImg} alt="slide 1" /> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={VueImg} alt="slide 2" /> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={AngularImg} alt="slide 3" /> - </CCarouselItem> -</CCarousel> -``` - -### With controls - -Adding in the previous and next controls by `controls` property. - -```jsx preview -<CCarousel controls> - <CCarouselItem> - <CImage className="d-block w-100" src={ReactImg} alt="slide 1" /> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={VueImg} alt="slide 2" /> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={AngularImg} alt="slide 3" /> - </CCarouselItem> -</CCarousel> -``` - -### With indicators - -You can attach the indicators to the carousel, lengthwise the controls, too. - -```jsx preview -<CCarousel controls indicators> - <CCarouselItem> - <CImage className="d-block w-100" src={ReactImg} alt="slide 1" /> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={VueImg} alt="slide 2" /> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={AngularImg} alt="slide 3" /> - </CCarouselItem> -</CCarousel> -``` - -### With captions - -You can add captions to slides with the `<CCarouselCaption>` element within any `<CCarouselItem>`. They can be immediately hidden on smaller viewports, as shown below, with optional [display utilities](https://coreui.io/4.0/utilities/display). We hide them with `.d-none` and draw them back on medium-sized devices with `.d-md-block`. - -<Example> - <CCarousel controls indicators> - <CCarouselItem> - <CImage className="d-block w-100" src={ReactImg} alt="slide 1" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>First slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={VueImg} alt="slide 2" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Second slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={AngularImg} alt="slide 3" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Third slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - </CCarousel> -</Example> - -```jsx -<CCarousel controls indicators> - <CCarouselItem> - <CImage className="d-block w-100" src={ReactImg} alt="slide 1" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>First slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={VueImg} alt="slide 2" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Second slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={AngularImg} alt="slide 3" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Third slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> -</CCarousel> -``` - -### Crossfade - -Add `transition="crossfade"` to your carousel to animate slides with a fade transition instead of a slide. - -```jsx preview -<CCarousel controls transition="crossfade"> - <CCarouselItem> - <CImage className="d-block w-100" src={ReactImg} alt="slide 1" /> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={VueImg} alt="slide 2" /> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={AngularImg} alt="slide 3" /> - </CCarouselItem> -</CCarousel> -``` - -## Dark variant - -Add `dark` property to the `CCarousel` for darker controls, indicators, and captions. Controls have been inverted from their default white fill with the `filter` CSS property. Captions and controls have additional Sass variables that customize the `color` and `background-color`. - -<Example> - <CCarousel controls indicators dark> - <CCarouselItem> - <CImage className="d-block w-100" src={ReactImg} alt="slide 1" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>First slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={VueImg} alt="slide 2" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Second slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={AngularImg} alt="slide 3" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Third slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - </CCarousel> -</Example> - -```jsx -<CCarousel controls indicators dark> - <CCarouselItem> - <CImage className="d-block w-100" src={ReactImg} alt="slide 1" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>First slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={VueImg} alt="slide 2" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Second slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <CImage className="d-block w-100" src={AngularImg} alt="slide 3" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Third slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> -</CCarousel> -``` - -## Customizing - -### SASS variables - -<ScssDocs file="_variables.scss" capture="carousel-variables"/> - -## API - -### CCarousel - -`markdown:CCarousel.api.mdx` - -### CCarouselCaption - -`markdown:CCarouselCaption.api.mdx` - -### CCarouselItem - -`markdown:CCarouselItem.api.mdx` diff --git a/packages/docs/content/components/chart.mdx b/packages/docs/content/components/chart.mdx deleted file mode 100644 index b5e43f03..00000000 --- a/packages/docs/content/components/chart.mdx +++ /dev/null @@ -1,847 +0,0 @@ ---- -title: React Chart.js Component -name: Chart -description: React wrapper for Chart.js 4.x, the most popular charting library. -menu: Components -route: /components/chart ---- - -import { - CChart, - CChartBar, - CChartBubble, - CChartDoughnut, - CChartLine, - CChartPolarArea, - CChartRadar, - CChartScatter -} from '@coreui/react-chartjs' - -import { useEffect, useRef, useState } from 'react' -import { getStyle } from '@coreui/utils' - -## Installation - -If you want to use our Chart.js React wrapper you have to install an additional package. - -### Npm - -```bash -npm install @coreui/react-chartjs -``` - -### Yarn - -```bash -yarn add @coreui/react-chartjs -``` - -## Chart Types - -### Line Chart - -A line chart is a way of plotting data points on a line. Often, it is used to show trend data, or the comparison of two data sets. -[Line Chart properties](https://www.chartjs.org/docs/latest/charts/line.html#dataset-properties) - -export const LineChartExample = () => { - const chartRef = useRef() - - useEffect(() => { - document.documentElement.addEventListener('ColorSchemeChange', () => { - if (chartRef.current) { - chartRef.current.options.plugins.legend.labels.color = getStyle('--cui-body-color') - chartRef.current.options.scales.x.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.options.scales.x.ticks.color = getStyle('--cui-body-color') - chartRef.current.options.scales.y.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.options.scales.y.ticks.color = getStyle('--cui-body-color') - chartRef.current.update() - } - }) - }, [chartRef]) - - return ( - <CChart - ref={chartRef} - type="line" - data={{ - labels: ["January", "February", "March", "April", "May", "June", "July"], - datasets: [ - { - label: "My First dataset", - backgroundColor: "rgba(220, 220, 220, 0.2)", - borderColor: "rgba(220, 220, 220, 1)", - pointBackgroundColor: "rgba(220, 220, 220, 1)", - pointBorderColor: "#fff", - data: [40, 20, 12, 39, 10, 40, 39, 80, 40] - }, - { - label: "My Second dataset", - backgroundColor: "rgba(151, 187, 205, 0.2)", - borderColor: "rgba(151, 187, 205, 1)", - pointBackgroundColor: "rgba(151, 187, 205, 1)", - pointBorderColor: "#fff", - data: [50, 12, 28, 29, 7, 25, 12, 70, 60] - }, - ], - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - x: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - y: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - }, - }} - /> - ) -} - -<Example> - <LineChartExample /> -</Example> - - -```jsx -<CChart - type="line" - data={{ - labels: ["January", "February", "March", "April", "May", "June", "July"], - datasets: [ - { - label: "My First dataset", - backgroundColor: "rgba(220, 220, 220, 0.2)", - borderColor: "rgba(220, 220, 220, 1)", - pointBackgroundColor: "rgba(220, 220, 220, 1)", - pointBorderColor: "#fff", - data: [40, 20, 12, 39, 10, 40, 39, 80, 40] - }, - { - label: "My Second dataset", - backgroundColor: "rgba(151, 187, 205, 0.2)", - borderColor: "rgba(151, 187, 205, 1)", - pointBackgroundColor: "rgba(151, 187, 205, 1)", - pointBorderColor: "#fff", - data: [50, 12, 28, 29, 7, 25, 12, 70, 60] - }, - ], - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - x: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - y: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - }, - }} -/> -``` - -### Bar Chart - -A bar chart provides a way of showing data values represented as vertical bars. It is sometimes used to show trend data, and the comparison of multiple data sets side by side. [Bar Chart properties](https://www.chartjs.org/docs/latest/charts/bar.html#dataset-properties) - -export const BarChartExample = () => { - const chartRef = useRef() - - useEffect(() => { - document.documentElement.addEventListener('ColorSchemeChange', () => { - if (chartRef.current) { - chartRef.current.options.plugins.legend.labels.color = getStyle('--cui-body-color') - chartRef.current.options.scales.x.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.options.scales.x.ticks.color = getStyle('--cui-body-color') - chartRef.current.options.scales.y.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.options.scales.y.ticks.color = getStyle('--cui-body-color') - chartRef.current.update() - } - }) - }, [chartRef]) - - return ( - <CChart - ref={chartRef} - type="bar" - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - label: 'GitHub Commits', - backgroundColor: '#f87979', - data: [40, 20, 12, 39, 10, 40, 39, 80, 40], - }, - ], - }} - labels="months" - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - x: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - y: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - }, - }} - /> - ) -} - -<Example> - <BarChartExample /> -</Example> - -```jsx -<CChart - type="bar" - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - label: 'GitHub Commits', - backgroundColor: '#f87979', - data: [40, 20, 12, 39, 10, 40, 39, 80, 40], - }, - ], - }} - labels="months" - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - x: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - y: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - }, - }} -/> -``` - -### Radar Chart - -A radar chart is a way of showing multiple data points and the variation between them. They are often useful for comparing the points of two or more different data sets. [Radar Chart properties](https://www.chartjs.org/docs/latest/charts/radar.html#dataset-properties) - -export const RadarChartExample = () => { - const chartRef = useRef() - - useEffect(() => { - document.documentElement.addEventListener('ColorSchemeChange', () => { - if (chartRef.current) { - chartRef.current.options.plugins.legend.labels.color = getStyle('--cui-body-color') - chartRef.current.options.scales.r.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.options.scales.r.ticks.color = getStyle('--cui-body-color') - chartRef.current.update() - } - }) - }, [chartRef]) - - return ( - <CChart - ref={chartRef} - type="radar" - data={{ - labels: [ - 'Eating', - 'Drinking', - 'Sleeping', - 'Designing', - 'Coding', - 'Cycling', - 'Running', - ], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'rgba(220, 220, 220, 0.2)', - borderColor: 'rgba(220, 220, 220, 1)', - pointBackgroundColor: 'rgba(220, 220, 220, 1)', - pointBorderColor: '#fff', - pointHighlightFill: '#fff', - pointHighlightStroke: 'rgba(220, 220, 220, 1)', - data: [65, 59, 90, 81, 56, 55, 40], - }, - { - label: 'My Second dataset', - backgroundColor: 'rgba(151, 187, 205, 0.2)', - borderColor: 'rgba(151, 187, 205, 1)', - pointBackgroundColor: 'rgba(151, 187, 205, 1)', - pointBorderColor: '#fff', - pointHighlightFill: '#fff', - pointHighlightStroke: 'rgba(151, 187, 205, 1)', - data: [28, 48, 40, 19, 96, 27, 100], - }, - ], - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - r: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - }, - }} - /> - ) -} - -<Example> - <RadarChartExample /> -</Example> - -```jsx -<CChart - type="radar" - data={{ - labels: [ - 'Eating', - 'Drinking', - 'Sleeping', - 'Designing', - 'Coding', - 'Cycling', - 'Running', - ], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'rgba(220, 220, 220, 0.2)', - borderColor: 'rgba(220, 220, 220, 1)', - pointBackgroundColor: 'rgba(220, 220, 220, 1)', - pointBorderColor: '#fff', - pointHighlightFill: '#fff', - pointHighlightStroke: 'rgba(220, 220, 220, 1)', - data: [65, 59, 90, 81, 56, 55, 40], - }, - { - label: 'My Second dataset', - backgroundColor: 'rgba(151, 187, 205, 0.2)', - borderColor: 'rgba(151, 187, 205, 1)', - pointBackgroundColor: 'rgba(151, 187, 205, 1)', - pointBorderColor: '#fff', - pointHighlightFill: '#fff', - pointHighlightStroke: 'rgba(151, 187, 205, 1)', - data: [28, 48, 40, 19, 96, 27, 100], - }, - ], - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - r: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - }, - }} -/> -``` - -### Doughnut and Pie Charts - -Pie and doughnut charts are probably the most commonly used charts. They are divided into segments, the arc of each segment shows the proportional value of each piece of data. [Doughnut and Pie Charts properties](https://www.chartjs.org/docs/latest/charts/doughnut.html#dataset-properties) - -export const DoughnutAndPieExample = () => { - const chartRef = useRef() - - useEffect(() => { - document.documentElement.addEventListener('ColorSchemeChange', () => { - if (chartRef.current) { - chartRef.current.options.plugins.legend.labels.color = getStyle('--cui-body-color') - chartRef.current.update() - } - }) - }, [chartRef]) - - return ( - <CChart - ref={chartRef} - type="doughnut" - data={{ - labels: ['VueJs', 'EmberJs', 'ReactJs', 'AngularJs'], - datasets: [ - { - backgroundColor: ['#41B883', '#E46651', '#00D8FF', '#DD1B16'], - data: [40, 20, 80, 10], - }, - ], - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - }} - /> - ) -} - -<Example> - <DoughnutAndPieExample /> -</Example> - -```jsx -<CChart - type="doughnut" - data={{ - labels: ['VueJs', 'EmberJs', 'ReactJs', 'AngularJs'], - datasets: [ - { - backgroundColor: ['#41B883', '#E46651', '#00D8FF', '#DD1B16'], - data: [40, 20, 80, 10], - }, - ], - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - }} -/> -``` - -### Polar Area Chart - -Polar area charts are similar to pie charts, but each segment has the same angle - the radius of the segment differs depending on the value. [Polar Area Chart properties](https://www.chartjs.org/docs/latest/charts/polar.html#dataset-properties) - -export const PolarAreaExample = () => { - const chartRef = useRef() - - useEffect(() => { - document.documentElement.addEventListener('ColorSchemeChange', () => { - if (chartRef.current) { - chartRef.current.options.plugins.legend.labels.color = getStyle('--cui-body-color') - chartRef.current.options.scales.r.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.update() - } - }) - }, [chartRef]) - - return ( - <CChart - ref={chartRef} - type="polarArea" - data={{ - labels: ['Red', 'Green', 'Yellow', 'Grey', 'Blue'], - datasets: [ - { - data: [11, 16, 7, 3, 14], - backgroundColor: ['#FF6384', '#4BC0C0', '#FFCE56', '#E7E9ED', '#36A2EB'], - }, - ], - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - r: { - grid: { - color: getStyle('--cui-border-color'), - }, - } - } - }} - /> - ) -} - -<Example> - <PolarAreaExample /> -</Example> - -```jsx -<CChart - type="polarArea" - data={{ - labels: ['Red', 'Green', 'Yellow', 'Grey', 'Blue'], - datasets: [ - { - data: [11, 16, 7, 3, 14], - backgroundColor: ['#FF6384', '#4BC0C0', '#FFCE56', '#E7E9ED', '#36A2EB'], - }, - ], - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - r: { - grid: { - color: getStyle('--cui-border-color'), - }, - } - } - }} -/> -``` - -### Bubble Chart - -A bubble chart is used to display three dimensions of data at the same time. The location of the bubble is determined by the first two dimensions and the corresponding horizontal and vertical axes. The third dimension is represented by the size of the individual bubbles. [Bubble Chart properties](https://www.chartjs.org/docs/latest/charts/bubble.html#dataset-properties) - -export const BubbleChartExample = () => { - const chartRef = useRef() - - useEffect(() => { - document.documentElement.addEventListener('ColorSchemeChange', () => { - if (chartRef.current) { - chartRef.current.options.plugins.legend.labels.color = getStyle('--cui-body-color') - chartRef.current.options.scales.x.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.options.scales.x.ticks.color = getStyle('--cui-body-color') - chartRef.current.options.scales.y.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.options.scales.y.ticks.color = getStyle('--cui-body-color') - chartRef.current.update() - } - }) - }, [chartRef]) - - return ( - <CChart - ref={chartRef} - type="bubble" - data={{ - datasets: [{ - label: 'First Dataset', - data: [{ - x: 20, - y: 30, - r: 15 - }, { - x: 40, - y: 10, - r: 10 - }], - backgroundColor: 'rgb(255, 99, 132)' - }] - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - x: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - y: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - }, - }} - /> - ) -} - -<Example> - <BubbleChartExample /> -</Example> - -```jsx -<CChart - type="bubble" - data={{ - datasets: [{ - label: 'First Dataset', - data: [{ - x: 20, - y: 30, - r: 15 - }, { - x: 40, - y: 10, - r: 10 - }], - backgroundColor: 'rgb(255, 99, 132)' - }] - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - x: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - y: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - }, - }} -/> -``` - -### Scatter Chart - -A bubble chart is used to display three dimensions of data at the same time. The location of the bubble is determined by the first two dimensions and the corresponding horizontal and vertical axes. The third dimension is represented by the size of the individual bubbles. [Scatter Chart properties](https://www.chartjs.org/docs/latest/charts/scatter.html#dataset-properties) - -export const ScatterChartExample = () => { - const chartRef = useRef() - - useEffect(() => { - document.documentElement.addEventListener('ColorSchemeChange', () => { - if (chartRef.current) { - chartRef.current.options.plugins.legend.labels.color = getStyle('--cui-body-color') - chartRef.current.options.scales.x.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.options.scales.x.ticks.color = getStyle('--cui-body-color') - chartRef.current.options.scales.y.grid.color = getStyle('--cui-border-color-translucent') - chartRef.current.options.scales.y.ticks.color = getStyle('--cui-body-color') - chartRef.current.update() - } - }) - }, [chartRef]) - - return ( - <CChart - ref={chartRef} - type="scatter" - data={{ - datasets: [{ - label: 'Scatter Dataset', - data: [{ - x: -10, - y: 0 - }, { - x: 0, - y: 10 - }, { - x: 10, - y: 5 - }, { - x: 0.5, - y: 5.5 - }], - backgroundColor: 'rgb(255, 99, 132)' - }], - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - x: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - position: 'bottom', - ticks: { - color: getStyle('--cui-body-color'), - }, - type: 'linear', - }, - y: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - }, - }} - /> - ) -} - -<Example> - <ScatterChartExample /> -</Example> - - -```jsx -<CChart - type="scatter" - data={{ - datasets: [{ - label: 'Scatter Dataset', - data: [{ - x: -10, - y: 0 - }, { - x: 0, - y: 10 - }, { - x: 10, - y: 5 - }, { - x: 0.5, - y: 5.5 - }], - backgroundColor: 'rgb(255, 99, 132)' - }], - }} - options={{ - plugins: { - legend: { - labels: { - color: getStyle('--cui-body-color'), - } - } - }, - scales: { - x: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - position: 'bottom', - ticks: { - color: getStyle('--cui-body-color'), - }, - type: 'linear', - }, - y: { - grid: { - color: getStyle('--cui-border-color-translucent'), - }, - ticks: { - color: getStyle('--cui-body-color'), - }, - }, - }, - }} -/> -``` - -## API - -### CChart - -`markdown:CChart.api.mdx` \ No newline at end of file diff --git a/packages/docs/content/components/close-button.mdx b/packages/docs/content/components/close-button.mdx deleted file mode 100644 index 98fa69b8..00000000 --- a/packages/docs/content/components/close-button.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: React Close Button Component -name: Close Button -description: A generic close button component for dismissing content like modals and alerts. -menu: Components -route: /components/close-button -other_frameworks: close-button ---- - -import { CCloseButton } from '@coreui/react/src/index' - -## Example - -Provide an option to dismiss or close a component with `<CCloseButton>`. Default styling is limited, but highly customizable. Modify the Sass variables to replace the default `background-image`. - -```jsx preview -<CCloseButton /> -``` - -## Disabled state - -Disabled close buttons change their `opacity`. We've also applied `pointer-events: none` and `user-select: none` to preventing hover and active states from triggering. - -```jsx preview -<CCloseButton disabled /> -``` - -## Dark variant - -Add `dark` boolean property to the `<CCloseButton>`, to invert the close button. This uses the filter property to invert the background-image without overriding its value. - -```jsx preview className="bg-dark border-0" -<CCloseButton dark /> -<CCloseButton dark disabled /> -``` - -## API - -### CCloseButton - -`markdown:CCloseButton.api.mdx` diff --git a/packages/docs/content/components/collapse.mdx b/packages/docs/content/components/collapse.mdx deleted file mode 100644 index ed1dff62..00000000 --- a/packages/docs/content/components/collapse.mdx +++ /dev/null @@ -1,263 +0,0 @@ ---- -title: React Collapse Component -name: Collapse -description: React collapse component toggles the visibility of content across your project with a few classes and some scripts. Useful for a large amount of content. -menu: Components -route: /components/collapse -other_frameworks: collapse ---- - -import { useState } from 'react' - -import { - CButton, - CCard, - CCardBody, - CCol, - CCollapse, - CContainer, - CRow, -} from '@coreui/react/src/index' - -## How it works - -The collapse component is used to show and hide content. Buttons or anchors are used as triggers that are mapped to specific elements you toggle. Collapsing an element will animate the `height` from its current value to `0`. Given how CSS handles animations, you cannot use `padding` on a `.collapse` element. Instead, use the class as an independent wrapping element. - -## Example - -You can use a link or a button component. - -export const BasicExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton - color="primary" - href="#" - onClick={(event) => { - event.preventDefault() - setVisible(!visible) - }} - > - Link - </CButton> - <CButton color="primary" onClick={() => setVisible(!visible)}> - Button - </CButton> - <CCollapse visible={visible}> - <CCard className="mt-3"> - <CCardBody> - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad - squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt - sapiente ea proident. - </CCardBody> - </CCard> - </CCollapse> - </> - ) -} - -<Example> - <BasicExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton - color="primary" - href="#" - onClick={(event) => { - event.preventDefault() - setVisible(!visible) - }} - > - Link - </CButton> - <CButton color="primary" onClick={() => setVisible(!visible)}> - Button - </CButton> - <CCollapse visible={visible}> - <CCard className="mt-3"> - <CCardBody> - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad - squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt - sapiente ea proident. - </CCardBody> - </CCard> - </CCollapse> - </> -) -``` - -## Horizontal - -The collapse plugin also supports horizontal collapsing. Add the `horizontal` property to transition the `width` instead of `height` and set a `width` on the immediate child element. - -export const HorizontalExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton - color="primary" - className="mb-3" - onClick={() => setVisible(!visible)} - aria-expanded={visible} - aria-controls="collapseWidthExample" - > - Button - </CButton> - <div style={{ minHeight: '120px' }}> - <CCollapse id="collapseWidthExample" horizontal visible={visible}> - <CCard style={{ width: '300px' }}> - <CCardBody> - This is some placeholder content for a horizontal collapse. It's hidden by default and - shown when triggered. - </CCardBody> - </CCard> - </CCollapse> - </div> - </> - ) -} - -<Example> - <HorizontalExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton - className="mb-3" - onClick={() => setVisible(!visible)} - aria-expanded={visible} - aria-controls="collapseWidthExample" - > - Button - </CButton> - <div style={{ minHeight: '120px' }}> - <CCollapse id="collapseWidthExample" horizontal visible={visible}> - <CCard style={{ width: '300px' }}> - <CCardBody> - This is some placeholder content for a horizontal collapse. It's hidden by default and - shown when triggered. - </CCardBody> - </CCard> - </CCollapse> - </div> - </> -) -``` - -## Multiple targets - -A `<CButton>` can show and hide multiple elements. - -export const MultipleTargetsExample = () => { - const [visibleA, setVisibleA] = useState(false) - const [visibleB, setVisibleB] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisibleA(!visibleA)}> - Toggle first element - </CButton> - <CButton color="primary" onClick={() => setVisibleB(!visibleB)}> - Toggle second element - </CButton> - <CButton - color="primary" - onClick={() => { - setVisibleA(!visibleA) - setVisibleB(!visibleB) - }} - > - Toggle both elements - </CButton> - <CRow> - <CCol xs={6}> - <CCollapse visible={visibleA}> - <CCard className="mt-3"> - <CCardBody> - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry - richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson - cred nesciunt sapiente ea proident. - </CCardBody> - </CCard> - </CCollapse> - </CCol> - <CCol xs={6}> - <CCollapse visible={visibleB}> - <CCard className="mt-3"> - <CCardBody> - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry - richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson - cred nesciunt sapiente ea proident. - </CCardBody> - </CCard> - </CCollapse> - </CCol> - </CRow> - </> - ) -} - -<Example> - <MultipleTargetsExample /> -</Example> - -```jsx -const [visibleA, setVisibleA] = useState(false) -const [visibleB, setVisibleB] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisibleA(!visibleA)}> - Toggle first element - </CButton> - <CButton color="primary" onClick={() => setVisibleB(!visibleB)}> - Toggle second element - </CButton> - <CButton - color="primary" - onClick={() => { - setVisibleA(!visibleA) - setVisibleB(!visibleB) - }} - > - Toggle both elements - </CButton> - <CRow> - <CCol xs={6}> - <CCollapse visible={visibleA}> - <CCard className="mt-3"> - <CCardBody> - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson - ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt - sapiente ea proident. - </CCardBody> - </CCard> - </CCollapse> - </CCol> - <CCol xs={6}> - <CCollapse visible={visibleB}> - <CCard className="mt-3"> - <CCardBody> - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson - ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt - sapiente ea proident. - </CCardBody> - </CCard> - </CCollapse> - </CCol> - </CRow> - </> -) -``` - -## API - -### CCollapse - -`markdown:CCollapse.api.mdx` diff --git a/packages/docs/content/components/dropdown.mdx b/packages/docs/content/components/dropdown.mdx deleted file mode 100644 index 2c50a879..00000000 --- a/packages/docs/content/components/dropdown.mdx +++ /dev/null @@ -1,615 +0,0 @@ ---- -title: React Dropdown Component -name: Dropdown -description: React dropdown component allows you to toggle contextual overlays for displaying lists, links, and more html elements. -menu: Components -route: /components/dropdown -other_frameworks: dropdown ---- - -import { - CButton, - CButtonGroup, - CCollapse, - CContainer, - CDropdown, - CDropdownDivider, - CDropdownHeader, - CDropdownItem, - CDropdownItemPlain, - CDropdownMenu, - CDropdownToggle, - CForm, - CFormCheck, - CFormInput, - CFormLabel, - CNavbar, - CNavbarBrand, - CNavbarNav, - CNavbarToggler, -} from '@coreui/react/src/index' - -## Overview - -Dropdowns are toggleable, contextual overlays for displaying lists of links and more. - -Dropdowns are built on a third party library, [Popper.js](https://popper.js.org/), which provides dynamic positioning and viewport detection. Popper.js isn't used to position dropdowns in navbars though as dynamic positioning isn't required. - -## Examples - -Bind the dropdown's toggle and the dropdown menu inside `<CDropdown>`, or different element that declares `position: relative;`. Dropdowns can be triggered from `<a>` or `<button>` elements to better fit your possible requirements. - -### Single button - -Here's how you can put them to work with either `<button>` elements: - -```jsx preview -<CDropdown> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> -</CDropdown> -``` - -And with `<a>` elements: - -```jsx preview -<CDropdown> - <CDropdownToggle href="#" color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> -</CDropdown> -``` - -The best part is you can do this with any button variant, too: - -<Example> - <> - {['primary', 'secondary', 'success', 'info', 'warning', 'danger'].map((color, index) => ( - <CDropdown variant="btn-group" key={index}> - <CDropdownToggle color={color}>{color}</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - ))} - </> -</Example> - -```jsx -<> - {['primary', 'secondary', 'success', 'info', 'warning', 'danger'].map((color, index) => ( - <CDropdown variant="btn-group" key={index}> - <CDropdownToggle color={color}>{color}</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - ))} -</> -``` - -### Split button - -Similarly, create split button dropdowns with virtually the same markup as single button dropdowns, but with the addition of boolean prop `split` for proper spacing around the dropdown caret. - -We use this extra class to reduce the horizontal `padding` on either side of the caret by 25% and remove the `margin-left` that's attached for normal button dropdowns. Those additional changes hold the caret centered in the split button and implement a more properly sized hit area next to the main button. - -<Example> - <> - {['primary', 'secondary', 'success', 'info', 'warning', 'danger'].map((color, index) => ( - <CDropdown variant="btn-group" key={index}> - <CButton color={color}>{color}</CButton> - <CDropdownToggle color={color} split /> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - ))} - </> -</Example> - -```jsx -<> - {['primary', 'secondary', 'success', 'info', 'warning', 'danger'].map((color, index) => ( - <CDropdown variant="btn-group" key={index}> - <CButton color={color}>{color}</CButton> - <CDropdownToggle color={color} split /> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - ))} -</> -``` - -## Sizing - -Button dropdowns work with buttons of all sizes, including default and split dropdown buttons. - -```jsx preview - <CDropdown variant="btn-group"> - <CDropdownToggle color="secondary" size="lg">Large button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - - <CDropdown variant="btn-group"> - <CButton color="secondary" size="lg">Large split button</CButton> - <CDropdownToggle color="secondary" size="lg" split/> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> -``` - -```jsx preview - <CDropdown variant="btn-group"> - <CDropdownToggle color="secondary" size="sm">Small button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - - <CDropdown variant="btn-group"> - <CButton color="secondary" size="sm">Small split button</CButton> - <CDropdownToggle color="secondary" size="sm"split/> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> -``` - -## Dark dropdowns - -Opt into darker dropdowns to match a dark navbar or custom style by set `dark` property. No changes are required to the dropdown items. - -```jsx preview -<CDropdown dark> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> -</CDropdown> -``` - -And putting it to use in a navbar: - -```jsx preview -<CNavbar expand="lg" colorScheme="dark" className="bg-dark"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler aria-label="Toggle navigation" aria-expanded={true} /> - <CCollapse className="navbar-collapse" visible={true}> - <CNavbarNav> - <CDropdown dark component="li" variant="nav-item"> - <CDropdownToggle color="dark">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </CNavbarNav> - </CCollapse> - </CContainer> -</CNavbar> -``` - -## Directions - -<Callout color="info" title="RTL"> - Directions are mirrored when using CoreUI in RTL, meaning `.dropstart` will appear on the right side. -</Callout> - -### Centered - -Make the dropdown menu centered below the toggle by adding `direction="center"` to the `<CDropdown>` component. - -```jsx preview -<CDropdown variant="btn-group" direction="center"> - <CDropdownToggle color="secondary">Centered dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> -</CDropdown> -``` - -### Dropup - -Trigger dropdown menus above elements by adding `direction="dropup"` to the `<CDropdown>` component. - -```jsx preview - <CDropdown variant="btn-group" direction="dropup"> - <CDropdownToggle color="secondary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - - <CDropdown variant="btn-group" direction="dropup"> - <CButton color="secondary" >Small split button</CButton> - <CDropdownToggle color="secondary" split/> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> -``` - -### Dropup centered - -Make the dropup menu centered above the toggle by adding `direction="dropup-center"` to the `<CDropdown>` component. - -```jsx preview -<CDropdown variant="btn-group" direction="dropup-center"> - <CDropdownToggle color="secondary">Centered dropup</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> -</CDropdown> -``` - -### Dropend - -Trigger dropdown menus at the right of the elements by adding `direction="dropend"` to the `<CDropdown>` component. - -```jsx preview - <CDropdown variant="btn-group" direction="dropend"> - <CDropdownToggle color="secondary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - - <CDropdown variant="btn-group" direction="dropend"> - <CButton color="secondary" >Small split button</CButton> - <CDropdownToggle color="secondary" split/> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> -``` - -### Dropstart - -Trigger dropdown menus at the left of the elements by adding `direction="dropstart"` to the `<CDropdown>` component. - -```jsx preview - <CDropdown variant="btn-group" direction="dropstart"> - <CDropdownToggle color="secondary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - - <CButtonGroup> - <CDropdown variant="btn-group" direction="dropstart"> - <CDropdownToggle color="secondary" split/> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CButton color="secondary" >Small split button</CButton> - </CButtonGroup> -``` - -## Menu items - -Historically dropdown menu contents _had_ to be links, but that's no longer the case with v4. Now you can optionally use `<button>` elements in your dropdowns instead of just `<a>`s. - -```jsx preview -<CDropdown> - <CDropdownToggle color="secondary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem component="button">Action</CDropdownItem> - <CDropdownItem component="button">Another action</CDropdownItem> - <CDropdownItem component="button">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem component="button">Separated link</CDropdownItem> - </CDropdownMenu> -</CDropdown> -``` - -You can also create non-interactive dropdown items with `<CDropdownItemPlain>`. - -```jsx preview -<CDropdownMenu> - <CDropdownItemPlain>Dropdown item text</CDropdownItemPlain> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> -</CDropdownMenu> -``` - -### Active - -Set boolean property `active` to **style item as active**. - -In the following example we use `div` instead of `<CDropdownMenu>` to show `<CDropdownMenu>` content. - -```jsx preview -<CDropdownMenu> - <CDropdownItem href="#">Regular link</CDropdownItem> - <CDropdownItem href="#" active>Active link</CDropdownItem> - <CDropdownItem href="#">Another link</CDropdownItem> -</CDropdownMenu> -``` - -### Disabled - -Add `disabled` boolean property to items in the dropdown to **style them as disabled**. - -In the following example we use `div` instead of `<CDropdownMenu>` to show `<CDropdownMenu>` content. - -```jsx preview -<CDropdownMenu> - <CDropdownItem href="#">Regular link</CDropdownItem> - <CDropdownItem href="#" disabled>Disabled link</CDropdownItem> - <CDropdownItem href="#">Another link</CDropdownItem> -</CDropdownMenu> -``` - -## Menu alignment - -By default, a dropdown menu is automatically positioned 100% from the top and along the left side of its parent. Add `aligment="end"` to right align the dropdown menu. - -<Callout color="info"> - <strong>Heads up!</strong> Dropdowns are positioned thanks to Popper. -</Callout> - -```jsx preview -<CDropdown alignment="end"> - <CDropdownToggle color="secondary">Right-aligned menu example</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> -</CDropdown> -``` - -### Responsive alignment - -If you use responsive alignment, dynamic positioning is disabled. - -To align **right** the dropdown menu with the given breakpoint or larger, add `aligment="xs|sm|md|lg|xl|xxl: end"`. - -```jsx preview -<CDropdown alignment={{ lg: 'end' }}> - <CDropdownToggle color="secondary">Left-aligned but right aligned when large screen</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> -</CDropdown> -``` - -To align **left** the dropdown menu with the given breakpoint or larger, add `aligment="xs|sm|md|lg|xl|xxl: start"`. - -```jsx preview -<CDropdown alignment={{ xs: 'end', lg: 'start' }}> - <CDropdownToggle color="secondary">Right-aligned but left aligned when large screen</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> -</CDropdown> -``` - -## Menu content - -### Headers - -Add a header to label sections of actions in any dropdown menu. - -In the following example we use `div` instead of `<CDropdownMenu>` to show `<CDropdownMenu>` content. - -```jsx preview -<CDropdownMenu> - <CDropdownHeader>Dropdown header</CDropdownHeader> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> -</CDropdownMenu> -``` - -### Dividers - -Separate groups of related menu items with a divider. - -In the following example we use `div` instead of `<CDropdownMenu>` to show `<CDropdownMenu>` content. - -```jsx preview -<CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> -</CDropdownMenu> -``` - -### Text - -Place any freeform text within a dropdown menu with text. Note that you'll likely need additional sizing styles to constrain the menu width. - -```jsx preview -<CDropdownMenu className="p-4 text-body-secondary" style={{ maxWidth: '200px' }}> - <p>Some example text that's free-flowing within the dropdown menu.</p> - <p className="mb-0">And this is more example text.</p> -</CDropdownMenu> -``` - -### Forms - -Put a form within a dropdown menu, or make it into a dropdown menu. - -```jsx preview -<CDropdownMenu> - <CForm className="px-4 py-4"> - <div className="mb-3"> - <CFormLabel htmlFor="exampleDropdownFormEmail1">Email address</CFormLabel> - <CFormInput type="email" id="exampleDropdownFormEmail1" placeholder="email@example.com" /> - </div> - <div className="mb-3"> - <CFormLabel htmlFor="exampleDropdownFormPassword1">Password</CFormLabel> - <CFormInput type="password" id="exampleDropdownFormPassword1" placeholder="Password" /> - </div> - <div className="mb-3"> - <CFormCheck id="dropdownCheck" label="Remember me" /> - </div> - <CButton color="primary" type="submit">Sign in</CButton> - </CForm> - <CDropdownDivider /> - <CDropdownItem href="#">New around here? Sign up</CDropdownItem> - <CDropdownItem href="#">Forgot password?</CDropdownItem> -</CDropdownMenu> -``` - -## Customizing - -### CSS variables - -React dropdowns use local CSS variables on `.dropdown` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_dropdown.scss" capture="dropdown-css-vars"/> - -Customization through CSS variables can be seen on the `.dropdown-menu-dark` class where we override specific values without adding duplicate CSS selectors. - -<ScssDocs file="_dropdown.scss" capture="dropdown-dark-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CDropdown style={vars}>...</CDropdown> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="dropdown-variables"/> - -Variables for the dark dropdown: - -<ScssDocs file="_variables.scss" capture="dropdown-dark-variables"/> - -Variables for the CSS-based carets that indicate a dropdown's interactivity: - -<ScssDocs file="_variables.scss" capture="caret-variables"/> - -## API - -### CDropdown - -`markdown:CDropdown.api.mdx` - -### CDropdownDivider - -`markdown:CDropdownDivider.api.mdx` - -### CDropdownHeader - -`markdown:CDropdownHeader.api.mdx` - -### CDropdownItem - -`markdown:CDropdownItem.api.mdx` - -### CDropdownItemPlain - -`markdown:CDropdownItemPlain.api.mdx` - -### CDropdownMenu - -`markdown:CDropdownMenu.api.mdx` - -### CDropdownToggle - -`markdown:CDropdownToggle.api.mdx` diff --git a/packages/docs/content/components/footer.mdx b/packages/docs/content/components/footer.mdx deleted file mode 100644 index a1b380c8..00000000 --- a/packages/docs/content/components/footer.mdx +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: React Footer Component -name: Footer -description: React footer component is an additional navigation used for displaying general information that a user might want to access from any page within your site. It is a place to display boilerplate text about the site, company info, copyrights, links to a contact form, sitemap, FAQ and other such resources. -menu: Components -route: /components/footer -other_frameworks: footer ---- - -import { CFooter, CLink } from '@coreui/react/src/index' - -## Example - -```jsx preview demo -<CFooter> - <div> - <CLink href="https://coreui.io">CoreUI</CLink> - <span>© 2023 creativeLabs.</span> - </div> - <div> - <span>Powered by</span> - <CLink href="https://coreui.io">CoreUI</CLink> - </div> -</CFooter> -``` - -## Customizing - -### CSS variables - -React footers use local CSS variables on `.footer` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_footer.scss" capture="footer-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CFooter style={vars}>...</CFooter> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="footer-variables"/> - -## API - -### CFooter - -`markdown:CFooter.api.mdx` diff --git a/packages/docs/content/components/header.mdx b/packages/docs/content/components/header.mdx deleted file mode 100644 index d19e7c7b..00000000 --- a/packages/docs/content/components/header.mdx +++ /dev/null @@ -1,193 +0,0 @@ ---- -title: React Header Component -name: Header -description: Documentation and examples for the Header powerful, responsive navigation header. Includes support for branding, links, dropdowns, and more. -menu: Components -route: /components/header -other_frameworks: header ---- - -import { useState } from 'react' - -import { - CButton, - CContainer, - CCollapse, - CDropdown, - CDropdownDivider, - CDropdownHeader, - CDropdownItem, - CDropdownItemPlain, - CDropdownMenu, - CDropdownToggle, - CForm, - CFormInput, - CNav, - CNavItem, - CNavLink, - CHeader, - CHeaderBrand, - CHeaderDivider, - CHeaderNav, - CHeaderText, - CHeaderToggler, -} from '@coreui/react/src/index' - -## Supported content - -Headers come with built-in support for a handful of sub-components. Choose from the following as needed: - -- `<CHeaderBrand>` for your company, product, or project name. -- `<CHeaderNav>` for a full-height and lightweight navigation (including support for dropdowns). -- `<CHeaderToggler>` for use with our collapse plugin and other [navigation toggling](#responsive-behaviors) behaviors. -- Flex and spacing utilities for any form controls and actions. -- `<CHeaderText>` for adding vertically centered strings of text. -- `<CCollapse className="header-collapse">` for grouping and hiding header contents by a parent breakpoint. - -Here's an example of all the sub-components included in a responsive light-themed header that automatically collapses at the `lg` (large) breakpoint. - -## Basic usage - -export const BasicUsageExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CHeader> - <CContainer fluid> - <CHeaderBrand href="#">Header</CHeaderBrand> - <CHeaderToggler onClick={() => setVisible(!visible)} /> - <CCollapse className="header-collapse" visible={visible}> - <CHeaderNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item"> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CHeaderNav> - <CForm className="d-flex"> - <CFormInput className="me-2" type="search" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CHeader> - </> - ) -} - -<Example> - <BasicUsageExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CHeader> - <CContainer fluid> - <CHeaderBrand href="#">Header</CHeaderBrand> - <CHeaderToggler onClick={() => setVisible(!visible)} /> - <CCollapse className="header-collapse" visible={visible}> - <CHeaderNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item"> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CHeaderNav> - <CForm className="d-flex"> - <CFormInput className="me-2" type="search" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CHeader> - </> -) -``` - -## Customizing - -### CSS variables - -React headers use local CSS variables on `.header` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_header.scss" capture="header-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CHeader style={vars}>...</CHeader> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="header-variables"/> - -## API - -### CHeader - -`markdown:CHeader.api.mdx` - -### CHeaderBrand - -`markdown:CHeaderBrand.api.mdx` - -### CHeaderDivider - -`markdown:CHeaderDivider.api.mdx` - -### CHeaderNav - -`markdown:CHeaderNav.api.mdx` - -### CHeaderText - -`markdown:CHeaderText.api.mdx` - -### CHeaderToggler - -`markdown:CHeaderToggler.api.mdx` diff --git a/packages/docs/content/components/icon.mdx b/packages/docs/content/components/icon.mdx deleted file mode 100644 index 795072b5..00000000 --- a/packages/docs/content/components/icon.mdx +++ /dev/null @@ -1,320 +0,0 @@ ---- -title: React Icons Component -name: Icon -description: React icons library is a great resource for React developers, who can use its customizable SVG icons in their applications. It offers an extensive library of icons to choose from, which can be easily inserted into projects with just a few lines of code. Not only that, but users are also able to customize the appearance of these icons by setting various props on them. This provides developers with an efficient and flexible way to integrate useful graphical elements into their web pages without doing any extra work. -menu: Components -route: /components/icon ---- - -import { useState } from 'react' -import { - CCol, - CNav, - CNavItem, - CNavLink, - CRow, - CTabContent, - CTabPane } from '@coreui/react/src/index' -import CIcon from '@coreui/icons-react' -import { cilList, cilShieldAlt } from '@coreui/icons' -import * as icon from '@coreui/icons'; - -## Installation - -To start using CoreUI React Icons in your project, you need to install it as a dependency. Follow the instructions below based on your package manager of choice: - -### Npm - -```bash -npm install @coreui/icons @coreui/icons-react -``` - -### Yarn - -```bash -yarn add @coreui/icons @coreui/icons-react -``` - -## Usage - -Import react icons using one of these two options: - -### Single react icon - -To use a single react icon, import the `<CIcon>` component and the desired icon(s) from the `@coreui/icons` library. Then, include the `<CIcon>` component in your code and specify the icon prop with the imported icon variable. Additionally, you can set the desired size for the icon using the `size` prop. - -<Example> - <CIcon icon={cilList} size="xl"/> - <CIcon icon={cilShieldAlt} size="xl"/> -</Example> - -```jsx -import { CIcon } from '@coreui/icons-react'; -import { cilList, cilShieldAlt } from '@coreui/icons'; - -... -<CIcon icon={cilList} size="xl"/> -<CIcon icon={cilShieldAlt} size="xl"/> -... -``` - -### All react icons - -To use all icons available in the CoreUI React Icons package, import the CIcon component and the entire `@coreui/icons` library using the `* as` syntax. Then, reference the desired icon within the `icon` prop. - -```jsx -import CIcon from '@coreui/icons-react'; -import * as icon from '@coreui/icons'; - -... -render() { - return ( - <CIcon icon={icon.cilList} size="xxl"/> - ) -} -... -``` - -### Color - -The CoreUI React Icon component offers versatile color customization options, empowering you to personalize the icons in multiple ways. You can effortlessly modify the colors by utilizing either class names or CSS variables, providing flexibility and ease in creating visually stunning and cohesive icon designs. - -#### Utility classes - -With some [color utility classes](https://coreui.io/docs/utilities/colors/), you may use color to convey message. - -```jsx preview -<CIcon icon={cilList} size="xl" /> -<CIcon icon={cilList} className="text-primary" size="xl" /> -<CIcon icon={cilList} className="text-secondary" size="xl" /> -<CIcon icon={cilList} className="text-success" size="xl" /> -<CIcon icon={cilList} className="text-danger" size="xl" /> -<CIcon icon={cilList} className="text-warning" size="xl" /> -<CIcon icon={cilList} className="text-info" size="xl" /> -``` - -#### CSS Variables - -CoreUI React Icons leverage local CSS variables, such as `--ci-primary-color` and `--ci-secondary-color` (for Duotone icons), to facilitate real-time customization. This allows developers to easily customize the icons by providing their own custom CSS variables. - -```jsx preview -<CIcon icon={cilList} size="xl" style={{'--ci-primary-color': 'red'}} /> -<CIcon icon={cilList} size="xl" style={{'--ci-primary-color': 'green'}} /> -``` - -### Sizing - -Set heights of react icons using size property like size="lg" and size="sm". - -```jsx preview -<CIcon icon={cilList} size="sm" /> -<CIcon icon={cilList} size="md" /> -<CIcon icon={cilList} size="lg" /> -<CIcon icon={cilList} size="xl" /> -<CIcon icon={cilList} size="xxl" /> -<CIcon icon={cilList} size="3xl" /> -``` - - -## Accessibility - -It's crucial for react icons to be seen by as many people as possible because they have the power to communicate a variety of meaningful information. - -People who are blind, have low vision, or have other visual impairments make up approximately 10% of the world's population, and more than 5% of people worldwide have hearing loss that makes them unable to function normally. - -Therefore, it's crucial to make sure that the assistive equipment for people with disabilities, such as screen readers, either ignores or better understands the react icons you use online. - -Icons are used in one of two ways on websites, apps, and other digital spaces. - -#### Decorative Icons - -It is not necessary to declare an icon to visitors when they are using your website or app if you are utilizing it to offer extra decoration or branding. - -Additionally, if you use an icon to visually emphasize or add flair to content that is already present in your HTML, an assistive technology user does not need to see it again. - -In certain circumstances, the details of the icon ought to be concealed from the screenreader so as not to obstruct the intended message. - -#### Semantic Icons - -You need to make sure that consumers understand the meaning an icon is intended to represent by giving them text-based alternatives. - -This applies to both the content you're using icons to represent (such as the status of your shopping cart or the number of unread messages), as well react icons as interactive controls (such as buttons, form elements, toggles, etc.). - -### CoreUI React Icons and Accessibility - -Our React Icon component automatically takes care of accessibility concerns by adding appropriate elements. - -#### Decorative icons - -If your icons are only for decorative purposes, the CoreUI React Icon Component will ensure that assistive technology ignores the icon. In addition to referencing an icon as normal, the `aria-hidden=true` attribute has been introduced, so there is nothing else you need to do. - -If your markup looks like this: - -```jsx -<CButton> - <CIcon icon={cilCloudDownload} /> -</CButton> -``` - -By including the `aria-hidden` attribute, CoreUI React Icon Component will afterwards automatically hide it from screenreaders. - -```html -<button class="btn btn-primary" type="button"> - <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="icon" role="img" aria-hidden="true"> - <polygon fill="var(--ci-primary-color, currentColor)" points="272 434.744 272 209.176 240 209.176 240 434.744 188.118 382.862 165.49 405.489 256 496 346.51 405.489 323.882 382.862 272 434.744" class="ci-primary"></polygon><path fill="var(--ci-primary-color, currentColor)" d="M400,161.176c0-79.4-64.6-144-144-144s-144,64.6-144,144a96,96,0,0,0,0,192h80v-32H112a64,64,0,0,1,0-128h32v-32a112,112,0,0,1,224,0v32h32a64,64,0,0,1,0,128H320v32h80a96,96,0,0,0,0-192Z" class="ci-primary"></path> - </svg> -</button> -``` - -#### Semantic icons - -The description that you must set using the title property will be used by CoreUI React Icon Component to generate alternative text for the semantic icon. - -Thus, if your markup appears as follows: - -```jsx -<CButton> - <CIcon icon={cilCloudDownload} title="Download file" /> -</CButton> -``` - -CoreUI React Icon Component will make the necessary adjustments so that only screenreaders can "see" the supporting elements that convey the message. - -```html -<button class="btn btn-primary" type="button"> - <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="icon" role="img" aria-hidden="true"> - <polygon fill="var(--ci-primary-color, currentColor)" points="272 434.744 272 209.176 240 209.176 240 434.744 188.118 382.862 165.49 405.489 256 496 346.51 405.489 323.882 382.862 272 434.744" class="ci-primary"></polygon><path fill="var(--ci-primary-color, currentColor)" d="M400,161.176c0-79.4-64.6-144-144-144s-144,64.6-144,144a96,96,0,0,0,0,192h80v-32H112a64,64,0,0,1,0-128h32v-32a112,112,0,0,1,224,0v32h32a64,64,0,0,1,0,128H320v32h80a96,96,0,0,0,0-192Z" class="ci-primary"></path> - </svg> - <span class="visually-hidden">Download file</span> -</button> -``` - -## Available react icons - -The CoreUI React Icons package includes a comprehensive library of more than 1500 icons, available in various formats such as SVG, PNG, and Webfonts. These popular icons are meticulously crafted symbols representing common actions and items. You can utilize them in your digital products, whether they are web or mobile applications, to enhance their visual appeal and user experience. - -By leveraging the capabilities of the React Icons component from CoreUI, you can easily incorporate visually appealing icons into their React applications, allowing for more engaging and intuitive user interfaces. - -export const LinearExample = () => { - const icons = ['cilAccountLogout', 'cilActionRedo', 'cilActionUndo', 'cilAddressBook', 'cilAirplaneModeOff', 'cilAirplaneMode', 'cilAirplay', 'cilAlarm', 'cilAlbum', 'cilAlignCenter', 'cilAlignLeft', 'cilAlignRight', 'cilAmericanFootball', 'cilAnimal', 'cilAperture', 'cilApple', 'cilApplicationsSettings', 'cilApplications', 'cilAppsSettings', 'cilApps', 'cilArrowBottom', 'cilArrowCircleBottom', 'cilArrowCircleLeft', 'cilArrowCircleRight', 'cilArrowCircleTop', 'cilArrowLeft', 'cilArrowRight', 'cilArrowThickBottom', 'cilArrowThickFromBottom', 'cilArrowThickFromLeft', 'cilArrowThickFromRight', 'cilArrowThickFromTop', 'cilArrowThickLeft', 'cilArrowThickRight', 'cilArrowThickToBottom', 'cilArrowThickToLeft', 'cilArrowThickToRight', 'cilArrowThickToTop', 'cilArrowThickTop', 'cilArrowTop', 'cilAssistiveListeningSystem', 'cilAsteriskCircle', 'cilAsterisk', 'cilAt', 'cilAudioDescription', 'cilAudioSpectrum', 'cilAudio', 'cilAvTimer', 'cilBabyCarriage', 'cilBaby', 'cilBackspace', 'cilBadge', 'cilBalanceScale', 'cilBan', 'cilBank', 'cilBarChart', 'cilBarcode', 'cilBaseball', 'cilBasket', 'cilBasketball', 'cilBath', 'cilBathroom', 'cilBattery0', 'cilBattery3', 'cilBattery5', 'cilBatteryAlert', 'cilBatteryEmpty', 'cilBatteryFull', 'cilBatterySlash', 'cilBeachAccess', 'cilBeaker', 'cilBed', 'cilBellExclamation', 'cilBell', 'cilBike', 'cilBirthdayCake', 'cilBlind', 'cilBluetooth', 'cilBlurCircular', 'cilBlurLinear', 'cilBlur', 'cilBoatAlt', 'cilBold', 'cilBoltCircle', 'cilBolt', 'cilBook', 'cilBookmark', 'cilBorderAll', 'cilBorderBottom', 'cilBorderClear', 'cilBorderHorizontal', 'cilBorderInner', 'cilBorderLeft', 'cilBorderOuter', 'cilBorderRight', 'cilBorderStyle', 'cilBorderTop', 'cilBorderVertical', 'cilBowling', 'cilBraille', 'cilBriefcase', 'cilBrightness', 'cilBritishPound', 'cilBrowser', 'cilBrushAlt', 'cilBrush', 'cilBug', 'cilBuilding', 'cilBullhorn', 'cilBurger', 'cilBurn', 'cilBusAlt', 'cilCalculator', 'cilCalendarCheck', 'cilCalendar', 'cilCameraControl', 'cilCameraRoll', 'cilCamera', 'cilCarAlt', 'cilCaretBottom', 'cilCaretLeft', 'cilCaretRight', 'cilCaretTop', 'cilCart', 'cilCash', 'cilCasino', 'cilCast', 'cilCat', 'cilCc', 'cilCenterFocus', 'cilChartLine', 'cilChartPie', 'cilChart', 'cilChatBubble', 'cilCheckAlt', 'cilCheckCircle', 'cilCheck', 'cilChevronBottom', 'cilChevronCircleDownAlt', 'cilChevronCircleLeftAlt', 'cilChevronCircleRightAlt', 'cilChevronCircleUpAlt', 'cilChevronDoubleDown', 'cilChevronDoubleLeft', 'cilChevronDoubleRight', 'cilChevronDoubleUp', 'cilChevronLeft', 'cilChevronRight', 'cilChevronTop', 'cilChildFriendly', 'cilChild', 'cilCircle', 'cilClearAll', 'cilClipboard', 'cilClock', 'cilClone', 'cilClosedCaptioning', 'cilCloudDownload', 'cilCloudUpload', 'cilCloud', 'cilCloudy', 'cilCode', 'cilCoffee', 'cilCog', 'cilColorBorder', 'cilColorFill', 'cilColorPalette', 'cilColumns', 'cilCommand', 'cilCommentBubble', 'cilCommentSquare', 'cilCompass', 'cilCompress', 'cilContact', 'cilContrast', 'cilControl', 'cilCopy', 'cilCouch', 'cilCreditCard', 'cilCropRotate', 'cilCrop', 'cilCursorMove', 'cilCursor', 'cilCut', 'cilDataTransferDown', 'cilDataTransferUp', 'cilDeaf', 'cilDelete', 'cilDescription', 'cilDevices', 'cilDialpad', 'cilDiamond', 'cilDinner', 'cilDisabled', 'cilDog', 'cilDollar', 'cilDoor', 'cilDoubleQuoteSansLeft', 'cilDoubleQuoteSansRight', 'cilDrinkAlcohol', 'cilDrink', 'cilDrop', 'cilEco', 'cilEducation', 'cilElevator', 'cilEnvelopeClosed', 'cilEnvelopeLetter', 'cilEnvelopeOpen', 'cilEqualizer', 'cilEthernet', 'cilEuro', 'cilExcerpt', 'cilExitToApp', 'cilExpandDown', 'cilExpandLeft', 'cilExpandRight', 'cilExpandUp', 'cilExposure', 'cilExternalLink', 'cilEyedropper', 'cilFaceDead', 'cilFace', 'cilFactorySlash', 'cilFactory', 'cilFastfood', 'cilFax', 'cilFeaturedPlaylist', 'cilFile', 'cilFilterFrames', 'cilFilterPhoto', 'cilFilterSquare', 'cilFilterX', 'cilFilter', 'cilFindInPage', 'cilFingerprint', 'cilFire', 'cilFlagAlt', 'cilFlightTakeoff', 'cilFlipToBack', 'cilFlipToFront', 'cilFlip', 'cilFlower', 'cilFolderOpen', 'cilFolder', 'cilFont', 'cilFootball', 'cilFork', 'cilFridge', 'cilFrown', 'cilFullscreenExit', 'cilFullscreen', 'cilFunctionsAlt', 'cilFunctions', 'cilGamepad', 'cilGarage', 'cilGem', 'cilGif', 'cilGift', 'cilGlobeAlt', 'cilGolfAlt', 'cilGolf', 'cilGradient', 'cilGrain', 'cilGraph', 'cilGridSlash', 'cilGrid', 'cilGroup', 'cilHamburgerMenu', 'cilHandPointDown', 'cilHandPointLeft', 'cilHandPointRight', 'cilHandPointUp', 'cilHappy', 'cilHd', 'cilHdr', 'cilHeader', 'cilHeadphones', 'cilHealing', 'cilHeart', 'cilHighlighter', 'cilHighligt', 'cilHistory', 'cilHome', 'cilHospital', 'cilHotTub', 'cilHouse', 'cilHttps', 'cilImageBroken', 'cilImagePlus', 'cilImage', 'cilInbox', 'cilIndentDecrease', 'cilIndentIncrease', 'cilIndustrySlash', 'cilIndustry', 'cilInfinity', 'cilInfo', 'cilInputHdmi', 'cilInputPower', 'cilInput', 'cilInstitution', 'cilItalic', 'cilJustifyCenter', 'cilJustifyLeft', 'cilJustifyRight', 'cilKeyboard', 'cilLan', 'cilLanguage', 'cilLaptop', 'cilLayers', 'cilLeaf', 'cilLemon', 'cilLevelDown', 'cilLevelUp', 'cilLibraryAdd', 'cilLibraryBuilding', 'cilLibrary', 'cilLifeRing', 'cilLightbulb', 'cilLineSpacing', 'cilLineStyle', 'cilLineWeight', 'cilLinkAlt', 'cilLinkBroken', 'cilLink', 'cilListFilter', 'cilListHighPriority', 'cilListLowPriority', 'cilListNumberedRtl', 'cilListNumbered', 'cilListRich', 'cilList', 'cilLocationPin', 'cilLockLocked', 'cilLockUnlocked', 'cilLocomotive', 'cilLoop1', 'cilLoopCircular', 'cilLoop', 'cilLowVision', 'cilMagnifyingGlass', 'cilMap', 'cilMediaEject', 'cilMediaPause', 'cilMediaPlay', 'cilMediaRecord', 'cilMediaSkipBackward', 'cilMediaSkipForward', 'cilMediaStepBackward', 'cilMediaStepForward', 'cilMediaStop', 'cilMedicalCross', 'cilMeh', 'cilMemory', 'cilMenu', 'cilMic', 'cilMicrophone', 'cilMinus', 'cilMobileLandscape', 'cilMobile', 'cilMoney', 'cilMonitor', 'cilMoodBad', 'cilMoodGood', 'cilMoodVeryBad', 'cilMoodVeryGood', 'cilMoon', 'cilMouse', 'cilMouthSlash', 'cilMove', 'cilMovie', 'cilMugTea', 'cilMug', 'cilMusicNote', 'cilNewspaper', 'cilNoteAdd', 'cilNotes', 'cilObjectGroup', 'cilObjectUngroup', 'cilOpacity', 'cilOpentype', 'cilOptions', 'cilPaintBucket', 'cilPaint', 'cilPaperPlane', 'cilPaperclip', 'cilParagraph', 'cilPaw', 'cilPenAlt', 'cilPenNib', 'cilPen', 'cilPencil', 'cilPeople', 'cilPhone', 'cilPin', 'cilPizza', 'cilPlant', 'cilPlaylistAdd', 'cilPlus', 'cilPool', 'cilPowerStandby', 'cilPregnant', 'cilPrint', 'cilPushchair', 'cilPuzzle', 'cilQrCode', 'cilRain', 'cilRectangle', 'cilRecycle', 'cilReload', 'cilReportSlash', 'cilResizeBoth', 'cilResizeHeight', 'cilResizeWidth', 'cilRestaurant', 'cilRoom', 'cilRouter', 'cilRowing', 'cilRss', 'cilRuble', 'cilRunning', 'cilSad', 'cilSatelite', 'cilSave', 'cilSchool', 'cilScreenDesktop', 'cilScreenSmartphone', 'cilScrubber', 'cilSearch', 'cilSend', 'cilSettings', 'cilShareAll', 'cilShareAlt', 'cilShareBoxed', 'cilShare', 'cilShieldAlt', 'cilShortText', 'cilShower', 'cilSignLanguage', 'cilSignalCellular0', 'cilSignalCellular3', 'cilSignalCellular4', 'cilSim', 'cilSitemap', 'cilSmilePlus', 'cilSmile', 'cilSmokeFree', 'cilSmokeSlash', 'cilSmoke', 'cilSmokingRoom', 'cilSnowflake', 'cilSoccer', 'cilSofa', 'cilSortAlphaDown', 'cilSortAlphaUp', 'cilSortAscending', 'cilSortDescending', 'cilSortNumericDown', 'cilSortNumericUp', 'cilSpa', 'cilSpaceBar', 'cilSpeak', 'cilSpeaker', 'cilSpeech', 'cilSpeedometer', 'cilSpreadsheet', 'cilSquare', 'cilStarHalf', 'cilStar', 'cilStorage', 'cilStream', 'cilStrikethrough', 'cilSun', 'cilSwapHorizontal', 'cilSwapVertical', 'cilSwimming', 'cilSync', 'cilTablet', 'cilTag', 'cilTags', 'cilTask', 'cilTaxi', 'cilTennisBall', 'cilTennis', 'cilTerminal', 'cilTerrain', 'cilTextShapes', 'cilTextSize', 'cilTextSquare', 'cilTextStrike', 'cilText', 'cilThumbDown', 'cilThumbUp', 'cilToggleOff', 'cilToggleOn', 'cilToilet', 'cilTouchApp', 'cilTransfer', 'cilTranslate', 'cilTrash', 'cilTriangle', 'cilTruck', 'cilTv', 'cilUnderline', 'cilUsb', 'cilUserFemale', 'cilUserFollow', 'cilUserPlus', 'cilUserUnfollow', 'cilUserX', 'cilUser', 'cilVector', 'cilVerticalAlignBottom', 'cilVerticalAlignCenter', 'cilVerticalAlignTop', 'cilVideo', 'cilVideogame', 'cilViewColumn', 'cilViewModule', 'cilViewQuilt', 'cilViewStream', 'cilVoiceOverRecord', 'cilVoice', 'cilVolumeHigh', 'cilVolumeLow', 'cilVolumeOff', 'cilWalk', 'cilWallet', 'cilWallpaper', 'cilWarning', 'cilWatch', 'cilWc', 'cilWeightlifitng', 'cilWheelchair', 'cilWifiSignal0', 'cilWifiSignal1', 'cilWifiSignal2', 'cilWifiSignal3', 'cilWifiSignal4', 'cilWifiSignalOff', 'cilWindowMaximize', 'cilWindowMinimize', 'cilWindowRestore', 'cilWindow', 'cilWrapText', 'cilXCircle', 'cilX', 'cilYen', 'cilZoomIn', 'cilZoomOut', 'cilZoom'] - return ( - <CRow xs={{ cols: 3 }} sm={{ cols: 4 }} lg={{ cols: 5 }}> - {icons.map((i, idx) => { - return ( - <CCol className="mb-4" key={idx}> - <div className="p-3 py-4 mb-2 bg-light text-center rounded"> - <CIcon icon={icon[i]} size="xxl"/> - </div> - <div className="text-body-secondary text-center pt-1 small">{i}</div> - </CCol>) - })} - </CRow> - ) -} - -export const BrandExample = () => { - const icons = ['cib500px5', 'cib500px', 'cibAboutMe', 'cibAbstract', 'cibAcm', 'cibAddthis', 'cibAdguard', 'cibAdobeAcrobatReader', 'cibAdobeAfterEffects', 'cibAdobeAudition', 'cibAdobeCreativeCloud', 'cibAdobeDreamweaver', 'cibAdobeIllustrator', 'cibAdobeIndesign', 'cibAdobeLightroomClassic', 'cibAdobeLightroom', 'cibAdobePhotoshop', 'cibAdobePremiere', 'cibAdobeTypekit', 'cibAdobeXd', 'cibAdobe', 'cibAirbnb', 'cibAlgolia', 'cibAlipay', 'cibAllocine', 'cibAmazonAws', 'cibAmazonPay', 'cibAmazon', 'cibAmd', 'cibAmericanExpress', 'cibAnaconda', 'cibAnalogue', 'cibAndroidAlt', 'cibAndroid', 'cibAngellist', 'cibAngularUniversal', 'cibAngular', 'cibAnsible', 'cibApacheAirflow', 'cibApacheFlink', 'cibApacheSpark', 'cibApache', 'cibAppStoreIos', 'cibAppStore', 'cibAppleMusic', 'cibApplePay', 'cibApplePodcasts', 'cibApple', 'cibAppveyor', 'cibAral', 'cibArchLinux', 'cibArchiveOfOurOwn', 'cibArduino', 'cibArtstation', 'cibArxiv', 'cibAsana', 'cibAtAndT', 'cibAtlassian', 'cibAtom', 'cibAudible', 'cibAurelia', 'cibAuth0', 'cibAutomatic', 'cibAutotask', 'cibAventrix', 'cibAzureArtifacts', 'cibAzureDevops', 'cibAzurePipelines', 'cibBabel', 'cibBaidu', 'cibBamboo', 'cibBancontact', 'cibBandcamp', 'cibBasecamp', 'cibBathasu', 'cibBehance', 'cibBigCartel', 'cibBing', 'cibBit', 'cibBitbucket', 'cibBitcoin', 'cibBitdefender', 'cibBitly', 'cibBlackberry', 'cibBlender', 'cibBloggerB', 'cibBlogger', 'cibBluetoothB', 'cibBluetooth', 'cibBoeing', 'cibBoost', 'cibBootstrap', 'cibBower', 'cibBrandAi', 'cibBrave', 'cibBtc', 'cibBuddy', 'cibBuffer', 'cibBuyMeACoffee', 'cibBuysellads', 'cibBuzzfeed', 'cibC', 'cibCakephp', 'cibCampaignMonitor', 'cibCanva', 'cibCashapp', 'cibCassandra', 'cibCastro', 'cibCcAmazonPay', 'cibCcAmex', 'cibCcApplePay', 'cibCcDinersClub', 'cibCcDiscover', 'cibCcJcb', 'cibCcMastercard', 'cibCcPaypal', 'cibCcStripe', 'cibCcVisa', 'cibCentos', 'cibCevo', 'cibChase', 'cibChef', 'cibChromecast', 'cibCircle', 'cibCircleci', 'cibCirrusci', 'cibCisco', 'cibCivicrm', 'cibClockify', 'cibClojure', 'cibCloudbees', 'cibCloudflare', 'cibCmake', 'cibCoOp', 'cibCodacy', 'cibCodeClimate', 'cibCodecademy', 'cibCodecov', 'cibCodeigniter', 'cibCodepen', 'cibCoderwall', 'cibCodesandbox', 'cibCodeship', 'cibCodewars', 'cibCodio', 'cibCoffeescript', 'cibCommonWorkflowLanguage', 'cibComposer', 'cibCondaForge', 'cibConekta', 'cibConfluence', 'cibCoreuiC', 'cibCoreui', 'cibCoursera', 'cibCoveralls', 'cibCpanel', 'cibCplusplus', 'cibCreativeCommonsBy', 'cibCreativeCommonsNcEu', 'cibCreativeCommonsNcJp', 'cibCreativeCommonsNc', 'cibCreativeCommonsNd', 'cibCreativeCommonsPdAlt', 'cibCreativeCommonsPd', 'cibCreativeCommonsRemix', 'cibCreativeCommonsSa', 'cibCreativeCommonsSamplingPlus', 'cibCreativeCommonsSampling', 'cibCreativeCommonsShare', 'cibCreativeCommonsZero', 'cibCreativeCommons', 'cibCrunchbase', 'cibCrunchyroll', 'cibCss3Shiled', 'cibCss3', 'cibCsswizardry', 'cibD3Js', 'cibDailymotion', 'cibDashlane', 'cibDazn', 'cibDblp', 'cibDebian', 'cibDeepin', 'cibDeezer', 'cibDelicious', 'cibDell', 'cibDeno', 'cibDependabot', 'cibDesignerNews', 'cibDevTo', 'cibDeviantart', 'cibDevrant', 'cibDiaspora', 'cibDigg', 'cibDigitalOcean', 'cibDiscord', 'cibDiscourse', 'cibDiscover', 'cibDisqus', 'cibDisroot', 'cibDjango', 'cibDocker', 'cibDocusign', 'cibDotNet', 'cibDraugiemLv', 'cibDribbble', 'cibDrone', 'cibDropbox', 'cibDrupal', 'cibDtube', 'cibDuckduckgo', 'cibDynatrace', 'cibEbay', 'cibEclipseide', 'cibElasticCloud', 'cibElasticSearch', 'cibElasticStack', 'cibElastic', 'cibElectron', 'cibElementary', 'cibEleventy', 'cibEllo', 'cibElsevier', 'cibEmlakjet', 'cibEmpirekred', 'cibEnvato', 'cibEpicGames', 'cibEpson', 'cibEsea', 'cibEslint', 'cibEthereum', 'cibEtsy', 'cibEventStore', 'cibEventbrite', 'cibEvernote', 'cibEverplaces', 'cibEvry', 'cibExercism', 'cibExpertsExchange', 'cibExpo', 'cibEyeem', 'cibFSecure', 'cibFacebookF', 'cibFacebook', 'cibFaceit', 'cibFandango', 'cibFavro', 'cibFeathub', 'cibFedex', 'cibFedora', 'cibFeedly', 'cibFidoAlliance', 'cibFigma', 'cibFilezilla', 'cibFirebase', 'cibFitbit', 'cibFlask', 'cibFlattr', 'cibFlickr', 'cibFlipboard', 'cibFlutter', 'cibFnac', 'cibFoursquare', 'cibFramer', 'cibFreebsd', 'cibFreecodecamp', 'cibFurAffinity', 'cibFurryNetwork', 'cibGarmin', 'cibGatsby', 'cibGauges', 'cibGenius', 'cibGentoo', 'cibGeocaching', 'cibGerrit', 'cibGg', 'cibGhost', 'cibGimp', 'cibGit', 'cibGitea', 'cibGithub', 'cibGitkraken', 'cibGitlab', 'cibGitpod', 'cibGitter', 'cibGlassdoor', 'cibGlitch', 'cibGmail', 'cibGnuPrivacyGuard', 'cibGnuSocial', 'cibGnu', 'cibGo', 'cibGodotEngine', 'cibGogCom', 'cibGoldenline', 'cibGoodreads', 'cibGoogleAds', 'cibGoogleAllo', 'cibGoogleAnalytics', 'cibGoogleChrome', 'cibGoogleCloud', 'cibGoogleKeep', 'cibGooglePay', 'cibGooglePlay', 'cibGooglePodcasts', 'cibGoogle', 'cibGooglesCholar', 'cibGovUk', 'cibGradle', 'cibGrafana', 'cibGraphcool', 'cibGraphql', 'cibGrav', 'cibGravatar', 'cibGreenkeeper', 'cibGreensock', 'cibGroovy', 'cibGroupon', 'cibGrunt', 'cibGulp', 'cibGumroad', 'cibGumtree', 'cibHabr', 'cibHackaday', 'cibHackerearth', 'cibHackerone', 'cibHackerrank', 'cibHackhands', 'cibHackster', 'cibHappycow', 'cibHashnode', 'cibHaskell', 'cibHatenaBookmark', 'cibHaxe', 'cibHelm', 'cibHere', 'cibHeroku', 'cibHexo', 'cibHighly', 'cibHipchat', 'cibHitachi', 'cibHockeyapp', 'cibHomify', 'cibHootsuite', 'cibHotjar', 'cibHouzz', 'cibHp', 'cibHtml5Shield', 'cibHtml5', 'cibHtmlacademy', 'cibHuawei', 'cibHubspot', 'cibHulu', 'cibHumbleBundle', 'cibIata', 'cibIbm', 'cibIcloud', 'cibIconjar', 'cibIcq', 'cibIdeal', 'cibIfixit', 'cibImdb', 'cibIndeed', 'cibInkscape', 'cibInstacart', 'cibInstagram', 'cibInstapaper', 'cibIntel', 'cibIntellijidea', 'cibIntercom', 'cibInternetExplorer', 'cibInvision', 'cibIonic', 'cibIssuu', 'cibItchIo', 'cibJabber', 'cibJava', 'cibJavascript', 'cibJekyll', 'cibJenkins', 'cibJest', 'cibJet', 'cibJetbrains', 'cibJira', 'cibJoomla', 'cibJquery', 'cibJs', 'cibJsdelivr', 'cibJsfiddle', 'cibJson', 'cibJupyter', 'cibJustgiving', 'cibKaggle', 'cibKaios', 'cibKaspersky', 'cibKentico', 'cibKeras', 'cibKeybase', 'cibKeycdn', 'cibKhanAcademy', 'cibKibana', 'cibKickstarter', 'cibKik', 'cibKirby', 'cibKlout', 'cibKnown', 'cibKoFi', 'cibKodi', 'cibKoding', 'cibKotlin', 'cibKrita', 'cibKubernetes', 'cibLanyrd', 'cibLaravelHorizon', 'cibLaravelNova', 'cibLaravel', 'cibLastFm', 'cibLatex', 'cibLaunchpad', 'cibLeetcode', 'cibLenovo', 'cibLess', 'cibLetsEncrypt', 'cibLetterboxd', 'cibLgtm', 'cibLiberapay', 'cibLibrarything', 'cibLibreoffice', 'cibLine', 'cibLinkedinIn', 'cibLinkedin', 'cibLinuxFoundation', 'cibLinuxMint', 'cibLinux', 'cibLivejournal', 'cibLivestream', 'cibLogstash', 'cibLua', 'cibLumen', 'cibLyft', 'cibMacys', 'cibMagento', 'cibMagisk', 'cibMailRu', 'cibMailchimp', 'cibMakerbot', 'cibManjaro', 'cibMarkdown', 'cibMarketo', 'cibMastercard', 'cibMastodon', 'cibMaterialDesign', 'cibMathworks', 'cibMatrix', 'cibMattermost', 'cibMatternet', 'cibMaxcdn', 'cibMcafee', 'cibMediaTemple', 'cibMediafire', 'cibMediumM', 'cibMedium', 'cibMeetup', 'cibMega', 'cibMendeley', 'cibMessenger', 'cibMeteor', 'cibMicroBlog', 'cibMicrogenetics', 'cibMicrosoftEdge', 'cibMicrosoft', 'cibMinetest', 'cibMinutemailer', 'cibMix', 'cibMixcloud', 'cibMixer', 'cibMojang', 'cibMonero', 'cibMongodb', 'cibMonkeytie', 'cibMonogram', 'cibMonzo', 'cibMoo', 'cibMozillaFirefox', 'cibMozilla', 'cibMusescore', 'cibMxlinux', 'cibMyspace', 'cibMysql', 'cibNativescript', 'cibNec', 'cibNeo4J', 'cibNetflix', 'cibNetlify', 'cibNextJs', 'cibNextcloud', 'cibNextdoor', 'cibNginx', 'cibNim', 'cibNintendo3Ds', 'cibNintendoGamecube', 'cibNintendoSwitch', 'cibNintendo', 'cibNodeJs', 'cibNodeRed', 'cibNodemon', 'cibNokia', 'cibNotion', 'cibNpm', 'cibNucleo', 'cibNuget', 'cibNuxtJs', 'cibNvidia', 'cibOcaml', 'cibOctave', 'cibOctopusDeploy', 'cibOculus', 'cibOdnoklassniki', 'cibOpenAccess', 'cibOpenCollective', 'cibOpenId', 'cibOpenSourceInitiative', 'cibOpenstreetmap', 'cibOpensuse', 'cibOpenvpn', 'cibOpera', 'cibOpsgenie', 'cibOracle', 'cibOrcid', 'cibOrigin', 'cibOsi', 'cibOsmc', 'cibOvercast', 'cibOverleaf', 'cibOvh', 'cibPagekit', 'cibPalantir', 'cibPandora', 'cibPantheon', 'cibPatreon', 'cibPaypal', 'cibPeriscope', 'cibPhp', 'cibPicartoTv', 'cibPinboard', 'cibPingdom', 'cibPingup', 'cibPinterestP', 'cibPinterest', 'cibPivotaltracker', 'cibPlangrid', 'cibPlayerMe', 'cibPlayerfm', 'cibPlaystation', 'cibPlaystation3', 'cibPlaystation4', 'cibPlesk', 'cibPlex', 'cibPluralsight', 'cibPlurk', 'cibPocket', 'cibPostgresql', 'cibPostman', 'cibPostwoman', 'cibPowershell', 'cibPrettier', 'cibPrismic', 'cibProbot', 'cibProcesswire', 'cibProductHunt', 'cibProtoIo', 'cibProtonmail', 'cibProxmox', 'cibPypi', 'cibPython', 'cibPytorch', 'cibQgis', 'cibQiita', 'cibQq', 'cibQualcomm', 'cibQuantcast', 'cibQuantopian', 'cibQuarkus', 'cibQuora', 'cibQwiklabs', 'cibQzone', 'cibR', 'cibRadiopublic', 'cibRails', 'cibRaspberryPi', 'cibReact', 'cibReadTheDocs', 'cibReadme', 'cibRealm', 'cibReason', 'cibRedbubble', 'cibRedditAlt', 'cibReddit', 'cibRedhat', 'cibRedis', 'cibRedux', 'cibRenren', 'cibReverbnation', 'cibRiot', 'cibRipple', 'cibRiseup', 'cibRollupJs', 'cibRoots', 'cibRoundcube', 'cibRss', 'cibRstudio', 'cibRuby', 'cibRubygems', 'cibRunkeeper', 'cibRust', 'cibSafari', 'cibSahibinden', 'cibSalesforce', 'cibSaltstack', 'cibSamsungPay', 'cibSamsung', 'cibSap', 'cibSassAlt', 'cibSass', 'cibSaucelabs', 'cibScala', 'cibScaleway', 'cibScribd', 'cibScrutinizerci', 'cibSeagate', 'cibSega', 'cibSellfy', 'cibSemaphoreci', 'cibSensu', 'cibSentry', 'cibServerFault', 'cibShazam', 'cibShell', 'cibShopify', 'cibShowpad', 'cibSiemens', 'cibSignal', 'cibSinaWeibo', 'cibSitepoint', 'cibSketch', 'cibSkillshare', 'cibSkyliner', 'cibSkype', 'cibSlack', 'cibSlashdot', 'cibSlickpic', 'cibSlides', 'cibSlideshare', 'cibSmashingmagazine', 'cibSnapchat', 'cibSnapcraft', 'cibSnyk', 'cibSociety6', 'cibSocketIo', 'cibSogou', 'cibSolus', 'cibSongkick', 'cibSonos', 'cibSoundcloud', 'cibSourceforge', 'cibSourcegraph', 'cibSpacemacs', 'cibSpacex', 'cibSparkfun', 'cibSparkpost', 'cibSpdx', 'cibSpeakerDeck', 'cibSpectrum', 'cibSpotify', 'cibSpotlight', 'cibSpreaker', 'cibSpring', 'cibSprint', 'cibSquarespace', 'cibStackbit', 'cibStackexchange', 'cibStackoverflow', 'cibStackpath', 'cibStackshare', 'cibStadia', 'cibStatamic', 'cibStaticman', 'cibStatuspage', 'cibSteam', 'cibSteem', 'cibSteemit', 'cibStitcher', 'cibStorify', 'cibStorybook', 'cibStrapi', 'cibStrava', 'cibStripeS', 'cibStripe', 'cibStubhub', 'cibStumbleupon', 'cibStyleshare', 'cibStylus', 'cibSublimeText', 'cibSubversion', 'cibSuperuser', 'cibSvelte', 'cibSvg', 'cibSwagger', 'cibSwarm', 'cibSwift', 'cibSymantec', 'cibSymfony', 'cibSynology', 'cibTMobile', 'cibTableau', 'cibTails', 'cibTapas', 'cibTeamviewer', 'cibTed', 'cibTeespring', 'cibTelegramPlane', 'cibTelegram', 'cibTencentQq', 'cibTencentWeibo', 'cibTensorflow', 'cibTerraform', 'cibTesla', 'cibTheMighty', 'cibTheMovieDatabase', 'cibTidal', 'cibTiktok', 'cibTinder', 'cibTodoist', 'cibToggl', 'cibTopcoder', 'cibToptal', 'cibTor', 'cibToshiba', 'cibTrainerroad', 'cibTrakt', 'cibTravisci', 'cibTreehouse', 'cibTrello', 'cibTripadvisor', 'cibTrulia', 'cibTumblr', 'cibTwilio', 'cibTwitch', 'cibTwitter', 'cibTwoo', 'cibTypescript', 'cibTypo3', 'cibUber', 'cibUbisoft', 'cibUblockOrigin', 'cibUbuntu', 'cibUdacity', 'cibUdemy', 'cibUikit', 'cibUmbraco', 'cibUnity', 'cibUnrealEngine', 'cibUnsplash', 'cibUntappd', 'cibUpwork', 'cibUsb', 'cibV8', 'cibVagrant', 'cibVenmo', 'cibVerizon', 'cibViadeo', 'cibViber', 'cibVim', 'cibVimeoV', 'cibVimeo', 'cibVine', 'cibVirb', 'cibVisa', 'cibVisualStudioCode', 'cibVisualStudio', 'cibVk', 'cibVlc', 'cibVsco', 'cibVueJs', 'cibWattpad', 'cibWeasyl', 'cibWebcomponentsOrg', 'cibWebpack', 'cibWebstorm', 'cibWechat', 'cibWhatsapp', 'cibWhenIWork', 'cibWii', 'cibWiiu', 'cibWikipedia', 'cibWindows', 'cibWire', 'cibWireguard', 'cibWix', 'cibWolframLanguage', 'cibWolframMathematica', 'cibWolfram', 'cibWordpress', 'cibWpengine', 'cibXPack', 'cibXbox', 'cibXcode', 'cibXero', 'cibXiaomi', 'cibXing', 'cibXrp', 'cibXsplit', 'cibYCombinator', 'cibYahoo', 'cibYammer', 'cibYandex', 'cibYarn', 'cibYelp', 'cibYoutube', 'cibZalando', 'cibZapier', 'cibZeit', 'cibZendesk', 'cibZerply', 'cibZillow', 'cibZingat', 'cibZoom', 'cibZorin', 'cibZulip'] - return ( - <CRow xs={{ cols: 3 }} sm={{ cols: 4 }} lg={{ cols: 5 }}> - {icons.map((i, idx) => { - return ( - <CCol className="mb-4" key={idx}> - <div className="p-3 py-4 mb-2 bg-light text-center rounded"> - <CIcon icon={icon[i]} size="xxl"/> - </div> - <div className="text-body-secondary text-center pt-1 small">{i}</div> - </CCol>) - })} - </CRow> - ) -} - -export const FlagsExample = () => { - const icons = ['cifAd', 'cifAe', 'cifAf', 'cifAg', 'cifAl', 'cifAm', 'cifAo', 'cifAr', 'cifAt', 'cifAu', 'cifAz', 'cifBa', 'cifBb', 'cifBd', 'cifBe', 'cifBf', 'cifBg', 'cifBh', 'cifBi', 'cifBj', 'cifBn', 'cifBo', 'cifBr', 'cifBs', 'cifBt', 'cifBw', 'cifBy', 'cifBz', 'cifCa', 'cifCd', 'cifCf', 'cifCg', 'cifCh', 'cifCi', 'cifCl', 'cifCm', 'cifCn', 'cifCo', 'cifCr', 'cifCu', 'cifCv', 'cifCy', 'cifCz', 'cifDe', 'cifDj', 'cifDk', 'cifDm', 'cifDo', 'cifDz', 'cifEc', 'cifEe', 'cifEg', 'cifEr', 'cifEs', 'cifEt', 'cifFi', 'cifFj', 'cifFm', 'cifFr', 'cifGa', 'cifGb', 'cifGd', 'cifGe', 'cifGh', 'cifGm', 'cifGn', 'cifGq', 'cifGr', 'cifGt', 'cifGw', 'cifGy', 'cifHk', 'cifHn', 'cifHr', 'cifHt', 'cifHu', 'cifId', 'cifIe', 'cifIl', 'cifIn', 'cifIq', 'cifIr', 'cifIs', 'cifIt', 'cifJm', 'cifJo', 'cifJp', 'cifKe', 'cifKg', 'cifKh', 'cifKi', 'cifKm', 'cifKn', 'cifKp', 'cifKr', 'cifKw', 'cifKz', 'cifLa', 'cifLb', 'cifLc', 'cifLi', 'cifLk', 'cifLr', 'cifLs', 'cifLt', 'cifLu', 'cifLv', 'cifLy', 'cifMa', 'cifMc', 'cifMd', 'cifMe', 'cifMg', 'cifMh', 'cifMk', 'cifMl', 'cifMm', 'cifMn', 'cifMr', 'cifMt', 'cifMu', 'cifMv', 'cifMw', 'cifMx', 'cifMy', 'cifMz', 'cifNa', 'cifNe', 'cifNg', 'cifNi', 'cifNl', 'cifNo', 'cifNp', 'cifNr', 'cifNu', 'cifNz', 'cifOm', 'cifPa', 'cifPe', 'cifPg', 'cifPh', 'cifPk', 'cifPl', 'cifPt', 'cifPw', 'cifPy', 'cifQa', 'cifRo', 'cifRs', 'cifRu', 'cifRw', 'cifSa', 'cifSb', 'cifSc', 'cifSd', 'cifSe', 'cifSg', 'cifSi', 'cifSk', 'cifSl', 'cifSm', 'cifSn', 'cifSo', 'cifSr', 'cifSs', 'cifSt', 'cifSv', 'cifSy', 'cifSz', 'cifTd', 'cifTg', 'cifTh', 'cifTj', 'cifTl', 'cifTm', 'cifTn', 'cifTo', 'cifTr', 'cifTt', 'cifTv', 'cifTw', 'cifTz', 'cifUa', 'cifUg', 'cifUs', 'cifUy', 'cifUz', 'cifVa', 'cifVc', 'cifVe', 'cifVn', 'cifWs', 'cifXk', 'cifYe', 'cifZa', 'cifZm', 'cifZw'] - return ( - <CRow xs={{ cols: 3 }} sm={{ cols: 4 }} lg={{ cols: 5 }}> - {icons.map((i, idx) => { - return ( - <CCol className="mb-4" key={idx}> - <div className="p-3 py-4 mb-2 bg-light text-center rounded"> - <CIcon icon={icon[i]} size="xxl"/> - </div> - <div className="text-body-secondary text-center pt-1 small">{i}</div> - </CCol>) - })} - </CRow> - ) -} - -export const TabPanesExample = () => { - const [activeKey, setActiveKey] = useState(1) - return ( - <> - <CNav variant="tabs" role="tablist"> - <CNavItem> - <CNavLink - href="#" - active={activeKey === 1} - onClick={(e) => { - e.preventDefault() - setActiveKey(1) - }} - > - Linear - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink - href="#" - active={activeKey === 2} - onClick={(e) => { - e.preventDefault() - setActiveKey(2) - }} - > - Brand - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink - href="#" - active={activeKey === 3} - onClick={(e) => { - e.preventDefault() - setActiveKey(3) - }} - > - Flags - </CNavLink> - </CNavItem> - </CNav> - <CTabContent className="pt-4" style={{"--cui-light": "#f0f4f7"}}> - <CTabPane role="tabpanel" aria-labelledby="home-tab" visible={activeKey === 1}> - {activeKey === 1 && <LinearExample />} - </CTabPane> - <CTabPane role="tabpanel" aria-labelledby="profile-tab" visible={activeKey === 2}> - {activeKey === 2 && <BrandExample />} - </CTabPane> - <CTabPane role="tabpanel" aria-labelledby="contact-tab" visible={activeKey === 3}> - {activeKey === 3 && <FlagsExample />} - </CTabPane> - </CTabContent> - </> - ) -} - -<TabPanesExample /> - -React Icons also provides a variety of customization options, such as the ability to change the size, color, and style of the icons, as well as the ability to add additional CSS classes to the icons. You can find more information on these customization options in the documentation. - -## Premium icons - -If you find yourself in need of a greater selection of icons, we've got you covered with our [premium icon pack](https://coreui.io/icons/all/). This incredible package boasts an extensive collection of over 4,000 meticulously crafted icons, ensuring that you'll find the perfect representation for any concept or idea. Explore the vast range of options and unlock a world of visual possibilities. - -So if you need more icons our PRO package will be a great choice for you. - -## API - -### CIcon - -`markdown:CIcon.api.mdx` \ No newline at end of file diff --git a/packages/docs/content/components/image.mdx b/packages/docs/content/components/image.mdx deleted file mode 100644 index 6831409b..00000000 --- a/packages/docs/content/components/image.mdx +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: React Image Component -name: Image -description: React image component with responsive behavior (so it's never become larger than their parent element) and special styles. -menu: Components -route: /components/image -other_frameworks: image ---- - -import { CImage } from '@coreui/react/src/index' - -import ReactImg from './../assets/images/react.jpg' -import React400Img from './../assets/images/react400.jpg' - -## Responsive images - -Images in CoreUI for React.js are made responsive with `fluid` property. This applies `max-width: 100%;` and `height: auto;` to the image so that it scales with the parent element. - -```jsx preview -<CImage fluid src={ReactImg} /> -``` - -## Image thumbnails - -In addition to our [border-radius utilities](https://coreui.io/docs/utilities/borders), you can use prop`thumbnail` to give an image a rounded 1px border appearance. - -```jsx preview -<CImage rounded thumbnail src={React400Img} width={200} height={200} /> -``` - -## Aligning images - -Align images with the `align` property. - -```jsx preview -<div className="clearfix"> - <CImage align="start" rounded src={React400Img} width={200} height={200} /> - <CImage align="end" rounded src={React400Img} width={200} height={200} /> -</div> -``` - -```jsx preview -<div className="clearfix"> - <CImage align="center" rounded src={React400Img} width={200} height={200} /> -</div> -``` - -```jsx preview -<div className="text-center"> - <CImage rounded src={React400Img} width={200} height={200} /> -</div> -``` - -## API - -### CImage - -`markdown:CImage.api.mdx` diff --git a/packages/docs/content/components/list-group.mdx b/packages/docs/content/components/list-group.mdx deleted file mode 100644 index 06781945..00000000 --- a/packages/docs/content/components/list-group.mdx +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: React List Group Component -name: List group -description: React List Group component allows displaying a series of content. Learn how to use react list group to build complex list structure on your website. -menu: Components -route: /components/list-group -other_frameworks: list-group ---- - -import { - CBadge, - CFormCheck, - CListGroup, - CListGroupItem, - CLink, -} from '@coreui/react/src/index' - -## Basic example - -The default list group is an unordered list with items and the proper CSS classes. Build upon it with the options that follow, or with your CSS as required. - -```jsx preview -<CListGroup> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Morbi leo risus</CListGroupItem> - <CListGroupItem>Porta ac consectetur ac</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> -</CListGroup> -``` - -## Active items - -Add `active` boolean property to a `<CListGroupItem>` to show the current active selection. - -```jsx preview -<CListGroup> - <CListGroupItem active>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Morbi leo risus</CListGroupItem> - <CListGroupItem>Porta ac consectetur ac</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> -</CListGroup> -``` - -## Disabled items - -Add `disabled` boolean property to a `<CListGroupItem>` to make it appear disabled. - -```jsx preview -<CListGroup> - <CListGroupItem disabled>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Morbi leo risus</CListGroupItem> - <CListGroupItem>Porta ac consectetur ac</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> -</CListGroup> -``` - -## Links and buttons - -Use `<a>`s or `<button>`s to create _actionable_ list group items with hover, disabled, and active states by adding `component="a|button"`. We separate these pseudo-classes to ensure list groups made of non-interactive elements (like `<li>`s or `<div>`s) don't provide a click or tap affordance. - -```jsx preview -<CListGroup> - <CListGroupItem component="a" href="#" active> - Cras justo odio - </CListGroupItem> - <CListGroupItem component="a" href="#"> - Dapibus ac facilisis in - </CListGroupItem> - <CListGroupItem component="a" href="#"> - Morbi leo risus - </CListGroupItem> - <CListGroupItem component="a" href="#"> - Porta ac consectetur ac - </CListGroupItem> - <CListGroupItem component="a" href="#" disabled> - Vestibulum at eros - </CListGroupItem> -</CListGroup> -``` - -```jsx preview -<CListGroup> - <CListGroupItem component="button" active> - Cras justo odio - </CListGroupItem> - <CListGroupItem component="button">Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem component="button">Morbi leo risus</CListGroupItem> - <CListGroupItem component="button">Porta ac consectetur ac</CListGroupItem> - <CListGroupItem component="button" disabled> - Vestibulum at eros - </CListGroupItem> -</CListGroup> -``` - -## Flush - -Add `flush` boolean property to remove some borders and rounded corners to render list group items edge-to-edge in a parent container (e.g., cards). - -```jsx preview -<CListGroup flush> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Morbi leo risus</CListGroupItem> - <CListGroupItem>Porta ac consectetur ac</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> -</CListGroup> -``` - -## Horizontal - -Add `layout="horizontal"` to change the layout of list group items from vertical to horizontal across all breakpoints. Alternatively, choose a responsive variant `.layout="horizontal-{sm|md|lg|xl|xxl}"` to make a list group horizontal starting at that breakpoint's `min-width`. Currently **horizontal list groups cannot be combined with flush list groups.** - -<Example> - <> - {['', '-sm', '-md', '-lg', '-xl', '-xxl'].map((breakpoint, index) => ( - <CListGroup className="mb-2" layout={`horizontal${breakpoint}`} key={index}> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Morbi leo risus</CListGroupItem> - </CListGroup> - ))} - </> -</Example> - -```jsx -<> - {['', '-sm', '-md', '-lg', '-xl', '-xxl'].map((breakpoint, index) => ( - <CListGroup className="mb-2" layout={`horizontal${breakpoint}`} key={index}> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Morbi leo risus</CListGroupItem> - </CListGroup> - ))} -</> -``` - -## Contextual classes - -Use contextual classes to style list items with a stateful background and color. - -<Example> - <CListGroup> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - {['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark'].map( - (color, index) => ( - <CListGroupItem color={color} key={index}> - A simple {color} list group item - </CListGroupItem> - ), - )} - </CListGroup> -</Example> - -```jsx -<CListGroup> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - {['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark'].map( - (color, index) => ( - <CListGroupItem color={color} key={index}> - A simple {color} list group item - </CListGroupItem> - ), - )} -</CListGroup> -``` - -Contextual classes also work with `<a>`s or `<button>`s. Note the addition of the hover styles here not present in the previous example. Also supported is the `active` state; apply it to indicate an active selection on a contextual list group item. - -<Example> - <CListGroup> - <CListGroupItem component="a" href="#"> - Dapibus ac facilisis in - </CListGroupItem> - {['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark'].map( - (color, index) => ( - <CListGroupItem component="a" href="#" color={color} key={index}> - A simple {color} list group item - </CListGroupItem> - ), - )} - </CListGroup> -</Example> - -```jsx -<CListGroup> - <CListGroupItem component="a" href="#"> - Dapibus ac facilisis in - </CListGroupItem> - {['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark'].map( - (color, index) => ( - <CListGroupItem component="a" href="#" color={color} key={index}> - A simple {color} list group item - </CListGroupItem> - ), - )} -</CListGroup> -``` - -<Callout color="info" title="Conveying meaning to assistive technologies"> - Using color to add meaning only provides a visual indication, which will not be conveyed to - users of assistive technologies – such as screen readers. Ensure that information denoted by the - color is either obvious from the content itself (e.g. the visible text), or is included through - alternative means, such as additional text hidden with the `.visually-hidden` class. -</Callout> - -## With badges - -Add badges to any list group item to show unread counts, activity, and more. - -```jsx preview -<CListGroup> - <CListGroupItem className="d-flex justify-content-between align-items-center"> - Cras justo odio - <CBadge color="primary" shape="rounded-pill"> - 14 - </CBadge> - </CListGroupItem> - <CListGroupItem className="d-flex justify-content-between align-items-center"> - Dapibus ac facilisis in - <CBadge color="primary" shape="rounded-pill"> - 2 - </CBadge> - </CListGroupItem> - <CListGroupItem className="d-flex justify-content-between align-items-center"> - Morbi leo risus - <CBadge color="primary" shape="rounded-pill"> - 1 - </CBadge> - </CListGroupItem> -</CListGroup> -``` - -## Custom content - -Add nearly any HTML within, even for linked list groups like the one below, with the help of [flexbox utilities](https://coreui.io/docs/utilities/flex/). - -```jsx preview -<CListGroup> - <CListGroupItem component="a" href="#" active> - <div className="d-flex w-100 justify-content-between"> - <h5 className="mb-1">List group item heading</h5> - <small>3 days ago</small> - </div> - <p className="mb-1"> - Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit. - </p> - <small>Donec id elit non mi porta.</small> - </CListGroupItem> - <CListGroupItem component="a" href="#"> - <div className="d-flex w-100 justify-content-between"> - <h5 className="mb-1">List group item heading</h5> - <small className="text-body-secondary">3 days ago</small> - </div> - <p className="mb-1"> - Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit. - </p> - <small className="text-body-secondary">Donec id elit non mi porta.</small> - </CListGroupItem> - <CListGroupItem component="a" href="#"> - <div className="d-flex w-100 justify-content-between"> - <h5 className="mb-1">List group item heading</h5> - <small className="text-body-secondary">3 days ago</small> - </div> - <p className="mb-1"> - Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit. - </p> - <small className="text-body-secondary">Donec id elit non mi porta.</small> - </CListGroupItem> -</CListGroup> -``` - -## Checkboxes and radios - -Place CoreUI's checkboxes and radios within list group items and customize as needed. - -```jsx preview -<CListGroup> - <CListGroupItem> - <CFormCheck label="Cras justo odio" /> - </CListGroupItem> - <CListGroupItem> - <CFormCheck label="Dapibus ac facilisis in" defaultChecked /> - </CListGroupItem> - <CListGroupItem> - <CFormCheck label="Morbi leo risus" defaultChecked /> - </CListGroupItem> - <CListGroupItem> - <CFormCheck label="orta ac consectetur ac" /> - </CListGroupItem> - <CListGroupItem> - <CFormCheck label="Vestibulum at eros" /> - </CListGroupItem> -</CListGroup> -``` - -And if you want `<label>`s as the `.list-group-item` for large hit areas, you can do that, too. - -```jsx preview -<CListGroup> - <CListGroupItem> - <CFormCheck hitArea="full" label="First checkbox" value="" id="firstCheckboxStretched" /> - </CListGroupItem> - <CListGroupItem> - <CFormCheck hitArea="full" label="Second checkbox" value="" id="secondCheckboxStretched" defaultChecked/> - </CListGroupItem> - <CListGroupItem> - <CFormCheck hitArea="full" label="Third checkbox" value="" id="thirdCheckboxStretched"/> - </CListGroupItem> -</CListGroup> -``` - -## Customizing - -### CSS variables - -React list groups use local CSS variables on `.list-group` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_list-group.scss" capture="list-group-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CListGroup style={vars}>...</CListGroup> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="list-group-variables"/> - -## API - -### CListGroup - -`markdown:CListGroup.api.mdx` - -### CListGroupItem - -`markdown:CListGroupItem.api.mdx` diff --git a/packages/docs/content/components/modal.mdx b/packages/docs/content/components/modal.mdx deleted file mode 100644 index 15760787..00000000 --- a/packages/docs/content/components/modal.mdx +++ /dev/null @@ -1,1375 +0,0 @@ ---- -title: React Modal Component -name: Modal -description: React Modal component offers a lightweight, multi-purpose popup to add dialogs to yours. Learn how to customize CoreUI React modal components easily. Multiple examples and tutorial. -menu: Components -route: /components/modal -other_frameworks: modal ---- - -import { useState } from 'react' -import { - CButton, - CLink, - CModal, - CModalBody, - CModalFooter, - CModalHeader, - CModalTitle, - CPopover, - CTooltip, -} from '@coreui/react/src/index' - -## How to use React Modal Component? - -### Static modal component example - -Below is a static react modal component example (meaning its `position` and `display` have been overridden). Included are the modal header, modal body (required for `padding`), and modal footer (optional). We ask that you include react modal headers with dismiss actions whenever possible, or provide another explicit dismiss action. - -<Example> - <div className="modal position-static d-block" tabIndex="-1"> - <div className="modal-dialog"> - <div className="modal-content"> - <div className="modal-header"> - <h5 className="modal-title">React Modal title</h5> - <button type="button" className="btn-close" aria-label="Close"></button> - </div> - <div className="modal-body"> - <p>React Modal body text goes here.</p> - </div> - <div className="modal-footer"> - <button type="button" className="btn btn-secondary">Close</button> - <button type="button" className="btn btn-primary">Save changes</button> - </div> - </div> - </div> - </div> -</Example> -```jsx -<CModal> - <CModalHeader> - <CModalTitle>React Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p>React Modal body text goes here.</p> - </CModalBody> - <CModalFooter> - <CButton color="secondary">Close</CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> -</CModal> -``` - -### Live demo - -Toggle a working React modal component demo by clicking the button below. It will slide down and fade in from the top of the page. - -export const LiveDemoExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="LiveDemoExampleLabel" - > - <CModalHeader> - <CModalTitle id="LiveDemoExampleLabel">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p>Woohoo, you're reading this text in a modal!</p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -<Example> - <LiveDemoExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="LiveDemoExampleLabel" - > - <CModalHeader onClose={() => setVisible(false)}> - <CModalTitle id="LiveDemoExampleLabel">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p>Woohoo, you're reading this text in a modal!</p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> -) -``` - -### Static backdrop - -If you set a `backdrop` to `static`, your React modal component will behave as though the backdrop is static, meaning it will not close when clicking outside it. Click the button below to try it. - -export const StaticBackdropExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Launch static backdrop modal</CButton> - <CModal - backdrop="static" - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="StaticBackdropExampleLabel" - > - <CModalHeader> - <CModalTitle id="StaticBackdropExampleLabel">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - I will not close if you click outside me. Don't even try to press escape key. - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -<Example> - <StaticBackdropExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Launch static backdrop modal</CButton> - <CModal - backdrop="static" - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="StaticBackdropExampleLabel" - > - <CModalHeader> - <CModalTitle id="StaticBackdropExampleLabel">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - I will not close if you click outside me. Don't even try to press escape key. - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> -) -``` - -### Scrolling long content - -When modals become too long for the user's viewport or device, they scroll independent of the page itself. Try the demo below to see what we mean. - -export const ScrollingLongContentExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="ScrollingLongContentExampleLabel" - > - <CModalHeader> - <CModalTitle id="ScrollingLongContentExampleLabel">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -<Example> - <ScrollingLongContentExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="ScrollingLongContentExampleLabel" - > - <CModalHeader> - <CModalTitle id="ScrollingLongContentExampleLabel">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> -) -``` - -You can also create a scrollable react modal component that allows scroll the modal body by adding `scrollable` prop. - -export const ScrollingLongContentExample2 = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal - scrollable - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="ScrollingLongContentExampleLabel2" - > - <CModalHeader> - <CModalTitle id="ScrollingLongContentExampleLabel2">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -<Example> - <ScrollingLongContentExample2 /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal - scrollable - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="ScrollingLongContentExampleLabel2" - > - <CModalHeader> - <CModalTitle id="ScrollingLongContentExampleLabel2">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> -) -``` - -### Vertically centered - -Add `alignment="center` to `<CModal>` to vertically center the React modal. - -export const VerticallyCenteredExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Vertically centered modal</CButton> - <CModal - alignment="center" - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="VerticallyCenteredExample" - > - <CModalHeader> - <CModalTitle id="VerticallyCenteredExample">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -<Example> - <VerticallyCenteredExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Vertically centered modal</CButton> - <CModal - alignment="center" - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="VerticallyCenteredExample" - > - <CModalHeader> - <CModalTitle id="VerticallyCenteredExample">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, - egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> -) -``` - -export const VerticallyCenteredScrollableExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Vertically centered scrollable modal</CButton> - <CModal - alignment="center" - scrollable - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="VerticallyCenteredScrollableExample2" - > - <CModalHeader> - <CModalTitle id="VerticallyCenteredScrollableExample2">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -<Example> - <VerticallyCenteredScrollableExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Vertically centered scrollable modal</CButton> - <CModal - alignment="center" - scrollable - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="VerticallyCenteredScrollableExample2" - > - <CModalHeader> - <CModalTitle id="VerticallyCenteredScrollableExample2">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus - vel augue laoreet rutrum faucibus dolor auctor. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> -) -``` - -### Tooltips and popovers - -`<CTooltips>` and `<CPopovers>` can be placed within react modals as needed. When modal components are closed, any tooltips and popovers within are also automatically dismissed. - -export const TooltipsAndPopoversExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal - alignment="center" - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="TooltipsAndPopoverExample" - > - <CModalHeader> - <CModalTitle id="TooltipsAndPopoverExample">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <h5>Popover in a modal</h5> - <p> - This - <CPopover title="Popover title" content="Popover body content is set in this property."> - <CButton color="primary">button</CButton> - </CPopover> triggers a popover on click. - </p> - <hr /> - <h5>Tooltips in a modal</h5> - <p> - <CTooltip content="Tooltip"> - <CLink>This link</CLink> - </CTooltip>{' '} - and - <CTooltip content="Tooltip"> - <CLink>that link</CLink> - </CTooltip> have tooltips on hover. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -<Example> - <TooltipsAndPopoversExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal - alignment="center" - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="TooltipsAndPopoverExample" - > - <CModalHeader> - <CModalTitle id="TooltipsAndPopoverExample">Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <h5>Popover in a modal</h5> - <p> - This - <CPopover title="Popover title" content="Popover body content is set in this property."> - <CButton color="primary">button</CButton> - </CPopover> triggers a popover on click. - </p> - <hr /> - <h5>Tooltips in a modal</h5> - <p> - <CTooltip content="Tooltip"> - <CLink>This link</CLink> - </CTooltip>{' '} - and - <CTooltip content="Tooltip"> - <CLink>that link</CLink> - </CTooltip> have tooltips on hover. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> -) -``` - -### Toggle between modals - -Toggle between multiple modals with some clever placement of the `visible` props. **Please note multiple modals cannot be opened at the same time** — this method simply toggles between two separate modals. - -export const ToggleBetweenModalsExample = () => { - const [visible, setVisible] = useState(false) - const [visible2, setVisible2] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Open first modal</CButton> - <CModal - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="ToggleBetweenModalsExample1" - > - <CModalHeader> - <CModalTitle id="ToggleBetweenModalsExample1">Modal 1 title</CModalTitle> - </CModalHeader> - <CModalBody> - <p>Show a second modal and hide this one with the button below.</p> - </CModalBody> - <CModalFooter> - <CButton - color="primary" - onClick={() => { - setVisible(false) - setVisible2(true) - }} - > - Open second modal - </CButton> - </CModalFooter> - </CModal> - <CModal - visible={visible2} - onClick={() => { - setVisible(true) - setVisible2(false) - }} - aria-labelledby="ToggleBetweenModalsExample2" - > - <CModalHeader> - <CModalTitle id="ToggleBetweenModalsExample2">Modal 2 title</CModalTitle> - </CModalHeader> - <CModalBody> - <p>Hide this modal and show the first with the button below.</p> - </CModalBody> - <CModalFooter> - <CButton - color="primary" - onClick={() => { - setVisible(true) - setVisible2(false) - }} - > - Back to first - </CButton> - </CModalFooter> - </CModal> - </> - ) -} - -<Example> - <ToggleBetweenModalsExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -const [visible2, setVisible2] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Open first modal</CButton> - <CModal - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="ToggleBetweenModalsExample1" - > - <CModalHeader> - <CModalTitle id="ToggleBetweenModalsExample1">Modal 1 title</CModalTitle> - </CModalHeader> - <CModalBody> - <p>Show a second modal and hide this one with the button below.</p> - </CModalBody> - <CModalFooter> - <CButton - color="primary" - onClick={() => { - setVisible(false) - setVisible2(true) - }} - > - Open second modal - </CButton> - </CModalFooter> - </CModal> - <CModal - visible={visible2} - onClick={() => { - setVisible(true) - setVisible2(false) - }} - aria-labelledby="ToggleBetweenModalsExample2" - > - <CModalHeader> - <CModalTitle id="ToggleBetweenModalsExample2">Modal 2 title</CModalTitle> - </CModalHeader> - <CModalBody> - <p>Hide this modal and show the first with the button below.</p> - </CModalBody> - <CModalFooter> - <CButton - color="primary" - onClick={() => { - setVisible(true) - setVisible2(false) - }} - > - Back to first - </CButton> - </CModalFooter> - </CModal> - </> -) -``` - -### Change animation - -The variable `$modal-fade-transform` determines the transform state of React Modal component before the modal fade-in animation, whereas the variable `$modal-show-transform` determines the transform state of Modal component after the modal fade-in animation. - -If you want a zoom-in animation, for example, set `$modal-fade-transform: scale(.8)`. - -### Remove animation - -For modals that simply appear rather than fade into view, set `transition` to `false`. - -```jsx -<CModal transition={false}>...</CModal> -``` - -### Accessibility - -Be sure to add `aria-labelledby="..."`, referencing the modal title, to `<CModal />` Additionally, you may give a description of your modal dialog with `aria-describedby` on `<CModal>`. Note that you don’t need to add `role="dialog`, `aria-hidden="true"`, and `aria-modal="true"` since we already add it. - -## Optional sizes - -Modals have three optional sizes, available via modifier classes to be placed on a `<CModal>`. These sizes kick in at certain breakpoints to avoid horizontal scrollbars on narrower viewports. - -| Size | Property size | Modal max-width | -| ----------- | ------------- | --------------- | -| Small | `'sm'` | `300px` | -| Default | None | `500px` | -| Large | `'lg'` | `800px` | -| Extra large | `'xl'` | `1140px` | - -export const OptionalSizesExample = () => { - const [visibleXL, setVisibleXL] = useState(false) - const [visibleLg, setVisibleLg] = useState(false) - const [visibleSm, setVisibleSm] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisibleXL(!visibleXL)}>Extra large modal</CButton> - <CButton color="primary" onClick={() => setVisibleLg(!visibleLg)}>Large modal</CButton> - <CButton color="primary" onClick={() => setVisibleSm(!visibleSm)}>Small modal</CButton> - <CModal - size="xl" - visible={visibleXL} - onClose={() => setVisibleXL(false)} - aria-labelledby="OptionalSizesExample1" - > - <CModalHeader> - <CModalTitle id="OptionalSizesExample1">Extra large modal</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - size="lg" - visible={visibleLg} - onClose={() => setVisibleLg(false)} - aria-labelledby="OptionalSizesExample2" - > - <CModalHeader> - <CModalTitle id="OptionalSizesExample2">Large modal</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - size="sm" - visible={visibleSm} - onClose={() => setVisibleSm(false)} - aria-labelledby="OptionalSizesExample3" - > - <CModalHeader> - <CModalTitle id="OptionalSizesExample3">Small modal</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - </> - ) -} - -<Example> - <OptionalSizesExample /> -</Example> - -```jsx -const [visibleXL, setVisibleXL] = useState(false) -const [visibleLg, setVisibleLg] = useState(false) -const [visibleSm, setVisibleSm] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisibleXL(!visibleXL)}>Extra large modal</CButton> - <CButton color="primary" onClick={() => setVisibleLg(!visibleLg)}>Large modal</CButton> - <CButton color="primary" onClick={() => setVisibleSm(!visibleSm)}>Small modal</CButton> - <CModal - size="xl" - visible={visibleXL} - onClose={() => setVisibleXL(false)} - aria-labelledby="OptionalSizesExample1" - > - <CModalHeader> - <CModalTitle id="OptionalSizesExample1">Extra large modal</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - size="lg" - visible={visibleLg} - onClose={() => setVisibleLg(false)} - aria-labelledby="OptionalSizesExample2" - > - <CModalHeader> - <CModalTitle id="OptionalSizesExample2">Large modal</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - size="sm" - visible={visibleSm} - onClose={() => setVisibleSm(false)} - aria-labelledby="OptionalSizesExample3" - > - <CModalHeader> - <CModalTitle id="OptionalSizesExample3">Small modal</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - </> -) -``` - -## Fullscreen Modal - -Another override is the option to pop up a React modal component that covers the user viewport, available via property `fullscrean`. - -| Fullscrean | Availability | -| ---------- | -------------- | -| `true` | Always | -| `'sm'` | Below `576px` | -| `'md'` | Below `768px` | -| `'lg'` | Below `992px` | -| `'xl'` | Below `1200px` | -| `'xxl'` | Below `1400px` | - -export const FullscreenExample = () => { - const [visible, setVisible] = useState(false) - const [visibleSm, setVisibleSm] = useState(false) - const [visibleMd, setVisibleMd] = useState(false) - const [visibleLg, setVisibleLg] = useState(false) - const [visibleXL, setVisibleXL] = useState(false) - const [visibleXXL, setVisibleXXL] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Full screen</CButton> - <CButton color="primary" onClick={() => setVisibleSm(!visibleSm)}>Full screen below sm</CButton> - <CButton color="primary" onClick={() => setVisibleMd(!visibleMd)}>Full screen below md</CButton> - <CButton color="primary" onClick={() => setVisibleLg(!visibleLg)}>Full screen below lg</CButton> - <CButton color="primary" onClick={() => setVisibleXL(!visibleXL)}>Full screen below xl</CButton> - <CButton color="primary" onClick={() => setVisibleXXL(!visibleXXL)}>Full screen below xxl</CButton> - <CModal - fullscreen - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="FullscreenExample1" - > - <CModalHeader> - <CModalTitle id="FullscreenExample1">Full screen</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - fullscreen="sm" - visible={visibleSm} - onClose={() => setVisibleSm(false)} - aria-labelledby="FullscreenExample2" - > - <CModalHeader> - <CModalTitle id="FullscreenExample2">Full screen below sm</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - fullscreen="md" - visible={visibleMd} - onClose={() => setVisibleMd(false)} - aria-labelledby="FullscreenExample3" - > - <CModalHeader> - <CModalTitle id="FullscreenExample3">Full screen below md</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - fullscreen="lg" - visible={visibleLg} - onClose={() => setVisibleLg(false)} - aria-labelledby="FullscreenExample4" - > - <CModalHeader> - <CModalTitle id="FullscreenExample4">Full screen below lg</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - fullscreen="xl" - visible={visibleXL} - onClose={() => setVisibleXL(false)} - aria-labelledby="FullscreenExample5" - > - <CModalHeader> - <CModalTitle id="FullscreenExample5">Full screen below xl</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - fullscreen="xxl" - visible={visibleXXL} - onClose={() => setVisibleXXL(false)} - aria-labelledby="FullscreenExample6" - > - <CModalHeader> - <CModalTitle id="FullscreenExample6">Full screen below xxl</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - </> - ) -} - -<Example> - <FullscreenExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -const [visibleSm, setVisibleSm] = useState(false) -const [visibleMd, setVisibleMd] = useState(false) -const [visibleLg, setVisibleLg] = useState(false) -const [visibleXL, setVisibleXL] = useState(false) -const [visibleXXL, setVisibleXXL] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(!visible)}>Full screen</CButton> - <CButton color="primary" onClick={() => setVisibleSm(!visibleSm)}>Full screen below sm</CButton> - <CButton color="primary" onClick={() => setVisibleMd(!visibleMd)}>Full screen below md</CButton> - <CButton color="primary" onClick={() => setVisibleLg(!visibleLg)}>Full screen below lg</CButton> - <CButton color="primary" onClick={() => setVisibleXL(!visibleXL)}>Full screen below xl</CButton> - <CButton color="primary" onClick={() => setVisibleXXL(!visibleXXL)}>Full screen below xxl</CButton> - <CModal - fullscreen - visible={visible} - onClose={() => setVisible(false)} - aria-labelledby="FullscreenExample1" - > - <CModalHeader> - <CModalTitle id="FullscreenExample1">Full screen</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - fullscreen="sm" - visible={visibleSm} - onClose={() => setVisibleSm(false)} - aria-labelledby="FullscreenExample2" - > - <CModalHeader> - <CModalTitle id="FullscreenExample2">Full screen below sm</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - fullscreen="md" - visible={visibleMd} - onClose={() => setVisibleMd(false)} - aria-labelledby="FullscreenExample3" - > - <CModalHeader> - <CModalTitle id="FullscreenExample3">Full screen below md</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - fullscreen="lg" - visible={visibleLg} - onClose={() => setVisibleLg(false)} - aria-labelledby="FullscreenExample4" - > - <CModalHeader> - <CModalTitle id="FullscreenExample4">Full screen below lg</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - fullscreen="xl" - visible={visibleXL} - onClose={() => setVisibleXL(false)} - aria-labelledby="FullscreenExample5" - > - <CModalHeader> - <CModalTitle id="FullscreenExample5">Full screen below xl</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal - fullscreen="xxl" - visible={visibleXXL} - onClose={() => setVisibleXXL(false)} - aria-labelledby="FullscreenExample6" - > - <CModalHeader> - <CModalTitle id="FullscreenExample6">Full screen below xxl</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - </> -) -``` - -## Customizing - -### CSS variables - -React modals use local CSS variables on `.modal` and `.modal-backdrop` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_modal.scss" capture="modal-css-vars" /> - -<ScssDocs file="_modal.scss" capture="modal-backdrop-css-vars" /> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': 'red', -} -return <CModal style={vars}>...</CModal> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="modal-variables" /> - -### SASS loops - -[Responsive fullscreen modals](#fullscreen-modal) are generated via the `$breakpoints` map and a loop in `scss/_modal.scss`. - -<ScssDocs file="_modal.scss" capture="modal-fullscreen-loop" /> - -## API - -### CModal - -`markdown:CModal.api.mdx` - -### CModalBody - -`markdown:CModalBody.api.mdx` - -### CModalFooter - -`markdown:CModalFooter.api.mdx` - -### CModalHeader - -`markdown:CModalHeader.api.mdx` - -### CModalTitle - -`markdown:CModalTitle.api.mdx` diff --git a/packages/docs/content/components/navbar.mdx b/packages/docs/content/components/navbar.mdx deleted file mode 100644 index fbca666f..00000000 --- a/packages/docs/content/components/navbar.mdx +++ /dev/null @@ -1,1475 +0,0 @@ ---- -title: React Navbar Component -name: Navbar -description: Documentation and examples for the React navbar powerful, responsive navigation header component. Includes support for branding, links, dropdowns, and more. -menu: Components -route: /components/navbar -other_frameworks: navbar ---- - -import { useState } from 'react' -import { - CButton, - CContainer, - CCloseButton, - CCollapse, - CDropdown, - CDropdownDivider, - CDropdownHeader, - CDropdownItem, - CDropdownItemPlain, - CDropdownMenu, - CDropdownToggle, - CForm, - CFormInput, - CInputGroup, - CInputGroupText, - CNav, - CNavItem, - CNavLink, - CNavbar, - CNavbarBrand, - CNavbarNav, - CNavbarText, - CNavbarToggler, - COffcanvas, - COffcanvasBody, - COffcanvasHeader, - COffcanvasTitle, -} from '@coreui/react/src/index' - -import CoreUISignetImg from './../assets/images/brand/coreui-signet.svg' - -## Supported content - -`<CNavbar>` come with built-in support for a handful of sub-components. Choose from the following as needed: - -- `<CNavbarBrand>` for your company, product, or project name. -- `<CNavbarNav>` for a full-height and lightweight navigation (including support for dropdowns). -- `<CNavbarToggler>` for use with our collapse plugin and other [navigation toggling](#responsive-behaviors) behaviors. -- Flex and spacing utilities for any form controls and actions. -- `<CNavbarText>` for adding vertically centered strings of text. -- `<CCollapse>` for grouping and hiding navbar contents by a parent breakpoint. - -Here's an example of all the sub-components included in a responsive light-themed navbar that automatically collapses at the `lg` (large) breakpoint. - -## Basic usage - -export const BasicUsageExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler onClick={() => setVisible(!visible)} /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - </> - ) -} - -<Example> - <BasicUsageExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler onClick={() => setVisible(!visible)} /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - </> -) -``` - -### Brand - -The `<CNavbarBrand>` can be applied to most elements, but an anchor works best, as some elements might require utility classes or custom styles. - -```jsx preview -<CNavbar className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - </CContainer> -</CNavbar> -<br/> -<CNavbar className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand className="mb-0 h1">Navbar</CNavbarBrand> - </CContainer> -</CNavbar> -``` - -Adding images to the `<CNavbarBrand>` will likely always require custom styles or utilities to properly size. Here are some examples to demonstrate. - -```jsx preview -<CNavbar className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#"> - <img src={CoreUISignetImg} alt="" width="22" height="24" /> - </CNavbarBrand> - </CContainer> -</CNavbar> -``` - -```jsx preview -<CNavbar className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#"> - <img - src={CoreUISignetImg} - alt="" - width="22" - height="24" - className="d-inline-block align-top" - /> CoreUI - </CNavbarBrand> - </CContainer> -</CNavbar> -``` - -### Nav - -`<CNavbar>` navigation is based on `<CNavbarNav>`. **Navigation in navbars will also grow to occupy as much horizontal space as possible** to keep your navbar contents securely aligned. - -export const NavExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Features</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Pricing</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - </CCollapse> - </CContainer> - </CNavbar> - </> - ) -} - -<Example> - <NavExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Features</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Pricing</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - </CCollapse> - </CContainer> - </CNavbar> - </> -) -``` - -And because we use classes for our navs, you can avoid the list-based approach entirely if you like. - -export const NavExample2 = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav component="nav"> - <CNavLink href="#" active> - Home - </CNavLink> - <CNavLink href="#">Features</CNavLink> - <CNavLink href="#">Pricing</CNavLink> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavbarNav> - </CCollapse> - </CContainer> - </CNavbar> - </> - ) -} - -<Example> - <NavExample2 /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav component="nav"> - <CNavLink href="#" active> - Home - </CNavLink> - <CNavLink href="#">Features</CNavLink> - <CNavLink href="#">Pricing</CNavLink> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavbarNav> - </CCollapse> - </CContainer> - </CNavbar> - </> -) -``` - -You can also use dropdowns in your navbar. Please note that `<CDropdown>` component requires `variant="nav-item"`. - -export const NavDropdownExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Features</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Pricing</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle>Dropdown link</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </CNavbarNav> - </CCollapse> - </CContainer> - </CNavbar> - </> - ) -} - -<Example> - <NavDropdownExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Features</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Pricing</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle>Dropdown link</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </CNavbarNav> - </CCollapse> - </CContainer> - </CNavbar> - </> -) -``` - -### Forms - -Place various form controls and components within a navbar: - -```jsx preview -<CNavbar className="bg-body-tertiary"> - <CContainer fluid> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CContainer> -</CNavbar> -``` - -Immediate child elements of `<CNavbar>` use flex layout and will default to `justify-content: space-between`. Use additional [flex utilities](https://coreui.io/docs/utilities/flex/) as needed to adjust this behavior. - -```jsx preview -<CNavbar className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CContainer> -</CNavbar> -``` - -Input groups work, too. If your navbar is an entire form, or mostly a form, you can use the `<CForm>` element as the container and save some HTML. - -```jsx preview -<CNavbar className="bg-body-tertiary"> - <CForm className="container-fluid"> - <CInputGroup> - <CInputGroupText id="basic-addon1">@</CInputGroupText> - <CFormInput placeholder="Username" aria-label="Username" aria-describedby="basic-addon1" /> - </CInputGroup> - </CForm> -</CNavbar> -``` - -Various buttons are supported as part of these navbar forms, too. This is also a great reminder that vertical alignment utilities can be used to align different sized elements. - -```jsx preview -<CNavbar className="bg-body-tertiary"> - <CForm className="container-fluid justify-content-start"> - <CButton type="button" color="success" variant="outline" className="me-2"> - Main button - </CButton> - <CButton type="button" color="secondary" variant="outline" size="sm"> - Smaller button - </CButton> - </CForm> -</CNavbar> -``` - -### Text - -Navbars may contain bits of text with the help of `<CNavbarText>`. This class adjusts vertical alignment and horizontal spacing for strings of text. - -```jsx preview -<CNavbar className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarText>Navbar text with an inline element</CNavbarText> - </CContainer> -</CNavbar> -``` - -## Color schemes - -Theming the navbar has never been easier thanks to the combination of theming classes and `background-color` utilities. Set `colorScheme="light"` for use with light background colors, or `colorScheme="dark"` for dark background colors. Then, customize with `.bg-*` utilities. - -export const ColorSchemesExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CNavbar expand="lg" colorScheme="dark" className="bg-dark"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="light" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - <br /> - <CNavbar expand="lg" colorScheme="dark" className="bg-primary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="light" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - <br /> - <CNavbar expand="lg" colorScheme="light" style={{ backgroundColor: '#e3f2fd' }}> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="primary" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - </> - ) -} - -<Example> - <ColorSchemesExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CNavbar expand="lg" colorScheme="dark" className="bg-dark"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="light" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - <CNavbar expand="lg" colorScheme="dark" className="bg-primary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="light" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - <CNavbar expand="lg" colorScheme="light" style={{ backgroundColor: '#e3f2fd' }}> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="primary" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - </> -) -``` - -## Containers - -Although it's not required, you can wrap a `<CNavbar>` in a `<CContainer>` to center it on a page–though note that an inner container is still required. Or you can add a container inside the `<CNavbar>` to only center the contents of a [fixed or static top navbar](#placement). - -```jsx preview -<CContainer> - <CNavbar className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - </CContainer> - </CNavbar> -</CContainer> -``` - -Use any of the responsive containers to change how wide the content in your navbar is presented. - -```jsx preview -<CNavbar className="bg-body-tertiary"> - <CContainer breakpoint="md"> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - </CContainer> -</CNavbar> -``` - -## Placement - -Use our `placement` properly to place navbars in non-static positions. Choose from fixed to the top, fixed to the bottom, or stickied to the top (scrolls with the page until it reaches the top, then stays there). Fixed navbars use `position: fixed`, meaning they're pulled from the normal flow of the DOM and may require custom CSS (e.g., `padding-top` on the `<body>`) to prevent overlap with other elements. - -Also note that **`.sticky-top` uses `position: sticky`, which [isn't fully supported in every browser](https://caniuse.com/css-sticky)**. - -```jsx preview -<CNavbar className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Default</CNavbarBrand> - </CContainer> -</CNavbar> -``` - -```jsx preview -<CNavbar className="bg-body-tertiary" placement="fixed-top"> - <CContainer fluid> - <CNavbarBrand href="#">Fixed top</CNavbarBrand> - </CContainer> -</CNavbar> -``` - -```jsx preview -<CNavbar className="bg-body-tertiary" placement="fixed-bottom"> - <CContainer fluid> - <CNavbarBrand href="#">Fixed bottom</CNavbarBrand> - </CContainer> -</CNavbar> -``` - -```jsx preview -<CNavbar className="bg-body-tertiary" placement="sticky-top"> - <CContainer fluid> - <CNavbarBrand href="#">Sticky top</CNavbarBrand> - </CContainer> -</CNavbar> -``` - -## Responsive behaviors - -Navbars can use `<CNavbarToggler>`, `<CCollapse>`, and `expand="{sm|md|lg|xl|xxl}"` property to determine when their content collapses behind a button. In combination with other utilities, you can easily choose when to show or hide particular elements. - -For navbars that never collapse, add the `expand` boolean property on the `<CNavbar>`. For navbars that always collapse, don't add any property. - -### Toggler - -Navbar togglers are left-aligned by default, but should they follow a sibling element like a `<CNavbarBrand>`, they'll automatically be aligned to the far right. Reversing your markup will reverse the placement of the toggler. Below are examples of different toggle styles. - -With no `<CNavbarBrand>` shown at the smallest breakpoint: - -export const ResponsiveBehaviorsExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarBrand href="#">Hidden brand</CNavbarBrand> - <CNavbarNav className="me-auto mb-2 mb-lg-0"> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - </> - ) -} - -<Example> - <ResponsiveBehaviorsExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarBrand href="#">Hidden brand</CNavbarBrand> - <CNavbarNav className="me-auto mb-2 mb-lg-0"> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - </> -) -``` - -With a brand name shown on the left and toggler on the right: - -export const ResponsiveBehaviorsExample2 = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav className="me-auto mb-2 mb-lg-0"> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - </> - ) -} - -<Example> - <ResponsiveBehaviorsExample2 /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav className="me-auto mb-2 mb-lg-0"> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - </> -) -``` - -With a toggler on the left and brand name on the right: - -export const ResponsiveBehaviorsExample3 = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav className="me-auto mb-2 mb-lg-0"> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - </> - ) -} - -<Example> - <ResponsiveBehaviorsExample3 /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CNavbar expand="lg" className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarToggler - aria-label="Toggle navigation" - aria-expanded={visible} - onClick={() => setVisible(!visible)} - /> - <CNavbarBrand href="#">Navbar</CNavbarBrand> - <CCollapse className="navbar-collapse" visible={visible}> - <CNavbarNav className="me-auto mb-2 mb-lg-0"> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </CCollapse> - </CContainer> - </CNavbar> - </> -) -``` - -### External content - -Sometimes you want to use the collapse plugin to trigger a container element for content that structurally sits outside of the `<CNavbar>`. - -export const ExternalContentExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CCollapse id="navbarToggleExternalContent" visible={visible}> - <div className="bg-dark p-4"> - <h5 className="text-white h4">Collapsed content</h5> - <span className="text-body-secondary-inverse">Toggleable via the navbar brand.</span> - </div> - </CCollapse> - <CNavbar colorScheme="dark" className="bg-dark"> - <CContainer fluid> - <CNavbarToggler - aria-controls="navbarToggleExternalContent" - aria-label="Toggle navigation" - onClick={() => setVisible(!visible)} - /> - </CContainer> - </CNavbar> - </> - ) -} - -<Example> - <ExternalContentExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CCollapse id="navbarToggleExternalContent" visible={visible}> - <div className="bg-dark p-4"> - <h5 className="text-white h4">Collapsed content</h5> - <span className="text-body-secondary-inverse">Toggleable via the navbar brand.</span> - </div> - </CCollapse> - <CNavbar colorScheme="dark" className="bg-dark"> - <CContainer fluid> - <CNavbarToggler - aria-controls="navbarToggleExternalContent" - aria-label="Toggle navigation" - onClick={() => setVisible(!visible)} - /> - </CContainer> - </CNavbar> - </> -) -``` - -### Offcanvas - -Transform your expanding and collapsing navbar into an offcanvas drawer with the offcanvas plugin. We extend both the offcanvas default styles and use our `expand="*"` prop to create a dynamic and flexible navigation sidebar. - -In the example below, to create an offcanvas navbar that is always collapsed across all breakpoints, omit the `expand="*"` prop entirely. - -export const OffcanvasExample = () => { - const [visible, setVisible] = useState(false) - return ( - <CNavbar className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand>Offcanvas navbar</CNavbarBrand> - <CNavbarToggler - aria-controls="offcanvasNavbar" - aria-label="Toggle navigation" - onClick={() => setVisible(!visible)} - /> - <COffcanvas id="offcanvasNavbar" placement="end" portal={false} visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </COffcanvasBody> - </COffcanvas> - </CContainer> - </CNavbar> - ) -} - -<Example> - <OffcanvasExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <CNavbar className="bg-body-tertiary"> - <CContainer fluid> - <CNavbarBrand>Offcanvas navbar</CNavbarBrand> - <CNavbarToggler - aria-controls="offcanvasNavbar" - aria-label="Toggle navigation" - onClick={() => setVisible(!visible)} - /> - <COffcanvas id="offcanvasNavbar" placement="end" portal={false} visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </COffcanvasBody> - </COffcanvas> - </CContainer> - </CNavbar> -) -``` - -To create an offcanvas navbar that expands into a normal navbar at a specific breakpoint like `xxl`, use `expand="xxl"` property. - -export const OffcanvasExample2 = () => { - const [visible, setVisible] = useState(false) - return ( - <CNavbar className="bg-body-tertiary" expand="xxl"> - <CContainer fluid> - <CNavbarBrand>Offcanvas navbar</CNavbarBrand> - <CNavbarToggler - aria-controls="offcanvasNavbar2" - aria-label="Toggle navigation" - onClick={() => setVisible(!visible)} - /> - <COffcanvas id="offcanvasNavbar2" placement="end" portal={false} visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </COffcanvasBody> - </COffcanvas> - </CContainer> - </CNavbar> - ) -} - -<Example> - <OffcanvasExample2 /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <CNavbar className="bg-body-tertiary" expand="xxl"> - <CNavbarBrand>Offcanvas navbar</CNavbarBrand> - <CContainer fluid> - <CNavbarToggler - aria-controls="offcanvasNavbar2" - aria-label="Toggle navigation" - onClick={() => setVisible(!visible)} - /> - <COffcanvas id="offcanvasNavbar2" placement="end" portal={false} visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - <CNavbarNav> - <CNavItem> - <CNavLink href="#" active> - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CDropdown variant="nav-item" popper={false}> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNavbarNav> - <CForm className="d-flex"> - <CFormInput type="search" className="me-2" placeholder="Search" /> - <CButton type="submit" color="success" variant="outline"> - Search - </CButton> - </CForm> - </COffcanvasBody> - </COffcanvas> - </CContainer> - </CNavbar> -) -``` - -## Customizing - -### CSS variables - -React navbars use local CSS variables on `.navbar` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_navbar.scss" capture="navbar-css-vars"/> - -Some additional CSS variables are also present on `.navbar-nav`: - -<ScssDocs file="_navbar.scss" capture="navbar-nav-css-vars"/> - -Customization through CSS variables can be seen on the `.navbar-dark` class where we override specific values without adding duplicate CSS selectors. - -<ScssDocs file="_navbar.scss" capture="navbar-dark-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CNavbar style={vars}>...</CNavbar> -``` - -### SASS variables - -Variables for all navbars: - -<ScssDocs file="_variables.scss" capture="navbar-variables"/> - -Variables for the [dark navbar](#color-schemes): - -<ScssDocs file="_variables.scss" capture="navbar-dark-variables"/> - -### SASS loops - -[Responsive navbar expand/collapse classes](#responsive-behaviors) (e.g., `.navbar-expand-lg`) are combined with the `$breakpoints` map and generated through a loop in `scss/_navbar.scss`. - -<ScssDocs file="_navbar.scss" capture="navbar-expand-loop"/> - -## API - -### CNavbar - -`markdown:CNavbar.api.mdx` - -### CNavbarBrand - -`markdown:CNavbarBrand.api.mdx` - -### CNavbarNav - -`markdown:CNavbarNav.api.mdx` - -### CNavbarText - -`markdown:CNavbarText.api.mdx` - -### CNavbarToggler - -`markdown:CNavbarToggler.api.mdx` diff --git a/packages/docs/content/components/navs-tabs.mdx b/packages/docs/content/components/navs-tabs.mdx deleted file mode 100644 index 5858935a..00000000 --- a/packages/docs/content/components/navs-tabs.mdx +++ /dev/null @@ -1,707 +0,0 @@ ---- -title: React Navs & Tabs Components -name: Navs & Tabs -description: Documentation and examples for how to use CoreUI's included React navigation components. -menu: Components -route: /components/navs-tabs -other_frameworks: navs-tabs ---- - -import { useState } from 'react' - -import { - CDropdown, - CDropdownDivider, - CDropdownHeader, - CDropdownItem, - CDropdownItemPlain, - CDropdownMenu, - CDropdownToggle, - CNav, - CNavItem, - CNavLink, - CTabContent, - CTabPane, -} from '@coreui/react/src/index' - -## Base nav - -Navigation available in CoreUI for React share general markup and styles, from the base `.nav` class to the active and disabled states. Swap modifier classes to switch between each style. - -The base `<CNav>` component is built with flexbox and provide a strong foundation for building all types of navigation components. It includes some style overrides (for working with lists), some link padding for larger hit areas, and basic disabled styling. - -```jsx preview -<CNav> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -Classes are used throughout, so your markup can be super flexible. Use `<ul>`s like above, `<ol>` if the order of your items is important, or roll your own with a `<nav>` element. Because the .nav uses display: flex, the nav links behave the same as nav items would, but without the extra markup. - -```jsx preview -<CNav component="nav"> - <CNavLink href="#" active> - Active - </CNavLink> - <CNavLink href="#">Link</CNavLink> - <CNavLink href="#">Link</CNavLink> - <CNavLink href="#" disabled> - Disabled - </CNavLink> -</CNav> -``` - -## Available styles - -Change the style of `<CNav>`'s component with modifiers and utilities. Mix and match as needed, or build your own. - -### Horizontal alignment - -Change the horizontal alignment of your nav with [flexbox utilities](https://coreui.io/docs/layout/grid/#horizontal-alignment). By default, navs are left-aligned, but you can easily change them to center or right aligned. - -Centered with `.justify-content-center`: - -```jsx preview -<CNav className="justify-content-center"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -Right-aligned with `.justify-content-end`: - -```jsx preview -<CNav className="justify-content-end"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -### Vertical - -Stack your navigation by changing the flex item direction with the `.flex-column` utility. Need to stack them on some viewports but not others? Use the responsive versions (e.g., `.flex-sm-column`). - -```jsx preview -<CNav className="flex-column"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -### Tabs - -Takes the basic nav from above and adds the `variant="tabs"` class to generate a tabbed interface - -```jsx preview -<CNav variant="tabs"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -### Pills - -Take that same code, but use `variant="pills"` instead: - -```jsx preview -<CNav variant="pills"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -### Underline - -Take that same code, but use `variant="underline"` instead: - -```jsx preview -<CNav variant="underline"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -### Underline border - -Take that same code, but use `variant="underline-border"` instead: - -```jsx preview -<CNav variant="underline-border"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -### Fill and justify - -Force your `<CNav>`'s contents to extend the full available width one of two modifier classes. To proportionately fill all available space with your `.nav-item`s, use `layout="fill"`. Notice that all horizontal space is occupied, but not every nav item has the same width. - -```jsx preview -<CNav variant="pills" layout="fill"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -For equal-width elements, use `layout="justified"`. All horizontal space will be occupied by nav links, but unlike the .nav-fill above, every nav item will be the same width. - -```jsx preview -<CNav variant="pills" layout="justified"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -## Working with flex utilities - -If you need responsive nav variations, consider using a series of [flexbox utilities](https://coreui.io/docs/utilities/flex). While more verbose, these utilities offer greater customization across responsive breakpoints. In the example below, our nav will be stacked on the lowest breakpoint, then adapt to a horizontal layout that fills the available width starting from the small breakpoint. - -```jsx preview -<CNav component="nav" variant="pills" className="flex-column flex-sm-row"> - <CNavLink href="#" active> - Active - </CNavLink> - <CNavLink href="#">Link</CNavLink> - <CNavLink href="#">Link</CNavLink> - <CNavLink href="#" disabled> - Disabled - </CNavLink> -</CNav> -``` - -## Regarding accessibility - -If you're using navs to provide a navigation bar, be sure to add a `role="navigation"` to the most logical parent container of the `<ul>`, or wrap a `<nav>` element around the whole navigation. Do not add the role to the `<ul>` itself, as this would prevent it from being announced as an actual list by assistive technologies. - -Note that navigation bars, even if visually styled as tabs with the `.nav-tabs` class, should **not** be given `role="tablist"`, `role="tab"` or `role="tabpanel"` attributes. These are only appropriate for dynamic tabbed interfaces, as described in the [<abbr title="Web Accessibility Initiative">WAI</abbr> <abbr title="Accessible Rich Internet Applications">ARIA</abbr> Authoring Practices](https://www.w3.org/TR/wai-aria-practices/#tabpanel). See [JavaScript behavior](#javascript-behavior) for dynamic tabbed interfaces in this section for an example. The `aria-current` attribute is not necessary on dynamic tabbed interfaces since our JavaScript handles the selected state by adding `aria-selected="true"` on the active tab. - -## Using dropdowns - -Add dropdown menus with a little extra HTML. - -### Tabs with dropdowns - -```jsx preview -<CNav> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CDropdown variant="nav-item"> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -### Pills with dropdowns - -```jsx preview -<CNav variant="pills"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CDropdown variant="nav-item"> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> -</CNav> -``` - -## Tab panes - -Dynamic tabbed interfaces, as described in the [<abbr title="Web Accessibility Initiative">WAI</abbr> <abbr title="Accessible Rich Internet Applications">ARIA</abbr> Authoring Practices](https://www.w3.org/TR/wai-aria-practices/#tabpanel), require `role="tablist"`, `role="tab"`, `role="tabpanel"`, and additional `aria-` attributes in order to convey their structure, functionality and current state to users of assistive technologies (such as screen readers). - -Note that dynamic tabbed interfaces should not contain dropdown menus, as this causes both usability and accessibility issues. From a usability perspective, the fact that the currently displayed tab's trigger element is not immediately visible (as it's inside the closed dropdown menu) can cause confusion. From an accessibility point of view, there is currently no sensible way to map this sort of construct to a standard WAI ARIA pattern, meaning that it cannot be easily made understandable to users of assistive technologies. - -export const TabPanesExample = () => { - const [activeKey, setActiveKey] = useState(1) - return ( - <> - <CNav variant="tabs" role="tablist"> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 1} - onClick={() => setActiveKey(1)} - > - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 2} - onClick={() => setActiveKey(2)} - > - Profile - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 3} - onClick={() => setActiveKey(3)} - > - Contact - </CNavLink> - </CNavItem> - </CNav> - <CTabContent> - <CTabPane role="tabpanel" aria-labelledby="home-tab" visible={activeKey === 1}> - Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown - aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan - helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh - mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan - aliquip quis cardigan american apparel, butcher voluptate nisi qui. - </CTabPane> - <CTabPane role="tabpanel" aria-labelledby="profile-tab" visible={activeKey === 2}> - Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. - Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan - four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft - beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, - assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero - magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, - sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party - scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park. - </CTabPane> - <CTabPane role="tabpanel" aria-labelledby="contact-tab" visible={activeKey === 3}> - Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic - lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork - tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie - helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. - Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro - mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog - stumptown. Pitchfork sustainable tofu synth chambray yr. - </CTabPane> - </CTabContent> - </> - ) -} - -<Example> - <TabPanesExample /> -</Example> - -```jsx -const [activeKey, setActiveKey] = useState(1) -return ( - <> - <CNav variant="tabs" role="tablist"> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 1} - onClick={() => setActiveKey(1)} - > - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 2} - onClick={() => setActiveKey(2)} - > - Profile - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 3} - onClick={() => setActiveKey(3)} - > - Contact - </CNavLink> - </CNavItem> - </CNav> - <CTabContent> - <CTabPane role="tabpanel" aria-labelledby="home-tab" visible={activeKey === 1}> - Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown - aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan - helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh - mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan - aliquip quis cardigan american apparel, butcher voluptate nisi qui. - </CTabPane> - <CTabPane role="tabpanel" aria-labelledby="profile-tab" visible={activeKey === 2}> - Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. - Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan - four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft - beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda - labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit - sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean - shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, - tumblr butcher vero sint qui sapiente accusamus tattooed echo park. - </CTabPane> - <CTabPane role="tabpanel" aria-labelledby="contact-tab" visible={activeKey === 3}> - Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic - lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork - tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. - DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh - mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. - Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. - Pitchfork sustainable tofu synth chambray yr. - </CTabPane> - </CTabContent> - </> -) -``` - -The tabs also works with pills. - -export const TabPanesPillsExample = () => { - const [activeKey, setActiveKey] = useState(1) - return ( - <> - <CNav variant="pills" role="tablist"> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 1} - onClick={() => setActiveKey(1)} - > - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 2} - onClick={() => setActiveKey(2)} - > - Profile - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 3} - onClick={() => setActiveKey(3)} - > - Contact - </CNavLink> - </CNavItem> - </CNav> - <CTabContent> - <CTabPane role="tabpanel" aria-labelledby="home-tab" visible={activeKey === 1}> - Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown - aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan - helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh - mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan - aliquip quis cardigan american apparel, butcher voluptate nisi qui. - </CTabPane> - <CTabPane role="tabpanel" aria-labelledby="profile-tab" visible={activeKey === 2}> - Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. - Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan - four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft - beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, - assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero - magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, - sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party - scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park. - </CTabPane> - <CTabPane role="tabpanel" aria-labelledby="contact-tab" visible={activeKey === 3}> - Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic - lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork - tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie - helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. - Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro - mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog - stumptown. Pitchfork sustainable tofu synth chambray yr. - </CTabPane> - </CTabContent> - </> - ) -} - -<Example> - <TabPanesPillsExample /> -</Example> - -```jsx -const [activeKey, setActiveKey] = useState(1) -return ( - <> - <CNav variant="pills" role="tablist"> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 1} - onClick={() => setActiveKey(1)} - > - Home - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 2} - onClick={() => setActiveKey(2)} - > - Profile - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink - href="#!" - active={activeKey === 3} - onClick={() => setActiveKey(3)} - > - Contact - </CNavLink> - </CNavItem> - </CNav> - <CTabContent> - <CTabPane role="tabpanel" aria-labelledby="home-tab" visible={activeKey === 1}> - Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown - aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan - helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh - mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan - aliquip quis cardigan american apparel, butcher voluptate nisi qui. - </CTabPane> - <CTabPane role="tabpanel" aria-labelledby="profile-tab" visible={activeKey === 2}> - Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. - Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan - four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft - beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda - labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit - sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean - shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, - tumblr butcher vero sint qui sapiente accusamus tattooed echo park. - </CTabPane> - <CTabPane role="tabpanel" aria-labelledby="contact-tab" visible={activeKey === 3}> - Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic - lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork - tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. - DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh - mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. - Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. - Pitchfork sustainable tofu synth chambray yr. - </CTabPane> - </CTabContent> - </> -) -``` - -## Customizing - -### CSS variables - -React cards use local CSS variables on `.nav`, `.nav-tabs`, and `.nav-pills` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -On the `.nav` base class: - -<ScssDocs file="_nav.scss" capture="nav-css-vars"/> - -On the `.nav-tabs` modifier class: - -<ScssDocs file="_nav.scss" capture="nav-tabs-css-vars"/> - -On the `.nav-pills` modifier class: - -<ScssDocs file="_nav.scss" capture="nav-pills-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CNav style={vars}>...</CNav> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="nav-variables"/> - -## API - -### CNav - -`markdown:CNav.api.mdx` - -### CNavItem - -`markdown:CNavItem.api.mdx` - -### CNavLink - -`markdown:CNavLink.api.mdx` - -### CTabContent - -`markdown:CTabContent.api.mdx` - -### CTabPane - -`markdown:CTabPane.api.mdx` diff --git a/packages/docs/content/components/offcanvas.mdx b/packages/docs/content/components/offcanvas.mdx deleted file mode 100644 index 37ac21d0..00000000 --- a/packages/docs/content/components/offcanvas.mdx +++ /dev/null @@ -1,467 +0,0 @@ ---- -title: React Offcanvas Component -name: Offcanvas -description: React alert component allows build hidden sidebars into your project for navigation, shopping carts. -menu: Components -route: /components/offcanvas -other_frameworks: offcanvas ---- - -import { useState } from 'react' - -import { - CAlert, - CButton, - CCloseButton, - CCallout, - COffcanvas, - COffcanvasBody, - COffcanvasHeader, - COffcanvasTitle, -} from '@coreui/react/src/index' - -## Examples - -### Offcanvas components - -Below is an offcanvas example that is shown by default (via `visible={true}`). Offcanvas includes support for a header with a close button and an optional body class for some initial `padding`. We suggest that you include offcanvas headers with dismiss actions whenever possible, or provide an explicit dismiss action. - -```jsx preview className="docs-example-offcanvas bg-body-tertiary p-0 overflow-hidden" -<COffcanvas backdrop={false} placement="start" visible={true}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" /> - </COffcanvasHeader> - <COffcanvasBody> - Content for the offcanvas goes here. You can place just about any React component or custom - elements here. - </COffcanvasBody> -</COffcanvas> -``` - -### Live demo - -Use the buttons below to show and hide an offcanvas component. - -- `visible={false}` hides content (default) -- `visible` or `visible={true}` shows content - -export const LiveDemoExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Toggle offcanvas</CButton> - <COffcanvas placement="start" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Content for the offcanvas goes here. You can place just about any React component or - custom elements here. - </COffcanvasBody> - </COffcanvas> - </> - ) -} - -<Example> - <LiveDemoExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Toggle offcanvas</CButton> - <COffcanvas placement="start" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Content for the offcanvas goes here. You can place just about any React component or - custom elements here. - </COffcanvasBody> - </COffcanvas> - </> -) -``` -### Body scrolling - -Scrolling the `<body>` element is disabled when an offcanvas and its backdrop are visible. Use the scroll property to toggle `<body>` scrolling and backdrop to toggle the backdrop. - -export const BodyScrollingExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Enable body scrolling</CButton> - <COffcanvas backdrop={false} placement="start" scroll={true} visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas with body scrolling</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Try scrolling the rest of the page to see this option in action. - </COffcanvasBody> - </COffcanvas> - </> - ) -} - -<Example> - <BodyScrollingExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Enable body scrolling</CButton> - <COffcanvas backdrop={false} placement="start" scroll={true} visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas with body scrolling</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Try scrolling the rest of the page to see this option in action. - </COffcanvasBody> - </COffcanvas> - </> -) -``` - -### Body scrolling and backdrop - -You can also enable `<body>` scrolling with a visible backdrop. - -export const BodyScrollingAndBackdropExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Enable both scrolling & backdrop</CButton> - <COffcanvas placement="start" scroll={true} visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Backdrop with scrolling</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Try scrolling the rest of the page to see this option in action. - </COffcanvasBody> - </COffcanvas> - </> - ) -} - -<Example> - <BodyScrollingAndBackdropExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Enable both scrolling & backdrop</CButton> - <COffcanvas placement="start" scroll={true} visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Backdrop with scrolling</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Try scrolling the rest of the page to see this option in action. - </COffcanvasBody> - </COffcanvas> - </> -) -``` - -### Static backdrop - -If you set a `backdrop` to `static`, your React offcanvas component will not close when clicking outside of it. - -export const StaticBackdropExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Toggle static offcanvas</CButton> - <COffcanvas backdrop="static" placement="start" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Backdrop with scrolling</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - I will not close if you click outside of me. - </COffcanvasBody> - </COffcanvas> - </> - ) -} - -<Example> - <StaticBackdropExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Toggle static offcanvas</CButton> - <COffcanvas backdrop="static" placement="start" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Backdrop with scrolling</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - I will not close if you click outside of me. - </COffcanvasBody> - </COffcanvas> - </> -) -``` - -## Dark offcanvas - -Change the appearance of offcanvases with `dark` boolean property to better match them to different contexts like dark navbars. - -```jsx preview className="docs-example-offcanvas bg-body-secondary p-0 overflow-hidden" -<COffcanvas backdrop={false} dark placement="start" visible={true}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" /> - </COffcanvasHeader> - <COffcanvasBody> - Content for the offcanvas goes here. You can place just about any React component or custom - elements here. - </COffcanvasBody> -</COffcanvas> -``` - -## Responsive - -Responsive offcanvas properties hide content outside the viewport from a specified breakpoint and down. -Above that breakpoint, the contents within will behave as usual. -For example, `responsive="lg"` hides content in an offcanvas below the lg breakpoint, but shows the content above the lg breakpoint. - -export const ResponsiveExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" className="d-lg-none" onClick={() => setVisible(true)}>Toggle offcanvas</CButton> - <CAlert className="d-none d-lg-block" color="info">Resize your browser to show the responsive offcanvas toggle.</CAlert> - <COffcanvas placement="start" responsive="lg" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Responsive offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - <p>This is content within an <code>.offcanvas-lg</code></p>. - </COffcanvasBody> - </COffcanvas> - </> - ) -} - -<Example> - <ResponsiveExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" className="d-lg-none" onClick={() => setVisible(true)}>Toggle offcanvas</CButton> - <CAlert className="d-none d-lg-block" color="info">Resize your browser to show the responsive offcanvas toggle.</CAlert> - <COffcanvas backdrop="static" placement="start" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Responsive offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - This is content within an <code>.offcanvas-lg</code>. - </COffcanvasBody> - </COffcanvas> - </> -) -``` - - -## Placement - -There's no default placement for offcanvas components, so you must add one of the modifier classes below; - -- `placement="start"` places offcanvas on the left of the viewport (shown above) -- `placement="end"` places offcanvas on the right of the viewport -- `placement="top"` places offcanvas on the top of the viewport -- `placement="bottom"` places offcanvas on the bottom of the viewport - -Try the top, right, and bottom examples out below. - -export const PlacementTopExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Toggle top offcanvas</CButton> - <COffcanvas placement="top" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Content for the offcanvas goes here. You can place just about any React component or - custom elements here. - </COffcanvasBody> - </COffcanvas> - </> - ) -} - -<Example> - <PlacementTopExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Toggle top offcanvas</CButton> - <COffcanvas placement="top" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Content for the offcanvas goes here. You can place just about any React component or - custom elements here. - </COffcanvasBody> - </COffcanvas> - </> -) -``` - -export const PlacementRightExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Toggle right offcanvas</CButton> - <COffcanvas placement="end" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Content for the offcanvas goes here. You can place just about any React component or - custom elements here. - </COffcanvasBody> - </COffcanvas> - </> - ) -} - -<Example> - <PlacementRightExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Toggle right offcanvas</CButton> - <COffcanvas placement="right" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Content for the offcanvas goes here. You can place just about any React component or - custom elements here. - </COffcanvasBody> - </COffcanvas> - </> -) -``` - -export const PlacementBottomExample = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Toggle bottom offcanvas</CButton> - <COffcanvas placement="bottom" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Content for the offcanvas goes here. You can place just about any React component or - custom elements here. - </COffcanvasBody> - </COffcanvas> - </> - ) -} - -<Example> - <PlacementBottomExample /> -</Example> - -```jsx -const [visible, setVisible] = useState(false) -return ( - <> - <CButton color="primary" onClick={() => setVisible(true)}>Toggle bottom offcanvas</CButton> - <COffcanvas placement="bottom" visible={visible} onHide={() => setVisible(false)}> - <COffcanvasHeader> - <COffcanvasTitle>Offcanvas</COffcanvasTitle> - <CCloseButton className="text-reset" onClick={() => setVisible(false)} /> - </COffcanvasHeader> - <COffcanvasBody> - Content for the offcanvas goes here. You can place just about any React component or - custom elements here. - </COffcanvasBody> - </COffcanvas> - </> -) -``` - -## Accessibility - -Since the offcanvas panel is conceptually a modal dialog, be sure to add `aria-labelledby="..."`—referencing the offcanvas title—to `<COffcanvas>`. Note that you don’t need to add `role="dialog"` since we already add it automatically. - -## Customizing - -### CSS variables - -React offcanvas uses local CSS variables on `.offcanvas` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_offcanvas.scss" capture="offcanvas-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <COffcanvas style={vars}>...</COffcanvas> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="offcanvas-variables"/> - -## API - -### COffcanvas - -`markdown:COffcanvas.api.mdx` - -### COffcanvasBody - -`markdown:COffcanvasBody.api.mdx` - -### COffcanvasHeader - -`markdown:COffcanvasHeader.api.mdx` - -### COffcanvasTitle - -`markdown:COffcanvasTitle.api.mdx` diff --git a/packages/docs/content/components/pagination.mdx b/packages/docs/content/components/pagination.mdx deleted file mode 100644 index 4562715f..00000000 --- a/packages/docs/content/components/pagination.mdx +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: React Pagination Component -name: Pagination -description: Documentation and examples for showing pagination to indicate a series of related content exists across multiple pages. -menu: Components -route: /components/pagination -other_frameworks: pagination ---- - -import { CPagination, CPaginationItem } from '@coreui/react/src/index' - -## Overview - -We use a large block of connected links for our pagination, making links hard to miss and easily scalable—all while providing large hit areas. Pagination is built with list HTML elements so screen readers can announce the number of available links. Use a wrapping `<nav>` element to identify it as a navigation section to screen readers and other assistive technologies. - -In addition, as pages likely have more than one such navigation section, it's advisable to provide a descriptive `aria-label` for the `<nav>` to reflect its purpose. For example, if the pagination component is used to navigate between a set of search results, an appropriate label could be `aria-label="Search results pages"`. - -```jsx preview -<CPagination aria-label="Page navigation example"> - <CPaginationItem>Previous</CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem>Next</CPaginationItem> -</CPagination> -``` - -## Working with icons - -Looking to use an icon or symbol in place of text for some pagination links? Be sure to provide proper screen reader support with `aria` attributes. - -```jsx preview -<CPagination aria-label="Page navigation example"> - <CPaginationItem aria-label="Previous"> - <span aria-hidden="true">«</span> - </CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem aria-label="Next"> - <span aria-hidden="true">»</span> - </CPaginationItem> -</CPagination> -``` - -## Disabled and active states - -Pagination links are customizable for different circumstances. Use `disabled` for links that appear un-clickable and `.active` to indicate the current page. - -While the `disabled` prop uses `pointer-events: none` to _try_ to disable the link functionality of `<a>`s, that CSS property is not yet standardized and doesn't account for keyboard navigation. As such, we always add `tabindex="-1"` on disabled links and use custom JavaScript to fully disable their functionality. - -```jsx preview -<CPagination aria-label="Page navigation example"> - <CPaginationItem aria-label="Previous" disabled> - <span aria-hidden="true">«</span> - </CPaginationItem> - <CPaginationItem active>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem aria-label="Next"> - <span aria-hidden="true">»</span> - </CPaginationItem> -</CPagination> -``` - -## Sizing - -Fancy larger or smaller pagination? Add `size="lg"` or `size="sm"` for additional sizes. - -```jsx preview -<CPagination size="lg" aria-label="Page navigation example"> - <CPaginationItem>Previous</CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem>Next</CPaginationItem> -</CPagination> -``` - -```jsx preview -<CPagination size="sm" aria-label="Page navigation example"> - <CPaginationItem>Previous</CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem>Next</CPaginationItem> -</CPagination> -``` - -## Alignment - -Change the alignment of pagination components with `align` property. - -```jsx preview -<CPagination align="center" aria-label="Page navigation example"> - <CPaginationItem disabled>Previous</CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem>Next</CPaginationItem> -</CPagination> -``` - -```jsx preview -<CPagination align="end" aria-label="Page navigation example"> - <CPaginationItem disabled>Previous</CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem>Next</CPaginationItem> -</CPagination> -``` - -## Customizing - -### CSS variables - -React pagination use local CSS variables on `.pagination` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_pagination.scss" capture="pagination-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CPagination style={vars}>...</CCard> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="pagination-variables"/> - -## API - -### CPagination - -`markdown:CPagination.api.mdx` - -### CPaginationItem - -`markdown:CPaginationItem.api.mdx` diff --git a/packages/docs/content/components/placeholder.mdx b/packages/docs/content/components/placeholder.mdx deleted file mode 100644 index 777e3b7f..00000000 --- a/packages/docs/content/components/placeholder.mdx +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: React Placeholder Component -name: Placeholder -description: Use loading react placeholders for your components or pages to indicate something may still be loading. -menu: Components -route: /components/placeholder -other_frameworks: placeholder ---- - -import { useState } from 'react' -import { - CButton, - CCard, - CCardBody, - CCardImage, - CCardText, - CCardTitle, - CPlaceholder, -} from '@coreui/react/src/index' - -import ReactImg from './../assets/images/react.jpg' - -## About - -Placeholders can be used to enhance the experience of your application. They're built only with HTML and CSS, meaning you don't need any JavaScript to create them. You will, however, need some custom JavaScript to toggle their visibility. Their appearance, color, and sizing can be easily customized with our utility classes. - -## Example - -In the example below, we take a typical card component and recreate it with placeholders applied to create a "loading card". Size and proportions are the same between the two. - -```jsx preview className="d-flex justify-content-around"> -<CCard style={{ width: '18rem' }}> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the card's - content. - </CCardText> - <CButton color="primary" href="#">Go somewhere</CButton> - </CCardBody> -</CCard> -<CCard style={{ width: '18rem' }}> - <CCardImage component="svg" orientation="top" width="100%" height="162" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Placeholder" preserveAspectRatio="xMidYMid slice" focusable="false"> - <title>Placeholder</title><rect width="100%" height="100%" fill="#868e96"></rect> - </CCardImage> - <CCardBody> - <CPlaceholder component={CCardTitle} animation="glow" xs={7}> - <CPlaceholder xs={6} /> - </CPlaceholder> - <CPlaceholder component={CCardText} animation="glow"> - <CPlaceholder xs={7} /> - <CPlaceholder xs={4} /> - <CPlaceholder xs={4} /> - <CPlaceholder xs={6} /> - <CPlaceholder xs={8} /> - </CPlaceholder> - <CPlaceholder component={CButton} disabled href="#" tabIndex={-1} xs={6}></CPlaceholder> - </CCardBody> -</CCard> -``` - -## How it works - -Create placeholders with the `<CPlaceholder>` component and a grid column propx (e.g., `xs={6}`) to set the `width`. They can replace the text inside an element or be added as a modifier class to an existing component. - -We apply additional styling to `CButton`s via `::before` to ensure the `height` is respected. You may extend this pattern for other situations as needed, or add a ` ` within the element to reflect the height when actual text is rendered in its place. - -```jsx preview -<p aria-hidden="true"> - <CPlaceholder xs={6} /> -</p> -<CPlaceholder component={CButton} aria-hidden="true" disabled href="#" tabIndex={-1} xs={4}></CPlaceholder> -``` - -<Callout className="mb-4" color="info"> - The use of <code>aria-hidden="true"</code> only indicates that the element should be hidden to - screen readers. The <strong>loading</strong> behavior of the placeholder depends on how authors - will actually use the placeholder styles, how they plan to update things, etc. Some JavaScript - code may be needed to *swap* the state of the placeholder and inform AT users of the update. -</Callout> - -### Width - -You can change the `width` through grid column classes, width utilities, or inline styles. - -```jsx preview -<CPlaceholder xs={6} /> -<CPlaceholder className="w-75" /> -<CPlaceholder style={{ width: '30%'}} /> -``` - -### Color - -By default, the `<CPlaceholder>` uses `currentColor`. This can be overridden with a custom color or utility class. - -```jsx preview -<CPlaceholder xs={12} /> - -<CPlaceholder color="primary" xs={12} /> -<CPlaceholder color="secondary" xs={12} /> -<CPlaceholder color="success" xs={12} /> -<CPlaceholder color="danger" xs={12} /> -<CPlaceholder color="warning" xs={12} /> -<CPlaceholder color="info" xs={12} /> -<CPlaceholder color="light" xs={12} /> -<CPlaceholder color="dark" xs={12} /> -``` - -### Sizing - -The size of `<CPlaceholder>`s are based on the typographic style of the parent element. Customize them with `size` prop: `lg`, `sm`, or `xs`. - -```jsx preview -<CPlaceholder xs={12} size="lg"/> -<CPlaceholder xs={12}/> -<CPlaceholder xs={12} size="sm"/> -<CPlaceholder xs={12} size="xs"/> -``` - -### Animation - -Animate placeholders with `animation="glow"` or `animation="wave"` to better convey the perception of something being _actively_ loaded. - -```jsx preview -<CPlaceholder component="p" animation="glow"> - <CPlaceholder xs={12} /> -</CPlaceholder> - -<CPlaceholder component="p" animation="wave"> - <CPlaceholder xs={12} /> -</CPlaceholder> -``` - -## Customizing - -### SASS variables - -<ScssDocs file="_variables.scss" capture="placeholders"/> - -## API - -### CPlaceholder - -`markdown:CPlaceholder.api.mdx` diff --git a/packages/docs/content/components/popover.mdx b/packages/docs/content/components/popover.mdx deleted file mode 100644 index ea2cdbc0..00000000 --- a/packages/docs/content/components/popover.mdx +++ /dev/null @@ -1,214 +0,0 @@ ---- -title: React Popover Component -name: Popover -description: Documentation and examples for adding React popovers, like those found in iOS, to any element on your site. -menu: Components -route: /components/popover -other_frameworks: popover ---- - -import { CPopover, CButton } from '@coreui/react/src/index' - -## Examples - -### Live demo - -<Example> - <CPopover - title="Popover title" - content="And here’s some amazing content. It’s very engaging. Right?" - placement="right" - > - <CButton color="danger" size="lg">Click to toggle popover</CButton> - </CPopover> -</Example> - -```jsx -<CPopover - title="Popover title" - content="And here’s some amazing content. It’s very engaging. Right?" - placement="right" -> - <CButton color="danger" size="lg">Click to toggle popover</CButton> -</CPopover> -``` - -### Four directions - -Four options are available: top, right, bottom, and left aligned. Directions are mirrored when using CoreUI for React in RTL. - -<Example> - <CPopover content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." placement="top"> - <CButton color="secondary">Popover on top</CButton> - </CPopover> - <CPopover content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." placement="right"> - <CButton color="secondary">Popover on right</CButton> - </CPopover> - <CPopover content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." placement="bottom"> - <CButton color="secondary">Popover on bottom</CButton> - </CPopover> - <CPopover content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." placement="left"> - <CButton color="secondary">Popover on left</CButton> - </CPopover> -</Example> - -```jsx - <CPopover - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="top" - > - <CButton color="secondary">Popover on top</CButton> - </CPopover> - <CPopover - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="right" - > - <CButton color="secondary">Popover on right</CButton> - </CPopover> - <CPopover - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="bottom" - > - <CButton color="secondary">Popover on bottom</CButton> - </CPopover> - <CPopover - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="left" - > - <CButton color="secondary">Popover on left</CButton> - </CPopover> -``` - -### Custom popovers - -You can customize the appearance of popovers using [CSS variables](#css-variables). We set a custom `style` to scope our custom appearance and use it to override some of the local CSS variables. - -export const CustomPopoversExample = () => { - const customPopoverStyle = { - '--cui-popover-max-width': '200px', - '--cui-popover-border-color': 'var(--cui-primary)', - '--cui-popover-header-bg': 'var(--cui-primary)', - '--cui-popover-header-color': 'var(--cui-white)', - '--cui-popover-body-padding-x': '1rem', - '--cui-popover-body-padding-y': '.5rem', - } - return ( - <CPopover - content="This popover is themed via CSS variables." - placement="right" - title="Custom popover" - style={customPopoverStyle} - > - <CButton color="secondary">Custom popover</CButton> - </CPopover> - ) -} - -<Example> - <CustomPopoversExample /> -</Example> -```jsx -const customPopoverStyle = { - '--cui-popover-max-width': '200px', - '--cui-popover-border-color': 'var(--cui-primary)', - '--cui-popover-header-bg': 'var(--cui-primary)', - '--cui-popover-header-color': 'var(--cui-white)', - '--cui-popover-body-padding-x': '1rem', - '--cui-popover-body-padding-y': '.5rem', -} -return ( - <CPopover - content="This popover is themed via CSS variables." - placement="right" - title="Custom popover" - style={customPopoverStyle} - > - <CButton color="secondary">Custom popover</CButton> - </CPopover> -) -``` - -### Dismiss on next click - -Use the `focus` trigger to dismiss popovers on the user's next click of a different element than the toggle element. - -<Example> - <CPopover - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="right" - title="Dismissible popover" - trigger="focus" - > - <CButton color="danger">Dismissible popover</CButton> - </CPopover> -</Example> -```jsx -<CPopover - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="right" - title="Dismissible popover" - trigger="focus" -> - <CButton color="danger">Dismissible popover</CButton> -</CPopover> -``` - -## Usage - -### Disabled elements - -Elements with the disabled attribute aren't interactive, meaning users cannot hover or click them to trigger a popover (or tooltip). As a workaround, you'll want to trigger the popover from a wrapper `<div>` or `<span>`, ideally made keyboard-focusable using `tabindex="0"`. - -For disabled popover triggers, you may also prefer `trigger={['hover', 'focus']}` so that the popover appears as immediate visual feedback to your users as they may not expect to click on a disabled element. - -<Example> - <CPopover - content="Disabled popover" - placement="right" - trigger={['hover', 'focus']} - > - <span className="d-inline-block" tabIndex={0}> - <CButton color="primary" disabled>Disabled button</CButton> - </span> - </CPopover> -</Example> -```jsx -<CPopover - content="Disabled popover" - placement="right" - trigger={['hover', 'focus']} -> - <span className="d-inline-block" tabIndex={0}> - <CButton color="primary" disabled>Disabled button</CButton> - </span> -</CPopover> -``` - - -## Customizing - -### CSS variables - -React popovers use local CSS variables on `.popover` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_popover.scss" capture="popover-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': 'red', -} -return <CPopover style={vars}>...</CPopover> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="popover-variables"/> - -## API - -### CPopover - -`markdown:CPopover.api.mdx` diff --git a/packages/docs/content/components/progress.mdx b/packages/docs/content/components/progress.mdx deleted file mode 100644 index 78b1b9ab..00000000 --- a/packages/docs/content/components/progress.mdx +++ /dev/null @@ -1,184 +0,0 @@ ---- -title: React Progress Component -name: Progress -description: Documentation and examples for using React progress bars featuring support for stacked bars, animated backgrounds, and text labels. -menu: Components -route: /components/progress -other_frameworks: progress ---- - -import { CButton, CProgress, CProgressBar, CProgressStacked } from '@coreui/react/src/index' - -## Example - -Progress components are built with two HTML elements, some CSS to set the width, and a few attributes. We don't use [the HTML5 `<progress>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress), ensuring you can stack progress bars, animate them, and place text labels over them. - -## Basic usage - -```jsx preview -<CProgress value={0} /> -<CProgress value={25} /> -<CProgress value={50} /> -<CProgress value={75} /> -<CProgress value={100} /> -``` - -## Labels - -Add labels to your progress bars by placing text within the `<CProgressBar>`. - -```jsx preview -<CProgress value={25}>25%</CProgress> -``` - -Please note that the default setting for the content within the `<CProgressBar />` is to be limited by the `overflow: hidden property`, preventing it from extending beyond the bar's boundaries. If the progress bar is shorter than its label, the content will be truncated and could be difficult to read. To modify this behavior, you can utilize the `.overflow-visible` class from the overflow utilities. However, it is important to specify a specific text color to ensure readability. It's worth noting that this approach currently does not consider color modes. - -```jsx preview -<CProgress value={10}> - <CProgressBar className="overflow-visible text-dark px-2" color="success">Long label text for the progress bar, set to a dark color</CProgressBar> -</CProgress> -``` - -Since **v4.9.0** you can also use the `progressBarClassName` property directly on the `<CProgress />` component to achieve the same. - -```jsx -<CProgress progressBarClassName="overflow-visible text-dark px-2" color="success" value={10}>Long label text for the progress bar, set to a dark color</CProgress> -``` - -## Height - -We only set a `height` value on the `<CProgress>`, so if you change that value the inner `<CProgressBar>` will automatically resize accordingly. - -```jsx preview -<CProgress height={1} value={25} /> -<CProgress height={20} value={25} /> -``` - -```jsx preview -<CProgress height={1}> - <CProgressBar value={25}></CProgressBar> -</CProgress> -<CProgress height={20}> - <CProgressBar value={25}></CProgressBar> -</CProgress> -``` - -## Backgrounds - -Use `color` prop to change the appearance of individual progress bars. - -```jsx preview -<CProgress color="success" value={25} /> -<CProgress color="info" value={50} /> -<CProgress color="warning" value={75} /> -<CProgress color="danger" value={100} /> -``` - -Ensure that when you incorporate labels into progress bars featuring a custom background color, you also select an appropriate text color to ensure readability and maintain adequate contrast for the labels. - -```jsx preview -<CProgress color="success" value={25}> - <CProgressBar>25%</CProgressBar> -</CProgress> -<CProgress color="info" value={50}> - <CProgressBar className="text-dark">50%</CProgressBar> -</CProgress> -<CProgress color="warning" value={75}> - <CProgressBar className="text-dark">75%</CProgressBar> -</CProgress> -<CProgress color="danger" value={100}> - <CProgressBar>100%</CProgressBar> -</CProgress> -``` - -Since **v4.9.0** you can also use the `progressBarClassName` property directly on the `<CProgress />` component to achieve the same. - -```jsx -<CProgress color="success" value={25}>25%</CProgress> -<CProgress color="info" progressBarClassName="text-dark" value={50}>50%</CProgress> -<CProgress color="warning" progressBarClassName="text-dark" value={75}>75%</CProgress> -<CProgress color="danger" value={100}>100%</CProgress> -``` - -## Multiple bars - -Include multiple progress bars in a progress component if you need. In **v4.9.0** - -<Callout color="info" title="New markup in v4.9.0"> - In version 4.9.0, we introduced a new `<CProgressStacked>` component to more logically wrap multiple progress bars into a single stacked progress bar. The previous structure will continue to work until the next major version. -</Callout> - - -**New markup** - -```jsx preview -<CProgressStacked> - <CProgress value={15} /> - <CProgress color="success" value={30} /> - <CProgress color="info" value={20} /> -</CProgressStacked> -``` - -**Previous markup** -```jsx -<CProgress> - <CProgressBar value={15} /> - <CProgressBar color="success" value={30} /> - <CProgressBar color="info" value={20} /> -</CProgress> -``` - -## Striped - -Add `variant="striped"` to any `<CProgressBar>` to apply a stripe via CSS gradient over the progress bar's background color. - -```jsx preview -<CProgress color="success" variant="striped" value={25} /> -<CProgress color="info" variant="striped" value={50} /> -<CProgress color="warning" variant="striped" value={75} /> -<CProgress color="danger" variant="striped" value={100} /> -``` - - -## Animated stripes - -The striped gradient can also be animated. Add `animated` property to `<CProgressBar>` to animate the stripes right to left via CSS3 animations. - -```jsx preview -<CProgress color="success" variant="striped" animated value={25} /> -<CProgress color="info" variant="striped" animated value={50} /> -<CProgress color="warning" variant="striped" animated value={75} /> -<CProgress color="danger" variant="striped" animated value={100} /> -``` - -## Customizing - -### CSS variables - -React cards use local CSS variables on `.card` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_progress.scss" capture="progress-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CProgress style={vars}>...</CProgress> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="progress-variables"/> - -## API - -### CProgress - -`markdown:CProgress.api.mdx` - -### CProgressBar - -`markdown:CProgressBar.api.mdx` diff --git a/packages/docs/content/components/sidebar.mdx b/packages/docs/content/components/sidebar.mdx deleted file mode 100644 index a2367350..00000000 --- a/packages/docs/content/components/sidebar.mdx +++ /dev/null @@ -1,305 +0,0 @@ ---- -title: React Sidebar Component -name: Sidebar -description: -menu: Components -route: /components/sidebar -other_frameworks: sidebar ---- - -import CIcon from '@coreui/icons-react' -import { cilCloudDownload, cilLayers, cilPuzzle, cilSpeedometer } from '@coreui/icons' - -import { - CBadge, - CSidebar, - CSidebarBrand, - CSidebarFooter, - CSidebarHeader, - CSidebarNav, - CSidebarToggler, - CNavGroup, - CNavGroupItems, - CNavItem, - CNavLink, - CNavTitle, -} from '@coreui/react/src/index' - -## Supported content - -Sidebar come with built-in support for a handful of sub-components. Choose from the following as needed: - -- `<CSidebarHeader>` for optional header. -- `<CSidebarBrand>` for your company, product, or project name. -- `<CSidebarNav>` for a full-height and lightweight navigation (including support for dropdowns). -- `<CSidebarFooter>` for optional footer. -- `<CSidebarToggler>` for use with our minimizer plugin. - -## Examples - -### Sidebar component - -Below is an sidebar example that is shown by default on desktop devices. - -<Example className="bg-body-secondary p-0 rounded-bottom-0 overflow-hidden"> - <CSidebar className="border-end"> - <CSidebarHeader className="border-bottom"> - <CSidebarBrand>CoreUI</CSidebarBrand> - </CSidebarHeader> - <CSidebarNav> - <CNavTitle>Nav Title</CNavTitle> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> Nav item</CNavItem> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> With badge <CBadge color="primary ms-auto">NEW</CBadge></CNavItem> - <CNavGroup - toggler={ - <> - <CIcon customClassName="nav-icon" icon={cilPuzzle} /> Nav dropdown - </> - } - > - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - </CNavGroup> - <CNavItem href="https://coreui.io"><CIcon customClassName="nav-icon" icon={cilCloudDownload} /> Download CoreUI</CNavItem> - <CNavItem href="https://coreui.io/pro/"><CIcon customClassName="nav-icon" icon={cilLayers} /> Try CoreUI PRO</CNavItem> - </CSidebarNav> - <CSidebarHeader className="border-top"> - <CSidebarToggler /> - </CSidebarHeader> - </CSidebar> -</Example> - -```jsx -<CSidebar className="border-end"> - <CSidebarHeader className="border-bottom"> - <CSidebarBrand>CoreUI</CSidebarBrand> - </CSidebarHeader> - <CSidebarNav> - <CNavTitle>Nav Title</CNavTitle> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> Nav item</CNavItem> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> With badge <CBadge color="primary ms-auto">NEW</CBadge></CNavItem> - <CNavGroup - toggler={ - <> - <CIcon customClassName="nav-icon" icon={cilPuzzle} /> Nav dropdown - </> - } - > - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - </CNavGroup> - <CNavItem href="https://coreui.io"><CIcon customClassName="nav-icon" icon={cilCloudDownload} /> Download CoreUI</CNavItem> - <CNavItem href="https://coreui.io/pro/"><CIcon customClassName="nav-icon" icon={cilLayers} /> Try CoreUI PRO</CNavItem> - </CSidebarNav> - <CSidebarHeader className="border-top"> - <CSidebarToggler /> - </CSidebarHeader> -</CSidebar> -``` - -### Narrow sidebar - -Add the `narrow` property to make the sidebar narrow. - -<Example className="bg-body-secondary p-0 rounded-bottom-0 overflow-hidden"> - <CSidebar className="border-end" narrow> - <CSidebarHeader className="border-bottom"> - <CSidebarBrand>CUI</CSidebarBrand> - </CSidebarHeader> - <CSidebarNav> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /></CNavItem> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /></CNavItem> - <CNavItem href="https://coreui.io"><CIcon customClassName="nav-icon" icon={cilCloudDownload} /></CNavItem> - <CNavItem href="https://coreui.io/pro/"><CIcon customClassName="nav-icon" icon={cilLayers} /></CNavItem> - </CSidebarNav> - </CSidebar> -</Example> - -```jsx -<CSidebar className="border-end" narrow> - <CSidebarHeader className="border-bottom"> - <CSidebarBrand>CUI</CSidebarBrand> - </CSidebarHeader> - <CSidebarNav> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /></CNavItem> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /></CNavItem> - <CNavItem href="https://coreui.io"><CIcon customClassName="nav-icon" icon={cilCloudDownload} /></CNavItem> - <CNavItem href="https://coreui.io/pro/"><CIcon customClassName="nav-icon" icon={cilLayers} /></CNavItem> - </CSidebarNav> -</CSidebar> -``` - -### Unfoldable sidebar - -Add the `unfoldable` property to make the sidebar narrow with unfoldable on hover. - -<Example className="bg-body-secondary p-0 rounded-bottom-0 overflow-hidden"> - <CSidebar className="border-end" unfoldable> - <CSidebarHeader className="border-bottom"> - <CSidebarBrand>CUI</CSidebarBrand> - </CSidebarHeader> - <CSidebarNav> - <CNavTitle>Nav Title</CNavTitle> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> Nav item</CNavItem> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> With badge <CBadge color="primary ms-auto">NEW</CBadge></CNavItem> - <CNavGroup - toggler={ - <> - <CIcon customClassName="nav-icon" icon={cilPuzzle} /> Nav dropdown - </> - } - > - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - </CNavGroup> - <CNavItem href="https://coreui.io"><CIcon customClassName="nav-icon" icon={cilCloudDownload} /> Download CUI</CNavItem> - <CNavItem href="https://coreui.io/pro/"><CIcon customClassName="nav-icon" icon={cilLayers} /> Try CoreUI PRO</CNavItem> - </CSidebarNav> - </CSidebar> -</Example> - -```jsx -<CSidebar className="border-end" unfoldable> - <CSidebarHeader className="border-bottom"> - <CSidebarBrand>CUI</CSidebarBrand> - </CSidebarHeader> - <CSidebarNav> - <CNavTitle>Nav Title</CNavTitle> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> Nav item</CNavItem> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> With badge <CBadge color="primary ms-auto">NEW</CBadge></CNavItem> - <CNavGroup - toggler={ - <> - <CIcon customClassName="nav-icon" icon={cilPuzzle} /> Nav dropdown - </> - } - > - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - </CNavGroup> - <CNavItem href="https://coreui.io"><CIcon customClassName="nav-icon" icon={cilCloudDownload} /> Download CoreUI</CNavItem> - <CNavItem href="https://coreui.io/pro/"><CIcon customClassName="nav-icon" icon={cilLayers} /> Try CoreUI PRO</CNavItem> - </CSidebarNav> -</CSidebar> -``` - -## Dark sidebar - -Change the appearance of sidebars with the `colorScheme="dark"`. - -<Example className="bg-body-secondary p-0 rounded-bottom-0 overflow-hidden"> - <CSidebar className="border-end" colorScheme="dark"> - <CSidebarHeader className="border-bottom"> - <CSidebarBrand>CoreUI</CSidebarBrand> - </CSidebarHeader> - <CSidebarNav> - <CNavTitle>Nav Title</CNavTitle> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> Nav item</CNavItem> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> With badge <CBadge color="primary ms-auto">NEW</CBadge></CNavItem> - <CNavGroup - toggler={ - <> - <CIcon customClassName="nav-icon" icon={cilPuzzle} /> Nav dropdown - </> - } - > - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - </CNavGroup> - <CNavItem href="https://coreui.io"><CIcon customClassName="nav-icon" icon={cilCloudDownload} /> Download CoreUI</CNavItem> - <CNavItem href="https://coreui.io/pro/"><CIcon customClassName="nav-icon" icon={cilLayers} /> Try CoreUI PRO</CNavItem> - </CSidebarNav> - </CSidebar> -</Example> - -```jsx -<CSidebar className="border-end" colorScheme="dark"> - <CSidebarHeader className="border-bottom"> - <CSidebarBrand>CoreUI</CSidebarBrand> - </CSidebarHeader> - <CSidebarNav> - <CNavTitle>Nav Title</CNavTitle> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> Nav item</CNavItem> - <CNavItem href="#"><CIcon customClassName="nav-icon" icon={cilSpeedometer} /> With badge <CBadge color="primary ms-auto">NEW</CBadge></CNavItem> - <CNavGroup - toggler={ - <> - <CIcon customClassName="nav-icon" icon={cilPuzzle} /> Nav dropdown - </> - } - > - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - <CNavItem href="#"><span className="nav-icon"><span className="nav-icon-bullet"></span></span> Nav dropdown item</CNavItem> - </CNavGroup> - <CNavItem href="https://coreui.io"><CIcon customClassName="nav-icon" icon={cilCloudDownload} /> Download CoreUI</CNavItem> - <CNavItem href="https://coreui.io/pro/"><CIcon customClassName="nav-icon" icon={cilLayers} /> Try CoreUI PRO</CNavItem> - </CSidebarNav> -</CSidebar> -``` - -## Placement - -By default placement for sidebar components is on the left of the viewport, but you can add one of the modifier classes below. - -- `placement="start"` places sidebar on the left of the viewport (shown above) -- `placement="end"` places sidebar on the right of the viewport - -## Customizing - -### CSS variables - -React sidebars use local CSS variables on `.sidebar` and `.sidebar-backdrop` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="sidebar/_sidebar.scss" capture="sidebar-css-vars" /> - -<ScssDocs file="sidebar/_sidebar.scss" capture="sidebar-overlaid-css-vars" /> - -<ScssDocs file="sidebar/_sidebar-narrow.scss" capture="sidebar-narrow-css-vars" /> - -<ScssDocs file="sidebar/_sidebar-nav.scss" capture="sidebar-nav-css-vars" /> - -<ScssDocs file="sidebar/_sidebar.scss" capture="sidebar-toggler-css-vars" /> - -<ScssDocs file="sidebar/_sidebar.scss" capture="sidebar-backdrop-css-vars" /> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': 'red', -} -return <CSidebar style={vars}>...</CSidebar> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="sidebar-variables" /> - -<ScssDocs file="_variables.scss" capture="sidebar-toggler" /> - -## API - -### CSidebar - -`markdown:CSidebar.api.mdx` - -### CSidebarBrand - -`markdown:CSidebarBrand.api.mdx` - -### CSidebarFooter - -`markdown:CSidebarFooter.api.mdx` - -### CSidebarHeader - -`markdown:CSidebarHeader.api.mdx` - -### CSidebarNav - -`markdown:CSidebarNav.api.mdx` - -### CSidebarToggler - -`markdown:CSidebarToggler.api.mdx` diff --git a/packages/docs/content/components/spinner.mdx b/packages/docs/content/components/spinner.mdx deleted file mode 100644 index cca0e412..00000000 --- a/packages/docs/content/components/spinner.mdx +++ /dev/null @@ -1,193 +0,0 @@ ---- -title: React Spinner Component -name: Spinner -description: Indicate the loading state of a component or page with CoreUI spinners, built entirely with HTML, CSS, and no JavaScript. -menu: Components -route: /components/spinner -other_frameworks: spinner ---- - -import { CSpinner, CButton } from '@coreui/react/src/index' - -## About - -CoreUI "spinners" can be used to show the loading state in your projects. They're built only with HTML and CSS, meaning you don't need any JavaScript to create them. You will, however, need some custom JavaScript to toggle their visibility. Their appearance, alignment, and sizing can be easily customized with our amazing utility classes. - -For accessibility purposes, each loader here includes `role="status"` and a nested `<span className="visually-hidden">Loading...</span>`. - -## Border spinner - -Use the border spinners for a lightweight loading indicator. - -```jsx preview -<CSpinner/> -``` - -### Colors - -The border spinner uses `currentColor` for its `border-color`. You can use any of our text color utilities on the standard spinner. - -```jsx preview -<CSpinner color="primary" /> -<CSpinner color="secondary" /> -<CSpinner color="success" /> -<CSpinner color="danger" /> -<CSpinner color="warning" /> -<CSpinner color="info" /> -<CSpinner color="light" /> -<CSpinner color="dark" /> -``` - -## Growing spinner - -If you don't fancy a border spinner, switch to the grow spinner. While it doesn't technically spin, it does repeatedly grow! - -```jsx preview -<CSpinner variant="grow" /> -``` - -Once again, this spinner is built with `currentColor`, so you can easily change its appearance. Here it is in blue, along with the supported variants. - -```jsx preview -<CSpinner color="primary" variant="grow" /> -<CSpinner color="secondary" variant="grow" /> -<CSpinner color="success" variant="grow" /> -<CSpinner color="danger" variant="grow" /> -<CSpinner color="warning" variant="grow" /> -<CSpinner color="info" variant="grow" /> -<CSpinner color="light" variant="grow" /> -<CSpinner color="dark" variant="grow" /> -``` - -## Alignment - -CoreUI React spinners are built with `rems`, `currentColor`, and `display: inline-flex`. This means they can easily be resized, recolored, and quickly aligned. - -### Margin - -Use [margin utilities](https://coreui.io/docs/utilities/spacing/#margin-and-padding) like `.m-5` for easy spacing. - -```jsx preview -<CSpinner className="m-5" /> -``` - -### Placement - -Use [flexbox utilities][https://coreui.io/docs/utilities/flex/], [float utilities][https://coreui.io/docs/utilities/float/], or [text alignment][https://coreui.io/docs/utilities/text/] utilities to place spinners exactly where you need them in any situation. - -#### Flex - -```jsx preview -<div className="d-flex justify-content-center"> - <CSpinner /> -</div> -``` - -```jsx preview -<div className="d-flex align-items-center"> - <strong role="status">Loading...</strong> - <CSpinner className="ms-auto" /> -</div> -``` - -#### Floats - -```jsx preview -<div className="clearfix"> - <CSpinner className="float-end" /> -</div> -``` - -#### Text align - -```jsx preview -<div className="text-center"> - <CSpinner /> -</div> -``` - -## Size - -Add `size="sm"` property to make a smaller spinner that can quickly be used within other components. - -```jsx preview -<CSpinner size="sm" /> -<CSpinner size="sm" variant="grow" /> -``` - -Or, use custom CSS or inline styles to change the dimensions as needed. - -```jsx preview -<CSpinner size="sm" style={{ width: '3rem', height: '3rem'}}/> -<CSpinner size="sm" variant="grow" style={{ width: '3rem', height: '3rem'}}/> -``` - -## Buttons - -Use spinners within buttons to indicate an action is currently processing or taking place. You may also swap the text out of the spinner element and utilize button text as needed. - -```jsx preview -<CButton color="primary" disabled> - <CSpinner component="span" size="sm" aria-hidden="true" /> -</CButton> -<CButton color="primary" disabled> - <CSpinner component="span" size="sm" aria-hidden="true" /> - Loading... -</CButton> -``` - -```jsx preview -<CButton color="primary" disabled> - <CSpinner component="span" size="sm" variant="grow" aria-hidden="true" /> -</CButton> -<CButton color="primary" disabled> - <CSpinner component="span" size="sm" variant="grow" aria-hidden="true" /> - Loading... -</CButton> -``` - -## Customizing - -### CSS variables - -React spinners use local CSS variables on `.spinner-border` and `.spinner-grow` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -Border spinner variables: - -<ScssDocs file="_spinners.scss" capture="spinner-border-css-vars" /> - -Growing spinner variables: - -<ScssDocs file="_spinners.scss" capture="spinner-grow-css-vars" /> - -For both spinners, small spinner modifier classes are used to update the values of these CSS variables as needed. For example, the `.spinner-border-sm` class does the following: - -<ScssDocs file="_spinners.scss" capture="spinner-border-sm-css-vars" /> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CSpinner style={vars}>...</CSpinner> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="spinner-variables" /> - -### Keyframes - -Used for creating the CSS animations for our spinners. Included in `_spinners.scss`. - -<ScssDocs file="_spinners.scss" capture="spinner-border-keyframes" /> - -<ScssDocs file="_spinners.scss" capture="spinner-grow-keyframes" /> - -## API - -### CSpinner - -`markdown:CSpinner.api.mdx` \ No newline at end of file diff --git a/packages/docs/content/components/table.mdx b/packages/docs/content/components/table.mdx deleted file mode 100644 index a62cb451..00000000 --- a/packages/docs/content/components/table.mdx +++ /dev/null @@ -1,1663 +0,0 @@ ---- -title: React Table Component -name: Table -description: Documentation and examples for opt-in styling of tables. -menu: Components -route: /components/table -other_frameworks: table ---- - -import { - CBadge, - CTable, - CTableBody, - CTableCaption, - CTableDataCell, - CTableFoot, - CTableHead, - CTableHeaderCell, - CTableRow, -} from '@coreui/react/src/index' - -## How to use React Table Component - -Due to the widespread use of `<CTable>` elements across third-party widgets like calendars and date pickers, CoreUI's react tables are **opt-in**. All table styles are not inherited in CoreUI, meaning any nested tables can be styled independent from the parent. - -Using the most basic table CoreUI, here's how `<CTable>`-based tables look in CoreUI. - -export const TableExample = (props) => { - const columns = [ - { - key: 'id', - label: '#', - _props: { scope: 'col' }, - }, - { - key: 'class', - _props: { scope: 'col' }, - }, - { - key: 'heading_1', - label: 'Heading', - _props: { scope: 'col' }, - }, - { - key: 'heading_2', - label: 'Heading', - _props: { scope: 'col' }, - }, - ] - const items = [ - { - id: 1, - class: 'Mark', - heading_1: 'Otto', - heading_2: '@mdo', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 2, - class: 'Jacob', - heading_1: 'Thornton', - heading_2: '@fat', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 3, - class: 'Larry the Bird', - heading_2: '@twitter', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - }, - ] - return <CTable columns={columns} items={items} {...props} /> -} - -<Example className="rounded"> - <TableExample /> -</Example> - -In version **4.3.0** we introduced a new way to create a table, similarly to our [Smart Table component](https://coreui.io/react/docs/components/smart-table/). - -```jsx -const columns = [ - { - key: 'id', - label: '#', - _props: { scope: 'col' }, - }, - { - key: 'class', - _props: { scope: 'col' }, - }, - { - key: 'heading_1', - label: 'Heading', - _props: { scope: 'col' }, - }, - { - key: 'heading_2', - label: 'Heading', - _props: { scope: 'col' }, - }, -] -const items = [ - { - id: 1, - class: 'Mark', - heading_1: 'Otto', - heading_2: '@mdo', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 2, - class: 'Jacob', - heading_1: 'Thornton', - heading_2: '@fat', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 3, - class: 'Larry the Bird', - heading_2: '@twitter', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - }, -] -return <CTable columns={columns} items={items} /> -``` - -You can also put all table components together manually as hitherto. - -```jsx -<CTable> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan={2}>Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> -</CTable> -``` - -Both methods produce the same html code. - -## Variants - -Use contextual classes to color react tables, table rows or individual cells. - -export const VariantExample = () => { - const columns = [ - { key: 'class', _props: { scope: 'col' } }, - { key: 'heading_1', label: 'Heading', _props: { scope: 'col' } }, - { key: 'heading_2', label: 'Heading', _props: { scope: 'col' } }, - ] - const items = [ - { - class: 'Default', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - }, - { - class: 'Primary', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'primary' }, - }, - { - class: 'Secondary', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'secondary' }, - }, - { - class: 'Success', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'success' }, - }, - { - class: 'Danger', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'danger' }, - }, - { - class: 'Warning', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'warning' }, - }, - { - class: 'Info', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'info' }, - }, - { - class: 'Light', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'light' }, - }, - { - class: 'Dark', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'dark' }, - }, - ] - return <CTable columns={columns} items={items} /> -} - -<Example> - <VariantExample /> -</Example> - -```jsx -<CTable> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">Default</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="primary"> - <CTableHeaderCell scope="row">Primary</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="secondary"> - <CTableHeaderCell scope="row">Secondary</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="success"> - <CTableHeaderCell scope="row">Success</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="danger"> - <CTableHeaderCell scope="row">Danger</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="warning"> - <CTableHeaderCell scope="row">Warning</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="info"> - <CTableHeaderCell scope="row">Info</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="light"> - <CTableHeaderCell scope="row">Light</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="dark"> - <CTableHeaderCell scope="row">Dark</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - </CTableBody> -</CTable> -``` - -Since version **4.3.0** also this way. - -```jsx -const columns = [ - { key: 'class', _props: { scope: 'col' } }, - { key: 'heading_1', label: 'Heading', _props: { scope: 'col' } }, - { key: 'heading_2', label: 'Heading', _props: { scope: 'col' } }, -] -const items = [ - { - class: 'Default', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - }, - { - class: 'Primary', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'primary' }, - }, - { - class: 'Secondary', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'secondary' }, - }, - { - class: 'Success', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'success' }, - }, - { - class: 'Danger', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'danger' }, - }, - { - class: 'Warning', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'warning' }, - }, - { - class: 'Info', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'info' }, - }, - { - class: 'Light', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'light' }, - }, - { - class: 'Dark', - heading_1: 'Cell', - heading_2: 'Cell', - _cellProps: { class: { scope: 'row' } }, - _props: { color: 'dark' }, - }, -] -return <CTable columns={columns} items={items} /> -``` - -## Accented tables - -### Striped rows - -Use `striped` property to add zebra-striping to any react table row within the `<CTableBody>`. - -<Example> - <TableExample striped /> -</Example> - -```jsx -<CTable striped> - ... -</CTable> -``` - -### Striped columns - -Use `stripedColumns` boolean property to add zebra-striping to any table column. - -<Example> - <TableExample stripedColumns /> -</Example> - -```jsx -<CTable stripedColumns> - ... -</CTable> -``` - -These classes can also be added to react table variants: - -<Example> - <TableExample color="dark" striped /> -</Example> - -```jsx -<CTable color="dark" striped> - ... -</CTable> -``` - -<Example> - <TableExample color="dark" stripedColumns /> -</Example> - -```jsx -<CTable color="dark" stripedColumns> - ... -</CTable> -``` - -<Example> - <TableExample color="success" striped /> -</Example> - -```jsx -<CTable color="success" striped> - ... -</CTable> -``` - -<Example> - <TableExample color="success" stripedColumns /> -</Example> - -```jsx -<CTable color="success" stripedColumns> - ... -</CTable> -``` - -### Hoverable rows - -Use `hover` property to enable a hover state on react table rows within a `<CTableBody>`. - -<Example> - <TableExample hover /> -</Example> - -```jsx -<CTable hover> - ... -</CTable> -``` - -<Example> - <TableExample color="dark" hover /> -</Example> - -```jsx -<CTable color="dark" hover> - ... -</CTable> -``` - -These hoverable rows can also be combined with the striped variant: - -<Example> - <TableExample striped hover /> -</Example> - -```jsx -<CTable striped hover> - ... -</CTable> -``` - -### Active tables - -Highlight a table row or cell by adding a `active` property. - -export const ActiveTableExample = () => { - const columns = [ - { - key: 'id', - label: '#', - _props: { scope: 'col' }, - }, - { - key: 'class', - _props: { scope: 'col' }, - }, - { - key: 'heading_1', - label: 'Heading', - _props: { scope: 'col' }, - }, - { - key: 'heading_2', - label: 'Heading', - _props: { scope: 'col' }, - }, - ] - const items = [ - { - id: 1, - class: 'Mark', - heading_1: 'Otto', - heading_2: '@mdo', - _props: { active: true }, - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 2, - class: 'Jacob', - heading_1: 'Thornton', - heading_2: '@fat', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 3, - class: 'Larry the Bird', - heading_2: '@twitter', - _cellProps: { id: { scope: 'row' }, class: { active: true, colSpan: 2 } }, - }, - ] - return <CTable columns={columns} items={items} /> -} - -<Example className="rounded"> - <ActiveTableExample /> -</Example> - -As mentioned before since version **4.3.0** we have two ways to generate tables, also with custom properties for rows, and cells. - -```jsx -const columns = [ - { - key: 'id', - label: '#', - _props: { scope: 'col' }, - }, - { - key: 'class', - _props: { scope: 'col' }, - }, - { - key: 'heading_1', - label: 'Heading', - _props: { scope: 'col' }, - }, - { - key: 'heading_2', - label: 'Heading', - _props: { scope: 'col' }, - }, -] -const items = [ - { - id: 1, - class: 'Mark', - heading_1: 'Otto', - heading_2: '@mdo', - _props: { active: true }, - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 2, - class: 'Jacob', - heading_1: 'Thornton', - heading_2: '@fat', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 3, - class: 'Larry the Bird', - heading_2: '@twitter', - _cellProps: { id: { scope: 'row' }, class: { active: true, colSpan: 2 } }, - }, -] -return <CTable columns={columns} items={items} /> -``` - -```jsx -<CTable> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow active> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan={2} active> - Larry the Bird - </CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> -</CTable> -``` - -export const ActiveTableDarkExample = () => { - const columns = [ - { - key: 'id', - label: '#', - _props: { scope: 'col' }, - }, - { - key: 'class', - _props: { scope: 'col' }, - }, - { - key: 'heading_1', - label: 'Heading', - _props: { scope: 'col' }, - }, - { - key: 'heading_2', - label: 'Heading', - _props: { scope: 'col' }, - }, - ] - const items = [ - { - id: 1, - class: 'Mark', - heading_1: 'Otto', - heading_2: '@mdo', - _props: { active: true }, - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 2, - class: 'Jacob', - heading_1: 'Thornton', - heading_2: '@fat', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 3, - class: 'Larry the Bird', - heading_2: '@twitter', - _cellProps: { id: { scope: 'row' }, class: { active: true, colSpan: 2 } }, - }, - ] - return <CTable color="dark" columns={columns} items={items} /> -} - -<Example> - <ActiveTableDarkExample /> -</Example> - -```jsx -const columns = [ - { - key: 'id', - label: '#', - _props: { scope: 'col' }, - }, - { - key: 'class', - _props: { scope: 'col' }, - }, - { - key: 'heading_1', - label: 'Heading', - _props: { scope: 'col' }, - }, - { - key: 'heading_2', - label: 'Heading', - _props: { scope: 'col' }, - }, -] -const items = [ - { - id: 1, - class: 'Mark', - heading_1: 'Otto', - heading_2: '@mdo', - _props: { active: true }, - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 2, - class: 'Jacob', - heading_1: 'Thornton', - heading_2: '@fat', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 3, - class: 'Larry the Bird', - heading_2: '@twitter', - _cellProps: { id: { scope: 'row' }, class: { active: true, colSpan: 2 } }, - }, -] -return <CTable color="dark" columns={columns} items={items} /> -``` - -## Table borders - -### Bordered tables - -Add `bordered` property for borders on all sides of the table and cells. - -<Example> - <TableExample bordered /> -</Example> - -```jsx -<CTable bordered> - ... -</CTable> -``` - -[Border color utilities](https://coreui.io/docs/utilities/borders#border-color) can be added to change colors: - -<Example> - <TableExample bordered borderColor="primary" /> -</Example> - -```jsx -<CTable bordered borderColor="primary"> - ... -</CTable> -``` - -### Tables without borders - -Add `borderless` property for a react table without borders. - -<Example> - <TableExample borderless /> -</Example> - -```jsx -<CTable borderless> - ... -</CTable> -``` - -<Example> - <TableExample borderless color="dark" /> -</Example> - -```jsx -<CTable color="dark" borderless> - ... -</CTable> -``` - -## Small tables - -Add `small` property to make any `<CTable>` more compact by cutting all cell `padding` in half. - -<Example> - <TableExample small /> -</Example> - -```jsx -<CTable small> - ... -</CTable> -``` - -## Vertical alignment - -Table cells of `<CTableHead>` are always vertical aligned to the bottom. Table cells in `<CTableBody>` inherit their alignment from `<CTable>` and are aligned to the the top by default. Use the align property to re-align where needed. - -export const VerticalAlignmentExample = () => { - const columns = [ - { - key: 'heading_1', - _props: { className: 'w-25', scope: 'col' }, - }, - { - key: 'heading_2', - _props: { className: 'w-25', scope: 'col' }, - }, - { - key: 'heading_3', - _props: { className: 'w-25', scope: 'col' }, - }, - { - key: 'heading_4', - _props: { className: 'w-25', scope: 'col' }, - }, - ] - const items = [ - { - heading_1: <>This cell inherits <code>vertical-align: middle;</code> from the table</>, - heading_2: <>This cell inherits <code>vertical-align: middle;</code> from the table</>, - heading_3: <>This cell inherits <code>vertical-align: middle;</code> from the table</>, - heading_4: 'This here is some placeholder text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.', - }, - { - heading_1: <>This cell inherits <code>vertical-align: bottom;</code> from the table row</>, - heading_2: <>This cell inherits <code>vertical-align: bottom;</code> from the table row</>, - heading_3: <>This cell inherits <code>vertical-align: bottom;</code> from the table row</>, - heading_4: 'This here is some placeholder text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.', - _props: { align: 'bottom' } - }, - { - heading_1: <>This cell inherits <code>vertical-align: middle;</code> from the table</>, - heading_2: <>This cell inherits <code>vertical-align: middle;</code> from the table</>, - heading_3: 'This cell is aligned to the top.', - heading_4: 'This here is some placeholder text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.', - _cellProps: { heading_3: { align: 'top' }}, - }, - ] - return <CTable align="middle" columns={columns} items={items} /> -} - -<Example className="rounded"> - <VerticalAlignmentExample /> -</Example> - -In version **4.3.0** we introduced a new way to create a table, similarly to our [Smart Table component](https://coreui.io/react/docs/components/smart-table/). - -```jsx -const columns = [ - { - key: 'heading_1', - _props: { className: 'w-25', scope: 'col' }, - }, - { - key: 'heading_2', - _props: { className: 'w-25', scope: 'col' }, - }, - { - key: 'heading_3', - _props: { className: 'w-25', scope: 'col' }, - }, - { - key: 'heading_4', - _props: { className: 'w-25', scope: 'col' }, - }, -] -const items = [ - { - heading_1: <>This cell inherits <code>vertical-align: middle;</code> from the table</>, - heading_2: <>This cell inherits <code>vertical-align: middle;</code> from the table</>, - heading_3: <>This cell inherits <code>vertical-align: middle;</code> from the table</>, - heading_4: 'This here is some placeholder text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.', - }, - { - heading_1: <>This cell inherits <code>vertical-align: bottom;</code> from the table row</>, - heading_2: <>This cell inherits <code>vertical-align: bottom;</code> from the table row</>, - heading_3: <>This cell inherits <code>vertical-align: bottom;</code> from the table row</>, - heading_4: 'This here is some placeholder text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.', - _props: { align: 'bottom' } - }, - { - heading_1: <>This cell inherits <code>vertical-align: middle;</code> from the table</>, - heading_2: <>This cell inherits <code>vertical-align: middle;</code> from the table</>, - heading_3: 'This cell is aligned to the top.', - heading_4: 'This here is some placeholder text, intended to take up quite a bit of vertical space, to demonstrate how the vertical alignment works in the preceding cells.', - _cellProps: { heading_3: { align: 'top' }}, - }, -] -return <CTable align="middle" columns={columns} items={items} /> -``` - -You can also put all table components together manually as hitherto. - -```jsx -<CTable align="middle" responsive> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col" className="w-25"> - Heading 1 - </CTableHeaderCell> - <CTableHeaderCell scope="col" className="w-25"> - Heading 2 - </CTableHeaderCell> - <CTableHeaderCell scope="col" className="w-25"> - Heading 3 - </CTableHeaderCell> - <CTableHeaderCell scope="col" className="w-25"> - Heading 4 - </CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableDataCell> - This cell inherits <code>vertical-align: middle;</code> from the table - </CTableDataCell> - <CTableDataCell> - This cell inherits <code>vertical-align: middle;</code> from the table - </CTableDataCell> - <CTableDataCell> - This cell inherits <code>vertical-align: middle;</code> from the table - </CTableDataCell> - <CTableDataCell> - This here is some placeholder text, intended to take up quite a bit of vertical space, to - demonstrate how the vertical alignment works in the preceding cells. - </CTableDataCell> - </CTableRow> - <CTableRow align="bottom"> - <CTableDataCell> - This cell inherits <code>vertical-align: bottom;</code> from the table row - </CTableDataCell> - <CTableDataCell> - This cell inherits <code>vertical-align: bottom;</code> from the table row - </CTableDataCell> - <CTableDataCell> - This cell inherits <code>vertical-align: bottom;</code> from the table row - </CTableDataCell> - <CTableDataCell> - This here is some placeholder text, intended to take up quite a bit of vertical space, to - demonstrate how the vertical alignment works in the preceding cells. - </CTableDataCell> - </CTableRow> - <CTableRow> - <CTableDataCell> - This cell inherits <code>vertical-align: middle;</code> from the table - </CTableDataCell> - <CTableDataCell> - This cell inherits <code>vertical-align: middle;</code> from the table - </CTableDataCell> - <CTableDataCell align="top">This cell is aligned to the top.</CTableDataCell> - <CTableDataCell> - This here is some placeholder text, intended to take up quite a bit of vertical space, to - demonstrate how the vertical alignment works in the preceding cells. - </CTableDataCell> - </CTableRow> - </CTableBody> -</CTable> -``` - -## Nesting - -Border styles, active styles, and react table component variants are not inherited by nested tables. - -<Example> - {<CTable striped> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell colSpan={4}> - <CTable> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">Header</CTableHeaderCell> - <CTableHeaderCell scope="col">Header</CTableHeaderCell> - <CTableHeaderCell scope="col">Header</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">A</CTableHeaderCell> - <CTableDataCell>First</CTableDataCell> - <CTableDataCell>Last</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">B</CTableHeaderCell> - <CTableDataCell>First</CTableDataCell> - <CTableDataCell>Last</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">C</CTableHeaderCell> - <CTableDataCell>First</CTableDataCell> - <CTableDataCell>Last</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </CTableHeaderCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan={2}>Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable>} -</Example> - -```jsx -<CTable striped> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell colSpan={4}> - <CTable> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">Header</CTableHeaderCell> - <CTableHeaderCell scope="col">Header</CTableHeaderCell> - <CTableHeaderCell scope="col">Header</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">A</CTableHeaderCell> - <CTableDataCell>First</CTableDataCell> - <CTableDataCell>Last</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">B</CTableHeaderCell> - <CTableDataCell>First</CTableDataCell> - <CTableDataCell>Last</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">C</CTableHeaderCell> - <CTableDataCell>First</CTableDataCell> - <CTableDataCell>Last</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </CTableHeaderCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan={2}>Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> -</CTable> -``` - -## Anatomy - -### Table head - -Similar to tables and dark tables, use the modifier prop `color="light"` or `color="dark"` to make `<CTableHead>`s appear light or dark gray. - -<Example> - <TableExample tableHeadProps={{ color: 'light' }} /> -</Example> - -```jsx -<CTable> - <CTableHead color="light"> - ... - </CTableHead> - <CTableBody> - ... - </CTableBody> -</CTable> -``` - -If you generate a table using the new method incorporated in version **4.3.0**, you have to use `tableHeadProps` property to pass properties to the table header component. - -```jsx -const columns = [...] -const items = [...] - -return <CTable columns={columns} items={items} tableHeadProps={{ color: 'light' }} /> -``` - -<Example> - <TableExample tableHeadProps={{ color: 'dark' }} /> -</Example> - -```jsx -<CTable> - <CTableHead color="dark"> - ... - </CTableHead> - <CTableBody> - ... - </CTableBody> -</CTable> -``` - -Starting from version **4.3.0** also this way. - -```jsx -const columns = [...] -const items = [...] - -return <CTable columns={columns} items={items} tableHeadProps={{ color: 'dark' }} /> -``` - -### Table foot - -export const TableFoodExample = () => { - const columns = [ - { - key: 'id', - label: '#', - _props: { scope: 'col' }, - }, - { - key: 'class', - _props: { scope: 'col' }, - }, - { - key: 'heading_1', - label: 'Heading', - _props: { scope: 'col' }, - }, - { - key: 'heading_2', - label: 'Heading', - _props: { scope: 'col' }, - }, - ] - const footer = [ - 'Footer', - 'Footer', - 'Footer', - 'Footer', - ] - const items = [ - { - id: 1, - class: 'Mark', - heading_1: 'Otto', - heading_2: '@mdo', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 2, - class: 'Jacob', - heading_1: 'Thornton', - heading_2: '@fat', - _cellProps: { id: { scope: 'row' } }, - }, - { - id: 3, - class: 'Larry the Bird', - heading_2: '@twitter', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - }, - ] - return <CTable columns={columns} footer={footer} items={items} tableHeadProps={{ color: 'light' }} /> -} - -<Example> - <TableFoodExample /> -</Example> - -```jsx -<CTable> - <CTableHead color="light"> - ... - </CTableHead> - <CTableBody> - ... - <CTableHead> - <CTableRow> - <CTableDataCell>Footer</CTableDataCell> - <CTableDataCell>Footer</CTableDataCell> - <CTableDataCell>Footer</CTableDataCell> - <CTableDataCell>Footer</CTableDataCell> - </CTableRow> - </CTableHead> -</CTable> -``` - -Starting from version **4.3.0** also this way. - -```jsx -const columns = [...] -const footer = [ - 'Footer', - 'Footer', - 'Footer', - 'Footer', -] -const items = [...] - -return <CTable columns={columns} footer={footer} items={items} tableHeadProps={{ color: 'light' }}/> -``` - -### Captions - -A `<CTableCaption>` functions like a heading for a table. It helps users with screen readers to find a table and understand what it's about and decide if they want to read it. - -<Example> - <TableExample caption="List of users" /> -</Example> - -```jsx -<CTable> - <CTableCaption>List of users</CTableCaption> - <CTableHead> - ... - </CTableHead> - <CTableBody> - ... - </CTableBody> -</CTable> -``` - -Starting from version **4.3.0** also this way. - -```jsx -const columns = [...] -const items = [...] - -return <CTable caption="List of users" columns={columns} items={items} /> -``` - -You can also put the `<CTableCaption>` on the top of the table with `caption="top"`. - -<Example> - <TableExample captionTop="List of users" /> -</Example> - -```jsx -<CTable caption="top"> - <CTableCaption>List of users</CTableCaption> - <CTableHead> - ... - </CTableHead> - <CTableBody> - ... - </CTableBody> -</CTable> -``` - -Since version **4.3.0** also this way. - -```jsx -const columns = [...] -const items = [...] - -return <CTable captionTop="List of users" columns={columns} items={items} /> -``` - -## Responsive tables - -Responsive tables allow tables to be scrolled horizontally with ease. Make any table responsive across all viewports by adding a `responsive` property. Or, pick a maximum breakpoint with which to have a responsive table up to by using `responsive="{-sm|-md|-lg|-xl|-xxl}"`. - -<Example> - {<CTable responsive> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable>} -</Example> - -```jsx -<CTable responsive> - ... -</CTable> -``` - -<Example> - {<CTable responsive="sm"> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable>} -</Example> - -```jsx -<CTable responsive="sm"> - ... -</CTable> -``` - -<Example> - {<CTable responsive="md"> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable>} -</Example> - -```jsx -<CTable responsive="md"> - ... -</CTable> -``` - -<Example> - {<CTable responsive="lg"> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable>} -</Example> - -```jsx -<CTable responsive="lg"> - ... -</CTable> -``` - -<Example> - {<CTable responsive="xl"> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable>} -</Example> - -```jsx -<CTable responsive="xl"> - ... -</CTable> -``` - -<Example> - {<CTable responsive="xxl"> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable>} -</Example> - -```jsx -<CTable responsive="xxl"> - ... -</CTable> -``` - -## API - -### CTable - -`markdown:CTable.api.mdx` - -### CTableBody - -`markdown:CTableBody.api.mdx` - -### CTableDataCell - -`markdown:CTableDataCell.api.mdx` - -### CTableFoot - -`markdown:CTableFoot.api.mdx` - -### CTableHead - -`markdown:CTableHead.api.mdx` - -### CTableHeaderCell - -`markdown:CTableHeaderCell.api.mdx` - -### CTableRow - -`markdown:CTableRow.api.mdx` diff --git a/packages/docs/content/components/toast.mdx b/packages/docs/content/components/toast.mdx deleted file mode 100644 index ee5ddfcc..00000000 --- a/packages/docs/content/components/toast.mdx +++ /dev/null @@ -1,281 +0,0 @@ ---- -title: React Toast Component -name: Toast -description: Push notifications to your visitors with a toast, a lightweight and easily customizable alert message. -menu: Components -route: /components/toast -other_frameworks: toast ---- - -import { useState, useRef } from 'react' -import { - CButton, - CCloseButton, - CToast, - CToastBody, - CToastClose, - CToastHeader, - CToaster, -} from '@coreui/react/src/index' - -React toasts are lightweight notifications designed to mimic the push notifications that have been popularized by mobile and desktop operating systems. They’re built with flexbox, so they’re easy to align and position. - -## Overview - -Things to know when using the toast plugin: - -- Toasts are opt-in for performance reasons, so **you must initialize them yourself**. -- Toasts will automatically hide if you do not specify `autohide: false`. - -## Examples - -### Basic - -To encourage extensible and predictable toasts, we recommend a header and body. Toast headers use `display: flex`, allowing easy alignment of content thanks to our margin and flexbox utilities. - -Toasts are as flexible as you need and have very little required markup. At a minimum, we require a single element to contain your "toasted" content and strongly encourage a dismiss button. - -```jsx preview -<CToast animation={false} autohide={false} visible={true}> - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <div className="fw-bold me-auto">CoreUI for React.js</div> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> -</CToast> -``` - -export const BasicExample = () => { - const [toast, addToast] = useState(0) - const toaster = useRef() - const exampleToast = ( - <CToast> - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <div className="fw-bold me-auto">CoreUI for React.js</div> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - </CToast> - ) - return ( - <> - <CButton color="primary" onClick={() => addToast(exampleToast)}>Send a toast</CButton> - <CToaster className="p-3" placement="top-end" push={toast} ref={toaster} /> - </> - ) -} - -<Example> - <BasicExample /> -</Example> - -```jsx -const [toast, addToast] = useState(0) -const toaster = useRef() -const exampleToast = ( - <CToast> - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <div className="fw-bold me-auto">CoreUI for React.js</div> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - </CToast> -) -return ( - <> - <CButton color="primary" onClick={() => addToast(exampleToast)}>Send a toast</CButton> - <CToaster className="p-3" placement="top-end" push={toast} ref={toaster} /> - </> -) -``` - -### Translucent - -Toasts are slightly translucent to blend in with what's below them. - -```jsx preview className="bg-dark border-0" -<CToast autohide={false} visible={true}> - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <div className="fw-bold me-auto">CoreUI for React.js</div> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> -</CToast> -``` - -### Stacking - -You can stack toasts by wrapping them in a toast container, which will vertically add some spacing. - -```jsx preview -<CToaster className="position-static"> - <CToast autohide={false} visible={true}> - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <div className="fw-bold me-auto">CoreUI for React.js</div> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - </CToast> - <CToast autohide={false} visible={true}> - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <div className="fw-bold me-auto">CoreUI for React.js</div> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - </CToast> -</CToaster> -``` - -### Custom content - -Customize your toasts by removing sub-components, tweaking them with [utilities](https://coreui.io/docs/utilities/api), or by adding your own markup. Here we've created a simpler toast by removing the default `<CToastHeader>`, adding a custom hide icon from [CoreUI Icons](https://icons.coreui.io), and using some [flexbox utilities](https://coreui.io/docs/utilities/flex) to adjust the layout. - -```jsx preview -<CToast autohide={false} visible={true} className="align-items-center"> - <div className="d-flex"> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - <CToastClose className="me-2 m-auto" /> - </div> -</CToast> -``` - -Alternatively, you can also add additional controls and components to toasts. - -```jsx preview -<CToast autohide={false} visible={true}> - <CToastBody> - Hello, world! This is a toast message. - <div className="mt-2 pt-2 border-top"> - <CButton type="button" color="primary" size="sm"> - Take action - </CButton> - <CToastClose component={CButton} color="secondary" size="sm" className="ms-1"> - Close - </CToastClose> - </div> - </CToastBody> -</CToast> -``` - -### Color schemes - -Building on the above example, you can create different toast color schemes with our [color](https://coreui.io/docs/utilities/colors) and [background](https://coreui.io/docs//utilities/background) utilities. Here we've set `color="primary"` and added `.text-white` class to the `<Ctoast>`, and then set `white` property to our close button. For a crisp edge, we remove the default border with `.border-0`. - -```jsx preview -<CToast autohide={false} visible={true} color="primary" className="text-white align-items-center"> - <div className="d-flex"> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - <CToastClose className="me-2 m-auto" white /> - </div> -</CToast> -``` - -## Customizing - -### CSS variables - -React toasts use local CSS variables on `.toast` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_toasts.scss" capture="toast-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CToast style={vars}>...</CToast> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="toast-variables"/> - -## API - -### CToast - -`markdown:CToast.api.mdx` - -### CToastHeader - -`markdown:CToastHeader.api.mdx` - -### CToastBody - -`markdown:CToastBody.api.mdx` - -### CToastClose - -`markdown:CToastClose.api.mdx` - -### CToaster - -`markdown:CToaster.api.mdx` diff --git a/packages/docs/content/components/tooltip.mdx b/packages/docs/content/components/tooltip.mdx deleted file mode 100644 index 6c148a82..00000000 --- a/packages/docs/content/components/tooltip.mdx +++ /dev/null @@ -1,191 +0,0 @@ ---- -title: React Tooltip Component -name: Tooltip -description: Documentation and examples for adding React Tooltips. -menu: Components -route: /components/tooltip -other_frameworks: tooltip ---- - -import { CTooltip, CButton, CLink } from '@coreui/react/src/index' - -## Examples - -### Tooltips on links - -Hover over the links below to see tooltips: - -<Example className="text-body-secondary"> - Tight pants next level keffiyeh <CTooltip content="Tooltip text"><CLink>you probably</CLink></CTooltip> - haven't heard of them. Photo booth beard raw denim letterpress vegan messenger bag stumptown. - Farm-to-table seitan, mcsweeney's fixie sustainable quinoa 8-bit american apparel <CTooltip content="Tooltip text"><CLink>have a</CLink></CTooltip> - terry richardson vinyl chambray. Beard stumptown, cardigans banh mi lomo thundercats. Tofu - biodiesel williamsburg marfa, four loko mcsweeney''s cleanse vegan chambray. A really ironic - artisan <CTooltip content="Tooltip text"><CLink>whatever keytar</CLink></CTooltip> - scenester farm-to-table banksy Austin <CTooltip content="Tooltip text"><CLink>twitter handle</CLink></CTooltip> - freegan cred raw denim single-origin coffee viral. -</Example> - - -```jsx -<p className="text-body-secondary"> - Tight pants next level keffiyeh - <CTooltip content="Tooltip text"> - <CLink> you probably </CLink> - </CTooltip> - haven't heard of them. Photo booth beard raw denim letterpress vegan messenger bag stumptown. - Farm-to-table seitan, mcsweeney's fixie sustainable quinoa 8-bit american apparel - <CTooltip content="Tooltip text"> - <CLink> have a </CLink> - </CTooltip> - terry richardson vinyl chambray. Beard stumptown, cardigans banh mi lomo thundercats. Tofu - biodiesel williamsburg marfa, four loko mcsweeney''s cleanse vegan chambray. A really ironic - artisan - <CTooltip content="Tooltip text"> - <CLink> whatever keytar </CLink> - </CTooltip> - scenester farm-to-table banksy Austin - <CTooltip content="Tooltip text"> - <CLink> twitter handle </CLink> - </CTooltip> - freegan cred raw denim single-origin coffee viral. -</p> -``` - -### Custom tooltips - -You can customize the appearance of tooltips using [CSS variables](#css-variables). We set a custom `style` to scope our custom appearance and use it to override some of the local CSS variables. - -export const CustomTooltipsExample = () => { - const customTooltipStyle = { - '--cui-tooltip-bg': 'var(--cui-primary)', - } - return ( - <CTooltip - content="This top tooltip is themed via CSS variables." - placement="top" - style={customTooltipStyle} - > - <CButton color="secondary">Custom tooltip</CButton> - </CTooltip> - ) -} - -<Example> - <CustomTooltipsExample /> -</Example> -```jsx -const customTooltipStyle = { - '--cui-tooltip-bg': 'var(--cui-primary)', -} -return ( - <CTooltip - content="This top tooltip is themed via CSS variables." - placement="top" - style={customTooltipStyle} - > - <CButton color="secondary">Custom tooltip</CButton> - </CTooltip> -) -``` - -### Directions - -Hover over the buttons below to see the four tooltips directions: top, right, bottom, and left. Directions are mirrored when using CoreUI in RTL. - -<Example> - <CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." placement="top"> - <CButton color="secondary">Tooltip on top</CButton> - </CTooltip> - <CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." placement="right"> - <CButton color="secondary">Tooltip on right</CButton> - </CTooltip> - <CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." placement="bottom"> - <CButton color="secondary">Tooltip on bottom</CButton> - </CTooltip> - <CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." placement="left"> - <CButton color="secondary">Tooltip on left</CButton> - </CTooltip> -</Example> - -```jsx -<CTooltip - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="top" -> - <CButton color="secondary">Tooltip on top</CButton> -</CTooltip> -<CTooltip - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="right" -> - <CButton color="secondary">Tooltip on right</CButton> -</CTooltip> -<CTooltip - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="bottom" -> - <CButton color="secondary">Tooltip on bottom</CButton> -</CTooltip> -<CTooltip - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="left" -> - <CButton color="secondary">Tooltip on left</CButton> -</CTooltip> -``` - -## Usage - -### Disabled elements - -Elements with the disabled attribute aren’t interactive, meaning users cannot focus, hover, or click them to trigger a tooltip (or popover). As a workaround, you’ll want to trigger the tooltip from a wrapper `<div>` or `<span>`, ideally made keyboard-focusable using `tabindex="0"`. - -<Example> - <CTooltip - content="Disabled tooltip" - trigger={['hover', 'focus']} - > - <span className="d-inline-block" tabIndex={0}> - <CButton color="primary" disabled>Disabled button</CButton> - </span> - </CTooltip> -</Example> -```jsx -<CTooltip - content="Disabled tooltip" - trigger={['hover', 'focus']} -> - <span className="d-inline-block" tabIndex={0}> - <CButton color="primary" disabled>Disabled button</CButton> - </span> -</CTooltip> -``` - -## Customizing - -### CSS variables - -React toltips use local CSS variables on `.tooltip` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_tooltip.scss" capture="tooltip-css-vars"/> - -#### How to use CSS variables - -```jsx -const vars = { - '--my-css-var': 10, - '--my-another-css-var': "red" -} -return <CTooltip style={vars}>...</CTooltip> -``` - -### SASS variables - -<ScssDocs file="_variables.scss" capture="tooltip-variables"/> - -## API - -### CTooltip - -`markdown:CTooltip.api.mdx` diff --git a/packages/docs/content/components/widgets.mdx b/packages/docs/content/components/widgets.mdx deleted file mode 100644 index 1881b4e9..00000000 --- a/packages/docs/content/components/widgets.mdx +++ /dev/null @@ -1,1450 +0,0 @@ ---- -title: React Widgets -name: Widgets -description: React widget components give information about the app statistics. -menu: Components -route: /components/widgets ---- - -import CIcon from '@coreui/icons-react' -import { - cibFacebook, - cibTwitter, - cilArrowRight, - cilArrowTop, - cilChartPie, - cilOptions, -} from '@coreui/icons' -import { CChartBar, CChartLine } from '@coreui/react-chartjs/src/index.ts' - -import { - CCol, - CDropdown, - CDropdownItem, - CDropdownMenu, - CDropdownToggle, - CLink, - CRow, - CWidgetStatsA, - CWidgetStatsB, - CWidgetStatsC, - CWidgetStatsD, - CWidgetStatsE, - CWidgetStatsF, -} from '@coreui/react/src/index' - -## CWidgetStatsA - -<Example> - <CRow> - <CCol sm={6}> - <CWidgetStatsA - className="mb-4" - color="primary" - value={ - <> - $9.000{' '} - <span className="fs-6 fw-normal"> - (40.9% <CIcon icon={cilArrowTop} />) - </span> - </> - } - title="Widget title" - action={ - <CDropdown alignment="end"> - <CDropdownToggle color="transparent" caret={false} className="p-0"> - <CIcon icon={cilOptions} className="text-white" /> - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>Action</CDropdownItem> - <CDropdownItem>Another action</CDropdownItem> - <CDropdownItem>Something else here...</CDropdownItem> - <CDropdownItem disabled>Disabled action</CDropdownItem> - </CDropdownMenu> - </CDropdown> - } - chart={ - <CChartLine - className="mt-3 mx-3" - style={{ height: '70px' }} - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'transparent', - borderColor: 'rgba(255,255,255,.55)', - pointBackgroundColor: '#5856d6', - data: [65, 59, 84, 84, 51, 55, 40], - }, - ], - }} - options={{ - plugins: { - legend: { - display: false, - }, - }, - maintainAspectRatio: false, - scales: { - x: { - grid: { - display: false, - drawBorder: false, - }, - ticks: { - display: false, - }, - }, - y: { - min: 30, - max: 89, - display: false, - grid: { - display: false, - }, - ticks: { - display: false, - }, - }, - }, - elements: { - line: { - borderWidth: 1, - tension: 0.4, - }, - point: { - radius: 4, - hitRadius: 10, - hoverRadius: 4, - }, - }, - }} - /> - } - /> - </CCol> - <CCol sm={6}> - <CWidgetStatsA - className="mb-4" - color="info" - value={ - <> - $9.000{' '} - <span className="fs-6 fw-normal"> - (40.9% <CIcon icon={cilArrowTop} />) - </span> - </> - } - title="Widget title" - action={ - <CDropdown alignment="end"> - <CDropdownToggle color="transparent" caret={false} className="p-0"> - <CIcon icon={cilOptions} className="text-white" /> - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>Action</CDropdownItem> - <CDropdownItem>Another action</CDropdownItem> - <CDropdownItem>Something else here...</CDropdownItem> - <CDropdownItem disabled>Disabled action</CDropdownItem> - </CDropdownMenu> - </CDropdown> - } - chart={ - <CChartLine - className="mt-3 mx-3" - style={{ height: '70px' }} - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'transparent', - borderColor: 'rgba(255,255,255,.55)', - pointBackgroundColor: '#39f', - data: [1, 18, 9, 17, 34, 22, 11], - }, - ], - }} - options={{ - plugins: { - legend: { - display: false, - }, - }, - maintainAspectRatio: false, - scales: { - x: { - grid: { - display: false, - drawBorder: false, - }, - ticks: { - display: false, - }, - }, - y: { - min: -9, - max: 39, - display: false, - grid: { - display: false, - }, - ticks: { - display: false, - }, - }, - }, - elements: { - line: { - borderWidth: 1, - }, - point: { - radius: 4, - hitRadius: 10, - hoverRadius: 4, - }, - }, - }} - /> - } - /> - </CCol> - <CCol sm={6}> - <CWidgetStatsA - className="mb-4" - color="warning" - value={ - <> - $9.000{' '} - <span className="fs-6 fw-normal"> - (40.9% <CIcon icon={cilArrowTop} />) - </span> - </> - } - title="Widget title" - action={ - <CDropdown alignment="end"> - <CDropdownToggle color="transparent" caret={false} className="p-0"> - <CIcon icon={cilOptions} className="text-white" /> - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>Action</CDropdownItem> - <CDropdownItem>Another action</CDropdownItem> - <CDropdownItem>Something else here...</CDropdownItem> - <CDropdownItem disabled>Disabled action</CDropdownItem> - </CDropdownMenu> - </CDropdown> - } - chart={ - <CChartLine - className="mt-3" - style={{ height: '70px' }} - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'rgba(255,255,255,.2)', - borderColor: 'rgba(255,255,255,.55)', - data: [78, 81, 80, 45, 34, 12, 40], - fill: true, - }, - ], - }} - options={{ - plugins: { - legend: { - display: false, - }, - }, - maintainAspectRatio: false, - scales: { - x: { - display: false, - }, - y: { - display: false, - }, - }, - elements: { - line: { - borderWidth: 2, - tension: 0.4, - }, - point: { - radius: 0, - hitRadius: 10, - hoverRadius: 4, - }, - }, - }} - /> - } - /> - </CCol> - <CCol sm={6}> - <CWidgetStatsA - className="mb-4" - color="danger" - value={ - <> - $9.000{' '} - <span className="fs-6 fw-normal"> - (40.9% <CIcon icon={cilArrowTop} />) - </span> - </> - } - title="Widget title" - action={ - <CDropdown alignment="end"> - <CDropdownToggle color="transparent" caret={false} className="p-0"> - <CIcon icon={cilOptions} className="text-white" /> - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>Action</CDropdownItem> - <CDropdownItem>Another action</CDropdownItem> - <CDropdownItem>Something else here...</CDropdownItem> - <CDropdownItem disabled>Disabled action</CDropdownItem> - </CDropdownMenu> - </CDropdown> - } - chart={ - <CChartBar - className="mt-3 mx-3" - style={{ height: '70px' }} - data={{ - labels: [ - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December', - 'January', - 'February', - 'March', - 'April', - ], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'rgba(255,255,255,.2)', - borderColor: 'rgba(255,255,255,.55)', - data: [78, 81, 80, 45, 34, 12, 40, 85, 65, 23, 12, 98, 34, 84, 67, 82], - barPercentage: 0.6, - }, - ], - }} - options={{ - maintainAspectRatio: false, - plugins: { - legend: { - display: false, - }, - }, - scales: { - x: { - grid: { - display: false, - drawTicks: false, - }, - ticks: { - display: false, - }, - }, - y: { - grid: { - display: false, - drawBorder: false, - drawTicks: false, - }, - ticks: { - display: false, - }, - }, - }, - }} - /> - } - /> - </CCol> - </CRow> -</Example> - -```jsx -<CRow> - <CCol sm={6}> - <CWidgetStatsA - className="mb-4" - color="primary" - value={ - <> - $9.000{' '} - <span className="fs-6 fw-normal"> - (40.9% <CIcon icon={cilArrowTop} />) - </span> - </> - } - title="Widget title" - action={ - <CDropdown alignment="end"> - <CDropdownToggle color="transparent" caret={false} className="p-0"> - <CIcon icon={cilOptions} className="text-white" /> - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>Action</CDropdownItem> - <CDropdownItem>Another action</CDropdownItem> - <CDropdownItem>Something else here...</CDropdownItem> - <CDropdownItem disabled>Disabled action</CDropdownItem> - </CDropdownMenu> - </CDropdown> - } - chart={ - <CChartLine - className="mt-3 mx-3" - style={{ height: '70px' }} - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'transparent', - borderColor: 'rgba(255,255,255,.55)', - pointBackgroundColor: '#321fdb', - data: [65, 59, 84, 84, 51, 55, 40], - }, - ], - }} - options={{ - plugins: { - legend: { - display: false, - }, - }, - maintainAspectRatio: false, - scales: { - x: { - grid: { - display: false, - drawBorder: false, - }, - ticks: { - display: false, - }, - }, - y: { - min: 30, - max: 89, - display: false, - grid: { - display: false, - }, - ticks: { - display: false, - }, - }, - }, - elements: { - line: { - borderWidth: 1, - tension: 0.4, - }, - point: { - radius: 4, - hitRadius: 10, - hoverRadius: 4, - }, - }, - }} - /> - } - /> - </CCol> - <CCol sm={6}> - <CWidgetStatsA - className="mb-4" - color="info" - value={ - <> - $9.000{' '} - <span className="fs-6 fw-normal"> - (40.9% <CIcon icon={cilArrowTop} />) - </span> - </> - } - title="Widget title" - action={ - <CDropdown alignment="end"> - <CDropdownToggle color="transparent" caret={false} className="p-0"> - <CIcon icon={cilOptions} className="text-white" /> - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>Action</CDropdownItem> - <CDropdownItem>Another action</CDropdownItem> - <CDropdownItem>Something else here...</CDropdownItem> - <CDropdownItem disabled>Disabled action</CDropdownItem> - </CDropdownMenu> - </CDropdown> - } - chart={ - <CChartLine - className="mt-3 mx-3" - style={{ height: '70px' }} - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'transparent', - borderColor: 'rgba(255,255,255,.55)', - pointBackgroundColor: '#39f', - data: [1, 18, 9, 17, 34, 22, 11], - }, - ], - }} - options={{ - plugins: { - legend: { - display: false, - }, - }, - maintainAspectRatio: false, - scales: { - x: { - grid: { - display: false, - drawBorder: false, - }, - ticks: { - display: false, - }, - }, - y: { - min: -9, - max: 39, - display: false, - grid: { - display: false, - }, - ticks: { - display: false, - }, - }, - }, - elements: { - line: { - borderWidth: 1, - }, - point: { - radius: 4, - hitRadius: 10, - hoverRadius: 4, - }, - }, - }} - /> - } - /> - </CCol> - <CCol sm={6}> - <CWidgetStatsA - className="mb-4" - color="warning" - value={ - <> - $9.000{' '} - <span className="fs-6 fw-normal"> - (40.9% <CIcon icon={cilArrowTop} />) - </span> - </> - } - title="Widget title" - action={ - <CDropdown alignment="end"> - <CDropdownToggle color="transparent" caret={false} className="p-0"> - <CIcon icon={cilOptions} className="text-white" /> - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>Action</CDropdownItem> - <CDropdownItem>Another action</CDropdownItem> - <CDropdownItem>Something else here...</CDropdownItem> - <CDropdownItem disabled>Disabled action</CDropdownItem> - </CDropdownMenu> - </CDropdown> - } - chart={ - <CChartLine - className="mt-3" - style={{ height: '70px' }} - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'rgba(255,255,255,.2)', - borderColor: 'rgba(255,255,255,.55)', - data: [78, 81, 80, 45, 34, 12, 40], - fill: true, - }, - ], - }} - options={{ - plugins: { - legend: { - display: false, - }, - }, - maintainAspectRatio: false, - scales: { - x: { - display: false, - }, - y: { - display: false, - }, - }, - elements: { - line: { - borderWidth: 2, - tension: 0.4, - }, - point: { - radius: 0, - hitRadius: 10, - hoverRadius: 4, - }, - }, - }} - /> - } - /> - </CCol> - <CCol sm={6}> - <CWidgetStatsA - className="mb-4" - color="danger" - value={ - <> - $9.000{' '} - <span className="fs-6 fw-normal"> - (40.9% <CIcon icon={cilArrowTop} />) - </span> - </> - } - title="Widget title" - action={ - <CDropdown alignment="end"> - <CDropdownToggle color="transparent" caret={false} className="p-0"> - <CIcon icon={cilOptions} className="text-white" /> - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>Action</CDropdownItem> - <CDropdownItem>Another action</CDropdownItem> - <CDropdownItem>Something else here...</CDropdownItem> - <CDropdownItem disabled>Disabled action</CDropdownItem> - </CDropdownMenu> - </CDropdown> - } - chart={ - <CChartBar - className="mt-3 mx-3" - style={{ height: '70px' }} - data={{ - labels: [ - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December', - 'January', - 'February', - 'March', - 'April', - ], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'rgba(255,255,255,.2)', - borderColor: 'rgba(255,255,255,.55)', - data: [78, 81, 80, 45, 34, 12, 40, 85, 65, 23, 12, 98, 34, 84, 67, 82], - barPercentage: 0.6, - }, - ], - }} - options={{ - maintainAspectRatio: false, - plugins: { - legend: { - display: false, - }, - }, - scales: { - x: { - grid: { - display: false, - drawTicks: false, - }, - ticks: { - display: false, - }, - }, - y: { - grid: { - display: false, - drawBorder: false, - drawTicks: false, - }, - ticks: { - display: false, - }, - }, - }, - }} - /> - } - /> - </CCol> -</CRow> -``` - -## CWidgetStatsB - -<Example> - <CRow> - <CCol xs={6}> - <CWidgetStatsB - className="mb-3" - progress={{ color: 'success', value: 75 }} - text="Widget helper text" - title="Widget title" - value="89.9%" - /> - </CCol> - <CCol xs={6}> - <CWidgetStatsB - className="mb-3" - color="primary" - inverse - progress={{ value: 75 }} - text="Widget helper text" - title="Widget title" - value="89.9%" - /> - </CCol> - </CRow> -</Example> - -```jsx -<CRow> - <CCol xs={6}> - <CWidgetStatsB - className="mb-3" - progress={{ color: 'success', value: 75 }} - text="Widget helper text" - title="Widget title" - value="89.9%" - /> - </CCol> - <CCol xs={6}> - <CWidgetStatsB - className="mb-3" - color="primary" - inverse - progress={{ value: 75 }} - text="Widget helper text" - title="Widget title" - value="89.9%" - /> - </CCol> -</CRow> -``` - -## CWidgetStatsC - -<Example> - <CRow> - <CCol xs={6}> - <CWidgetStatsC - className="mb-3" - icon={<CIcon icon={cilChartPie} height={36} />} - progress={{ color: 'success', value: 75 }} - text="Widget helper text" - title="Widget title" - value="89.9%" - /> - </CCol> - <CCol xs={6}> - <CWidgetStatsC - className="mb-3" - icon={<CIcon icon={cilChartPie} height={36} />} - color="primary" - inverse - progress={{ value: 75 }} - text="Widget helper text" - title="Widget title" - value="89.9%" - /> - </CCol> - </CRow> -</Example> - -```jsx -<CRow> - <CCol xs={6}> - <CWidgetStatsC - className="mb-3" - icon={<CIcon icon={cilChartPie} height={36} />} - progress={{ color: 'success', value: 75 }} - text="Widget helper text" - title="Widget title" - value="89.9%" - /> - </CCol> - <CCol xs={6}> - <CWidgetStatsC - className="mb-3" - icon={<CIcon icon={cilChartPie} height={36} />} - color="primary" - inverse - progress={{ value: 75 }} - text="Widget helper text" - title="Widget title" - value="89.9%" - /> - </CCol> -</CRow> -``` - -## CWidgetStatsD - -<Example> - <CRow> - <CCol xs={6}> - <CWidgetStatsD - className="mb-3" - icon={<CIcon className="my-4 text-white" icon={cibFacebook} height={52} />} - chart={ - <CChartLine - className="position-absolute w-100 h-100" - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - backgroundColor: 'rgba(255,255,255,.1)', - borderColor: 'rgba(255,255,255,.55)', - pointHoverBackgroundColor: '#fff', - borderWidth: 2, - data: [65, 59, 84, 84, 51, 55, 40], - fill: true, - }, - ], - }} - options={{ - elements: { - line: { - tension: 0.4, - }, - point: { - radius: 0, - hitRadius: 10, - hoverRadius: 4, - hoverBorderWidth: 3, - }, - }, - maintainAspectRatio: false, - plugins: { - legend: { - display: false, - }, - }, - scales: { - x: { - display: false, - }, - y: { - display: false, - }, - }, - }} - /> - } - style={{ '--cui-card-cap-bg': '#3b5998' }} - values={[ - { title: 'friends', value: '89K' }, - { title: 'feeds', value: '459' }, - ]} - /> - </CCol> - <CCol xs={6}> - <CWidgetStatsD - className="mb-3" - icon={<CIcon className="my-4 text-white" icon={cibTwitter} height={52} />} - chart={ - <CChartLine - className="position-absolute w-100 h-100" - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - backgroundColor: 'rgba(255,255,255,.1)', - borderColor: 'rgba(255,255,255,.55)', - pointHoverBackgroundColor: '#fff', - borderWidth: 2, - data: [1, 13, 9, 17, 34, 41, 38], - fill: true, - }, - ], - }} - options={{ - elements: { - line: { - tension: 0.4, - }, - point: { - radius: 0, - hitRadius: 10, - hoverRadius: 4, - hoverBorderWidth: 3, - }, - }, - maintainAspectRatio: false, - plugins: { - legend: { - display: false, - }, - }, - scales: { - x: { - display: false, - }, - y: { - display: false, - }, - }, - }} - /> - } - style={{ '--cui-card-cap-bg': '#00aced' }} - values={[ - { title: 'folowers', value: '973K' }, - { title: 'tweets', value: '1.792' }, - ]} - /> - </CCol> - </CRow> -</Example> - -```jsx -<CRow> - <CCol xs={6}> - <CWidgetStatsD - className="mb-3" - icon={<CIcon className="my-4 text-white" icon={cibFacebook} height={52} />} - chart={ - <CChartLine - className="position-absolute w-100 h-100" - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - backgroundColor: 'rgba(255,255,255,.1)', - borderColor: 'rgba(255,255,255,.55)', - pointHoverBackgroundColor: '#fff', - borderWidth: 2, - data: [65, 59, 84, 84, 51, 55, 40], - fill: true, - }, - ], - }} - options={{ - elements: { - line: { - tension: 0.4, - }, - point: { - radius: 0, - hitRadius: 10, - hoverRadius: 4, - hoverBorderWidth: 3, - }, - }, - maintainAspectRatio: false, - plugins: { - legend: { - display: false, - }, - }, - scales: { - x: { - display: false, - }, - y: { - display: false, - }, - }, - }} - /> - } - style={{ '--cui-card-cap-bg': '#3b5998' }} - values={[ - { title: 'friends', value: '89K' }, - { title: 'feeds', value: '459' }, - ]} - /> - </CCol> - <CCol xs={6}> - <CWidgetStatsD - className="mb-3" - icon={<CIcon className="my-4 text-white" icon={cibTwitter} height={52} />} - chart={ - <CChartLine - className="position-absolute w-100 h-100" - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - backgroundColor: 'rgba(255,255,255,.1)', - borderColor: 'rgba(255,255,255,.55)', - pointHoverBackgroundColor: '#fff', - borderWidth: 2, - data: [1, 13, 9, 17, 34, 41, 38], - fill: true, - }, - ], - }} - options={{ - elements: { - line: { - tension: 0.4, - }, - point: { - radius: 0, - hitRadius: 10, - hoverRadius: 4, - hoverBorderWidth: 3, - }, - }, - maintainAspectRatio: false, - plugins: { - legend: { - display: false, - }, - }, - scales: { - x: { - display: false, - }, - y: { - display: false, - }, - }, - }} - /> - } - style={{ '--cui-card-cap-bg': '#00aced' }} - values={[ - { title: 'folowers', value: '973K' }, - { title: 'tweets', value: '1.792' }, - ]} - /> - </CCol> -</CRow> -``` - -## CWidgetStatsE - -<Example> - <CRow> - <CCol xs={6}> - <CWidgetStatsE - className="mb-3" - chart={ - <CChartBar - className="mx-auto" - style={{ height: '40px', width: '80px' }} - data={{ - labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S', 'M', 'T', 'W', 'T', 'F', 'S', 'S', 'M'], - datasets: [ - { - backgroundColor: '#321fdb', - borderColor: 'transparent', - borderWidth: 1, - data: [41, 78, 51, 66, 74, 42, 89, 97, 87, 84, 78, 88, 67, 45, 47], - }, - ], - }} - options={{ - maintainAspectRatio: false, - plugins: { - legend: { - display: false, - }, - }, - scales: { - x: { - display: false, - }, - y: { - display: false, - }, - }, - }} - /> - } - title="Widget title" - value="89.9%" - /> - </CCol> - <CCol xs={6}> - <CWidgetStatsE - className="mb-3" - chart={ - <CChartLine - className="mx-auto" - style={{ height: '40px', width: '80px' }} - data={{ - labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S', 'M', 'T', 'W', 'T', 'F', 'S', 'S', 'M'], - datasets: [ - { - backgroundColor: 'transparent', - borderColor: '#321fdb', - borderWidth: 2, - data: [41, 78, 51, 66, 74, 42, 89, 97, 87, 84, 78, 88, 67, 45, 47], - }, - ], - }} - options={{ - maintainAspectRatio: false, - elements: { - line: { - tension: 0.4, - }, - point: { - radius: 0, - }, - }, - plugins: { - legend: { - display: false, - }, - }, - scales: { - x: { - display: false, - }, - y: { - display: false, - }, - }, - }} - /> - } - title="Widget title" - value="89.9%" - /> - </CCol> - </CRow> -</Example> - -```jsx -<CRow> - <CCol xs={6}> - <CWidgetStatsE - className="mb-3" - chart={ - <CChartBar - className="mx-auto" - style={{ height: '40px', width: '80px' }} - data={{ - labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S', 'M', 'T', 'W', 'T', 'F', 'S', 'S', 'M'], - datasets: [ - { - backgroundColor: '#321fdb', - borderColor: 'transparent', - borderWidth: 1, - data: [41, 78, 51, 66, 74, 42, 89, 97, 87, 84, 78, 88, 67, 45, 47], - }, - ], - }} - options={{ - maintainAspectRatio: false, - plugins: { - legend: { - display: false, - }, - }, - scales: { - x: { - display: false, - }, - y: { - display: false, - }, - }, - }} - /> - } - title="Widget title" - value="89.9%" - /> - </CCol> - <CCol xs={6}> - <CWidgetStatsE - className="mb-3" - chart={ - <CChartLine - className="mx-auto" - style={{ height: '40px', width: '80px' }} - data={{ - labels: ['M', 'T', 'W', 'T', 'F', 'S', 'S', 'M', 'T', 'W', 'T', 'F', 'S', 'S', 'M'], - datasets: [ - { - backgroundColor: 'transparent', - borderColor: '#321fdb', - borderWidth: 2, - data: [41, 78, 51, 66, 74, 42, 89, 97, 87, 84, 78, 88, 67, 45, 47], - }, - ], - }} - options={{ - maintainAspectRatio: false, - elements: { - line: { - tension: 0.4, - }, - point: { - radius: 0, - }, - }, - plugins: { - legend: { - display: false, - }, - }, - scales: { - x: { - display: false, - }, - y: { - display: false, - }, - }, - }} - /> - } - title="Widget title" - value="89.9%" - /> - </CCol> -</CRow> -``` - -## CWidgetStatsF - -<Example> - <CRow> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="primary" - icon={<CIcon icon={cilChartPie} height={24} />} - title="Widget title" - value="89.9%" - /> - </CCol> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="warning" - icon={<CIcon icon={cilChartPie} height={24} />} - title="Widget title" - value="89.9%" - /> - </CCol> - </CRow> - <CRow> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="primary" - icon={<CIcon icon={cilChartPie} height={24} />} - padding={false} - title="Widget title" - value="89.9%" - /> - </CCol> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="warning" - icon={<CIcon icon={cilChartPie} height={24} />} - padding={false} - title="Widget title" - value="89.9%" - /> - </CCol> - </CRow> - <CRow> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="primary" - footer={ - <CLink - className="font-weight-bold font-xs text-body-secondary" - href="https://coreui.io/" - rel="noopener norefferer" - target="_blank" - > - View more - <CIcon icon={cilArrowRight} className="float-end" width={16} /> - </CLink> - } - icon={<CIcon icon={cilChartPie} height={24} />} - title="Widget title" - value="89.9%" - /> - </CCol> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="warning" - footer={ - <CLink - className="font-weight-bold font-xs text-body-secondary" - href="https://coreui.io/" - rel="noopener norefferer" - target="_blank" - > - View more - <CIcon icon={cilArrowRight} className="float-end" width={16} /> - </CLink> - } - icon={<CIcon icon={cilChartPie} height={24} />} - title="Widget title" - value="89.9%" - /> - </CCol> - </CRow> -</Example> - -```jsx - <CRow> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="primary" - icon={<CIcon icon={cilChartPie} height={24} />} - title="Widget title" - value="89.9%"/> - </CCol> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="warning" - icon={<CIcon icon={cilChartPie} height={24} />} - title="Widget title" - value="89.9%"/> - </CCol> - </CRow> - <CRow> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="primary" - icon={<CIcon icon={cilChartPie} height={24} />} - padding={false} - title="Widget title" - value="89.9%"/> - </CCol> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="warning" - icon={<CIcon icon={cilChartPie} height={24} />} - padding={false} - title="Widget title" - value="89.9%"/> - </CCol> - </CRow> - <CRow> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="primary" - footer={ - <CLink - className="font-weight-bold font-xs text-body-secondary" - href="https://coreui.io/" - rel="noopener norefferer" - target="_blank" - > - View more - <CIcon icon={cilArrowRight} className="float-end" width={16} /> - </CLink> - } - icon={<CIcon icon={cilChartPie} height={24} />} - title="Widget title" - value="89.9%"/> - </CCol> - <CCol xs={6}> - <CWidgetStatsF - className="mb-3" - color="warning" - footer={ - <CLink - className="font-weight-bold font-xs text-body-secondary" - href="https://coreui.io/" - rel="noopener norefferer" - target="_blank" - > - View more - <CIcon icon={cilArrowRight} className="float-end" width={16} /> - </CLink> - } - icon={<CIcon icon={cilChartPie} height={24} />} - title="Widget title" - value="89.9%"/> - </CCol> - </CRow> -``` - -## API - -### CWidgetStatsA - -`markdown:CWidgetStatsA.api.mdx` - -### CWidgetStatsB - -`markdown:CWidgetStatsB.api.mdx` - -### CWidgetStatsC - -`markdown:CWidgetStatsC.api.mdx` - -### CWidgetStatsD - -`markdown:CWidgetStatsD.api.mdx` - -### CWidgetStatsE - -`markdown:CWidgetStatsE.api.mdx` - -### CWidgetStatsF - -`markdown:CWidgetStatsF.api.mdx` diff --git a/packages/docs/content/customize/css-variables.mdx b/packages/docs/content/customize/css-variables.mdx deleted file mode 100644 index d1495853..00000000 --- a/packages/docs/content/customize/css-variables.mdx +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: CSS variables -name: CSS variables -description: Use CoreUI's CSS custom properties for fast and forward-looking design and development. -menu: Customize -route: /templates/css-variables ---- - -CoreUI includes around two dozen [CSS custom properties (variables)](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) in its compiled CSS, with dozens more on the way for improved customization on a per-component basis. These provide easy access to commonly used values like our theme colors, breakpoints, and primary font stacks when working in your browser's inspector, a code sandbox, or general prototyping. - -**All our custom properties are prefixed with `cui-`** to avoid conflicts with third party CSS. - -## Root variables - -Here are the variables we include (note that the `:root` is required) that can be accessed anywhere CoreUI's CSS is loaded. They're located in our `_root.scss` file and included in our compiled dist files. - -```css -:root { - --cui-blue: #0d6efd; - --cui-indigo: #6610f2; - --cui-purple: #6f42c1; - --cui-pink: #d63384; - --cui-red: #dc3545; - --cui-orange: #fd7e14; - --cui-yellow: #ffc107; - --cui-green: #198754; - --cui-teal: #20c997; - --cui-cyan: #0dcaf0; - --cui-black: #000015; - --cui-white: #fff; - --cui-gray: #8a93a2; - --cui-gray-dark: #636f83; - --cui-gray-100: #ebedef; - --cui-gray-200: #d8dbe0; - --cui-gray-300: #c4c9d0; - --cui-gray-400: #b1b7c1; - --cui-gray-500: #9da5b1; - --cui-gray-600: #8a93a2; - --cui-gray-700: #768192; - --cui-gray-800: #636f83; - --cui-gray-900: #4f5d73; - --cui-primary: #321fdb; - --cui-secondary: #9da5b1; - --cui-success: #2eb85c; - --cui-info: #39f; - --cui-warning: #f9b115; - --cui-danger: #e55353; - --cui-light: #ebedef; - --cui-dark: #4f5d73; - --cui-primary-rgb: 50, 31, 219; - --cui-secondary-rgb: 157, 165, 177; - --cui-success-rgb: 46, 184, 92; - --cui-info-rgb: 51, 153, 255; - --cui-warning-rgb: 249, 177, 21; - --cui-danger-rgb: 229, 83, 83; - --cui-light-rgb: 235, 237, 239; - --cui-dark-rgb: 79, 93, 115; - --cui-white-rgb: 255, 255, 255; - --cui-black-rgb: 0, 0, 21; - --cui-body-color-rgb: 44, 56, 74; - --cui-body-bg-rgb: 255, 255, 255; - --cui-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - --cui-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - --cui-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); - --cui-body-font-family: var(--cui-font-sans-serif); - --cui-body-font-size: 1rem; - --cui-body-font-weight: 400; - --cui-body-line-height: 1.5; - --cui-body-color: rgba(44, 56, 74, 0.95); - --cui-body-bg: #fff; - --cui-border-width: 1px; - --cui-border-style: solid; - --cui-border-color: #d8dbe0; - --cui-border-color-translucent: rgba(0, 0, 21, 0.175); - --cui-border-radius: 0.375rem; - --cui-border-radius-sm: 0.25rem; - --cui-border-radius-lg: 0.5rem; - --cui-border-radius-xl: 1rem; - --cui-border-radius-2xl: 2rem; - --cui-border-radius-pill: 50rem; - --cui-heading-color: unset; - --cui-link-color: #321fdb; - --cui-link-hover-color: #2819af; - --cui-code-color: #d63384; - --cui-highlight-bg: #fff3cd; -} -``` - -## Component variables - -CoreUI is increasingly making use of custom properties as local variables for various components. This way we reduce our compiled CSS, ensure styles aren't inherited in places like nested tables, and allow some basic restyling and extending of CoreUI components after Sass compilation. - -Whenever possible, we'll assign CSS variables at the base component level (e.g., `.navbar` for navbar and its sub-components). This reduces guessing on where and how to customize, and allows for easy modifications by our team in future updates. - -## Prefix - -Most CSS variables use a prefix to avoid collisions with your own codebase. This prefix is in addition to the `--` that's required on every CSS variable. - -Customize the prefix via the `$prefix` Sass variable. By default, it's set to `cui-` (note the trailing dash). - -## Examples - -CSS variables offer similar flexibility to Sass's variables, but without the need for compilation before being served to the browser. For example, here we're resetting our page's font and link styles with CSS variables. - -```css -body { - font: 1rem/1.5 var(--cui-font-sans-serif); -} -a { - color: var(--cui-blue); -} -``` - -## Grid breakpoints - -While we include our grid breakpoints as CSS variables (except for `xs`), be aware that **CSS variables do not work in media queries**. This is by design in the CSS spec for variables, but may change in coming years with support for `env()` variables. Check out [this Stack Overflow answer](https://stackoverflow.com/a/47212942) for some helpful links. In the mean time, you can use these variables in other CSS situations, as well as in your JavaScript. diff --git a/packages/docs/content/customize/options.mdx b/packages/docs/content/customize/options.mdx deleted file mode 100644 index 4e1e6b3e..00000000 --- a/packages/docs/content/customize/options.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Options -description: Quickly customize CoreUI for React with built-in variables to easily toggle global CSS preferences for controlling style and behavior. -menu: Customize -route: /customize/options ---- - -Customize CoreUI for React with our built-in custom variables file and easily toggle global CSS preferences with new `$enable-*` Sass variables. Override a variable's value and recompile with `npm run test` as needed. - -You can find and customize these variables for key global options in CoreUI's `@coreui/coreui/scss/_variables.scss` file. - -| Variable | Values | Description | -| ------------------------------ | ---------------------------------- | -------------------------------------------------------------------------------------- | -| `$spacer` | `1rem` (default), or any value > 0 | Specifies the default spacer value to programmatically generate our [spacer utilities](https://coreui.io/docs/utilities/spacing). | -| `$enable-rounded` | `true` (default) or `false` | Enables predefined `border-radius` styles on various components. | -| `$enable-shadows` | `true` or `false` (default) | Enables predefined decorative `box-shadow` styles on various components. Does not affect `box-shadow`s used for focus states. | -| `$enable-gradients` | `true` or `false` (default) | Enables predefined gradients via `background-image` styles on various components. | -| `$enable-transitions` | `true` (default) or `false` | Enables predefined `transition`s on various components. | -| `$enable-reduced-motion` | `true` (default) or `false` | Enables the [`prefers-reduced-motion` media query](https://coreui.io/docs/getting-started/accessibility#reduced-motion), which suppresses certain animations/transitions based on the users' browser/operating system preferences. | -| `$enable-grid-classes` | `true` (default) or `false` | Enables the generation of CSS classes for the grid system (e.g. `.row`, `.col-md-1`, etc.). | -| `$enable-container-classes` | `true` (default) or `false` | Enables the generation of CSS classes for layout containers. (New in v4.2.0) | -| `$enable-caret` | `true` (default) or `false` | Enables pseudo element caret on `.dropdown-toggle`. | -| `$enable-button-pointers` | `true` (default) or `false` | Add "hand" cursor to non-disabled button elements. | -| `$enable-rfs` | `true` (default) or `false` | Globally enables [RFS](https://coreui.io/docs/getting-started/rfs). | -| `$enable-validation-icons` | `true` (default) or `false` | Enables `background-image` icons within textual inputs and some custom forms for validation states. | -| `$enable-negative-margins` | `true` or `false` (default) | Enables the generation of [negative margin utilities](https://coreui.io/docs/utilities/spacing#negative-margin). | -| `$enable-deprecation-messages` | `true` (default) or `false` | Set to `false` to hide warnings when using any of the deprecated mixins and functions that are planned to be removed in `v6`. | -| `$enable-important-utilities` | `true` (default) or `false` | Enables the `!important` suffix in utility classes. | -| `$enable-smooth-scroll` | `true` (default) or `false` | Applies `scroll-behavior: smooth` globally, except for users asking for reduced motion through [`prefers-reduced-motion` media query](https://coreui.io/docs/getting-started/accessibility#reduced-motion) | -| `$enable-ltr` | `false` or `false` (default) | Enables Left-to-Right | -| `$enable-rtl` | `true` (default) or `false` | Enables Right-to-Left | - diff --git a/packages/docs/content/customize/sass.mdx b/packages/docs/content/customize/sass.mdx deleted file mode 100644 index 60ee53fa..00000000 --- a/packages/docs/content/customize/sass.mdx +++ /dev/null @@ -1,325 +0,0 @@ ---- -title: Sass -name: Sass -description: Utilize our source Sass files to take advantage of variables, maps, mixins, and functions to help you build faster and customize your project. -menu: Customize -route: /customize/sass ---- - -Utilize our source Sass files to take advantage of variables, maps, mixins, and more. - -## File structure - -Whenever possible, avoid modifying CoreUI's core files. For Sass, that means creating your own stylesheet that imports CoreUI for Bootstrap so you can modify and extend it. Assuming you're using a package manager like npm, you'll have a file structure that looks like this: - -```text -your-project/ -├── scss -│ └── custom.scss -└── node_modules/ - └── @coreui/coreui - ├── js - └── scss -``` - -If you've downloaded our source files and aren't using a package manager, you'll want to manually create something similar to that structure, keeping CoreUI's source files separate from your own. - -```text -your-project/ -├── scss -│ └── custom.scss -└── @coreui/coreui/ - ├── js - └── scss -``` - -## Importing - -In your `custom.scss`, you'll import CoreUI's source Sass files. You have two options: include all of CoreUI, or pick the parts you need. We encourage the latter, though be aware there are some requirements and dependencies across our components. You also will need to include some JavaScript for our plugins. - -```scss -// Custom.scss -// Option A: Include all of CoreUI - -@import "../node_modules/@coreui/coreui/scss/coreui"; - -// Then add additional custom code here -``` - -```scss -// Custom.scss -// Option B: Include parts of CoreUI - -// 1. Include functions first (so you can manipulate colors, SVGs, calc, etc) -@import "../node_modules/@coreui/coreui/scss/functions"; - -// 2. Include any default variable overrides here - -// 3. Include remainder of required CoreUI stylesheets -@import "../node_modules/@coreui/coreui/scss/variables"; - -// 4. Include any default map overrides here - -// 5. Include remainder of required parts -@import "../node_modules/@coreui/coreui/scss/maps"; -@import "../node_modules/@coreui/coreui/scss/mixins"; -@import "../node_modules/@coreui/coreui/scss/root"; - -// 6. Optionally include any other parts as needed -@import "../node_modules/@coreui/coreui/scss/utilities"; -@import "../node_modules/@coreui/coreui/scss/reboot"; -@import "../node_modules/@coreui/coreui/scss/type"; -@import "../node_modules/@coreui/coreui/scss/images"; -@import "../node_modules/@coreui/coreui/scss/containers"; -@import "../node_modules/@coreui/coreui/scss/grid"; -@import "../node_modules/@coreui/coreui/scss/helpers"; - -// 7. Optionally include utilities API last to generate classes based on the Sass map in `_utilities.scss` -@import "../node_modules/@coreui/coreui/scss/utilities/api"; - -// 8. Add additional custom code here -``` - -With that setup in place, you can begin to modify any of the Sass variables and maps in your `custom.scss`. You can also start to add parts of CoreUI for Bootstrap under the `// Optional` section as needed. We suggest using the full import stack from our `coreui.scss` file as your starting point. - -## Variable defaults - -Every Sass variable in CoreUI for Bootstrap includes the `!default` flag allowing you to override the variable's default value in your own Sass without modifying CoreUI's source code. Copy and paste variables as needed, modify their values, and remove the `!default` flag. If a variable has already been assigned, then it won't be re-assigned by the default values in Bootstrap. - -You will find the complete list of CoreUI's variables in `@coreui/coreui/scss/_variables.scss`. Some variables are set to `null`, these variables don't output the property unless they are overridden in your configuration. - -Variable overrides must come after our functions are imported, but before the rest of the imports. - -Here's an example that changes the `background-color` and `color` for the `<body>` when importing and compiling CoreUI for Bootstrap via npm: - -```scss -// Required -@import "../node_modules/@coreui/coreui/scss/functions"; - -// Default variable overrides -$body-bg: #000; -$body-color: #111; - -// Required -@import "../node_modules/@coreui/coreui/scss/variables"; -@import "../node_modules/@coreui/coreui/scss/maps"; -@import "../node_modules/@coreui/coreui/scss/mixins"; -@import "../node_modules/@coreui/coreui/scss/root"; - -// Optional CoreUI components here -@import "../node_modules/@coreui/coreui/scss/reboot"; -@import "../node_modules/@coreui/coreui/scss/type"; -// etc -``` - -Repeat as necessary for any variable in CoreUI, including the global options below. - -## Maps and loops - -CoreUI for Bootstrap includes a handful of Sass maps, key value pairs that make it easier to generate families of related CSS. We use Sass maps for our colors, grid breakpoints, and more. Just like Sass variables, all Sass maps include the `!default` flag and can be overridden and extended. - -Some of our Sass maps are merged into empty ones by default. This is done to allow easy expansion of a given Sass map, but comes at the cost of making _removing_ items from a map slightly more difficult. - -### Modify map - -All variables in the `$theme-colors` map are defined as standalone variables. To modify an existing color in our `$theme-colors` map, add the following to your custom Sass file: - -```scss -$primary: #0074d9; -$danger: #ff4136; -``` - -Later on, these variables are set in CoreUI's `$theme-colors` map: - -```scss -$theme-colors: ( - "primary": $primary, - "danger": $danger -); -``` - -### Add to map - -Add new colors to `$theme-colors`, or any other map, by creating a new Sass map with your custom values and merging it with the original map. In this case, we'll create a new `$custom-colors` map and merge it with `$theme-colors`. - -```scss -// Create your own map -$custom-colors: ( - "custom-color": #900 -); - -// Merge the maps -$theme-colors: map-merge($theme-colors, $custom-colors); -``` - -### Remove from map - -To remove colors from `$theme-colors`, or any other map, use `map-remove`. Be aware you must insert it between our requirements and options: - -```scss -// Required -@import "../node_modules/@coreui/coreui/scss/functions"; -@import "../node_modules/@coreui/coreui/scss/variables"; -@import "../node_modules/@coreui/coreui/scss/maps"; -@import "../node_modules/@coreui/coreui/scss/mixins"; -@import "../node_modules/@coreui/coreui/scss/root"; - -$theme-colors: map-remove($theme-colors, "info", "light", "dark"); - -// Optional -@import "../node_modules/@coreui/coreui/scss/reboot"; -@import "../node_modules/@coreui/coreui/scss/type"; -// etc -``` - -## Required keys - -CoreUI for Bootstrap assumes the presence of some specific keys within Sass maps as we used and extend these ourselves. As you customize the included maps, you may encounter errors where a specific Sass map's key is being used. - -For example, we use the `primary`, `success`, and `danger` keys from `$theme-colors` for links, buttons, and form states. Replacing the values of these keys should present no issues, but removing them may cause Sass compilation issues. In these instances, you'll need to modify the Sass code that makes use of those values. - -## Functions - -### Colors - -Next to the [Sass maps](https://coreui.io/docs/customize/color#color-sass-maps") we have, theme colors can also be used as standalone variables, like `$primary`. - -```scss -.custom-element { - color: $gray-100; - background-color: $dark; -} -``` - -You can lighten or darken colors with CoreUI's `tint-color()` and `shade-color()` functions. These functions will mix colors with black or white, unlike Sass' native `lighten()` and `darken()` functions which will change the lightness by a fixed amount, which often doesn't lead to the desired effect. - -```scss -// Tint a color: mix a color with white -@function tint-color($color, $weight) { - @return mix(white, $color, $weight); -} - -// Shade a color: mix a color with black -@function shade-color($color, $weight) { - @return mix(black, $color, $weight); -} - -// Shade the color if the weight is positive, else tint it -@function shift-color($color, $weight) { - @return if($weight > 0, shade-color($color, $weight), tint-color($color, -$weight)); -} -``` - -In practice, you'd call the function and pass in the color and weight parameters. - -```scss -.custom-element { - color: tint-color($primary, 10%); -} - -.custom-element-2 { - color: shade-color($danger, 30%); -} -``` - -### Color contrast - -In order to meet the [Web Content Accessibility Guidelines (WCAG)](https://www.w3.org/TR/WCAG/) contrast requirements, authors **must** provide a minimum [text color contrast of 4.5:1](https://www.w3.org/TR/WCAG/#contrast-minimum) and a minimum [non-text color contrast of 3:1](https://www.w3.org/TR/WCAG/#non-text-contrast), with very few exceptions. - -An additional function we include in CoreUI for Bootstrap is the color contrast function, `color-contrast`. It utilizes the [WCAG 2.0 algorithm](https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests) for calculating contrast thresholds based on [relative luminance](https://www.w3.org/WAI/GL/wiki/Relative_luminance) in a `sRGB` colorspace to automatically return a light (`#fff`), dark (`#212529`) or black (`#000`) contrast color based on the specified base color. This function is especially useful for mixins or loops where you're generating multiple classes. - -For example, to generate color swatches from our `$theme-colors` map: - -```scss -@each $color, $value in $theme-colors { - .swatch-#{$color} { - color: color-contrast($value); - } -} -``` - -It can also be used for one-off contrast needs: - -```scss -.custom-element { - color: color-contrast(#000); // returns `color: #fff` -} -``` - -You can also specify a base color with our color map functions: - -```scss -.custom-element { - color: color-contrast($dark); // returns `color: #fff` -} -``` - -### Escape SVG - -We use the `escape-svg` function to escape the `<`, `>` and `#` characters for SVG background images. When using the `escape-svg` function, data URIs must be quoted. - -### Add and Subtract functions - -We use the `add` and `subtract` functions to wrap the CSS `calc` function. The primary purpose of these functions is to avoid errors when a "unitless" `0` value is passed into a `calc` expression. Expressions like `calc(10px - 0)` will return an error in all browsers, despite being mathematically correct. - -Example where the calc is valid: - -```scss -$border-radius: .25rem; -$border-width: 1px; - -.element { - // Output calc(.25rem - 1px) is valid - border-radius: calc($border-radius - $border-width); -} - -.element { - // Output the same calc(.25rem - 1px) as above - border-radius: subtract($border-radius, $border-width); -} -``` - -Example where the calc is invalid: - -```scss -$border-radius: .25rem; -$border-width: 0; - -.element { - // Output calc(.25rem - 0) is invalid - border-radius: calc($border-radius - $border-width); -} - -.element { - // Output .25rem - border-radius: subtract($border-radius, $border-width); -} -``` - -## Mixins - -Our `@coreui/coreui/scss/mixins/` directory has a ton of mixins that power parts of CoreUI and can also be used across your own project. - -### Color schemes - -A shorthand mixin for the `prefers-color-scheme` media query is available with support for `light`, `dark`, and custom color schemes. - -```scss -@mixin color-scheme($name) { - @media (prefers-color-scheme: #{$name}) { - @content; - } -} -``` - -```scss -.custom-element { - @include color-scheme(dark) { - // Insert dark mode styles here - } - - @include color-scheme(custom-named-scheme) { - // Insert custom color scheme styles here - } -} -``` diff --git a/packages/docs/content/forms/checkbox.mdx b/packages/docs/content/forms/checkbox.mdx deleted file mode 100644 index 70b87ac8..00000000 --- a/packages/docs/content/forms/checkbox.mdx +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: React Checkbox Components -name: Checkbox -description: Create consistent cross-browser and cross-device checkboxes with our React checkbox components. -menu: Forms -route: /forms/checkbox -other_frameworks: checkbox ---- - -import { useEffect, useRef } from 'react' -import { - CButton, - CFormCheck, -} from '@coreui/react/src/index' - -## Approach - -Browser default checkboxes and radios are replaced with the help of `<CFormCheck>`. Checkboxes are for selecting one or several options in a list. - -## Checkboxes - -```jsx preview -<CFormCheck id="flexCheckDefault" label="Default checkbox"/> -<CFormCheck id="flexCheckChecked" label="Checked checkbox" defaultChecked /> -``` - -### Indeterminate - -Checkboxes can utilize the `:indeterminate` pseudo-class when manually set via `indeterminate` property. - -```jsx preview -<CFormCheck id="flexCheckIndeterminate" label="Indeterminate checkbox" indeterminate /> -``` - -### Disabled - -Add the `disabled` attribute and the associated `<label>`s are automatically styled to match with a lighter color to help indicate the input's state. - -```jsx preview -<CFormCheck label="Disabled checkbox" disabled/> -<CFormCheck label="Disabled checked checkbox" defaultChecked disabled/> -``` - -## Default (stacked) - -By default, any number of checkboxes that are immediate sibling will be vertically stacked and appropriately spaced. - -```jsx preview -<CFormCheck id="defaultCheck1" label="Default checkbox"/> -<CFormCheck id="defaultCheck2" label="Disabled checkbox" disabled/> -``` - -## Inline - -Group checkboxes on the same horizontal row by adding `inline` boolean property to any `<CFormCheck>`. - -```jsx preview -<CFormCheck inline id="inlineCheckbox1" value="option1" label="1"/> -<CFormCheck inline id="inlineCheckbox2" value="option2" label="2"/> -<CFormCheck inline id="inlineCheckbox3" value="option3" label="3 (disabled)" disabled/> -``` - -## Reverse - -Put your checkboxes on the opposite side by adding `reverse` boolean property. - -```jsx preview -<CFormCheck reverse id="reverseCheckbox1" value="option1" label="Reverse checkbox"/> -<CFormCheck reverse id="reverseCheckbox2" value="option2" label="Disabled reverse checkbox" disabled/> -``` - -## Without labels - -Remember to still provide some form of accessible name for assistive technologies (for instance, using `aria-label`). - -```jsx preview -<CFormCheck id="checkboxNoLabel" value="" aria-label="..."/> -``` - -## Checkbox toggle buttons - -Create button-like checkboxes and radio buttons by using `button` boolean property on the `<CFormCheck>` component. These toggle buttons can further be grouped in a button group if needed. - -```jsx preview -<CFormCheck button={{ color: 'primary' }} id="btn-check" autoComplete="off" label="Single toggle" /> -``` - -```jsx preview -<CFormCheck - button={{ color: 'primary' }} - id="btn-check-2" - autoComplete="off" - label="Checked" - defaultChecked -/> -``` - -```jsx preview -<CFormCheck - button={{ color: 'primary' }} - id="btn-check-3" - autoComplete="off" - label="Disabled" - disabled -/> -``` - -### Outlined styles - -Different variants of button, such at the various outlined styles, are supported. - -```jsx preview -<CFormCheck button={{ color: 'primary', variant: 'outline' }} id="btn-check-outlined" autoComplete="off" label="Single toggle"/> -<CFormCheck button={{ color: 'secondary', variant: 'outline' }} id="btn-check-2-outlined" autoComplete="off" label="Checked" defaultChecked/> -``` - -## Customizing - -### SASS variables - -<ScssDocs file="_variables.scss" capture="form-check-variables" /> - -## API - -### CFormCheck - -`markdown:CFormCheck.api.mdx` diff --git a/packages/docs/content/forms/checks-radios.mdx b/packages/docs/content/forms/checks-radios.mdx deleted file mode 100644 index f9a7fc49..00000000 --- a/packages/docs/content/forms/checks-radios.mdx +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: React Checkbox & Radio Components -name: Checks & radios -description: Create consistent cross-browser and cross-device checkboxes and radios with our React checkbox, radio, and switch components. -menu: Forms -route: /forms/checks-radios ---- - -import { useEffect, useRef } from 'react' -import { - CButton, - CForm, - CFormCheck, - CFormLabel, - CFormSwitch, - CFormText, -} from '@coreui/react/src/index' - -## Approach - -Browser default checkboxes and radios are replaced with the help of `<CFormCheck>`. Checkboxes are for selecting one or several options in a list, while radios are for selecting one option from many. - -## Checks - -```jsx preview -<CFormCheck id="flexCheckDefault" label="Default checkbox"/> -<CFormCheck id="flexCheckChecked" label="Checked checkbox" defaultChecked /> -``` - -## Indeterminate - -Checkboxes can utilize the `:indeterminate` pseudo-class when manually set via `indeterminate` property. - -```jsx preview -<CFormCheck id="flexCheckIndeterminate" label="Indeterminate checkbox" indeterminate /> -``` - -### Disabled - -Add the `disabled` attribute and the associated `<label>`s are automatically styled to match with a lighter color to help indicate the input's state. - -```jsx preview -<CFormCheck label="Disabled checkbox" disabled/> -<CFormCheck label="Disabled checked checkbox" defaultChecked disabled/> -``` - -## Radios - -Add the `disabled` attribute and the associated `<label>`s are automatically styled to match with a lighter color to help indicate the input's state. - -```jsx preview -<CFormCheck type="radio" name="flexRadioDefault" id="flexRadioDefault1" label="Default radio"/> -<CFormCheck type="radio" name="flexRadioDefault" id="flexRadioDefault2" label="Checked radio" defaultChecked/> -``` - -### Disabled - -```jsx preview -<CFormCheck type="radio" name="flexRadioDisabled" id="flexRadioDisabled" label="Disabled radio" disabled/> -<CFormCheck type="radio" name="flexRadioDisabled" id="flexRadioCheckedDisabled" label="Disabled checked radio" defaultChecked disabled/> -``` - -## Switches - -A switch has the markup of a custom checkbox but uses the `switch` boolean properly to render a toggle switch. Switches also support the `disabled` attribute. - -```jsx preview -<CFormSwitch label="Default switch checkbox input" id="formSwitchCheckDefault"/> -<CFormSwitch label="Checked switch checkbox input" id="formSwitchCheckChecked" defaultChecked/> -<CFormSwitch label="Disabled switch checkbox input" id="formSwitchCheckDisabled" disabled/> -<CFormSwitch label="Disabled checked switch checkbox input" id="formSwitchCheckCheckedDisabled" defaultChecked disabled/> -``` - -### Sizes - -```jsx preview -<CFormSwitch label="Default switch checkbox input" id="formSwitchCheckDefault"/> -<CFormSwitch size="lg" label="Large switch checkbox input" id="formSwitchCheckDefaultLg"/> -<CFormSwitch size="xl" label="Extra large switch checkbox input" id="formSwitchCheckDefaultXL"/> -``` - -## Default (stacked) - -By default, any number of checkboxes and radios that are immediate sibling will be vertically stacked and appropriately spaced. - -```jsx preview -<CFormCheck id="defaultCheck1" label="Default checkbox"/> -<CFormCheck id="defaultCheck2" label="Disabled checkbox" disabled/> -``` - -```jsx preview -<CFormCheck type="radio" name="exampleRadios" id="exampleRadios1" value="option1" label="Default radio" defaultChecked/> -<CFormCheck type="radio" name="exampleRadios" id="exampleRadios2" value="option2" label="Second default radio"/> -<CFormCheck type="radio" name="exampleRadios" id="exampleRadios3" value="option3" label="Disabled radio" disabled/> -``` - -## Inline - -Group checkboxes or radios on the same horizontal row by adding `inline` boolean property to any `<CFormCheck>`. - -```jsx preview -<CFormCheck inline id="inlineCheckbox1" value="option1" label="1"/> -<CFormCheck inline id="inlineCheckbox2" value="option2" label="2"/> -<CFormCheck inline id="inlineCheckbox3" value="option3" label="3 (disabled)" disabled/> -``` - -```jsx preview -<CFormCheck inline type="radio" name="inlineRadioOptions" id="inlineCheckbox1" value="option1" label="1"/> -<CFormCheck inline type="radio" name="inlineRadioOptions" id="inlineCheckbox2" value="option2" label="2"/> -<CFormCheck inline type="radio" name="inlineRadioOptions" id="inlineCheckbox3" value="option3" label="3 (disabled)" disabled/> -``` - -## Without labels - -Remember to still provide some form of accessible name for assistive technologies (for instance, using `aria-label`). - -```jsx preview -<div> - <CFormCheck id="checkboxNoLabel" value="" aria-label="..."/> -</div> -<div> - <CFormCheck type="radio" name="radioNoLabel" id="radioNoLabel" value="" aria-label="..."/> -</div> -``` - -## Toggle buttons - -Create button-like checkboxes and radio buttons by using `button` boolean property on the `<CFormCheck>` component. These toggle buttons can further be grouped in a button group if needed. - -### Checkbox toggle buttons - -```jsx preview -<CFormCheck button={{ color: 'primary' }} id="btn-check" autoComplete="off" label="Single toggle" /> -``` - -```jsx preview -<CFormCheck - button={{ color: 'primary' }} - id="btn-check-2" - autoComplete="off" - label="Checked" - defaultChecked -/> -``` - -```jsx preview -<CFormCheck - button={{ color: 'primary' }} - id="btn-check-3" - autoComplete="off" - label="Disabled" - disabled -/> -``` - -### Radio toggle buttons - -```jsx preview -<CFormCheck button={{ color: 'secondary' }} type="radio" name="options" id="option1" autoComplete="off" label="Checked" defaultChecked/> -<CFormCheck button={{ color: 'secondary' }} type="radio" name="options" id="option2" autoComplete="off" label="Radio"/> -<CFormCheck button={{ color: 'secondary' }} type="radio" name="options" id="option3" autoComplete="off" label="Radio" disabled/> -<CFormCheck button={{ color: 'secondary' }} type="radio" name="options" id="option4" autoComplete="off" label="Radio"/> -``` - -### Outlined styles - -Different variants of button, such at the various outlined styles, are supported. - -```jsx preview -<div> - <CFormCheck button={{ color: 'primary', variant: 'outline' }} id="btn-check-outlined" autoComplete="off" label="Single toggle"/> -</div> -<div> - <CFormCheck button={{ color: 'secondary', variant: 'outline' }} id="btn-check-2-outlined" autoComplete="off" label="Checked" defaultChecked/> -</div> -<div> - <CFormCheck button={{ color: 'success', variant: 'outline' }} type="radio" name="options-outlined" id="success-outlined" autoComplete="off" label="Radio" defaultChecked/> - <CFormCheck button={{ color: 'danger', variant: 'outline' }} type="radio" name="options-outlined" id="danger-outlined" autoComplete="off" label="Radio"/> -</div> -``` - -## API - -### CFormCheck - -`markdown:CFormCheck.api.mdx` - -### CFormSwitch - -`markdown:CFormSwitch.api.mdx` diff --git a/packages/docs/content/forms/floating-labels.mdx b/packages/docs/content/forms/floating-labels.mdx deleted file mode 100644 index 5b4470e1..00000000 --- a/packages/docs/content/forms/floating-labels.mdx +++ /dev/null @@ -1,159 +0,0 @@ ---- -title: React Floating labels -name: Floating labels -description: React floating label component. Create beautifully simple form labels that float over your input fields. -menu: Forms -route: /forms/floating-labels -other_frameworks: floating-labels ---- - -import { - CButton, - CForm, - CFormFloating, - CFormInput, - CFormLabel, - CFormSelect, - CFormTextarea, - CCol, - CRow, -} from '@coreui/react/src/index' - -## Example - -Use `floatingLabel` property on `<CFormInput>`, `<CFormSelect>` or `<CFormTextarea>` to enable floating labels with textual form fields. A `placeholder` is required on each `<CFormInput>`, `<CFormSelect>` and `<CFormTextarea>` as our method of CSS-only floating labels uses the `:placeholder-shown` pseudo-element. - -```jsx preview -<CFormInput type="email" id="floatingInput" floatingClassName="mb-3" floatingLabel="Email address" placeholder="name@example.com" /> -<CFormInput type="password" id="floatingPassword" floatingLabel="Password" placeholder="Password" /> -``` - -You can create the same form control by wrapping a pair of `<CFormInput>` and `<CFormLabel>` elements in `<CFormFloating>` to enable floating labels with textual form fields. A `placeholder` is required on each `<CFormInput>` as our method of CSS-only floating labels uses the `:placeholder-shown` pseudo-element. Also, note that the `<CFormInput>` must come first so we can utilize a sibling selector (e.g., `~`). - -```jsx -<CFormFloating className="mb-3"> - <CFormInput type="email" id="floatingInput" placeholder="name@example.com" /> - <CFormLabel htmlFor="floatingInput">Email address</CFormLabel> -</CFormFloating> -<CFormFloating> - <CFormInput type="password" id="floatingPassword" placeholder="Password" /> - <CFormLabel htmlFor="exampleFormControlTextarea1">Password</CFormLabel> -</CFormFloating> -``` - -When there's a `value` already defined, `<CFormLabel>`s will automatically adjust to their floated position. - -```jsx preview -<CFormInput - type="email" - id="floatingInputValue" - floatingLabel="Input with value" - placeholder="name@example.com" - defaultValue="test@example.com" -/> -``` - - -Form validation styles also work as expected. - -```jsx preview -<CFormInput - type="email" - id="floatingInputValid" - floatingClassName="mb-3" - floatingLabel="Email addresss" - placeholder="name@example.com" - defaultValue="test@example.com" - valid -/> -<CFormInput - type="email" - id="floatingInputInvalid" - floatingLabel="Email addresss" - placeholder="name@example.com" - defaultValue="test@example.com" - invalid -/> -``` - -## Textareas - -By default, `<CFormTextarea>`s will be the same height as `<CFormInput>`s. - -```jsx preview -<CFormTextarea - id="floatingTextarea" - floatingLabel="Comments" - placeholder="Leave a comment here" -></CFormTextarea> -``` - -To set a custom height on your `<CFormTextarea>`, do not use the `rows` attribute. Instead, set an explicit `height` (either inline or via custom CSS). - -```jsx preview -<CFormTextarea - placeholder="Leave a comment here" - id="floatingTextarea2" - floatingLabel="Comments" - style={{ height: '100px' }} -></CFormTextarea> -``` - -## Selects - -Other than `<CFormInput>`, floating labels are only available on `<CFormSelect>`s. They work in the same way, but unlike `<CFormInput>`s, they'll always show the `<CFormLabel>` in its floated state. **Selects with `size` and `multiple` are not supported.** - -```jsx preview -<CFormSelect - id="floatingSelect" - floatingLabel="Works with selects" - aria-label="Floating label select example" -> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> -</CFormSelect> -``` - -## Layout - -When working with the CoreUI for Bootstrap grid system, be sure to place form elements within column classes. - -```jsx preview -<CRow xs={{ gutter: 2 }}> - <CCol md> - <CFormInput - type="email" - id="floatingInputGrid" - floatingLabel="Email address" - placeholder="name@example.com" - defaultValue="email@example.com" - /> - </CCol> - <CCol md> - <CFormSelect - id="floatingSelectGrid" - floatingLabel="Email address" - aria-label="Works with selects" - > - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </CCol> -</CRow> -``` - -## Customizing - -### SASS variables - -<ScssDocs file="_variables.scss" capture="form-floating-variables" /> - -## API - -### CFormFloating - -`markdown:CFormFloating.api.mdx` diff --git a/packages/docs/content/forms/form-control.mdx b/packages/docs/content/forms/form-control.mdx deleted file mode 100644 index f64fe0de..00000000 --- a/packages/docs/content/forms/form-control.mdx +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: React Form Controls -name: Form control -description: React input and textarea components. Give textual form controls like `<input>`s and `<textarea>`s an upgrade with custom styles, sizing, focus states, and more. -menu: Forms -route: /forms/form-control ---- - -import { - CButton, - CForm, - CFormInput, - CFormLabel, - CFormTextarea, - CCol, - CRow -} from '@coreui/react/src/index' - -## Example - -```jsx preview -<CForm> - <div className="mb-3"> - <CFormLabel htmlFor="exampleFormControlInput1">Email address</CFormLabel> - <CFormInput type="email" id="exampleFormControlInput1" placeholder="name@example.com"/> - </div> - <div className="mb-3"> - <CFormLabel htmlFor="exampleFormControlTextarea1">Example textarea</CFormLabel> - <CFormTextarea id="exampleFormControlTextarea1" rows={3}></CFormTextarea> - </div> -</CForm> -``` - -## Sizing - -Set heights using `size` property like `size="lg"` and `size="sm"`. - -```jsx preview -<CFormInput type="text" size="lg" placeholder="Large input" aria-label="lg input example"/> -<CFormInput type="text" placeholder="Default input" aria-label="default input example"/> -<CFormInput type="text" size="sm" placeholder="Small input" aria-label="sm input example"/> -``` - -## Disabled - -Add the `disabled` boolean attribute on an input to give it a grayed out appearance and remove pointer events. - -```jsx preview -<CFormInput type="text" placeholder="Disabled input" aria-label="Disabled input example" disabled/> -<CFormInput type="text" placeholder="Disabled readonly input" aria-label="Disabled input example" disabled readOnly/> -``` - -## Readonly - -Add the `readOnly` boolean attribute on an input to prevent modification of the input's value. Read-only inputs appear lighter (just like disabled inputs), but retain the standard cursor. - -```jsx preview -<CFormInput type="text" placeholder="Readonly input here..." aria-label="readonly input example" readOnly/> -``` - -## Readonly plain text - -If you want to have `<input readonly>` elements in your form styled as plain text, use the `plainText` boolean property to remove the default form field styling and preserve the correct margin and padding. - -```jsx preview -<CRow className="mb-3"> - <CFormLabel htmlFor="staticEmail" className="col-sm-2 col-form-label">Email</CFormLabel> - <CCol sm={10}> - <CFormInput type="text" id="staticEmail" defaultValue="email@example.com" readOnly plainText/> - </CCol> -</CRow> -<CRow className="mb-3"> - <CFormLabel htmlFor="inputPassword" className="col-sm-2 col-form-label">Password</CFormLabel> - <CCol sm={10}> - <CFormInput type="password" id="inputPassword"/> - </CCol> -</CRow> -``` - -```jsx preview -<CForm className="row g-3"> - <CCol xs="auto"> - <CFormLabel htmlFor="staticEmail2" className="visually-hidden">Email</CFormLabel> - <CFormInput type="text" id="staticEmail2" defaultValue="email@example.com" readOnly plainText/> - </CCol> - <CCol xs="auto"> - <CFormLabel htmlFor="inputPassword2" className="visually-hidden">Password</CFormLabel> - <CFormInput type="password" id="inputPassword2" placeholder="Password"/> - </CCol> - <CCol xs="auto"> - <CButton color="primary" type="submit" className="mb-3">Confirm identity</CButton> - </CCol> -</CForm> -``` - -## File input - -```jsx preview -<div className="mb-3"> - <CFormLabel htmlFor="formFile">Default file input example</CFormLabel> - <CFormInput type="file" id="formFile"/> -</div> -<div className="mb-3"> - <CFormLabel htmlFor="formFileMultiple">Multiple files input example</CFormLabel> - <CFormInput type="file" id="formFileMultiple" multiple/> -</div> -<div className="mb-3"> - <CFormLabel htmlFor="formFileDisabled">Disabled file input example</CFormLabel> - <CFormInput type="file" id="formFileDisabled" disabled/> -</div> -<div className="mb-3"> - <CFormLabel htmlFor="formFileSm">Small file input example</CFormLabel> - <CFormInput type="file" size="sm" id="formFileSm"/> -</div> -<div> - <CFormLabel htmlFor="formFileLg">Large file input example</CFormLabel> - <CFormInput type="file" size="lg" id="formFileLg"/> -</div> -``` - -## Color - -```jsx preview -<CFormLabel htmlFor="exampleColorInput">Color picker</CFormLabel> -<CFormInput type="color" id="exampleColorInput" defaultValue="#563d7c" title="Choose your color" /> -``` - -## API - -### CFormInput - -`markdown:CFormInput.api.mdx` - -### CFormTextarea - -`markdown:CFormTextarea.api.mdx` diff --git a/packages/docs/content/forms/input-group.mdx b/packages/docs/content/forms/input-group.mdx deleted file mode 100644 index 0c11690a..00000000 --- a/packages/docs/content/forms/input-group.mdx +++ /dev/null @@ -1,356 +0,0 @@ ---- -title: React Input Group Component -name: Input group -description: Easily extend form controls by adding text, buttons, or button groups on either side of textual inputs, custom selects, and custom file inputs. -menu: Forms -route: /forms/input-group -other_frameworks: input-group ---- - -import { - CButton, - CDropdown, - CDropdownDivider, - CDropdownHeader, - CDropdownItem, - CDropdownItemPlain, - CDropdownMenu, - CDropdownToggle, - CForm, - CFormInput, - CFormCheck, - CFormLabel, - CFormSelect, - CFormTextarea, - CInputGroup, - CInputGroupText, - CCol, - CRow, -} from '@coreui/react/src/index' - -## Basic example - -Place one add-on or button on either side of an input. You may also place one on both sides of an input. Remember to place `<CFormLabel>`s outside the input group. - -```jsx preview -<CInputGroup className="mb-3"> - <CInputGroupText id="basic-addon1">@</CInputGroupText> - <CFormInput placeholder="Username" aria-label="Username" aria-describedby="basic-addon1"/> -</CInputGroup> - -<CInputGroup className="mb-3"> - <CFormInput placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="basic-addon2"/> - <CInputGroupText id="basic-addon2">@example.com</CInputGroupText> -</CInputGroup> - -<CFormLabel htmlFor="basic-url">Your vanity URL</CFormLabel> -<CInputGroup className="mb-3"> - <CInputGroupText id="basic-addon3">https://example.com/users/</CInputGroupText> - <CFormInput id="basic-url" aria-describedby="basic-addon3"/> -</CInputGroup> - -<CInputGroup className="mb-3"> - <CInputGroupText>$</CInputGroupText> - <CFormInput aria-label="Amount (to the nearest dollar)"/> - <CInputGroupText>.00</CInputGroupText> -</CInputGroup> - -<CInputGroup className="mb-3"> - <CFormInput placeholder="Username" aria-label="Username"/> - <CInputGroupText>@</CInputGroupText> - <CFormInput placeholder="Server" aria-label="Server"/> -</CInputGroup> - -<CInputGroup> - <CInputGroupText>With textarea</CInputGroupText> - <CFormTextarea aria-label="With textarea"></CFormTextarea> -</CInputGroup> -``` - -## Wrapping - -Input groups wrap by default via `flex-wrap: wrap` in order to accommodate custom form field validation within an input group. You may disable this with `.flex-nowrap`. - -```jsx preview -<CInputGroup className="flex-nowrap"> - <CInputGroupText id="addon-wrapping">@</CInputGroupText> - <CFormInput placeholder="Username" aria-label="Username" aria-describedby="addon-wrapping" /> -</CInputGroup> -``` - -## Sizing - -Add the relative form sizing classes to the `<CInputGroup>` itself and contents within will automatically resize—no need for repeating the form control size classes on each element. - -**Sizing on the individual input group elements isn't supported.** - -```jsx preview -<CInputGroup size="sm" className="mb-3"> - <CInputGroupText id="inputGroup-sizing-sm">Small</CInputGroupText> - <CFormInput aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm"/> -</CInputGroup> - -<CInputGroup className="mb-3"> - <CInputGroupText id="inputGroup-sizing-default">Default</CInputGroupText> - <CFormInput aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default"/> -</CInputGroup> - -<CInputGroup size="lg"> - <CInputGroupText id="inputGroup-sizing-lg">Large</CInputGroupText> - <CFormInput aria-label="Sizing example input" aria-describedby="inputGroup-sizing-lg"/> -</CInputGroup> -``` - -## Checkboxes and radios - -Place any checkbox or radio option within an input group's addon instead of text. - -```jsx preview -<CInputGroup className="mb-3"> - <CInputGroupText> - <CFormCheck type="checkbox" value="" aria-label="Checkbox for following text input"/> - </CInputGroupText> - <CFormInput aria-label="Text input with checkbox"/> -</CInputGroup> - -<CInputGroup> - <CInputGroupText> - <CFormCheck type="radio" value="" aria-label="Radio button for following text input"/> - </CInputGroupText> - <CFormInput aria-label="Text input with radio button"/> -</CInputGroup> -``` - -## Multiple inputs - -While multiple `<CFormInput>`s are supported visually, validation styles are only available for input groups with a single `<CFormInput>`. - -```jsx preview -<CInputGroup> - <CInputGroupText>First and last name</CInputGroupText> - <CFormInput aria-label="First name" /> - <CFormInput aria-label="Last name" /> -</CInputGroup> -``` - -## Multiple addons - -Multiple add-ons are supported and can be mixed with checkbox and radio input versions. - -```jsx preview -<CInputGroup className="mb-3"> - <CInputGroupText>$</CInputGroupText> - <CInputGroupText>0.00</CInputGroupText> - <CFormInput aria-label="Dollar amount (with dot and two decimal places)"/> -</CInputGroup> - -<CInputGroup> - <CFormInput aria-label="Dollar amount (with dot and two decimal places)"/> - <CInputGroupText>$</CInputGroupText> - <CInputGroupText>0.00</CInputGroupText> -</CInputGroup> -``` - -## Button addons - -```jsx preview -<CInputGroup className="mb-3"> - <CButton type="button" color="secondary" variant="outline" id="button-addon1">Button</CButton> - <CFormInput placeholder="" aria-label="Example text with button addon" aria-describedby="button-addon1"/> -</CInputGroup> - -<CInputGroup className="mb-3"> - <CFormInput placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="button-addon2"/> - <CButton type="button" color="secondary" variant="outline" id="button-addon2">Button</CButton> -</CInputGroup> - -<CInputGroup className="mb-3"> - <CButton type="button" color="secondary" variant="outline">Button</CButton> - <CButton type="button" color="secondary" variant="outline">Button</CButton> - <CFormInput placeholder="" aria-label="Example text with two button addons"/> -</CInputGroup> - -<CInputGroup> - <CFormInput placeholder="Recipient's username" aria-label="Recipient's username with two button addons"/> - <CButton type="button" color="secondary" variant="outline">Button</CButton> - <CButton type="button" color="secondary" variant="outline">Button</CButton> -</CInputGroup> -``` - -## Buttons with dropdowns - -```jsx preview -<CInputGroup className="mb-3"> - <CDropdown variant="input-group"> - <CDropdownToggle color="secondary" variant="outline">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CFormInput aria-label="Text input with dropdown button"/> -</CInputGroup> - -<CInputGroup className="mb-3"> - <CFormInput aria-label="Text input with dropdown button"/> - <CDropdown alignment="end" variant="input-group"> - <CDropdownToggle color="secondary" variant="outline">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> -</CInputGroup> - -<CInputGroup> - <CDropdown variant="input-group"> - <CDropdownToggle color="secondary" variant="outline">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CFormInput aria-label="Text input with 2 dropdown buttons"/> - <CDropdown alignment="end" variant="input-group"> - <CDropdownToggle color="secondary" variant="outline">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> -</CInputGroup> -``` - -## Segmented buttons - -```jsx preview -<CInputGroup className="mb-3"> - <CDropdown variant="input-group"> - <CButton type="button" color="secondary" variant="outline">Action</CButton> - <CDropdownToggle color="secondary" variant="outline" split/> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CFormInput aria-label="Text input with segmented dropdown button"/> -</CInputGroup> - -<CInputGroup> - <CFormInput aria-label="Text input with segmented dropdown button"/> - <CDropdown alignment="end" variant="input-group"> - <CButton type="button" color="secondary" variant="outline">Action</CButton> - <CDropdownToggle color="secondary" variant="outline" split/> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider/> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> -</CInputGroup> -``` - -## Custom forms - -Input groups include support for custom selects and custom file inputs. Browser default versions of these are not supported. - -### Custom select - -```jsx preview -<CInputGroup className="mb-3"> - <CInputGroupText component="label" htmlFor="inputGroupSelect01">Options</CInputGroupText> - <CFormSelect id="inputGroupSelect01"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> -</CInputGroup> - -<CInputGroup className="mb-3"> - <CFormSelect id="inputGroupSelect02"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - <CInputGroupText component="label" htmlFor="inputGroupSelect02">Options</CInputGroupText> -</CInputGroup> - -<CInputGroup className="mb-3"> - <CButton type="button" color="secondary" variant="outline">Button</CButton> - <CFormSelect id="inputGroupSelect03" aria-label="Example select with button addon"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> -</CInputGroup> - -<CInputGroup> - <CFormSelect id="inputGroupSelect04" aria-label="Example select with button addon"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - <CButton type="button" color="secondary" variant="outline">Button</CButton> -</CInputGroup> -``` - -### Custom file input - -```jsx preview -<CInputGroup className="mb-3"> - <CInputGroupText component="label" htmlFor="inputGroupFile01">Upload</CInputGroupText> - <CFormInput type="file" id="inputGroupFile01"/> -</CInputGroup> - -<CInputGroup className="mb-3"> - <CFormInput type="file" id="inputGroupFile02"/> - <CInputGroupText component="label" htmlFor="inputGroupFile02">Upload</CInputGroupText> -</CInputGroup> - -<CInputGroup className="mb-3"> - <CButton type="button" color="secondary" variant="outline" id="inputGroupFileAddon03">Button</CButton> - <CFormInput type="file" id="inputGroupFile03" aria-describedby="inputGroupFileAddon03" aria-label="Upload"/> -</CInputGroup> - -<CInputGroup> - <CFormInput type="file" id="inputGroupFile04" aria-describedby="inputGroupFileAddon04" aria-label="Upload"/> - <CButton type="button" color="secondary" variant="outline" id="inputGroupFileAddon04">Button</CButton> -</CInputGroup> -``` - -## Customizing - -### SASS variables - -<ScssDocs file="_variables.scss" capture="input-group-variables" /> - -## API - -### CInputGroup - -`markdown:CInputGroup.api.mdx` - -### CInputGroupText - -`markdown:CInputGroupText.api.mdx` diff --git a/packages/docs/content/forms/input-mask.mdx b/packages/docs/content/forms/input-mask.mdx deleted file mode 100644 index 8c682e77..00000000 --- a/packages/docs/content/forms/input-mask.mdx +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: React Input Mask -name: Input mask -description: React input masks allow you to regulate the format of data entered. Yyou can enhance data entry accuracy by implementing react input masks for fields with consistent formatting requirements. This ensures that users input data correctly, such as accurately formatted phone numbers in a designated phone number field. -menu: Forms -route: /forms/input-mask ---- - -import { CFormInput } from '@coreui/react/src/index' - -import { IMaskMixin } from 'react-imask' - -## Usage - -While CoreUI for React does not currently include a 'mask' feature, it can be enhanced by leveraging existing libraries like `react-imask` to extend the functionality of our components. - -To enable the extension of the `<CFormInput />` component, please ensure that you have installed `react-imask` first. - -```bash -npm install react-imask -``` - -or - -```bash -yarn add react-imask -``` - -Once you have installed react-imask, you can proceed to create a custom component with a mask. - -```jsx -import { IMaskMixin } from 'react-imask' -``` - -```jsx -const CFormInputWithMask = IMaskMixin(({ inputRef, ...props }) => ( - <CFormInput - {...props} - ref={inputRef} // bind internal input - /> -)) -``` - -Here is an example of a date mask for reference. - -export const MaskExample = () => { - const CFormInputWithMask = IMaskMixin(({ inputRef, ...props }) => ( - <CFormInput {...props} ref={inputRef} /> - )) - return ( - <CFormInputWithMask - mask={Date} - min={new Date(1990, 0, 1)} - max={new Date(2020, 0, 1)} - lazy={false} - /> - ) -} - -<Example> - <MaskExample /> -</Example> - -```jsx -const CFormInputWithMask = IMaskMixin(({ inputRef, ...props }) => ( - <CFormInput {...props} ref={inputRef} /> -)) -return ( - <CFormInputWithMask - mask={Date} - min={new Date(1990, 0, 1)} - max={new Date(2020, 0, 1)} - lazy={false} - /> -) -``` - -## Example masks - -Please take a moment to review some example masks you can use for reference. These examples serve as helpful templates for implementing input masks and can assist you in effectively controlling data entry formats. - -### Phone - -This example react input mask for a phone number follows the format commonly used in North America. It consists of three groups of numbers: the area code enclosed in parentheses, followed by a space, and then the seven-digit phone number separated by a hyphen. - -export const PhoneMaskExample = () => { - const CFormInputWithMask = IMaskMixin(({ inputRef, ...props }) => ( - <CFormInput {...props} ref={inputRef} /> - )) - return <CFormInputWithMask mask="+{1}(000)000-00-00" /> -} - -<Example> - <PhoneMaskExample /> -</Example> - -```jsx -const CFormInputWithMask = IMaskMixin(({ inputRef, ...props }) => ( - <CFormInput {...props} ref={inputRef} /> -)) -return <CFormInputWithMask mask="+{1}(000)000-00-00" /> -``` - -### Credit Card - -The provided code snippet demonstrates an implementation of an react input mask for a credit card number using the IMask library in JavaScript. The mask is set to "0000 0000 0000 0000", indicating that the input should consist of a 16-digit credit card number with spaces separating every four digits. The component renders an input field with the specified mask, allowing users to enter credit card numbers in the desired format. - -export const CreditCardMaskExample = () => { - const CFormInputWithMask = IMaskMixin(({ inputRef, ...props }) => ( - <CFormInput {...props} ref={inputRef} /> - )) - return <CFormInputWithMask mask="0000 0000 0000 0000" /> -} - -<Example> - <CreditCardMaskExample /> -</Example> - -```jsx -const CFormInputWithMask = IMaskMixin(({ inputRef, ...props }) => ( - <CFormInput {...props} ref={inputRef} /> -)) -return <CFormInputWithMask mask="0000 0000 0000 0000" /> -``` - -For more information on how to use the input mask, you can refer to the following resource: https://imask.js.org/ diff --git a/packages/docs/content/forms/input.mdx b/packages/docs/content/forms/input.mdx deleted file mode 100644 index ae96c755..00000000 --- a/packages/docs/content/forms/input.mdx +++ /dev/null @@ -1,192 +0,0 @@ ---- -title: React Form Input Component -name: Form control -description: React input components. Give textual form `<input>`s an upgrade with custom styles, sizing, focus states, validation, and more. -menu: Forms -route: /forms/input -other_frameworks: input ---- - -import { - CButton, - CForm, - CFormFloating, - CFormInput, - CFormLabel, - CFormText, - CFormTextarea, - CCol, - CRow, -} from '@coreui/react/src/index' - -## Example - -```jsx preview -<CForm> - <CFormInput - type="email" - id="exampleFormControlInput1" - label="Email address" - placeholder="name@example.com" - text="Must be 8-20 characters long." - aria-describedby="exampleFormControlInputHelpInline" - /> -</CForm> -``` - -If you need to add custom classNames to form's components, or need to add some custom elements you can add each form component separately. Please check the example below. - -```jsx -<CForm> - <CFormLabel htmlFor="exampleFormControlInput1">Email address</CFormLabel> - <CFormInput type="email" id="exampleFormControlInput1" placeholder="name@example.com" aria-describedby="exampleFormControlInputHelpInline" /> - <CFormText component="span" id="exampleFormControlInputHelpInline"> - Must be 8-20 characters long. - </CFormText> -</CForm> -``` - -## Sizing - -Set heights using `size` property like `size="lg"` and `size="sm"`. - -```jsx preview -<CFormInput type="text" size="lg" placeholder="Large input" aria-label="lg input example"/> -<CFormInput type="text" placeholder="Default input" aria-label="default input example"/> -<CFormInput type="text" size="sm" placeholder="Small input" aria-label="sm input example"/> -``` - -## Disabled - -Add the `disabled` boolean attribute on an input to give it a grayed out appearance and remove pointer events. - -```jsx preview -<CFormInput type="text" placeholder="Disabled input" aria-label="Disabled input example" disabled/> -<CFormInput type="text" placeholder="Disabled readonly input" aria-label="Disabled input example" disabled readOnly/> -``` - -## Readonly - -Add the `readOnly` boolean attribute on an input to prevent modification of the input's value. Read-only inputs appear lighter (just like disabled inputs), but retain the standard cursor. - -```jsx preview -<CFormInput - type="text" - placeholder="Readonly input here..." - aria-label="readonly input example" - readOnly -/> -``` - -## Readonly plain text - -If you want to have `<input readonly>` elements in your form styled as plain text, use the `plainText` boolean property to remove the default form field styling and preserve the correct margin and padding. - -```jsx preview -<CRow className="mb-3"> - <CFormLabel htmlFor="staticEmail" className="col-sm-2 col-form-label">Email</CFormLabel> - <CCol sm={10}> - <CFormInput type="text" id="staticEmail" defaultValue="email@example.com" readOnly plainText/> - </CCol> -</CRow> -<CRow className="mb-3"> - <CFormLabel htmlFor="inputPassword" className="col-sm-2 col-form-label">Password</CFormLabel> - <CCol sm={10}> - <CFormInput type="password" id="inputPassword"/> - </CCol> -</CRow> -``` - -```jsx preview -<CForm className="row g-3"> - <CCol xs="auto"> - <CFormLabel htmlFor="staticEmail2" className="visually-hidden"> - Email - </CFormLabel> - <CFormInput type="text" id="staticEmail2" defaultValue="email@example.com" readOnly plainText /> - </CCol> - <CCol xs="auto"> - <CFormLabel htmlFor="inputPassword2" className="visually-hidden"> - Password - </CFormLabel> - <CFormInput type="password" id="inputPassword2" placeholder="Password" /> - </CCol> - <CCol xs="auto"> - <CButton color="primary" type="submit" className="mb-3"> - Confirm identity - </CButton> - </CCol> -</CForm> -``` - -## File input - -<Example> - -</Example> - -```jsx preview -<div className="mb-3"> - <CFormInput type="file" id="formFile" label="Default file input example" /> -</div> -<div className="mb-3"> - <CFormInput type="file" id="formFileMultiple" label="Multiple files input example" multiple /> -</div> -<div className="mb-3"> - <CFormInput type="file" id="formFileDisabled" label="Disabled file input example" disabled /> -</div> -<div className="mb-3"> - <CFormInput type="file" size="sm" id="formFileSm" label="Small file input example" /> -</div> -<div> - <CFormInput type="file" size="lg" id="formFileLg" label="Large file input example" /> -</div> -``` - -## Color - -```jsx preview -<CFormInput - type="color" - id="exampleColorInput" - defaultValue="#563d7c" - label="Color picker" - title="Choose your color" -/> -``` - -## Customizing - -### SASS variables - -`$input-*` are shared across most of our form controls (and not buttons). - -<ScssDocs file="_variables.scss" capture="form-input-variables" /> - -`$form-label-*` and `$form-text-*` are for our `<CFormLabel />`s and `<CFormText />` component. - -<ScssDocs file="_variables.scss" capture="form-label-variables" /> - -<ScssDocs file="_variables.scss" capture="form-text-variables" /> - -`$form-file-*` are for file input. - -<ScssDocs file="_variables.scss" capture="form-file-variables" /> - -## API - -### CFormInput - -`markdown:CFormInput.api.mdx` - -### CFormFeedback - -`markdown:CFormFeedback.api.mdx` - -### CFormLabel - -`markdown:CFormLabel.api.mdx` - -### CFormText - -`markdown:CFormText.api.mdx` diff --git a/packages/docs/content/forms/layout.mdx b/packages/docs/content/forms/layout.mdx deleted file mode 100644 index 91c6c988..00000000 --- a/packages/docs/content/forms/layout.mdx +++ /dev/null @@ -1,290 +0,0 @@ ---- -title: React Form Layout -name: Layout -description: Give your forms some structure—from inline to horizontal to custom grid implementations—with our form layout options. -menu: Forms -route: /forms/layout ---- - -import { - CButton, - CDropdown, - CDropdownDivider, - CDropdownHeader, - CDropdownItem, - CDropdownItemPlain, - CDropdownMenu, - CDropdownToggle, - CForm, - CFormCheck, - CFormInput, - CFormLabel, - CFormSelect, - CInputGroup, - CInputGroupText, - CCol, - CRow -} from '@coreui/react/src/index' - -## Forms - -Every group of form fields should reside in a `<CForm>` element. CoreUI provides no default styling for the `<CForm>` element, but there are some powerful browser features that are provided by default. - -- New to browser forms? Consider reviewing [the MDN form docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) for an overview and complete list of available attributes. -- `<CButton>`s within a `<CForm>` default to `type="submit"`, so strive to be specific and always include a `type`. -- You can disable every form element within a form with the `disabled` attribute on the `<CForm>`. - -Since CoreUI applies `display: block` and `width: 100%` to almost all our form controls, forms will by default stack vertically. Additional classes can be used to vary this layout on a per-form basis. - -## Utilities - -[Margin utilities](https://coreui.io/docs/utilities/spacing/) are the easiest way to add some structure to forms. They provide basic grouping of labels, controls, optional form text, and form validation messaging. We recommend sticking to `margin-bottom` utilities, and using a single direction throughout the form for consistency. - -## Form grid - -More complex forms can be built using our grid classes. Use these for form layouts that require multiple columns, varied widths, and additional alignment options. - -```jsx preview -<CRow> - <CCol xs> - <CFormInput placeholder="First name" aria-label="First name"/> - </CCol> - <CCol xs> - <CFormInput placeholder="Last name" aria-label="Last name"/> - </CCol> -</CRow> -``` - -## Gutters - -By adding [gutter modifier classes](https://coreui.io/docs/layout/gutters/), you can have control over the gutter width in as well the inline as block direction. - -```jsx preview -<CRow className="g-3"> - <CCol xs> - <CFormInput placeholder="First name" aria-label="First name"/> - </CCol> - <CCol xs> - <CFormInput placeholder="Last name" aria-label="Last name"/> - </CCol> -</CRow> -``` - -More complex layouts can also be created with the grid system. - -```jsx preview -<CForm className="row g-3"> - <CCol md={6}> - <CFormInput type="email" id="inputEmail4" label="Email" /> - </CCol> - <CCol md={6}> - <CFormInput type="password" id="inputPassword4" label="Password" /> - </CCol> - <CCol xs={12}> - <CFormInput id="inputAddress" label="Address" placeholder="1234 Main St"/> - </CCol> - <CCol xs={12}> - <CFormInput id="inputAddress2" label="Address 2" placeholder="Apartment, studio, or floor"/> - </CCol> - <CCol md={6}> - <CFormInput id="inputCity" label="City"/> - </CCol> - <CCol md={4}> - <CFormSelect id="inputState" label="State"> - <option>Choose...</option> - <option>...</option> - </CFormSelect> - </CCol> - <CCol md={2}> - <CFormInput id="inputZip" label="Zip" /> - </CCol> - <CCol xs={12}> - <CFormCheck type="checkbox" id="gridCheck" label="Check me out"/> - </CCol> - <CCol xs={12}> - <CButton color="primary" type="submit">Sign in</CButton> - </CCol> -</CForm> -``` - -## Horizontal form - -Create horizontal forms with the grid by adding the `.row` class to form groups and using the `.col-*-*` classes to specify the width of your labels and controls. Be sure to add `.col-form-label` to your `<CFormLabel>`s as well so they're vertically centered with their associated form controls. - -At times, you maybe need to use margin or padding utilities to create that perfect alignment you need. For example, we've removed the `padding-top` on our stacked radio inputs label to better align the text baseline. - -```jsx preview -<CForm> - <CRow className="mb-3"> - <CFormLabel htmlFor="inputEmail3" className="col-sm-2 col-form-label">Email</CFormLabel> - <CCol sm={10} > - <CFormInput type="email" id="inputEmail3"/> - </CCol> - </CRow> - <CRow className="mb-3"> - <CFormLabel htmlFor="inputPassword3" className="col-sm-2 col-form-label">Password</CFormLabel> - <CCol sm={10} > - <CFormInput type="password" id="inputPassword3"/> - </CCol> - </CRow> - <fieldset className="row mb-3"> - <legend className="col-form-label col-sm-2 pt-0">Radios</legend> - <CCol sm={10} > - <CFormCheck type="radio" name="gridRadios" id="gridRadios1" value="option1" label="First radio" defaultChecked/> - <CFormCheck type="radio" name="gridRadios" id="gridRadios2" value="option2" label="Second radio"/> - <CFormCheck type="radio" name="gridRadios" id="gridRadios3" value="option3" label="Third disabled radio" disabled/> - </CCol> - </fieldset> - <CRow className="mb-3"> - <div className="col-sm-10 offset-sm-2"> - <CFormCheck type="checkbox" id="gridCheck1" label="Example checkbox"/> - </div> - </CRow> - <CButton color="primary" type="submit">Sign in</CButton> -</CForm> -``` - -### Horizontal form label sizing - -Be sure to use `.col-form-label-sm` or `.col-form-label-lg` to your `<CFormLabel>`s or `<legend>`s to correctly follow the size of `.form-control-lg` and `.form-control-sm`. - -```jsx preview -<CRow className="mb-3"> - <CFormLabel htmlFor="colFormLabelSm" className="col-sm-2 col-form-label col-form-label-sm">Email</CFormLabel> - <CCol sm={10} > - <CFormInput type="email" className="form-control form-control-sm" id="colFormLabelSm" placeholder="col-form-label-sm"/> - </CCol> -</CRow> -<CRow className="mb-3"> - <CFormLabel htmlFor="colFormLabel" className="col-sm-2 col-form-label">Email</CFormLabel> - <CCol sm={10} > - <CFormInput type="email" id="colFormLabel" placeholder="col-form-label"/> - </CCol> -</CRow> -<CRow> - <CFormLabel htmlFor="colFormLabelLg" className="col-sm-2 col-form-label col-form-label-lg">Email</CFormLabel> - <CCol sm={10} > - <CFormInput type="email" className="form-control form-control-lg" id="colFormLabelLg" placeholder="col-form-label-lg"/> - </CCol> -</CRow> -``` - -## Column sizing - -As shown in the previous examples, our grid system allows you to place any number of `<CCol>`s within a `<CRow>`. They'll split the available width equally between them. You may also pick a subset of your columns to take up more or less space, while the remaining `<CCol>`s equally split the rest, with specific column classes like `<CCol sm={7} >`. - -```jsx preview -<CRow className="g-3"> - <CCol sm={7} > - <CFormInput placeholder="City" aria-label="City"/> - </CCol> - <CCol sm> - <CFormInput placeholder="State" aria-label="State"/> - </CCol> - <CCol sm> - <CFormInput placeholder="Zip" aria-label="Zip"/> - </CCol> -</CRow> -``` - -## Auto-sizing - -The example below uses a flexbox utility to vertically center the contents and changes `<CCol>` to `<CCol xs="auto">` so that your columns only take up as much space as needed. Put another way, the column sizes itself based on the contents. - -```jsx preview -<CForm className="row gy-2 gx-3 align-items-center"> - <CCol xs="auto"> - <CFormLabel className="visually-hidden" htmlFor="autoSizingInput">Name</CFormLabel> - <CFormInput id="autoSizingInput" placeholder="Jane Doe"/> - </CCol> - <CCol xs="auto"> - <CFormLabel className="visually-hidden" htmlFor="autoSizingInputGroup">Username</CFormLabel> - <CInputGroup> - <CInputGroupText>@</CInputGroupText> - <CFormInput id="autoSizingInputGroup" placeholder="Username"/> - </CInputGroup> - </CCol> - <CCol xs="auto"> - <CFormLabel className="visually-hidden" htmlFor="autoSizingSelect">Preference</CFormLabel> - <CFormSelect id="autoSizingSelect"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </CCol> - <CCol xs="auto"> - <CFormCheck type="checkbox" id="autoSizingCheck" label="Remember me"/> - </CCol> - <CCol xs="auto"> - <CButton color="primary" type="submit">Submit</CButton> - </CCol> -</CForm> -``` - -You can then remix that once again with size-specific column classes. - -```jsx preview -<CForm className="row gx-3 gy-2 align-items-center"> - <CCol sm={3} > - <CFormLabel className="visually-hidden" htmlFor="specificSizeInputName">Name</CFormLabel> - <CFormInput id="specificSizeInputName" placeholder="Jane Doe"/> - </CCol> - <CCol sm={3} > - <CFormLabel className="visually-hidden" htmlFor="specificSizeInputGroupUsername">Username</CFormLabel> - <CInputGroup> - <CInputGroupText>@</CInputGroupText> - <CFormInput id="specificSizeInputGroupUsername" placeholder="Username"/> - </CInputGroup> - </CCol> - <CCol sm={3} > - <CFormLabel className="visually-hidden" htmlFor="specificSizeSelect">Preference</CFormLabel> - <CFormSelect id="specificSizeSelect"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </CCol> - <CCol xs="auto"> - <CFormCheck type="checkbox" id="autoSizingCheck2" label="Remember me"/> - </CCol> - <CCol xs="auto"> - <CButton color="primary" type="submit">Submit</CButton> - </CCol> -</CForm> -``` - -## Inline forms - -Use the `<CCol xs="auto">` class to create horizontal layouts. By adding [gutter modifier classes](https://coreui.io/docs/layout/gutters/), we will have gutters in horizontal and vertical directions. The `.align-items-center` aligns the form elements to the middle, making the `<CFormCheck>` align properly. - -```jsx preview -<CForm className="row row-cols-lg-auto g-3 align-items-center"> - <CCol xs={12}> - <CFormLabel className="visually-hidden" htmlFor="inlineFormInputGroupUsername">Username</CFormLabel> - <CInputGroup> - <CInputGroupText>@</CInputGroupText> - <CFormInput id="inlineFormInputGroupUsername" placeholder="Username"/> - </CInputGroup> - </CCol> - - <CCol xs={12}> - <CFormLabel className="visually-hidden" htmlFor="inlineFormSelectPref">Preference</CFormLabel> - <CFormSelect id="inlineFormSelectPref"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </CCol> - - <CCol xs={12}> - <CFormCheck type="checkbox" id="inlineFormCheck" label="Remember me"/> - </CCol> - - <CCol xs={12}> - <CButton color="primary" type="submit">Submit</CButton> - </CCol> -</CForm> -``` diff --git a/packages/docs/content/forms/overview.mdx b/packages/docs/content/forms/overview.mdx deleted file mode 100644 index a7e70c71..00000000 --- a/packages/docs/content/forms/overview.mdx +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: React Form Components -name: Overview -description: Examples and usage guidelines for form control styles, layout options, and custom components for creating a wide variety of forms. -menu: Forms -route: /forms/overview ---- - -import { - CButton, - CForm, - CFormCheck, - CFormInput, - CFormLabel, - CFormSelect, - CFormText, - CCol, - CRow, -} from '@coreui/react/src/index' - -## Overview - -CoreUI’s form controls expand on our Rebooted form styles with classes. Use these classes to opt into their customized displays for a more consistent rendering across browsers and devices. - -Be sure to use an appropriate `type` attribute on all inputs (e.g., `email` for email address or `number` for numerical information) to take advantage of newer input controls like email verification, number selection, and more. - -Here’s a quick example to demonstrate CoreUI’s form styles. Keep reading for documentation on required classes, form layout, and more. - -<Example> - <CForm> - <div className="mb-3"> - <CFormLabel htmlFor="exampleInputEmail1">Email address</CFormLabel> - <CFormInput type="email" id="exampleInputEmail1" aria-describedby="emailHelp" /> - <CFormText id="emailHelp">We'll never share your email with anyone else.</CFormText> - </div> - <div className="mb-3"> - <CFormLabel htmlFor="exampleInputPassword1">Email Password</CFormLabel> - <CFormInput type="password" id="exampleInputPassword1" /> - </div> - <CFormCheck - className="mb-3" - label="Check me out" - onChange={(e) => { - console.log(e.target) - }} - /> - <CButton type="submit" color="primary"> - Submit - </CButton> - </CForm> -</Example> - -```jsx -<CForm> - <div className="mb-3"> - <CFormLabel htmlFor="exampleInputEmail1">Email address</CFormLabel> - <CFormInput type="email" id="exampleInputEmail1" aria-describedby="emailHelp" /> - <CFormText id="emailHelp">We'll never share your email with anyone else.</CFormText> - </div> - <div className="mb-3"> - <CFormLabel htmlFor="exampleInputPassword1">Email Password</CFormLabel> - <CFormInput type="password" id="exampleInputPassword1" /> - </div> - <CFormCheck - className="mb-3" - label="Check me out" - onChange={(e) => { - console.log(e.target) - }} - /> - <CButton type="submit" color="primary"> - Submit - </CButton> -</CForm> -``` - -## Form text - -Block-level or inline-level form text can be created using `<CFormText>`. - -Associating form text with form controls -Form text should be explicitly associated with the form control it relates to using the aria-describedby attribute. This will ensure that assistive technologies—such as screen readers—will announce this form text when the user focuses or enters the control. - -Form text below inputs can be styled with `<CFormText>`. If a block-level element will be used, a top margin is added for easy spacing from the inputs above. - -<Example> - <CForm> - <div className="mb-3"> - <CFormLabel htmlFor="inputPassword5">Password</CFormLabel> - <CFormInput type="password" id="inputPassword5" aria-describedby="passwordHelpBlock" /> - <CFormText id="passwordHelpBlock"> - Your password must be 8-20 characters long, contain letters and numbers, and must not - contain spaces, special characters, or emoji. - </CFormText> - </div> - </CForm> -</Example> - -```jsx -<CForm> - <div className="mb-3"> - <CFormLabel htmlFor="inputPassword5">Password</CFormLabel> - <CFormInput type="password" id="inputPassword5" aria-describedby="passwordHelpBlock" /> - <CFormText id="passwordHelpBlock"> - Your password must be 8-20 characters long, contain letters and numbers, and must not - contain spaces, special characters, or emoji. - </CFormText> - </div> -</CForm> -``` - -Inline text can use any typical inline HTML element (be it a `<span>`, `<small>`, or something else) with nothing more than the `.form-text` class. - -<Example> - <CRow className="g-3 align-items-center"> - <CCol xs="auto"> - <CFormLabel htmlFor="inputPassword6" className="col-form-label"> - Password - </CFormLabel> - </CCol> - <CCol xs="auto"> - <CFormInput type="password" id="inputPassword6" aria-describedby="passwordHelpInline" /> - </CCol> - <CCol xs="auto"> - <CFormText component="span" id="passwordHelpInline"> - Must be 8-20 characters long. - </CFormText> - </CCol> - </CRow> -</Example> - -```jsx -<CRow className="g-3 align-items-center"> - <CCol xs="auto"> - <CFormLabel htmlFor="inputPassword6" className="col-form-label"> - Password - </CFormLabel> - </CCol> - <CCol xs="auto"> - <CFormInput type="password" id="inputPassword6" aria-describedby="passwordHelpInline" /> - </CCol> - <CCol xs="auto"> - <CFormText component="span" id="passwordHelpInline"> - Must be 8-20 characters long. - </CFormText> - </CCol> -</CRow> -``` - -## Disabled forms - -Add the `disabled` boolean attribute on an input to prevent user interactions and make it appear lighter. - -```jsx -<CFormLabel id="disabledInput" type="text" placeholder="Disabled input here..." disabled /> -``` - -Add the `disabled` attribute to a `<fieldset>` to disable all the controls within. Browsers treat all native form controls (`<input>`, `<select>`, and `<button>` elements) inside a `<fieldset disabled>` as disabled, preventing both keyboard and mouse interactions on them. - -However, if your form also includes custom button-like elements such as `<CButton>...</CButton>`, these will only be given a style of `pointer-events: none`, meaning they are still focusable and operable using the keyboard. In this case, you must manually modify these controls by adding `tabindex="-1"` to prevent them from receiving focus and `aria-disabled="disabled"` to signal their state to assistive technologies. - -<Example> - <CForm> - <fieldset disabled> - <legend>Disabled fieldset example</legend> - <div className="mb-3"> - <CFormLabel htmlFor="disabledTextInput">Disabled input</CFormLabel> - <CFormInput id="disabledTextInput" placeholder="Disabled input" /> - </div> - <div className="mb-3"> - <CFormLabel htmlFor="disabledSelect">Disabled select menu</CFormLabel> - <CFormSelect id="disabledSelect"> - <option>Disabled select</option> - </CFormSelect> - </div> - <div className="mb-3"> - <CFormCheck id="disabledFieldsetCheck" label="Can't check this" disabled /> - </div> - <CButton color="primary" type="submit">Submit</CButton> - </fieldset> - </CForm> -</Example> - -```jsx -<CForm> - <fieldset disabled> - <legend>Disabled fieldset example</legend> - <div className="mb-3"> - <CFormLabel htmlFor="disabledTextInput">Disabled input</CFormLabel> - <CFormInput id="disabledTextInput" placeholder="Disabled input" /> - </div> - <div className="mb-3"> - <CFormLabel htmlFor="disabledSelect">Disabled select menu</CFormLabel> - <CFormSelect id="disabledSelect"> - <option>Disabled select</option> - </CFormSelect> - </div> - <div className="mb-3"> - <CFormCheck id="disabledFieldsetCheck" label="Can't check this" disabled /> - </div> - <CButton color="primary" type="submit">Submit</CButton> - </fieldset> -</CForm> -``` diff --git a/packages/docs/content/forms/radio.mdx b/packages/docs/content/forms/radio.mdx deleted file mode 100644 index ee4d3ba0..00000000 --- a/packages/docs/content/forms/radio.mdx +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: React Radio Components -name: Radio -description: Create consistent cross-browser and cross-device radios with our React radio component. -menu: Forms -route: /forms/radio -other_frameworks: radio ---- - -import { useEffect, useRef } from 'react' -import { - CButton, - CFormCheck, -} from '@coreui/react/src/index' - -## Approach - -Browser default radios are replaced with the help of `<CFormCheck radio>`. Radios are for selecting one option from many. - -## Radios - -Add the `disabled` attribute and the associated `<label>`s are automatically styled to match with a lighter color to help indicate the input's state. - -```jsx preview -<CFormCheck type="radio" name="flexRadioDefault" id="flexRadioDefault1" label="Default radio"/> -<CFormCheck type="radio" name="flexRadioDefault" id="flexRadioDefault2" label="Checked radio" defaultChecked/> -``` - -### Disabled - -```jsx preview -<CFormCheck type="radio" name="flexRadioDisabled" id="flexRadioDisabled" label="Disabled radio" disabled/> -<CFormCheck type="radio" name="flexRadioDisabled" id="flexRadioCheckedDisabled" label="Disabled checked radio" defaultChecked disabled/> -``` - -## Default (stacked) - -By default, any number of radios that are immediate sibling will be vertically stacked and appropriately spaced. - -```jsx preview -<CFormCheck type="radio" name="exampleRadios" id="exampleRadios1" value="option1" label="Default radio" defaultChecked/> -<CFormCheck type="radio" name="exampleRadios" id="exampleRadios2" value="option2" label="Second default radio"/> -<CFormCheck type="radio" name="exampleRadios" id="exampleRadios3" value="option3" label="Disabled radio" disabled/> -``` - -## Inline - -Group radios on the same horizontal row by adding `inline` boolean property to any `<CFormCheck radio>`. - -```jsx preview -<CFormCheck inline type="radio" name="inlineRadioOptions" id="inlineCheckbox1" value="option1" label="1"/> -<CFormCheck inline type="radio" name="inlineRadioOptions" id="inlineCheckbox2" value="option2" label="2"/> -<CFormCheck inline type="radio" name="inlineRadioOptions" id="inlineCheckbox3" value="option3" label="3 (disabled)" disabled/> -``` - -## Reverse - -Put your radios on the opposite side by adding `reverse` boolean property. - -```jsx preview -<CFormCheck reverse type="radio" id="reverseOption1" value="option1" label="Reverse radio"/> -<CFormCheck reverse type="radio" id="reverseOption2" value="option2" label="Disabled reverse radio" disabled/> -``` - -## Without labels - -Remember to still provide some form of accessible name for assistive technologies (for instance, using `aria-label`). - -```jsx preview -<CFormCheck type="radio" name="radioNoLabel" id="radioNoLabel" value="" aria-label="..."/> -``` - -## Radio toggle buttons - -Create button-like radio buttons by using `button` boolean property on the `<CFormCheck radio>` component. These toggle buttons can further be grouped in a button group if needed. - -```jsx preview -<CFormCheck button={{ color: 'secondary' }} type="radio" name="options" id="option1" autoComplete="off" label="Checked" defaultChecked/> -<CFormCheck button={{ color: 'secondary' }} type="radio" name="options" id="option2" autoComplete="off" label="Radio"/> -<CFormCheck button={{ color: 'secondary' }} type="radio" name="options" id="option3" autoComplete="off" label="Radio" disabled/> -<CFormCheck button={{ color: 'secondary' }} type="radio" name="options" id="option4" autoComplete="off" label="Radio"/> -``` - -### Outlined styles - -Different variants of button, such at the various outlined styles, are supported. - -```jsx preview -<CFormCheck button={{ color: 'success', variant: 'outline' }} type="radio" name="options-outlined" id="success-outlined" autoComplete="off" label="Radio" defaultChecked/> -<CFormCheck button={{ color: 'danger', variant: 'outline' }} type="radio" name="options-outlined" id="danger-outlined" autoComplete="off" label="Radio"/> -``` - -## Customizing - -### SASS variables - -<ScssDocs file="_variables.scss" capture="form-check-variables" /> - -## API - -### CFormCheck - -`markdown:CFormCheck.api.mdx` diff --git a/packages/docs/content/forms/range.mdx b/packages/docs/content/forms/range.mdx deleted file mode 100644 index e5370095..00000000 --- a/packages/docs/content/forms/range.mdx +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: React Range Component -name: Range -description: React range component. Use our custom range inputs for consistent cross-browser styling and built-in customization. -menu: Forms -route: /forms/range -other_frameworks: range ---- - -import { CForm, CFormLabel, CFormRange } from '@coreui/react/src/index' - -## Overview - -Create custom `<input type="range">` controls with `<CFormRange>`. The track (the background) and thumb (the value) are both styled to appear the same across browsers. As only Edge Legacy and Firefox supports "filling" their track from the left or right of the thumb as a means to visually indicate progress, we do not currently support it. - -```jsx preview -<CFormRange id="customRange1" label="Example range" /> -``` - -## Disabled - -Add the `disabled` boolean attribute on an input to give it a grayed out appearance and remove pointer events. - -```jsx preview -<CFormRange id="disabledRange" label="Disabled range" disabled /> -``` - -## Min and max - -Range inputs have implicit values for `min` and `max`—`0` and `100`, respectively. You may specify new values for those using the `min` and `max` attributes. - -```jsx preview -<CFormRange min={0} max={5} label="Example range" defaultValue="3" id="customRange2" /> -``` - -## Steps - -By default, range inputs "snap" to integer values. To change this, you can specify a `step` value. In the example below, we double the number of steps by using `step={0.5}`. - -```jsx preview -<CFormRange min={0} max={5} step={0.5} label="Example range" defaultValue="3" id="customRange3" /> -``` - -## Customizing - -### SASS variables - -<ScssDocs file="_variables.scss" capture="form-range-variables" /> - -## API - -### CFormRange - -`markdown:CFormRange.api.mdx` diff --git a/packages/docs/content/forms/select.mdx b/packages/docs/content/forms/select.mdx deleted file mode 100644 index 40613cc8..00000000 --- a/packages/docs/content/forms/select.mdx +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: React Select Component -name: Select -description: React select component. Customize the native `<select>`s with custom CSS that changes the element's initial appearance. -menu: Forms -route: /forms/select -other_frameworks: select ---- - -import { - CButton, - CForm, - CFormCheck, - CFormLabel, - CFormSelect, - CFormText, - CCol, - CRow, -} from '@coreui/react/src/index' - -## Default - -```jsx preview -<CFormSelect - aria-label="Default select example" - options={[ - 'Open this select menu', - { label: 'One', value: '1' }, - { label: 'Two', value: '2' }, - { label: 'Three', value: '3', disabled: true } - ]} -/> -``` -You can also add options manually - -```jsx -<CFormSelect aria-label="Default select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3" disabled>Three</option> -</CFormSelect> -``` - -## Sizing - -You may also choose from small and large custom selects to match our similarly sized text inputs. - -```jsx preview -<CFormSelect size="lg" className="mb-3" aria-label="Large select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> -</CFormSelect> -<CFormSelect size="sm" className="mb-3" aria-label="Small select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> -</CFormSelect> -``` - -The `multiple` attribute is also supported: - -```jsx preview -<CFormSelect size="lg" multiple aria-label="Multiple select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> -</CFormSelect> -``` - -As is the `htmlSize` property: - -```jsx preview -<CFormSelect htmlSize={3} multiple aria-label="size 3 select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> -</CFormSelect> -``` - -## Disabled - -Add the `disabled` boolean attribute on a select to give it a grayed out appearance and remove pointer events. - -```jsx preview -<CFormSelect aria-label="Disabled select example" disabled> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> -</CFormSelect> -``` - -## Customizing - -### SASS variables - -<ScssDocs file="_variables.scss" capture="form-select-variables" /> - -## API - -### CFormSelect - -`markdown:CFormSelect.api.mdx` diff --git a/packages/docs/content/forms/switch.mdx b/packages/docs/content/forms/switch.mdx deleted file mode 100644 index 4dd94510..00000000 --- a/packages/docs/content/forms/switch.mdx +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: React Switch Components -name: Switch -description: Create consistent cross-browser and cross-device switch component. -menu: Forms -route: /forms/checks-radios -other_frameworks: switch ---- - -import { useEffect, useRef } from 'react' -import { - CFormSwitch, -} from '@coreui/react/src/index' - -## About - -React Switch Components are a type of UI component that allows users to toggle between two states, usually represented as "on" or "off", "enabled" or "disabled", or "checked" or "unchecked". - -When a user interacts with the component by clicking or tapping on it, the switch toggles its state, triggering an action or changing the appearance of the component. This type of component is often used in forms, settings panels, and other places where users need to turn something on or off or choose between two options. - -## Example - -```jsx preview -<CFormSwitch label="Default switch checkbox input" id="formSwitchCheckDefault"/> -<CFormSwitch label="Checked switch checkbox input" id="formSwitchCheckChecked" defaultChecked/> -<CFormSwitch label="Disabled switch checkbox input" id="formSwitchCheckDisabled" disabled/> -<CFormSwitch label="Disabled checked switch checkbox input" id="formSwitchCheckCheckedDisabled" defaultChecked disabled/> -``` - -## Sizing - -Larger or smaller react switches? Add `size="lg"` or `size="xl"` for additional sizes. - -```jsx preview -<CFormSwitch label="Default switch checkbox input" id="formSwitchCheckDefaultNormal"/> -<CFormSwitch size="lg" label="Large switch checkbox input" id="formSwitchCheckDefaultLg"/> -<CFormSwitch size="xl" label="Extra large switch checkbox input" id="formSwitchCheckDefaultXL"/> -``` - -## Reverse - -Put your switches on the opposite side by adding `reverse` boolean property. - -```jsx preview -<CFormSwitch reverse type="radio" id="reverseFormSwitch1" label="Reverse switch"/> -<CFormSwitch reverse type="radio" id="reverseFormSwitch2" label="Disabled reverse switch" disabled/> -``` - -## Customizing - -### SASS variables - -<ScssDocs file="_variables.scss" capture="form-switch-variables" /> - -## API - -### CFormSwitch - -`markdown:CFormSwitch.api.mdx` diff --git a/packages/docs/content/forms/textarea.mdx b/packages/docs/content/forms/textarea.mdx deleted file mode 100644 index 95c61829..00000000 --- a/packages/docs/content/forms/textarea.mdx +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: React Form Text Component -name: Form control -description: React textarea components. Give textual form `<textarea>`s an upgrade with custom styles, sizing, focus states, validation, and more. -menu: Forms -route: /forms/textarea -other_frameworks: textarea ---- - -import { - CButton, - CForm, - CFormFloating, - CFormInput, - CFormLabel, - CFormText, - CFormTextarea, - CCol, - CRow, -} from '@coreui/react/src/index' - -## Example - -```jsx preview -<CForm> - <CFormTextarea - id="exampleFormControlTextarea1" - label="Example textarea" - rows={3} - text="Must be 8-20 words long." - ></CFormTextarea> -</CForm> -``` - -If you need to add custom classNames to form's components, or need to add some custom elements you can add each form component separately. Please check the example below. - -```jsx -<CFormLabel htmlFor="exampleFormControlTextarea1">Example textarea</CFormLabel> -<CFormTextarea id="exampleFormControlTextarea1" rows={3}></CFormTextarea> -<CFormText component="span" id="passwordHelpInline">Must be 8-20 words long.</CFormText> -``` - -## Disabled - -Add the `disabled` boolean attribute on an textarea to give it a grayed out appearance and remove pointer events. - -```jsx preview -<CFormTextarea - className="mb-3" - placeholder="Disabled textarea" - aria-label="Disabled textarea example" - disabled -></CFormTextarea> -``` - -## Readonly - -Add the `readOnly` boolean attribute on an textarea to prevent modification of the textarea's value. Read-only textareas appear lighter (just like disabled textareas), but retain the standard cursor. - -```jsx preview -<CFormTextarea - placeholder="Readonly textarea" - aria-label="Readonly textarea example" - disabled - readOnly -></CFormTextarea> -``` - -## Customizing - -### SASS variables - -`$input-*` are shared across most of our form controls (and not buttons). - -<ScssDocs file="_variables.scss" capture="form-input-variables" /> - -`$form-label-*` and `$form-text-*` are for our `<CFormLabel />`s and `<CFormText />` component. - -<ScssDocs file="_variables.scss" capture="form-label-variables" /> - -<ScssDocs file="_variables.scss" capture="form-text-variables" /> - -## API - -### CFormTextarea - -`markdown:CFormTextarea.api.mdx` - -### CFormFeedback - -`markdown:CFormFeedback.api.mdx` - -### CFormLabel - -`markdown:CFormLabel.api.mdx` - -### CFormText - -`markdown:CFormText.api.mdx` diff --git a/packages/docs/content/forms/validation.mdx b/packages/docs/content/forms/validation.mdx deleted file mode 100644 index 17020582..00000000 --- a/packages/docs/content/forms/validation.mdx +++ /dev/null @@ -1,697 +0,0 @@ ---- -title: React Form Validation -name: Validation -description: Provide valuable, actionable feedback to your users with HTML5 form validation, via browser default behaviors or custom styles and JavaScript. -menu: Forms -route: /forms/validation ---- - -import { useState } from 'react' - -import { - CButton, - CDropdown, - CDropdownDivider, - CDropdownHeader, - CDropdownItem, - CDropdownItemPlain, - CDropdownMenu, - CDropdownToggle, - CForm, - CFormCheck, - CFormInput, - CFormFeedback, - CFormLabel, - CFormSelect, - CFormTextarea, - CInputGroup, - CInputGroupText, - CCol, - CRow, -} from '@coreui/react/src/index' - -## Example - -For custom CoreUI form validation messages, you'll need to add the `noValidate` boolean property to your `<CForm>`. This disables the browser default feedback tooltips, but still provides access to the form validation APIs in JavaScript. Try to submit the form below; our JavaScript will intercept the submit button and relay feedback to you. When attempting to submit, you'll see the `:invalid` and `:valid` styles applied to your form controls. - -Custom feedback styles apply custom colors, borders, focus styles, and background icons to better communicate feedback. - -export const CustomStylesExample = () => { - const [validated, setValidated] = useState(false) - const handleSubmit = (event) => { - const form = event.currentTarget - if (form.checkValidity() === false) { - event.preventDefault() - event.stopPropagation() - } - setValidated(true) - } - return ( - <CForm - className="row g-3 needs-validation" - noValidate - validated={validated} - onSubmit={handleSubmit} - > - <CCol md={4}> - <CFormInput - type="text" - defaultValue="Mark" - feedbackValid="Looks good!" - id="validationCustom01" - label="First name" - required - /> - </CCol> - <CCol md={4}> - <CFormInput - type="text" - defaultValue="Otto" - feedbackValid="Looks good!" - id="validationCustom02" - label="First name" - required - /> - </CCol> - <CCol md={4}> - <CFormLabel htmlFor="validationCustomUsername">Username</CFormLabel> - <CInputGroup className="has-validation"> - <CInputGroupText>@</CInputGroupText> - <CFormInput - type="text" - aria-describedby="inputGroupPrependFeedback" - feedbackValid="Please choose a username." - id="validationCustomUsername" - required - /> - </CInputGroup> - </CCol> - <CCol md={6}> - <CFormInput - type="text" - aria-describedby="validationCustom03Feedback" - feedbackInvalid="Please provide a valid city." - id="validationCustom03" - label="City" - required - /> - </CCol> - <CCol md={3}> - <CFormSelect - aria-describedby="validationCustom04Feedback" - feedbackInvalid="Please select a valid state." - id="validationCustom04" - label="State" - required - > - <option selected="" disabled="" value=""> - Choose... - </option> - <option>...</option> - </CFormSelect> - </CCol> - <CCol md={3}> - <CFormInput - type="text" - aria-describedby="validationCustom05Feedback" - feedbackInvalid="Please provide a valid zip." - id="validationCustom05" - label="Zip" - required - /> - </CCol> - <CCol xs={12}> - <CFormCheck - type="checkbox" - id="invalidCheck" - label="Agree to terms and conditions" - required - /> - <CFormFeedback invalid>You must agree before submitting.</CFormFeedback> - </CCol> - <CCol xs={12}> - <CButton color="primary" type="submit"> - Submit form - </CButton> - </CCol> - </CForm> - ) -} - -<Example> - <CustomStylesExample /> -</Example> - -```jsx -const [validated, setValidated] = useState(false) -const handleSubmit = (event) => { - const form = event.currentTarget - if (form.checkValidity() === false) { - event.preventDefault() - event.stopPropagation() - } - setValidated(true) -} -return ( - <CForm - className="row g-3 needs-validation" - noValidate - validated={validated} - onSubmit={handleSubmit} - > - <CCol md={4}> - <CFormInput - type="text" - defaultValue="Mark" - feedbackValid="Looks good!" - id="validationCustom01" - label="First name" - required - /> - </CCol> - <CCol md={4}> - <CFormInput - type="text" - defaultValue="Otto" - feedbackValid="Looks good!" - id="validationCustom02" - label="First name" - required - /> - </CCol> - <CCol md={4}> - <CFormLabel htmlFor="validationCustomUsername">Username</CFormLabel> - <CInputGroup className="has-validation"> - <CInputGroupText>@</CInputGroupText> - <CFormInput - type="text" - aria-describedby="inputGroupPrependFeedback" - feedbackValid="Please choose a username." - id="validationCustomUsername" - required - /> - </CInputGroup> - </CCol> - <CCol md={6}> - <CFormInput - type="text" - aria-describedby="validationCustom03Feedback" - feedbackInvalid="Please provide a valid city." - id="validationCustom03" - label="City" - required - /> - </CCol> - <CCol md={3}> - <CFormSelect - aria-describedby="validationCustom04Feedback" - feedbackInvalid="Please select a valid state." - id="validationCustom04" - label="State" - required - > - <option disabled>Choose...</option> - <option>...</option> - </CFormSelect> - </CCol> - <CCol md={3}> - <CFormInput - type="text" - aria-describedby="validationCustom05Feedback" - feedbackInvalid="Please provide a valid zip." - id="validationCustom05" - label="Zip" - required - /> - </CCol> - <CCol xs={12}> - <CFormCheck - type="checkbox" - id="invalidCheck" - label="Agree to terms and conditions" - required - /> - <CFormFeedback invalid>You must agree before submitting.</CFormFeedback> - </CCol> - <CCol xs={12}> - <CButton color="primary" type="submit"> - Submit form - </CButton> - </CCol> - </CForm> -) -``` - -## Browser defaults - -Not interested in custom validation feedback messages or writing JavaScript to change form behaviors? All good, you can use the browser defaults. Try submitting the form below. Depending on your browser and OS, you'll see a slightly different style of feedback. - -While these feedback styles cannot be styled with CSS, you can still customize the feedback text through JavaScript. - -```jsx preview -<CForm className="row g-3"> - <CCol md={4}> - <CFormInput - type="text" - id="validationDefault01" - label="First name" - defaultValue="Mark" - required - /> - </CCol> - <CCol md={4}> - <CFormInput - type="text" - id="validationDefault02" - label="Last name" - defaultValue="Otto" - required - /> - </CCol> - <CCol md={4}> - <CFormLabel htmlFor="validationDefaultUsername">Username</CFormLabel> - <CInputGroup> - <CInputGroupText id="inputGroupPrepend02">@</CInputGroupText> - <CFormInput - type="text" - id="validationDefaultUsername" - defaultValue="" - aria-describedby="inputGroupPrepend02" - required - /> - </CInputGroup> - </CCol> - <CCol md={6}> - <CFormInput type="text" id="validationDefault03" label="City" required /> - </CCol> - <CCol md={3}> - <CFormSelect id="validationDefault04" label="State"> - <option disabled>Choose...</option> - <option>...</option> - </CFormSelect> - </CCol> - <CCol md={3}> - <CFormInput type="text" id="validationDefault05" label="Zip" required /> - </CCol> - <CCol xs={12}> - <CFormCheck type="checkbox" id="invalidCheck" label="Agree to terms and conditions" required /> - </CCol> - <CCol xs={12}> - <CButton color="primary" type="submit"> - Submit form - </CButton> - </CCol> -</CForm> -``` - -## Custom validation - -In case you require custom or server-side validation, you can indicate invalid and valid form fields with `invalid` and `valid` boolean properties. - -For invalid fields, ensure that the invalid feedback/error message is associated with the relevant form field using `aria-describedby` (noting that this attribute allows more than one `id` to be referenced, in case the field already points to additional form text). - -```jsx preview -<CForm className="row g-3"> - <CCol md={4}> - <CFormInput - type="text" - id="validationServer01" - label="Email" - feedback="Looks good!" - defaultValue="name@surname.com" - valid - required - /> - </CCol> - <CCol md={4}> - <CFormInput - type="text" - id="validationServer02" - label="Repeat email" - feedback="Looks good!" - defaultValue="name@surname.com" - valid - required - /> - </CCol> - <CCol md={4}> - <CFormLabel htmlFor="validationServerUsername">Username</CFormLabel> - <CInputGroup className="has-validation"> - <CInputGroupText id="inputGroupPrepend03">@</CInputGroupText> - <CFormInput - type="text" - id="validationServerUsername" - feedback="Please choose a username." - defaultValue="" - aria-describedby="inputGroupPrepend03" - invalid - required - /> - </CInputGroup> - </CCol> - <CCol md={6}> - <CFormInput - type="text" - id="validationServer03" - label="City" - feedback="Please provide a valid city." - invalid - required - /> - </CCol> - <CCol md={3}> - <CFormSelect - id="validationServer04" - label="State" - feedback="Please provide a valid city." - invalid - > - <option disabled>Choose...</option> - <option>...</option> - </CFormSelect> - </CCol> - <CCol md={3}> - <CFormInput - type="text" - id="validationServer05" - label="zip" - feedback="Please provide a valid zip." - invalid - required - /> - </CCol> - <CCol xs={12}> - <CFormCheck - type="checkbox" - id="invalidCheck" - label="Agree to terms and conditions" - invalid - required - /> - <CFormFeedback invalid>You must agree before submitting.</CFormFeedback> - </CCol> - <CCol xs={12}> - <CButton color="primary" type="submit"> - Submit form - </CButton> - </CCol> -</CForm> -``` - -## Supported elements - -Validation styles are available for the following form controls and components: - -- `<CFormCheck>`s -- `<CFormInput>`s -- `<CFormSelect>`s -- `<CFormTextarea>`s - -```jsx preview -<CForm validated={true}> - <div className="mb-3"> - <CFormTextarea - feedbackInvalid="Please enter a message in the textarea." - id="validationTextarea" - label="Textarea" - placeholder="Required example textarea" - required - ></CFormTextarea> - </div> - <CFormCheck - className="mb-3" - id="validationFormCheck1" - label="Check this checkbox" - feedbackInvalid="Example invalid feedback text" - required - /> - <CFormCheck - type="radio" - name="radio-stacked" - id="validationFormCheck2" - label="Check this checkbox" - required - /> - <CFormCheck - className="mb-3" - type="radio" - name="radio-stacked" - id="validationFormCheck3" - label="Or toggle this other radio" - feedbackInvalid="More example invalid feedback text" - required - /> - <div className="mb-3"> - <CFormSelect - feedbackInvalid="Example invalid select feedback" - aria-label="select example" - required - > - <option selected="" value=""> - Open this select menu - </option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </div> - <div className="mb-3"> - <CFormInput - type="file" - id="validationTextarea" - feedbackInvalid="Example invalid form file feedback" - aria-label="file example" - required - /> - </div> - <div className="mb-3"> - <CButton type="submit" color="primary" disabled> - Submit form - </CButton> - </div> -</CForm> -``` - -## Tooltips - -If your form layout allows it, you can swap the text for the tooltip to display validation feedback in a styled tooltip. Be sure to have a parent with `position: relative` on it for tooltip positioning. In the example below, our column classes have this already, but your project may require an alternative setup. - -export const TooltipsExample = () => { - const [validated, setValidated] = useState(false) - const handleSubmit = (event) => { - const form = event.currentTarget - if (form.checkValidity() === false) { - event.preventDefault() - event.stopPropagation() - } - setValidated(true) - } - return ( - <CForm - className="row g-3 needs-validation" - noValidate - validated={validated} - onSubmit={handleSubmit} - > - <CCol md={4} className="position-relative"> - <CFormInput - type="text" - defaultValue="Mark" - feedbackValid="Looks good!" - id="validationTooltip01" - label="First name" - required - tooltipFeedback - /> - </CCol> - <CCol md={4} className="position-relative"> - <CFormInput - type="text" - defaultValue="Otto" - feedbackValid="Looks good!" - id="validationTooltip02" - label="First name" - required - tooltipFeedback - /> - </CCol> - <CCol md={4} className="position-relative"> - <CFormLabel htmlFor="validationTooltipUsername">Username</CFormLabel> - <CInputGroup className="has-validation"> - <CInputGroupText id="inputGroupPrepend">@</CInputGroupText> - <CFormInput - type="text" - aria-describedby="inputGroupPrependFeedback" - feedbackInvalid="Please choose a username." - id="validationTooltipUsername" - required - tooltipFeedback - /> - </CInputGroup> - </CCol> - <CCol md={6} className="position-relative"> - <CFormInput - type="text" - aria-describedby="validationTooltip03Feedback" - feedbackInvalid="Please provide a valid city." - id="validationTooltip03" - label="City" - required - tooltipFeedback - /> - </CCol> - <CCol md={3} className="position-relative"> - <CFormSelect - aria-describedby="validationTooltip04Feedback" - feedbackInvalid="Please select a valid state." - id="validationTooltip04" - label="State" - required - tooltipFeedback - > - <option selected="" disabled="" value=""> - Choose... - </option> - <option>...</option> - </CFormSelect> - </CCol> - <CCol md={3} className="position-relative"> - <CFormInput - type="text" - aria-describedby="validationTooltip05Feedback" - feedbackInvalid="Please provide a valid zip." - id="validationTooltip05" - label="Zip" - required - tooltipFeedback - /> - </CCol> - <CCol xs={12} className="position-relative"> - <CButton color="primary" type="submit"> - Submit form - </CButton> - </CCol> - </CForm> - ) -} - -<Example> - <TooltipsExample /> -</Example> - -```jsx -const [validated, setValidated] = useState(false) -const handleSubmit = (event) => { - const form = event.currentTarget - if (form.checkValidity() === false) { - event.preventDefault() - event.stopPropagation() - } - setValidated(true) -} -return ( - <CForm - className="row g-3 needs-validation" - noValidate - validated={validated} - onSubmit={handleSubmit} -> - <CCol md={4} className="position-relative"> - <CFormInput - type="text" - defaultValue="Mark" - feedbackValid="Looks good!" - id="validationTooltip01" - label="First name" - required - tooltipFeedback - /> - </CCol> - <CCol md={4} className="position-relative"> - <CFormInput - type="text" - defaultValue="Otto" - feedbackValid="Looks good!" - id="validationTooltip02" - label="First name" - required - tooltipFeedback - /> - </CCol> - <CCol md={4} className="position-relative"> - <CFormLabel htmlFor="validationTooltipUsername">Username</CFormLabel> - <CInputGroup className="has-validation"> - <CInputGroupText id="inputGroupPrepend">@</CInputGroupText> - <CFormInput - type="text" - aria-describedby="inputGroupPrependFeedback" - feedbackInvalid="Please choose a username." - id="validationTooltipUsername" - required - tooltipFeedback - /> - </CInputGroup> - </CCol> - <CCol md={6} className="position-relative"> - <CFormInput - type="text" - aria-describedby="validationTooltip03Feedback" - feedbackInvalid="Please provide a valid city." - id="validationTooltip03" - label="City" - required - tooltipFeedback - /> - </CCol> - <CCol md={3} className="position-relative"> - <CFormSelect - aria-describedby="validationTooltip04Feedback" - feedbackInvalid="Please select a valid state." - id="validationTooltip04" - label="State" - required - tooltipFeedback - > - <option selected="" disabled="" value=""> - Choose... - </option> - <option>...</option> - </CFormSelect> - </CCol> - <CCol md={3} className="position-relative"> - <CFormInput - type="text" - aria-describedby="validationTooltip05Feedback" - feedbackInvalid="Please provide a valid zip." - id="validationTooltip05" - label="Zip" - required - tooltipFeedback - /> - </CCol> - <CCol xs={12} className="position-relative"> - <CButton color="primary" type="submit"> - Submit form - </CButton> - </CCol> -</CForm> -) -``` - -## Customizing - -### CSS variables - -CoreUI for React components use local CSS variables for validation for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. - -<ScssDocs file="_root.scss" capture="root-form-validation-variables"/> - -These variables are also color mode adaptive, meaning they change color while in dark mode. - -### SASS variables - -<ScssDocs file="_variables.scss" capture="form-feedback-variables" /> - -<ScssDocs file="_variables.scss" capture="form-validation-colors" /> - -<ScssDocs file="_variables-dark.scss" capture="form-validation-colors-dark" /> diff --git a/packages/docs/content/getting-started/accessibility.mdx b/packages/docs/content/getting-started/accessibility.mdx deleted file mode 100644 index 17bbee89..00000000 --- a/packages/docs/content/getting-started/accessibility.mdx +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: Accessibility -name: Accessibility -description: A brief overview of CoreUI for React features and limitations for the creation of accessible content. -menu: Getting started -route: /getting-started/accessibility ---- - -CoreUI for React provides an easy-to-use framework of ready-made styles, layout tools, and interactive components, allowing developers to create websites and applications that are visually appealing, functionally rich, and accessible out of the box. - -## Overview and limitations - -The overall accessibility of any project built with CoreUI for React depends in large part on the author's markup, additional styling, and scripting they've included. However, provided that these have been implemented correctly, it should be perfectly possible to create websites and applications with CoreUI for React that fulfill [<abbr title="Web Content Accessibility Guidelines">WCAG</abbr> 2.1](https://www.w3.org/TR/WCAG21/) (A/AA/AAA), [Section 508](https://www.section508.gov/), and similar accessibility standards and requirements. - -### Structural markup - -CoreUI for React styling and layout can be applied to a wide range of markup structures. This documentation aims to provide developers with best practice examples to demonstrate the use of CoreUI for React itself and illustrate appropriate semantic markup, including ways in which potential accessibility concerns can be addressed. - -### Interactive components - -CoreUI for React interactive components—such as modal dialogs, dropdown menus, and custom tooltips—are designed to work for touch, mouse, and keyboard users. Through the use of relevant [<abbr title="Web Accessibility Initiative">WAI</abbr>-<abbr title="Accessible Rich Internet Applications">ARIA</abbr>](https://www.w3.org/WAI/standards-guidelines/aria/) roles and attributes, these components should also be understandable and operable using assistive technologies (such as screen readers). - -Because CoreUI for React components are purposely designed to be fairly generic, authors may need to include further <abbr title="Accessible Rich Internet Applications">ARIA</abbr> roles and attributes, as well as JavaScript behavior, to more accurately convey the precise nature and functionality of their component. This is usually noted in the documentation. - -### Color contrast - -Some combinations of colors that currently make up CoreUI for React default palette—used throughout the framework for things such as button variations, alert variations, form validation indicators—may lead to *insufficient* color contrast (below the recommended [WCAG 2.1 text color contrast ratio of 4.5:1](https://www.w3.org/TR/WCAG21/#contrast-minimum) and the [WCAG 2.1 non-text color contrast ratio of 3:1](https://www.w3.org/TR/WCAG21/#non-text-contrast)), particularly when used against a light background. Authors are encouraged to test their specific uses of color and, where necessary, manually modify/extend these default colors to ensure adequate color contrast ratios. - -### Visually hidden content - -Content which should be visually hidden, but remain accessible to assistive technologies such as screen readers, can be styled using the `.visually-hidden` class. This can be useful in situations where additional visual information or cues (such as meaning denoted through the use of color) need to also be conveyed to non-visual users. - -```html -<p className="text-danger"> - <span className="visually-hidden">Danger: </span> - This action is not reversible -</p> -``` - -For visually hidden interactive controls, such as traditional "skip" links, use the `.visually-hidden-focusable` class. This will ensure that the control becomes visible once focused (for sighted keyboard users). **Watch out, compared to the equivalent `.sr-only` and `.sr-only-focusable` classes in past versions, CoreUI's `.visually-hidden-focusable` is a standalone class, and must not be used in combination with the `.visually-hidden` class.** - -```html -<a className="visually-hidden-focusable" href="#content">Skip to main content</a> -``` - -### Reduced motion - -CoreUI for React includes support for the [`prefers-reduced-motion` media feature](https://drafts.csswg.org/mediaqueries-5/#prefers-reduced-motion). In browsers/environments that allow the user to specify their preference for reduced motion, most CSS transition effects in CoreUI for React (for instance, when a modal dialog is opened or closed, or the sliding animation in carousels) will be disabled, and meaningful animations (such as spinners) will be slowed down. - -On browsers that support `prefers-reduced-motion`, and where the user has *not* explicitly signaled that they'd prefer reduced motion (i.e. where `prefers-reduced-motion: no-preference`), CoreUI for React enables smooth scrolling using the `scroll-behavior` property. - -## Additional resources - -- [Web Content Accessibility Guidelines (WCAG) 2.1](https://www.w3.org/TR/WCAG21/) -- [The A11Y Project](https://www.a11yproject.com/) -- [MDN accessibility documentation](https://developer.mozilla.org/en-US/docs/Web/Accessibility) -- [Tenon.io Accessibility Checker](https://tenon.io/) -- [Color Contrast Analyser (CCA)](https://developer.paciellogroup.com/resources/contrastanalyser/) -- ["HTML Codesniffer" bookmarklet for identifying accessibility issues](https://github.com/squizlabs/HTML_CodeSniffer) -- [Microsoft Accessibility Insights](https://accessibilityinsights.io/) -- [Deque Axe testing tools](https://www.deque.com/axe/) diff --git a/packages/docs/content/getting-started/introduction.mdx b/packages/docs/content/getting-started/introduction.mdx deleted file mode 100644 index 679bd183..00000000 --- a/packages/docs/content/getting-started/introduction.mdx +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Introduction -name: Introduction -description: CoreUI for React.js is UI Component library written in TypeScript, and ready for your next React.js project. Learn how to include CoreUI for React.js in your project. -menu: Getting started -route: /getting-started/introduction ---- - -## Installation - -### Npm - -```bash -npm install @coreui/react @coreui/coreui -``` - -If you use CoreUI PRO version. - -```bash -npm install @coreui/react-pro @coreui/coreui-pro -``` - -### Yarn - -```bash -yarn add @coreui/react @coreui/coreui -``` - -If you use CoreUI PRO version. - -```bash -yarn add @coreui/react-pro @coreui/coreui-pro -``` - - -## Using components - -```jsx -import { CAlert } from '@coreui/react'; - -// CoreUI PRO version -import { CAlert } from '@coreui/react-pro'; -``` - -## Stylesheets - -React components are styled using the `@coreui/coreui` or `@coreui/coreui-pro` CSS library, but you can also use them with the bootstrap CSS library. That is possible because the `@coreui/coreui` library is compatible with Bootstrap, it just extends its functionalities. The only exceptions are custom CoreUI and CoreUI PRO components, which don't exist in the Bootstrap ecosystem. - -### CoreUI and CoreUI PRO CSS files - -###### Basic usage - -```js -import '@coreui/coreui/dist/css/coreui.min.css' - -// CoreUI PRO version -import '@coreui/coreui-pro/dist/css/coreui.min.css' -``` - -### Bootstrap CSS files - -###### Installation - -```bash -npm install bootstrap -``` - -###### Basic usage - -```js -import 'bootstrap/dist/css/bootstrap.min.css' -``` \ No newline at end of file diff --git a/packages/docs/content/layout/breakpoints.mdx b/packages/docs/content/layout/breakpoints.mdx deleted file mode 100644 index fd7ddd93..00000000 --- a/packages/docs/content/layout/breakpoints.mdx +++ /dev/null @@ -1,178 +0,0 @@ ---- -name: Breakpoints -description: Breakpoints are the triggers in CoreUI for React.js for how your layout responsive changes across device or viewport sizes. -menu: Layout -route: "/layout/breakpoints" ---- - -## Core concepts - -- **Breakpoints are the building blocks of responsive design.** Use them to control when your layout can be adapted at a particular viewport or device size. - -- **Use media queries to architect your CSS by breakpoint.** Media queries are a feature of CSS that allow you to conditionally apply styles based on a set of browser and operating system parameters. We most commonly use `min-width` in our media queries. - -- **Mobile first, responsive design is the goal.** CoreUI's CSS aims to apply the bare minimum of styles to make a layout work at the smallest breakpoint, and then layers on styles to adjust that design for larger devices. This optimizes your CSS, improves rendering time, and provides a great experience for your visitors. - -## Available breakpoints - -CoreUI for React.js includes six default breakpoints, sometimes referred to as _grid tiers_, for building responsively. These breakpoints can be customized if you're using our source Sass files. - -| Breakpoint | Class infix | Dimensions | -| --- | --- | --- | -| Extra small | <em>None</em> | <576px | -| Small | `sm` | ≥576px | -| Medium | `md` | ≥768px | -| Large | `lg` | ≥992px | -| Extra large | `xl` | ≥1200px | -| Extra extra large | `xxl` | ≥1400px | - -Each breakpoint was chosen to comfortably hold containers whose widths are multiples of 12. Breakpoints are also representative of a subset of common device sizes and viewport dimensions—they don't specifically target every use case or device. Instead, the ranges provide a strong and consistent foundation to build on for nearly any device. - -These breakpoints are customizable via Sass—you'll find them in a Sass map in our `_variables.scss` stylesheet. - -```scss -$grid-breakpoints: ( - xs: 0, - sm: 576px, - md: 768px, - lg: 992px, - xl: 1200px, - xxl: 1400px -); -``` - -For more information and examples on how to modify our Sass maps and variables, please refer to [the Sass section of the Grid documentation](https://coreui.io/docs/layout/grid#sass). - -## Media queries - -Since CoreUI for React.js is developed to be mobile first, we use a handful of [media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries) to create sensible breakpoints for our layouts and interfaces. These breakpoints are mostly based on minimum viewport widths and allow us to scale up elements as the viewport changes. - -### Min-width - -CoreUI for React.js primarily uses the following media query ranges—or breakpoints—in our source Sass files for our layout, grid system, and components. - -```scss -// Source mixins - -// No media query necessary for xs breakpoint as it's effectively `@media (min-width: 0) { ... }` -@include media-breakpoint-up(sm) { ... } -@include media-breakpoint-up(md) { ... } -@include media-breakpoint-up(lg) { ... } -@include media-breakpoint-up(xl) { ... } -@include media-breakpoint-up(xxl) { ... } - -// Usage - -// Example: Hide starting at `min-width: 0`, and then show at the `sm` breakpoint -.custom-class { - display: none; -} -@include media-breakpoint-up(sm) { - .custom-class { - display: block; - } -} -``` - -These Sass mixins translate in our compiled CSS using the values declared in our Sass variables. For example: - -```scss -// X-Small devices (portrait phones, less than 576px) -// No media query for `xs` since this is the default in CoreUI - -// Small devices (landscape phones, 576px and up) -@media (min-width: 576px) { ... } - -// Medium devices (tablets, 768px and up) -@media (min-width: 768px) { ... } - -// Large devices (desktops, 992px and up) -@media (min-width: 992px) { ... } - -// X-Large devices (large desktops, 1200px and up) -@media (min-width: 1200px) { ... } - -// XX-Large devices (larger desktops, 1400px and up) -@media (min-width: 1400px) { ... } -``` - -### Max-width - -We occasionally use media queries that go in the other direction (the given screen size *or smaller*): - -```scss -// No media query necessary for xs breakpoint as it's effectively `@media (max-width: 0) { ... }` -@include media-breakpoint-down(sm) { ... } -@include media-breakpoint-down(md) { ... } -@include media-breakpoint-down(lg) { ... } -@include media-breakpoint-down(xl) { ... } -@include media-breakpoint-down(xxl) { ... } - -// Example: Style from medium breakpoint and down -@include media-breakpoint-down(md) { - .custom-class { - display: block; - } -} -``` - -These mixins take those declared breakpoints, subtract `.02px` from them, and use them as our `max-width` values. For example: - -```scss -// X-Small devices (portrait phones, less than 576px) -@media (max-width: 575.98px) { ... } - -// Small devices (landscape phones, less than 768px) -@media (max-width: 767.98px) { ... } - -// Medium devices (tablets, less than 992px) -@media (max-width: 991.98px) { ... } - -// Large devices (desktops, less than 1200px) -@media (max-width: 1199.98px) { ... } - -// X-Large devices (large desktops, less than 1400px) -@media (max-width: 1399.98px) { ... } - -// XX-Large devices (larger desktops) -// No media query since the xxl breakpoint has no upper bound on its width -``` - -<Callout color="warning"> - <strong>Why subtract .02px?</strong> Browsers don’t currently support <a href="https://www.w3.org/TR/mediaqueries-4/#range-context">range context queries</a>, so we work around the limitations of <a href="https://www.w3.org/TR/mediaqueries-4/#mq-min-max"><code>min-</code> and <code>max-</code> prefixes</a> and viewports with fractional widths (which can occur under certain conditions on high-dpi devices, for instance) by using values with higher precision. -</Callout> - -### Single breakpoint - -There are also media queries and mixins for targeting a single segment of screen sizes using the minimum and maximum breakpoint widths. - -```scss -@include media-breakpoint-only(xs) { ... } -@include media-breakpoint-only(sm) { ... } -@include media-breakpoint-only(md) { ... } -@include media-breakpoint-only(lg) { ... } -@include media-breakpoint-only(xl) { ... } -@include media-breakpoint-only(xxl) { ... } -``` - -For example the `@include media-breakpoint-only(md) { ... }` will result in : - -```scss -@media (min-width: 768px) and (max-width: 991.98px) { ... } -``` - -### Between breakpoints - -Similarly, media queries may span multiple breakpoint widths: - -```scss -@include media-breakpoint-between(md, xl) { ... } -``` - -Which results in: - -```scss -// Example -// Apply styles starting from medium devices and up to extra large devices -@media (min-width: 768px) and (max-width: 1199.98px) { ... } -``` diff --git a/packages/docs/content/layout/columns.mdx b/packages/docs/content/layout/columns.mdx deleted file mode 100644 index ed496b07..00000000 --- a/packages/docs/content/layout/columns.mdx +++ /dev/null @@ -1,273 +0,0 @@ ---- -name: Columns -description: Learn how to modify columns with a handful of options for alignment, ordering, and offsetting thanks to our flexbox grid system. -menu: Layout -route: '/layout/columns' ---- - -import { CCol, CContainer, CRow } from '@coreui/react/src/index' - -## How they work - -- **Columns build on the grid's flexbox architecture.** Flexbox means we have options for changing individual columns and [modifying groups of columns at the row level](./../grid#row-columns). You choose how columns grow, shrink, or otherwise change. - -- **When building grid layouts, all content goes in columns.** The hierarchy of CoreUI's grid goes from [container](./../containers) to row to column to your content. On rare occasions, you may combine content and column, but be aware there can be unintended consequences. - -- **CoreUI for React.js includes predefined components for creating fast, responsive layouts.** With [six breakpoints](./../breakpoints) and a dozen columns at each grid tier, we have dozens of components already built for you to create your desired layouts. This can be disabled via Sass if you wish. - -## Alignment - -Use flexbox alignment utilities to vertically and horizontally align columns. - -### Vertical alignment - -```jsx preview className="docs-example-row docs-example-row-flex-cols" -<CContainer> - <CRow className="align-items-start"> - <CCol>One of three columns</CCol> - <CCol>One of three columns</CCol> - <CCol>One of three columns</CCol> - </CRow> - <CRow className="align-items-center"> - <CCol>One of three columns</CCol> - <CCol>One of three columns</CCol> - <CCol>One of three columns</CCol> - </CRow> - <CRow className="align-items-end"> - <CCol>One of three columns</CCol> - <CCol>One of three columns</CCol> - <CCol>One of three columns</CCol> - </CRow> -</CContainer> -``` - -```jsx preview className="docs-example-row docs-example-row-flex-cols" -<CContainer> - <CRow> - <CCol className="align-self-start">One of three columns</CCol> - <CCol className="align-self-center">One of three columns</CCol> - <CCol className="align-self-end">One of three columns</CCol> - </CRow> -</CContainer> -``` - -### Horizontal alignment - -```jsx preview className="docs-example-row" -<CContainer> - <CRow className="justify-content-start"> - <CCol xs={4}>One of two columns</CCol> - <CCol xs={4}>One of two columns</CCol> - </CRow> - <CRow className="justify-content-center"> - <CCol xs={4}>One of two columns</CCol> - <CCol xs={4}>One of two columns</CCol> - </CRow> - <CRow className="justify-content-end"> - <CCol xs={4}>One of two columns</CCol> - <CCol xs={4}>One of two columns</CCol> - </CRow> - <CRow className="justify-content-around"> - <CCol xs={4}>One of two columns</CCol> - <CCol xs={4}>One of two columns</CCol> - </CRow> - <CRow className="justify-content-between"> - <CCol xs={4}>One of two columns</CCol> - <CCol xs={4}>One of two columns</CCol> - </CRow> - <CRow className="justify-content-evenly"> - <CCol xs={4}>One of two columns</CCol> - <CCol xs={4}>One of two columns</CCol> - </CRow> -</CContainer> -``` - -### Column wrapping - -If more than 12 columns are placed within a single row, each group of extra columns will, as one unit, wrap onto a new line. - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol xs={9}>.col-9</CCol> - <CCol xs={4}> - .col-4 - <br /> - Since 9 + 4 = 13 > 12, this 4-column-wide div gets wrapped onto a new line as one - contiguous unit. - </CCol> - <CCol xs={6}> - .col-6 - <br /> - Subsequent columns continue along the new line. - </CCol> - </CRow> -</CContainer> -``` - -### Column breaks - -Breaking columns to a new line in flexbox requires a small hack: add an element with `width: 100%` wherever you want to wrap your columns to a new line. Normally this is accomplished with multiple `<CRow>`s, but not every implementation method can account for this. - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol xs={6} sm={3}> - .col-6 .col-sm-3 - </CCol> - <CCol xs={6} sm={3}> - .col-6 .col-sm-3 - </CCol> - <div className="w-100"></div> - <CCol xs={6} sm={3}> - .col-6 .col-sm-3 - </CCol> - <CCol xs={6} sm={3}> - .col-6 .col-sm-3 - </CCol> - </CRow> -</CContainer> -``` - -You may also apply this break at specific breakpoints with our [responsive display utilities](https://coreui.io/docs/utilities/display). - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol xs={6} sm={4}> - .col-6 .col-sm-4 - </CCol> - <CCol xs={6} sm={4}> - .col-6 .col-sm-4 - </CCol> - <div className="w-100 d-none d-md-block"></div> - <CCol xs={6} sm={4}> - .col-6 .col-sm-4 - </CCol> - <CCol xs={6} sm={4}> - .col-6 .col-sm-4 - </CCol> - </CRow> -</CContainer> -``` - -## Reordering - -### Order props - -Use `xs|sm|md|lg|xl|xxl={{ order: 1-5 }}` props for controlling the **visual order** of your content. These props are responsive, so you can set the `order` by breakpoint (e.g., `xs={{ order: 1}} md={{ order: 2}}`). Includes support for `1` through `5` across all six grid tiers. - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol>First in DOM, no order applied</CCol> - <CCol xs={{ span: true, order: 5 }}>Second in DOM, with a larger order</CCol> - <CCol xs={{ span: true, order: 1 }}>Third in DOM, with an order of 1</CCol> - </CRow> -</CContainer> -``` - -There are also responsive `xs|sm|md|lg|xl|xxl={{ order: 'first' }}` and `xs|sm|md|lg|xl|xxl={{ order: 'last' }}` props that change the `order` of an element by applying `order: -1` and `order: 6`, respectively. These values can also be intermixed with the numbered `xs|sm|md|lg|xl|xxl={{ order: 1-5 }}` values as needed. - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol xs={{ span: true, order: 'last' }}>First in DOM, ordered last</CCol> - <CCol>Second in DOM, unordered</CCol> - <CCol xs={{ span: true, order: 'first' }}>Third in DOM, ordered first</CCol> - </CRow> -</CContainer> -``` - -### Offsetting columns - -You can offset grid columns in two ways: our responsive `xs|sm|md|lg|xl|xxl={{ offset: 0-12 }}` grid props and our [margin utilities](https://coreui.io/docs/utilities/spacing). Grid props are sized to match columns while margins are more useful for quick layouts where the width of the offset is variable. - -#### Offset prop - -Move columns to the right using `md={{ offset: * }}` props. These props increase the left margin of a column by `*` columns. For example, `md={{ offset: 4 }}` moves `.col-md-4` over four columns. - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol md={4}>.col-md-4</CCol> - <CCol md={{ span: 4, offset: 4 }}>.col-md-4 .offset-md-4</CCol> - </CRow> - <CRow> - <CCol md={{ span: 3, offset: 3 }}>.col-md-3 .offset-md-3</CCol> - <CCol md={{ span: 3, offset: 3 }}>.col-md-3 .offset-md-3</CCol> - </CRow> - <CRow> - <CCol md={{ span: 6, offset: 3 }}>.col-md-6 .offset-md-3</CCol> - </CRow> -</CContainer> -``` - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol sm={5} md={6}> - .col-sm-5 .col-md-6 - </CCol> - <CCol sm={{ span: 5, offset: 2 }} md={{ span: 6, offset: 0 }}> - .col-sm-5 .offset-sm-2 .col-md-6 .offset-md-0 - </CCol> - </CRow> - <CRow> - <CCol sm={6} md={5} lg={6}> - .col-sm-6 .col-md-5 .col-lg-6 - </CCol> - <CCol sm={6} md={{ span: 5, offset: 2 }} lg={{ span: 6, offset: 0 }}> - .col-sm-6 .col-md-5 .offset-md-2 .col-lg-6 .offset-lg-0 - </CCol> - </CRow> -</CContainer> -``` - -#### Margin utilities - -You can use margin utilities like `.me-auto` to force sibling columns away from one another. - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol md={4}>.col-md-4</CCol> - <CCol md={4} className="ms-auto"> - .col-md-4 .ms-auto - </CCol> - </CRow> - <CRow> - <CCol md={3} className="ms-md-auto"> - .col-md-3 .ms-md-auto - </CCol> - <CCol md={3} className="ms-md-auto"> - .col-md-3 .ms-md-auto - </CCol> - </CRow> - <CRow> - <CCol xs="auto" className="me-auto"> - .col-auto .me-auto - </CCol> - <CCol xs="auto">.col-auto</CCol> - </CRow> -</CContainer> -``` - -## Standalone column component - -The `<CCol>` component can also be used outside a `<CRow>` to give an element a specific width. Whenever column component are used as non direct children of a row, the paddings are omitted. - -```jsx preview -<CCol xs={3} className="bg-light p-3 border"> - .col-3: width of 25% -</CCol> -<CCol sm={9} className="bg-light p-3 border"> - .col-sm-9: width of 75% above sm breakpoint -</CCol> -``` - -## API - -### CCol - -`markdown:CCol.api.mdx` diff --git a/packages/docs/content/layout/containers.mdx b/packages/docs/content/layout/containers.mdx deleted file mode 100644 index 3e0fe2a7..00000000 --- a/packages/docs/content/layout/containers.mdx +++ /dev/null @@ -1,70 +0,0 @@ ---- -name: Containers -title: Containers -description: Containers are a fundamental building block of CoreUI for React.js that contain, pad, and align your content within a given device or viewport. -menu: Layout -route: "/layout/containers" ---- - -import { CCol, CContainer, CRow } from '@coreui/react/src/index' - -## How they work - -Containers are the most basic layout element in CoreUI for React.js and are **required when using our default grid system**. Containers are used to contain, pad, and (sometimes) center the content within them. While containers *can* be nested, most layouts do not require a nested container. - -CoreUI for React.js comes with three different containers: - -- `<CContainer>`, which sets a `max-width` at each responsive breakpoint -- `<CContainer fluid>`, which is `width: 100%` at all breakpoints -- `<CContainer {sm|md|lg|xl|xxl}>`, which is `width: 100%` until the specified breakpoint - -The table below illustrates how each container's `max-width` compares to the original `<CContainer>` and `<CContainer fluid>` across each breakpoint. - -| | Extra small<div className="fw-normal"><576px</div> | Small<div className="fw-normal">≥576px</div> | Medium<div className="fw-normal">≥768px</div> | Large<div className="fw-normal">≥992px</div> | X-Large<div className="fw-normal">≥1200px</div> | XX-Large<div className="fw-normal">≥1400px</div> | -| --- | --- | --- | --- | --- | --- | --- | -| `.container` | <span className="text-body-secondary">100%</span> | 540px | 720px | 960px | 1140px | 1320px | -| `.container-sm` | <span className="text-body-secondary">100%</span> | 540px | 720px | 960px | 1140px | 1320px | -| `.container-md` | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | 720px | 960px | 1140px | 1320px | -| `.container-lg` | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | 960px | 1140px | 1320px | -| `.container-xl` | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | 1140px | 1320px | -| `.container-xxl` | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | 1320px | -| `.container-fluid` | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | <span className="text-body-secondary">100%</span> | - - -## Default container - -Our default `<CContainer>` class is a responsive, fixed-width container, meaning its `max-width` changes at each breakpoint. - -```jsx -<CContainer> - Content here -</CContainer> -``` - -## Responsive containers - -Responsive containers allow you to specify a class that is 100% wide until the specified breakpoint is reached, after which we apply `max-width`s for each of the higher breakpoints. For example, `<CContainer sm>` is 100% wide to start until the `sm` breakpoint is reached, where it will scale up with `md`, `lg`, `xl`, and `xxl`. - -```jsx -<CContainer sm>100% wide until small breakpoint</CContainer> -<CContainer md>100% wide until medium breakpoint</CContainer> -<CContainer lg>100% wide until large breakpoint</CContainer> -<CContainer xl>100% wide until extra large breakpoint</CContainer> -<CContainer xxl>100% wide until extra extra large breakpoint</CContainer> -``` - -## Fluid containers - -Use `<CContainer fluid>` for a full width container, spanning the entire width of the viewport. - -```jsx -<CContainer fluid> - Content here -</CContainer> -``` - -## API - -### CContainer - -`markdown:CContainer.api.mdx` diff --git a/packages/docs/content/layout/grid.mdx b/packages/docs/content/layout/grid.mdx deleted file mode 100644 index e6c2c9f3..00000000 --- a/packages/docs/content/layout/grid.mdx +++ /dev/null @@ -1,351 +0,0 @@ ---- -name: Grid -description: Use our powerful mobile-first flexbox grid to build layouts of all shapes and sizes thanks to a twelve column system, six default responsive tiers, Sass variables and mixins, and dozens of predefined classes. -menu: Layout -route: '/layout/grid' ---- - -import { CCol, CContainer, CRow } from '@coreui/react/src/index' - -## Example - -CoreUI's grid system uses a series of containers, rows, and columns to layout and align content. It's built with [flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox) and is fully responsive. Below is an example and an in-depth explanation for how the grid system comes together. - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol sm="auto">One of three columns</CCol> - <CCol sm="auto">One of three columns</CCol> - <CCol sm="auto">One of three columns</CCol> - </CRow> -</CContainer> -``` - -The above example creates three equal-width columns across all devices and viewports using our predefined grid classes. Those columns are centered in the page with the parent `<CContainer>`. - -## How it works - -Breaking it down, here's how the grid system comes together: - -- **Our grid supports [six responsive breakpoints](../breakpoints).** Breakpoints are based on `min-width` media queries, meaning they affect that breakpoint and all those above it (e.g., `sm={4}` applies to `sm`, `md`, `lg`, `xl`, and `xxl`). This means you can control container and column sizing and behavior by each breakpoint. - -- **Containers center and horizontally pad your content.** Use `<CContainer>` for a responsive pixel width, `<CContainer fluid>` for `width: 100%` across all viewports and devices, or a responsive container (e.g., `<CContainer md>`) for a combination of fluid and pixel widths. - -- **Rows are wrappers for columns.** Each column has horizontal `padding` (called a gutter) for controlling the space between them. This `padding` is then counteracted on the rows with negative margins to ensure the content in your columns is visually aligned down the left side. Rows also support modifier classes to [uniformly apply column sizing](#row-columns) and [gutter classes](../gutters) to change the spacing of your content. - -- **Columns are incredibly flexible.** There are 12 template columns available per row, allowing you to create different combinations of elements that span any number of columns. Column classes indicate the number of template columns to span (e.g., `CCol xs={4}` spans four). `width`s are set in percentages so you always have the same relative sizing. - -- **Gutters are also responsive and customizable.** [Gutter classes are available](../gutters) across all breakpoints, with all the same sizes as our [margin and padding spacing](https://coreui.io/docs/utilities/spacing/). Change horizontal gutters with `xs|sm|md|lg|xl|xxl={{ gutterX: * }}` classes, vertical gutters with `xs|sm|md|lg|xl|xxl={{ gutterY: * }}`, or all gutters with `xs|sm|md|lg|xl|xxl={{ gutter: * }}` classes. `xs|sm|md|lg|xl|xxl={{ gutter: 0 }}` is also available to remove gutters. - -Be aware of the limitations and [bugs around flexbox](https://github.com/philipwalton/flexbugs), like the [inability to use some HTML elements as flex containers](https://github.com/philipwalton/flexbugs#flexbug-9). - -## Grid options - -CoreUI's grid system can adapt across all six default breakpoints, and any breakpoints you customize. The six default grid tiers are as follow: - -- Extra small (xs) -- Small (sm) -- Medium (md) -- Large (lg) -- Extra large (xl) -- Extra extra large (xxl) - -As noted above, each of these breakpoints have their own container, unique class prefix, and modifiers. Here's how the grid changes across these breakpoints: - -{<div className="table-responsive"> - <table className="table mb-4"> - <thead> - <tr> - <th scope="col"></th> - <th scope="col"> - xs - <div className="fw-normal"><576px</div> - </th> - <th scope="col"> - sm - <div className="fw-normal">≥576px</div> - </th> - <th scope="col"> - md - <div className="fw-normal">≥768px</div> - </th> - <th scope="col"> - lg - <div className="fw-normal">≥992px</div> - </th> - <th scope="col"> - xl - <div className="fw-normal">≥1200px</div> - </th> - <th scope="col"> - xxl - <div className="fw-normal">≥1400px</div> - </th> - </tr> - </thead> - <tbody> - <tr> - <th className="text-nowrap" scope="row">Container <code className="fw-normal">max-width</code></th> - <td>None (auto)</td> - <td>540px</td> - <td>720px</td> - <td>960px</td> - <td>1140px</td> - <td>1320px</td> - </tr> - <tr> - <th className="text-nowrap" scope="row">Class prefix</th> - <td><code>.col-</code></td> - <td><code>.col-sm-</code></td> - <td><code>.col-md-</code></td> - <td><code>.col-lg-</code></td> - <td><code>.col-xl-</code></td> - <td><code>.col-xxl-</code></td> - </tr> - <tr> - <th className="text-nowrap" scope="row"># of columns</th> - <td colSpan={6}>12</td> - </tr> - <tr> - <th className="text-nowrap" scope="row">Gutter width</th> - <td colSpan={6}>1.5rem (.75rem on left and right)</td> - </tr> - <tr> - <th className="text-nowrap" scope="row">Custom gutters</th> - <td colSpan={6}><a href="../gutters">Yes</a></td> - </tr> - <tr> - <th className="text-nowrap" scope="row">Nestable</th> - <td colSpan={6}><a href="#nesting">Yes</a></td> - </tr> - <tr> - <th className="text-nowrap" scope="row">Column ordering</th> - <td colSpan={6}><a href="../columns#reordering">Yes</a></td> - </tr> - </tbody> - </table> -</div>} - -## Auto-layout columns - -Utilize breakpoint-specific column classes for easy column sizing without an explicit numbered class like `<CCol sm={6}>`. - -### Equal-width - -For example, here are two grid layouts that apply to every device and viewport, from `xs` to `xxl`. Add any number of unit-less classes for each breakpoint you need and every column will be the same width. - - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol>1 of 2</CCol> - <CCol>2 of 2</CCol> - </CRow> - <CRow> - <CCol>1 of 3</CCol> - <CCol>2 of 3</CCol> - <CCol>3 of 3</CCol> - </CRow> -</CContainer> -``` - -### Setting one column width - -Auto-layout for flexbox grid columns also means you can set the width of one column and have the sibling columns automatically resize around it. You may use predefined grid classes (as shown below), grid mixins, or inline widths. Note that the other columns will resize no matter the width of the center column. - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol>1 of 3</CCol> - <CCol xs={6}>2 of 3 (wider)</CCol> - <CCol>3 of 3</CCol> - </CRow> - <CRow> - <CCol>1 of 3</CCol> - <CCol xs={6}>2 of 3 (wider)</CCol> - <CCol>3 of 3</CCol> - </CRow> -</CContainer> -``` - -### Variable width content - -Use `<CCol {breakpoint}="auto"` props to size columns based on the natural width of their content. - -```jsx preview className="docs-example-row" -<CContainer> - <div className="row justify-content-md-center"> - <CCol xs lg={2}> - 1 of 3 - </CCol> - <CCol md="auto">Variable width content</CCol> - <CCol xs lg={2}> - 3 of 3 - </CCol> - </div> - <CRow> - <CCol>1 of 3</CCol> - <CCol md="auto">Variable width content</CCol> - <CCol xs lg={2}> - 3 of 3 - </CCol> - </CRow> -</CContainer> -``` - -## Responsive classes - -CoreUI's grid includes six tiers of predefined classes for building complex responsive layouts. Customize the size of your columns on extra small, small, medium, large, or extra large devices however you see fit. - -### All breakpoints - -For grids that are the same from the smallest of devices to the largest, use the `<CCol>` and `<CCol xs={*}>` classes. Specify a numbered class when you need a particularly sized column; otherwise, feel free to stick to `<CCol>`. - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol>col</CCol> - <CCol>col</CCol> - <CCol>col</CCol> - <CCol>col</CCol> - </CRow> - <CRow> - <CCol xs={8}>col-8</CCol> - <CCol xs={4}>col-4</CCol> - </CRow> -</CContainer> -``` - -### Stacked to horizontal - -Using a single set of `<CCol sm={*}>` classes, you can create a basic grid system that starts out stacked and becomes horizontal at the small breakpoint (`sm`). - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol sm={8}>col-sm-8</CCol> - <CCol sm={4}>col-sm-4</CCol> - </CRow> - <CRow> - <CCol sm>col-sm</CCol> - <CCol sm>col-sm</CCol> - <CCol sm>col-sm</CCol> - </CRow> -</CContainer> -``` - -### Mix and match - -Don't want your columns to simply stack in some grid tiers? Use a combination of different classes for each tier as needed. See the example below for a better idea of how it all works. - -```jsx preview className="docs-example-row" -<CContainer> - <CRow> - <CCol md={8}>.col-md-8</CCol> - <CCol xs={6} md={4}> - .col-6 .col-md-4 - </CCol> - </CRow> - <CRow> - <CCol xs={6} md={4}> - .col-6 .col-md-4 - </CCol> - <CCol xs={6} md={4}> - .col-6 .col-md-4 - </CCol> - <CCol xs={6} md={4}> - .col-6 .col-md-4 - </CCol> - </CRow> - <CRow> - <CCol xs={6}>.col-6</CCol> - <CCol xs={6}>.col-6</CCol> - </CRow> -</CContainer> -``` - -### Row columns - -Use the responsive `{breakpoint}={{ cols: * }}` classes to quickly set the number of columns that best render your content and layout. Whereas normal `<CCol xs={*}>` classes apply to the individual columns (e.g., `<CCol xs={4}>`), the row columns classes are set on the parent `<CRow>` as a shortcut. With `{breakpoint}={{ cols: 'auto' }}` you can give the columns their natural width. - -Use these row columns classes to quickly create basic grid layouts or to control your card layouts. - -```jsx preview className="docs-example-row" -<CContainer> - <CRow xs={{ cols: 2 }}> - <CCol>Column</CCol> - <CCol>Column</CCol> - <CCol>Column</CCol> - <CCol>Column</CCol> - </CRow> -</CContainer> -``` - -```jsx preview className="docs-example-row" -<CContainer> - <CRow xs={{ cols: 3 }}> - <CCol>Column</CCol> - <CCol>Column</CCol> - <CCol>Column</CCol> - <CCol>Column</CCol> - </CRow> -</CContainer> -``` - -```jsx preview className="docs-example-row" -<CContainer> - <CRow xs={{ cols: 'auto' }}> - <CCol>Column</CCol> - <CCol>Column</CCol> - <CCol>Column</CCol> - <CCol>Column</CCol> - </CRow> -</CContainer> -``` - -```jsx preview className="docs-example-row" -<CContainer> - <CRow xs={{ cols: 4 }}> - <CCol>Column</CCol> - <CCol>Column</CCol> - <CCol>Column</CCol> - <CCol>Column</CCol> - </CRow> -</CContainer> -``` - -```jsx preview className="docs-example-row" -<CContainer> - <CRow xs={{ cols: 4 }}> - <CCol>Column</CCol> - <CCol>Column</CCol> - <CCol xs={6}>Column</CCol> - <CCol>Column</CCol> - </CRow> -</CContainer> -``` - -```jsx preview className="docs-example-row" -<CContainer> - <CRow xs={{ cols: 1 }} sm={{ cols: 2 }} md={{ cols: 4 }}> - <CCol>Column</CCol> - <CCol>Column</CCol> - <CCol>Column</CCol> - <CCol>Column</CCol> - </CRow> -</CContainer> -``` - -## API - -### CContainer - -`markdown:CContainer.api.mdx` - -### CRow - -`markdown:CRow.api.mdx` - -### CCol - -`markdown:CCol.api.mdx` diff --git a/packages/docs/content/layout/gutters.mdx b/packages/docs/content/layout/gutters.mdx deleted file mode 100644 index 0674a963..00000000 --- a/packages/docs/content/layout/gutters.mdx +++ /dev/null @@ -1,181 +0,0 @@ ---- -name: Gutters -title: Gutters -description: Gutters are the padding between your columns, used to responsively space and align content in the CoreUI for React.js grid system. -menu: Layout -route: "/layout/gutters" ---- - -import { CCol, CContainer, CRow } from '@coreui/react/src/index' - -## How they work - -- **Gutters are the gaps between column content, created by horizontal `padding`.** We set `padding-right` and `padding-left` on each column, and use negative `margin` to offset that at the start and end of each row to align content. - -- **Gutters start at `1.5rem` (`24px`) wide.** This allows us to match our grid to the [padding and margin spacers](https://coreui.io/docs/utilities/spacing) scale. - -- **Gutters can be responsively adjusted.** Use breakpoint-specific gutter props to modify horizontal gutters, vertical gutters, and all gutters. - -## Horizontal gutters - -`{breakpoint}={{ gutterX: * }}` props can be used to control the horizontal gutter widths. The `<CContainer>` or `<CContainer fluid>` parent may need to be adjusted if larger gutters are used too to avoid unwanted overflow, using a matching padding utility. For example, in the following example we've increased the padding with `.px-4`: - -```jsx preview className="docs-example m-0 border-0 docs-example-cols" -<CContainer className="px-4"> - <CRow xs={{ gutterX: 5 }}> - <CCol> - <div className="p-3">Custom column padding</div> - </CCol> - <CCol> - <div className="p-3">Custom column padding</div> - </CCol> - </CRow> -</CContainer> -``` - -An alternative solution is to add a wrapper around the `<CRow>` with the `.overflow-hidden` class: - -```jsx preview className="docs-example m-0 border-0 docs-example-cols" -<CContainer className="overflow-hidden"> - <CRow xs={{ gutterX: 5 }}> - <CCol> - <div className="p-3">Custom column padding</div> - </CCol> - <CCol> - <div className="p-3">Custom column padding</div> - </CCol> - </CRow> -</CContainer> -``` - -## Vertical gutters - -`{breakpoint}={{ gutterY: * }}` props can be used to control the vertical gutter widths. Like the horizontal gutters, the vertical gutters can cause some overflow below the `<CRow>` at the end of a page. If this occurs, you add a wrapper around `<CRow>` with the `.overflow-hidden` class: - -```jsx preview className="docs-example m-0 border-0 docs-example-cols" -<CContainer className="overflow-hidden"> - <CRow xs={{ gutterY: 5 }}> - <CCol xs={{ span: 6 }}> - <div className="p-3">Custom column padding</div> - </CCol> - <CCol xs={{ span: 6 }}> - <div className="p-3">Custom column padding</div> - </CCol> - <CCol xs={{ span: 6 }}> - <div className="p-3">Custom column padding</div> - </CCol> - <CCol xs={{ span: 6 }}> - <div className="p-3">Custom column padding</div> - </CCol> - </CRow> -</CContainer> -``` - -## Horizontal & vertical gutters - -`{breakpoint}={{ gutter: * }}` props can be used to control the horizontal gutter widths, for the following example we use a smaller gutter width, so there won't be a need to add the `.overflow-hidden` wrapper class. - -```jsx preview className="docs-example m-0 border-0 docs-example-cols" -<CContainer> - <CRow xs={{ gutter: 2 }}> - <CCol xs={{ span: 6 }}> - <div className="p-3">Custom column padding</div> - </CCol> - <CCol xs={{ span: 6 }}> - <div className="p-3">Custom column padding</div> - </CCol> - <CCol xs={{ span: 6 }}> - <div className="p-3">Custom column padding</div> - </CCol> - <CCol xs={{ span: 6 }}> - <div className="p-3">Custom column padding</div> - </CCol> - </CRow> -</CContainer> -``` - -## Row columns gutters - -Gutter props can also be added to [row columns](../layout/grid#row-columns). In the following example, we use responsive row columns and responsive gutter props. - -```jsx preview className="docs-example m-0 border-0 docs-example-cols" -<CContainer> - <CRow xs={{ cols:2, gutter: 2 }} lg={{ cols: 5, gutter: 3}}> - <CCol> - <div className="p-3">Row column</div> - </CCol> - <CCol> - <div className="p-3">Row column</div> - </CCol> - <CCol> - <div className="p-3">Row column</div> - </CCol> - <CCol> - <div className="p-3">Row column</div> - </CCol> - <CCol> - <div className="p-3">Row column</div> - </CCol> - <CCol> - <div className="p-3">Row column</div> - </CCol> - <CCol> - <div className="p-3">Row column</div> - </CCol> - <CCol> - <div className="p-3">Row column</div> - </CCol> - <CCol> - <div className="p-3">Row column</div> - </CCol> - <CCol> - <div className="p-3">Row column</div> - </CCol> - </CRow> -</CContainer> -``` - -## No gutters - -The gutters between columns in our predefined grid props can be removed with `{breakpoint}={{ gutter: 0 }}`. This removes the negative `margin`s from `<CRow>` and the horizontal `padding` from all immediate children columns. - -**Need an edge-to-edge design?** Drop the parent `<CContainer>` or `<CContainer fluid>`. - -In practice, here's how it looks. Note you can continue to use this with all other predefined grid props (including column widths, responsive tiers, reorders, and more). - -```jsx preview className="docs-example m-0 border-0 docs-example-row" -<CRow xs={{ gutter: 0 }}> - <CCol sm={6} md={8}>.col-sm-6 .col-md-8</CCol> - <CCol xs={6} md={4}>.col-6 .col-md-4</CCol> -</CRow> -``` - -## Change the gutters - -Classes are built from the `$gutters` Sass map which is inherited from the `$spacers` Sass map. - -```scss -$grid-gutter-width: 1.5rem; -$gutters: ( - 0: 0, - 1: $spacer * .25, - 2: $spacer * .5, - 3: $spacer, - 4: $spacer * 1.5, - 5: $spacer * 3, -); -``` - -## API - -### CContainer - -`markdown:CContainer.api.mdx` - -### CRow - -`markdown:CRow.api.mdx` - -### CCol - -`markdown:CCol.api.mdx` diff --git a/packages/docs/content/migration/v4.mdx b/packages/docs/content/migration/v4.mdx deleted file mode 100644 index d1139895..00000000 --- a/packages/docs/content/migration/v4.mdx +++ /dev/null @@ -1,408 +0,0 @@ ---- -title: Migration to v4 -description: Track and review changes to the CoreUI for React.js components to help you migrate from v3 to v4. -menu: "Migration" -route: "/migration/v4" ---- - -CoreUI for React is the React.js version of CoreUI components library, so before read this migration guide, please check also [CoreUI 3 to 4 migration guide](https://coreui.io/docs/migration/v4/). - -## Components - -### CAlert - -- Deprecated property `innerRef`. -- Deprecated property `fade`. -- Deprecated property `onShowChange`. -- Deprecated property `closeButton`, use `dismissible` instead of. -- Deprecated property `show`, use `visible` instead of. - -### CBadge - -- Deprecated property `innerRef`. -- Deprecated property `tag`, use `component` instead of. - -### CBreadcrumb - -- Deprecated property `innerRef`. - -#### CBreadcrumbItem - -- Deprecated property `innerRef`. - -### CButton - -- Deprecated property `block`. -- Deprecated property `innerRef`. -- Deprecated property `pressed`. -- Deprecated property `tag`, use `component` instead of. - -### CCallout - -- Deprecated property `innerRef`. - -### CCard - -- Deprecated property `innerRef`. -- Deprecated property `accentColor`, use utilities `className="border-top-{#color} border-top-3"` instead of. - -#### CCardBody - -- Deprecated property `innerRef`. - -#### CCardFooter - -- Deprecated property `innerRef`. - -#### CCardGroup - -- Deprecated property `columns`. -- Deprecated property `deck`. -- Deprecated property `innerRef`. - -#### CCardHeader - -- Deprecated property `innerRef`. -- Deprecated property `tag`, use `component` instead of. - -#### CCardImg - -- **Component renamed to `CCardImg`** -- Deprecated property `variant`, use `orientation` instead of. - -#### CCardImgOverlay - -- **Component renamed to `CCardImgOverlay`** -- Deprecated property `innerRef`. -- Deprecated property `tag`. - -#### CCardSubtitle - -- Deprecated property `innerRef`. -- Deprecated property `tag`, use `component` instead of. - -#### CCardText - -- Deprecated property `innerRef`. -- Deprecated property `tag`, use `component` instead of. - -#### CCardTitle - -- Deprecated property `innerRef`. -- Deprecated property `tag`, use `component` instead of. - -### CCarousel - -- Deprecated property `autoSlide`. -- Deprecated property `innerRef`. -- Deprecated property `activeIndex`, use `index` instead of. - -#### CCarouselControl - -- Component is depracated, use `<CCarousel controls>` instead of. - -#### CCarouselIndicators - -- Component is depracated, use `<CCarousel indicators>` instead of. - -#### CCarouselInner - -- Component is depracated. - -### CCollapse - -- Deprecated property `innerRef`. -- Deprecated property `navbar`. -- Deprecated property `show`, use `visible` instead of. - -#### CCreateElement - -- Component is depracated. - -### CDropdown - -- Deprecated property `innerRef`. -- Deprecated property `inNav`, use `variant="nav-item"` instead of. -- Deprecated property `tag`, use `component` instead of. - -#### CDropdownitem - -- Deprecated property `color`. -- Deprecated property `divider`. -- Deprecated property `innerRef`. -- Deprecated property `header`. -- Deprecated property `onClick`. -- Deprecated property `tag`, use `component` instead of. - -#### CDropdownMenu - -- Deprecated property `innerRef`. -- Deprecated property `modifiers`. -- Deprecated property `placement` , use `<CDropdown placement="...">` instead of. -- Deprecated property `show` , use `<CDropdown visible>` instead of. - -#### CDropdownToggle - -- Deprecated property `innerRef`. -- Deprecated property `tag`, use `component` instead of. - -### CEmbed - -- Component is depracated. - -### CFade - -- Component is depracated. - -### CHeader - -- Deprecated property `withSubheader`. -- Deprecated component `CHeaderNavItem`, use `CNavItem` instead of. -- Deprecated component `CHeaderNavLink`, use `CNavLink` instead of. - -### CImg - -- **Component renamed to `CImage`** -- Deprecated property `block`. -- Deprecated property `innerRef`. -- Deprecated property `fluidGrow`. -- Deprecated property `placeholderColor`. -- Deprecated property `shape`. -- Deprecated property `tag`. - -### CJumbotron - -- Component is depracated. - -### CListGroup - -- Deprecated property `accent`. -- Deprecated property `horizontal`, use `layout` instead of. -- Deprecated property `innerRef`. -- Deprecated property `tag`, use `component` instead of. - -#### CListGroupItem - -- Deprecated property `accent`. -- Deprecated property `action`, use property `component="a"` or `component="button"` instead of. -- Deprecated property `innerRef`. -- Deprecated property `tag`, use `component` instead of. - -### CMedia - -- Component is depracated. - -### CModal - -- Deprecated property `addContentClass`. -- Deprecated property `borderColor`, use utilities `className="border border-{#color}"` instead of. -- Deprecated property `centered`. -- Deprecated property `closeOnBackdrop`. -- Deprecated property `fade`, use `transition` instead of. -- Deprecated property `innerRef`. -- Deprecated property `onClosed`. -- Deprecated property `onOpened`. -- Deprecated property `show`, use `visible` instead of. - -#### CModalBody - -- Deprecated property `innerRef`. -- Deprecated property `tag`. - -#### CModalFooter - -- Deprecated property `innerRef`. -- Deprecated property `tag`. - -#### CModalHeader - -- Deprecated property `innerRef`. -- Deprecated property `tag`. - -### CNav - -- Deprecated property `inCard`. -- Deprecated property `innerRef`. -- Deprecated property `fill`, use `layout="fill"` instead of. -- Deprecated property `justified`, use `layout="justified"` instead of. -- Deprecated property `tag`, use `component` instead of. - -#### CNavItem - -- Deprecated property `innerRef`. -- Deprecated property `tag`, use `component` instead of. - -#### CNavLink - -- Deprecated property `innerRef`. - -### CNavbar - -- Deprecated property `expandable`, use `expand` instead of. -- Deprecated property `fixed`, use `placement="fixed-top"` instead of. -- Deprecated property `innerRef`. -- Deprecated property `light`, use `colorScheme="light"` instead of. -- Deprecated property `sticky`, use `placement="sticky-top"` instead of. -- Deprecated property `tag`, use `component` instead of. - -#### CNavbarNav - -- Deprecated property `innerRef`. -- Deprecated property `tag`, use `component` instead of. - -#### CNavbarText - -- Deprecated property `innerRef`. -- Deprecated property `tag`, use `component` instead of. - -### CPagination - -- **The component has been split into `CPagination` and to `CSmartPagination` components. - -### CPopover - -- Deprecated property `header`, use `title` instead of. - -### CProgress - -- Deprecated property `innerRef`. -- Deprecated property `max`. -- Deprecated property `precision`. -- Deprecated property `showPercentage`. -- Deprecated property `showValue`. -- Deprecated property `size`, use `height` instead of. -- Deprecated property `striped`, use `variant="striped"` instead of. - -### CProgressBar - -- Deprecated property `innerRef`. -- Deprecated property `max`. -- Deprecated property `precision`. -- Deprecated property `showPercentage`. -- Deprecated property `showValue`. -- Deprecated property `size`, use `height` instead of. -- Deprecated property `striped`, use `variant="striped"` instead of. - -### CSidebar -- Deprecated property `minimize` use `narrow` instead of. -- Deprecated property `dropdownMode`. -- Deprecated component `CSidebarForm`, use `CForm` instead of. -- Deprecated component `CSidebarNavDivider`, use `CNavDivider` instead of. -- Deprecated component `CSidebarNavDropdown`, use `CNavGroup` instead of. -- Deprecated component `CSidebarNavLink`, use `CNavLink` instead of. -- Deprecated component `CSidebarNavItem`, use `CNavItem` instead of. -- Deprecated component `CSidebarNavTitile`, use `CNavTitle` instead of. - -### CSwitch - -- Component is depracated, use `CFormSwitch` instead of. - -### CSpinner - -- Deprecated property `innerRef`. -- Deprecated property `grow`, use `variant="grow"` instead of. -- Deprecated property `tag`, use `component` instead of. - -### CTabs - -- Component is depracated, use `<CNav variant="tabs" role="tablist">` instead of - -#### CTabContent - -- Deprecated property `innerRef`. -- Deprecated property `fade`. - -#### CTabPane - -- Deprecated property `active`, use `visible` instead of. -- Deprecated property `innerRef`. - -### CToast - -- Deprecated property `innerRef`. -- Deprecated property `fade`, use `animation` instead of. -- Deprecated property `show`, use `visible` instead of. -- Deprecated property `onStateChange`. - -#### CToastBody - -- Deprecated property `innerRef`. - -#### CToastHeader - -- Deprecated property `innerRef`. - - -### CToggler - -- Component is depracated. - -### CTooltip - -- Deprecated property `interactive`. -- Deprecated property `advancedOptions`. - - -## Forms - -### CFormGroup - -- Component is depracated. - -### CInput - -- **Component renamed to `CFormInput`** -- Deprecated property `plaintext`, use `plainText` instead of. - -### CInputCheckbox - -- Component is depracated, use `<CFormCheck>` instead of. - -### CInputFile - -- Component is depracated, use `<CFormInput type="file">` instead of. - -### CInputRadio - -- Component is depracated, use `<CFormCheck type="radio">` instead of. - -### CInputGroup - -- Deprecated property `innerRef`. - -#### CInputGroupAddon - -- Component is depracated, use `CInputGroupText` instead of. - -### CSelect - -- Component is depracated, use `<CFormSelect>` instead of. - -### CValidFeedback - -- Component is depracated, use `<CFormFeedback valid>` instead of. - -### CInvalidFeedback - -- Component is depracated, use `<CCFormFeedback invalid>` instead of. - -## Layout - -### CContainer - -- Deprecated property `tag`. -- Deprecated property `innerRef`. - -### CCol - -- Deprecated property `tag`. -- Deprecated property `width`, use `xs`, `sm`, `md`, `lg`, `xl`, `xxl`. - -### CRow - -- Deprecated property `alignHorizontal`. -- Deprecated property `alignVertical`. -- Deprecated property `form`. -- Deprecated property `gutters`. -- Deprecated property `tag`. -- Deprecated property `width`, use `xs`, `sm`, `md`, `lg`, `xl`, `xxl`. \ No newline at end of file diff --git a/packages/docs/content/migration/v5.mdx b/packages/docs/content/migration/v5.mdx deleted file mode 100644 index 6565b38e..00000000 --- a/packages/docs/content/migration/v5.mdx +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Migration to v5 -description: Track and review changes to the CoreUI for React.js components to help you migrate from v4 to v5. -menu: "Migration" -route: "/migration/v5" ---- - -CoreUI for React is the React.js version of CoreUI components library, so before read this migration guide, please check also [CoreUI 4 to 5 migration guide](https://coreui.io/docs/migration/v5/). - -## Components - -### CAvatar - -- Deprecated `textColor` values: `muted`, `high-emphasis`, `medium-emphasis`, `disabled`, `high-emphasis-inverse`, `medium-emphasis-inverse`, `disabled-inverse`. -- New `textColor` values: `primary-emphasis`, `secondary-emphasis`, `success-emphasis`, `danger-emphasis`, `warning-emphasis`, `info-emphasis`, `light-emphasis`, `body`, `body-emphasis`, `body-secondary`, `body-tertiary`, `black`, `black-50`, `white`, `white-50`. - -### CBadge - -- Deprecated `textColor` values: `muted`, `high-emphasis`, `medium-emphasis`, `disabled`, `high-emphasis-inverse`, `medium-emphasis-inverse`, `disabled-inverse`. -- New `textColor` values: `primary-emphasis`, `secondary-emphasis`, `success-emphasis`, `danger-emphasis`, `warning-emphasis`, `info-emphasis`, `light-emphasis`, `body`, `body-emphasis`, `body-secondary`, `body-tertiary`, `black`, `black-50`, `white`, `white-50`. - -### CButton - -- The button doesn't have a default color anymore, you have to add `color="primary"` - -### CCard - -- Deprecated `textColor` values: `muted`, `high-emphasis`, `medium-emphasis`, `disabled`, `high-emphasis-inverse`, `medium-emphasis-inverse`, `disabled-inverse`. -- New `textColor` values: `primary-emphasis`, `secondary-emphasis`, `success-emphasis`, `danger-emphasis`, `warning-emphasis`, `info-emphasis`, `light-emphasis`, `body`, `body-emphasis`, `body-secondary`, `body-tertiary`, `black`, `black-50`, `white`, `white-50`. - -### CCloseButton - -- Deprecated property `white`, use `dark` instead of. - -### CNav - -- The `underline` variant has been changed to `underline-border` - -### CSidebar - -- Sidebar has a light color scheme by default, use `colorScheme="dark"` to make it dark. - -### CToastClose - -- Deprecated property `white`, use `dark` instead of. diff --git a/packages/docs/content/templates/admin-dashboard.mdx b/packages/docs/content/templates/admin-dashboard.mdx deleted file mode 100644 index 42153487..00000000 --- a/packages/docs/content/templates/admin-dashboard.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: React Templates -name: React Templates -description: Develop modern, beautiful, and responsive applications in half the time with high-performing and easy-to-customize react admin panels to cover any requirement. -menu: Templates -route: /templates/admin-dashboard ---- - -import { - CCard, - CCardBody, - CCardSubtitle, - CCardTitle, - CCol, - CImage, - CLink, - CRow -} from '@coreui/react/src/index' - -## React Admin & Dashboard Templates - -Check out the fully-featured, ready-to-use admin dashboard templates built using CoreUI for React.js, and CoreUI PRO for React.js - -<CRow> - <CCol md={6}> - <CCard className="mb-4"> - <CCardBody> - <CLink className="text-decoration-none text-reset" href="https://coreui.io/react/#compare" target="_blank"> - <CCardTitle>Free React Admin Template</CCardTitle> - <CCardSubtitle className="mb-3 text-body-secondary">Default Theme</CCardSubtitle> - <CImage className="rounded shadow-sm" fluid src="https://coreui.io/images/templates/coreui_free_1440.webp" alt=""/> - </CLink> - </CCardBody> - </CCard> - </CCol> - <CCol md={6}> - <CCard className="mb-4"> - <CCardBody> - <CLink className="text-decoration-none text-reset" href="https://coreui.io/product/react-dashboard-template/?theme=default-v3" target="_blank"> - <CCardTitle>React Dashboard Template</CCardTitle> - <CCardSubtitle className="mb-3 text-body-secondary">Default Theme v3</CCardSubtitle> - <CImage className="rounded shadow-sm" fluid src="https://coreui.io/images/templates/coreui_pro_default_v3_1440.webp" alt=""/> - </CLink> - </CCardBody> - </CCard> - </CCol> - <CCol md={6}> - <CCard className="mb-4"> - <CCardBody> - <CLink className="text-decoration-none text-reset" href="https://coreui.io/product/react-dashboard-template/?theme=light-v3" target="_blank"> - <CCardTitle>React Dashboard Template</CCardTitle> - <CCardSubtitle className="mb-3 text-body-secondary">Light Theme v3</CCardSubtitle> - <CImage className="rounded shadow-sm" fluid src="https://coreui.io/images/templates/coreui_pro_light_v3_1440.webp" alt=""/> - </CLink> - </CCardBody> - </CCard> - </CCol> - <CCol md={6}> - <CCard className="mb-4"> - <CCardBody> - <CLink className="text-decoration-none text-reset" href="https://coreui.io/product/react-dashboard-template/?theme=default" target="_blank"> - <CCardTitle>React Dashboard Template</CCardTitle> - <CCardSubtitle className="mb-3 text-body-secondary">Default Theme</CCardSubtitle> - <CImage className="rounded shadow-sm" fluid src="https://coreui.io/images/templates/coreui_pro_default_1440.webp" alt=""/> - </CLink> - </CCardBody> - </CCard> - </CCol> - <CCol md={6}> - <CCard className="mb-4"> - <CCardBody> - <CLink className="text-decoration-none text-reset" href="https://coreui.io/product/react-dashboard-template/?theme=light" target="_blank"> - <CCardTitle>React Dashboard Template</CCardTitle> - <CCardSubtitle className="mb-3 text-body-secondary">Light Theme</CCardSubtitle> - <CImage className="rounded shadow-sm" fluid src="https://coreui.io/images/templates/coreui_pro_light_1440.webp" alt=""/> - </CLink> - </CCardBody> - </CCard> - </CCol> - <CCol md={6}> - <CCard className="mb-4"> - <CCardBody> - <CLink className="text-decoration-none text-reset" href="https://coreui.io/product/react-dashboard-template/?theme=dark" target="_blank"> - <CCardTitle>React Dashboard Template</CCardTitle> - <CCardSubtitle className="mb-3 text-body-secondary">Dark Theme</CCardSubtitle> - <CImage className="rounded shadow-sm" fluid src="https://coreui.io/images/templates/coreui_pro_dark_1440.webp" alt=""/> - </CLink> - </CCardBody> - </CCard> - </CCol> -</CRow> \ No newline at end of file diff --git a/packages/docs/content/templates/contents.mdx b/packages/docs/content/templates/contents.mdx deleted file mode 100644 index c11998d1..00000000 --- a/packages/docs/content/templates/contents.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: React templates contents -name: React templates contents -description: Discover what's included in CoreUI React Admin Template, including our precompiled and source code flavors. -menu: Templates -route: /templates/contents ---- - -## Project structure - -Once downloaded, unzip the compressed folder and you'll see something like this: - -```text -coreui-react-admin-template/ -├── public/ -├── src/ -│ ├── assets/ -│ │ ├── brand/ -│ │ └── images/ -│ ├── components/ -│ ├── layout/ -│ ├── scss/ -│ └── views/ -│ ├── base/ -│ ├── buttons/ -│ ├── css/ -│ ├── icons/ -│ ├── notifications/ -│ ├── App.js -│ ├── App.test.js -│ ├── _nav.js -│ ├── index.js -│ ├── reportWebVitals.js -│ ├── routes.js -│ ├── setupTests.js -│ └── store.js -└── package.json -``` - -This is the most basic form of CoreUI React Admin Templates. diff --git a/packages/docs/content/templates/customize.mdx b/packages/docs/content/templates/customize.mdx deleted file mode 100644 index 740e3f2a..00000000 --- a/packages/docs/content/templates/customize.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Customize react templates -name: Customize react templates -description: Learn how to theme, customize, and extend CoreUI React Templates with Sass, a boatload of global options. -menu: Templates -route: /templates/customize ---- - -## Overview - -There are multiple ways to customize CoreUI for React. Your best path can depend on your project, the complexity of your build tools, the version of CoreUI for React you're using, browser support, and more. - -Our two preferred methods are: - -1. You can extend our source files. -2. You can override CoreUI’s styles. - -## File structure - -Utilize our source Sass files to take advantage of variables, maps, mixins, and functions to help you build faster and customize your project. - -Whenever possible, avoid modifying CoreUI's core files. For Sass, that means creating your own stylesheet that imports CoreUI for React so you can modify and extend it. Assuming you're using a package manager like npm, you'll have a file structure that looks like this: - -```text -your-project/ -├── ... -├── node_modules/ -│ ├── @coreui/coreui -│ │ ├── scss -│ │ └── ... -│ └── @coreui/react -│ └── ... -├── src -│ └── scss -│ ├── _custom.scss -│ ├── ... -│ ├── _variables.scss -│ └── ... -└── ... -``` - -## Variable defaults - -Every Sass variable in CoreUI for React includes the `!default` flag allowing you to override the variable's default value in your own Sass without modifying CoreUI's source code. Copy and paste variables as needed, modify their values, and remove the `!default` flag. If a variable has already been assigned, then it won't be re-assigned by the default values in CoreUI. - -You will find the complete list of CoreUI's variables in `node_modules/@coreui/coreui/scss/_variables.scss`. Some variables are set to `null`, these variables don't output the property unless they are overridden in your configuration. You can also find a specific component variables list in **Customizing** section ex. [Alerts - Customizing](https://coreui.io/react/docs/components/alerts#customizing) - -Here's an example that changes the `background-color` and `color` for the `<body>` when importing and compiling CoreUI for React via npm: - -```scss -// _variables.scss - -// Default variable overrides -$body-bg: #000; -$body-color: #111; -``` - -## Custom styles and overrides - -In your `custom.scss`, you can put custom code for CoreUI's components or your own styles. - -```scss -// _custom.scss - -// Additional custom code here -.custom-component { - border: 2px solid #222; -} -``` diff --git a/packages/docs/content/templates/download.mdx b/packages/docs/content/templates/download.mdx deleted file mode 100644 index af732f34..00000000 --- a/packages/docs/content/templates/download.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Download react templates -name: Download react templates -description: Download CoreUI React Admin Templates to get the source code that lets you customize and create your react-based application. -route: /templates/download ---- - -## Source files - -Compile CoreUI React Admin with your own asset pipeline by downloading our source Sass, and JavaScript files. This option requires some additional tooling: - -- Create React App -- React, React Dom, React Router -- Redux -- Sass compiler for compiling your CSS. - -<a href="https://coreui.io/product/free-react-admin-template/" className="btn btn-primary">Download</a> - -<br/><br/> - -### Clone repo - -You can also fork [CoreUI React Admin Template's repository](https://github.com/coreui/coreui-free-react-admin-template.git). - -```sh -git clone https://github.com/coreui/coreui-free-react-admin-template.git my-project -``` diff --git a/packages/docs/content/templates/installation.mdx b/packages/docs/content/templates/installation.mdx deleted file mode 100644 index 485dbe61..00000000 --- a/packages/docs/content/templates/installation.mdx +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: React templates installation -name: React templates installation -description: Learn how to use CoreUI React Admin Dashboard Templates including npm scripts to build templates, compile source code, run tests, and more. -menu: Templates -route: /templates/admin-dashboard ---- - -## Tooling setup - -CoreUI React Admin Templates uses [npm scripts](https://docs.npmjs.com/misc/scripts/) for its build system. Our `package.json` includes convenient methods for working with the framework, including compiling code, running tests, and more. - -To use our build system and run our admin template locally, you'll need a copy of source files and Node. Follow these steps and you should be ready to rock: - -1. [Download and install Node.js](https://nodejs.org/en/download/), which we use to manage our dependencies. -2. If you prefer to use Yarn instead of NPM, you have to [download and install it](https://classic.yarnpkg.com/lang/en/docs/install/) -3. [Download CoreUI React Admin Template](https://coreui.io/product/free-react-admin-template/). -4. Navigate to the root template directory and run `npm install` or `yarn install` to install our local dependencies listed in `package.json`. - -When completed, you'll be able to run the various commands provided from the command line. - -## Using npm scripts - -Our `package.json` includes numerous tasks for developing the project. Run `npm run` or `yarn run` to see all the npm scripts in your terminal. **Primary tasks include:** - -| Task | Description | -| --- | --- | -| `npm start` or `yarn start` | Compiles CSS and JavaScript, builds the documentation, and starts a local server. | -| `npm run build` or `yarn build` | Creates the `dist/` directory with compiled files. Uses [Sass](https://sass-lang.com/), [Autoprefixer](https://github.com/postcss/autoprefixer). | -| `npm test` or `yarn test` | Runs tests locally | - -## Sass - -CoreUI uses [Dart Sass](https://sass-lang.com/dart-sass) for compiling our Sass source files into CSS files (included in our build process), and we recommend you do the same if you're compiling Sass using your own asset pipeline. - -Dart Sass uses a rounding precision of 10 and for efficiency reasons does not allow adjustment of this value. We don't lower this precision during further processing of our generated CSS, such as during minification, but if you chose to do so we recommend maintaining a precision of at least 6 to prevent issues with browser rounding. - -## Autoprefixer - -We uses [Autoprefixer][autoprefixer] (included in our build process) to automatically add vendor prefixes to some CSS properties at build time. Doing so saves us time and code by allowing us to write key parts of our CSS a single time while eliminating the need for vendor mixins like those found in v3. - -We maintain the list of browsers supported through Autoprefixer in a separate file within our GitHub repository. See `.browserslistrc`. - -## Local template - -Here's how to get it started: - -1. Run through the [tooling setup](#tooling-setup) above to install all dependencies. -2. From the root template directory, run `npm run start` or `yarn start` in the command line. -3. Open `http://localhost:3000` in your browser, and voilà. - -## Troubleshooting - -Should you encounter problems with installing dependencies, uninstall all previous dependency versions (global and local). Then, rerun `npm install` or `yarn install`. diff --git a/packages/docs/gatsby-browser.js b/packages/docs/gatsby-browser.js deleted file mode 100644 index 4791853e..00000000 --- a/packages/docs/gatsby-browser.js +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react' -import '@docsearch/css' -import DefaultLayout from './src/templates/DefaultLayout' -import './src/styles/styles.scss' - -export const wrapPageElement = ({ element, props }) => { - return <DefaultLayout {...props}>{element}</DefaultLayout> -} diff --git a/packages/docs/gatsby-config.js b/packages/docs/gatsby-config.js deleted file mode 100644 index 5af7a215..00000000 --- a/packages/docs/gatsby-config.js +++ /dev/null @@ -1,101 +0,0 @@ -module.exports = { - siteMetadata: { - title: `CoreUI for React.js`, - titleTemplate: `%s · React UI Components · CoreUI `, - description: `CoreUI for React.js is UI Component library written in TypeScript, and ready for your next React.js project.`, - author: `@coreui_io`, - url: `https://coreui.io/react/docs/`, - siteUrl: `https://coreui.io/react/docs/`, - image: ``, // Path to your image you placed in the `static` folder - twitterUsername: `@coreui_io`, - }, - pathPrefix: `react/docs/`, - plugins: [ - `gatsby-plugin-react-helmet`, - `gatsby-plugin-image`, - { - resolve: `gatsby-source-filesystem`, - options: { - name: `images`, - path: `${__dirname}/src/images`, - }, - }, - `gatsby-transformer-sharp`, - `gatsby-plugin-sharp`, - { - resolve: `gatsby-plugin-manifest`, - options: { - icon: `${__dirname}/src/assets/images/brand/icon.png`, - name: `CoreUI for React.js`, - short_name: `CoreUI for React.js`, - start_url: `https://coreui.io/react/`, - background_color: `#fff`, - theme_color: `#321fdb`, - display: `standalone`, - }, - }, - { - resolve: `gatsby-source-filesystem`, - options: { - name: `docs`, - path: `${__dirname}/content/`, - }, - }, - { - resolve: `gatsby-source-filesystem`, - options: { - name: `scss`, - path: `./../../node_modules/@coreui/coreui/scss/`, - }, - }, - { - resolve: `gatsby-plugin-mdx`, - options: { - mdxOptions: { - remarkPlugins: [ - // Add GitHub Flavored Markdown (GFM) support - require(`remark-gfm`), - ], - }, - gatsbyRemarkPlugins: [ - { - resolve: `gatsby-remark-import-markdown`, - options: { - directory: `${__dirname}/content/api/`, - }, - }, - `gatsby-remark-jsx-preview`, - { - resolve: `gatsby-remark-autolink-headers`, - options: { - className: `anchor-link`, - icon: `<span>#</span>`, - isIconAfterHeader: true, - }, - }, - { - resolve: 'gatsby-remark-external-links', - options: { - target: '_blank', - rel: 'nofollow', - }, - }, - ], - }, - }, - `gatsby-plugin-sass`, - `gatsby-plugin-typescript`, - { - resolve: `gatsby-plugin-sitemap`, - options: { - output: `/sitemap-react.xml`, - }, - }, - { - resolve: `gatsby-plugin-google-tagmanager`, - options: { - id: `GTM-KX4JH47`, - }, - }, - ], -} diff --git a/packages/docs/gatsby-node.js b/packages/docs/gatsby-node.js deleted file mode 100644 index a93ffd30..00000000 --- a/packages/docs/gatsby-node.js +++ /dev/null @@ -1,66 +0,0 @@ -const path = require('node:path') -const { createFilePath } = require('gatsby-source-filesystem') - -exports.onCreateNode = async ({ node, loadNodeContent, actions: { createNodeField }, getNode }) => { - if (node.internal.type === 'Mdx') { - const slug = createFilePath({ node, getNode }) - - createNodeField({ - node, - name: 'slug', - value: `${slug}`, - }) - } - - if (node.ext === '.scss') { - const nodeContent = await loadNodeContent(node) - createNodeField({ - node, - name: `content`, - value: nodeContent, - }) - } -} - -exports.createPages = async ({ graphql, actions: { createPage, createRedirect }, reporter }) => { - const result = await graphql(` - query { - allMdx { - nodes { - id - fields { - slug - } - internal { - contentFilePath - } - tableOfContents(maxDepth: 3) - } - } - } - `) - - if (result.errors) { - reporter.panicOnBuild('Error loading MDX result', result.errors) - } - - const posts = result.data.allMdx.nodes - - if (posts.length > 0) { - posts.forEach((node) => { - createPage({ - path: node.fields.slug, - component: `${path.resolve(`./src/templates/MdxLayout.tsx`)}?__contentFilePath=${ - node.internal.contentFilePath - }`, - context: { id: node.id }, - }) - }) - createRedirect({ - fromPath: `/`, - toPath: `/getting-started/introduction/`, - redirectInBrowser: true, - isPermanent: true, - }) - } -} diff --git a/packages/docs/gatsby-ssr.js b/packages/docs/gatsby-ssr.js deleted file mode 100644 index 4791853e..00000000 --- a/packages/docs/gatsby-ssr.js +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react' -import '@docsearch/css' -import DefaultLayout from './src/templates/DefaultLayout' -import './src/styles/styles.scss' - -export const wrapPageElement = ({ element, props }) => { - return <DefaultLayout {...props}>{element}</DefaultLayout> -} diff --git a/packages/docs/package.json b/packages/docs/package.json deleted file mode 100644 index ee205308..00000000 --- a/packages/docs/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "@coreui/react-docs", - "version": "5.0.0-rc.0", - "private": true, - "description": "", - "homepage": "https://coreui.io/react/", - "bugs": { - "url": "https://github.com/coreui/coreui-react/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/coreui/coreui-react.git" - }, - "license": "MIT", - "author": "The CoreUI Team (https://github.com/orgs/coreui/people)", - "scripts": { - "api": "rimraf \"content/api/*\" & node build/api.js", - "build": "gatsby build", - "develop": "gatsby develop", - "dist": "run-s api build", - "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"", - "start": "gatsby develop", - "serve": "gatsby serve", - "clean": "gatsby clean" - }, - "dependencies": { - "@coreui/chartjs": "^4.0.0-rc.0", - "@coreui/coreui": "^5.0.0-rc.0", - "@coreui/icons": "^3.0.1", - "@coreui/icons-react": "^2.2.1", - "@coreui/react-chartjs": "^3.0.0-rc.0", - "@coreui/utils": "^2.0.2", - "@docsearch/css": "^3.5.2", - "@mdx-js/mdx": "^2.3.0", - "@mdx-js/react": "^2.3.0", - "@types/react-helmet": "^6.1.9", - "gatsby": "^5.12.9", - "gatsby-plugin-google-tagmanager": "^5.12.3", - "gatsby-plugin-image": "^3.12.3", - "gatsby-plugin-manifest": "^5.12.3", - "gatsby-plugin-mdx": "^5.12.3", - "gatsby-plugin-offline": "^6.12.3", - "gatsby-plugin-react-helmet": "^6.12.0", - "gatsby-plugin-sass": "^6.12.3", - "gatsby-plugin-sharp": "^5.12.3", - "gatsby-plugin-sitemap": "^6.12.3", - "gatsby-remark-autolink-headers": "^6.12.3", - "gatsby-remark-external-links": "^0.0.4", - "gatsby-source-filesystem": "^5.12.1", - "gatsby-transformer-sharp": "^5.12.3", - "glob": "^7.2.3", - "globby": "^11.1.0", - "prism-react-renderer": "^2.2.0", - "prismjs": "^1.29.0", - "prop-types": "^15.8.1", - "react": "^18.2.0", - "react-docgen-typescript": "^2.2.2", - "react-dom": "^18.2.0", - "react-helmet": "^6.1.0", - "react-imask": "^7.1.3", - "rimraf": "^5.0.5", - "sass": "^1.69.5" - }, - "devDependencies": { - "npm-run-all": "^4.1.5" - } -} diff --git a/packages/docs/src/AppContext.tsx b/packages/docs/src/AppContext.tsx deleted file mode 100644 index 39ff4698..00000000 --- a/packages/docs/src/AppContext.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' - -export interface AppContextProps { - name?: string - sidebarVisible?: boolean | undefined - setSidebarVisible?: React.Dispatch<React.SetStateAction<boolean | undefined>> -} - -export const AppContextInitialState: AppContextProps = { - name: 'DocsContext', -} - -export const AppContext = React.createContext(AppContextInitialState) diff --git a/packages/docs/src/assets/coreui-react.svg b/packages/docs/src/assets/coreui-react.svg deleted file mode 100755 index 00738947..00000000 --- a/packages/docs/src/assets/coreui-react.svg +++ /dev/null @@ -1,28 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 615 134"> - <g> - <g fill="#00a1ff"> - <path d="M361.773,90.1513,353.0054,69.415a.25.25,0,0,0-.2558-.1914h-9.9844a.2263.2263,0,0,0-.2559.2558v20.543a.5659.5659,0,0,1-.64.6406h-1.2163a.5654.5654,0,0,1-.64-.6406v-43.52a.5656.5656,0,0,1,.64-.64h12.5444a9.9785,9.9785,0,0,1,7.7437,3.2315,12.2042,12.2042,0,0,1,2.9443,8.5449,12.4389,12.4389,0,0,1-2.24,7.584,9.3707,9.3707,0,0,1-6.08,3.7441c-.1709.0859-.2139.1914-.1279.3193l8.7041,20.6084.0639.2559c0,.3418-.1919.5117-.5757.5117h-1.1523A.7029.7029,0,0,1,361.773,90.1513Zm-19.2637-41.793V66.8544a.2263.2263,0,0,0,.2559.2569h10.3037a7.6687,7.6687,0,0,0,6.0166-2.5928,9.878,9.878,0,0,0,2.3037-6.8154,10.2858,10.2858,0,0,0-2.272-6.9756,7.601,7.601,0,0,0-6.0483-2.625H342.7652A.2263.2263,0,0,0,342.5093,48.3583Z"/> - <path d="M401.0816,48.1025H381.05a.2263.2263,0,0,0-.2559.2558V66.8544a.2263.2263,0,0,0,.2559.2569h13.8237a.5663.5663,0,0,1,.6406.64v.96a.566.566,0,0,1-.6406.64H381.05a.2263.2263,0,0,0-.2559.2559V88.1669a.2259.2259,0,0,0,.2559.2559h20.0317a.567.567,0,0,1,.6406.6406v.959a.5663.5663,0,0,1-.6406.6406H378.938a.5656.5656,0,0,1-.64-.6406v-43.52a.5657.5657,0,0,1,.64-.64h22.1436a.5664.5664,0,0,1,.6406.64v.96A.566.566,0,0,1,401.0816,48.1025Z"/> - <path d="M438.8023,90.1513l-2.4316-8.832a.2962.2962,0,0,0-.32-.1924H419.2828a.2946.2946,0,0,0-.32.1924l-2.3682,8.7676a.6576.6576,0,0,1-.7036.5761h-1.2163a.5883.5883,0,0,1-.4795-.1914.5822.5822,0,0,1-.0962-.5127L426.13,46.3749a.6436.6436,0,0,1,.7041-.5117h1.6a.6442.6442,0,0,1,.7041.5117l12.16,43.584.0644.1924c0,.3418-.2138.5117-.64.5117h-1.2163A.6428.6428,0,0,1,438.8023,90.1513ZM419.6988,78.9189a.3026.3026,0,0,0,.2236.0957h15.4883a.3039.3039,0,0,0,.2236-.0957c.0645-.0645.0742-.1172.0323-.16L427.7945,49.831c-.043-.085-.086-.1279-.1279-.1279s-.086.0429-.128.1279l-7.872,28.9277C419.6236,78.8017,419.6343,78.8544,419.6988,78.9189Z"/> - <path d="M456.357,87.9111a11.6374,11.6374,0,0,1-3.3277-8.7041V57.19a11.4135,11.4135,0,0,1,3.36-8.5752,12.0908,12.0908,0,0,1,8.8-3.2647,12.2528,12.2528,0,0,1,8.8643,3.2324,11.3906,11.3906,0,0,1,3.36,8.6075v.6406a.5663.5663,0,0,1-.6406.6406l-1.28.0635q-.6408,0-.64-.5762v-.832a9.2874,9.2874,0,0,0-2.6558-6.9121,10.67,10.67,0,0,0-14.0161,0,9.2838,9.2838,0,0,0-2.6562,6.9121V79.3994a9.2824,9.2824,0,0,0,2.6562,6.9121,10.6734,10.6734,0,0,0,14.0161,0,9.286,9.286,0,0,0,2.6558-6.9121v-.7686q0-.5757.64-.5752l1.28.0635a.5663.5663,0,0,1,.6406.64V79.27a11.4976,11.4976,0,0,1-3.36,8.6407,13.6262,13.6262,0,0,1-17.6963,0Z"/> - <path d="M514.1929,46.5029v.96a.5655.5655,0,0,1-.64.64h-10.752a.2262.2262,0,0,0-.2558.2558V90.0224a.5663.5663,0,0,1-.6407.6406H500.689a.5654.5654,0,0,1-.64-.6406V48.3583a.2267.2267,0,0,0-.2559-.2558H489.6172a.5653.5653,0,0,1-.64-.64v-.96a.5657.5657,0,0,1,.64-.64h23.9361A.5659.5659,0,0,1,514.1929,46.5029Z"/> - <path d="M521.8218,89.5107a2.8346,2.8346,0,0,1-.8-2.0479,2.9233,2.9233,0,0,1,.8-2.1123,2.7577,2.7577,0,0,1,2.08-.832,2.8467,2.8467,0,0,1,2.9439,2.9443,2.7544,2.7544,0,0,1-.8321,2.08,2.9213,2.9213,0,0,1-2.1118.8A2.754,2.754,0,0,1,521.8218,89.5107Z"/> - <path d="M542.1607,88.0068a11.3094,11.3094,0,0,1-3.2-8.416V74.1513a.5663.5663,0,0,1,.64-.6406h1.2159a.5667.5667,0,0,1,.64.6406v5.5039a9.1437,9.1437,0,0,0,2.5283,6.72,8.9735,8.9735,0,0,0,6.6875,2.56,8.7894,8.7894,0,0,0,9.28-9.2793V46.5029a.5655.5655,0,0,1,.64-.64h1.2163a.5661.5661,0,0,1,.64.64V79.5908a11.2516,11.2516,0,0,1-3.2324,8.416,13.0622,13.0622,0,0,1-17.0557,0Z"/> - <path d="M580.1055,88.1025a10.4824,10.4824,0,0,1-3.36-8.127V78.1826a.5655.5655,0,0,1,.64-.64h1.0884a.566.566,0,0,1,.64.64v1.6005a8.5438,8.5438,0,0,0,2.752,6.6553,10.5357,10.5357,0,0,0,7.36,2.4961,9.8761,9.8761,0,0,0,6.9761-2.3672,8.2153,8.2153,0,0,0,2.56-6.3359,8.3974,8.3974,0,0,0-1.12-4.416,11.3828,11.3828,0,0,0-3.3282-3.3926,71.6257,71.6257,0,0,0-6.1762-3.7119,71.3024,71.3024,0,0,1-6.24-3.84,12.174,12.174,0,0,1-3.4238-3.6806,10.2567,10.2567,0,0,1-1.28-5.3438,9.8592,9.8592,0,0,1,3.0718-7.7441,12.0122,12.0122,0,0,1,8.32-2.752q5.6953,0,8.96,3.1045a10.8233,10.8233,0,0,1,3.2641,8.2236v1.6006a.5658.5658,0,0,1-.64.64h-1.1519a.5653.5653,0,0,1-.64-.64V56.8076a8.8646,8.8646,0,0,0-2.624-6.6885,9.9938,9.9938,0,0,0-7.232-2.5283,9.3654,9.3654,0,0,0-6.5278,2.1445,7.8216,7.8216,0,0,0-2.3682,6.1113,7.8007,7.8007,0,0,0,1.0245,4.16,10.3761,10.3761,0,0,0,3.0078,3.04,62.8289,62.8289,0,0,0,5.9521,3.4883,71.0575,71.0575,0,0,1,6.72,4.2559,13.4537,13.4537,0,0,1,3.648,3.9365,10.0487,10.0487,0,0,1,1.28,5.1836,10.7141,10.7141,0,0,1-3.2637,8.1914q-3.2637,3.0732-8.832,3.0722Q583.4649,91.1747,580.1055,88.1025Z"/> - </g> - <g fill="var(--cui-body-color, currentColor)"> - <g> - <path d="M99.59,36.0577l-39-22.5167a12,12,0,0,0-12,0l-39,22.5166a12.0337,12.0337,0,0,0-6,10.3924V91.4833a12.0331,12.0331,0,0,0,6,10.3923l39,22.5167a12,12,0,0,0,12,0l39-22.5167a12.0333,12.0333,0,0,0,6-10.3923V46.45A12.0336,12.0336,0,0,0,99.59,36.0577Zm-2,55.4256a4,4,0,0,1-2,3.4641l-39,22.5167a4.0006,4.0006,0,0,1-4,0l-39-22.5167a4,4,0,0,1-2-3.4641V46.45a4,4,0,0,1,2-3.4642l39-22.5166a4,4,0,0,1,4,0l39,22.5166a4,4,0,0,1,2,3.4642Z"/> - <path d="M77.612,82.0046H74.746a4.001,4.001,0,0,0-1.9247.4934L55.5406,91.9833,35.59,80.4648V57.4872L55.54,45.9687l17.2893,9.4549a3.9993,3.9993,0,0,0,1.9192.4906h2.8632a2,2,0,0,0,2-2V51.2024a2,2,0,0,0-1.04-1.7547L59.3833,38.9521a8.0389,8.0389,0,0,0-7.8427.09L31.59,50.56a8.0245,8.0245,0,0,0-4,6.9287v22.976a8,8,0,0,0,4,6.9283l19.95,11.5186a8.0427,8.0427,0,0,0,7.8432.0879l19.19-10.5312a2,2,0,0,0,1.0378-1.7533v-2.71A2,2,0,0,0,77.612,82.0046Z"/> - </g> - <g> - <path d="M172.3351,45.3618a15.0166,15.0166,0,0,0-15,14.9995V77.6387a15,15,0,0,0,30,0V60.3613A15.0166,15.0166,0,0,0,172.3351,45.3618Zm7,32.2769a7,7,0,0,1-14,0V60.3613a7,7,0,0,1,14,0Z"/> - <path d="M135.6692,53.4211a7.01,7.01,0,0,1,7.8681,6.0752.9892.9892,0,0,0,.9842.865h6.03a1.0109,1.0109,0,0,0,.9988-1.0971,15.0183,15.0183,0,0,0-15.7162-13.8837A15.2881,15.2881,0,0,0,121.59,60.7968V77.2037A15.288,15.288,0,0,0,135.8346,92.62a15.0184,15.0184,0,0,0,15.7162-13.8842,1.0109,1.0109,0,0,0-.9988-1.0971h-6.03a.9892.9892,0,0,0-.9842.865,7.0106,7.0106,0,0,1-7.868,6.0757,7.1642,7.1642,0,0,1-6.0789-7.1849V60.6057A7.1638,7.1638,0,0,1,135.6692,53.4211Z"/> - <path d="M218.5125,72.9277a12.1584,12.1584,0,0,0,7.1843-11.0771V58.1494A12.1494,12.1494,0,0,0,213.5474,46H196.59a1,1,0,0,0-1,1V91a1,1,0,0,0,1,1h6a1,1,0,0,0,1-1V74h6.6215l7.9154,17.4138a1,1,0,0,0,.91.5862h6.5912a1,1,0,0,0,.91-1.4138Zm-.8157-11.0771A4.1538,4.1538,0,0,1,213.5479,66h-9.8511V54h9.8511a4.1538,4.1538,0,0,1,4.1489,4.1494Z"/> - <path d="M260.59,46h-26a1,1,0,0,0-1,1V91a1,1,0,0,0,1,1h26a1,1,0,0,0,1-1V85a1,1,0,0,0-1-1h-19V72h13a1,1,0,0,0,1-1V65a1,1,0,0,0-1-1h-13V54h19a1,1,0,0,0,1-1V47A1,1,0,0,0,260.59,46Z"/> - <path d="M298.59,46h-6a1,1,0,0,0-1,1V69.6475a7.0066,7.0066,0,1,1-14,0V47a1,1,0,0,0-1-1h-6a1,1,0,0,0-1,1V69.6475a15.0031,15.0031,0,1,0,30,0V47A1,1,0,0,0,298.59,46Z"/> - <rect x="307.5904" y="46" width="8" height="38" rx="1"/> - </g> - </g> - </g> -</svg> \ No newline at end of file diff --git a/packages/docs/src/assets/images/brand/icon.png b/packages/docs/src/assets/images/brand/icon.png deleted file mode 100644 index ba91b901bb397c8b9ffa65097128a244347c97c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18140 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�`@H9YcqER9VHIipTM(UJBMTMZA7(l|Gzvpd!~{ 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 diff --git a/packages/docs/src/components/Ads.tsx b/packages/docs/src/components/Ads.tsx deleted file mode 100644 index a873d30a..00000000 --- a/packages/docs/src/components/Ads.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { FC, useEffect, useRef } from 'react' - -interface AdsProps { - code: string - location: string - placement: string -} - -export const Ads: FC<AdsProps> = ({ code, location, placement }) => { - const ref = useRef<HTMLDivElement>(null) - - useEffect(() => { - if (ref.current) { - ref.current.innerHTML = '' - const s = document.createElement('script') - s.id = '_carbonads_js' - s.src = `//cdn.carbonads.com/carbon.js?serve=${code}&placement=${placement}` - ref.current.appendChild(s) - } - }, [location]) - - return <div ref={ref} /> -} - -Ads.displayName = 'Ads' - -export default Ads diff --git a/packages/docs/src/components/Banner.tsx b/packages/docs/src/components/Banner.tsx deleted file mode 100644 index 4d0fc3a0..00000000 --- a/packages/docs/src/components/Banner.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import React, { FC } from 'react' -import { CLink } from '@coreui/react/src/index' - -interface BannerProps { - pro: boolean -} - -const Banner: FC<BannerProps> = ({ pro }) => { - return pro ? ( - <div className="bg-danger d-none d-lg-block bg-opacity-10 border-start border-start-5 border-start-danger p-4 pb-3 mb-5"> - <h3 className="mb-4">CoreUI PRO Component</h3> - <p> - To use this component you must have a CoreUI PRO license. Buy the{' '} - <a href="https://coreui.io/pricing/?framework=react&docs=coreui-banner-pro">CoreUI PRO</a>{' '} - and get access to all PRO components, features, templates, and dedicated support. - </p> - </div> - ) : ( - <div className="bg-info d-none d-lg-block bg-opacity-10 border-start border-start-5 border-start-info p-4 pb-3 mb-5"> - <h3 className="mb-4">Support CoreUI Development</h3> - <p> - CoreUI is an MIT-licensed open source project and is completely free to use. However, the - amount of effort needed to maintain and develop new features for the project is not - sustainable without proper financial backing. - </p> - <p>You can support our Open Source software development in the following ways:</p> - <ul> - <li> - Buy the{' '} - <CLink href="https://coreui.io/pricing/?framework=react&docs=coreui-banner-free"> - CoreUI PRO - </CLink> - , and get access to PRO components, and dedicated support. - </li> - <li> - <CLink href="https://opencollective.com/coreui" target="_blank"> - Became a sponsor - </CLink> - , and get your logo on BACKERS.md/README.md files or each site of this documentation - </li> - <li> - Give us a star ⭐️ on{' '} - <CLink href="https://github.com/coreui/coreui-react" target="_blank"> - Github - </CLink> - . - </li> - </ul> - </div> - ) -} - -Banner.displayName = 'Banner' - -export default Banner diff --git a/packages/docs/src/components/Callout.tsx b/packages/docs/src/components/Callout.tsx deleted file mode 100644 index b1299b12..00000000 --- a/packages/docs/src/components/Callout.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React, { FC, ReactNode } from 'react' -interface CalloutProps { - children: ReactNode - color: string - title?: string -} - -const Callout: FC<CalloutProps> = ({ children, color, title }) => { - return ( - <div className={`docs-callout docs-callout-${color}`}> - {title && <h5>{title}</h5>} - {children} - </div> - ) -} - -Callout.displayName = 'Callout' - -export default Callout diff --git a/packages/docs/src/components/CodeBlock.tsx b/packages/docs/src/components/CodeBlock.tsx deleted file mode 100644 index d7fd2422..00000000 --- a/packages/docs/src/components/CodeBlock.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { FC } from 'react' -import { Highlight, Prism } from 'prism-react-renderer' - -interface CodeBlockProps { - children: any // eslint-disable-line @typescript-eslint/no-explicit-any -} - -const CodeBlock: FC<CodeBlockProps> = ({ children }) => { - ;(typeof global === 'undefined' ? window : global).Prism = Prism - // eslint-disable-next-line unicorn/prefer-module - require('prismjs/components/prism-bash') - require('prismjs/components/prism-scss') - const _children = children && children.props.children - const language = children.props.className - ? children.props.className.replace(/language-/, '') - : 'jsx' - - return ( - <div className="highlight"> - <Highlight code={_children?.trim()} language={language} theme={{ plain: {}, styles: [] }}> - {({ className, style, tokens, getLineProps, getTokenProps }) => ( - <pre className={className} style={{ ...style }}> - {tokens.map((line, i) => ( - <div key={i} {...getLineProps({ line, key: i })}> - {line.map((token, key) => ( - <span key={key} {...getTokenProps({ token, key })} /> - ))} - </div> - ))} - </pre> - )} - </Highlight> - </div> - ) -} - -CodeBlock.displayName = 'CodeBlock' - -export default CodeBlock diff --git a/packages/docs/src/components/Example.tsx b/packages/docs/src/components/Example.tsx deleted file mode 100644 index c8c2a47e..00000000 --- a/packages/docs/src/components/Example.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React, { FC, ReactNode } from 'react' -interface ExampleProps { - children: ReactNode - className: string -} - -const Example: FC<ExampleProps> = ({ children, className, ...rest }) => { - return ( - <div - className={`docs-example ${className} ${className && className.includes('p-') ? '' : 'p-3'}`} - {...rest} - > - {children} - </div> - ) -} - -Example.displayName = 'Example' - -export default Example diff --git a/packages/docs/src/components/Footer.tsx b/packages/docs/src/components/Footer.tsx deleted file mode 100644 index 0533513f..00000000 --- a/packages/docs/src/components/Footer.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React, { FC } from 'react' - -import { CContainer, CFooter } from '@coreui/react/src/index' - -// @ts-expect-error json file -import pkg from './../../package.json' - -const Footer: FC = () => { - return ( - <CFooter className="docs-footer p-3 p-md-5 mt-5 text-center text-sm-start"> - <CContainer> - <ul className="docs-footer-links ps-0 mb-3"> - <li className="d-inline-block"> - <a href="https://github.com/coreui">GitHub</a> - </li> - <li className="d-inline-block ms-3"> - <a href="https://twitter.com/core_ui">Twitter</a> - </li> - <li className="d-inline-block ms-3 ps-3 border-start border-2"> - <a href="https://coreui.io/">CoreUI (Vanilla)</a> - </li> - <li className="d-inline-block ms-3"> - <a href="https://coreui.io/angular/">CoreUI for Angular</a> - </li> - <li className="d-inline-block ms-3"> - <a href="https://coreui.io/vue/">CoreUI for Vue.js</a> - </li> - </ul> - <p className="mb-0">CoreUI for React is Open Source UI Components Library for React.js.</p> - <p className="mb-0"> - Currently v{pkg.version}. CoreUI code licensed{' '} - <a - href="https://github.com/coreui/coreui/blob/main/LICENSE" - target="_blank" - rel="noreferrer" - > - MIT - </a> - , docs{' '} - <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank" rel="noreferrer"> - CC BY 3.0 - </a> - .{' '} - <strong> - CoreUI PRO requires a{' '} - <a href="https://coreui.io/pricing/?framework=react&docs=footer">commercial license</a>. - </strong> - </p> - </CContainer> - </CFooter> - ) -} - -Footer.displayName = 'Footer' - -export default Footer diff --git a/packages/docs/src/components/Header.tsx b/packages/docs/src/components/Header.tsx deleted file mode 100644 index 50cf1b7a..00000000 --- a/packages/docs/src/components/Header.tsx +++ /dev/null @@ -1,143 +0,0 @@ -import React, { FC } from 'react' - -import CIcon from '@coreui/icons-react' -import { - cibGithub, - cibOpenCollective, - cibTwitter, - cilCloudDownload, - cilMenu, - cilSun, - cilMoon, - cilContrast, - cilHandshake, -} from '@coreui/icons' - -import { - CButton, - CDropdown, - CDropdownItem, - CDropdownMenu, - CDropdownToggle, - CHeader, - CHeaderNav, - CHeaderToggler, - CNavItem, - useColorModes, -} from '@coreui/react/src' -import { AppContext } from './../AppContext' - -const Header: FC = () => { - const { colorMode, setColorMode } = useColorModes('coreui-react-docs-theme') - return ( - <> - <AppContext.Consumer> - {(context) => ( - <CHeader className="mb-5" position="sticky"> - <CHeaderToggler - className="ms-md-3" - onClick={() => { - context.setSidebarVisible && context.setSidebarVisible(!context.sidebarVisible) - }} - > - <CIcon icon={cilMenu} size="lg" /> - </CHeaderToggler> - <div className="docs-search" id="docsearch"></div> - <CHeaderNav className="ms-auto"> - <CNavItem - href="https://github.com/coreui/coreui-react/" - aria-label="Visit our GitHub" - > - <CIcon icon={cibGithub} size="xl" /> - </CNavItem> - <CNavItem href="https://twitter.com/core_ui" aria-label="Visit our Twitter"> - <CIcon icon={cibTwitter} size="xl" /> - </CNavItem> - <CNavItem - href="https://opencollective.com/coreui" - aria-label="Visit our OpenCollective" - > - <CIcon icon={cibOpenCollective} size="xl" /> - </CNavItem> - <li className="nav-item py-2 py-lg-1"> - <div className="vr d-none d-lg-flex h-100 mx-lg-2 text-body text-opacity-75"></div> - <hr className="d-lg-none my-2 text-white-50" /> - </li> - <CDropdown variant="nav-item" placement="bottom-end"> - <CDropdownToggle className="nav-link" color="link" caret={false}> - {colorMode === 'dark' ? ( - <CIcon icon={cilMoon} size="xl" /> - ) : (colorMode === 'auto' ? ( - <CIcon icon={cilContrast} size="xl" /> - ) : ( - <CIcon icon={cilSun} size="xl" /> - ))} - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem - active={colorMode === 'light'} - className="d-flex align-items-center" - component="button" - type="button" - onClick={() => setColorMode('light')} - > - <CIcon className="me-2" icon={cilSun} size="lg" /> Light - </CDropdownItem> - <CDropdownItem - active={colorMode === 'dark'} - className="d-flex align-items-center" - component="button" - type="button" - onClick={() => setColorMode('dark')} - > - <CIcon className="me-2" icon={cilMoon} size="lg" /> Dark - </CDropdownItem> - <CDropdownItem - active={colorMode === 'auto'} - className="d-flex align-items-center" - component="button" - type="button" - onClick={() => setColorMode('auto')} - > - <CIcon className="me-2" icon={cilContrast} size="lg" /> Auto - </CDropdownItem> - </CDropdownMenu> - </CDropdown> - <li className="nav-item py-2 py-lg-1"> - <div className="vr d-none d-lg-flex h-100 mx-lg-2 text-body text-opacity-75"></div> - <hr className="d-lg-none my-2 text-white-50" /> - </li> - </CHeaderNav> - <CButton - className="d-lg-inline-block my-2 my-md-0 ms-md-3" - color="primary" - href="https://coreui.io/react/docs/getting-started/introduction/" - variant="outline" - > - <CIcon className="me-2" icon={cilCloudDownload} /> Download - </CButton> - <CButton - className="d-lg-inline-block my-2 my-md-0 ms-md-3" - color="primary" - href="https://coreui.io/about/services/?docs=coreui-header-button" - variant="outline" - > - <CIcon className="me-2" icon={cilHandshake} /> Hire Us - </CButton> - <CButton - className="d-lg-inline-block my-2 my-md-0 ms-md-3" - color="primary" - href="https://coreui.io/pricing/?framework=react&docs=coreui-header-button" - > - Get CoreUI PRO - </CButton> - </CHeader> - )} - </AppContext.Consumer> - </> - ) -} - -Header.displayName = 'Header' - -export default Header diff --git a/packages/docs/src/components/ScssDocs.tsx b/packages/docs/src/components/ScssDocs.tsx deleted file mode 100644 index 45d649db..00000000 --- a/packages/docs/src/components/ScssDocs.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react' -import { useStaticQuery, graphql } from 'gatsby' -import { Highlight, Prism } from 'prism-react-renderer' - -interface ScssDocsProps { - file: string - capture: string -} - -const ScssDocs = ({ file, capture }: ScssDocsProps) => { - ;(typeof global === 'undefined' ? window : global).Prism = Prism - // eslint-disable-next-line unicorn/prefer-module - require('prismjs/components/prism-scss') - - const data = useStaticQuery(graphql` - query { - allFile(filter: { ext: { eq: ".scss" } }) { - edges { - node { - name - relativePath - id - internal { - content - } - } - } - } - } - `) - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const _file = data.allFile.edges.find((node: any) => node.node.relativePath === file) - const captureStart = `// scss-docs-start ${capture}` - const captureEnd = `// scss-docs-end ${capture}` - const re = new RegExp(`${captureStart}((?:.|\n)*)${captureEnd}`) - const captured = re.exec(_file.node.internal.content) - const code = captured ? captured[1].trim() : undefined - - if (code === undefined) { - console.error(`Can't find "${capture}" in ${_file.node.relativePath}`) - } - - return ( - code && ( - <div className="highlight"> - <Highlight - code={code - .replaceAll('--#{$prefix}', '--cui-') - .replaceAll('\n -', '\n-') - .replaceAll('\n @', '\n@')} - language="scss" - theme={{ plain: {}, styles: [] }} - > - {({ className, style, tokens, getLineProps, getTokenProps }) => ( - <pre className={className} style={{ ...style }}> - {tokens.map((line, i) => { - const lineProps = getLineProps({ line, key: i }) - return ( - <div className={lineProps.className} key={i}> - {line.map((token, key) => { - const tokenProps = getTokenProps({ token, key }) - return ( - <span className={tokenProps.className} key={key}> - {tokenProps.children} - </span> - ) - })} - </div> - ) - })} - </pre> - )} - </Highlight> - </div> - ) - ) -} - -ScssDocs.displayName = 'ScssDocs' - -export default ScssDocs diff --git a/packages/docs/src/components/Seo.tsx b/packages/docs/src/components/Seo.tsx deleted file mode 100644 index 72a162f0..00000000 --- a/packages/docs/src/components/Seo.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import React from 'react' -import { Helmet } from 'react-helmet' -import { useLocation } from '@reach/router' -import { useStaticQuery, graphql } from 'gatsby' - -interface SEOProps { - title?: string - description?: string - name?: string - image?: string - article?: string -} - -const SEO = ({ title, description, name, image, article }: SEOProps) => { - const { pathname } = useLocation() - const { site } = useStaticQuery(query) - - const { - defaultTitle, - titleTemplate, - defaultDescription, - siteUrl, - defaultImage, - twitterUsername, - } = site.siteMetadata - - const prefix = site.pathPrefix - - const seo = { - title: title || defaultTitle, - description: description || defaultDescription, - name: name, - image: `${siteUrl}${image || defaultImage}`, - url: `${siteUrl}${pathname.replace(`${prefix}/`, '')}`, - } - - return ( - <Helmet title={seo.title} titleTemplate={titleTemplate}> - <meta name="description" content={seo.description} /> - <meta name="image" content={seo.image} /> - - {seo.url && <meta property="og:url" content={seo.url.replace('docs//', 'docs/')} />} - - {(article ? true : null) && <meta property="og:type" content="article" />} - - {seo.title && <meta property="og:title" content={seo.title} />} - - {seo.description && <meta property="og:description" content={seo.description} />} - - {seo.image && <meta property="og:image" content={seo.image} />} - - <meta name="twitter:card" content="summary_large_image" /> - - {twitterUsername && <meta name="twitter:creator" content={twitterUsername} />} - - {seo.title && <meta name="twitter:title" content={seo.title} />} - - {seo.description && <meta name="twitter:description" content={seo.description} />} - - {seo.image && <meta name="twitter:image" content={seo.image} />} - - {seo.name && ( - <script type="application/ld+json"> - {` - "@context": "https://schema.org", - "@type": "BreadcrumbList", - "itemListElement": [{ - "@type": "ListItem", - "position": 1, - "name": "React", - "item": "${siteUrl}" - },{ - "@type": "ListItem", - "position": 2, - "name": "${seo.name}", - "item": "${seo.url.replace('docs//', 'docs/')}" - }] - `} - </script> - )} - </Helmet> - ) -} - -export default SEO - -const query = graphql` - query SEO { - site { - siteMetadata { - defaultTitle: title - titleTemplate - defaultDescription: description - siteUrl: url - defaultImage: image - twitterUsername - } - pathPrefix - } - } -` diff --git a/packages/docs/src/components/Sidebar.tsx b/packages/docs/src/components/Sidebar.tsx deleted file mode 100644 index 55e68aa7..00000000 --- a/packages/docs/src/components/Sidebar.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import React, { FC } from 'react' - -import { - CDropdown, - CDropdownToggle, - CDropdownMenu, - CDropdownItem, - CSidebar, - CSidebarBrand, -} from '@coreui/react/src' -import { SidebarNav } from '.' - -import { AppContext } from './../AppContext' - -import items from './../nav' - -interface SidebarProps { - currentRoute: string -} - -const Sidebar: FC<SidebarProps> = ({ ...props }) => { - return ( - <AppContext.Consumer> - {(context) => ( - <CSidebar - className="docs-sidebar border-end px-xl-4 elevation-0" - position="fixed" - size="lg" - visible={context.sidebarVisible} - onVisibleChange={(value: boolean) => { - context.setSidebarVisible && context.setSidebarVisible(value) - }} - > - <CSidebarBrand className="justify-content-start ps-3"> - <svg - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 615 134" - height={50} - className="d-block mt-4 mb-5" - > - <g fill="#00a1ff"> - <path d="m361.773 90.151-8.768-20.736a.25.25 0 0 0-.255-.191h-9.985a.226.226 0 0 0-.256.255v20.543a.566.566 0 0 1-.64.641h-1.216a.565.565 0 0 1-.64-.64v-43.52a.566.566 0 0 1 .64-.64h12.544a9.979 9.979 0 0 1 7.744 3.23 12.204 12.204 0 0 1 2.944 8.546 12.439 12.439 0 0 1-2.24 7.584 9.37 9.37 0 0 1-6.08 3.744c-.17.086-.213.191-.127.32l8.704 20.608.063.256c0 .341-.191.511-.575.511h-1.153a.703.703 0 0 1-.704-.51Zm-19.264-41.793v18.496a.226.226 0 0 0 .256.257h10.304a7.669 7.669 0 0 0 6.017-2.593 9.878 9.878 0 0 0 2.303-6.815 10.286 10.286 0 0 0-2.272-6.975 7.601 7.601 0 0 0-6.048-2.625h-10.304a.226.226 0 0 0-.256.255ZM401.082 48.102H381.05a.226.226 0 0 0-.256.256v18.496a.226.226 0 0 0 .256.257h13.824a.566.566 0 0 1 .64.64v.96a.566.566 0 0 1-.64.64H381.05a.226.226 0 0 0-.256.256v18.56a.226.226 0 0 0 .256.256h20.032a.567.567 0 0 1 .64.64v.96a.566.566 0 0 1-.64.64h-22.144a.566.566 0 0 1-.64-.64v-43.52a.566.566 0 0 1 .64-.64h22.144a.566.566 0 0 1 .64.64v.96a.566.566 0 0 1-.64.64ZM438.802 90.151l-2.431-8.832a.296.296 0 0 0-.32-.192h-16.768a.295.295 0 0 0-.32.192l-2.368 8.768a.658.658 0 0 1-.704.576h-1.216a.588.588 0 0 1-.48-.191.582.582 0 0 1-.096-.513l12.031-43.584a.644.644 0 0 1 .704-.512h1.6a.644.644 0 0 1 .704.512l12.16 43.584.065.192c0 .342-.214.512-.64.512h-1.217a.643.643 0 0 1-.704-.512ZM419.7 78.92a.303.303 0 0 0 .223.096h15.489a.304.304 0 0 0 .223-.096c.065-.065.074-.117.033-.16l-7.872-28.928c-.043-.085-.086-.128-.128-.128s-.086.043-.128.128l-7.872 28.928c-.043.043-.033.095.032.16ZM456.357 87.911a11.637 11.637 0 0 1-3.328-8.704V57.19a11.414 11.414 0 0 1 3.36-8.575 12.09 12.09 0 0 1 8.8-3.265 12.253 12.253 0 0 1 8.865 3.232 11.39 11.39 0 0 1 3.36 8.608v.64a.566.566 0 0 1-.641.641l-1.28.064q-.64 0-.64-.577v-.832a9.287 9.287 0 0 0-2.656-6.912 10.67 10.67 0 0 0-14.016 0 9.284 9.284 0 0 0-2.656 6.912V79.4a9.282 9.282 0 0 0 2.656 6.912 10.673 10.673 0 0 0 14.016 0 9.286 9.286 0 0 0 2.656-6.912v-.768q0-.576.64-.575l1.28.063a.566.566 0 0 1 .64.64v.511a11.498 11.498 0 0 1-3.36 8.64 13.626 13.626 0 0 1-17.696 0ZM514.193 46.503v.96a.566.566 0 0 1-.64.64H502.8a.226.226 0 0 0-.256.256v41.663a.566.566 0 0 1-.64.641h-1.216a.565.565 0 0 1-.64-.64V48.357a.227.227 0 0 0-.256-.255h-10.176a.565.565 0 0 1-.64-.64v-.96a.566.566 0 0 1 .64-.64h23.936a.566.566 0 0 1 .64.64ZM521.822 89.51a2.835 2.835 0 0 1-.8-2.047 2.923 2.923 0 0 1 .8-2.112 2.758 2.758 0 0 1 2.08-.833 2.847 2.847 0 0 1 2.944 2.945 2.754 2.754 0 0 1-.832 2.08 2.921 2.921 0 0 1-2.112.8 2.754 2.754 0 0 1-2.08-.832ZM542.16 88.007a11.31 11.31 0 0 1-3.2-8.416v-5.44a.566.566 0 0 1 .64-.64h1.217a.567.567 0 0 1 .64.64v5.504a9.144 9.144 0 0 0 2.528 6.72 8.973 8.973 0 0 0 6.687 2.56 8.79 8.79 0 0 0 9.28-9.28V46.504a.566.566 0 0 1 .64-.64h1.217a.566.566 0 0 1 .64.64V79.59a11.252 11.252 0 0 1-3.233 8.416 13.062 13.062 0 0 1-17.055 0ZM580.106 88.103a10.482 10.482 0 0 1-3.36-8.127v-1.793a.566.566 0 0 1 .64-.64h1.088a.566.566 0 0 1 .64.64v1.6a8.544 8.544 0 0 0 2.752 6.655 10.536 10.536 0 0 0 7.36 2.496 9.876 9.876 0 0 0 6.976-2.367 8.215 8.215 0 0 0 2.56-6.336 8.397 8.397 0 0 0-1.12-4.416 11.383 11.383 0 0 0-3.328-3.392 71.626 71.626 0 0 0-6.176-3.712 71.302 71.302 0 0 1-6.24-3.84 12.174 12.174 0 0 1-3.424-3.68 10.257 10.257 0 0 1-1.28-5.345 9.86 9.86 0 0 1 3.072-7.744 12.012 12.012 0 0 1 8.32-2.752q5.695 0 8.96 3.105a10.823 10.823 0 0 1 3.264 8.223v1.601a.566.566 0 0 1-.64.64h-1.152a.565.565 0 0 1-.64-.64v-1.471a8.865 8.865 0 0 0-2.624-6.689 9.994 9.994 0 0 0-7.232-2.528 9.365 9.365 0 0 0-6.528 2.144 7.822 7.822 0 0 0-2.368 6.112 7.8 7.8 0 0 0 1.024 4.16 10.376 10.376 0 0 0 3.008 3.04 62.829 62.829 0 0 0 5.952 3.488 71.058 71.058 0 0 1 6.72 4.256 13.454 13.454 0 0 1 3.648 3.936 10.049 10.049 0 0 1 1.28 5.184 10.714 10.714 0 0 1-3.264 8.191q-3.263 3.073-8.832 3.072-5.697 0-9.057-3.072Z" /> - </g> - <g fill="var(--cui-body-color, currentColor)"> - <path d="m99.59 36.058-39-22.517a12 12 0 0 0-12 0l-39 22.517a12.034 12.034 0 0 0-6 10.392v45.033a12.033 12.033 0 0 0 6 10.393l39 22.516a12 12 0 0 0 12 0l39-22.516a12.033 12.033 0 0 0 6-10.393V46.45a12.034 12.034 0 0 0-6-10.392Zm-2 55.425a4 4 0 0 1-2 3.464l-39 22.517a4 4 0 0 1-4 0l-39-22.517a4 4 0 0 1-2-3.464V46.45a4 4 0 0 1 2-3.464l39-22.517a4 4 0 0 1 4 0l39 22.517a4 4 0 0 1 2 3.464Z" /> - <path d="M77.612 82.005h-2.866a4.001 4.001 0 0 0-1.925.493l-17.28 9.485L35.59 80.465V57.487L55.54 45.97l17.29 9.455a4 4 0 0 0 1.919.49h2.863a2 2 0 0 0 2-2v-2.712a2 2 0 0 0-1.04-1.754L59.383 38.952a8.039 8.039 0 0 0-7.842.09L31.59 50.56a8.024 8.024 0 0 0-4 6.929v22.976a8 8 0 0 0 4 6.928l19.95 11.519a8.043 8.043 0 0 0 7.843.087l19.19-10.53a2 2 0 0 0 1.038-1.754v-2.71a2 2 0 0 0-1.999-2ZM172.335 45.362a15.017 15.017 0 0 0-15 15v17.277a15 15 0 0 0 30 0V60.36a15.017 15.017 0 0 0-15-15Zm7 32.277a7 7 0 0 1-14 0V60.36a7 7 0 0 1 14 0ZM135.67 53.421a7.01 7.01 0 0 1 7.867 6.075.99.99 0 0 0 .984.865h6.03a1.01 1.01 0 0 0 1-1.097 15.018 15.018 0 0 0-15.717-13.883 15.288 15.288 0 0 0-14.244 15.416v16.407a15.288 15.288 0 0 0 14.245 15.416 15.018 15.018 0 0 0 15.716-13.884 1.01 1.01 0 0 0-.999-1.097h-6.03a.99.99 0 0 0-.984.865 7.01 7.01 0 0 1-7.868 6.075 7.164 7.164 0 0 1-6.08-7.184v-16.79a7.164 7.164 0 0 1 6.08-7.184ZM218.512 72.928a12.158 12.158 0 0 0 7.185-11.077v-3.702A12.15 12.15 0 0 0 213.547 46H196.59a1 1 0 0 0-1 1v44a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V74h6.622l7.915 17.414a1 1 0 0 0 .91.586h6.591a1 1 0 0 0 .91-1.414Zm-.815-11.077a4.154 4.154 0 0 1-4.15 4.149h-9.85V54h9.85a4.154 4.154 0 0 1 4.15 4.15ZM260.59 46h-26a1 1 0 0 0-1 1v44a1 1 0 0 0 1 1h26a1 1 0 0 0 1-1v-6a1 1 0 0 0-1-1h-19V72h13a1 1 0 0 0 1-1v-6a1 1 0 0 0-1-1h-13V54h19a1 1 0 0 0 1-1v-6a1 1 0 0 0-1-1ZM298.59 46h-6a1 1 0 0 0-1 1v22.647a7.007 7.007 0 1 1-14 0V47a1 1 0 0 0-1-1h-6a1 1 0 0 0-1 1v22.647a15.003 15.003 0 1 0 30 0V47a1 1 0 0 0-1-1Z" /> - <rect width="8" height="38" x="307.59" y="46" rx="1" /> - </g> - </svg> - </CSidebarBrand> - <div className="text-body-secondary mx-3 mb-2 small fw-semibold">Framework:</div> - <CDropdown className="mx-3 mb-4"> - <CDropdownToggle color="primary" variant="outline"> - React.js - </CDropdownToggle> - <CDropdownMenu className="w-100"> - <CDropdownItem href="https://coreui.io/angular/docs/" target="_blank"> - Angular - </CDropdownItem> - <CDropdownItem href="https://coreui.io/docs/" target="_blank"> - JavaScript / Vanilla JS - </CDropdownItem> - <CDropdownItem href="https://coreui.io/vue/docs/" target="_blank"> - Vue.js - </CDropdownItem> - </CDropdownMenu> - </CDropdown> - <SidebarNav items={items} currentRoute={props.currentRoute} /> - </CSidebar> - )} - </AppContext.Consumer> - ) -} - -Sidebar.displayName = 'Sidebar' - -export default Sidebar diff --git a/packages/docs/src/components/SidebarNav.tsx b/packages/docs/src/components/SidebarNav.tsx deleted file mode 100644 index 040470ca..00000000 --- a/packages/docs/src/components/SidebarNav.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React, { ReactNode } from 'react' -import { Link } from 'gatsby' - -import { CBadge, CNavGroup, CNavItem, CSidebarNav } from '@coreui/react/src/index' -import CIcon from '@coreui/icons-react' - -export type Badge = { - color: string - text: string -} - -export type NavItem = { - name: string | JSX.Element - icon?: string | JSX.Element - badge?: Badge - to: string - items?: NavItem[] -} - -interface SidebarNavProps { - items: NavItem[] - currentRoute: string -} - -export const SidebarNav = ({ items, currentRoute }: SidebarNavProps) => { - const navLink = (name: string | JSX.Element, icon: string | ReactNode, badge?: Badge) => { - return ( - <> - {icon && typeof icon === 'string' ? <CIcon name={icon} customClassName="nav-icon" /> : icon} - {name && name} - {badge && ( - <CBadge color={badge.color} className="ms-auto"> - {badge.text} - </CBadge> - )} - </> - ) - } - - const navItem = (item: NavItem, index: number) => { - const { name, badge, icon, ...rest } = item - return ( - <CNavItem component={Link} activeClassName="active" key={index} {...rest}> - {navLink(name, icon, badge)} - </CNavItem> - ) - } - - const navGroup = (item: NavItem, index: number) => { - const { name, icon, to, ...rest } = item - return ( - <CNavGroup - compact - toggler={navLink(name, icon)} - visible={to.startsWith(currentRoute)} - idx={String(index)} - key={index} - {...rest} - > - {item.items?.map((item: NavItem, index: number) => - item.items ? navGroup(item, index) : navItem(item, index), - )} - </CNavGroup> - ) - } - - return ( - <CSidebarNav> - {items && - items.map((item: NavItem, index: number) => - item.items ? navGroup(item, index) : navItem(item, index), - )} - </CSidebarNav> - ) -} diff --git a/packages/docs/src/components/Toc.tsx b/packages/docs/src/components/Toc.tsx deleted file mode 100644 index 27cedff2..00000000 --- a/packages/docs/src/components/Toc.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React, { FC } from 'react' -import { CNav } from '@coreui/react/src/index' - -type TocItem = { - url: string - title: string - items: TocItem[] -} - -interface TocProps { - items: TocItem[] -} - -const Toc: FC<TocProps> = ({ items }) => { - const toc = (items: TocItem[]) => { - return ( - items && - items.map((item, index) => { - if (Array.isArray(item.items)) { - return ( - <li key={index}> - <a href={item.url}>{item.title}</a> - <ul>{toc(item.items)}</ul> - </li> - ) - } - return ( - <li key={index}> - <a href={item.url}>{item.title}</a> - </li> - ) - }) - ) - } - - return ( - <div className="docs-toc mt-4 mb-5 my-md-0 ps-xl-5 mb-lg-5 text-body-secondary"> - <strong className="d-block h6 mb-2 pb-2 border-bottom">On this page</strong> - <CNav component="nav" className="flex-column"> - <ul>{toc(items)}</ul> - </CNav> - </div> - ) -} - -export default Toc diff --git a/packages/docs/src/components/index.ts b/packages/docs/src/components/index.ts deleted file mode 100644 index fe8398f8..00000000 --- a/packages/docs/src/components/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import Ads from './Ads' -import Banner from './Banner' -import Callout from './Callout' -import CodeBlock from './CodeBlock' -import Example from './Example' -import Footer from './Footer' -import Header from './Header' -import ScssDocs from './ScssDocs' -import Seo from './Seo' -import Sidebar from './Sidebar' -import { SidebarNav } from './SidebarNav' -import Toc from './Toc' - -export { - Ads, - Banner, - Callout, - CodeBlock, - Example, - Footer, - Header, - ScssDocs, - Seo, - Sidebar, - SidebarNav, - Toc, -} diff --git a/packages/docs/src/data/other_frameworks.json b/packages/docs/src/data/other_frameworks.json deleted file mode 100644 index 32046bbd..00000000 --- a/packages/docs/src/data/other_frameworks.json +++ /dev/null @@ -1,241 +0,0 @@ -{ - "accordion": { - "angular": "https://coreui.io/angular/docs/components/accordion", - "bootstrap": "https://coreui.io/docs/components/accordion/", - "react": "https://coreui.io/react/docs/components/accordion/", - "vue": "https://coreui.io/vue/docs/components/accordion.html" - }, - "alert": { - "angular": "https://coreui.io/angular/docs/components/alert", - "bootstrap": "https://coreui.io/docs/components/alerts/", - "react": "https://coreui.io/react/docs/components/alert/", - "vue": "https://coreui.io/vue/docs/components/alert.html" - }, - "avatar": { - "angular": "https://coreui.io/angular/docs/components/avatar", - "bootstrap": "https://coreui.io/docs/components/avatar/", - "react": "https://coreui.io/react/docs/components/avatar/", - "vue": "https://coreui.io/vue/docs/components/avatar.html" - }, - "badge": { - "angular": "https://coreui.io/angular/docs/components/badge", - "bootstrap": "https://coreui.io/docs/components/badge/", - "react": "https://coreui.io/react/docs/components/badge/", - "vue": "https://coreui.io/vue/docs/components/badge.html" - }, - "breadcrumb": { - "angular": "https://coreui.io/angular/docs/components/breadcrumb", - "bootstrap": "https://coreui.io/docs/components/breadcrumb/", - "react": "https://coreui.io/react/docs/components/breadcrumb/", - "vue": "https://coreui.io/vue/docs/components/breadcrumb.html" - }, - "button": { - "angular": "https://coreui.io/angular/docs/components/button", - "bootstrap": "https://coreui.io/docs/components/buttons/", - "react": "https://coreui.io/react/docs/components/button/", - "vue": "https://coreui.io/vue/docs/components/button.html" - }, - "button-group": { - "angular": "https://coreui.io/angular/docs/components/button-group", - "bootstrap": "https://coreui.io/docs/components/button-group/", - "react": "https://coreui.io/react/docs/components/button-group/", - "vue": "https://coreui.io/vue/docs/components/button-group.html" - }, - "callout": { - "angular": "https://coreui.io/angular/docs/components/callout", - "bootstrap": "https://coreui.io/docs/components/callout/", - "react": "https://coreui.io/react/docs/components/callout/", - "vue": "https://coreui.io/vue/docs/components/callout.html" - }, - "card": { - "angular": "https://coreui.io/angular/docs/components/card", - "bootstrap": "https://coreui.io/docs/components/card/", - "react": "https://coreui.io/react/docs/components/card/", - "vue": "https://coreui.io/vue/docs/components/card.html" - }, - "carousel": { - "angular": "https://coreui.io/angular/docs/components/carousel", - "bootstrap": "https://coreui.io/docs/components/carousel/", - "react": "https://coreui.io/react/docs/components/carousel/", - "vue": "https://coreui.io/vue/docs/components/carousel.html" - }, - "checkbox": { - "angular": "https://coreui.io/angular/docs/forms/checks-radios", - "bootstrap": "https://coreui.io/docs/forms/checks-radios/", - "react": "https://coreui.io/react/docs/forms/checkbox/", - "vue": "https://coreui.io/vue/docs/forms/checkbox.html" - }, - "close-button": { - "angular": "https://coreui.io/angular/docs/components/close-button", - "bootstrap": "https://coreui.io/docs/components/close-button/", - "react": "https://coreui.io/react/docs/components/close-button/", - "vue": "https://coreui.io/vue/docs/components/close-button.html" - }, - "collapse": { - "angular": "https://coreui.io/angular/docs/components/collapse", - "bootstrap": "https://coreui.io/docs/components/collapse/", - "react": "https://coreui.io/react/docs/components/collapse/", - "vue": "https://coreui.io/vue/docs/components/collapse.html" - }, - "dropdown": { - "angular": "https://coreui.io/angular/docs/components/dropdown", - "bootstrap": "https://coreui.io/docs/components/dropdowns/", - "react": "https://coreui.io/react/docs/components/dropdown/", - "vue": "https://coreui.io/vue/docs/components/dropdown.html" - }, - "footer": { - "angular": "https://coreui.io/angular/docs/components/footer", - "bootstrap": "https://coreui.io/docs/components/footer/", - "react": "https://coreui.io/react/docs/components/footer/", - "vue": "https://coreui.io/vue/docs/components/footer.html" - }, - "header": { - "angular": "https://coreui.io/angular/docs/components/header", - "bootstrap": "https://coreui.io/docs/components/header/", - "react": "https://coreui.io/react/docs/components/header/", - "vue": "https://coreui.io/vue/docs/components/header.html" - }, - "icon": { - "angular": "https://coreui.io/angular/docs/components/icon", - "bootstrap": "https://coreui.io/docs/components/icon/", - "react": "https://coreui.io/react/docs/components/icon/", - "vue": "https://coreui.io/vue/docs/components/icon.html" - }, - "image": { - "angular": "https://coreui.io/angular/docs/components/image", - "bootstrap": "https://coreui.io/docs/content/images/", - "react": "https://coreui.io/react/docs/components/image/", - "vue": "https://coreui.io/vue/docs/components/image.html" - }, - "input": { - "angular": "https://coreui.io/angular/docs/forms/input", - "bootstrap": "https://coreui.io/docs/forms/form-control/", - "react": "https://coreui.io/react/docs/forms/input/", - "vue": "https://coreui.io/vue/docs/forms/input.html" - }, - "input-group": { - "angular": "https://coreui.io/angular/docs/forms/input-group", - "bootstrap": "https://coreui.io/docs/forms/input-group/", - "react": "https://coreui.io/react/docs/forms/input-group/", - "vue": "https://coreui.io/vue/docs/forms/input-group.html" - }, - "floating-labels": { - "angular": "https://coreui.io/angular/docs/forms/floating-labels", - "bootstrap": "https://coreui.io/docs/forms/floating-labels/", - "react": "https://coreui.io/react/docs/forms/floating-labels/", - "vue": "https://coreui.io/vue/docs/forms/floating-labels.html" - }, - "list-group": { - "angular": "https://coreui.io/angular/docs/components/list-group", - "bootstrap": "https://coreui.io/docs/components/list-group/", - "react": "https://coreui.io/react/docs/components/list-group/", - "vue": "https://coreui.io/vue/docs/components/list-group.html" - }, - "modal": { - "angular": "https://coreui.io/angular/docs/components/modal", - "bootstrap": "https://coreui.io/docs/components/modal/", - "react": "https://coreui.io/react/docs/components/modal/", - "vue": "https://coreui.io/vue/docs/components/modal.html" - }, - "navbar": { - "bootstrap": "https://coreui.io/docs/components/navbar/", - "react": "https://coreui.io/react/docs/components/navbar/", - "vue": "https://coreui.io/vue/docs/components/navbar.html" - }, - "navs-tabs": { - "angular": "https://coreui.io/angular/docs/components/nav", - "bootstrap": "https://coreui.io/docs/components/navs-tabs/", - "react": "https://coreui.io/react/docs/components/navs-tabs/", - "vue": "https://coreui.io/vue/docs/components/navs-tabs.html" - }, - "offcanvas": { - "angular": "https://coreui.io/angular/docs/components/offcanvas", - "bootstrap": "https://coreui.io/docs/components/offcanvas/", - "react": "https://coreui.io/react/docs/components/offcanvas/", - "vue": "https://coreui.io/vue/docs/components/offcanvas.html" - }, - "pagination": { - "angular": "https://coreui.io/angular/docs/components/pagination", - "bootstrap": "https://coreui.io/docs/components/pagination/", - "react": "https://coreui.io/react/docs/components/pagination/", - "vue": "https://coreui.io/vue/docs/components/pagination.html" - }, - "placeholder": { - "angular": "https://coreui.io/angular/docs/components/placeholder", - "bootstrap": "https://coreui.io/docs/components/placeholders/", - "react": "https://coreui.io/react/docs/components/placeholder/", - "vue": "https://coreui.io/vue/docs/components/placeholder.html" - }, - "popover": { - "angular": "https://coreui.io/angular/docs/components/popover", - "bootstrap": "https://coreui.io/docs/components/popovers/", - "react": "https://coreui.io/react/docs/components/popover/", - "vue": "https://coreui.io/vue/docs/components/popover.html" - }, - "progress": { - "angular": "https://coreui.io/angular/docs/components/progress", - "bootstrap": "https://coreui.io/docs/components/progress/", - "react": "https://coreui.io/react/docs/components/progress/", - "vue": "https://coreui.io/vue/docs/components/progress.html" - }, - "radio": { - "angular": "https://coreui.io/angular/docs/forms/checks-radios", - "bootstrap": "https://coreui.io/docs/forms/checks-radios/", - "react": "https://coreui.io/react/docs/forms/radio/", - "vue": "https://coreui.io/vue/docs/forms/radio.html" - }, - "range": { - "angular": "https://coreui.io/angular/docs/forms/range", - "bootstrap": "https://coreui.io/docs/forms/range/", - "react": "https://coreui.io/react/docs/forms/range/", - "vue": "https://coreui.io/vue/docs/forms/range.html" - }, - "select": { - "angular": "https://coreui.io/angular/docs/forms/select", - "bootstrap": "https://coreui.io/docs/forms/select/", - "react": "https://coreui.io/react/docs/forms/select/", - "vue": "https://coreui.io/vue/docs/forms/select.html" - }, - "sidebar": { - "angular": "https://coreui.io/angular/docs/components/sidebar", - "bootstrap": "https://coreui.io/docs/components/sidebar/", - "react": "https://coreui.io/react/docs/components/sidebar/", - "vue": "https://coreui.io/vue/docs/components/sidebar.html" - }, - "spinner": { - "angular": "https://coreui.io/angular/docs/components/spinner", - "bootstrap": "https://coreui.io/docs/components/spinners/", - "react": "https://coreui.io/react/docs/components/spinner/", - "vue": "https://coreui.io/vue/docs/components/spinner.html" - }, - "switch": { - "angular": "https://coreui.io/angular/docs/forms/checks-radios", - "bootstrap": "https://coreui.io/docs/forms/checks-radios/", - "react": "https://coreui.io/react/docs/forms/switch/", - "vue": "https://coreui.io/vue/docs/forms/switch.html" - }, - "table": { - "angular": "https://coreui.io/angular/docs/components/table", - "bootstrap": "https://coreui.io/docs/content/tables/", - "react": "https://coreui.io/react/docs/components/table/", - "vue": "https://coreui.io/vue/docs/components/table.html" - }, - "textarea": { - "angular": "https://coreui.io/angular/docs/forms/form-control", - "bootstrap": "https://coreui.io/docs/forms/form-control/", - "react": "https://coreui.io/react/docs/forms/textarea/", - "vue": "https://coreui.io/vue/docs/forms/textarea.html" - }, - "toast": { - "angular": "https://coreui.io/angular/docs/components/toast", - "bootstrap": "https://coreui.io/docs/components/toasts/", - "react": "https://coreui.io/react/docs/components/toast/", - "vue": "https://coreui.io/vue/docs/components/toast.html" - }, - "tooltip": { - "angular": "https://coreui.io/angular/docs/components/tooltip", - "bootstrap": "https://coreui.io/docs/components/tooltips/", - "react": "https://coreui.io/react/docs/components/tooltip/", - "vue": "https://coreui.io/vue/docs/components/tooltip.html" - } -} diff --git a/packages/docs/src/images/gatsby-astronaut.png b/packages/docs/src/images/gatsby-astronaut.png deleted file mode 100644 index da58ece0a8c5b4f0e4d25fa443e65278349b4f3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167273 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 NNQ%mdR0!#R{eKbVnbrUR diff --git a/packages/docs/src/images/gatsby-icon.png b/packages/docs/src/images/gatsby-icon.png deleted file mode 100644 index 908bc78a7f5596fab5a638d6ac07e331dc4c74d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21212 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 Pwx}U%bK8?;ra1Edyv(7f diff --git a/packages/docs/src/index.ts b/packages/docs/src/index.ts deleted file mode 100644 index cb64ac1b..00000000 --- a/packages/docs/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './components' diff --git a/packages/docs/src/nav.tsx b/packages/docs/src/nav.tsx deleted file mode 100644 index 2b3a062e..00000000 --- a/packages/docs/src/nav.tsx +++ /dev/null @@ -1,378 +0,0 @@ -import React from 'react' -import CIcon from '@coreui/icons-react' - -const nav = [ - { - name: 'Getting Started', - to: '/getting-started/', - icon: ( - <CIcon - customClassName="nav-icon text-primary" - icon={[ - '512 512', - '<rect width="32" height="32" x="144" y="464" fill="var(--ci-primary-color, currentColor)" class="ci-primary"></rect><rect width="32" height="32" x="240" y="464" fill="var(--ci-primary-color, currentColor)" class="ci-primary"></rect><rect width="32" height="32" x="336" y="464" fill="var(--ci-primary-color, currentColor)" class="ci-primary"></rect><path fill="var(--ci-primary-color, currentColor)" d="M312,76.82v34.265a142.419,142.419,0,0,1,86.207,130.708C398.207,320.206,334.413,384,256,384S113.793,320.206,113.793,241.793A142.419,142.419,0,0,1,200,111.085V76.82c-68.671,23.373-118.207,88.5-118.207,164.973C81.793,337.851,159.942,416,256,416s174.207-78.149,174.207-174.207C430.207,165.316,380.671,100.193,312,76.82Z" class="ci-primary"></path><rect width="32" height="229.793" x="240" y="16" fill="var(--ci-primary-color, currentColor)" class="ci-primary"></rect>', - ]} - width={64} - height={64} - /> - ), - items: [ - { - name: 'Introduction', - to: '/getting-started/introduction/', - }, - { - name: 'Accessibility', - to: '/getting-started/accessibility/', - }, - ], - }, - { - name: 'Customize', - to: '/customize/', - icon: ( - <CIcon - customClassName="nav-icon text-primary" - icon={[ - '512 512', - '<path fill="var(--ci-primary-color, currentColor)" d="M425.514,82.055C380.778,39.458,320.673,16,256.271,16,196.248,16,136.415,36.073,92.115,71.071,43.032,109.85,16,164.161,16,224c0,60.1,15.531,98.87,48.876,122.019,28,19.438,68.412,27.731,135.124,27.731h29.75A26.28,26.28,0,0,1,256,400v47.984a32,32,0,0,0,32,32h.032l90.755-.088a32.094,32.094,0,0,0,19.686-6.8c9.725-7.622,34.727-29.4,56.8-66.9C482.3,360.262,496,307.037,496,248,496,184.268,470.968,125.334,425.514,82.055Zm2.173,307.915c-19.3,32.792-40.663,51.447-48.932,57.926L288,447.984V400a58.316,58.316,0,0,0-58.25-58.25H200c-59.69,0-94.644-6.585-116.876-22.019C58.833,302.869,48,273.344,48,224,48,113.833,153.9,48,256.271,48,372.755,48,464,135.851,464,248,464,301.253,451.782,349.019,427.687,389.97Z" class="ci-primary"/><path fill="var(--ci-primary-color, currentColor)" d="M128,144a56,56,0,1,0,56,56A56.064,56.064,0,0,0,128,144Zm0,80a24,24,0,1,1,24-24A24.027,24.027,0,0,1,128,224Z" class="ci-primary"/><path fill="var(--ci-primary-color, currentColor)" d="M240,72a56,56,0,1,0,56,56A56.064,56.064,0,0,0,240,72Zm0,80a24,24,0,1,1,24-24A24.027,24.027,0,0,1,240,152Z" class="ci-primary"/><path fill="var(--ci-primary-color, currentColor)" d="M360,128a56,56,0,1,0,56,56A56.064,56.064,0,0,0,360,128Zm0,80a24,24,0,1,1,24-24A24.027,24.027,0,0,1,360,208Z" class="ci-primary"/><path fill="var(--ci-primary-color, currentColor)" d="M376,264a56,56,0,1,0,56,56A56.064,56.064,0,0,0,376,264Zm0,80a24,24,0,1,1,24-24A24.027,24.027,0,0,1,376,344Z" class="ci-primary"/>', - ]} - width={64} - height={64} - /> - ), - items: [ - { - name: 'Sass', - to: '/customize/sass/', - }, - { - name: 'Options', - to: '/customize/options/', - }, - { - name: 'CSS Variables', - to: '/customize/css-variables/', - }, - ], - }, - { - name: 'Layout', - to: '/layout/', - icon: ( - <CIcon - customClassName="nav-icon text-primary" - icon={[ - '512 512', - '<path fill="var(--ci-primary-color, currentColor)" d="M16,64V448H496V64ZM464,240H192V96H464ZM192,272H312V416H192ZM48,96H160V416H48ZM344,416V272H464V416Z" class="ci-primary"></path>', - ]} - width={64} - height={64} - /> - ), - items: [ - { - name: 'Breakpoints', - to: '/layout/breakpoints/', - }, - { - name: 'Containers', - to: '/layout/containers/', - }, - { - name: 'Grid', - to: '/layout/grid/', - }, - { - name: 'Columns', - to: '/layout/columns/', - }, - { - name: 'Gutters', - to: '/layout/gutters/', - }, - ], - }, - { - name: 'Forms', - to: '/forms/', - icon: ( - <CIcon - customClassName="nav-icon text-primary" - icon={[ - '512 512', - '<rect width="288" height="32" x="112" y="152" fill="var(--ci-primary-color, currentColor)" class="ci-primary"></rect><rect width="288" height="32" x="112" y="240" fill="var(--ci-primary-color, currentColor)" class="ci-primary"></rect><rect width="152" height="32" x="112" y="328" fill="var(--ci-primary-color, currentColor)" class="ci-primary"></rect><path fill="var(--ci-primary-color, currentColor)" d="M480,48H32V464H480ZM448,432H64V80H448Z" class="ci-primary"></path>', - ]} - width={64} - height={64} - /> - ), - items: [ - { - name: 'Checkbox', - to: '/forms/checkbox/', - }, - { - name: 'Input', - to: '/forms/input/', - }, - { - name: 'Input Mask', - to: '/forms/input-mask/', - }, - { - name: 'Input Group', - to: '/forms/input-group/', - }, - { - name: 'Radio', - to: '/forms/radio/', - }, - { - name: 'Range', - to: '/forms/range/', - }, - { - name: 'Select', - to: '/forms/select/', - }, - { - name: 'Switch', - to: '/forms/switch/', - }, - { - name: 'Textarea', - to: '/forms/textarea/', - }, - { - name: 'Floating Labels', - to: '/forms/floating-labels/', - }, - { - name: 'Layout', - to: '/forms/layout/', - }, - { - name: 'Validation', - to: '/forms/validation/', - }, - ], - }, - { - name: 'Components', - to: '/components/', - icon: ( - <CIcon - customClassName="nav-icon text-primary" - icon={[ - '512 512', - '<path fill="var(--ci-primary-color, currentColor)" d="M410.989,16H101.011L16,237.029V496H496V237.029Zm-288,32H240V240H49.143ZM184,272H328v40H184ZM464,464H48V272H152v72H360V272H464ZM272,240V48H389.012l73.845,192Z" class="ci-primary"></path>', - ]} - width={64} - height={64} - /> - ), - items: [ - { - name: 'Accordion', - to: '/components/accordion/', - }, - { - name: 'Alert', - to: '/components/alert/', - }, - { - name: 'Avatar', - to: '/components/avatar/', - }, - { - name: 'Badge', - to: '/components/badge/', - }, - { - name: 'Breadcrumb', - to: '/components/breadcrumb/', - }, - { - name: 'Button', - to: '/components/button/', - }, - { - name: 'Button Group', - to: '/components/button-group/', - }, - { - name: 'Callout', - to: '/components/callout/', - }, - { - name: 'Card', - to: '/components/card/', - }, - { - name: 'Carousel', - to: '/components/carousel/', - }, - { - name: 'Chart', - to: '/components/chart/', - }, - { - name: 'Close Button', - to: '/components/close-button/', - }, - { - name: 'Collapse', - to: '/components/collapse/', - }, - { - name: 'Dropdown', - to: '/components/dropdown/', - }, - { - name: 'Footer', - to: '/components/footer/', - }, - { - name: 'Header', - to: '/components/header/', - }, - { - name: 'Icon', - to: '/components/icon/', - }, - { - name: 'Image', - to: '/components/image/', - }, - { - name: 'List Group', - to: '/components/list-group/', - }, - { - name: 'Modal', - to: '/components/modal/', - }, - { - name: 'Navbar', - to: '/components/navbar/', - }, - { - name: 'Navs & Tabs', - to: '/components/navs-tabs/', - }, - { - name: 'Offcanvas', - to: '/components/offcanvas/', - }, - { - name: 'Pagination', - to: '/components/pagination/', - }, - { - name: 'Placeholder', - to: '/components/placeholder/', - }, - { - name: 'Popover', - to: '/components/popover/', - }, - { - name: 'Progress', - to: '/components/progress/', - }, - { - name: 'Sidebar', - to: '/components/sidebar/', - }, - { - name: 'Spinner', - to: '/components/spinner/', - }, - { - name: 'Table', - to: '/components/table/', - }, - { - name: 'Toast', - to: '/components/toast/', - }, - { - name: 'Tooltip', - to: '/components/tooltip/', - }, - { - name: 'Widgets', - to: '/components/widgets/', - }, - ], - }, - { - name: 'Templates', - to: '/templates/', - icon: ( - <CIcon - customClassName="nav-icon text-primary" - icon={[ - '512 512', - '<path fill="var(--ci-primary-color, currentColor)" d="M472,232H424V120a24.028,24.028,0,0,0-24-24H40a24.028,24.028,0,0,0-24,24V366a24.028,24.028,0,0,0,24,24H212v50H152v32H304V440H244V390h92v58a24.027,24.027,0,0,0,24,24H472a24.027,24.027,0,0,0,24-24V256A24.027,24.027,0,0,0,472,232ZM336,256V358H48V128H392V232H360A24.027,24.027,0,0,0,336,256ZM464,440H368V264h96Z" class="ci-primary"/>', - ]} - width={64} - height={64} - /> - ), - items: [ - { - name: 'Admin & Dashboard', - to: '/templates/admin-dashboard/', - badge: { - color: 'success', - text: 'New', - }, - }, - { - name: 'Download', - to: '/templates/download/', - }, - { - name: 'Installation', - to: '/templates/installation/', - }, - { - name: 'Customize', - to: '/templates/customize/', - }, - { - name: 'Contents', - to: '/templates/contents/', - }, - ], - }, - { - name: 'Migration', - to: '/migration/', - icon: ( - <CIcon - customClassName="nav-icon text-primary" - icon={[ - '512 512', - '<path fill="var(--ci-primary-color, currentColor)" d="M464,256.25C464,370.8,370.8,464,256.25,464S48.5,370.8,48.5,256.25,141.7,48.5,256.25,48.5a208,208,0,0,1,149.963,64H328.5v32h128V16.5h-32V85.478A239.717,239.717,0,1,0,496,256.25Z" class="ci-primary"></path><polygon fill="var(--ci-primary-color, currentColor)" points="272.5 112.451 240.5 112.549 241.017 282.756 353.301 334.53 366.699 305.47 272.954 262.244 272.5 112.451" class="ci-primary"></polygon>', - ]} - width={64} - height={64} - /> - ), - items: [ - { - name: 'v4', - to: '/migration/v4/', - }, - { - name: 'v5', - to: '/migration/v5/', - }, - ], - }, -] - -export default nav diff --git a/packages/docs/src/pages/404.tsx b/packages/docs/src/pages/404.tsx deleted file mode 100644 index 8a78d388..00000000 --- a/packages/docs/src/pages/404.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from 'react' -import { graphql, useStaticQuery } from 'gatsby' -import { CButton } from '@coreui/react/src/index' - -import Seo from './../components/Seo' - -const NotFoundPage = () => { - const { site } = useStaticQuery(query) - const { siteUrl } = site.siteMetadata - return ( - <> - <Seo title="404: Not found" /> - <h1>404: Not Found</h1> - <p>You just hit a route that doesn't exist... the sadness.</p> - <CButton color="primary" href={siteUrl}>Go to documentation</CButton> - </> - ) -} - -export default NotFoundPage - -const query = graphql` - query URL { - site { - siteMetadata { - siteUrl: url - } - } - } -` diff --git a/packages/docs/src/styles/_ads.scss b/packages/docs/src/styles/_ads.scss deleted file mode 100644 index 575db8b0..00000000 --- a/packages/docs/src/styles/_ads.scss +++ /dev/null @@ -1,38 +0,0 @@ -// stylelint-disable declaration-no-important, selector-max-id - -// -// Carbon ads -// - -#carbonads { - position: static; - display: block; - max-width: 400px; - padding: 15px 15px 15px 160px; - margin: 2rem 0; - overflow: hidden; - @include font-size(.8125rem); - line-height: 1.4; - text-align: left; - background-color: var(--cui-tertiary-bg); - - a { - color: var(--cui-body-color); - text-decoration: none; - } - - @include media-breakpoint-up(sm) { - @include border-radius(.5rem); - } -} - -.carbon-img { - float: left; - margin-left: -145px; -} - -.carbon-poweredby { - display: block; - margin-top: .75rem; - color: var(--cui-body-color) !important; -} diff --git a/packages/docs/src/styles/_anchor.scss b/packages/docs/src/styles/_anchor.scss deleted file mode 100644 index 1f8831fb..00000000 --- a/packages/docs/src/styles/_anchor.scss +++ /dev/null @@ -1,23 +0,0 @@ - -.anchor-link { - font-weight: 400; - color: rgba($link-color, .5); - padding-left: 0.375em; - text-decoration: none; - opacity: 0; - @include transition(color .15s ease-in-out); - - &:focus, - &:hover { - color: $link-color; - text-decoration: none; - } -} - -h2, h3, h4, h5, h6 { - &:hover { - .anchor-link { - opacity: 1; - } - } -} \ No newline at end of file diff --git a/packages/docs/src/styles/_callouts.scss b/packages/docs/src/styles/_callouts.scss deleted file mode 100644 index a0dc566c..00000000 --- a/packages/docs/src/styles/_callouts.scss +++ /dev/null @@ -1,39 +0,0 @@ -// -// Callouts -// - -.docs-callout { - --#{$prefix}link-color-rgb: var(--cd-callout-link); - --#{$prefix}code-color: var(--cd-callout-code-color); - - padding: 1.25rem; - margin-top: 1.25rem; - margin-bottom: 1.25rem; - background-color: var(--cd-callout-bg, var(--cui-gray-100)); - border-left: .25rem solid var(--cd-callout-border, var(--cui-gray-300)); - - h4 { - margin-bottom: .25rem; - } - - > :last-child { - margin-bottom: 0; - } - - + .docs-callout { - margin-top: -.25rem; - } - - .highlight { - background-color: rgba($black, .05); - } -} - -// Variations -@each $variant in $cd-callout-variants { - .docs-callout-#{$variant} { - --cd-callout-color: var(--cui-#{$variant}-text-emphasis); - --cd-callout-bg: rgba(var(--cui-#{$variant}-rgb), .1); - --cd-callout-border: var(--cui-#{$variant}); - } -} diff --git a/packages/docs/src/styles/_component-examples.scss b/packages/docs/src/styles/_component-examples.scss deleted file mode 100644 index dccc0281..00000000 --- a/packages/docs/src/styles/_component-examples.scss +++ /dev/null @@ -1,436 +0,0 @@ -// -// Docs examples -// - -.docs-example-snippet { - border: solid var(--cui-border-color); - border-width: 1px 0; - - @include media-breakpoint-up(md) { - border-width: 1px; - } -} - -.docs-example { - --cd-example-padding: 1rem; - - position: relative; - padding: var(--cd-example-padding); - margin: 0 ($cd-gutter-x * -.5); - border: solid var(--cui-border-color); - border-width: 1px 0; - @include clearfix(); - - @include media-breakpoint-up(md) { - --cd-example-padding: 1.5rem; - - margin-right: 0; - margin-left: 0; - border-width: 1px; - @include border-top-radius(var(--cui-border-radius)); - } - - + .docs-code-snippet { - @include border-top-radius(0); - border: solid var(--cui-border-color); - border-width: 0 1px 1px; - } - - + p { - margin-top: 2rem; - } - - > .form-control { - + .form-control { - margin-top: .5rem; - } - } - - > .nav + .nav, - > .alert + .alert, - > .navbar + .navbar, - > .progress + .progress { - margin-top: $spacer; - } - - > .dropdown-menu { - position: static; - display: block; - } - - > :last-child, - > nav:last-child .breadcrumb { - margin-bottom: 0; - } - - > hr:last-child { - margin-bottom: $spacer; - } - - // Images - > svg + svg, - > img + img { - margin-left: .5rem; - } - - // Buttons - > .btn, - > .btn-group { - margin: .25rem .125rem; - } - > .btn-toolbar + .btn-toolbar { - margin-top: .5rem; - } - - // List groups - > .list-group { - max-width: 400px; - } - - > [class*="list-group-horizontal"] { - max-width: 100%; - } - - // Navbars - .fixed-top, - .sticky-top { - position: static; - margin: calc(var(--cd-example-padding) * -1) calc(var(--cd-example-padding) * -1) var(--cd-example-padding); // stylelint-disable-line function-disallowed-list - } - - .fixed-bottom, - .sticky-bottom { - position: static; - margin: var(--cd-example-padding) calc(var(--cd-example-padding) * -1) calc(var(--cd-example-padding) * -1); // stylelint-disable-line function-disallowed-list - - } - - // Pagination - .pagination { - margin-bottom: 0; - } - - // Spinners - > .spinner-grow + .spinner-border, - > .spinner-border + .spinner-grow, - > .spinner-border + .spinner-border, - > .spinner-grow + .spinner-grow { - margin-left: .25rem; - } - - // Sidebar - .sidebar-narrow, - .sidebar-narrow-unfoldable { - position: static; - } - - .sidebar-narrow-unfoldable { - min-height: 550px; - } -} - -// -// Grid examples -// - -.docs-example-row [class^="col"], -.docs-example-cols [class^="col"] > *, -.docs-example-cssgrid [class*="grid"] > * { - padding-top: .75rem; - padding-bottom: .75rem; - background-color: rgba(var(--cd-violet-rgb), .15); - border: 1px solid rgba(var(--cd-violet-rgb), .3); -} - -.docs-example-row .row + .row, -.docs-example-cssgrid .grid + .grid { - margin-top: 1rem; -} - -.docs-example-row-flex-cols .row { - min-height: 10rem; - background-color: rgba(var(--cd-violet-rgb), .15); -} - -.docs-example-flex div:not(.vr) { - background-color: rgba(var(--cd-violet-rgb), .15); - border: 1px solid rgba(var(--cd-violet-rgb), .3); -} - -// Grid mixins -.example-container { - width: 800px; - @include make-container(); -} - -.example-row { - @include make-row(); -} - -.example-content-main { - @include make-col-ready(); - - @include media-breakpoint-up(sm) { - @include make-col(6); - } - - @include media-breakpoint-up(lg) { - @include make-col(8); - } -} - -.example-content-secondary { - @include make-col-ready(); - - @include media-breakpoint-up(sm) { - @include make-col(6); - } - - @include media-breakpoint-up(lg) { - @include make-col(4); - } -} - -// Ratio helpers -.docs-example-ratios { - .ratio { - display: inline-block; - width: 10rem; - color: var(--cui-secondary-color); - background-color: var(--cui-tertiary-bg); - border: var(--cui-border-width) solid var(--cui-border-color); - - > div { - display: flex; - align-items: center; - justify-content: center; - } - } -} -.docs-example-ratios-breakpoint { - .ratio-4x3 { - width: 16rem; - - @include media-breakpoint-up(md) { - --cui-aspect-ratio: 50%; // 2x1 - } - } -} - -.docs-example-offcanvas { - .offcanvas { - position: static; - display: block; - height: 200px; - visibility: visible; - transform: translate(0); - } -} - -// Tooltips -.tooltip-demo { - a { - white-space: nowrap; - } - - .btn { - margin: .25rem .125rem; - } -} - -// scss-docs-start custom-tooltip -.custom-tooltip { - --cui-tooltip-bg: var(--cui-primary); -} -// scss-docs-end custom-tooltip - -// scss-docs-start custom-popovers -.custom-popover { - --cui-popover-max-width: 200px; - --cui-popover-border-color: var(--cui-primary); - --cui-popover-header-bg: var(--cui-primary); - --cui-popover-header-color: var(--cui-white); - --cui-popover-body-padding-x: 1rem; - --cui-popover-body-padding-y: .5rem; -} -// scss-docs-end custom-popovers - -// Scrollspy demo on fixed height div -.scrollspy-example { - height: 200px; - margin-top: .5rem; - overflow: auto; -} - -.scrollspy-example-2 { - height: 350px; - overflow: auto; -} - -.simple-list-example-scrollspy { - .active { - background-color: rgba(var(--cd-violet-rgb), .15); - } -} - -.docs-example-border-utils { - [class^="border"] { - display: inline-block; - width: 5rem; - height: 5rem; - margin: .25rem; - background-color: var(--cui-tertiary-bg); - } -} - -.docs-example-rounded-utils { - [class*="rounded"] { - margin: .25rem; - } -} - -.docs-example-position-utils { - position: relative; - padding: 2rem; - - .position-relative { - height: 200px; - background-color: var(--cui-tertiary-bg); - } - - .position-absolute { - width: 2rem; - height: 2rem; - background-color: var(--cui-body-color); - @include border-radius(); - } -} - -.docs-example-position-examples { - &::after { - content: none; - } -} - -// Placeholders -.docs-example-placeholder-cards { - &::after { - display: none; - } - - .card { - width: 18rem; - } -} - -// Toasts -.docs-example-toasts { - min-height: 240px; -} - -.docs-example-zindex-levels { - min-height: 15rem; - - > div { - color: var(--cui-body-bg); - background-color: var(--cd-violet); - border: 1px solid var(--cd-purple); - - > span { - position: absolute; - right: 5px; - bottom: 0; - } - } - - > :nth-child(2) { - top: 3rem; - left: 3rem; - } - > :nth-child(3) { - top: 4.5rem; - left: 4.5rem; - } - > :nth-child(4) { - top: 6rem; - left: 6rem; - } - > :nth-child(5) { - top: 7.5rem; - left: 7.5rem; - } -} - -// -// Code snippets -// - -.highlight { - position: relative; - padding: .75rem ($cd-gutter-x * .5); - margin-bottom: 1rem; - border: 1px solid var(--cui-border-color); - background-color: var(--cd-pre-bg); - - @include media-breakpoint-up(md) { - padding: .75rem 1.25rem; - @include border-radius(var(--cui-border-radius)); - } - - pre { - padding: .25rem 0 .875rem; - margin-top: .8125rem; - margin-right: 1.875rem; - margin-bottom: 0; - overflow: overlay; - white-space: pre; - background-color: transparent; - border: 0; - } - - pre code { - @include font-size(inherit); - color: var(--cui-body-color); // Effectively the base text color - word-wrap: normal; - } -} - -.docs-code-snippet { - margin: 0 ($cd-gutter-x * -.5) $spacer; - - .highlight { - margin-bottom: 0; - } - - .docs-example ~ .highlight { - border: solid var(--cui-border-color); - border-width: 1px 0 0; - @include border-top-radius(0); - } - - .docs-example { - margin: 0; - border: 0; - } - - @include media-breakpoint-up(md) { - margin-right: 0; - margin-left: 0; - @include border-radius($border-radius); - } -} - -.highlight-toolbar { - background-color: var(--cd-pre-bg); -} - -.docs-scss-docs { - .highlight-toolbar { - @include border-top-radius(calc(var(--cui-border-radius) + 1px)); - } -} - -.docs-example + .highlight { - border-top-width: 0; - @include border-top-radius(0); -} diff --git a/packages/docs/src/styles/_footer.scss b/packages/docs/src/styles/_footer.scss deleted file mode 100644 index 7544a17b..00000000 --- a/packages/docs/src/styles/_footer.scss +++ /dev/null @@ -1,19 +0,0 @@ -// -// Footer -// - -.footer { - --cui-footer-bg: var(--cui-tertiary-bg); - @include font-size(.875rem); - - a { - color: var(--#{$prefix}tertiary-color); - text-decoration: none; - - &:hover, - &:focus { - color: var(--cui-link-hover-color); - text-decoration: underline; - } - } -} diff --git a/packages/docs/src/styles/_prism.scss b/packages/docs/src/styles/_prism.scss deleted file mode 100644 index 6145e4b6..00000000 --- a/packages/docs/src/styles/_prism.scss +++ /dev/null @@ -1,172 +0,0 @@ -/* PrismJS 1.24.1 -https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript */ -/** - * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML - * Based on https://github.com/chriskempson/tomorrow-theme - * @author Rose Pritchard - */ - -:root, -[data-coreui-theme="light"] { - // --base00: #fff; - // --base01: #f5f5f5; - --base02: #c8c8fa; - --base03: #565c64; - --base04: #666; - --base05: #333; - --base06: #fff; - --base07: #{$teal-700}; // #9a6700 - --base08: #{mix($red-500, $red-600, 50%)}; // #bc4c00 - --base09: #{$cyan-700}; // #087990 - --base0A: #{$purple-500}; // #795da3 - --base0B: #{$blue-700}; // #183691 - --base0C: #{$blue-700}; // #183691 - --base0D: #{$purple-500}; // #795da3 - --base0E: #{$pink-600}; // #a71d5d - --base0F: #333; - } - -@include color-mode(dark, true) { - // --base00: #282c34; - // --base01: #353b45; - --base02: #3e4451; - --base03: #868e96; - --base04: #868e96; - --base05: #abb2bf; - --base06: #b6bdca; - --base07: #{$orange-300}; // #d19a66 - --base08: #{$cyan-300}; - --base09: #{$orange-300}; // #d19a66 - --base0A: #{$yellow-200}; // #e5c07b - --base0B: #{$teal-300}; // #98c379 - --base0C: #{$teal-300}; // #56b6c2 - --base0D: #{$blue-300}; // #61afef - --base0E: #{$indigo-200}; // #c678dd - --base0F: #{$red-300}; // #be5046 - - .language-diff .gd { - color: $red-400; - } - .language-diff .gi { - color: $green-400; - } -} - -code[class*='language-'], -pre[class*='language-'] { - background: none; - font-family: var(--cui-font-monospace); - font-size: .875em; - text-align: left; - white-space: pre; - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; -} - -pre[class*='language-']:not(.language-sass):not(.language-scss):not(.language-text):not(.language-css) { - overflow: scroll; - max-height: 500px; -} - -.token.comment, -.token.block-comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: var(--base03); -} - -.token.tag { - color: var(--base08); -} - -.token.attr-name, -.token.namespace, -.token.deleted { - color: var(--base0A); -} - -.token.punctuation { - color: var(--base05); -} - -.token.function-name { - color: var(--base0A); -} - -.token.boolean, -.token.number, -.token.function { - color: var(--base09); -} - -.token.class-name, -.token.maybe-class-name { - color: var(--base08); -} - -.token.property, -.token.constant, -.token.symbol { - color: var(--base0A); -} - -.token.selector, -.token.important, -.token.atrule, -.token.keyword, -.token.builtin { - color: var(--base0E); -} - -.token.string, -.token.char, -.token.attr-value, -.token.regex, -.token.variable { - color: var(--base0C); -} - -.token.operator, -.token.entity, -.token.url { - color: var(--base05); -} - -.token.important, -.token.bold { - font-weight: bold; -} -.token.italic { - font-style: italic; -} - -.token.entity { - cursor: help; -} - -.token.inserted { - color: green; -} - -.language-bash, -.language-sh { - .token-line::before { - color: var(--base03); - content: "$ "; - user-select: none; - } -} - -.language-powershell::before { - color: var(--base0C); - content: "PM> "; - user-select: none; -} \ No newline at end of file diff --git a/packages/docs/src/styles/_scrolling.scss b/packages/docs/src/styles/_scrolling.scss deleted file mode 100644 index 20179600..00000000 --- a/packages/docs/src/styles/_scrolling.scss +++ /dev/null @@ -1,13 +0,0 @@ -// When navigating with the keyboard, prevent focus from landing behind the sticky header - -main { - a, - button, - h2, - h3, - h4, - [tabindex="0"] { - scroll-margin-top: 80px; - scroll-margin-bottom: 100px; - } -} diff --git a/packages/docs/src/styles/_search.scss b/packages/docs/src/styles/_search.scss deleted file mode 100644 index c487e640..00000000 --- a/packages/docs/src/styles/_search.scss +++ /dev/null @@ -1,152 +0,0 @@ -// stylelint-disable selector-class-pattern - -:root { - --docsearch-primary-color: var(--cui-primary); - --docsearch-logo-color: var(--cui-primary); -} - -@include color-mode(dark, true) { - // From here, the values are copied from https://cdn.jsdelivr.net/npm/@docsearch/css@3 - // in html[data-theme="dark"] selector - // and are slightly modified for formatting purpose - --docsearch-text-color: #f5f6f7; - --docsearch-container-background: rgba(9, 10, 17, .8); - --docsearch-modal-background: #15172a; - --docsearch-modal-shadow: inset 1px 1px 0 0 #2c2e40, 0 3px 8px 0 #000309; - --docsearch-searchbox-background: #090a11; - --docsearch-searchbox-focus-background: #000; - --docsearch-hit-color: #bec3c9; - --docsearch-hit-shadow: none; - --docsearch-hit-background: #090a11; - --docsearch-key-gradient: linear-gradient(-26.5deg, #565872, #31355b); - --docsearch-key-shadow: inset 0 -2px 0 0 #282d55, inset 0 0 1px 1px #51577d, 0 2px 2px 0 rgba(3, 4, 9, .3); - --docsearch-footer-background: #1e2136; - --docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 76, 106, .5), 0 -4px 8px 0 rgba(0, 0, 0, .2); - --docsearch-muted-color: #7f8497; -} - -.DocSearch-Container { - --docsearch-muted-color: var(--cui-secondary-color); - --docsearch-hit-shadow: none; - - z-index: 2000; // Make sure to be over all components showcased in the documentation - cursor: auto; // Needed because of [role="button"] in Algolia search modal. Remove once https://github.com/algolia/docsearch/issues/1370 is tackled. - - @include media-breakpoint-up(lg) { - padding-top: 4rem; - } -} - -.DocSearch-Button { - --docsearch-searchbox-background: #{rgba($black, .1)}; - // --docsearch-searchbox-color: #{$white}; - --docsearch-searchbox-focus-background: #{rgba($black, .25)}; - // --docsearch-searchbox-shadow: #{0 0 0 .25rem rgba($bd-accent, .4)}; - // --docsearch-text-color: #{$white}; - // --docsearch-muted-color: #{rgba($white, .65)}; - - min-width: 200px; - min-height: 38px; - font-family: $input-font-family; - font-weight: $input-font-weight; - line-height: $input-line-height; - @include font-size($input-font-size); - color: $input-color; - background-color: $input-bg; - background-clip: padding-box; - border: $input-border-width solid $input-border-color; - - // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS. - @include border-radius($btn-border-radius); - - @include box-shadow($input-box-shadow); - @include transition($input-transition); - - &:focus { - color: $input-focus-color; - background-color: $input-focus-bg; - border-color: $input-focus-border-color; - outline: 0; - @if $enable-shadows { - @include box-shadow($input-box-shadow, $input-focus-box-shadow); - } @else { - // Avoid using mixin so we can pass custom focus shadow properly - box-shadow: $input-focus-box-shadow; - } - } - - &:hover:not(:disabled):not([readonly])::file-selector-button { - background-color: $form-file-button-hover-bg; - } - - .DocSearch-Search-Icon { - opacity: .65; - } -} - - -.DocSearch-Button-Keys { - min-width: 0; - padding: 0 .25rem; - background: rgba($black, .125); - @include border-radius(.25rem); -} - -.DocSearch-Button-Key { - top: 0; - width: auto; - height: 1.5rem; - padding: 0 .125rem; - margin-right: 0; - font-size: .875rem; - background: none; - box-shadow: none; -} - -.DocSearch-Commands-Key { - padding-left: 1px; - font-size: .875rem; - background-color: rgba($black, .1); - background-image: none; - box-shadow: none; -} - -.DocSearch-Form { - @include border-radius(var(--cui-border-radius)); -} - -.DocSearch-Hits { - mark { - padding: 0; - } -} - -.DocSearch-Hit { - padding-bottom: 0; - @include border-radius(0); - - a { - @include border-radius(0); - border: solid var(--cui-border-color); - border-width: 0 1px 1px; - } - - &:first-child a { - @include border-top-radius(var(--cui-border-radius)); - border-top-width: 1px; - } - &:last-child a { - @include border-bottom-radius(var(--cui-border-radius)); - } -} - -.DocSearch-Hit-icon { - display: flex; - align-items: center; -} - -// Fix --docsearch-logo-color that doesn't do anything -.DocSearch-Logo svg .cls-1, -.DocSearch-Logo svg .cls-2 { - fill: var(--docsearch-logo-color); -} diff --git a/packages/docs/src/styles/_sidebar.scss b/packages/docs/src/styles/_sidebar.scss deleted file mode 100644 index c6d8818e..00000000 --- a/packages/docs/src/styles/_sidebar.scss +++ /dev/null @@ -1,32 +0,0 @@ -.docs-sidebar { - --cui-sidebar-bg: var(--cui-tertiary-bg); - --cui-sidebar-brand-bg: transparent; - --cui-sidebar-brand-color: var(--cui-body-color); - - .sidebar-nav { - --cui-sidebar-nav-link-color: var(--cui-body-color); - --cui-sidebar-nav-link-active-bg: transparent; - --cui-sidebar-nav-link-active-color: var(--cui-primary); - --cui-sidebar-nav-link-hover-bg: transparent; - --cui-sidebar-nav-link-hover-color: var(--cui-primary); - --cui-sidebar-nav-link-icon-margin: 1rem; - --cui-sidebar-nav-group-bg: transparent; - --cui-sidebar-nav-group-toggle-show-color: var(--cui-primary); - - .compact .nav-link { - --cui-sidebar-nav-link-padding-y: .375rem; - } - - .nav-group-items { - --cui-sidebar-nav-link-color: var(--cui-body-color); - } - } -} - -@if $enable-dark-mode { - @include color-mode(dark) { - .docs-sidebar { - --cui-sidebar-bg: var(--cui-body-bg); - } - } -} diff --git a/packages/docs/src/styles/_table-api.scss b/packages/docs/src/styles/_table-api.scss deleted file mode 100644 index 9e430366..00000000 --- a/packages/docs/src/styles/_table-api.scss +++ /dev/null @@ -1,24 +0,0 @@ -.table-api { - tr td { - padding-top: 1rem; - padding-bottom: 1rem; - } - td:nth-child(1n), - th:nth-child(1n) { - width: 15%; - padding-left: 1rem; - } - td:nth-child(2n) { - width: 55%; - } - td:nth-child(3n) { - width: 20%; - } - td:nth-child(4n) { - width: 10%; - } -} - -.markdown + h3 { - margin-top: 3rem; -} \ No newline at end of file diff --git a/packages/docs/src/styles/_toc.scss b/packages/docs/src/styles/_toc.scss deleted file mode 100644 index 6178d193..00000000 --- a/packages/docs/src/styles/_toc.scss +++ /dev/null @@ -1,42 +0,0 @@ -// stylelint-disable selector-max-type - -.docs-toc { - @include media-breakpoint-up(lg) { - position: sticky; - top: 5rem; - right: 0; - z-index: 2; - height: subtract(100vh, 7rem); - overflow-y: auto; - } - - nav { - @include font-size(.875rem); - - ul { - padding-left: 0; - list-style: none; - - ul { - padding-left: 1rem; - margin-top: .25rem; - } - } - - li { - margin-bottom: .25rem; - } - - a { - color: inherit; - - &:not(:hover) { - text-decoration: none; - } - - code { - font: inherit; - } - } - } -} \ No newline at end of file diff --git a/packages/docs/src/styles/_variables.scss b/packages/docs/src/styles/_variables.scss deleted file mode 100644 index b53b7754..00000000 --- a/packages/docs/src/styles/_variables.scss +++ /dev/null @@ -1,25 +0,0 @@ -// stylelint-disable scss/dollar-variable-default - -// Local docs variables -$cd-purple: #4c0bce; -$cd-violet: lighten(saturate($cd-purple, 5%), 15%); // stylelint-disable-line function-disallowed-list -$cd-accent: #ffe484; - -$cd-gutter-x: 3rem; -$cd-callout-variants: info, warning, danger !default; - -:root { - --cd-purple: #{$cd-purple}; - --cd-violet: #{$cd-violet}; - --cd-accent: #{$cd-accent}; - --cd-violet-rgb: #{to-rgb($cd-violet)}; - --cd-accent-rgb: #{to-rgb($cd-accent)}; - --cd-pink-rgb: #{to-rgb($pink-500)}; - --cd-teal-rgb: #{to-rgb($teal-500)}; - --cd-violet-bg: var(--cd-violet); - --cd-toc-color: var(--cd-violet); - --cd-sidebar-link-bg: rgba(var(--cd-violet-rgb), .1); - --cd-callout-link: #{to-rgb($blue-600)}; - --cd-callout-code-color: #{$pink-600}; - --cd-pre-bg: var(--cui-tertiary-bg); -} diff --git a/packages/docs/src/styles/styles.scss b/packages/docs/src/styles/styles.scss deleted file mode 100644 index d90d130a..00000000 --- a/packages/docs/src/styles/styles.scss +++ /dev/null @@ -1,18 +0,0 @@ -@import "@coreui/coreui/scss/coreui"; - -// Import Chart.js custom tooltips styles -@import "@coreui/chartjs/scss/coreui-chartjs"; - -@import "variables"; -@import "ads"; -@import "anchor"; -@import "callouts"; -@import "component-examples"; -@import "footer"; -@import "layout"; -@import "prism"; -@import "scrolling"; -@import "search"; -@import "sidebar"; -@import "table-api"; -@import "toc"; diff --git a/packages/docs/src/templates/DefaultLayout.tsx b/packages/docs/src/templates/DefaultLayout.tsx deleted file mode 100644 index 643cc254..00000000 --- a/packages/docs/src/templates/DefaultLayout.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React, { FC, useState } from 'react' -import { Footer, Header, Sidebar, Seo } from '../components' -import { CContainer } from '@coreui/react/src/' -import DocsLayout from './DocsLayout' - -import { AppContext } from '../AppContext' -import { Script } from 'gatsby' - -interface DefaultLayoutProps { - children: any // eslint-disable-line @typescript-eslint/no-explicit-any - data: any // eslint-disable-line @typescript-eslint/no-explicit-any - pageContext: any // eslint-disable-line @typescript-eslint/no-explicit-any - path: any // eslint-disable-line @typescript-eslint/no-explicit-any -} - -const DefaultLayout: FC<DefaultLayoutProps> = ({ children, data, pageContext, path }) => { - const [sidebarVisible, setSidebarVisible] = useState() - - const title = pageContext.frontmatter ? pageContext.frontmatter.title : '' - const description = pageContext.frontmatter ? pageContext.frontmatter.description : '' - const name = pageContext.frontmatter ? pageContext.frontmatter.name : '' - const route = pageContext.frontmatter ? pageContext.frontmatter.route : '' - - return ( - <AppContext.Provider - value={{ - sidebarVisible, - setSidebarVisible, - }} - > - <Seo title={title} description={description} name={name} /> - <Sidebar currentRoute={route} /> - <div className="wrapper d-flex flex-column min-vh-100"> - <Header /> - <div className="body flex-grow-1 px-3"> - {path === '/404/' ? ( - <CContainer lg>{children}</CContainer> - ) : ( - <DocsLayout data={data} pageContext={pageContext}> - {children} - </DocsLayout> - )} - </div> - <Footer /> - </div> - <Script - src="https://cdn.jsdelivr.net/npm/@docsearch/js@3" - onLoad={() => { - const searchElement = document.getElementById('docsearch') - - // @ts-expect-error global variable - if (!window.docsearch || !searchElement) { - return - } - - // @ts-expect-error global variable - window.docsearch({ - appId: 'JIOZIZPLMM', - apiKey: '6e3f7692d2589d042bb40426b75df1b7', - indexName: 'coreui-react', - container: searchElement, - // Set debug to `true` if you want to inspect the dropdown - debug: true, - }) - }} - /> - - <script type="text/javascript"></script> - </AppContext.Provider> - ) -} - -DefaultLayout.displayName = 'DefaultLayout' - -export default DefaultLayout diff --git a/packages/docs/src/templates/DocsLayout.tsx b/packages/docs/src/templates/DocsLayout.tsx deleted file mode 100644 index 8c260651..00000000 --- a/packages/docs/src/templates/DocsLayout.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import React, { FC } from 'react' -import { Ads, Banner, Seo, Toc } from '../components' -import { CCol, CContainer, CRow } from '@coreui/react/src/' - -interface DocsLayoutProps { - children: any // eslint-disable-line @typescript-eslint/no-explicit-any - data: any // eslint-disable-line @typescript-eslint/no-explicit-any - pageContext: any // eslint-disable-line @typescript-eslint/no-explicit-any -} - -// @ts-expect-error json file -import jsonData from './../data/other_frameworks.json' - -const humanize = (text: string) => { - const string = text - .split('-') - .reduce( - (accumulator, currentValue) => - accumulator + ' ' + currentValue[0].toUpperCase() + currentValue.slice(1), - ) - return string[0].toUpperCase() + string.slice(1) -} - -const DocsLayout: FC<DocsLayoutProps> = ({ children, data, pageContext }) => { - const title = pageContext.frontmatter ? pageContext.frontmatter.title : '' - const description = pageContext.frontmatter ? pageContext.frontmatter.description : '' - const name = pageContext.frontmatter ? pageContext.frontmatter.name : '' - const other_frameworks = pageContext.frontmatter ? pageContext.frontmatter.other_frameworks : '' - const pro_component = pageContext.frontmatter ? pageContext.frontmatter.pro_component : '' - const route = pageContext.frontmatter ? pageContext.frontmatter.route : '' - const frameworks = other_frameworks ? other_frameworks.split(', ') : false - const otherFrameworks = JSON.parse(JSON.stringify(jsonData)) - - return ( - <> - <Seo title={title} description={description} name={name} /> - <CContainer lg> - <main className="docs-main"> - <CRow> - <CCol lg={9}> - <Banner pro={pro_component} /> - <h1>{title}</h1> - <p className="docs-lead fs-4 fw-light">{description}</p> - <Ads code="CEAICKJY" location={route} placement="coreuiio" /> - {frameworks && ( - <> - <h2>Other frameworks</h2> - <p> - CoreUI components are available as native Angular, Bootstrap (Vanilla JS), and - Vue components. To learn more please visit the following pages. - </p> - <ul> - {frameworks.map((item: string, index: number) => ( - <React.Fragment key={index}> - {Object.keys(otherFrameworks[item]).map( - (el, index) => - el !== 'react' && ( - <li key={index}> - <a href={otherFrameworks[item][el]}> - <> - {el[0].toUpperCase() + el.slice(1)} {humanize(item)} - </> - </a> - </li> - ), - )} - </React.Fragment> - ))} - </ul> - </> - )} - {children} - </CCol> - {data && data.mdx && ( - <CCol lg={3}> - <Toc items={data.mdx.tableOfContents.items} /> - </CCol> - )} - </CRow> - </main> - </CContainer> - </> - ) -} - -DocsLayout.displayName = 'DocsLayout' - -export default DocsLayout diff --git a/packages/docs/src/templates/MdxLayout.tsx b/packages/docs/src/templates/MdxLayout.tsx deleted file mode 100644 index cfe62f86..00000000 --- a/packages/docs/src/templates/MdxLayout.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import React, { FC } from 'react' -import { graphql } from 'gatsby' -import { MDXProvider } from '@mdx-js/react' -import { CBadge, CTable } from '@coreui/react/src/index' -import { Callout, CodeBlock, Example, ScssDocs } from '../components' - -interface MdxLayoutProps { - data: any // eslint-disable-line @typescript-eslint/no-explicit-any - children: any // eslint-disable-line @typescript-eslint/no-explicit-any -} - -const MdxLayout: FC<MdxLayoutProps> = ({ children }) => { - return ( - <MDXProvider - components={{ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ScssDocs: (props: any) => <ScssDocs {...props} />, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - strong: (props: any) => { - if (props.children.type == 'em') { - const color = props.children.props.children.includes('Deprecated') - ? 'warning' - : 'primary' - return ( - <> - <br /> - <CBadge {...props.children.props} color={color} /> - </> - ) - } else { - return <strong>{props.children}</strong> - } - }, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - pre: (props: any) => <CodeBlock {...props} />, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - table: (props: any) => { - // TODO: find better soultion - const isApiTable = - props.children[0].props.children.props.children[0].props.children && - props.children[0].props.children.props.children[0].props.children.includes('Property') - return ( - <CTable - responsive - {...props} - className={`table ${isApiTable && ' table-striped table-api'}`} - /> - ) - }, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - Callout: (props: any) => { - const { children, title, ...rest } = props - return ( - <Callout {...rest}> - {title && <h5>{title}</h5>} - {children} - </Callout> - ) - }, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - Example: (props: any) => { - const { children, ...rest } = props - return ( - <Example {...rest}> - {React.Children.map(children, (child) => { - if (React.isValidElement(child)) { - return React.cloneElement(child) - } - return - })} - </Example> - ) - }, - }} - > - {children} - </MDXProvider> - ) -} - -MdxLayout.displayName = 'MdxLayout' - -export default MdxLayout - -export const pageQuery = graphql` - query BlogPostQuery($id: String) { - mdx(id: { eq: $id }) { - tableOfContents(maxDepth: 3) - } - } -` diff --git a/packages/docs/static/index.html b/packages/docs/static/index.html deleted file mode 100644 index b08ad38b..00000000 --- a/packages/docs/static/index.html +++ /dev/null @@ -1,3 +0,0 @@ -<script> - window.location.replace("./getting-started/introduction/"); -</script> \ No newline at end of file diff --git a/packages/gatsby-remark-import-markdown/index.js b/packages/gatsby-remark-import-markdown/index.js deleted file mode 100755 index 398ce941..00000000 --- a/packages/gatsby-remark-import-markdown/index.js +++ /dev/null @@ -1,52 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -'use strict' - -const fs = require('fs') -const normalizePath = require('normalize-path') -const visit = require('unist-util-visit') -const unified = require('unified') -const parse = require('remark-parse') -const remarkGfm = require('remark-gfm') -const html = require('remark-html') - -module.exports = ({ markdownAST }, pluginOptions = {}) => { - const directory = pluginOptions.directory - - if (!directory) { - throw Error(`Required option \"directory\" not specified`) - } else if (!fs.existsSync(directory)) { - throw Error(`Invalid directory specified \"${directory}\"`) - } else if (!directory.endsWith('/')) { - directory += '/' - } - - visit(markdownAST, 'inlineCode', (node, _, parent) => { - const value = node.value - - if (value.startsWith('markdown:')) { - const file = value.substr(9) - const path = normalizePath('' + directory + file) - - if (!fs.existsSync(path)) { - throw Error(`Invalid fragment specified; no such file "${path}"`) - } - - const code = fs.readFileSync(path, 'utf8') - const markdown = unified() - .use(parse) - .use(remarkGfm) - .use(html, { sanitize: false }) - .parse(code) - - parent.type = 'div' - parent.children = [] - - markdown.children.forEach((child) => { - delete child.position - parent.children.push(child) - }) - } - }) - - return markdownAST -} diff --git a/packages/gatsby-remark-import-markdown/package.json b/packages/gatsby-remark-import-markdown/package.json deleted file mode 100644 index 84f9c71d..00000000 --- a/packages/gatsby-remark-import-markdown/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "gatsby-remark-import-markdown", - "license": "MIT", - "version": "1.0.0", - "author": "Łukasz Holeczek <https://github.com/mrholek>", - "repository": "", - "keywords": [ - "markdown", - "embed", - "gatsby", - "gatsby-plugin", - "remark" - ], - "description": "Gatsby plugin to embed markdown fragments within markdown", - "dependencies": { - "normalize-path": "^2.1.1", - "unist-util-map": "^1.0.3", - "unist-util-visit": "^2.0.3", - "unified": "^9.2.1", - "remark-gfm": "^1.0.0", - "remark-html": "^13.0.2", - "remark-parse": "^9.0.0", - "remark-rehype": "^8.1.0", - "rehype-stringify": "^8.0.0" - }, - "scripts": {}, - "peerDependencies": { - "gatsby": ">=5.0.0" - }, - "main": "index.js" -} diff --git a/packages/gatsby-remark-jsx-preview/index.js b/packages/gatsby-remark-jsx-preview/index.js deleted file mode 100755 index f2219dba..00000000 --- a/packages/gatsby-remark-jsx-preview/index.js +++ /dev/null @@ -1,48 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -'use strict' - -const acorn = require('acorn') -const fromMarkdown = require('mdast-util-from-markdown') -const mdxJsx = require('mdast-util-mdx-jsx') -const mdxMd = require('micromark-extension-mdx-md') -const syntax = require('micromark-extension-mdx-jsx') -const visit = require('unist-util-visit') - -module.exports = ({ markdownAST }) => { - visit(markdownAST, 'code', (node) => { - if (node.meta && node.meta.includes('preview')) { - const value = node.value - const className = /className="(.*)"/.test(node.meta) ? RegExp.$1 : '' - const tree = fromMarkdown(value.replace(/(\r\n|\n|\r)/gm, ''), { - extensions: [syntax({ acorn: acorn, addResult: true }), mdxMd], - mdastExtensions: [mdxJsx.fromMarkdown], - }) - - delete node.value - delete node.position - delete node.lang - delete node.meta - - node.type = 'div' - node.data = { hProperties: { className: ['docs-example-snippet docs-code-snippet'] } } - node.children = [ - { - type: 'mdxJsxFlowElement', - name: 'Example', - attributes: [{ type: 'mdxJsxAttribute', name: 'className', value: className }], - children: - tree.children[0].type === 'paragraph' - ? tree.children[0].children.map((child) => child) - : tree.children.map((child) => child), - }, - { - type: 'code', - lang: 'jsx', - value: value, - }, - ] - } - }) - - return markdownAST -} diff --git a/packages/gatsby-remark-jsx-preview/package.json b/packages/gatsby-remark-jsx-preview/package.json deleted file mode 100644 index f21a9d2f..00000000 --- a/packages/gatsby-remark-jsx-preview/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "gatsby-remark-jsx-preview", - "license": "MIT", - "version": "1.0.0", - "author": "Łukasz Holeczek <https://github.com/mrholek>", - "repository": "", - "keywords": [ - "code", - "jsx", - "gatsby", - "gatsby-plugin", - "remark" - ], - "description": "Gatsby plugin to embed jsx code preview", - "dependencies": { - "mdast-util-from-markdown": "^0.8.5", - "micromark-extension-mdx-jsx": "^0.3.3", - "micromark-extension-mdx-md": "^0.1.1", - "mdast-util-mdx-jsx": "^0.1.4", - "unist-util-visit": "^2.0.3" - }, - "peerDependencies": { - "gatsby": ">=5.0.0" - }, - "main": "index.js" -} diff --git a/src/App.js b/src/App.js new file mode 100644 index 00000000..7c248818 --- /dev/null +++ b/src/App.js @@ -0,0 +1,38 @@ +import React, { Component, Suspense } from 'react' +import { HashRouter, Route, Routes } from 'react-router-dom' +import './scss/style.scss' + +const loading = ( + <div className="pt-3 text-center"> + <div className="sk-spinner sk-spinner-pulse"></div> + </div> +) + +// Containers +const DefaultLayout = React.lazy(() => import('./layout/DefaultLayout')) + +// Pages +const Login = React.lazy(() => import('./views/pages/login/Login')) +const Register = React.lazy(() => import('./views/pages/register/Register')) +const Page404 = React.lazy(() => import('./views/pages/page404/Page404')) +const Page500 = React.lazy(() => import('./views/pages/page500/Page500')) + +class App extends Component { + render() { + return ( + <HashRouter> + <Suspense fallback={loading}> + <Routes> + <Route exact path="/login" name="Login Page" element={<Login />} /> + <Route exact path="/register" name="Register Page" element={<Register />} /> + <Route exact path="/404" name="Page 404" element={<Page404 />} /> + <Route exact path="/500" name="Page 500" element={<Page500 />} /> + <Route path="*" name="Home" element={<DefaultLayout />} /> + </Routes> + </Suspense> + </HashRouter> + ) + } +} + +export default App diff --git a/src/App.test.js b/src/App.test.js new file mode 100644 index 00000000..3a7a8cc5 --- /dev/null +++ b/src/App.test.js @@ -0,0 +1,9 @@ +import React from 'react' +import { render, screen } from '@testing-library/react' +import App from './App' + +test('renders learn react link', () => { + render(<App />) + const linkElement = screen.getByText(/learn react/i) + expect(linkElement).toBeInTheDocument() +}) diff --git a/src/_nav.js b/src/_nav.js new file mode 100644 index 00000000..8f3d730d --- /dev/null +++ b/src/_nav.js @@ -0,0 +1,305 @@ +import React from 'react' +import CIcon from '@coreui/icons-react' +import { + cilBell, + cilCalculator, + cilChartPie, + cilCursor, + cilDescription, + cilDrop, + cilNotes, + cilPencil, + cilPuzzle, + cilSpeedometer, + cilStar, +} from '@coreui/icons' +import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react' + +const _nav = [ + { + component: CNavItem, + name: 'Dashboard', + to: '/dashboard', + icon: <CIcon icon={cilSpeedometer} customClassName="nav-icon" />, + badge: { + color: 'info', + text: 'NEW', + }, + }, + { + component: CNavTitle, + name: 'Theme', + }, + { + component: CNavItem, + name: 'Colors', + to: '/theme/colors', + icon: <CIcon icon={cilDrop} customClassName="nav-icon" />, + }, + { + component: CNavItem, + name: 'Typography', + to: '/theme/typography', + icon: <CIcon icon={cilPencil} customClassName="nav-icon" />, + }, + { + component: CNavTitle, + name: 'Components', + }, + { + component: CNavGroup, + name: 'Base', + to: '/base', + icon: <CIcon icon={cilPuzzle} customClassName="nav-icon" />, + items: [ + { + component: CNavItem, + name: 'Accordion', + to: '/base/accordion', + }, + { + component: CNavItem, + name: 'Breadcrumb', + to: '/base/breadcrumbs', + }, + { + component: CNavItem, + name: 'Cards', + to: '/base/cards', + }, + { + component: CNavItem, + name: 'Carousel', + to: '/base/carousels', + }, + { + component: CNavItem, + name: 'Collapse', + to: '/base/collapses', + }, + { + component: CNavItem, + name: 'List group', + to: '/base/list-groups', + }, + { + component: CNavItem, + name: 'Navs & Tabs', + to: '/base/navs', + }, + { + component: CNavItem, + name: 'Pagination', + to: '/base/paginations', + }, + { + component: CNavItem, + name: 'Placeholders', + to: '/base/placeholders', + }, + { + component: CNavItem, + name: 'Popovers', + to: '/base/popovers', + }, + { + component: CNavItem, + name: 'Progress', + to: '/base/progress', + }, + { + component: CNavItem, + name: 'Spinners', + to: '/base/spinners', + }, + { + component: CNavItem, + name: 'Tables', + to: '/base/tables', + }, + { + component: CNavItem, + name: 'Tooltips', + to: '/base/tooltips', + }, + ], + }, + { + component: CNavGroup, + name: 'Buttons', + to: '/buttons', + icon: <CIcon icon={cilCursor} customClassName="nav-icon" />, + items: [ + { + component: CNavItem, + name: 'Buttons', + to: '/buttons/buttons', + }, + { + component: CNavItem, + name: 'Buttons groups', + to: '/buttons/button-groups', + }, + { + component: CNavItem, + name: 'Dropdowns', + to: '/buttons/dropdowns', + }, + ], + }, + { + component: CNavGroup, + name: 'Forms', + icon: <CIcon icon={cilNotes} customClassName="nav-icon" />, + items: [ + { + component: CNavItem, + name: 'Form Control', + to: '/forms/form-control', + }, + { + component: CNavItem, + name: 'Select', + to: '/forms/select', + }, + { + component: CNavItem, + name: 'Checks & Radios', + to: '/forms/checks-radios', + }, + { + component: CNavItem, + name: 'Range', + to: '/forms/range', + }, + { + component: CNavItem, + name: 'Input Group', + to: '/forms/input-group', + }, + { + component: CNavItem, + name: 'Floating Labels', + to: '/forms/floating-labels', + }, + { + component: CNavItem, + name: 'Layout', + to: '/forms/layout', + }, + { + component: CNavItem, + name: 'Validation', + to: '/forms/validation', + }, + ], + }, + { + component: CNavItem, + name: 'Charts', + to: '/charts', + icon: <CIcon icon={cilChartPie} customClassName="nav-icon" />, + }, + { + component: CNavGroup, + name: 'Icons', + icon: <CIcon icon={cilStar} customClassName="nav-icon" />, + items: [ + { + component: CNavItem, + name: 'CoreUI Free', + to: '/icons/coreui-icons', + badge: { + color: 'success', + text: 'NEW', + }, + }, + { + component: CNavItem, + name: 'CoreUI Flags', + to: '/icons/flags', + }, + { + component: CNavItem, + name: 'CoreUI Brands', + to: '/icons/brands', + }, + ], + }, + { + component: CNavGroup, + name: 'Notifications', + icon: <CIcon icon={cilBell} customClassName="nav-icon" />, + items: [ + { + component: CNavItem, + name: 'Alerts', + to: '/notifications/alerts', + }, + { + component: CNavItem, + name: 'Badges', + to: '/notifications/badges', + }, + { + component: CNavItem, + name: 'Modal', + to: '/notifications/modals', + }, + { + component: CNavItem, + name: 'Toasts', + to: '/notifications/toasts', + }, + ], + }, + { + component: CNavItem, + name: 'Widgets', + to: '/widgets', + icon: <CIcon icon={cilCalculator} customClassName="nav-icon" />, + badge: { + color: 'info', + text: 'NEW', + }, + }, + { + component: CNavTitle, + name: 'Extras', + }, + { + component: CNavGroup, + name: 'Pages', + icon: <CIcon icon={cilStar} customClassName="nav-icon" />, + items: [ + { + component: CNavItem, + name: 'Login', + to: '/login', + }, + { + component: CNavItem, + name: 'Register', + to: '/register', + }, + { + component: CNavItem, + name: 'Error 404', + to: '/404', + }, + { + component: CNavItem, + name: 'Error 500', + to: '/500', + }, + ], + }, + { + component: CNavItem, + name: 'Docs', + href: 'https://coreui.io/react/docs/templates/installation/', + icon: <CIcon icon={cilDescription} customClassName="nav-icon" />, + }, +] + +export default _nav diff --git a/src/assets/brand/logo-negative.js b/src/assets/brand/logo-negative.js new file mode 100644 index 00000000..114a6a04 --- /dev/null +++ b/src/assets/brand/logo-negative.js @@ -0,0 +1,33 @@ +export const logoNegative = [ + '608 134', + ` + <title>coreui react pro logo</title> + <g> + <g style="fill:#80d0ff;"> + <path d="M362.0177,90.1512,353.25,69.4149a.2507.2507,0,0,0-.2559-.1914H343.01a.2263.2263,0,0,0-.2559.2559V90.0233a.5657.5657,0,0,1-.64.64h-1.2163a.5652.5652,0,0,1-.64-.64V46.5028a.5655.5655,0,0,1,.64-.64H353.442a9.9792,9.9792,0,0,1,7.7437,3.2324A12.2,12.2,0,0,1,364.13,57.64a12.4389,12.4389,0,0,1-2.24,7.584,9.37,9.37,0,0,1-6.08,3.7441c-.1709.086-.2139.1915-.128.3194l8.7041,20.6084.064.2558q0,.5127-.5757.5118h-1.1523A.703.703,0,0,1,362.0177,90.1512ZM342.754,48.3593v18.496a.2259.2259,0,0,0,.2559.2559h10.3037a7.6713,7.6713,0,0,0,6.0166-2.5918,9.8807,9.8807,0,0,0,2.3037-6.8164,10.2875,10.2875,0,0,0-2.272-6.9756,7.6033,7.6033,0,0,0-6.0483-2.624H343.01A.2263.2263,0,0,0,342.754,48.3593Z"/> + <path d="M401.3263,48.1034H381.2945a.2262.2262,0,0,0-.2558.2559v18.496a.2259.2259,0,0,0,.2558.2559h13.8238a.5664.5664,0,0,1,.6406.64v.96a.5663.5663,0,0,1-.6406.6406H381.2945a.2263.2263,0,0,0-.2558.2559v18.56a.2258.2258,0,0,0,.2558.2558h20.0318a.5671.5671,0,0,1,.6406.6407v.96a.566.566,0,0,1-.6406.64H379.1827a.5653.5653,0,0,1-.64-.64V46.5028a.5656.5656,0,0,1,.64-.64h22.1436a.5664.5664,0,0,1,.6406.64v.96A.5663.5663,0,0,1,401.3263,48.1034Z"/> + <path d="M439.047,90.1512l-2.4317-8.832a.2971.2971,0,0,0-.32-.1924H419.5274a.2957.2957,0,0,0-.32.1924l-2.3681,8.7676a.6577.6577,0,0,1-.7036.5762H414.919a.5385.5385,0,0,1-.5756-.7041l12.0317-43.584a.6436.6436,0,0,1,.7041-.5117h1.6a.6442.6442,0,0,1,.7041.5117l12.16,43.584.0644.1923q0,.5127-.64.5118h-1.2163A.6428.6428,0,0,1,439.047,90.1512ZM419.9435,78.9188a.3031.3031,0,0,0,.2236.0967h15.4883a.3048.3048,0,0,0,.2236-.0967c.0645-.0635.0742-.1162.0322-.1592l-7.872-28.9287c-.043-.0849-.086-.1279-.128-.1279s-.0859.043-.1279.1279L419.9112,78.76C419.8683,78.8026,419.879,78.8553,419.9435,78.9188Z"/> + <path d="M456.6017,87.911a11.6372,11.6372,0,0,1-3.3277-8.7041V57.1913a11.4158,11.4158,0,0,1,3.36-8.5762,12.0941,12.0941,0,0,1,8.8-3.2637,12.2566,12.2566,0,0,1,8.8643,3.2315,11.3927,11.3927,0,0,1,3.36,8.6084v.64a.5663.5663,0,0,1-.6406.6407l-1.28.0634q-.6408,0-.64-.5761v-.8321a9.289,9.289,0,0,0-2.6558-6.9121,10.6734,10.6734,0,0,0-14.0161,0,9.2854,9.2854,0,0,0-2.6563,6.9121V79.3993a9.2808,9.2808,0,0,0,2.6563,6.9121,10.67,10.67,0,0,0,14.0161,0,9.2843,9.2843,0,0,0,2.6558-6.9121v-.7686q0-.5757.64-.5752l1.28.0635a.5667.5667,0,0,1,.6406.6406v.5118a11.4952,11.4952,0,0,1-3.36,8.64,13.6227,13.6227,0,0,1-17.6963,0Z"/> + <path d="M514.4376,46.5028v.96a.5658.5658,0,0,1-.64.6406H503.046a.2263.2263,0,0,0-.2559.2559v41.664a.566.566,0,0,1-.6406.64h-1.2158a.5652.5652,0,0,1-.64-.64V48.3593a.2266.2266,0,0,0-.2558-.2559H489.8619a.5656.5656,0,0,1-.64-.6406v-.96a.5656.5656,0,0,1,.64-.64H513.798A.5658.5658,0,0,1,514.4376,46.5028Z"/> + <path d="M522.0665,89.5116a2.8385,2.8385,0,0,1-.8-2.0488,2.9194,2.9194,0,0,1,.8-2.1114,2.7544,2.7544,0,0,1,2.08-.832,2.8465,2.8465,0,0,1,2.9438,2.9434,2.7541,2.7541,0,0,1-.832,2.08,2.9221,2.9221,0,0,1-2.1118.8008A2.754,2.754,0,0,1,522.0665,89.5116Z"/> + <path d="M542.4054,88.0077a11.3123,11.3123,0,0,1-3.2-8.416v-5.44a.5656.5656,0,0,1,.64-.64h1.2158a.5661.5661,0,0,1,.64.64v5.5039a9.1424,9.1424,0,0,0,2.5283,6.72,8.9745,8.9745,0,0,0,6.6875,2.5605,8.7908,8.7908,0,0,0,9.28-9.28V46.5028a.5655.5655,0,0,1,.64-.64h1.2163a.566.566,0,0,1,.64.64V79.5917a11.2545,11.2545,0,0,1-3.2325,8.416,13.0618,13.0618,0,0,1-17.0556,0Z"/> + <path d="M580.35,88.1034a10.4859,10.4859,0,0,1-3.36-8.1279v-1.792a.5663.5663,0,0,1,.64-.6407h1.0884a.5668.5668,0,0,1,.64.6407v1.6a8.5459,8.5459,0,0,0,2.752,6.6562,10.5353,10.5353,0,0,0,7.36,2.4961,9.8719,9.8719,0,0,0,6.9761-2.3681,8.2161,8.2161,0,0,0,2.56-6.336,8.4,8.4,0,0,0-1.12-4.416,11.3812,11.3812,0,0,0-3.3281-3.3926,71.6714,71.6714,0,0,0-6.1763-3.7119,71.0479,71.0479,0,0,1-6.24-3.84,12.1711,12.1711,0,0,1-3.4238-3.68,10.2614,10.2614,0,0,1-1.28-5.3438,9.8579,9.8579,0,0,1,3.0718-7.7441,12.0122,12.0122,0,0,1,8.32-2.752q5.6954,0,8.96,3.1036a10.8251,10.8251,0,0,1,3.2642,8.2246v1.6a.5658.5658,0,0,1-.64.64h-1.1519a.5652.5652,0,0,1-.64-.64V56.8075a8.8647,8.8647,0,0,0-2.624-6.6885,9.9933,9.9933,0,0,0-7.232-2.5273,9.37,9.37,0,0,0-6.5278,2.1435,7.8224,7.8224,0,0,0-2.3682,6.1123,7.8006,7.8006,0,0,0,1.0244,4.16,10.387,10.387,0,0,0,3.0078,3.0391,62.8714,62.8714,0,0,0,5.9522,3.4882,71.0575,71.0575,0,0,1,6.72,4.2559,13.4674,13.4674,0,0,1,3.648,3.9365,10.049,10.049,0,0,1,1.28,5.1836,10.7177,10.7177,0,0,1-3.2637,8.1924q-3.2637,3.0717-8.832,3.0723Q583.71,91.1757,580.35,88.1034Z"/> + </g> + + <g style="fill:#fff;"> + <g> + <path d="M99.835,36.0577l-39-22.5167a12,12,0,0,0-12,0l-39,22.5166a12.0339,12.0339,0,0,0-6,10.3924V91.4833a12.0333,12.0333,0,0,0,6,10.3923l39,22.5167a12,12,0,0,0,12,0l39-22.5167a12.0331,12.0331,0,0,0,6-10.3923V46.45A12.0334,12.0334,0,0,0,99.835,36.0577Zm-2,55.4256a4,4,0,0,1-2,3.4641l-39,22.5167a4.0006,4.0006,0,0,1-4,0l-39-22.5167a4,4,0,0,1-2-3.4641V46.45a4,4,0,0,1,2-3.4642l39-22.5166a4,4,0,0,1,4,0l39,22.5166a4,4,0,0,1,2,3.4642Z"/> + <path d="M77.8567,82.0046h-2.866a4,4,0,0,0-1.9247.4934L55.7852,91.9833,35.835,80.4648V57.4872l19.95-11.5185,17.2893,9.4549a3.9993,3.9993,0,0,0,1.9192.4906h2.8632a2,2,0,0,0,2-2V51.2024a2,2,0,0,0-1.04-1.7547L59.628,38.9521a8.0391,8.0391,0,0,0-7.8428.09L31.8346,50.56a8.0246,8.0246,0,0,0-4,6.9287v22.976a8,8,0,0,0,4,6.9283l19.95,11.5186a8.0429,8.0429,0,0,0,7.8433.0879l19.19-10.5312a2,2,0,0,0,1.0378-1.7533v-2.71A2,2,0,0,0,77.8567,82.0046Z"/> + </g> + <g> + <path d="M172.58,45.3618a15.0166,15.0166,0,0,0-15,14.9995V77.6387a15,15,0,0,0,30,0V60.3613A15.0166,15.0166,0,0,0,172.58,45.3618Zm7,32.2769a7,7,0,0,1-14,0V60.3613a7,7,0,0,1,14,0Z"/> + <path d="M135.9138,53.4211a7.01,7.01,0,0,1,7.8681,6.0752.9894.9894,0,0,0,.9843.865h6.03a1.0108,1.0108,0,0,0,.9987-1.0971,15.0182,15.0182,0,0,0-15.7162-13.8837,15.2881,15.2881,0,0,0-14.2441,15.4163V77.2037A15.288,15.288,0,0,0,136.0792,92.62a15.0183,15.0183,0,0,0,15.7162-13.8842,1.0107,1.0107,0,0,0-.9987-1.0971h-6.03a.9894.9894,0,0,0-.9843.865,7.01,7.01,0,0,1-7.8679,6.0757,7.1642,7.1642,0,0,1-6.0789-7.1849V60.6057A7.1638,7.1638,0,0,1,135.9138,53.4211Z"/> + <path d="M218.7572,72.9277a12.1585,12.1585,0,0,0,7.1843-11.0771V58.1494A12.1494,12.1494,0,0,0,213.7921,46H196.835a1,1,0,0,0-1,1V91a1,1,0,0,0,1,1h6a1,1,0,0,0,1-1V74h6.6216l7.9154,17.4138a1,1,0,0,0,.91.5862h6.5911a1,1,0,0,0,.91-1.4138Zm-.8157-11.0771A4.1538,4.1538,0,0,1,213.7926,66h-9.8511V54h9.8511a4.1538,4.1538,0,0,1,4.1489,4.1494Z"/> + <path d="M260.835,46h-26a1,1,0,0,0-1,1V91a1,1,0,0,0,1,1h26a1,1,0,0,0,1-1V85a1,1,0,0,0-1-1h-19V72h13a1,1,0,0,0,1-1V65a1,1,0,0,0-1-1h-13V54h19a1,1,0,0,0,1-1V47A1,1,0,0,0,260.835,46Z"/> + <path d="M298.835,46h-6a1,1,0,0,0-1,1V69.6475a7.0066,7.0066,0,1,1-14,0V47a1,1,0,0,0-1-1h-6a1,1,0,0,0-1,1V69.6475a15.0031,15.0031,0,1,0,30,0V47A1,1,0,0,0,298.835,46Z"/> + <rect x="307.835" y="46" width="8" height="38" rx="1"/> + </g> + </g> + </g> +`, +] diff --git a/src/assets/brand/logo.js b/src/assets/brand/logo.js new file mode 100644 index 00000000..7a2d7e0b --- /dev/null +++ b/src/assets/brand/logo.js @@ -0,0 +1,32 @@ +export const logo = [ + '608 134', + ` + <title>coreui react pro</title> + <g> + <g style="fill:#00a1ff"> + <path d="M362.0177,90.1512,353.25,69.4149a.2507.2507,0,0,0-.2559-.1914H343.01a.2263.2263,0,0,0-.2559.2559V90.0233a.5657.5657,0,0,1-.64.64h-1.2163a.5652.5652,0,0,1-.64-.64V46.5028a.5655.5655,0,0,1,.64-.64H353.442a9.9792,9.9792,0,0,1,7.7437,3.2324A12.2,12.2,0,0,1,364.13,57.64a12.4389,12.4389,0,0,1-2.24,7.584,9.37,9.37,0,0,1-6.08,3.7441c-.1709.086-.2139.1915-.128.3194l8.7041,20.6084.064.2558q0,.5127-.5757.5118h-1.1523A.703.703,0,0,1,362.0177,90.1512ZM342.754,48.3593v18.496a.2259.2259,0,0,0,.2559.2559h10.3037a7.6713,7.6713,0,0,0,6.0166-2.5918,9.8807,9.8807,0,0,0,2.3037-6.8164,10.2875,10.2875,0,0,0-2.272-6.9756,7.6033,7.6033,0,0,0-6.0483-2.624H343.01A.2263.2263,0,0,0,342.754,48.3593Z"/> + <path d="M401.3263,48.1034H381.2945a.2262.2262,0,0,0-.2558.2559v18.496a.2259.2259,0,0,0,.2558.2559h13.8238a.5664.5664,0,0,1,.6406.64v.96a.5663.5663,0,0,1-.6406.6406H381.2945a.2263.2263,0,0,0-.2558.2559v18.56a.2258.2258,0,0,0,.2558.2558h20.0318a.5671.5671,0,0,1,.6406.6407v.96a.566.566,0,0,1-.6406.64H379.1827a.5653.5653,0,0,1-.64-.64V46.5028a.5656.5656,0,0,1,.64-.64h22.1436a.5664.5664,0,0,1,.6406.64v.96A.5663.5663,0,0,1,401.3263,48.1034Z"/> + <path d="M439.047,90.1512l-2.4317-8.832a.2971.2971,0,0,0-.32-.1924H419.5274a.2957.2957,0,0,0-.32.1924l-2.3681,8.7676a.6577.6577,0,0,1-.7036.5762H414.919a.5385.5385,0,0,1-.5756-.7041l12.0317-43.584a.6436.6436,0,0,1,.7041-.5117h1.6a.6442.6442,0,0,1,.7041.5117l12.16,43.584.0644.1923q0,.5127-.64.5118h-1.2163A.6428.6428,0,0,1,439.047,90.1512ZM419.9435,78.9188a.3031.3031,0,0,0,.2236.0967h15.4883a.3048.3048,0,0,0,.2236-.0967c.0645-.0635.0742-.1162.0322-.1592l-7.872-28.9287c-.043-.0849-.086-.1279-.128-.1279s-.0859.043-.1279.1279L419.9112,78.76C419.8683,78.8026,419.879,78.8553,419.9435,78.9188Z"/> + <path d="M456.6017,87.911a11.6372,11.6372,0,0,1-3.3277-8.7041V57.1913a11.4158,11.4158,0,0,1,3.36-8.5762,12.0941,12.0941,0,0,1,8.8-3.2637,12.2566,12.2566,0,0,1,8.8643,3.2315,11.3927,11.3927,0,0,1,3.36,8.6084v.64a.5663.5663,0,0,1-.6406.6407l-1.28.0634q-.6408,0-.64-.5761v-.8321a9.289,9.289,0,0,0-2.6558-6.9121,10.6734,10.6734,0,0,0-14.0161,0,9.2854,9.2854,0,0,0-2.6563,6.9121V79.3993a9.2808,9.2808,0,0,0,2.6563,6.9121,10.67,10.67,0,0,0,14.0161,0,9.2843,9.2843,0,0,0,2.6558-6.9121v-.7686q0-.5757.64-.5752l1.28.0635a.5667.5667,0,0,1,.6406.6406v.5118a11.4952,11.4952,0,0,1-3.36,8.64,13.6227,13.6227,0,0,1-17.6963,0Z"/> + <path d="M514.4376,46.5028v.96a.5658.5658,0,0,1-.64.6406H503.046a.2263.2263,0,0,0-.2559.2559v41.664a.566.566,0,0,1-.6406.64h-1.2158a.5652.5652,0,0,1-.64-.64V48.3593a.2266.2266,0,0,0-.2558-.2559H489.8619a.5656.5656,0,0,1-.64-.6406v-.96a.5656.5656,0,0,1,.64-.64H513.798A.5658.5658,0,0,1,514.4376,46.5028Z"/> + <path d="M522.0665,89.5116a2.8385,2.8385,0,0,1-.8-2.0488,2.9194,2.9194,0,0,1,.8-2.1114,2.7544,2.7544,0,0,1,2.08-.832,2.8465,2.8465,0,0,1,2.9438,2.9434,2.7541,2.7541,0,0,1-.832,2.08,2.9221,2.9221,0,0,1-2.1118.8008A2.754,2.754,0,0,1,522.0665,89.5116Z"/> + <path d="M542.4054,88.0077a11.3123,11.3123,0,0,1-3.2-8.416v-5.44a.5656.5656,0,0,1,.64-.64h1.2158a.5661.5661,0,0,1,.64.64v5.5039a9.1424,9.1424,0,0,0,2.5283,6.72,8.9745,8.9745,0,0,0,6.6875,2.5605,8.7908,8.7908,0,0,0,9.28-9.28V46.5028a.5655.5655,0,0,1,.64-.64h1.2163a.566.566,0,0,1,.64.64V79.5917a11.2545,11.2545,0,0,1-3.2325,8.416,13.0618,13.0618,0,0,1-17.0556,0Z"/> + <path d="M580.35,88.1034a10.4859,10.4859,0,0,1-3.36-8.1279v-1.792a.5663.5663,0,0,1,.64-.6407h1.0884a.5668.5668,0,0,1,.64.6407v1.6a8.5459,8.5459,0,0,0,2.752,6.6562,10.5353,10.5353,0,0,0,7.36,2.4961,9.8719,9.8719,0,0,0,6.9761-2.3681,8.2161,8.2161,0,0,0,2.56-6.336,8.4,8.4,0,0,0-1.12-4.416,11.3812,11.3812,0,0,0-3.3281-3.3926,71.6714,71.6714,0,0,0-6.1763-3.7119,71.0479,71.0479,0,0,1-6.24-3.84,12.1711,12.1711,0,0,1-3.4238-3.68,10.2614,10.2614,0,0,1-1.28-5.3438,9.8579,9.8579,0,0,1,3.0718-7.7441,12.0122,12.0122,0,0,1,8.32-2.752q5.6954,0,8.96,3.1036a10.8251,10.8251,0,0,1,3.2642,8.2246v1.6a.5658.5658,0,0,1-.64.64h-1.1519a.5652.5652,0,0,1-.64-.64V56.8075a8.8647,8.8647,0,0,0-2.624-6.6885,9.9933,9.9933,0,0,0-7.232-2.5273,9.37,9.37,0,0,0-6.5278,2.1435,7.8224,7.8224,0,0,0-2.3682,6.1123,7.8006,7.8006,0,0,0,1.0244,4.16,10.387,10.387,0,0,0,3.0078,3.0391,62.8714,62.8714,0,0,0,5.9522,3.4882,71.0575,71.0575,0,0,1,6.72,4.2559,13.4674,13.4674,0,0,1,3.648,3.9365,10.049,10.049,0,0,1,1.28,5.1836,10.7177,10.7177,0,0,1-3.2637,8.1924q-3.2637,3.0717-8.832,3.0723Q583.71,91.1757,580.35,88.1034Z"/> + </g> + <g style="fill:#3c4b64"> + <g> + <path d="M99.835,36.0577l-39-22.5167a12,12,0,0,0-12,0l-39,22.5166a12.0339,12.0339,0,0,0-6,10.3924V91.4833a12.0333,12.0333,0,0,0,6,10.3923l39,22.5167a12,12,0,0,0,12,0l39-22.5167a12.0331,12.0331,0,0,0,6-10.3923V46.45A12.0334,12.0334,0,0,0,99.835,36.0577Zm-2,55.4256a4,4,0,0,1-2,3.4641l-39,22.5167a4.0006,4.0006,0,0,1-4,0l-39-22.5167a4,4,0,0,1-2-3.4641V46.45a4,4,0,0,1,2-3.4642l39-22.5166a4,4,0,0,1,4,0l39,22.5166a4,4,0,0,1,2,3.4642Z"/> + <path d="M77.8567,82.0046h-2.866a4,4,0,0,0-1.9247.4934L55.7852,91.9833,35.835,80.4648V57.4872l19.95-11.5185,17.2893,9.4549a3.9993,3.9993,0,0,0,1.9192.4906h2.8632a2,2,0,0,0,2-2V51.2024a2,2,0,0,0-1.04-1.7547L59.628,38.9521a8.0391,8.0391,0,0,0-7.8428.09L31.8346,50.56a8.0246,8.0246,0,0,0-4,6.9287v22.976a8,8,0,0,0,4,6.9283l19.95,11.5186a8.0429,8.0429,0,0,0,7.8433.0879l19.19-10.5312a2,2,0,0,0,1.0378-1.7533v-2.71A2,2,0,0,0,77.8567,82.0046Z"/> + </g> + <g> + <path d="M172.58,45.3618a15.0166,15.0166,0,0,0-15,14.9995V77.6387a15,15,0,0,0,30,0V60.3613A15.0166,15.0166,0,0,0,172.58,45.3618Zm7,32.2769a7,7,0,0,1-14,0V60.3613a7,7,0,0,1,14,0Z"/> + <path d="M135.9138,53.4211a7.01,7.01,0,0,1,7.8681,6.0752.9894.9894,0,0,0,.9843.865h6.03a1.0108,1.0108,0,0,0,.9987-1.0971,15.0182,15.0182,0,0,0-15.7162-13.8837,15.2881,15.2881,0,0,0-14.2441,15.4163V77.2037A15.288,15.288,0,0,0,136.0792,92.62a15.0183,15.0183,0,0,0,15.7162-13.8842,1.0107,1.0107,0,0,0-.9987-1.0971h-6.03a.9894.9894,0,0,0-.9843.865,7.01,7.01,0,0,1-7.8679,6.0757,7.1642,7.1642,0,0,1-6.0789-7.1849V60.6057A7.1638,7.1638,0,0,1,135.9138,53.4211Z"/> + <path d="M218.7572,72.9277a12.1585,12.1585,0,0,0,7.1843-11.0771V58.1494A12.1494,12.1494,0,0,0,213.7921,46H196.835a1,1,0,0,0-1,1V91a1,1,0,0,0,1,1h6a1,1,0,0,0,1-1V74h6.6216l7.9154,17.4138a1,1,0,0,0,.91.5862h6.5911a1,1,0,0,0,.91-1.4138Zm-.8157-11.0771A4.1538,4.1538,0,0,1,213.7926,66h-9.8511V54h9.8511a4.1538,4.1538,0,0,1,4.1489,4.1494Z"/> + <path d="M260.835,46h-26a1,1,0,0,0-1,1V91a1,1,0,0,0,1,1h26a1,1,0,0,0,1-1V85a1,1,0,0,0-1-1h-19V72h13a1,1,0,0,0,1-1V65a1,1,0,0,0-1-1h-13V54h19a1,1,0,0,0,1-1V47A1,1,0,0,0,260.835,46Z"/> + <path d="M298.835,46h-6a1,1,0,0,0-1,1V69.6475a7.0066,7.0066,0,1,1-14,0V47a1,1,0,0,0-1-1h-6a1,1,0,0,0-1,1V69.6475a15.0031,15.0031,0,1,0,30,0V47A1,1,0,0,0,298.835,46Z"/> + <rect x="307.835" y="46" width="8" height="38" rx="1"/> + </g> + </g> + </g> +`, +] diff --git a/src/assets/brand/sygnet.js b/src/assets/brand/sygnet.js new file mode 100644 index 00000000..3a57fbdd --- /dev/null +++ b/src/assets/brand/sygnet.js @@ -0,0 +1,12 @@ +export const sygnet = [ + '160 160', + ` + <title>coreui logo</title> + <g> + <g style="fill:#fff;"> + <path d="M125,47.091,86,24.5743a12,12,0,0,0-12,0L35,47.091a12.0336,12.0336,0,0,0-6,10.3923v45.0334a12.0335,12.0335,0,0,0,6,10.3923l39,22.5166a11.9993,11.9993,0,0,0,12,0l39-22.5166a12.0335,12.0335,0,0,0,6-10.3923V57.4833A12.0336,12.0336,0,0,0,125,47.091Zm-2,55.4257a4,4,0,0,1-2,3.464L82,128.4974a4,4,0,0,1-4,0L39,105.9807a4,4,0,0,1-2-3.464V57.4833a4,4,0,0,1,2-3.4641L78,31.5025a4,4,0,0,1,4,0l39,22.5167a4,4,0,0,1,2,3.4641Z"/> + <path d="M103.0216,93.0379h-2.866a4,4,0,0,0-1.9246.4935L80.95,103.0167,61,91.4981V68.5206L80.95,57.002l17.2894,9.455a4,4,0,0,0,1.9192.4905h2.8632a2,2,0,0,0,2-2V62.2357a2,2,0,0,0-1.04-1.7547L84.793,49.9854a8.0391,8.0391,0,0,0-7.8428.09L57,61.5929A8.0243,8.0243,0,0,0,53,68.5216v22.976a8,8,0,0,0,4,6.9283l19.95,11.5185a8.0422,8.0422,0,0,0,7.8433.0879l19.19-10.5311a2,2,0,0,0,1.0378-1.7534v-2.71A2,2,0,0,0,103.0216,93.0379Z"/> + </g> + </g> +`, +] diff --git a/packages/docs/content/assets/images/angular.jpg b/src/assets/images/angular.jpg similarity index 100% rename from packages/docs/content/assets/images/angular.jpg rename to src/assets/images/angular.jpg diff --git a/packages/docs/content/assets/images/avatars/1.jpg b/src/assets/images/avatars/1.jpg similarity index 100% rename from packages/docs/content/assets/images/avatars/1.jpg rename to src/assets/images/avatars/1.jpg diff --git a/packages/docs/content/assets/images/avatars/2.jpg b/src/assets/images/avatars/2.jpg similarity index 100% rename from packages/docs/content/assets/images/avatars/2.jpg rename to src/assets/images/avatars/2.jpg diff --git a/packages/docs/content/assets/images/avatars/3.jpg b/src/assets/images/avatars/3.jpg similarity index 100% rename from packages/docs/content/assets/images/avatars/3.jpg rename to src/assets/images/avatars/3.jpg diff --git a/packages/docs/content/assets/images/avatars/4.jpg b/src/assets/images/avatars/4.jpg similarity index 100% rename from packages/docs/content/assets/images/avatars/4.jpg rename to src/assets/images/avatars/4.jpg diff --git a/packages/docs/content/assets/images/avatars/5.jpg b/src/assets/images/avatars/5.jpg similarity index 100% rename from packages/docs/content/assets/images/avatars/5.jpg rename to src/assets/images/avatars/5.jpg diff --git a/packages/docs/content/assets/images/avatars/6.jpg b/src/assets/images/avatars/6.jpg similarity index 100% rename from packages/docs/content/assets/images/avatars/6.jpg rename to src/assets/images/avatars/6.jpg diff --git a/packages/docs/content/assets/images/avatars/7.jpg b/src/assets/images/avatars/7.jpg similarity index 100% rename from packages/docs/content/assets/images/avatars/7.jpg rename to src/assets/images/avatars/7.jpg diff --git a/packages/docs/content/assets/images/avatars/8.jpg b/src/assets/images/avatars/8.jpg similarity index 100% rename from packages/docs/content/assets/images/avatars/8.jpg rename to src/assets/images/avatars/8.jpg diff --git a/packages/docs/content/assets/images/avatars/9.jpg b/src/assets/images/avatars/9.jpg similarity index 100% rename from packages/docs/content/assets/images/avatars/9.jpg rename to src/assets/images/avatars/9.jpg diff --git a/packages/docs/content/assets/images/react.jpg b/src/assets/images/react.jpg similarity index 100% rename from packages/docs/content/assets/images/react.jpg rename to src/assets/images/react.jpg diff --git a/packages/docs/content/assets/images/vue.jpg b/src/assets/images/vue.jpg similarity index 100% rename from packages/docs/content/assets/images/vue.jpg rename to src/assets/images/vue.jpg diff --git a/src/components/AppBreadcrumb.js b/src/components/AppBreadcrumb.js new file mode 100644 index 00000000..35be72c3 --- /dev/null +++ b/src/components/AppBreadcrumb.js @@ -0,0 +1,51 @@ +import React from 'react' +import { useLocation } from 'react-router-dom' + +import routes from '../routes' + +import { CBreadcrumb, CBreadcrumbItem } from '@coreui/react' + +const AppBreadcrumb = () => { + const currentLocation = useLocation().pathname + + const getRouteName = (pathname, routes) => { + const currentRoute = routes.find((route) => route.path === pathname) + return currentRoute ? currentRoute.name : false + } + + const getBreadcrumbs = (location) => { + const breadcrumbs = [] + location.split('/').reduce((prev, curr, index, array) => { + const currentPathname = `${prev}/${curr}` + const routeName = getRouteName(currentPathname, routes) + routeName && + breadcrumbs.push({ + pathname: currentPathname, + name: routeName, + active: index + 1 === array.length ? true : false, + }) + return currentPathname + }) + return breadcrumbs + } + + const breadcrumbs = getBreadcrumbs(currentLocation) + + return ( + <CBreadcrumb className="m-0 ms-2"> + <CBreadcrumbItem href="/">Home</CBreadcrumbItem> + {breadcrumbs.map((breadcrumb, index) => { + return ( + <CBreadcrumbItem + {...(breadcrumb.active ? { active: true } : { href: breadcrumb.pathname })} + key={index} + > + {breadcrumb.name} + </CBreadcrumbItem> + ) + })} + </CBreadcrumb> + ) +} + +export default React.memo(AppBreadcrumb) diff --git a/src/components/AppContent.js b/src/components/AppContent.js new file mode 100644 index 00000000..7a03fe58 --- /dev/null +++ b/src/components/AppContent.js @@ -0,0 +1,33 @@ +import React, { Suspense } from 'react' +import { Navigate, Route, Routes } from 'react-router-dom' +import { CContainer, CSpinner } from '@coreui/react' + +// routes config +import routes from '../routes' + +const AppContent = () => { + return ( + <CContainer lg> + <Suspense fallback={<CSpinner color="primary" />}> + <Routes> + {routes.map((route, idx) => { + return ( + route.element && ( + <Route + key={idx} + path={route.path} + exact={route.exact} + name={route.name} + element={<route.element />} + /> + ) + ) + })} + <Route path="/" element={<Navigate to="dashboard" replace />} /> + </Routes> + </Suspense> + </CContainer> + ) +} + +export default React.memo(AppContent) diff --git a/src/components/AppFooter.js b/src/components/AppFooter.js new file mode 100644 index 00000000..c853f5b8 --- /dev/null +++ b/src/components/AppFooter.js @@ -0,0 +1,23 @@ +import React from 'react' +import { CFooter } from '@coreui/react' + +const AppFooter = () => { + return ( + <CFooter> + <div> + <a href="https://coreui.io" target="_blank" rel="noopener noreferrer"> + CoreUI + </a> + <span className="ms-1">© 2023 creativeLabs.</span> + </div> + <div className="ms-auto"> + <span className="me-1">Powered by</span> + <a href="https://coreui.io/react" target="_blank" rel="noopener noreferrer"> + CoreUI React Admin & Dashboard Template + </a> + </div> + </CFooter> + ) +} + +export default React.memo(AppFooter) diff --git a/src/components/AppHeader.js b/src/components/AppHeader.js new file mode 100644 index 00000000..dd5f544e --- /dev/null +++ b/src/components/AppHeader.js @@ -0,0 +1,79 @@ +import React from 'react' +import { NavLink } from 'react-router-dom' +import { useSelector, useDispatch } from 'react-redux' +import { + CContainer, + CHeader, + CHeaderBrand, + CHeaderDivider, + CHeaderNav, + CHeaderToggler, + CNavLink, + CNavItem, +} from '@coreui/react' +import CIcon from '@coreui/icons-react' +import { cilBell, cilEnvelopeOpen, cilList, cilMenu } from '@coreui/icons' + +import { AppBreadcrumb } from './index' +import { AppHeaderDropdown } from './header/index' +import { logo } from 'src/assets/brand/logo' + +const AppHeader = () => { + const dispatch = useDispatch() + const sidebarShow = useSelector((state) => state.sidebarShow) + + return ( + <CHeader position="sticky" className="mb-4"> + <CContainer fluid> + <CHeaderToggler + className="ps-1" + onClick={() => dispatch({ type: 'set', sidebarShow: !sidebarShow })} + > + <CIcon icon={cilMenu} size="lg" /> + </CHeaderToggler> + <CHeaderBrand className="mx-auto d-md-none" to="/"> + <CIcon icon={logo} height={48} alt="Logo" /> + </CHeaderBrand> + <CHeaderNav className="d-none d-md-flex me-auto"> + <CNavItem> + <CNavLink to="/dashboard" component={NavLink}> + Dashboard + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Users</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Settings</CNavLink> + </CNavItem> + </CHeaderNav> + <CHeaderNav> + <CNavItem> + <CNavLink href="#"> + <CIcon icon={cilBell} size="lg" /> + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#"> + <CIcon icon={cilList} size="lg" /> + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#"> + <CIcon icon={cilEnvelopeOpen} size="lg" /> + </CNavLink> + </CNavItem> + </CHeaderNav> + <CHeaderNav className="ms-3"> + <AppHeaderDropdown /> + </CHeaderNav> + </CContainer> + <CHeaderDivider /> + <CContainer fluid> + <AppBreadcrumb /> + </CContainer> + </CHeader> + ) +} + +export default AppHeader diff --git a/src/components/AppSidebar.js b/src/components/AppSidebar.js new file mode 100644 index 00000000..a75bf652 --- /dev/null +++ b/src/components/AppSidebar.js @@ -0,0 +1,49 @@ +import React from 'react' +import { useSelector, useDispatch } from 'react-redux' + +import { CSidebar, CSidebarBrand, CSidebarNav, CSidebarToggler } from '@coreui/react' +import CIcon from '@coreui/icons-react' + +import { AppSidebarNav } from './AppSidebarNav' + +import { logoNegative } from 'src/assets/brand/logo-negative' +import { sygnet } from 'src/assets/brand/sygnet' + +import SimpleBar from 'simplebar-react' +import 'simplebar/dist/simplebar.min.css' + +// sidebar nav config +import navigation from '../_nav' + +const AppSidebar = () => { + const dispatch = useDispatch() + const unfoldable = useSelector((state) => state.sidebarUnfoldable) + const sidebarShow = useSelector((state) => state.sidebarShow) + + return ( + <CSidebar + position="fixed" + unfoldable={unfoldable} + visible={sidebarShow} + onVisibleChange={(visible) => { + dispatch({ type: 'set', sidebarShow: visible }) + }} + > + <CSidebarBrand className="d-none d-md-flex" to="/"> + <CIcon className="sidebar-brand-full" icon={logoNegative} height={35} /> + <CIcon className="sidebar-brand-narrow" icon={sygnet} height={35} /> + </CSidebarBrand> + <CSidebarNav> + <SimpleBar> + <AppSidebarNav items={navigation} /> + </SimpleBar> + </CSidebarNav> + <CSidebarToggler + className="d-none d-lg-flex" + onClick={() => dispatch({ type: 'set', sidebarUnfoldable: !unfoldable })} + /> + </CSidebar> + ) +} + +export default React.memo(AppSidebar) diff --git a/src/components/AppSidebarNav.js b/src/components/AppSidebarNav.js new file mode 100644 index 00000000..2063d9e7 --- /dev/null +++ b/src/components/AppSidebarNav.js @@ -0,0 +1,67 @@ +import React from 'react' +import { NavLink, useLocation } from 'react-router-dom' +import PropTypes from 'prop-types' + +import { CBadge } from '@coreui/react' + +export const AppSidebarNav = ({ items }) => { + const location = useLocation() + const navLink = (name, icon, badge) => { + return ( + <> + {icon && icon} + {name && name} + {badge && ( + <CBadge color={badge.color} className="ms-auto"> + {badge.text} + </CBadge> + )} + </> + ) + } + + const navItem = (item, index) => { + const { component, name, badge, icon, ...rest } = item + const Component = component + return ( + <Component + {...(rest.to && + !rest.items && { + component: NavLink, + })} + key={index} + {...rest} + > + {navLink(name, icon, badge)} + </Component> + ) + } + const navGroup = (item, index) => { + const { component, name, icon, to, ...rest } = item + const Component = component + return ( + <Component + idx={String(index)} + key={index} + toggler={navLink(name, icon)} + visible={location.pathname.startsWith(to)} + {...rest} + > + {item.items?.map((item, index) => + item.items ? navGroup(item, index) : navItem(item, index), + )} + </Component> + ) + } + + return ( + <React.Fragment> + {items && + items.map((item, index) => (item.items ? navGroup(item, index) : navItem(item, index)))} + </React.Fragment> + ) +} + +AppSidebarNav.propTypes = { + items: PropTypes.arrayOf(PropTypes.any).isRequired, +} diff --git a/src/components/DocsCallout.js b/src/components/DocsCallout.js new file mode 100644 index 00000000..926ebfc4 --- /dev/null +++ b/src/components/DocsCallout.js @@ -0,0 +1,38 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { CCallout, CLink } from '@coreui/react' + +const DocsCallout = (props) => { + const { content, href, name } = props + + const plural = name.slice(-1) === 's' ? true : false + + const _href = `https://coreui.io/react/docs/${href}` + + return ( + <CCallout color="info" className="bg-white"> + {content + ? content + : `A React ${name} component ${ + plural ? 'have' : 'has' + } been created as a native React.js version + of Bootstrap ${name}. ${name} ${plural ? 'are' : 'is'} delivered with some new features, + variants, and unique design that matches CoreUI Design System requirements.`} + <br /> + <br /> + For more information please visit our official{' '} + <CLink href={_href} target="_blank"> + documentation of CoreUI Components Library for React.js + </CLink> + . + </CCallout> + ) +} + +DocsCallout.propTypes = { + content: PropTypes.string, + href: PropTypes.string, + name: PropTypes.string, +} + +export default React.memo(DocsCallout) diff --git a/src/components/DocsExample.js b/src/components/DocsExample.js new file mode 100644 index 00000000..3340cbc8 --- /dev/null +++ b/src/components/DocsExample.js @@ -0,0 +1,42 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { CNav, CNavItem, CNavLink, CTabContent, CTabPane } from '@coreui/react' +import CIcon from '@coreui/icons-react' +import { cilCode, cilMediaPlay } from '@coreui/icons' + +const DocsExample = (props) => { + const { children, href } = props + + const _href = `https://coreui.io/react/docs/${href}` + + return ( + <div className="example"> + <CNav variant="tabs"> + <CNavItem> + <CNavLink href="#" active> + <CIcon icon={cilMediaPlay} className="me-2" /> + Preview + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href={_href} target="_blank"> + <CIcon icon={cilCode} className="me-2" /> + Code + </CNavLink> + </CNavItem> + </CNav> + <CTabContent className="rounded-bottom"> + <CTabPane className="p-3 preview" visible> + {children} + </CTabPane> + </CTabContent> + </div> + ) +} + +DocsExample.propTypes = { + children: PropTypes.node, + href: PropTypes.string, +} + +export default React.memo(DocsExample) diff --git a/src/components/DocsLink.js b/src/components/DocsLink.js new file mode 100644 index 00000000..b5cdb97e --- /dev/null +++ b/src/components/DocsLink.js @@ -0,0 +1,31 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { CLink } from '@coreui/react' + +const DocsLink = (props) => { + const { href, name, text, ...rest } = props + + const _href = name ? `https://coreui.io/react/docs/components/${name}` : href + + return ( + <div className="float-end"> + <CLink + {...rest} + href={_href} + rel="noreferrer noopener" + target="_blank" + className="card-header-action" + > + <small className="text-medium-emphasis">{text || 'docs'}</small> + </CLink> + </div> + ) +} + +DocsLink.propTypes = { + href: PropTypes.string, + name: PropTypes.string, + text: PropTypes.string, +} + +export default React.memo(DocsLink) diff --git a/src/components/header/AppHeaderDropdown.js b/src/components/header/AppHeaderDropdown.js new file mode 100644 index 00000000..5be919ee --- /dev/null +++ b/src/components/header/AppHeaderDropdown.js @@ -0,0 +1,96 @@ +import React from 'react' +import { + CAvatar, + CBadge, + CDropdown, + CDropdownDivider, + CDropdownHeader, + CDropdownItem, + CDropdownMenu, + CDropdownToggle, +} from '@coreui/react' +import { + cilBell, + cilCreditCard, + cilCommentSquare, + cilEnvelopeOpen, + cilFile, + cilLockLocked, + cilSettings, + cilTask, + cilUser, +} from '@coreui/icons' +import CIcon from '@coreui/icons-react' + +import avatar8 from './../../assets/images/avatars/8.jpg' + +const AppHeaderDropdown = () => { + return ( + <CDropdown variant="nav-item"> + <CDropdownToggle placement="bottom-end" className="py-0" caret={false}> + <CAvatar src={avatar8} size="md" /> + </CDropdownToggle> + <CDropdownMenu className="pt-0" placement="bottom-end"> + <CDropdownHeader className="bg-light fw-semibold py-2">Account</CDropdownHeader> + <CDropdownItem href="#"> + <CIcon icon={cilBell} className="me-2" /> + Updates + <CBadge color="info" className="ms-2"> + 42 + </CBadge> + </CDropdownItem> + <CDropdownItem href="#"> + <CIcon icon={cilEnvelopeOpen} className="me-2" /> + Messages + <CBadge color="success" className="ms-2"> + 42 + </CBadge> + </CDropdownItem> + <CDropdownItem href="#"> + <CIcon icon={cilTask} className="me-2" /> + Tasks + <CBadge color="danger" className="ms-2"> + 42 + </CBadge> + </CDropdownItem> + <CDropdownItem href="#"> + <CIcon icon={cilCommentSquare} className="me-2" /> + Comments + <CBadge color="warning" className="ms-2"> + 42 + </CBadge> + </CDropdownItem> + <CDropdownHeader className="bg-light fw-semibold py-2">Settings</CDropdownHeader> + <CDropdownItem href="#"> + <CIcon icon={cilUser} className="me-2" /> + Profile + </CDropdownItem> + <CDropdownItem href="#"> + <CIcon icon={cilSettings} className="me-2" /> + Settings + </CDropdownItem> + <CDropdownItem href="#"> + <CIcon icon={cilCreditCard} className="me-2" /> + Payments + <CBadge color="secondary" className="ms-2"> + 42 + </CBadge> + </CDropdownItem> + <CDropdownItem href="#"> + <CIcon icon={cilFile} className="me-2" /> + Projects + <CBadge color="primary" className="ms-2"> + 42 + </CBadge> + </CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#"> + <CIcon icon={cilLockLocked} className="me-2" /> + Lock Account + </CDropdownItem> + </CDropdownMenu> + </CDropdown> + ) +} + +export default AppHeaderDropdown diff --git a/src/components/header/index.js b/src/components/header/index.js new file mode 100644 index 00000000..bf8af6c1 --- /dev/null +++ b/src/components/header/index.js @@ -0,0 +1,3 @@ +import AppHeaderDropdown from './AppHeaderDropdown' + +export { AppHeaderDropdown } diff --git a/src/components/index.js b/src/components/index.js new file mode 100644 index 00000000..6cdf3356 --- /dev/null +++ b/src/components/index.js @@ -0,0 +1,21 @@ +import AppBreadcrumb from './AppBreadcrumb' +import AppContent from './AppContent' +import AppFooter from './AppFooter' +import AppHeader from './AppHeader' +import AppHeaderDropdown from './header/AppHeaderDropdown' +import AppSidebar from './AppSidebar' +import DocsCallout from './DocsCallout' +import DocsLink from './DocsLink' +import DocsExample from './DocsExample' + +export { + AppBreadcrumb, + AppContent, + AppFooter, + AppHeader, + AppHeaderDropdown, + AppSidebar, + DocsCallout, + DocsLink, + DocsExample, +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 00000000..d19a3bcd --- /dev/null +++ b/src/index.js @@ -0,0 +1,19 @@ +import 'react-app-polyfill/stable' +import 'core-js' +import React from 'react' +import { createRoot } from 'react-dom/client' +import App from './App' +import reportWebVitals from './reportWebVitals' +import { Provider } from 'react-redux' +import store from './store' + +createRoot(document.getElementById('root')).render( + <Provider store={store}> + <App /> + </Provider>, +) + +// If you want to start measuring performance in your app, pass a function +// to log results (for example: reportWebVitals(console.log)) +// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals +reportWebVitals() diff --git a/src/layout/DefaultLayout.js b/src/layout/DefaultLayout.js new file mode 100644 index 00000000..43bd6443 --- /dev/null +++ b/src/layout/DefaultLayout.js @@ -0,0 +1,19 @@ +import React from 'react' +import { AppContent, AppSidebar, AppFooter, AppHeader } from '../components/index' + +const DefaultLayout = () => { + return ( + <div> + <AppSidebar /> + <div className="wrapper d-flex flex-column min-vh-100 bg-light"> + <AppHeader /> + <div className="body flex-grow-1 px-3"> + <AppContent /> + </div> + <AppFooter /> + </div> + </div> + ) +} + +export default DefaultLayout diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js new file mode 100644 index 00000000..dc6ff078 --- /dev/null +++ b/src/reportWebVitals.js @@ -0,0 +1,13 @@ +const reportWebVitals = (onPerfEntry) => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry) + getFID(onPerfEntry) + getFCP(onPerfEntry) + getLCP(onPerfEntry) + getTTFB(onPerfEntry) + }) + } +} + +export default reportWebVitals diff --git a/src/routes.js b/src/routes.js new file mode 100644 index 00000000..d168b1ca --- /dev/null +++ b/src/routes.js @@ -0,0 +1,100 @@ +import React from 'react' + +const Dashboard = React.lazy(() => import('./views/dashboard/Dashboard')) +const Colors = React.lazy(() => import('./views/theme/colors/Colors')) +const Typography = React.lazy(() => import('./views/theme/typography/Typography')) + +// Base +const Accordion = React.lazy(() => import('./views/base/accordion/Accordion')) +const Breadcrumbs = React.lazy(() => import('./views/base/breadcrumbs/Breadcrumbs')) +const Cards = React.lazy(() => import('./views/base/cards/Cards')) +const Carousels = React.lazy(() => import('./views/base/carousels/Carousels')) +const Collapses = React.lazy(() => import('./views/base/collapses/Collapses')) +const ListGroups = React.lazy(() => import('./views/base/list-groups/ListGroups')) +const Navs = React.lazy(() => import('./views/base/navs/Navs')) +const Paginations = React.lazy(() => import('./views/base/paginations/Paginations')) +const Placeholders = React.lazy(() => import('./views/base/placeholders/Placeholders')) +const Popovers = React.lazy(() => import('./views/base/popovers/Popovers')) +const Progress = React.lazy(() => import('./views/base/progress/Progress')) +const Spinners = React.lazy(() => import('./views/base/spinners/Spinners')) +const Tables = React.lazy(() => import('./views/base/tables/Tables')) +const Tooltips = React.lazy(() => import('./views/base/tooltips/Tooltips')) + +// Buttons +const Buttons = React.lazy(() => import('./views/buttons/buttons/Buttons')) +const ButtonGroups = React.lazy(() => import('./views/buttons/button-groups/ButtonGroups')) +const Dropdowns = React.lazy(() => import('./views/buttons/dropdowns/Dropdowns')) + +//Forms +const ChecksRadios = React.lazy(() => import('./views/forms/checks-radios/ChecksRadios')) +const FloatingLabels = React.lazy(() => import('./views/forms/floating-labels/FloatingLabels')) +const FormControl = React.lazy(() => import('./views/forms/form-control/FormControl')) +const InputGroup = React.lazy(() => import('./views/forms/input-group/InputGroup')) +const Layout = React.lazy(() => import('./views/forms/layout/Layout')) +const Range = React.lazy(() => import('./views/forms/range/Range')) +const Select = React.lazy(() => import('./views/forms/select/Select')) +const Validation = React.lazy(() => import('./views/forms/validation/Validation')) + +const Charts = React.lazy(() => import('./views/charts/Charts')) + +// Icons +const CoreUIIcons = React.lazy(() => import('./views/icons/coreui-icons/CoreUIIcons')) +const Flags = React.lazy(() => import('./views/icons/flags/Flags')) +const Brands = React.lazy(() => import('./views/icons/brands/Brands')) + +// Notifications +const Alerts = React.lazy(() => import('./views/notifications/alerts/Alerts')) +const Badges = React.lazy(() => import('./views/notifications/badges/Badges')) +const Modals = React.lazy(() => import('./views/notifications/modals/Modals')) +const Toasts = React.lazy(() => import('./views/notifications/toasts/Toasts')) + +const Widgets = React.lazy(() => import('./views/widgets/Widgets')) + +const routes = [ + { path: '/', exact: true, name: 'Home' }, + { path: '/dashboard', name: 'Dashboard', element: Dashboard }, + { path: '/theme', name: 'Theme', element: Colors, exact: true }, + { path: '/theme/colors', name: 'Colors', element: Colors }, + { path: '/theme/typography', name: 'Typography', element: Typography }, + { path: '/base', name: 'Base', element: Cards, exact: true }, + { path: '/base/accordion', name: 'Accordion', element: Accordion }, + { path: '/base/breadcrumbs', name: 'Breadcrumbs', element: Breadcrumbs }, + { path: '/base/cards', name: 'Cards', element: Cards }, + { path: '/base/carousels', name: 'Carousel', element: Carousels }, + { path: '/base/collapses', name: 'Collapse', element: Collapses }, + { path: '/base/list-groups', name: 'List Groups', element: ListGroups }, + { path: '/base/navs', name: 'Navs', element: Navs }, + { path: '/base/paginations', name: 'Paginations', element: Paginations }, + { path: '/base/placeholders', name: 'Placeholders', element: Placeholders }, + { path: '/base/popovers', name: 'Popovers', element: Popovers }, + { path: '/base/progress', name: 'Progress', element: Progress }, + { path: '/base/spinners', name: 'Spinners', element: Spinners }, + { path: '/base/tables', name: 'Tables', element: Tables }, + { path: '/base/tooltips', name: 'Tooltips', element: Tooltips }, + { path: '/buttons', name: 'Buttons', element: Buttons, exact: true }, + { path: '/buttons/buttons', name: 'Buttons', element: Buttons }, + { path: '/buttons/dropdowns', name: 'Dropdowns', element: Dropdowns }, + { path: '/buttons/button-groups', name: 'Button Groups', element: ButtonGroups }, + { path: '/charts', name: 'Charts', element: Charts }, + { path: '/forms', name: 'Forms', element: FormControl, exact: true }, + { path: '/forms/form-control', name: 'Form Control', element: FormControl }, + { path: '/forms/select', name: 'Select', element: Select }, + { path: '/forms/checks-radios', name: 'Checks & Radios', element: ChecksRadios }, + { path: '/forms/range', name: 'Range', element: Range }, + { path: '/forms/input-group', name: 'Input Group', element: InputGroup }, + { path: '/forms/floating-labels', name: 'Floating Labels', element: FloatingLabels }, + { path: '/forms/layout', name: 'Layout', element: Layout }, + { path: '/forms/validation', name: 'Validation', element: Validation }, + { path: '/icons', exact: true, name: 'Icons', element: CoreUIIcons }, + { path: '/icons/coreui-icons', name: 'CoreUI Icons', element: CoreUIIcons }, + { path: '/icons/flags', name: 'Flags', element: Flags }, + { path: '/icons/brands', name: 'Brands', element: Brands }, + { path: '/notifications', name: 'Notifications', element: Alerts, exact: true }, + { path: '/notifications/alerts', name: 'Alerts', element: Alerts }, + { path: '/notifications/badges', name: 'Badges', element: Badges }, + { path: '/notifications/modals', name: 'Modals', element: Modals }, + { path: '/notifications/toasts', name: 'Toasts', element: Toasts }, + { path: '/widgets', name: 'Widgets', element: Widgets }, +] + +export default routes diff --git a/src/scss/_custom.scss b/src/scss/_custom.scss new file mode 100644 index 00000000..15d367af --- /dev/null +++ b/src/scss/_custom.scss @@ -0,0 +1 @@ +// Here you can add other styles diff --git a/src/scss/_example.scss b/src/scss/_example.scss new file mode 100644 index 00000000..f8791fb2 --- /dev/null +++ b/src/scss/_example.scss @@ -0,0 +1,109 @@ +.example { + &:not(:first-child) { + margin-top: 1.5rem; + } + + .tab-content { + background-color: $light-50 !important; + + @at-root .dark-theme & { + background-color: rgba(255, 255, 255, .1) !important; + } + } + + code[class*="language-"], + pre[class*="language-"] { + font-size: .875rem !important; + } + + :not(pre) > code[class*="language-"], + pre[class*="language-"] { + background: transparent; + } + + & + p { + margin-top: 1.5rem + } + + // Components examples + .preview, + .preview .col { + + p { + margin-top: 2rem; + } + + > .form-control { + + .form-control { + margin-top: .5rem; + } + } + + > .nav + .nav, + > .alert + .alert, + > .navbar + .navbar, + > .progress + .progress { + margin-top: 1rem; + } + + > .dropdown-menu { + position: static; + display: block; + } + + > :last-child { + margin-bottom: 0; + } + + // Images + > svg + svg, + > img + img { + margin-left: .5rem; + } + + // Buttons + > .btn, + > .btn-group { + margin: .25rem .125rem; + } + > .btn-toolbar + .btn-toolbar { + margin-top: .5rem; + } + + // List groups + > .list-group { + max-width: 400px; + } + + > [class*="list-group-horizontal"] { + max-width: 100%; + } + + // Navbars + .fixed-top, + .sticky-top { + position: static; + margin: -1rem -1rem 1rem; + } + + .fixed-bottom { + position: static; + margin: 1rem -1rem -1rem; + } + + @include media-breakpoint-up(sm) { + .fixed-top, + .sticky-top { + margin: -1.5rem -1.5rem 1rem; + } + .fixed-bottom { + margin: 1rem -1.5rem -1.5rem; + } + } + + // Pagination + .pagination { + margin-top: .5rem; + margin-bottom: .5rem; + } + } +} diff --git a/packages/docs/src/styles/_layout.scss b/src/scss/_layout.scss similarity index 100% rename from packages/docs/src/styles/_layout.scss rename to src/scss/_layout.scss diff --git a/src/scss/_variables.scss b/src/scss/_variables.scss new file mode 100644 index 00000000..373dbeec --- /dev/null +++ b/src/scss/_variables.scss @@ -0,0 +1,1791 @@ +// Variables +// +// If you want to customize your project please uncomment and update one of the following variables. + +// Color system + +// scss-docs-start gray-color-variables +// $white: #fff !default; +// $gray-base: #3c4b64 !default; +// $gray-100: #ebedef !default; +// $gray-200: #d8dbe0 !default; +// $gray-300: #c4c9d0 !default; +// $gray-400: #b1b7c1 !default; +// $gray-500: #9da5b1 !default; +// $gray-600: #8a93a2 !default; +// $gray-700: #768192 !default; +// $gray-800: #636f83 !default; +// $gray-900: #4f5d73 !default; +// $black: #000015 !default; +// scss-docs-end gray-color-variables + +// fusv-disable +// scss-docs-start gray-colors-map +// $grays: ( +// "100": $gray-100, +// "200": $gray-200, +// "300": $gray-300, +// "400": $gray-400, +// "500": $gray-500, +// "600": $gray-600, +// "700": $gray-700, +// "800": $gray-800, +// "900": $gray-900 +// ) !default; +// scss-docs-end gray-colors-map +// fusv-enable + +// $high-emphasis: rgba(shift-color($gray-base, +26), .95) !default; +// $medium-emphasis: rgba(shift-color($gray-base, +26), .681) !default; +// $disabled: rgba(shift-color($gray-base, +26), .38) !default; + +// $high-emphasis-inverse: rgba($white, .87) !default; +// $medium-emphasis-inverse: rgba($white, .6) !default; +// $disabled-inverse: rgba($white, .38) !default; + +// scss-docs-start color-variables +// $blue: #0d6efd !default; +// $indigo: #6610f2 !default; +// $purple: #6f42c1 !default; +// $pink: #d63384 !default; +// $red: #dc3545 !default; +// $orange: #fd7e14 !default; +// $yellow: #ffc107 !default; +// $green: #198754 !default; +// $teal: #20c997 !default; +// $cyan: #0dcaf0 !default; +// scss-docs-end color-variables + +// scss-docs-start colors-map +// $colors: ( +// "blue": $blue, +// "indigo": $indigo, +// "purple": $purple, +// "pink": $pink, +// "red": $red, +// "orange": $orange, +// "yellow": $yellow, +// "green": $green, +// "teal": $teal, +// "cyan": $cyan, +// "white": $white, +// "gray": $gray-600, +// "gray-dark": $gray-800 +// ) !default; +// scss-docs-end colors-map + +// fusv-disable +// $primary-dark: #1f1498 !default; +// $primary-base: #321fdb !default; +// $primary-50: #988fed !default; +// $primary-25: #ccc7f6 !default; + +// $secondary-dark: #212233 !default; +// $secondary-base: #9da5b1 !default; +// $secondary-50: #9da5b1 !default; +// $secondary-25: #ced2d8 !default; + +// $success-dark: #1b9e3e !default; +// $success-base: #2eb85c !default; +// $success-50: #96dbad !default; +// $success-25: #cbedd6 !default; + +// $info-dark: #2982cc !default; +// $info-base: #39f !default; +// $info-50: #80c6ff !default; +// $info-25: #c0e6ff !default; + +// $warning-dark: #f6960b !default; +// $warning-base: #f9b115 !default; +// $warning-50: #fcd88a !default; +// $warning-25: #feecc5 !default; + +// $danger-dark: #d93737 !default; +// $danger-base: #e55353 !default; +// $danger-50: #f2a9a9 !default; +// $danger-25: #f9d4d4 !default; + +// $light-dark: $gray-100 !default; +// $light-base: $gray-100 !default; +// $light-50: shift-color($light-base, -70) !default; +// $light-25: shift-color($light-base, -80) !default; + +// $dark-dark: $gray-900 !default; +// $dark-base: $gray-900 !default; +// $dark-50: shift-color($dark-base, -70) !default; +// $dark-25: shift-color($dark-base, -80) !default; +// fusv-enable + +// scss-docs-start theme-color-variables +// $primary: $primary-base !default; +// $secondary: $secondary-base !default; +// $success: $success-base !default; +// $info: $info-base !default; +// $warning: $warning-base !default; +// $danger: $danger-base !default; +// $light: $light-base !default; +// $dark: $dark-base !default; +// scss-docs-end theme-color-variables + +// scss-docs-start theme-colors-map +// $theme-colors: ( +// "primary": $primary, +// "secondary": $secondary, +// "success": $success, +// "info": $info, +// "warning": $warning, +// "danger": $danger, +// "light": $light, +// "dark": $dark +// ) !default; +// scss-docs-end theme-colors-map + +// The contrast ratio to reach against white, to determine if color changes from "light" to "dark". Acceptable values for WCAG 2.0 are 3, 4.5 and 7. +// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast +// $min-contrast-ratio: 4.5 !default; + +// Customize the light and dark text colors for use in our color contrast function. +// $color-contrast-dark: $high-emphasis-inverse !default; +// $color-contrast-light: $high-emphasis !default; + +// fusv-disable +// $blue-100: tint-color($blue, 80%) !default; +// $blue-200: tint-color($blue, 60%) !default; +// $blue-300: tint-color($blue, 40%) !default; +// $blue-400: tint-color($blue, 20%) !default; +// $blue-500: $blue !default; +// $blue-600: shade-color($blue, 20%) !default; +// $blue-700: shade-color($blue, 40%) !default; +// $blue-800: shade-color($blue, 60%) !default; +// $blue-900: shade-color($blue, 80%) !default; + +// $indigo-100: tint-color($indigo, 80%) !default; +// $indigo-200: tint-color($indigo, 60%) !default; +// $indigo-300: tint-color($indigo, 40%) !default; +// $indigo-400: tint-color($indigo, 20%) !default; +// $indigo-500: $indigo !default; +// $indigo-600: shade-color($indigo, 20%) !default; +// $indigo-700: shade-color($indigo, 40%) !default; +// $indigo-800: shade-color($indigo, 60%) !default; +// $indigo-900: shade-color($indigo, 80%) !default; + +// $purple-100: tint-color($purple, 80%) !default; +// $purple-200: tint-color($purple, 60%) !default; +// $purple-300: tint-color($purple, 40%) !default; +// $purple-400: tint-color($purple, 20%) !default; +// $purple-500: $purple !default; +// $purple-600: shade-color($purple, 20%) !default; +// $purple-700: shade-color($purple, 40%) !default; +// $purple-800: shade-color($purple, 60%) !default; +// $purple-900: shade-color($purple, 80%) !default; + +// $pink-100: tint-color($pink, 80%) !default; +// $pink-200: tint-color($pink, 60%) !default; +// $pink-300: tint-color($pink, 40%) !default; +// $pink-400: tint-color($pink, 20%) !default; +// $pink-500: $pink !default; +// $pink-600: shade-color($pink, 20%) !default; +// $pink-700: shade-color($pink, 40%) !default; +// $pink-800: shade-color($pink, 60%) !default; +// $pink-900: shade-color($pink, 80%) !default; + +// $red-100: tint-color($red, 80%) !default; +// $red-200: tint-color($red, 60%) !default; +// $red-300: tint-color($red, 40%) !default; +// $red-400: tint-color($red, 20%) !default; +// $red-500: $red !default; +// $red-600: shade-color($red, 20%) !default; +// $red-700: shade-color($red, 40%) !default; +// $red-800: shade-color($red, 60%) !default; +// $red-900: shade-color($red, 80%) !default; + +// $orange-100: tint-color($orange, 80%) !default; +// $orange-200: tint-color($orange, 60%) !default; +// $orange-300: tint-color($orange, 40%) !default; +// $orange-400: tint-color($orange, 20%) !default; +// $orange-500: $orange !default; +// $orange-600: shade-color($orange, 20%) !default; +// $orange-700: shade-color($orange, 40%) !default; +// $orange-800: shade-color($orange, 60%) !default; +// $orange-900: shade-color($orange, 80%) !default; + +// $yellow-100: tint-color($yellow, 80%) !default; +// $yellow-200: tint-color($yellow, 60%) !default; +// $yellow-300: tint-color($yellow, 40%) !default; +// $yellow-400: tint-color($yellow, 20%) !default; +// $yellow-500: $yellow !default; +// $yellow-600: shade-color($yellow, 20%) !default; +// $yellow-700: shade-color($yellow, 40%) !default; +// $yellow-800: shade-color($yellow, 60%) !default; +// $yellow-900: shade-color($yellow, 80%) !default; + +// $green-100: tint-color($green, 80%) !default; +// $green-200: tint-color($green, 60%) !default; +// $green-300: tint-color($green, 40%) !default; +// $green-400: tint-color($green, 20%) !default; +// $green-500: $green !default; +// $green-600: shade-color($green, 20%) !default; +// $green-700: shade-color($green, 40%) !default; +// $green-800: shade-color($green, 60%) !default; +// $green-900: shade-color($green, 80%) !default; + +// $teal-100: tint-color($teal, 80%) !default; +// $teal-200: tint-color($teal, 60%) !default; +// $teal-300: tint-color($teal, 40%) !default; +// $teal-400: tint-color($teal, 20%) !default; +// $teal-500: $teal !default; +// $teal-600: shade-color($teal, 20%) !default; +// $teal-700: shade-color($teal, 40%) !default; +// $teal-800: shade-color($teal, 60%) !default; +// $teal-900: shade-color($teal, 80%) !default; + +// $cyan-100: tint-color($cyan, 80%) !default; +// $cyan-200: tint-color($cyan, 60%) !default; +// $cyan-300: tint-color($cyan, 40%) !default; +// $cyan-400: tint-color($cyan, 20%) !default; +// $cyan-500: $cyan !default; +// $cyan-600: shade-color($cyan, 20%) !default; +// $cyan-700: shade-color($cyan, 40%) !default; +// $cyan-800: shade-color($cyan, 60%) !default; +// $cyan-900: shade-color($cyan, 80%) !default; +// fusv-enable + +// Characters which are escaped by the escape-svg function +// $escaped-characters: ( +// ("<", "%3c"), +// (">", "%3e"), +// ("#", "%23"), +// ("(", "%28"), +// (")", "%29"), +// ) !default; + +// Options +// +// Quickly modify global styling by enabling or disabling optional features. + +// $enable-caret: true !default; +// $enable-rounded: true !default; +// $enable-shadows: false !default; +// $enable-gradients: false !default; +// $enable-transitions: true !default; +// $enable-reduced-motion: true !default; +// $enable-smooth-scroll: true !default; +// $enable-grid-classes: true !default; +// $enable-button-pointers: true !default; +// $enable-rfs: true !default; +// $enable-validation-icons: true !default; +// $enable-negative-margins: false !default; +// $enable-deprecation-messages: true !default; +// $enable-important-utilities: true !default; +// $enable-contrast-ratio-correction: true !default; +// $enable-contrast-ratio-warnings: false !default; +// $enable-ltr: true !default; +// $enable-rtl: false !default; + +// Set mobile breakpoint + +// $mobile-breakpoint: md !default; + +// Prefix for :root CSS variables + +// $variable-prefix: cui- !default; + +// Gradient +// +// The gradient which is added to components if `$enable-gradients` is `true` +// This gradient is also added to elements with `.bg-gradient` +// scss-docs-start variable-gradient +// $gradient: linear-gradient(180deg, rgba($white, .15), rgba($white, 0)) !default; +// scss-docs-end variable-gradient + +// Spacing +// +// Control the default styling of most Bootstrap elements by modifying these +// variables. Mostly focused on spacing. +// You can add more entries to the $spacers map, should you need more variation. + +// scss-docs-start spacer-variables-maps +// $spacer: 1rem !default; +// $spacers: ( +// 0: 0, +// 1: $spacer / 4, +// 2: $spacer / 2, +// 3: $spacer, +// 4: $spacer * 1.5, +// 5: $spacer * 3, +// ) !default; + +// $negative-spacers: if($enable-negative-margins, negativify-map($spacers), null) !default; +// scss-docs-end spacer-variables-maps + +// Position +// +// Define the edge positioning anchors of the position utilities. + +// scss-docs-start position-map +// $position-values: ( +// 0: 0, +// 50: 50%, +// 100: 100% +// ) !default; +// scss-docs-end position-map + +// Body +// +// Settings for the `<body>` element. + +// $body-bg: $white !default; +// $body-color: $high-emphasis !default; +// $body-text-align: null !default; + + +// Links +// +// Style anchor elements. + +// $link-color: $primary !default; +// $link-decoration: underline !default; +// $link-shade-percentage: 20% !default; +// $link-hover-color: shift-color($link-color, $link-shade-percentage) !default; +// $link-hover-decoration: null !default; + +// $stretched-link-pseudo-element: after !default; +// $stretched-link-z-index: 1 !default; + +// Paragraphs +// +// Style p element. + +// $paragraph-margin-bottom: 1rem !default; + + +// Grid breakpoints +// +// Define the minimum dimensions at which your layout will change, +// adapting to different screen sizes, for use in media queries. + +// scss-docs-start grid-breakpoints +// $grid-breakpoints: ( +// xs: 0, +// sm: 576px, +// md: 768px, +// lg: 992px, +// xl: 1200px, +// xxl: 1400px +// ) !default; +// scss-docs-end grid-breakpoints + +// @include _assert-ascending($grid-breakpoints, "$grid-breakpoints"); +// @include _assert-starts-at-zero($grid-breakpoints, "$grid-breakpoints"); + + +// Grid containers +// +// Define the maximum width of `.container` for different screen sizes. + +// scss-docs-start container-max-widths +// $container-max-widths: ( +// sm: 540px, +// md: 720px, +// lg: 960px, +// xl: 1140px, +// xxl: 1320px +// ) !default; +// scss-docs-end container-max-widths + +// @include _assert-ascending($container-max-widths, "$container-max-widths"); + + +// Grid columns +// +// Set the number of columns and specify the width of the gutters. + +// $grid-columns: 12 !default; +// $grid-gutter-width: 1.5rem !default; +// $grid-row-columns: 6 !default; + +// $gutters: $spacers !default; + +// Container padding + +// $container-padding-x: $grid-gutter-width / 2 !default; + + +// Components +// +// Define common padding and border radius sizes and more. + +// scss-docs-start border-variables +// $border-width: 1px !default; +// $border-widths: ( +// 1: 1px, +// 2: 2px, +// 3: 3px, +// 4: 4px, +// 5: 5px +// ) !default; + +// $border-color: $gray-200 !default; +// scss-docs-end border-variables + +// scss-docs-start border-radius-variables +// $border-radius: .25rem !default; +// $border-radius-sm: .2rem !default; +// $border-radius-lg: .3rem !default; +// $border-radius-pill: 50rem !default; +// scss-docs-end border-radius-variables + +// scss-docs-start box-shadow-variables +// $box-shadow: 0 .5rem 1rem rgba($black, .15) !default; +// $box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default; +// $box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default; +// $box-shadow-inset: inset 0 1px 2px rgba($black, .075) !default; +// scss-docs-end box-shadow-variables + +// $component-active-color: $high-emphasis-inverse !default; +// $component-active-bg: $primary !default; + +// scss-docs-start caret-variables +// $caret-width: .3em !default; +// $caret-vertical-align: $caret-width * .85 !default; +// $caret-spacing: $caret-width * .85 !default; +// scss-docs-end caret-variables + +// $transition-base: all .2s ease-in-out !default; +// $transition-fade: opacity .15s linear !default; +// scss-docs-start collapse-transition +// $transition-collapse: height .35s ease !default; +// scss-docs-end collapse-transition + +// stylelint-disable function-disallowed-list +// scss-docs-start aspect-ratios +// $aspect-ratios: ( +// "1x1": 100%, +// "4x3": calc(3 / 4 * 100%), +// "16x9": calc(9 / 16 * 100%), +// "21x9": calc(9 / 21 * 100%) +// ) !default; +// scss-docs-end aspect-ratios +// stylelint-enable function-disallowed-list + +// Typography +// +// Font, line-height, and color for body text, headings, and more. + +// scss-docs-start font-variables +// stylelint-disable value-keyword-case +// $font-family-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default; +// $font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default; +// stylelint-enable value-keyword-case +// $font-family-base: var(--#{$variable-prefix}font-sans-serif) !default; +// $font-family-code: var(--#{$variable-prefix}font-monospace) !default; + +// $font-size-root effects the value of `rem`, which is used for as well font sizes, paddings and margins +// $font-size-base effects the font size of the body text +// $font-size-root: null !default; +// $font-size-base: 1rem !default; // Assumes the browser default, typically `16px` +// $font-size-sm: $font-size-base * .875 !default; +// $font-size-lg: $font-size-base * 1.25 !default; + +// $font-weight-lighter: lighter !default; +// $font-weight-light: 300 !default; +// $font-weight-normal: 400 !default; +// $font-weight-medium: 500 !default; +// $font-weight-semibold: 600 !default; +// $font-weight-bold: 700 !default; +// $font-weight-bolder: bolder !default; + +// $font-weight-base: $font-weight-normal !default; + +// $line-height-base: 1.5 !default; +// $line-height-sm: 1.25 !default; +// $line-height-lg: 2 !default; + +// $h1-font-size: $font-size-base * 2.5 !default; +// $h2-font-size: $font-size-base * 2 !default; +// $h3-font-size: $font-size-base * 1.75 !default; +// $h4-font-size: $font-size-base * 1.5 !default; +// $h5-font-size: $font-size-base * 1.25 !default; +// $h6-font-size: $font-size-base !default; +// scss-docs-end font-variables + +// scss-docs-start font-sizes +// $font-sizes: ( +// 1: $h1-font-size, +// 2: $h2-font-size, +// 3: $h3-font-size, +// 4: $h4-font-size, +// 5: $h5-font-size, +// 6: $h6-font-size +// ) !default; +// scss-docs-end font-sizes + +// scss-docs-start headings-variables +// $headings-margin-bottom: $spacer / 2 !default; +// $headings-font-family: null !default; +// $headings-font-style: null !default; +// $headings-font-weight: 500 !default; +// $headings-line-height: 1.2 !default; +// $headings-color: unset !default; +// scss-docs-end headings-variables + +// scss-docs-start display-headings +// $display-font-sizes: ( +// 1: 5rem, +// 2: 4.5rem, +// 3: 4rem, +// 4: 3.5rem, +// 5: 3rem, +// 6: 2.5rem +// ) !default; + +// $display-font-weight: 300 !default; +// $display-line-height: $headings-line-height !default; +// scss-docs-end display-headings + +// scss-docs-start type-variables +// $lead-font-size: $font-size-base * 1.25 !default; +// $lead-font-weight: 300 !default; + +// $small-font-size: .875em !default; + +// $sub-sup-font-size: .75em !default; + +// $text-high-emphasis: $high-emphasis !default; +// $text-medium-emphasis: $medium-emphasis !default; +// $text-disabled: $disabled !default; +// $text-muted: $disabled !default; + +// $text-high-emphasis-inverse: $high-emphasis-inverse !default; +// $text-medium-emphasis-inverse: $medium-emphasis-inverse !default; +// $text-disabled-inverse: $disabled-inverse !default; + +// $initialism-font-size: $small-font-size !default; + +// $blockquote-margin-y: $spacer !default; +// $blockquote-font-size: $font-size-base * 1.25 !default; +// $blockquote-footer-color: $gray-600 !default; +// $blockquote-footer-font-size: $small-font-size !default; + +// $hr-margin-y: $spacer !default; +// $hr-color: inherit !default; +// $hr-height: $border-width !default; +// $hr-opacity: .25 !default; + +// $vr-color: inherit !default; +// $vr-width: $border-width !default; +// $vr-opacity: .25 !default; + +// $legend-margin-bottom: .5rem !default; +// $legend-font-size: 1.5rem !default; +// $legend-font-weight: null !default; + +// $mark-padding: .2em !default; + +// $dt-font-weight: $font-weight-bold !default; + +// $nested-kbd-font-weight: $font-weight-bold !default; + +// $list-inline-padding: .5rem !default; + +// $mark-bg: #fcf8e3 !default; +// scss-docs-end type-variables + +// Icons +// $icon-size-base: 1rem !default; +// $icon-size-sm: $icon-size-base * .875 !default; +// $icon-size-lg: $icon-size-base * 1.25 !default; +// $icon-size-xl: $icon-size-base * 1.5 !default; + + +// Tables +// +// Customizes the `.table` component with basic values, each used across all table variations. + +// scss-docs-start table-variables +// $table-cell-padding-y: .5rem !default; +// $table-cell-padding-x: .5rem !default; +// $table-cell-padding-y-sm: .25rem !default; +// $table-cell-padding-x-sm: .25rem !default; + +// $table-cell-vertical-align: top !default; + +// $table-color: $body-color !default; +// $table-bg: transparent !default; + +// $table-th-font-weight: 600 !default; + +// $table-striped-color: $table-color !default; +// $table-striped-bg-factor: .05 !default; +// $table-striped-bg: rgba($black, $table-striped-bg-factor) !default; + +// $table-active-color: $table-color !default; +// $table-active-bg-factor: .1 !default; +// $table-active-bg: rgba($black, $table-active-bg-factor) !default; + +// $table-hover-color: $table-color !default; +// $table-hover-bg-factor: .075 !default; +// $table-hover-bg: rgba($black, $table-hover-bg-factor) !default; + +// $table-border-factor: .1 !default; +// $table-border-width: $border-width !default; +// $table-border-color: $border-color !default; + +// $table-striped-order: odd !default; + +// $table-group-separator-color: currentColor !default; + +// $table-caption-color: $text-muted !default; + +// $table-bg-scale: -80% !default; +// scss-docs-end table-variables + +// scss-docs-start table-loop +// $table-variants: ( +// "primary": table-color-map(shift-color($primary, $table-bg-scale)), +// "secondary": table-color-map(shift-color($secondary, $table-bg-scale)), +// "success": table-color-map(shift-color($success, $table-bg-scale)), +// "danger": table-color-map(shift-color($danger, $table-bg-scale)), +// "warning": table-color-map(shift-color($warning, $table-bg-scale)), +// "info": table-color-map(shift-color($info, $table-bg-scale)), +// "light": table-color-map(shift-color($light, $table-bg-scale)), +// "dark": table-color-map(shift-color($dark, $table-bg-scale)) +// ) !default; +// scss-docs-end table-loop + + +// Buttons + Forms +// +// Shared variables that are reassigned to `$input-` and `$btn-` specific variables. + +// scss-docs-start input-btn-variables +// $input-btn-padding-y: .375rem !default; +// $input-btn-padding-x: .75rem !default; +// $input-btn-font-family: null !default; +// $input-btn-font-size: $font-size-base !default; +// $input-btn-line-height: $line-height-base !default; + +// $input-btn-focus-width: .25rem !default; +// $input-btn-focus-color-opacity: .25 !default; +// $input-btn-focus-color: rgba($component-active-bg, $input-btn-focus-color-opacity) !default; +// $input-btn-focus-blur: 0 !default; +// $input-btn-focus-box-shadow: 0 0 $input-btn-focus-blur $input-btn-focus-width $input-btn-focus-color !default; + +// $input-btn-padding-y-sm: .25rem !default; +// $input-btn-padding-x-sm: .5rem !default; +// $input-btn-font-size-sm: $font-size-sm !default; + +// $input-btn-padding-y-lg: .5rem !default; +// $input-btn-padding-x-lg: 1rem !default; +// $input-btn-font-size-lg: $font-size-lg !default; + +// $input-btn-border-width: $border-width !default; +// scss-docs-end input-btn-variables + + +// Buttons +// +// For each of Bootstrap's buttons, define text, background, and border color. + +// scss-docs-start btn-variables +// $btn-padding-y: $input-btn-padding-y !default; +// $btn-padding-x: $input-btn-padding-x !default; +// $btn-font-family: $input-btn-font-family !default; +// $btn-font-size: $input-btn-font-size !default; +// $btn-line-height: $input-btn-line-height !default; +// $btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping + +// $btn-padding-y-sm: $input-btn-padding-y-sm !default; +// $btn-padding-x-sm: $input-btn-padding-x-sm !default; +// $btn-font-size-sm: $input-btn-font-size-sm !default; + +// $btn-padding-y-lg: $input-btn-padding-y-lg !default; +// $btn-padding-x-lg: $input-btn-padding-x-lg !default; +// $btn-font-size-lg: $input-btn-font-size-lg !default; + +// $btn-border-width: $input-btn-border-width !default; + +// $btn-font-weight: $font-weight-normal !default; +// $btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default; +// $btn-focus-width: $input-btn-focus-width !default; +// $btn-focus-box-shadow: $input-btn-focus-box-shadow !default; +// $btn-disabled-opacity: .65 !default; +// $btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default; + +// $btn-link-color: $link-color !default; +// $btn-link-hover-color: $link-hover-color !default; +// $btn-link-disabled-color: $gray-600 !default; + +// Allows for customizing button radius independently from global border radius +// $btn-border-radius: $border-radius !default; +// $btn-border-radius-sm: $border-radius-sm !default; +// $btn-border-radius-lg: $border-radius-lg !default; + +// $btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default; + +// $btn-hover-bg-shade-amount: 15% !default; +// $btn-hover-bg-tint-amount: 15% !default; +// $btn-hover-border-shade-amount: 20% !default; +// $btn-hover-border-tint-amount: 10% !default; +// $btn-active-bg-shade-amount: 20% !default; +// $btn-active-bg-tint-amount: 20% !default; +// $btn-active-border-shade-amount: 25% !default; +// $btn-active-border-tint-amount: 10% !default; + +// $button-variants: ( +// "primary": btn-color-map($primary, $primary), +// "secondary": btn-color-map($secondary, $secondary), +// "success": btn-color-map($success, $success), +// "danger": btn-color-map($danger, $danger), +// "warning": btn-color-map($warning, $warning), +// "info": btn-color-map($info, $info), +// "light": btn-color-map($light, $light), +// "dark": btn-color-map($dark, $dark) +// ) !default; + +// $button-outline-ghost-variants: ( +// "primary": btn-outline-color-map($primary), +// "secondary": btn-outline-color-map($secondary), +// "success": btn-outline-color-map($success), +// "danger": btn-outline-color-map($danger), +// "warning": btn-outline-color-map($warning), +// "info": btn-outline-color-map($info), +// "light": btn-outline-color-map($light), +// "dark": btn-outline-color-map($dark) +// ) !default; +// scss-docs-end btn-variables + + +// Forms +// scss-docs-start form-variables +// scss-docs-start form-text-variables +// $form-text-margin-top: .25rem !default; +// $form-text-font-size: $small-font-size !default; +// $form-text-font-style: null !default; +// $form-text-font-weight: null !default; +// $form-text-color: $text-muted !default; +// scss-docs-end form-text-variables + +// scss-docs-start form-label-variables +// $form-label-margin-bottom: .5rem !default; +// $form-label-font-size: null !default; +// $form-label-font-style: null !default; +// $form-label-font-weight: null !default; +// $form-label-color: null !default; +// scss-docs-end form-label-variables + +// scss-docs-start form-input-variables +// $input-padding-y: $input-btn-padding-y !default; +// $input-padding-x: $input-btn-padding-x !default; +// $input-font-family: $input-btn-font-family !default; +// $input-font-size: $input-btn-font-size !default; +// $input-font-weight: $font-weight-base !default; +// $input-line-height: $input-btn-line-height !default; + +// $input-padding-y-sm: $input-btn-padding-y-sm !default; +// $input-padding-x-sm: $input-btn-padding-x-sm !default; +// $input-font-size-sm: $input-btn-font-size-sm !default; + +// $input-padding-y-lg: $input-btn-padding-y-lg !default; +// $input-padding-x-lg: $input-btn-padding-x-lg !default; +// $input-font-size-lg: $input-btn-font-size-lg !default; + +// $input-bg: $white !default; +// $input-disabled-bg: $gray-200 !default; +// $input-disabled-border-color: $gray-400 !default; + +// $input-color: $body-color !default; +// $input-border-color: $gray-400 !default; +// $input-border-width: $input-btn-border-width !default; +// $input-box-shadow: $box-shadow-inset !default; + +// $input-border-radius: $border-radius !default; +// $input-border-radius-sm: $border-radius-sm !default; +// $input-border-radius-lg: $border-radius-lg !default; + +// $input-focus-bg: $input-bg !default; +// $input-focus-border-color: tint-color($component-active-bg, 50%) !default; +// $input-focus-color: $input-color !default; +// $input-focus-width: $input-btn-focus-width !default; +// $input-focus-box-shadow: $input-btn-focus-box-shadow !default; + +// $input-placeholder-color: $gray-600 !default; +// $input-plaintext-color: $body-color !default; + +// $input-height-border: $input-border-width * 2 !default; + +// $input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default; +// $input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default; +// $input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y / 2) !default; + +// $input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default; +// $input-height-sm: add($input-line-height * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default; +// $input-height-lg: add($input-line-height * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default; + +// $input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default; +// scss-docs-end form-input-variables + +// scss-docs-start form-check-variables +// $form-check-input-width: 1em !default; +// $form-check-min-height: $font-size-base * $line-height-base !default; +// $form-check-padding-start: $form-check-input-width + .5em !default; +// $form-check-margin-bottom: .125rem !default; +// $form-check-label-color: unset !default; +// $form-check-label-cursor: null !default; +// $form-check-transition: null !default; + +// $form-check-input-active-filter: brightness(90%) !default; + +// $form-check-input-bg: $input-bg !default; +// $form-check-input-border: 1px solid rgba($black, .25) !default; +// $form-check-input-border-radius: .25em !default; +// $form-check-radio-border-radius: 50% !default; +// $form-check-input-focus-border: $input-focus-border-color !default; +// $form-check-input-focus-box-shadow: $input-btn-focus-box-shadow !default; + +// $form-check-input-checked-color: $component-active-color !default; +// $form-check-input-checked-bg-color: $component-active-bg !default; +// $form-check-input-checked-border-color: $form-check-input-checked-bg-color !default; +// $form-check-input-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path fill='none' stroke='#{$form-check-input-checked-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/></svg>") !default; +// $form-check-radio-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='2' fill='#{$form-check-input-checked-color}'/></svg>") !default; + +// $form-check-input-indeterminate-color: $component-active-color !default; +// $form-check-input-indeterminate-bg-color: $component-active-bg !default; +// $form-check-input-indeterminate-border-color: $form-check-input-indeterminate-bg-color !default; +// $form-check-input-indeterminate-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path fill='none' stroke='#{$form-check-input-indeterminate-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/></svg>") !default; + +// $form-check-input-disabled-opacity: .5 !default; +// $form-check-label-disabled-opacity: $form-check-input-disabled-opacity !default; +// $form-check-btn-check-disabled-opacity: $btn-disabled-opacity !default; + +// $form-check-inline-margin-end: 1rem !default; +// scss-docs-end form-check-variables + +// scss-docs-start form-switch-variables +// $form-switch-color: rgba(0, 0, 0, .25) !default; +// $form-switch-width: 1.5em !default; +// $form-switch-padding-start: $form-switch-width + .5em !default; +// $form-switch-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-color}'/></svg>") !default; +// $form-switch-border-radius: $form-switch-width !default; +// $form-switch-transition: background-position .15s ease-in-out !default; + +// $form-switch-focus-color: $input-focus-border-color !default; +// $form-switch-focus-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-focus-color}'/></svg>") !default; + +// $form-switch-checked-color: $component-active-color !default; +// $form-switch-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-checked-color}'/></svg>") !default; +// $form-switch-checked-bg-position: right center !default; + +// $form-switch-widths: ( +// lg: ( +// width: 1.75em, +// height: 1.25em +// ), +// xl: ( +// width: 2em, +// height: 1.5em +// ) +// ) !default; +// scss-docs-end form-switch-variables + +// $form-check-inline-margin-end: 1rem !default; + +// scss-docs-start input-group-variables +// $input-group-addon-padding-y: $input-padding-y !default; +// $input-group-addon-padding-x: $input-padding-x !default; +// $input-group-addon-font-weight: $input-font-weight !default; +// $input-group-addon-color: $input-color !default; +// $input-group-addon-bg: $gray-200 !default; +// $input-group-addon-border-color: $input-border-color !default; +// scss-docs-end input-group-variables + +// scss-docs-start form-select-variables +// $form-select-padding-y: $input-padding-y !default; +// $form-select-padding-x: $input-padding-x !default; +// $form-select-font-family: $input-font-family !default; +// $form-select-font-size: $input-font-size !default; +// $form-select-indicator-padding: $form-select-padding-x * 3 !default; // Extra padding for background-image +// $form-select-font-weight: $input-font-weight !default; +// $form-select-line-height: $input-line-height !default; +// $form-select-color: $input-color !default; +// $form-select-bg: $input-bg !default; +// $form-select-disabled-color: null !default; +// $form-select-disabled-bg: $gray-200 !default; +// $form-select-disabled-border-color: $input-disabled-border-color !default; +// $form-select-bg-position: right $form-select-padding-x center !default; +// $form-select-bg-size: 16px 12px !default; // In pixels because image dimensions +// $form-select-indicator-color: $gray-800 !default; +// $form-select-indicator: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$form-select-indicator-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/></svg>") !default; + +// $form-select-feedback-icon-padding-end: $form-select-padding-x * 2.5 + $form-select-indicator-padding !default; +// $form-select-feedback-icon-position: center right $form-select-indicator-padding !default; +// $form-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default; + +// $form-select-border-width: $input-border-width !default; +// $form-select-border-color: $input-border-color !default; +// $form-select-border-radius: $border-radius !default; +// $form-select-box-shadow: $box-shadow-inset !default; + +// $form-select-focus-border-color: $input-focus-border-color !default; +// $form-select-focus-width: $input-focus-width !default; +// $form-select-focus-box-shadow: 0 0 0 $form-select-focus-width $input-btn-focus-color !default; + +// $form-select-padding-y-sm: $input-padding-y-sm !default; +// $form-select-padding-x-sm: $input-padding-x-sm !default; +// $form-select-font-size-sm: $input-font-size-sm !default; + +// $form-select-padding-y-lg: $input-padding-y-lg !default; +// $form-select-padding-x-lg: $input-padding-x-lg !default; +// $form-select-font-size-lg: $input-font-size-lg !default; +// scss-docs-end form-select-variables + +// scss-docs-start form-range-variables +// $form-range-track-width: 100% !default; +// $form-range-track-height: .5rem !default; +// $form-range-track-cursor: pointer !default; +// $form-range-track-bg: $gray-300 !default; +// $form-range-track-border-radius: 1rem !default; +// $form-range-track-box-shadow: $box-shadow-inset !default; + +// $form-range-thumb-width: 1rem !default; +// $form-range-thumb-height: $form-range-thumb-width !default; +// $form-range-thumb-bg: $component-active-bg !default; +// $form-range-thumb-border: 0 !default; +// $form-range-thumb-border-radius: 1rem !default; +// $form-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default; +// $form-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default; +// $form-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in Edge +// $form-range-thumb-active-bg: tint-color($component-active-bg, 70%) !default; +// $form-range-thumb-disabled-bg: $gray-500 !default; +// $form-range-thumb-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default; +// scss-docs-end form-range-variables + +// scss-docs-start form-file-variables +// $form-file-button-color: $input-color !default; +// $form-file-button-bg: $input-group-addon-bg !default; +// $form-file-button-hover-bg: shade-color($form-file-button-bg, 5%) !default; +// scss-docs-end form-file-variables + +// scss-docs-start form-floating-variables +// $form-floating-height: add(3.5rem, $input-height-border) !default; +// $form-floating-padding-x: $input-padding-x !default; +// $form-floating-padding-y: 1rem !default; +// $form-floating-input-padding-t: 1.625rem !default; +// $form-floating-input-padding-b: .625rem !default; +// $form-floating-label-opacity: .65 !default; +// $form-floating-label-transform: scale(.85) translateY(-.5rem) translateX(.15rem) !default; +// $form-floating-transition: opacity .1s ease-in-out, transform .1s ease-in-out !default; +// scss-docs-end form-floating-variables + +// Form validation + +// scss-docs-start form-feedback-variables +// $form-feedback-margin-top: $form-text-margin-top !default; +// $form-feedback-font-size: $form-text-font-size !default; +// $form-feedback-font-style: $form-text-font-style !default; +// $form-feedback-valid-color: $success !default; +// $form-feedback-invalid-color: $danger !default; + +// $form-feedback-icon-valid-color: $form-feedback-valid-color !default; +// $form-feedback-icon-valid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>") !default; +// $form-feedback-icon-invalid-color: $form-feedback-invalid-color !default; +// $form-feedback-icon-invalid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>") !default; +// scss-docs-end form-feedback-variables + +// scss-docs-start form-validation-states +// $form-validation-states: ( +// "valid": ( +// "color": $form-feedback-valid-color, +// "icon": $form-feedback-icon-valid +// ), +// "invalid": ( +// "color": $form-feedback-invalid-color, +// "icon": $form-feedback-icon-invalid +// ) +// ) !default; +// scss-docs-end form-validation-states +// scss-docs-end form-variables +// Z-index master list +// +// Warning: Avoid customizing these values. They're used for a bird's eye view +// of components dependent on the z-axis and are designed to all work together. + +// scss-docs-start zindex-stack +// $zindex-dropdown: 1000 !default; +// $zindex-sticky: 1020 !default; +// $zindex-fixed: 1030 !default; +// $zindex-modal-backdrop: 1040 !default; +// $zindex-offcanvas: 1050 !default; +// $zindex-modal: 1060 !default; +// $zindex-popover: 1070 !default; +// $zindex-tooltip: 1080 !default; +// $zindex-toaster: 1090 !default; +// scss-docs-end zindex-stack + + +// Navs +// scss-docs-start nav-variables +// $nav-link-padding-y: .5rem !default; +// $nav-link-padding-x: 1rem !default; +// $nav-link-font-size: null !default; +// $nav-link-font-weight: null !default; +// $nav-link-color: $link-color !default; +// $nav-link-hover-color: $link-hover-color !default; +// $nav-link-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out !default; +// $nav-link-disabled-color: $gray-600 !default; + +// $nav-tabs-border-color: $gray-300 !default; +// $nav-tabs-border-width: $border-width !default; +// $nav-tabs-border-radius: $border-radius !default; +// $nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default; +// $nav-tabs-link-active-color: $gray-700 !default; +// $nav-tabs-link-active-bg: $body-bg !default; +// $nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default; + +// $nav-pills-border-radius: $border-radius !default; +// $nav-pills-link-active-color: $component-active-color !default; +// $nav-pills-link-active-bg: $component-active-bg !default; +// scss-docs-end nav-variables + + +// Navbar + +// scss-docs-start navbar-variables +// $navbar-padding-y: $spacer / 2 !default; +// $navbar-padding-x: null !default; + +// $navbar-nav-link-padding-x: .5rem !default; + +// $navbar-brand-font-size: $font-size-lg !default; +// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link +// $nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default; +// $navbar-brand-height: $navbar-brand-font-size * $line-height-base !default; +// $navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default; +// $navbar-brand-margin-end: 1rem !default; + +// $navbar-toggler-padding-y: .25rem !default; +// $navbar-toggler-padding-x: .75rem !default; +// $navbar-toggler-font-size: $font-size-lg !default; +// $navbar-toggler-border-radius: $btn-border-radius !default; +// $navbar-toggler-focus-width: $btn-focus-width !default; +// $navbar-toggler-transition: box-shadow .15s ease-in-out !default; +// scss-docs-end navbar-variables + +// scss-docs-start navbar-theme-variables +// $navbar-dark-color: $medium-emphasis-inverse !default; +// $navbar-dark-hover-color: $high-emphasis-inverse !default; +// $navbar-dark-active-color: $high-emphasis-inverse !default; +// $navbar-dark-disabled-color: $disabled-inverse !default; +// $navbar-dark-toggler-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-dark-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>") !default; +// $navbar-dark-toggler-border-color: rgba($white, .1) !default; + +// $navbar-light-color: $medium-emphasis !default; +// $navbar-light-hover-color: $high-emphasis !default; +// $navbar-light-active-color: $high-emphasis !default; +// $navbar-light-disabled-color: $disabled !default; +// $navbar-light-toggler-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-light-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>") !default; +// $navbar-light-toggler-border-color: rgba($black, .1) !default; + +// $navbar-light-brand-color: $navbar-light-active-color !default; +// $navbar-light-brand-hover-color: $navbar-light-active-color !default; +// $navbar-dark-brand-color: $navbar-dark-active-color !default; +// $navbar-dark-brand-hover-color: $navbar-dark-active-color !default; +// scss-docs-end navbar-theme-variables + + +// Dropdowns +// +// Dropdown menu container and contents. +// scss-docs-start dropdown-variables +// $dropdown-min-width: 10rem !default; +// $dropdown-padding-x: 0 !default; +// $dropdown-padding-y: .5rem !default; +// $dropdown-spacer: .125rem !default; +// $dropdown-font-size: $font-size-base !default; +// $dropdown-color: $body-color !default; +// $dropdown-bg: $white !default; +// $dropdown-border-color: rgba($black, .15) !default; +// $dropdown-border-radius: $border-radius !default; +// $dropdown-border-width: $border-width !default; +// $dropdown-inner-border-radius: subtract($dropdown-border-radius, $dropdown-border-width) !default; +// $dropdown-divider-bg: $dropdown-border-color !default; +// $dropdown-divider-margin-y: $spacer / 2 !default; +// $dropdown-box-shadow: $box-shadow !default; + +// $dropdown-link-color: $gray-900 !default; +// $dropdown-link-hover-color: shade-color($gray-900, 10%) !default; +// $dropdown-link-hover-bg: $gray-200 !default; + +// $dropdown-link-active-color: $component-active-color !default; +// $dropdown-link-active-bg: $component-active-bg !default; + +// $dropdown-link-disabled-color: $gray-500 !default; + +// $dropdown-item-padding-y: $spacer / 4 !default; +// $dropdown-item-padding-x: $spacer !default; + +// $dropdown-header-color: $gray-600 !default; +// $dropdown-header-padding: $dropdown-padding-y $dropdown-item-padding-x !default; +// scss-docs-end dropdown-variables + +// scss-docs-start dropdown-dark-variables +// $dropdown-dark-color: $gray-300 !default; +// $dropdown-dark-bg: $gray-800 !default; +// $dropdown-dark-border-color: $dropdown-border-color !default; +// $dropdown-dark-divider-bg: $dropdown-divider-bg !default; +// $dropdown-dark-box-shadow: null !default; +// $dropdown-dark-link-color: $dropdown-dark-color !default; +// $dropdown-dark-link-hover-color: $high-emphasis-inverse !default; +// $dropdown-dark-link-hover-bg: rgba($white, .15) !default; +// $dropdown-dark-link-active-color: $dropdown-link-active-color !default; +// $dropdown-dark-link-active-bg: $dropdown-link-active-bg !default; +// $dropdown-dark-link-disabled-color: $gray-500 !default; +// $dropdown-dark-header-color: $gray-500 !default; +// scss-docs-end dropdown-dark-variables + + +// Pagination + +// scss-docs-start pagination-variables +// $pagination-padding-y: .375rem !default; +// $pagination-padding-x: .75rem !default; +// $pagination-padding-y-sm: .25rem !default; +// $pagination-padding-x-sm: .5rem !default; +// $pagination-padding-y-lg: .75rem !default; +// $pagination-padding-x-lg: 1.5rem !default; + +// $pagination-color: $link-color !default; +// $pagination-bg: $white !default; +// $pagination-border-width: $border-width !default; +// $pagination-border-radius: $border-radius !default; +// $pagination-margin-start: -$pagination-border-width !default; +// $pagination-border-color: $gray-300 !default; + +// $pagination-focus-color: $link-hover-color !default; +// $pagination-focus-bg: $gray-200 !default; +// $pagination-focus-box-shadow: $input-btn-focus-box-shadow !default; +// $pagination-focus-outline: 0 !default; + +// $pagination-hover-color: $link-hover-color !default; +// $pagination-hover-bg: $gray-200 !default; +// $pagination-hover-border-color: $gray-300 !default; + +// $pagination-active-color: $component-active-color !default; +// $pagination-active-bg: $component-active-bg !default; +// $pagination-active-border-color: $pagination-active-bg !default; + +// $pagination-disabled-color: $gray-600 !default; +// $pagination-disabled-bg: $white !default; +// $pagination-disabled-border-color: $gray-300 !default; + +// $pagination-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default; +// scss-docs-end pagination-variables + +// $pagination-border-radius-sm: $border-radius-sm !default; +// $pagination-border-radius-lg: $border-radius-lg !default; +// scss-docs-end pagination-variables + + +// Cards +// scss-docs-start card-variables +// $card-spacer-y: $spacer !default; +// $card-spacer-x: $spacer !default; +// $card-title-spacer-y: $spacer / 2 !default; +// $card-border-width: $border-width !default; +// $card-border-radius: $border-radius !default; +// $card-border-color: rgba($black, .125) !default; +// $card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default; +// $card-cap-padding-y: $card-spacer-y / 2 !default; +// $card-cap-padding-x: $card-spacer-x !default; +// $card-cap-bg: rgba($black, .03) !default; +// $card-cap-color: unset !default; +// $card-height: null !default; +// $card-color: unset !default; +// $card-bg: $white !default; +// $card-img-overlay-padding: $spacer !default; +// $card-group-margin: $grid-gutter-width / 2 !default; +// scss-docs-end card-variables + +// Accordion +// scss-docs-start accordion-variables +// $accordion-padding-y: 1rem !default; +// $accordion-padding-x: 1.25rem !default; +// $accordion-color: $body-color !default; +// $accordion-bg: $body-bg !default; +// $accordion-border-width: $border-width !default; +// $accordion-border-color: rgba($black, .125) !default; +// $accordion-border-radius: $border-radius !default; +// $accordion-inner-border-radius: subtract($accordion-border-radius, $accordion-border-width) !default; + +// $accordion-body-padding-y: $accordion-padding-y !default; +// $accordion-body-padding-x: $accordion-padding-x !default; + +// $accordion-button-padding-y: $accordion-padding-y !default; +// $accordion-button-padding-x: $accordion-padding-x !default; +// $accordion-button-color: $accordion-color !default; +// $accordion-button-bg: $accordion-bg !default; +// $accordion-transition: $btn-transition, border-radius .15s ease !default; +// $accordion-button-active-bg: tint-color($component-active-bg, 90%) !default; +// $accordion-button-active-color: shade-color($primary, 10%) !default; + +// $accordion-button-focus-border-color: $input-focus-border-color !default; +// $accordion-button-focus-box-shadow: $btn-focus-box-shadow !default; + +// $accordion-icon-width: 1.25rem !default; +// $accordion-icon-color: $accordion-color !default; +// $accordion-icon-active-color: $accordion-button-active-color !default; +// $accordion-icon-transition: transform .2s ease-in-out !default; +// $accordion-icon-transform: rotate(-180deg) !default; + +// $accordion-button-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default; +// $accordion-button-active-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-active-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default; +// scss-docs-end accordion-variables + +// Tooltips + +// scss-docs-start tooltip-variables +// $tooltip-font-size: $font-size-sm !default; +// $tooltip-max-width: 200px !default; +// $tooltip-color: $high-emphasis-inverse !default; +// $tooltip-bg: $black !default; +// $tooltip-border-radius: $border-radius !default; +// $tooltip-opacity: .9 !default; +// $tooltip-padding-y: $spacer / 4 !default; +// $tooltip-padding-x: $spacer / 2 !default; +// $tooltip-margin: 0 !default; + +// $tooltip-arrow-width: .8rem !default; +// $tooltip-arrow-height: .4rem !default; +// $tooltip-arrow-color: $tooltip-bg !default; +// scss-docs-end tooltip-variables + +// Form tooltips must come after regular tooltips +// scss-docs-start tooltip-feedback-variables +// $form-feedback-tooltip-padding-y: $tooltip-padding-y !default; +// $form-feedback-tooltip-padding-x: $tooltip-padding-x !default; +// $form-feedback-tooltip-font-size: $tooltip-font-size !default; +// $form-feedback-tooltip-line-height: null !default; +// $form-feedback-tooltip-opacity: $tooltip-opacity !default; +// $form-feedback-tooltip-border-radius: $tooltip-border-radius !default; +// scss-docs-end tooltip-feedback-variables + + +// Popovers +// scss-docs-start popover-variables +// $popover-font-size: $font-size-sm !default; +// $popover-bg: $white !default; +// $popover-max-width: 276px !default; +// $popover-border-width: $border-width !default; +// $popover-border-color: rgba($black, .2) !default; +// $popover-border-radius: $border-radius-lg !default; +// $popover-inner-border-radius: subtract($popover-border-radius, $popover-border-width) !default; +// $popover-box-shadow: $box-shadow !default; + +// $popover-header-bg: shade-color($popover-bg, 6%) !default; +// $popover-header-color: $headings-color !default; +// $popover-header-padding-y: .5rem !default; +// $popover-header-padding-x: $spacer !default; + +// $popover-body-color: $body-color !default; +// $popover-body-padding-y: $spacer !default; +// $popover-body-padding-x: $spacer !default; + +// $popover-arrow-width: 1rem !default; +// $popover-arrow-height: .5rem !default; +// $popover-arrow-color: $popover-bg !default; + +// $popover-arrow-outer-color: fade-in($popover-border-color, .05) !default; +// scss-docs-end popover-variables + + +// Toasts +// scss-docs-start toast-variables +// $toast-max-width: 350px !default; +// $toast-padding-x: .75rem !default; +// $toast-padding-y: .5rem !default; +// $toast-font-size: .875rem !default; +// $toast-color: unset !default; +// $toast-background-color: rgba($white, .85) !default; +// $toast-border-width: 1px !default; +// $toast-border-color: rgba(0, 0, 0, .1) !default; +// $toast-border-radius: $border-radius !default; +// $toast-box-shadow: $box-shadow !default; +// $toast-spacing: $container-padding-x !default; + +// $toast-header-color: $gray-600 !default; +// $toast-header-background-color: rgba($white, .85) !default; +// $toast-header-border-color: rgba(0, 0, 0, .05) !default; +// scss-docs-end toast-variables + + +// Badges +// scss-docs-start badge-variables +// $badge-font-size: .75em !default; +// $badge-font-weight: $font-weight-bold !default; +// $badge-color: $high-emphasis-inverse !default; +// $badge-padding-y: .35em !default; +// $badge-padding-x: .65em !default; +// $badge-border-radius: $border-radius !default; +// scss-docs-end badge-variables + +// $badge-font-size-sm: .65em !default; +// $badge-padding-y-sm: .3em !default; +// $badge-padding-x-sm: .5em !default; +// scss-docs-end badge-variables + + +// Modals + +// scss-docs-start modal-variables +// $modal-inner-padding: $spacer !default; + +// $modal-footer-margin-between: .5rem !default; + +// $modal-dialog-margin: .5rem !default; +// $modal-dialog-margin-y-sm-up: 1.75rem !default; + +// $modal-title-line-height: $line-height-base !default; + +// $modal-content-color: unset !default; +// $modal-content-bg: $white !default; +// $modal-content-border-color: rgba($black, .2) !default; +// $modal-content-border-width: $border-width !default; +// $modal-content-border-radius: $border-radius-lg !default; +// $modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default; +// $modal-content-box-shadow-xs: $box-shadow-sm !default; +// $modal-content-box-shadow-sm-up: $box-shadow !default; + +// $modal-backdrop-bg: $black !default; +// $modal-backdrop-opacity: .5 !default; +// $modal-header-border-color: $border-color !default; +// $modal-footer-border-color: $modal-header-border-color !default; +// $modal-header-border-width: $modal-content-border-width !default; +// $modal-footer-border-width: $modal-header-border-width !default; +// $modal-header-padding-y: $modal-inner-padding !default; +// $modal-header-padding-x: $modal-inner-padding !default; +// $modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility + +// $modal-sm: 300px !default; +// $modal-md: 500px !default; +// $modal-lg: 800px !default; +// $modal-xl: 1140px !default; + +// $modal-fade-transform: translate(0, -50px) !default; +// $modal-show-transform: none !default; +// $modal-transition: transform .3s ease-out !default; +// $modal-scale-transform: scale(1.02) !default; +// scss-docs-end modal-variables + + +// Avatars +// scss-docs-start avatar-variables +// $avatar-width: 2rem !default; + +// $avatar-widths: ( +// sm: 1.5rem, +// md: 2.5rem, +// lg: 3rem, +// xl: 4rem +// ) !default; + +// $avatar-transition: margin .15s !default; +// scss-docs-end avatar-variables + +// Alerts +// +// Define alert colors, border radius, and padding. + +// scss-docs-start alert-variables +// $alert-padding-y: $spacer !default; +// $alert-padding-x: $spacer !default; +// $alert-margin-bottom: 1rem !default; +// $alert-border-radius: $border-radius !default; +// $alert-link-font-weight: $font-weight-bold !default; +// $alert-border-width: $border-width !default; +// $alert-bg-scale: -80% !default; +// $alert-border-scale: -70% !default; +// $alert-color-scale: 40% !default; +// $alert-dismissible-padding-r: $alert-padding-x * 3 !default; // 3x covers width of x plus default padding on either side +// scss-docs-end alert-variables + +// $alert-variants: ( +// "primary": alert-color-map($primary), +// "secondary": alert-color-map($secondary), +// "success": alert-color-map($success), +// "danger": alert-color-map($danger), +// "warning": alert-color-map($warning), +// "info": alert-color-map($info), +// "light": alert-color-map($light), +// "dark": alert-color-map($dark) +// ) !default; +// scss-docs-end alert-variables + +// Callouts +// scss-docs-start callout-variables +// $callout-padding-y: $spacer !default; +// $callout-padding-x: $spacer !default; +// $callout-margin-y: $spacer !default; +// $callout-margin-x: 0 !default; +// $callout-border-radius: $border-radius !default; +// $callout-border-width: $border-width !default; +// $callout-border-color: $border-color !default; +// $callout-border-left-width: (4 * $callout-border-width) !default; + +// $callout-variants: ( +// "primary": $primary, +// "secondary": $secondary, +// "success": $success, +// "danger": $danger, +// "warning": $warning, +// "info": $info, +// "light": $light, +// "dark": $dark +// ) !default; +// scss-docs-end callout-variables + + +// Progress bars + +// scss-docs-start progress-variables +// $progress-height: 1rem !default; +// $progress-font-size: $font-size-base * .75 !default; +// $progress-bg: $gray-200 !default; +// $progress-border-radius: $border-radius !default; +// $progress-box-shadow: $box-shadow-inset !default; +// $progress-bar-color: $high-emphasis-inverse !default; +// $progress-bar-bg: $primary !default; +// $progress-bar-animation-timing: 1s linear infinite !default; +// $progress-bar-transition: width .6s ease !default; +// scss-docs-end progress-variables + +// List group +// scss-docs-start list-group-variables +// $list-group-color: unset !default; +// $list-group-bg: $white !default; +// $list-group-border-color: rgba($black, .125) !default; +// $list-group-border-width: $border-width !default; +// $list-group-border-radius: $border-radius !default; + +// $list-group-item-padding-y: $spacer / 2 !default; +// $list-group-item-padding-x: $spacer !default; +// $list-group-item-bg-scale: -80% !default; +// $list-group-item-color-scale: 40% !default; + +// $list-group-hover-bg: $gray-100 !default; +// $list-group-active-color: $component-active-color !default; +// $list-group-active-bg: $component-active-bg !default; +// $list-group-active-border-color: $list-group-active-bg !default; + +// $list-group-disabled-color: $gray-600 !default; +// $list-group-disabled-bg: $list-group-bg !default; + +// $list-group-action-color: $gray-700 !default; +// $list-group-action-hover-color: $list-group-action-color !default; + +// $list-group-action-active-color: $body-color !default; +// $list-group-action-active-bg: $gray-200 !default; +// scss-docs-end list-group-variables + +// $list-group-variants: ( +// "primary": list-group-color-map($primary), +// "secondary": list-group-color-map($secondary), +// "success": list-group-color-map($success), +// "danger": list-group-color-map($danger), +// "warning": list-group-color-map($warning), +// "info": list-group-color-map($info), +// "light": list-group-color-map($light), +// "dark": list-group-color-map($dark) +// ) !default; +// scss-docs-end list-group-variables + + +// Header +// scss-docs-start header-variables +// $header-min-height: 4rem !default; +// $header-padding-y: $spacer / 2 !default; +// $header-padding-x: $spacer / 2 !default; +// $header-brand-font-size: $font-size-lg !default; +// $header-color: $medium-emphasis !default; +// $header-bg: $white !default; +// $header-border-color: $border-color !default; +// $header-border-width: 1px !default; +// $header-hover-color: $high-emphasis !default; +// $header-active-color: $high-emphasis !default; +// $header-disabled-color: $disabled !default; + +// Compute the header-brand padding-y so the header-brand will have the same height as header-text and nav-link +// $nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default; +// $header-brand-height: $header-brand-font-size * $line-height-base !default; +// $header-brand-padding-y: ($nav-link-height - $header-brand-height) / 2 !default; +// $header-brand-margin-end: 1rem !default; +// $header-brand-font-size: $font-size-lg !default; +// $header-brand-color: $gray-900 !default; +// $header-brand-hover-color: shade-color($gray-900, 10%) !default; + +// $header-toggler-padding-y: .25rem !default; +// $header-toggler-padding-x: .75rem !default; +// $header-toggler-font-size: $font-size-lg !default; +// $header-toggler-bg: transparent !default; +// $header-toggler-border: 0 !default; +// $header-toggler-border-radius: $btn-border-radius !default; + +// $header-toggler-icon-bg: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$header-color}' stroke-width='2.25' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E") !default; +// $header-toggler-hover-icon-bg: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$header-hover-color}' stroke-width='2.25' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E") !default; +// $header-toggler-border-color: rgba($black, .1) !default; + +// $header-nav-link-padding-x: .5rem !default; + +// $header-divider-border-width: 1px !default; +// $header-divider-border-color: $header-border-color !default; +// scss-docs-end header-variables + +// Subheader +// scss-docs-start subheader-variables +// $subheader-min-height: 3rem !default; +// $subheader-padding-y: $spacer / 2 !default; +// $subheader-padding-x: $spacer !default; +// $subheader-border-color: $border-color !default; +// $subheader-border-width: 1px !default; + +// $subheader-nav-link-padding-x: .5rem !default; +// scss-docs-end subheader-variables + +// Default theme +// scss-docs-start subheader-default-themes +// $subheader-bg: $white !default; +// $subheader-color: $medium-emphasis !default; +// $subheader-hover-color: $high-emphasis !default; +// $subheader-active-color: $high-emphasis !default; +// $subheader-disabled-color: $disabled !default; +// scss-docs-end subheader-default-themes + + +// Image thumbnails + +// scss-docs-start thumbnail-variables +// $thumbnail-padding: .25rem !default; +// $thumbnail-bg: $body-bg !default; +// $thumbnail-border-width: $border-width !default; +// $thumbnail-border-color: $gray-300 !default; +// $thumbnail-border-radius: $border-radius !default; +// $thumbnail-box-shadow: $box-shadow-sm !default; +// scss-docs-end thumbnail-variables + + +// Figures + +// scss-docs-start figure-variables +// $figure-caption-font-size: $small-font-size !default; +// $figure-caption-color: $gray-600 !default; +// scss-docs-end figure-variables + + +// Breadcrumbs +// scss-docs-start breadcrumb-variables +// $breadcrumb-font-size: null !default; +// $breadcrumb-padding-y: 0 !default; +// $breadcrumb-padding-x: 0 !default; +// $breadcrumb-item-padding-x: .5rem !default; +// $breadcrumb-margin-bottom: 1rem !default; +// $breadcrumb-bg: unset !default; +// $breadcrumb-divider-color: $gray-600 !default; +// $breadcrumb-active-color: $gray-600 !default; +// $breadcrumb-divider: quote("/") !default; +// $breadcrumb-divider-flipped: $breadcrumb-divider !default; +// $breadcrumb-border-radius: null !default; +// scss-docs-end breadcrumb-variables + +// Carousel +// scss-docs-start carousel-variables +// $carousel-control-color: $high-emphasis-inverse !default; +// $carousel-control-width: 15% !default; +// $carousel-control-opacity: .5 !default; +// $carousel-control-hover-opacity: .9 !default; +// $carousel-control-transition: opacity .15s ease !default; + +// $carousel-indicator-width: 30px !default; +// $carousel-indicator-height: 3px !default; +// $carousel-indicator-hit-area-height: 10px !default; +// $carousel-indicator-spacer: 3px !default; +// $carousel-indicator-opacity: .5 !default; +// $carousel-indicator-active-bg: $white !default; +// $carousel-indicator-active-opacity: 1 !default; +// $carousel-indicator-transition: opacity .6s ease !default; + +// $carousel-caption-width: 70% !default; +// $carousel-caption-color: $high-emphasis-inverse !default; +// $carousel-caption-padding-y: 1.25rem !default; +// $carousel-caption-spacer: 1.25rem !default; + +// $carousel-control-icon-width: 2rem !default; + +// $carousel-control-prev-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$carousel-control-color}'><path d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/></svg>") !default; +// $carousel-control-next-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$carousel-control-color}'><path d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/></svg>") !default; + +// $carousel-transition-duration: .6s !default; +// $carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`) + +// $carousel-dark-indicator-active-bg: $black !default; +// $carousel-dark-caption-color: $high-emphasis !default; +// $carousel-dark-control-icon-filter: invert(1) grayscale(100) !default; +// scss-docs-end carousel-variables + +// scss-docs-start sidebar-variables +// $sidebar-width: 16rem !default; +// $sidebar-widths: ( +// sm: 12rem, +// lg: 20rem, +// xl: 24rem +// ) !default; +// $sidebar-padding-y: 0 !default; +// $sidebar-padding-x: 0 !default; +// $sidebar-color: $high-emphasis-inverse !default; +// $sidebar-bg: $gray-base !default; +// $sidebar-border-width: 0 !default; +// $sidebar-border-color: transparent !default; +// $sidebar-transition: margin-left .15s, margin-right .15s, box-shadow .075s, transform .15s, width .15s, z-index 0s ease .15s !default; + +// $sidebar-brand-height: 4rem !default; +// $sidebar-brand-color: $high-emphasis-inverse !default; +// $sidebar-brand-bg: rgba($black, .2) !default; + +// $sidebar-header-height: 4rem !default; +// $sidebar-header-padding-y: .75rem !default; +// $sidebar-header-padding-x: 1rem !default; +// $sidebar-header-bg: rgba($black, .2) !default; +// $sidebar-header-height-transition: height .15s, padding .15s !default; + +// $sidebar-narrow-width: 4rem !default; + +// $sidebar-backdrop-bg: $black !default; +// $sidebar-backdrop-opacity: .5 !default; +// $sidebar-backdrop-transition: opacity .15s linear !default; + +// $sidebar-nav-title-padding-y: .75rem !default; +// $sidebar-nav-title-padding-x: 1rem !default; +// $sidebar-nav-title-margin-top: 1rem !default; +// $sidebar-nav-title-color: $medium-emphasis-inverse !default; +// $sidebar-nav-title-transition: height .15s, margin .15s !default; + +// $sidebar-nav-link-padding-y: .8445rem !default; +// $sidebar-nav-link-padding-x: 1rem !default; +// $sidebar-nav-link-color: $medium-emphasis-inverse !default; +// $sidebar-nav-link-bg: transparent !default; +// $sidebar-nav-link-transition: background .15s ease, color .15s ease !default; +// $sidebar-nav-link-icon-color: $medium-emphasis-inverse !default; + +// $sidebar-nav-link-hover-color: $high-emphasis-inverse !default; +// $sidebar-nav-link-hover-bg: rgba($white, .05) !default; +// $sidebar-nav-link-hover-icon-color: $high-emphasis-inverse !default; + +// $sidebar-nav-link-active-color: $high-emphasis-inverse !default; +// $sidebar-nav-link-active-bg: rgba($white, .05) !default; +// $sidebar-nav-link-active-icon-color: $high-emphasis-inverse !default; + +// $sidebar-nav-link-disabled-color: $disabled-inverse !default; +// $sidebar-nav-link-disabled-icon-color: $sidebar-nav-link-icon-color !default; + +// $sidebar-nav-icon-width: 4rem !default; +// $sidebar-nav-icon-height: 1.25rem !default; +// $sidebar-nav-icon-font-size: $sidebar-nav-icon-height !default; + +// $sidebar-nav-group-bg: rgba(0, 0, 0, .2) !default; +// $sidebar-nav-group-transition: background .15s ease-in-out !default; +// $sidebar-nav-group-items-transition: height .15s ease !default; +// $sidebar-nav-group-toggle-show-color: $sidebar-nav-link-color !default; + +// $sidebar-nav-group-indicator-color: $medium-emphasis-inverse !default; +// $sidebar-nav-group-indicator-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$sidebar-nav-group-indicator-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default; +// $sidebar-nav-group-indicator-hover-color: $sidebar-nav-link-hover-color !default; +// $sidebar-nav-group-indicator-hover-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$sidebar-nav-group-indicator-hover-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default; +// $sidebar-nav-group-indicator-transition: transform .15s !default; + +// $sidebar-footer-height: auto !default; +// $sidebar-footer-padding-y: .75rem !default; +// $sidebar-footer-padding-x: 1rem !default; +// $sidebar-footer-bg: rgba($black, .2) !default; +// $sidebar-footer-height-transition: height .15s, padding .15s !default; + +// $sidebar-toggler-height: 3rem !default; +// $sidebar-toggler-bg: rgba($black, .2) !default; +// $sidebar-toggler-transition: transform .15s !default; + +// $sidebar-toggler-indicator-width: 4rem !default; +// $sidebar-toggler-indicator-height: 3rem !default; +// $sidebar-toggler-indicator-color: $gray-600 !default; +// $sidebar-toggler-indicator-icon: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 14'%3E%3Cpath fill='#{$sidebar-toggler-indicator-color}' d='M9.148 2.352l-4.148 4.148 4.148 4.148q0.148 0.148 0.148 0.352t-0.148 0.352l-1.297 1.297q-0.148 0.148-0.352 0.148t-0.352-0.148l-5.797-5.797q-0.148-0.148-0.148-0.352t0.148-0.352l5.797-5.797q0.148-0.148 0.352-0.148t0.352 0.148l1.297 1.297q0.148 0.148 0.148 0.352t-0.148 0.352z'/%3E%3C/svg%3E") !default; +// $sidebar-toggler-hover-bg: rgba(0, 0, 0, .3) !default; +// $sidebar-toggler-indicator-hover-color: $sidebar-nav-link-hover-color !default; +// $sidebar-toggler-indicator-hover-icon: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 14'%3E%3Cpath fill='#{$sidebar-toggler-indicator-hover-color}' d='M9.148 2.352l-4.148 4.148 4.148 4.148q0.148 0.148 0.148 0.352t-0.148 0.352l-1.297 1.297q-0.148 0.148-0.352 0.148t-0.352-0.148l-5.797-5.797q-0.148-0.148-0.148-0.352t0.148-0.352l5.797-5.797q0.148-0.148 0.352-0.148t0.352 0.148l1.297 1.297q0.148 0.148 0.148 0.352t-0.148 0.352z'/%3E%3C/svg%3E") !default; +// scss-docs-end sidebar-variables + +// Footer +// scss-docs-start footer-variables +// $footer-min-height: 3rem !default; +// $footer-padding-y: $spacer / 2 !default; +// $footer-padding-x: $spacer !default; +// $footer-bg: $gray-100 !default; +// $footer-color: $body-color !default; +// $footer-border-width: 1px !default; +// $footer-border-color: $border-color !default; +// scss-docs-end footer-variables + +// Spinners +// scss-docs-start spinner-variables +// $spinner-width: 2rem !default; +// $spinner-height: $spinner-width !default; +// $spinner-vertical-align: -.125em !default; +// $spinner-border-width: .25em !default; +// $spinner-animation-speed: .75s !default; + +// $spinner-width-sm: 1rem !default; +// $spinner-height-sm: $spinner-width-sm !default; +// $spinner-border-width-sm: .2em !default; +// scss-docs-end spinner-variables + + +// Close +// scss-docs-start close-variables +// $btn-close-width: 1em !default; +// $btn-close-height: $btn-close-width !default; +// $btn-close-padding-x: .25em !default; +// $btn-close-padding-y: $btn-close-padding-x !default; +// $btn-close-color: $high-emphasis !default; +// $btn-close-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$btn-close-color}'><path d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/></svg>") !default; +// $btn-close-focus-shadow: $input-btn-focus-box-shadow !default; +// $btn-close-opacity: .5 !default; +// $btn-close-hover-opacity: .75 !default; +// $btn-close-focus-opacity: 1 !default; +// $btn-close-disabled-opacity: .25 !default; +// $btn-close-white-filter: invert(1) grayscale(100%) brightness(200%) !default; +// scss-docs-end close-variables + + +// Offcanvas + +// scss-docs-start offcanvas-variables +// $offcanvas-padding-y: $modal-inner-padding !default; +// $offcanvas-padding-x: $modal-inner-padding !default; +// $offcanvas-horizontal-width: 400px !default; +// $offcanvas-vertical-height: 30vh !default; +// $offcanvas-transition-duration: .3s !default; +// $offcanvas-border-color: $modal-content-border-color !default; +// $offcanvas-border-width: $modal-content-border-width !default; +// $offcanvas-title-line-height: $modal-title-line-height !default; +// $offcanvas-bg-color: $modal-content-bg !default; +// $offcanvas-color: $modal-content-color !default; +// $offcanvas-box-shadow: $modal-content-box-shadow-xs !default; +// scss-docs-end offcanvas-variables + +// Code + +// $code-font-size: $small-font-size !default; +// $code-color: $pink !default; + +// $kbd-padding-y: .2rem !default; +// $kbd-padding-x: .4rem !default; +// $kbd-font-size: $code-font-size !default; +// $kbd-color: $high-emphasis-inverse !default; +// $kbd-bg: $gray-900 !default; + +// $pre-color: unset !default; diff --git a/src/scss/style.scss b/src/scss/style.scss new file mode 100644 index 00000000..02f199c4 --- /dev/null +++ b/src/scss/style.scss @@ -0,0 +1,17 @@ +// If you want to override variables do it here +@import "variables"; + +$enable-ltr: true; +$enable-rtl: true; + +// Import CoreUI for React components library +@import "@coreui/coreui/scss/coreui"; + +// Import Chart.js custom tooltips styles +@import "@coreui/chartjs/scss/coreui-chartjs"; + +@import "layout"; +@import "example"; + +// If you want to add custom CSS you can put it here. +@import "custom"; diff --git a/src/setupTests.js b/src/setupTests.js new file mode 100644 index 00000000..52aaef1d --- /dev/null +++ b/src/setupTests.js @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom' diff --git a/src/store.js b/src/store.js new file mode 100644 index 00000000..ab446364 --- /dev/null +++ b/src/store.js @@ -0,0 +1,17 @@ +import { createStore } from 'redux' + +const initialState = { + sidebarShow: true, +} + +const changeState = (state = initialState, { type, ...rest }) => { + switch (type) { + case 'set': + return { ...state, ...rest } + default: + return state + } +} + +const store = createStore(changeState) +export default store diff --git a/src/views/base/accordion/Accordion.js b/src/views/base/accordion/Accordion.js new file mode 100644 index 00000000..21e88215 --- /dev/null +++ b/src/views/base/accordion/Accordion.js @@ -0,0 +1,177 @@ +import React from 'react' +import { + CCard, + CCardBody, + CCardHeader, + CCol, + CRow, + CAccordion, + CAccordionBody, + CAccordionHeader, + CAccordionItem, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const Accordion = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Accordion</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Click the accordions below to expand/collapse the accordion content. + </p> + <DocsExample href="components/accordion"> + <CAccordion activeItemKey={2}> + <CAccordionItem itemKey={1}> + <CAccordionHeader>Accordion Item #1</CAccordionHeader> + <CAccordionBody> + <strong>This is the first item's accordion body.</strong> It is hidden by + default, until the collapse plugin adds the appropriate classes that we use to + style each element. These classes control the overall appearance, as well as the + showing and hiding via CSS transitions. You can modify any of this with custom + CSS or overriding our default variables. It's also worth noting that just + about any HTML can go within the <code>.accordion-body</code>, though the + transition does limit overflow. + </CAccordionBody> + </CAccordionItem> + <CAccordionItem itemKey={2}> + <CAccordionHeader>Accordion Item #2</CAccordionHeader> + <CAccordionBody> + <strong>This is the second item's accordion body.</strong> It is hidden by + default, until the collapse plugin adds the appropriate classes that we use to + style each element. These classes control the overall appearance, as well as the + showing and hiding via CSS transitions. You can modify any of this with custom + CSS or overriding our default variables. It's also worth noting that just + about any HTML can go within the <code>.accordion-body</code>, though the + transition does limit overflow. + </CAccordionBody> + </CAccordionItem> + <CAccordionItem itemKey={3}> + <CAccordionHeader>Accordion Item #3</CAccordionHeader> + <CAccordionBody> + <strong>This is the second item's accordion body.</strong> It is hidden by + default, until the collapse plugin adds the appropriate classes that we use to + style each element. These classes control the overall appearance, as well as the + showing and hiding via CSS transitions. You can modify any of this with custom + CSS or overriding our default variables. It's also worth noting that just + about any HTML can go within the <code>.accordion-body</code>, though the + transition does limit overflow. + </CAccordionBody> + </CAccordionItem> + </CAccordion> + </DocsExample> + </CCardBody> + </CCard> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Accordion</strong> <small>Flush</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>flush</code> to remove the default <code>background-color</code>, some + borders, and some rounded corners to render accordions edge-to-edge with their parent + container. + </p> + <DocsExample href="components/accordion#flush"> + <CAccordion flush> + <CAccordionItem itemKey={1}> + <CAccordionHeader>Accordion Item #1</CAccordionHeader> + <CAccordionBody> + <strong>This is the first item's accordion body.</strong> It is hidden by + default, until the collapse plugin adds the appropriate classes that we use to + style each element. These classes control the overall appearance, as well as the + showing and hiding via CSS transitions. You can modify any of this with custom + CSS or overriding our default variables. It's also worth noting that just + about any HTML can go within the <code>.accordion-body</code>, though the + transition does limit overflow. + </CAccordionBody> + </CAccordionItem> + <CAccordionItem itemKey={2}> + <CAccordionHeader>Accordion Item #2</CAccordionHeader> + <CAccordionBody> + <strong>This is the second item's accordion body.</strong> It is hidden by + default, until the collapse plugin adds the appropriate classes that we use to + style each element. These classes control the overall appearance, as well as the + showing and hiding via CSS transitions. You can modify any of this with custom + CSS or overriding our default variables. It's also worth noting that just + about any HTML can go within the <code>.accordion-body</code>, though the + transition does limit overflow. + </CAccordionBody> + </CAccordionItem> + <CAccordionItem itemKey={3}> + <CAccordionHeader>Accordion Item #3</CAccordionHeader> + <CAccordionBody> + <strong>This is the second item's accordion body.</strong> It is hidden by + default, until the collapse plugin adds the appropriate classes that we use to + style each element. These classes control the overall appearance, as well as the + showing and hiding via CSS transitions. You can modify any of this with custom + CSS or overriding our default variables. It's also worth noting that just + about any HTML can go within the <code>.accordion-body</code>, though the + transition does limit overflow. + </CAccordionBody> + </CAccordionItem> + </CAccordion> + </DocsExample> + </CCardBody> + </CCard> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Accordion</strong> <small>Always open</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>alwaysOpen</code> property to make accordion items stay open when another + item is opened. + </p> + <DocsExample href="components/accordion#flush"> + <CAccordion alwaysOpen> + <CAccordionItem itemKey={1}> + <CAccordionHeader>Accordion Item #1</CAccordionHeader> + <CAccordionBody> + <strong>This is the first item's accordion body.</strong> It is hidden by + default, until the collapse plugin adds the appropriate classes that we use to + style each element. These classes control the overall appearance, as well as the + showing and hiding via CSS transitions. You can modify any of this with custom + CSS or overriding our default variables. It's also worth noting that just + about any HTML can go within the <code>.accordion-body</code>, though the + transition does limit overflow. + </CAccordionBody> + </CAccordionItem> + <CAccordionItem itemKey={2}> + <CAccordionHeader>Accordion Item #2</CAccordionHeader> + <CAccordionBody> + <strong>This is the second item's accordion body.</strong> It is hidden by + default, until the collapse plugin adds the appropriate classes that we use to + style each element. These classes control the overall appearance, as well as the + showing and hiding via CSS transitions. You can modify any of this with custom + CSS or overriding our default variables. It's also worth noting that just + about any HTML can go within the <code>.accordion-body</code>, though the + transition does limit overflow. + </CAccordionBody> + </CAccordionItem> + <CAccordionItem itemKey={3}> + <CAccordionHeader>Accordion Item #3</CAccordionHeader> + <CAccordionBody> + <strong>This is the second item's accordion body.</strong> It is hidden by + default, until the collapse plugin adds the appropriate classes that we use to + style each element. These classes control the overall appearance, as well as the + showing and hiding via CSS transitions. You can modify any of this with custom + CSS or overriding our default variables. It's also worth noting that just + about any HTML can go within the <code>.accordion-body</code>, though the + transition does limit overflow. + </CAccordionBody> + </CAccordionItem> + </CAccordion> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Accordion diff --git a/src/views/base/breadcrumbs/Breadcrumbs.js b/src/views/base/breadcrumbs/Breadcrumbs.js new file mode 100644 index 00000000..8ddd0cc0 --- /dev/null +++ b/src/views/base/breadcrumbs/Breadcrumbs.js @@ -0,0 +1,74 @@ +import React from 'react' +import { + CBreadcrumb, + CBreadcrumbItem, + CCard, + CCardBody, + CCardHeader, + CCol, + CRow, + CLink, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const Breadcrumbs = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Breadcrumb</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + The breadcrumb navigation provides links back to each previous page the user navigated + through and shows the current location in a website or an application. You don’t have + to add separators, because they automatically added in CSS through{' '} + <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/::before"> + {' '} + <code>::before</code> + </a>{' '} + and{' '} + <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/content"> + {' '} + <code>content</code> + </a> + . + </p> + <DocsExample href="components/breadcrumb"> + <CBreadcrumb> + <CBreadcrumbItem> + <CLink href="#">Home</CLink> + </CBreadcrumbItem> + <CBreadcrumbItem active>Library</CBreadcrumbItem> + </CBreadcrumb> + <CBreadcrumb> + <CBreadcrumbItem> + <CLink href="#">Home</CLink> + </CBreadcrumbItem> + <CBreadcrumbItem> + <CLink href="#">Library</CLink> + </CBreadcrumbItem> + <CBreadcrumbItem active>Data</CBreadcrumbItem> + </CBreadcrumb> + <CBreadcrumb> + <CBreadcrumbItem> + <CLink href="#">Home</CLink> + </CBreadcrumbItem> + <CBreadcrumbItem> + <CLink href="#">Library</CLink> + </CBreadcrumbItem> + <CBreadcrumbItem> + <CLink href="#">Data</CLink> + </CBreadcrumbItem> + <CBreadcrumbItem active>Bootstrap</CBreadcrumbItem> + </CBreadcrumb> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Breadcrumbs diff --git a/src/views/base/cards/Cards.js b/src/views/base/cards/Cards.js new file mode 100644 index 00000000..b9bdfffc --- /dev/null +++ b/src/views/base/cards/Cards.js @@ -0,0 +1,906 @@ +import React from 'react' +import { + CButton, + CCard, + CCardBody, + CCardFooter, + CCardGroup, + CCardHeader, + CCardImage, + CCardLink, + CCardSubtitle, + CCardText, + CCardTitle, + CListGroup, + CListGroupItem, + CNav, + CNavItem, + CNavLink, + CCol, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +import ReactImg from 'src/assets/images/react.jpg' + +const Cards = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Example</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Cards are built with as little markup and styles as possible but still manage to + deliver a bunch of control and customization. Built with flexbox, they offer easy + alignment and mix well with other CoreUI components. Cards have no top, left, and + right margins by default, so use{' '} + <a href="https://coreui.io/docs/utilities/spacing">spacing utilities</a> as needed. + They have no fixed width to start, so they'll fill the full width of its parent. + </p> + <p className="text-medium-emphasis small"> + Below is an example of a basic card with mixed content and a fixed width. Cards have + no fixed width to start, so they'll naturally fill the full width of its parent + element. + </p> + <DocsExample href="components/card"> + <CCard style={{ width: '18rem' }}> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + Some quick example text to build on the card title and make up the bulk of the + card's content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Body</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + The main block of a card is the <code><CCardBody></code>. Use it whenever you + need a padded section within a card. + </p> + <DocsExample href="components/card/#body"> + <CCard> + <CCardBody>This is some text within a card body.</CCardBody> + </CCard> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Titles, text, and links</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Card titles are managed by <code><CCardTitle></code> component. Identically, + links are attached and collected next to each other by <code><CCardLink></code>{' '} + component. + </p> + <p className="text-medium-emphasis small"> + Subtitles are managed by <code><CCardSubtitle></code> component. If the{' '} + <code><CCardTitle></code> also, the <code><CCardSubtitle></code> items are + stored in a <code><CCardBody></code> item, the card title, and subtitle are + arranged rightly. + </p> + <DocsExample href="components/card/#titles-text-and-links"> + <CCard style={{ width: '18rem' }}> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardSubtitle className="mb-2 text-medium-emphasis">Card subtitle</CCardSubtitle> + <CCardText> + Some quick example text to build on the card title and make up the bulk of the + card's content. + </CCardText> + <CCardLink href="#">Card link</CCardLink> + <CCardLink href="#">Another link</CCardLink> + </CCardBody> + </CCard> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Images</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + <code>.card-img-top</code> places a picture to the top of the card. With{' '} + <code>.card-text</code>, text can be added to the card. Text within{' '} + <code>.card-text</code> can additionally be styled with the regular HTML tags. + </p> + <DocsExample href="components/card/#images"> + <CCard style={{ width: '18rem' }}> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardText> + Some quick example text to build on the card title and make up the bulk of the + card's content. + </CCardText> + </CCardBody> + </CCard> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>List groups</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Create lists of content in a card with a flush list group. + </p> + <DocsExample href="components/card/#list-groups"> + <CRow> + <CCol lg={4}> + <CCard> + <CListGroup flush> + <CListGroupItem>Cras justo odio</CListGroupItem> + <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> + <CListGroupItem>Vestibulum at eros</CListGroupItem> + </CListGroup> + </CCard> + </CCol> + <CCol lg={4}> + <CCard> + <CCardHeader>Header</CCardHeader> + <CListGroup flush> + <CListGroupItem>Cras justo odio</CListGroupItem> + <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> + <CListGroupItem>Vestibulum at eros</CListGroupItem> + </CListGroup> + </CCard> + </CCol> + <CCol lg={4}> + <CCard> + <CListGroup flush> + <CListGroupItem>Cras justo odio</CListGroupItem> + <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> + <CListGroupItem>Vestibulum at eros</CListGroupItem> + </CListGroup> + <CCardFooter>Footer</CCardFooter> + </CCard> + </CCol> + </CRow> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Kitchen sink</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Combine and match many content types to build the card you need, or throw everything + in there. Shown below are image styles, blocks, text styles, and a list group—all + wrapped in a fixed-width card. + </p> + <DocsExample href="components/card/#kitchen-sink"> + <CCard style={{ width: '18rem' }}> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + Some quick example text to build on the card title and make up the bulk of the + card's content. + </CCardText> + </CCardBody> + <CListGroup flush> + <CListGroupItem>Cras justo odio</CListGroupItem> + <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> + <CListGroupItem>Vestibulum at eros</CListGroupItem> + </CListGroup> + <CCardBody> + <CCardLink href="#">Card link</CCardLink> + <CCardLink href="#">Another link</CCardLink> + </CCardBody> + </CCard> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Header and footer</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add an optional header and/or footer within a card. + </p> + <DocsExample href="components/card/#header-and-footer"> + <CCard> + <CCardHeader>Header</CCardHeader> + <CCardBody> + <CCardTitle>Special title treatment</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + </DocsExample> + <p className="text-medium-emphasis small"> + Card headers can be styled by adding ex. <code>component="h5"</code>. + </p> + <DocsExample href="components/card/#header-and-footer"> + <CCard> + <CCardHeader component="h5">Header</CCardHeader> + <CCardBody> + <CCardTitle>Special title treatment</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + </DocsExample> + <DocsExample href="components/card/#header-and-footer"> + <CCard> + <CCardHeader>Quote</CCardHeader> + <CCardBody> + <blockquote className="blockquote mb-0"> + <p> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat + a ante. + </p> + <footer className="blockquote-footer"> + Someone famous in <cite title="Source Title">Source Title</cite> + </footer> + </blockquote> + </CCardBody> + </CCard> + </DocsExample> + <DocsExample href="components/card/#header-and-footer"> + <CCard className="text-center"> + <CCardHeader>Header</CCardHeader> + <CCardBody> + <CCardTitle>Special title treatment</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + <CCardFooter className="text-medium-emphasis">2 days ago</CCardFooter> + </CCard> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Body</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Cards assume no specific <code>width</code> to start, so they'll be 100% wide + unless otherwise stated. You can adjust this as required with custom CSS, grid + classes, grid Sass mixins, or services. + </p> + <h3>Using grid markup</h3> + <p className="text-medium-emphasis small"> + Using the grid, wrap cards in columns and rows as needed. + </p> + <DocsExample href="components/card/#sizing"> + <CRow> + <CCol sm={6}> + <CCard> + <CCardBody> + <CCardTitle>Special title treatment</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + </CCol> + <CCol sm={6}> + <CCard> + <CCardBody> + <CCardTitle>Special title treatment</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + </CCol> + </CRow> + </DocsExample> + <h3>Using utilities</h3> + <p className="text-medium-emphasis small"> + Use some of{' '} + <a href="https://coreui.io/docs/utilities/sizing/">available sizing utilities</a> to + rapidly set a card's width. + </p> + <DocsExample href="components/card/#sizing"> + <CCard className="w-75"> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + <CCard className="w-50"> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + </DocsExample> + <strong>Using custom CSS</strong> + <p className="text-medium-emphasis small"> + Use custom CSS in your stylesheets or as inline styles to set a width. + </p> + <DocsExample href="components/card/#sizing"> + <CCard style={{ width: '18rem' }}> + <CCardBody> + <CCardTitle>Special title treatment</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Text alignment</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + You can instantly change the text arrangement of any card—in its whole or specific + parts—with{' '} + <a href="https://coreui.io/docs/utilities/text/#text-alignment">text align classes</a> + . + </p> + <DocsExample href="components/card/#text-alignment"> + <CCard style={{ width: '18rem' }}> + <CCardBody> + <CCardTitle>Special title treatment</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + <CCard className="text-center" style={{ width: '18rem' }}> + <CCardBody> + <CCardTitle>Special title treatment</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + <CCard className="text-end" style={{ width: '18rem' }}> + <CCardBody> + <CCardTitle>Special title treatment</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Navigation</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add some navigation to a <code><CCardHeader></code> with our{' '} + <code><CNav></code> component. + </p> + <DocsExample href="components/card/##navigation"> + <CCard className="text-center"> + <CCardHeader> + <CNav variant="tabs" className="card-header-tabs"> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </CCardHeader> + <CCardBody> + <CCardTitle>Special title treatment</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + </DocsExample> + <DocsExample href="components/card/##navigation"> + <CCard className="text-center"> + <CCardHeader> + <CNav variant="pills" className="card-header-pills"> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </CCardHeader> + <CCardBody> + <CCardTitle>Special title treatment</CCardTitle> + <CCardText> + With supporting text below as a natural lead-in to additional content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Image caps</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Similar to headers and footers, cards can include top and bottom "image + caps"—images at the top or bottom of a card. + </p> + <DocsExample href="components/card/#image-caps"> + <CRow> + <CCol lg={6}> + <CCard className="mb-3"> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + <CCardText> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardText> + </CCardBody> + </CCard> + </CCol> + <CCol lg={6}> + <CCard className="mb-3"> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + <CCardText> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardText> + </CCardBody> + <CCardImage orientation="bottom" src={ReactImg} /> + </CCard> + </CCol> + </CRow> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Card styles</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Cards include various options for customizing their backgrounds, borders, and color. + </p> + <h3>Background and color</h3> + <p className="text-medium-emphasis small"> + Use <code>color</code> property to change the appearance of a card. + </p> + <DocsExample href="components/card/#background-and-color"> + <CRow> + {[ + { color: 'primary', textColor: 'white' }, + { color: 'secondary', textColor: 'white' }, + { color: 'success', textColor: 'white' }, + { color: 'danger', textColor: 'white' }, + { color: 'warning' }, + { color: 'info', textColor: 'white' }, + { color: 'light' }, + { color: 'dark', textColor: 'white' }, + ].map((item, index) => ( + <CCol lg={4} key={index}> + <CCard color={item.color} textColor={item.textColor} className="mb-3"> + <CCardHeader>Header</CCardHeader> + <CCardBody> + <CCardTitle>{item.color} card title</CCardTitle> + <CCardText> + Some quick example text to build on the card title and make up the bulk of + the card's content. + </CCardText> + </CCardBody> + </CCard> + </CCol> + ))} + </CRow> + </DocsExample> + <h3>Border</h3> + <p className="text-medium-emphasis small"> + Use <a href="https://coreui.io/docs/utilities/borders/">border utilities</a> to change + just the <code>border-color</code> of a card. Note that you can set{' '} + <code>textColor</code> property on the <code><CCard></code> or a subset of the + card's contents as shown below. + </p> + <DocsExample href="components/card/#border"> + <CRow> + {[ + { color: 'primary', textColor: 'primary' }, + { color: 'secondary', textColor: 'secondary' }, + { color: 'success', textColor: 'success' }, + { color: 'danger', textColor: 'danger' }, + { color: 'warning', textColor: 'warning' }, + { color: 'info', textColor: 'info' }, + { color: 'light' }, + { color: 'dark' }, + ].map((item, index) => ( + <CCol lg={4} key={index}> + <CCard textColor={item.textColor} className={`mb-3 border-${item.color}`}> + <CCardHeader>Header</CCardHeader> + <CCardBody> + <CCardTitle>{item.color} card title</CCardTitle> + <CCardText> + Some quick example text to build on the card title and make up the bulk of + the card's content. + </CCardText> + </CCardBody> + </CCard> + </CCol> + ))} + </CRow> + </DocsExample> + <h3>Top border</h3> + <p className="text-medium-emphasis small"> + Use <a href="https://coreui.io/docs/utilities/borders/">border utilities</a> to change + just the <code>border-color</code> of a card. Note that you can set{' '} + <code>textColor</code> property on the <code><CCard></code> or a subset of the + card's contents as shown below. + </p> + <DocsExample href="components/card/#top-border"> + <CRow> + {[ + { color: 'primary', textColor: 'primary' }, + { color: 'secondary', textColor: 'secondary' }, + { color: 'success', textColor: 'success' }, + { color: 'danger', textColor: 'danger' }, + { color: 'warning', textColor: 'warning' }, + { color: 'info', textColor: 'info' }, + { color: 'light' }, + { color: 'dark' }, + ].map((item, index) => ( + <CCol lg={4} key={index}> + <CCard + textColor={item.textColor} + className={`mb-3 border-top-${item.color} border-top-3`} + > + <CCardHeader>Header</CCardHeader> + <CCardBody> + <CCardTitle>{item.color} card title</CCardTitle> + <CCardText> + Some quick example text to build on the card title and make up the bulk of + the card's content. + </CCardText> + </CCardBody> + </CCard> + </CCol> + ))} + </CRow> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Card groups</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use card groups to render cards as a single, attached element with equal width and + height columns. Card groups start off stacked and use <code>display: flex;</code> to + become attached with uniform dimensions starting at the <code>sm</code> breakpoint. + </p> + <DocsExample href="components/card/#card-groups"> + <CCardGroup> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + <CCardText> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardText> + </CCardBody> + </CCard> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This card has supporting text below as a natural lead-in to additional + content. + </CCardText> + <CCardText> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardText> + </CCardBody> + </CCard> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This card has even longer content than the first to show + that equal height action. + </CCardText> + <CCardText> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardText> + </CCardBody> + </CCard> + </CCardGroup> + </DocsExample> + <p className="text-medium-emphasis small"> + When using card groups with footers, their content will automatically line up. + </p> + <DocsExample href="components/card/#card-groups"> + <CCardGroup> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + </CCardBody> + <CCardFooter> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardFooter> + </CCard> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This card has supporting text below as a natural lead-in to additional + content. + </CCardText> + </CCardBody> + <CCardFooter> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardFooter> + </CCard> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This card has even longer content than the first to show + that equal height action. + </CCardText> + </CCardBody> + <CCardFooter> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardFooter> + </CCard> + </CCardGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Card</strong> <small>Grid cards</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use the <code>CRow</code> component and set{' '} + <code>{xs|sm|md|lg|xl|xxl}={{ cols: * }}</code> property + to control how many grid columns (wrapped around your cards) you show per row. For + example, here's <code>xs={{cols: 1}}</code> laying out the + cards on one column, and <code>md={{cols: 1}}</code> splitting + four cards to equal width across multiple rows, from the medium breakpoint up. + </p> + <DocsExample href="components/card/#grid-cards"> + <CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 2 }}> + <CCol xs> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + </CCardBody> + <CCardFooter> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardFooter> + </CCard> + </CCol> + <CCol xs> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + </CCardBody> + <CCardFooter> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardFooter> + </CCard> + </CCol> + <CCol xs> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + </CCardBody> + <CCardFooter> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardFooter> + </CCard> + </CCol> + <CCol xs> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + </CCardBody> + <CCardFooter> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardFooter> + </CCard> + </CCol> + </CRow> + </DocsExample> + <p className="text-medium-emphasis small"> + Change it to <code>md={{ cols: 3}}</code> and you'll see the + fourth card wrap. + </p> + <DocsExample href="components/card/#grid-cards"> + <CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 3 }}> + <CCol xs> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + </CCardBody> + <CCardFooter> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardFooter> + </CCard> + </CCol> + <CCol xs> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + </CCardBody> + <CCardFooter> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardFooter> + </CCard> + </CCol> + <CCol xs> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + </CCardBody> + <CCardFooter> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardFooter> + </CCard> + </CCol> + <CCol xs> + <CCard> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + This is a wider card with supporting text below as a natural lead-in to + additional content. This content is a little bit longer. + </CCardText> + </CCardBody> + <CCardFooter> + <small className="text-medium-emphasis">Last updated 3 mins ago</small> + </CCardFooter> + </CCard> + </CCol> + </CRow> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Cards diff --git a/src/views/base/carousels/Carousels.js b/src/views/base/carousels/Carousels.js new file mode 100644 index 00000000..3f09b3b3 --- /dev/null +++ b/src/views/base/carousels/Carousels.js @@ -0,0 +1,212 @@ +import React from 'react' +import { + CCard, + CCardBody, + CCardHeader, + CCarousel, + CCarouselCaption, + CCarouselItem, + CCol, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +import AngularImg from 'src/assets/images/angular.jpg' +import ReactImg from 'src/assets/images/react.jpg' +import VueImg from 'src/assets/images/vue.jpg' + +const slidesLight = [ + 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22800%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20800%20400%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_1607923e7e2%20text%20%7B%20fill%3A%23AAA%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A40pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_1607923e7e2%22%3E%3Crect%20width%3D%22800%22%20height%3D%22400%22%20fill%3D%22%23F5F5F5%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22285.9296875%22%20y%3D%22217.75625%22%3EFirst%20slide%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E', + 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22800%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20800%20400%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_15ba800aa20%20text%20%7B%20fill%3A%23BBB%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A40pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_15ba800aa20%22%3E%3Crect%20width%3D%22800%22%20height%3D%22400%22%20fill%3D%22%23EEE%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22247.3203125%22%20y%3D%22218.3%22%3ESecond%20slide%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E', + 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22800%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20800%20400%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_15ba800aa21%20text%20%7B%20fill%3A%23999%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A40pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_15ba800aa21%22%3E%3Crect%20width%3D%22800%22%20height%3D%22400%22%20fill%3D%22%23E5E5E5%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22277%22%20y%3D%22218.3%22%3EThird%20slide%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E', +] + +const Carousels = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Carousel</strong> <small>Slide only</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small">Here’s a carousel with slides</p> + <DocsExample href="components/carousel"> + <CCarousel> + <CCarouselItem> + <img className="d-block w-100" src={ReactImg} alt="slide 1" /> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={AngularImg} alt="slide 2" /> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={VueImg} alt="slide 3" /> + </CCarouselItem> + </CCarousel> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Carousel</strong> <small>With controls</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Adding in the previous and next controls by <code>controls</code> property. + </p> + <DocsExample href="components/carousel/#with-controls"> + <CCarousel controls> + <CCarouselItem> + <img className="d-block w-100" src={ReactImg} alt="slide 1" /> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={AngularImg} alt="slide 2" /> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={VueImg} alt="slide 3" /> + </CCarouselItem> + </CCarousel> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Carousel</strong> <small>With indicators</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + You can attach the indicators to the carousel, lengthwise the controls, too. + </p> + <DocsExample href="components/carousel/#with-indicators"> + <CCarousel controls indicators> + <CCarouselItem> + <img className="d-block w-100" src={ReactImg} alt="slide 1" /> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={AngularImg} alt="slide 2" /> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={VueImg} alt="slide 3" /> + </CCarouselItem> + </CCarousel> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Carousel</strong> <small>With captions</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + You can add captions to slides with the <code><CCarouselCaption></code> element + within any <code><CCarouselItem></code>. They can be immediately hidden on + smaller viewports, as shown below, with optional{' '} + <a href="https://coreui.io/4.0/utilities/display">display utilities</a>. We hide them + with <code>.d-none</code> and draw them back on medium-sized devices with{' '} + <code>.d-md-block</code>. + </p> + <DocsExample href="components/carousel/#with-captions"> + <CCarousel controls indicators> + <CCarouselItem> + <img className="d-block w-100" src={ReactImg} alt="slide 1" /> + <CCarouselCaption className="d-none d-md-block"> + <h5>First slide label</h5> + <p>Some representative placeholder content for the first slide.</p> + </CCarouselCaption> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={AngularImg} alt="slide 2" /> + <CCarouselCaption className="d-none d-md-block"> + <h5>Second slide label</h5> + <p>Some representative placeholder content for the first slide.</p> + </CCarouselCaption> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={VueImg} alt="slide 3" /> + <CCarouselCaption className="d-none d-md-block"> + <h5>Third slide label</h5> + <p>Some representative placeholder content for the first slide.</p> + </CCarouselCaption> + </CCarouselItem> + </CCarousel> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Carousel</strong> <small>Crossfade</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>transition="crossfade"</code> to your carousel to animate slides + with a fade transition instead of a slide. + </p> + <DocsExample href="components/carousel/#crossfade"> + <CCarousel controls transition="crossfade"> + <CCarouselItem> + <img className="d-block w-100" src={ReactImg} alt="slide 1" /> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={AngularImg} alt="slide 2" /> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={VueImg} alt="slide 3" /> + </CCarouselItem> + </CCarousel> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Carousel</strong> <small>Dark variant</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>dark</code> property to the <code>CCarousel</code> for darker controls, + indicators, and captions. Controls have been inverted from their default white fill + with the <code>filter</code> CSS property. Captions and controls have additional Sass + variables that customize the <code>color</code> and <code>background-color</code>. + </p> + <DocsExample href="components/carousel/#dark-variant"> + <CCarousel controls indicators dark> + <CCarouselItem> + <img className="d-block w-100" src={slidesLight[0]} alt="slide 1" /> + <CCarouselCaption className="d-none d-md-block"> + <h5>First slide label</h5> + <p>Some representative placeholder content for the first slide.</p> + </CCarouselCaption> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={slidesLight[1]} alt="slide 2" /> + <CCarouselCaption className="d-none d-md-block"> + <h5>Second slide label</h5> + <p>Some representative placeholder content for the first slide.</p> + </CCarouselCaption> + </CCarouselItem> + <CCarouselItem> + <img className="d-block w-100" src={slidesLight[2]} alt="slide 3" /> + <CCarouselCaption className="d-none d-md-block"> + <h5>Third slide label</h5> + <p>Some representative placeholder content for the first slide.</p> + </CCarouselCaption> + </CCarouselItem> + </CCarousel> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Carousels diff --git a/src/views/base/collapses/Collapses.js b/src/views/base/collapses/Collapses.js new file mode 100644 index 00000000..37e608e0 --- /dev/null +++ b/src/views/base/collapses/Collapses.js @@ -0,0 +1,126 @@ +import React, { useState } from 'react' +import { CButton, CCard, CCardBody, CCardHeader, CCol, CCollapse, CRow } from '@coreui/react' +import { DocsExample } from 'src/components' + +const Collapses = () => { + const [visible, setVisible] = useState(false) + const [visibleHorizontal, setVisibleHorizontal] = useState(false) + const [visibleA, setVisibleA] = useState(false) + const [visibleB, setVisibleB] = useState(false) + + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Collapse</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small">You can use a link or a button component.</p> + <DocsExample href="components/collapse"> + <CButton + href="#" + onClick={(e) => { + e.preventDefault() + setVisible(!visible) + }} + > + Link + </CButton> + <CButton onClick={() => setVisible(!visible)}>Button</CButton> + <CCollapse visible={visible}> + <CCard className="mt-3"> + <CCardBody> + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry + richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes + anderson cred nesciunt sapiente ea proident. + </CCardBody> + </CCard> + </CCollapse> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Collapse</strong> <small> Horizontal</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small">You can use a link or a button component.</p> + <DocsExample href="components/collapse#horizontal"> + <CButton + className="mb-3" + onClick={() => setVisibleHorizontal(!visibleHorizontal)} + aria-expanded={visibleHorizontal} + aria-controls="collapseWidthExample" + > + Button + </CButton> + <div style={{ minHeight: '120px' }}> + <CCollapse id="collapseWidthExample" horizontal visible={visibleHorizontal}> + <CCard style={{ width: '300px' }}> + <CCardBody> + This is some placeholder content for a horizontal collapse. It's hidden by + default and shown when triggered. + </CCardBody> + </CCard> + </CCollapse> + </div> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Collapse</strong> <small> multi target</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + A <code><CButton></code> can show and hide multiple elements. + </p> + <DocsExample href="components/collapse#multiple-targets"> + <CButton onClick={() => setVisibleA(!visibleA)}>Toggle first element</CButton> + <CButton onClick={() => setVisibleB(!visibleB)}>Toggle second element</CButton> + <CButton + onClick={() => { + setVisibleA(!visibleA) + setVisibleB(!visibleB) + }} + > + Toggle both elements + </CButton> + <CRow> + <CCol xs={6}> + <CCollapse visible={visibleA}> + <CCard className="mt-3"> + <CCardBody> + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry + richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes + anderson cred nesciunt sapiente ea proident. + </CCardBody> + </CCard> + </CCollapse> + </CCol> + <CCol xs={6}> + <CCollapse visible={visibleB}> + <CCard className="mt-3"> + <CCardBody> + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry + richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes + anderson cred nesciunt sapiente ea proident. + </CCardBody> + </CCard> + </CCollapse> + </CCol> + </CRow> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Collapses diff --git a/src/views/base/index.js b/src/views/base/index.js new file mode 100644 index 00000000..2b7656c8 --- /dev/null +++ b/src/views/base/index.js @@ -0,0 +1,31 @@ +import Breadcrumbs from './Breadcrumbs' +import Cards from './Cards' +import Carousels from './Carousels' +import Collapses from './Collapses' +import Dropdowns from './Dropdowns' +import Jumbotrons from './Jumbotrons' +import ListGroups from './ListGroups' +import Navbars from './Navbars' +import Navs from './Navs' +import Paginations from './Paginations' +import Popovers from './Popovers' +import ProgressBar from './ProgressBar' +import Tabs from './Tabs' +import Tooltips from './Tooltips' + +export { + Breadcrumbs, + Cards, + Carousels, + Collapses, + Dropdowns, + Jumbotrons, + ListGroups, + Navbars, + Navs, + Popovers, + ProgressBar, + Tabs, + Tooltips, + Paginations, +} diff --git a/src/views/base/jumbotrons/Jumbotrons.js b/src/views/base/jumbotrons/Jumbotrons.js new file mode 100644 index 00000000..56068136 --- /dev/null +++ b/src/views/base/jumbotrons/Jumbotrons.js @@ -0,0 +1,56 @@ +import React from 'react' +import { CButton, CCard, CCardBody, CCardHeader, CCol, CContainer, CRow } from '@coreui/react' +import { DocsLink } from 'src/components' + +const Jumbotrons = () => { + return ( + <> + <CCard className="mb-4"> + <CCardHeader> + Jumbotron + <DocsLink name="CJumbotron" /> + </CCardHeader> + <CCardBody> + <CContainer className="py-5" fluid> + <h1 className="display-5 fw-bold">Custom jumbotron</h1> + <p className="col-md-8 fs-4"> + Using a series of utilities, you can create this jumbotron, just like the one in + previous versions of Bootstrap. Check out the examples below for how you can remix and + restyle it to your liking. + </p> + <CButton size="lg">Example button</CButton> + </CContainer> + <CRow className="align-items-md-stretch"> + <CCol md={6}> + <div className="h-100 p-5 text-white bg-dark rounded-3"> + <h2>Change the background</h2> + <p> + Swap the background-color utility and add a `.text-*` color utility to mix up the + jumbotron look. Then, mix and match with additional component themes and more. + </p> + <CButton color="light" variant="outline"> + DocsExample button + </CButton> + </div> + </CCol> + <CCol md={6}> + <div className="h-100 p-5 bg-light border rounded-3"> + <h2>Add borders</h2> + <p> + Or, keep it light and add a border for some added definition to the boundaries of + your content. Be sure to look under the hood at the source HTML here as we've + adjusted the alignment and sizing of both column's content for equal-height. + </p> + <CButton color="secondary" variant="outline"> + DocsExample button + </CButton> + </div> + </CCol> + </CRow> + </CCardBody> + </CCard> + </> + ) +} + +export default Jumbotrons diff --git a/src/views/base/list-groups/ListGroups.js b/src/views/base/list-groups/ListGroups.js new file mode 100644 index 00000000..91cfbf1e --- /dev/null +++ b/src/views/base/list-groups/ListGroups.js @@ -0,0 +1,346 @@ +import React from 'react' +import { + CBadge, + CCard, + CCardBody, + CCardHeader, + CCol, + CFormCheck, + CListGroup, + CListGroupItem, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const ListGroups = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React List Group</strong> <small>Basic example</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + The default list group is an unordered list with items and the proper CSS classes. + Build upon it with the options that follow, or with your CSS as required. + </p> + <DocsExample href="components/list-group"> + <CListGroup> + <CListGroupItem>Cras justo odio</CListGroupItem> + <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> + <CListGroupItem>Morbi leo risus</CListGroupItem> + <CListGroupItem>Porta ac consectetur ac</CListGroupItem> + <CListGroupItem>Vestibulum at eros</CListGroupItem> + </CListGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React List Group</strong> <small>Active items</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>active</code> boolean property to a <code><CListGroupItem></code> to + show the current active selection. + </p> + <DocsExample href="components/list-group/#active-items"> + <CListGroup> + <CListGroupItem active>Cras justo odio</CListGroupItem> + <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> + <CListGroupItem>Morbi leo risus</CListGroupItem> + <CListGroupItem>Porta ac consectetur ac</CListGroupItem> + <CListGroupItem>Vestibulum at eros</CListGroupItem> + </CListGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React List Group</strong> <small>Disabled items</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>disabled</code> boolean property to a <code><CListGroupItem></code> to + make it appear disabled. + </p> + <DocsExample href="components/list-group/#disabled-items"> + <CListGroup> + <CListGroupItem disabled>Cras justo odio</CListGroupItem> + <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> + <CListGroupItem>Morbi leo risus</CListGroupItem> + <CListGroupItem>Porta ac consectetur ac</CListGroupItem> + <CListGroupItem>Vestibulum at eros</CListGroupItem> + </CListGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React List Group</strong> <small>Links and buttons</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use <code><a></code>s or <code><button></code>s to create{' '} + <em>actionable</em> list group items with hover, disabled, and active states by adding{' '} + <code>component="a|button"</code>. We separate these pseudo-classes to ensure + list groups made of non-interactive elements (like <code><li></code>s or{' '} + <code><div></code> + s) don'tprovide a click or tap affordance. + </p> + <DocsExample href="components/list-group/#links-and-buttons"> + <CListGroup> + <CListGroupItem component="a" href="#" active> + Cras justo odio + </CListGroupItem> + <CListGroupItem component="a" href="#"> + Dapibus ac facilisis in + </CListGroupItem> + <CListGroupItem component="a" href="#"> + Morbi leo risus + </CListGroupItem> + <CListGroupItem component="a" href="#"> + Porta ac consectetur ac + </CListGroupItem> + <CListGroupItem component="a" href="#" disabled> + Vestibulum at eros + </CListGroupItem> + </CListGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React List Group</strong> <small>Flush</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>flush</code> boolean property to remove some borders and rounded corners to + render list group items edge-to-edge in a parent container (e.g., cards). + </p> + <DocsExample href="components/list-group/#flush"> + <CListGroup flush> + <CListGroupItem>Cras justo odio</CListGroupItem> + <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> + <CListGroupItem>Morbi leo risus</CListGroupItem> + <CListGroupItem>Porta ac consectetur ac</CListGroupItem> + <CListGroupItem>Vestibulum at eros</CListGroupItem> + </CListGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React List Group</strong> <small>Horizontal</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>layout="horizontal"</code> to change the layout of list group items + from vertical to horizontal across all breakpoints. Alternatively, choose a responsive + variant <code>.layout="horizontal-{sm | md | lg | xl | xxl}"</code>{' '} + to make a list group horizontal starting at that breakpoint's{' '} + <code>min-width</code>. Currently{' '} + <strong>horizontal list groups cannot be combined with flush list groups.</strong> + </p> + <DocsExample href="components/list-group/#flush"> + {['', '-sm', '-md', '-lg', '-xl', '-xxl'].map((breakpoint, index) => ( + <CListGroup className="mb-2" layout={`horizontal${breakpoint}`} key={index}> + <CListGroupItem>Cras justo odio</CListGroupItem> + <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> + <CListGroupItem>Morbi leo risus</CListGroupItem> + </CListGroup> + ))} + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React List Group</strong> <small>Contextual classes</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use contextual classes to style list items with a stateful background and color. + </p> + <DocsExample href="components/list-group/#contextual-classes"> + <CListGroup> + <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> + {[ + 'primary', + 'secondary', + 'success', + 'danger', + 'warning', + 'info', + 'light', + 'dark', + ].map((color, index) => ( + <CListGroupItem color={color} key={index}> + A simple {color} list group item + </CListGroupItem> + ))} + </CListGroup> + </DocsExample> + <p className="text-medium-emphasis small"> + Contextual classes also work with <code><a></code>s or{' '} + <code><button></code>s. Note the addition of the hover styles here not present + in the previous example. Also supported is the <code>active</code> state; apply it to + indicate an active selection on a contextual list group item. + </p> + <DocsExample href="components/list-group/#contextual-classes"> + <CListGroup> + <CListGroupItem component="a" href="#"> + Dapibus ac facilisis in + </CListGroupItem> + {[ + 'primary', + 'secondary', + 'success', + 'danger', + 'warning', + 'info', + 'light', + 'dark', + ].map((color, index) => ( + <CListGroupItem component="a" href="#" color={color} key={index}> + A simple {color} list group item + </CListGroupItem> + ))} + </CListGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React List Group</strong> <small>With badges</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add badges to any list group item to show unread counts, activity, and more. + </p> + <DocsExample href="components/list-group/#with-badges"> + <CListGroup> + <CListGroupItem className="d-flex justify-content-between align-items-center"> + Cras justo odio + <CBadge color="primary" shape="rounded-pill"> + 14 + </CBadge> + </CListGroupItem> + <CListGroupItem className="d-flex justify-content-between align-items-center"> + Dapibus ac facilisis in + <CBadge color="primary" shape="rounded-pill"> + 2 + </CBadge> + </CListGroupItem> + <CListGroupItem className="d-flex justify-content-between align-items-center"> + Morbi leo risus + <CBadge color="primary" shape="rounded-pill"> + 1 + </CBadge> + </CListGroupItem> + </CListGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React List Group</strong> <small>Custom content</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add nearly any HTML within, even for linked list groups like the one below, with the + help of <a href="https://coreui.io/docs/utilities/flex/">flexbox utilities</a>. + </p> + <DocsExample href="components/list-group/#custom-content"> + <CListGroup> + <CListGroupItem component="a" href="#" active> + <div className="d-flex w-100 justify-content-between"> + <h5 className="mb-1">List group item heading</h5> + <small>3 days ago</small> + </div> + <p className="mb-1"> + Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus + varius blandit. + </p> + <small>Donec id elit non mi porta.</small> + </CListGroupItem> + <CListGroupItem component="a" href="#"> + <div className="d-flex w-100 justify-content-between"> + <h5 className="mb-1">List group item heading</h5> + <small className="text-medium-emphasis">3 days ago</small> + </div> + <p className="mb-1"> + Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus + varius blandit. + </p> + <small className="text-medium-emphasis">Donec id elit non mi porta.</small> + </CListGroupItem> + <CListGroupItem component="a" href="#"> + <div className="d-flex w-100 justify-content-between"> + <h5 className="mb-1">List group item heading</h5> + <small className="text-medium-emphasis">3 days ago</small> + </div> + <p className="mb-1"> + Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus + varius blandit. + </p> + <small className="text-medium-emphasis">Donec id elit non mi porta.</small> + </CListGroupItem> + </CListGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React List Group</strong> <small>Checkboxes and radios</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Place CoreUI's checkboxes and radios within list group items and customize as + needed. + </p> + <DocsExample href="components/list-group/#checkboxes-and-radios"> + <CListGroup> + <CListGroupItem> + <CFormCheck label="Cras justo odio" /> + </CListGroupItem> + <CListGroupItem> + <CFormCheck label="Dapibus ac facilisis in" defaultChecked /> + </CListGroupItem> + <CListGroupItem> + <CFormCheck label="Morbi leo risus" defaultChecked /> + </CListGroupItem> + <CListGroupItem> + <CFormCheck label="orta ac consectetur ac" /> + </CListGroupItem> + <CListGroupItem> + <CFormCheck label="Vestibulum at eros" /> + </CListGroupItem> + </CListGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default ListGroups diff --git a/src/views/base/navbars/Navbars.js b/src/views/base/navbars/Navbars.js new file mode 100644 index 00000000..e8b9fd08 --- /dev/null +++ b/src/views/base/navbars/Navbars.js @@ -0,0 +1,174 @@ +import React, { useState } from 'react' +import { + CCard, + CCardBody, + CCardHeader, + CCollapse, + CDropdownItem, + CDropdownMenu, + CDropdownToggle, + CForm, + CFormInput, + CImage, + CNavbar, + CNavbarNav, + CNavbarBrand, + CNavbarText, + CNavbarToggler, + CNavLink, + CDropdown, + CButton, +} from '@coreui/react' +import { DocsLink } from 'src/components' + +const CNavbars = () => { + const [visible, setVisible] = useState(false) + const [isOpenDropdown, setIsOpenDropdown] = useState(false) + const [navbarText, setNavbarText] = useState(false) + + return ( + <> + <CCard className="mb-4"> + <CCardHeader> + CNavbar + <DocsLink name="CNavbar" /> + </CCardHeader> + <CCardBody> + <CNavbar expandable="sm" color="info"> + <CNavbarToggler onClick={() => setVisible(!visible)} /> + <CNavbarBrand>NavbarBrand</CNavbarBrand> + <CCollapse show={visible} navbar> + <CNavbarNav> + <CNavLink>Home</CNavLink> + <CNavLink>Link</CNavLink> + </CNavbarNav> + <CNavbarNav className="ms-auto"> + <CForm className="d-flex"> + <CFormInput className="me-sm-2" placeholder="Search" size="sm" /> + <CButton color="light" className="my-2 my-sm-0" type="submit"> + Search + </CButton> + </CForm> + <CDropdown inNav> + <CDropdownToggle color="primary">Lang</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem>EN</CDropdownItem> + <CDropdownItem>ES</CDropdownItem> + <CDropdownItem>RU</CDropdownItem> + <CDropdownItem>FA</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CDropdown inNav> + <CDropdownToggle color="primary">User</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem>Account</CDropdownItem> + <CDropdownItem>Settings</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </CNavbarNav> + </CCollapse> + </CNavbar> + </CCardBody> + </CCard> + + <CCard className="mb-4"> + <CCardHeader>CNavbar brand</CCardHeader> + <CCardBody> + <CNavbar color="faded" light> + <CNavbarBrand> + <CImage + src="https://placekitten.com/g/30/30" + className="d-inline-block align-top" + alt="CoreuiVue" + /> + CoreUI React + </CNavbarBrand> + </CNavbar> + </CCardBody> + </CCard> + + <CCard className="mb-4"> + <CCardHeader>CNavbar text</CCardHeader> + <CCardBody> + <CNavbar toggleable="sm" light color="light"> + <CNavbarToggler + inNavbar + onClick={() => { + setNavbarText(!navbarText) + }} + /> + <CNavbarBrand>NavbarBrand</CNavbarBrand> + <CCollapse show={navbarText}> + <CNavbarNav> + <CNavbarText>Navbar text</CNavbarText> + </CNavbarNav> + </CCollapse> + </CNavbar> + </CCardBody> + </CCard> + + <CCard className="mb-4"> + <CCardHeader>CNavbar dropdown</CCardHeader> + <CCardBody> + <CNavbar expandable="false" color="primary"> + <CNavbarToggler + inNavbar + onClick={() => { + setIsOpenDropdown(!isOpenDropdown) + }} + /> + <CCollapse show={isOpenDropdown} navbar> + <CNavbarNav> + <CNavLink>Home</CNavLink> + <CNavLink>Link</CNavLink> + <CDropdown inNav> + <CDropdownToggle color="primary">Lang</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem>EN</CDropdownItem> + <CDropdownItem>ES</CDropdownItem> + <CDropdownItem>RU</CDropdownItem> + <CDropdownItem>FA</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CDropdown inNav> + <CDropdownToggle color="primary">User</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem>Account</CDropdownItem> + <CDropdownItem>Settings</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </CNavbarNav> + </CCollapse> + </CNavbar> + </CCardBody> + </CCard> + + <CCard className="mb-4"> + <CCardHeader>CNavbar form</CCardHeader> + <CCardBody> + <CNavbar light color="light"> + <CForm className="d-flex"> + <CFormInput className="me-sm-2" placeholder="Search" size="sm" /> + <CButton color="outline-success" className="my-2 my-sm-0" type="submit"> + Search + </CButton> + </CForm> + </CNavbar> + </CCardBody> + </CCard> + + <CCard className="mb-4"> + <CCardHeader>CNavbar input group</CCardHeader> + <CCardBody> + <CNavbar light color="light"> + <CForm className="d-flex"> + <CFormInput className="me-sm-2" placeholder="Username" /> + </CForm> + </CNavbar> + </CCardBody> + </CCard> + </> + ) +} + +export default CNavbars diff --git a/src/views/base/navs/Navs.js b/src/views/base/navs/Navs.js new file mode 100644 index 00000000..89310faf --- /dev/null +++ b/src/views/base/navs/Navs.js @@ -0,0 +1,397 @@ +import React from 'react' +import { + CRow, + CCol, + CCard, + CCardBody, + CCardHeader, + CDropdown, + CDropdownItem, + CDropdownMenu, + CDropdownToggle, + CNav, + CNavItem, + CNavLink, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const Navs = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Navs</strong> <small>Base navs</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + The base <code>.nav</code> component is built with flexbox and provide a strong + foundation for building all types of navigation components. It includes some style + overrides (for working with lists), some link padding for larger hit areas, and basic + disabled styling. + </p> + <DocsExample href="components/nav#base-nav"> + <CNav> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </DocsExample> + <p className="text-medium-emphasis small"> + Classes are used throughout, so your markup can be super flexible. Use{' '} + <code><ul></code>s like above, <code><ol></code> if the order of your + items is important, or roll your own with a <code><nav></code> element. Because + the .nav uses display: flex, the nav links behave the same as nav items would, but + without the extra markup. + </p> + <DocsExample href="components/nav#base-nav"> + <CNav component="nav"> + <CNavLink href="#" active> + Active + </CNavLink> + <CNavLink href="#">Link</CNavLink> + <CNavLink href="#">Link</CNavLink> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNav> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Navs</strong> <small>Horizontal alignment</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Change the horizontal alignment of your nav with{' '} + <a href="https://coreui.io/docs/layout/grid/#horizontal-alignment"> + flexbox utilities + </a> + . By default, navs are left-aligned, but you can easily change them to center or right + aligned. + </p> + <p className="text-medium-emphasis small"> + Centered with <code>.justify-content-center</code>: + </p> + <DocsExample href="components/nav#horizontal-alignment"> + <CNav className="justify-content-center"> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </DocsExample> + <p className="text-medium-emphasis small"> + Right-aligned with <code>.justify-content-end</code>: + </p> + <DocsExample href="components/nav#base-nav"> + <CNav className="justify-content-end"> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Navs</strong> <small>Vertical</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Stack your navigation by changing the flex item direction with the{' '} + <code>.flex-column</code> utility. Need to stack them on some viewports but not + others? Use the responsive versions (e.g., <code>.flex-sm-column</code>). + </p> + <DocsExample href="components/nav#vertical"> + <CNav className="flex-column"> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Navs</strong> <small>Tabs</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Takes the basic nav from above and adds the <code>variant="tabs"</code> class + to generate a tabbed interface + </p> + <DocsExample href="components/nav#tabs"> + <CNav variant="tabs"> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Navs</strong> <small>Pills</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Take that same HTML, but use <code>variant="pills"</code> instead: + </p> + <DocsExample href="components/nav#pills"> + <CNav variant="pills"> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Navs</strong> <small>Fill and justify</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Force your <code>.nav</code>'s contents to extend the full available width one of + two modifier classes. To proportionately fill all available space with your{' '} + <code>.nav-item</code>s, use <code>layout="fill"</code>. Notice that all + horizontal space is occupied, but not every nav item has the same width. + </p> + <DocsExample href="components/nav#fill-and-justify"> + <CNav variant="pills" layout="fill"> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </DocsExample> + <p className="text-medium-emphasis small"> + For equal-width elements, use <code>layout="justified"</code>. All horizontal + space will be occupied by nav links, but unlike the .nav-fill above, every nav item + will be the same width. + </p> + <DocsExample href="components/nav#fill-and-justify"> + <CNav variant="pills" layout="justified"> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Navs</strong> <small>Working with flex utilities</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + If you need responsive nav variations, consider using a series of{' '} + <a href="https://coreui.io/docs/utilities/flex">flexbox utilities</a>. While more + verbose, these utilities offer greater customization across responsive breakpoints. In + the example below, our nav will be stacked on the lowest breakpoint, then adapt to a + horizontal layout that fills the available width starting from the small breakpoint. + </p> + <DocsExample href="components/nav#working-with-flex-utilities"> + <CNav component="nav" variant="pills" className="flex-column flex-sm-row"> + <CNavLink href="#" active> + Active + </CNavLink> + <CNavLink href="#">Link</CNavLink> + <CNavLink href="#">Link</CNavLink> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNav> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Navs</strong> <small>Tabs with dropdowns</small> + </CCardHeader> + <CCardBody> + <DocsExample href="components/nav#tabs-with-dropdowns"> + <CNav> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CDropdown variant="nav-item"> + <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Navs</strong> <small>Pills with dropdowns</small> + </CCardHeader> + <CCardBody> + <DocsExample href="components/nav#pills-with-dropdowns"> + <CNav variant="pills"> + <CNavItem> + <CNavLink href="#" active> + Active + </CNavLink> + </CNavItem> + <CDropdown variant="nav-item"> + <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CNavItem> + <CNavLink href="#">Link</CNavLink> + </CNavItem> + <CNavItem> + <CNavLink href="#" disabled> + Disabled + </CNavLink> + </CNavItem> + </CNav> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Navs diff --git a/src/views/base/paginations/Paginations.js b/src/views/base/paginations/Paginations.js new file mode 100644 index 00000000..f8596150 --- /dev/null +++ b/src/views/base/paginations/Paginations.js @@ -0,0 +1,174 @@ +import React from 'react' +import { + CCard, + CCardBody, + CCardHeader, + CCol, + CPagination, + CPaginationItem, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const Paginations = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Pagination</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + We use a large block of connected links for our pagination, making links hard to miss + and easily scalable—all while providing large hit areas. Pagination is built with list + HTML elements so screen readers can announce the number of available links. Use a + wrapping <code><nav></code> element to identify it as a navigation section to + screen readers and other assistive technologies. + </p> + <p className="text-medium-emphasis small"> + In addition, as pages likely have more than one such navigation section, it's + advisable to provide a descriptive <code>aria-label</code> for the{' '} + <code><nav></code> to reflect its purpose. For example, if the pagination + component is used to navigate between a set of search results, an appropriate label + could be <code>aria-label="Search results pages"</code>. + </p> + <DocsExample href="components/pagination"> + <CPagination aria-label="Page navigation example"> + <CPaginationItem>Previous</CPaginationItem> + <CPaginationItem>1</CPaginationItem> + <CPaginationItem>2</CPaginationItem> + <CPaginationItem>3</CPaginationItem> + <CPaginationItem>Next</CPaginationItem> + </CPagination> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Pagination</strong> <small>Working with icons</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Looking to use an icon or symbol in place of text for some pagination links? Be sure + to provide proper screen reader support with <code>aria</code> attributes. + </p> + <DocsExample href="components/pagination#working-with-icons"> + <CPagination aria-label="Page navigation example"> + <CPaginationItem aria-label="Previous"> + <span aria-hidden="true">«</span> + </CPaginationItem> + <CPaginationItem>1</CPaginationItem> + <CPaginationItem>2</CPaginationItem> + <CPaginationItem>3</CPaginationItem> + <CPaginationItem aria-label="Next"> + <span aria-hidden="true">»</span> + </CPaginationItem> + </CPagination> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Pagination</strong> <small>Disabled and active states</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Pagination links are customizable for different circumstances. Use{' '} + <code>disabled</code> for links that appear un-clickable and <code>.active</code> to + indicate the current page. + </p> + <p className="text-medium-emphasis small"> + While the <code>disabled</code> prop uses <code>pointer-events: none</code> to{' '} + <em>try</em> to disable the link functionality of <code><a></code>s, that CSS + property is not yet standardized and doesn'taccount for keyboard navigation. As + such, we always add <code>tabindex="-1"</code> on disabled links and use + custom JavaScript to fully disable their functionality. + </p> + <DocsExample href="components/pagination#disabled-and-active-states"> + <CPagination aria-label="Page navigation example"> + <CPaginationItem aria-label="Previous" disabled> + <span aria-hidden="true">«</span> + </CPaginationItem> + <CPaginationItem active>1</CPaginationItem> + <CPaginationItem>2</CPaginationItem> + <CPaginationItem>3</CPaginationItem> + <CPaginationItem aria-label="Next"> + <span aria-hidden="true">»</span> + </CPaginationItem> + </CPagination> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Pagination</strong> <small>Sizing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Fancy larger or smaller pagination? Add <code>size="lg"</code> or{' '} + <code>size="sm"</code> for additional sizes. + </p> + <DocsExample href="components/pagination#sizing"> + <CPagination size="lg" aria-label="Page navigation example"> + <CPaginationItem>Previous</CPaginationItem> + <CPaginationItem>1</CPaginationItem> + <CPaginationItem>2</CPaginationItem> + <CPaginationItem>3</CPaginationItem> + <CPaginationItem>Next</CPaginationItem> + </CPagination> + </DocsExample> + <DocsExample href="components/pagination#sizing"> + <CPagination size="sm" aria-label="Page navigation example"> + <CPaginationItem>Previous</CPaginationItem> + <CPaginationItem>1</CPaginationItem> + <CPaginationItem>2</CPaginationItem> + <CPaginationItem>3</CPaginationItem> + <CPaginationItem>Next</CPaginationItem> + </CPagination> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Pagination</strong> <small>Alignment</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Change the alignment of pagination components with{' '} + <a href="https://coreui.io/docs/utilities/flex/">flexbox utilities</a>. + </p> + <DocsExample href="components/pagination#aligment"> + <CPagination className="justify-content-center" aria-label="Page navigation example"> + <CPaginationItem disabled>Previous</CPaginationItem> + <CPaginationItem>1</CPaginationItem> + <CPaginationItem>2</CPaginationItem> + <CPaginationItem>3</CPaginationItem> + <CPaginationItem>Next</CPaginationItem> + </CPagination> + </DocsExample> + <DocsExample href="components/pagination#aligment"> + <CPagination className="justify-content-end" aria-label="Page navigation example"> + <CPaginationItem disabled>Previous</CPaginationItem> + <CPaginationItem>1</CPaginationItem> + <CPaginationItem>2</CPaginationItem> + <CPaginationItem>3</CPaginationItem> + <CPaginationItem>Next</CPaginationItem> + </CPagination> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Paginations diff --git a/src/views/base/placeholders/Placeholders.js b/src/views/base/placeholders/Placeholders.js new file mode 100644 index 00000000..5342f221 --- /dev/null +++ b/src/views/base/placeholders/Placeholders.js @@ -0,0 +1,193 @@ +import React from 'react' +import { + CButton, + CCard, + CCardBody, + CCardHeader, + CCardImage, + CCardText, + CCardTitle, + CCol, + CPlaceholder, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +import ReactImg from 'src/assets/images/react.jpg' + +const Placeholders = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Placeholder</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + In the example below, we take a typical card component and recreate it with + placeholders applied to create a "loading card". Size and proportions are the + same between the two. + </p> + <DocsExample href="components/placeholder"> + <div className="d-flex justify-content-around p-3"> + <CCard style={{ width: '18rem' }}> + <CCardImage orientation="top" src={ReactImg} /> + <CCardBody> + <CCardTitle>Card title</CCardTitle> + <CCardText> + Some quick example text to build on the card title and make up the bulk of the + card's content. + </CCardText> + <CButton href="#">Go somewhere</CButton> + </CCardBody> + </CCard> + <CCard style={{ width: '18rem' }}> + <CCardImage + component="svg" + orientation="top" + width="100%" + height="162" + xmlns="http://www.w3.org/2000/svg" + role="img" + aria-label="Placeholder" + preserveAspectRatio="xMidYMid slice" + focusable="false" + > + <title>Placeholder</title> + <rect width="100%" height="100%" fill="#868e96"></rect> + </CCardImage> + <CCardBody> + <CPlaceholder component={CCardTitle} animation="glow" xs={7}> + <CPlaceholder xs={6} /> + </CPlaceholder> + <CPlaceholder component={CCardText} animation="glow"> + <CPlaceholder xs={7} /> + <CPlaceholder xs={4} /> + <CPlaceholder xs={4} /> + <CPlaceholder xs={6} /> + <CPlaceholder xs={8} /> + </CPlaceholder> + <CPlaceholder + component={CButton} + disabled + href="#" + tabIndex={-1} + xs={6} + ></CPlaceholder> + </CCardBody> + </CCard> + </div> + </DocsExample> + </CCardBody> + </CCard> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Placeholder</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Create placeholders with the <code><CPlaceholder></code> component and a grid + column propx (e.g., <code>xs={6}</code>) to set the <code>width</code>. They can + replace the text inside an element or be added as a modifier class to an existing + component. + </p> + <DocsExample href="components/placeholder"> + <p aria-hidden="true"> + <CPlaceholder xs={6} /> + </p> + <CPlaceholder + component={CButton} + aria-hidden="true" + disabled + href="#" + tabIndex={-1} + xs={4} + ></CPlaceholder> + </DocsExample> + </CCardBody> + </CCard> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Placeholder</strong> <small> Width</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + You can change the <code>width</code> through grid column classes, width utilities, or + inline styles. + </p> + <DocsExample href="components/placeholder#width"> + <CPlaceholder xs={6} /> + <CPlaceholder className="w-75" /> + <CPlaceholder style={{ width: '30%' }} /> + </DocsExample> + </CCardBody> + </CCard> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Placeholder</strong> <small> Color</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + By default, the <code><CPlaceholder></code> uses <code>currentColor</code>. This + can be overridden with a custom color or utility class. + </p> + <DocsExample href="components/placeholder#color"> + <CPlaceholder xs={12} /> + + <CPlaceholder color="primary" xs={12} /> + <CPlaceholder color="secondary" xs={12} /> + <CPlaceholder color="success" xs={12} /> + <CPlaceholder color="danger" xs={12} /> + <CPlaceholder color="warning" xs={12} /> + <CPlaceholder color="info" xs={12} /> + <CPlaceholder color="light" xs={12} /> + <CPlaceholder color="dark" xs={12} /> + </DocsExample> + </CCardBody> + </CCard> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Placeholder</strong> <small> Sizing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + The size of <code><CPlaceholder></code>s are based on the typographic style of + the parent element. Customize them with <code>size</code> prop: <code>lg</code>,{' '} + <code>sm</code>, or <code>xs</code>. + </p> + <DocsExample href="components/placeholder#sizing"> + <CPlaceholder xs={12} size="lg" /> + <CPlaceholder xs={12} /> + <CPlaceholder xs={12} size="sm" /> + <CPlaceholder xs={12} size="xs" /> + </DocsExample> + </CCardBody> + </CCard> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Placeholder</strong> <small> Animation</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Animate placeholders with <code>animation="glow"</code> or{' '} + <code>animation="wave"</code> to better convey the perception of something + being <em>actively</em> loaded. + </p> + <DocsExample href="components/placeholder#animation"> + <CPlaceholder component="p" animation="glow"> + <CPlaceholder xs={12} /> + </CPlaceholder> + + <CPlaceholder component="p" animation="wave"> + <CPlaceholder xs={12} /> + </CPlaceholder> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Placeholders diff --git a/src/views/base/popovers/Popovers.js b/src/views/base/popovers/Popovers.js new file mode 100644 index 00000000..8d98e0de --- /dev/null +++ b/src/views/base/popovers/Popovers.js @@ -0,0 +1,71 @@ +import React from 'react' +import { CButton, CCard, CCardBody, CCardHeader, CPopover, CRow, CCol } from '@coreui/react' +import { DocsExample } from 'src/components' + +const Popovers = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Popover</strong> <small>Basic example</small> + </CCardHeader> + <CCardBody> + <DocsExample href="components/popover"> + <CPopover + title="Popover title" + content="And here’s some amazing content. It’s very engaging. Right?" + placement="right" + > + <CButton color="danger" size="lg"> + Click to toggle popover + </CButton> + </CPopover> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Popover</strong> <small>Four directions</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Four options are available: top, right, bottom, and left aligned. Directions are + mirrored when using CoreUI for React in RTL. + </p> + <DocsExample href="components/popover#four-directions"> + <CPopover + content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." + placement="top" + > + <CButton color="secondary">Popover on top</CButton> + </CPopover> + <CPopover + content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." + placement="right" + > + <CButton color="secondary">Popover on right</CButton> + </CPopover> + <CPopover + content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." + placement="bottom" + > + <CButton color="secondary">Popover on bottom</CButton> + </CPopover> + <CPopover + content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." + placement="left" + > + <CButton color="secondary">Popover on left</CButton> + </CPopover> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Popovers diff --git a/src/views/base/progress/Progress.js b/src/views/base/progress/Progress.js new file mode 100644 index 00000000..42b9819f --- /dev/null +++ b/src/views/base/progress/Progress.js @@ -0,0 +1,186 @@ +import React from 'react' +import { CCard, CCardBody, CCardHeader, CCol, CProgress, CProgressBar, CRow } from '@coreui/react' +import { DocsExample } from 'src/components' + +const Progress = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Progress</strong> <small>Basic example</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Progress components are built with two HTML elements, some CSS to set the width, and a + few attributes. We don'tuse{' '} + <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress"> + the HTML5 <code><progress></code> element + </a> + , ensuring you can stack progress bars, animate them, and place text labels over them. + </p> + <DocsExample href="components/progress"> + <CProgress className="mb-3"> + <CProgressBar value={0} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar value={25} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar value={50} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar value={75} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar value={100} /> + </CProgress> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Progress</strong> <small>Labels</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add labels to your progress bars by placing text within the{' '} + <code><CProgressBar></code>. + </p> + <DocsExample href="components/progress#labels"> + <CProgress className="mb-3"> + <CProgressBar value={25}>25%</CProgressBar> + </CProgress> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Progress</strong> <small>Height</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + We only set a <code>height</code> value on the <code><CProgress></code>, so if + you change that value the inner <code><CProgressBar></code> will automatically + resize accordingly. + </p> + <DocsExample href="components/progress#height"> + <CProgress height={1} className="mb-3"> + <CProgressBar value={25}></CProgressBar> + </CProgress> + <CProgress height={20} className="mb-3"> + <CProgressBar value={25}></CProgressBar> + </CProgress> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Progress</strong> <small>Backgrounds</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use <code>color</code> prop to change the appearance of individual progress bars. + </p> + <DocsExample href="components/progress#backgrounds"> + <CProgress className="mb-3"> + <CProgressBar color="success" value={25} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar color="info" value={50} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar color="warning" value={75} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar color="danger" value={100} /> + </CProgress> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Progress</strong> <small>Multiple bars</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Include multiple progress bars in a progress component if you need. + </p> + <DocsExample href="components/progress#multiple-bars"> + <CProgress className="mb-3"> + <CProgressBar value={15} /> + <CProgressBar color="success" value={30} /> + <CProgressBar color="info" value={20} /> + </CProgress> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Progress</strong> <small>Striped</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>variant="striped"</code> to any <code><CProgressBar></code> to + apply a stripe via CSS gradient over the progress bar's background color. + </p> + <DocsExample href="components/progress#striped"> + <CProgress className="mb-3"> + <CProgressBar color="success" variant="striped" value={25} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar color="info" variant="striped" value={50} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar color="warning" variant="striped" value={75} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar color="danger" variant="striped" value={100} /> + </CProgress> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Progress</strong> <small>Animated stripes</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + The striped gradient can also be animated. Add <code>animated</code> property to{' '} + <code><CProgressBar></code> to animate the stripes right to left via CSS3 + animations. + </p> + <DocsExample href="components/progress#animated-stripes"> + <CProgress className="mb-3"> + <CProgressBar color="success" variant="striped" animated value={25} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar color="info" variant="striped" animated value={50} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar color="warning" variant="striped" animated value={75} /> + </CProgress> + <CProgress className="mb-3"> + <CProgressBar color="danger" variant="striped" animated value={100} /> + </CProgress> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Progress diff --git a/src/views/base/spinners/Spinners.js b/src/views/base/spinners/Spinners.js new file mode 100644 index 00000000..918c2713 --- /dev/null +++ b/src/views/base/spinners/Spinners.js @@ -0,0 +1,120 @@ +import React from 'react' +import { CButton, CCard, CCardBody, CCardHeader, CCol, CSpinner, CRow } from '@coreui/react' +import { DocsExample } from 'src/components' + +const Accordion = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Spinner</strong> <small>Border</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use the border spinners for a lightweight loading indicator. + </p> + <DocsExample href="components/spinner"> + <CSpinner /> + </DocsExample> + <p className="text-medium-emphasis small"> + The border spinner uses <code>currentColor</code> for its <code>border-color</code>. + You can use any of our text color utilities on the standard spinner. + </p> + <DocsExample href="components/spinner#colors"> + <CSpinner color="primary" /> + <CSpinner color="secondary" /> + <CSpinner color="success" /> + <CSpinner color="danger" /> + <CSpinner color="warning" /> + <CSpinner color="info" /> + <CSpinner color="light" /> + <CSpinner color="dark" /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Spinner</strong> <small>Growing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + If you don'tfancy a border spinner, switch to the grow spinner. While it + doesn't technically spin, it does repeatedly grow! + </p> + <DocsExample href="components/spinner#growing-spinner"> + <CSpinner variant="grow" /> + </DocsExample> + <p className="text-medium-emphasis small"> + Once again, this spinner is built with <code>currentColor</code>, so you can easily + change its appearance. Here it is in blue, along with the supported variants. + </p> + <DocsExample href="components/spinner#growing-spinner"> + <CSpinner color="primary" variant="grow" /> + <CSpinner color="secondary" variant="grow" /> + <CSpinner color="success" variant="grow" /> + <CSpinner color="danger" variant="grow" /> + <CSpinner color="warning" variant="grow" /> + <CSpinner color="info" variant="grow" /> + <CSpinner color="light" variant="grow" /> + <CSpinner color="dark" variant="grow" /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Spinner</strong> <small>Size</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>size="sm"</code> property to make a smaller spinner that can quickly + be used within other components. + </p> + <DocsExample href="components/spinner#size"> + <CSpinner size="sm" /> + <CSpinner size="sm" variant="grow" /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Spinner</strong> <small>Buttons</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use spinners within buttons to indicate an action is currently processing or taking + place. You may also swap the text out of the spinner element and utilize button text + as needed. + </p> + <DocsExample href="components/spinner#buttons"> + <CButton disabled> + <CSpinner component="span" size="sm" aria-hidden="true" /> + </CButton> + <CButton disabled> + <CSpinner component="span" size="sm" aria-hidden="true" /> + Loading... + </CButton> + </DocsExample> + <DocsExample href="components/spinner#buttons"> + <CButton disabled> + <CSpinner component="span" size="sm" variant="grow" aria-hidden="true" /> + </CButton> + <CButton disabled> + <CSpinner component="span" size="sm" variant="grow" aria-hidden="true" /> + Loading... + </CButton> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Accordion diff --git a/src/views/base/tables/Tables.js b/src/views/base/tables/Tables.js new file mode 100644 index 00000000..f06843d0 --- /dev/null +++ b/src/views/base/tables/Tables.js @@ -0,0 +1,986 @@ +import React from 'react' +import { + CCard, + CCardBody, + CCardHeader, + CCol, + CRow, + CTable, + CTableBody, + CTableCaption, + CTableDataCell, + CTableHead, + CTableHeaderCell, + CTableRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const Tables = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Basic example</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Using the most basic table CoreUI, here's how <code><CTable></code>-based + tables look in CoreUI. + </p> + <DocsExample href="components/table"> + <CTable> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Variants</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use contextual classes to color tables, table rows or individual cells. + </p> + <DocsExample href="components/table#variants"> + <CTable> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">Default</CTableHeaderCell> + <CTableDataCell>Cell</CTableDataCell> + <CTableDataCell>Cell</CTableDataCell> + </CTableRow> + <CTableRow color="primary"> + <CTableHeaderCell scope="row">Primary</CTableHeaderCell> + <CTableDataCell>Cell</CTableDataCell> + <CTableDataCell>Cell</CTableDataCell> + </CTableRow> + <CTableRow color="secondary"> + <CTableHeaderCell scope="row">Secondary</CTableHeaderCell> + <CTableDataCell>Cell</CTableDataCell> + <CTableDataCell>Cell</CTableDataCell> + </CTableRow> + <CTableRow color="success"> + <CTableHeaderCell scope="row">Success</CTableHeaderCell> + <CTableDataCell>Cell</CTableDataCell> + <CTableDataCell>Cell</CTableDataCell> + </CTableRow> + <CTableRow color="danger"> + <CTableHeaderCell scope="row">Danger</CTableHeaderCell> + <CTableDataCell>Cell</CTableDataCell> + <CTableDataCell>Cell</CTableDataCell> + </CTableRow> + <CTableRow color="warning"> + <CTableHeaderCell scope="row">Warning</CTableHeaderCell> + <CTableDataCell>Cell</CTableDataCell> + <CTableDataCell>Cell</CTableDataCell> + </CTableRow> + <CTableRow color="info"> + <CTableHeaderCell scope="row">Info</CTableHeaderCell> + <CTableDataCell>Cell</CTableDataCell> + <CTableDataCell>Cell</CTableDataCell> + </CTableRow> + <CTableRow color="light"> + <CTableHeaderCell scope="row">Light</CTableHeaderCell> + <CTableDataCell>Cell</CTableDataCell> + <CTableDataCell>Cell</CTableDataCell> + </CTableRow> + <CTableRow color="dark"> + <CTableHeaderCell scope="row">Dark</CTableHeaderCell> + <CTableDataCell>Cell</CTableDataCell> + <CTableDataCell>Cell</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Striped rows</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use <code>striped</code> property to add zebra-striping to any table row within the{' '} + <code><CTableBody></code>. + </p> + <DocsExample href="components/table#striped-rows"> + <CTable striped> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + <p className="text-medium-emphasis small"> + These classes can also be added to table variants: + </p> + <DocsExample href="components/table#striped-rows"> + <CTable color="dark" striped> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + <DocsExample href="components/table#striped-rows"> + <CTable color="success" striped> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Hoverable rows</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use <code>hover</code> property to enable a hover state on table rows within a{' '} + <code><CTableBody></code>. + </p> + <DocsExample href="components/table#hoverable-rows"> + <CTable hover> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + <DocsExample href="components/table#hoverable-rows"> + <CTable color="dark" hover> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + <DocsExample href="components/table#hoverable-rows"> + <CTable striped hover> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Active tables</small> + </CCardHeader> + <CCardBody> + <DocsExample href="components/table#active-tables"> + <CTable> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow active> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2" active> + Larry the Bird + </CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + <DocsExample href="components/table#active-tables"> + <CTable color="dark"> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow active> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2" active> + Larry the Bird + </CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Bordered tables</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>bordered</code> property for borders on all sides of the table and cells. + </p> + <DocsExample href="components/table#bordered-tables"> + <CTable bordered> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + <p className="text-medium-emphasis small"> + <a href="https://coreui.io/docs/4.0/utilities/borders#border-color"> + Border color utilities + </a>{' '} + can be added to change colors: + </p> + <DocsExample href="components/table#bordered-tables"> + <CTable bordered borderColor="primary"> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Tables without borders</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>borderless</code> property for a table without borders. + </p> + <DocsExample href="components/table#tables-without-borders"> + <CTable borderless> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + <DocsExample href="components/table#tables-without-borders"> + <CTable color="dark" borderless> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Small tables</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>small</code> property to make any <code><CTable></code> more compact + by cutting all cell <code>padding</code> in half. + </p> + <DocsExample href="components/table#small-tables"> + <CTable small> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Vertical alignment</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Table cells of <code><CTableHead></code> are always vertical aligned to the + bottom. Table cells in <code><CTableBody></code> inherit their alignment from{' '} + <code><CTable></code> and are aligned to the the top by default. Use the align + property to re-align where needed. + </p> + <DocsExample href="components/table#vertical-alignment"> + <CTable align="middle" responsive> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col" className="w-25"> + Heading 1 + </CTableHeaderCell> + <CTableHeaderCell scope="col" className="w-25"> + Heading 2 + </CTableHeaderCell> + <CTableHeaderCell scope="col" className="w-25"> + Heading 3 + </CTableHeaderCell> + <CTableHeaderCell scope="col" className="w-25"> + Heading 4 + </CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableDataCell> + This cell inherits <code>vertical-align: middle;</code> from the table + </CTableDataCell> + <CTableDataCell> + This cell inherits <code>vertical-align: middle;</code> from the table + </CTableDataCell> + <CTableDataCell> + This cell inherits <code>vertical-align: middle;</code> from the table + </CTableDataCell> + <CTableDataCell> + This here is some placeholder text, intended to take up quite a bit of + vertical space, to demonsCTableRowate how the vertical alignment works in the + preceding cells. + </CTableDataCell> + </CTableRow> + <CTableRow align="bottom"> + <CTableDataCell> + This cell inherits <code>vertical-align: bottom;</code> from the table row + </CTableDataCell> + <CTableDataCell> + This cell inherits <code>vertical-align: bottom;</code> from the table row + </CTableDataCell> + <CTableDataCell> + This cell inherits <code>vertical-align: bottom;</code> from the table row + </CTableDataCell> + <CTableDataCell> + This here is some placeholder text, intended to take up quite a bit of + vertical space, to demonsCTableRowate how the vertical alignment works in the + preceding cells. + </CTableDataCell> + </CTableRow> + <CTableRow> + <CTableDataCell> + This cell inherits <code>vertical-align: middle;</code> from the table + </CTableDataCell> + <CTableDataCell> + This cell inherits <code>vertical-align: middle;</code> from the table + </CTableDataCell> + <CTableDataCell align="top">This cell is aligned to the top.</CTableDataCell> + <CTableDataCell> + This here is some placeholder text, intended to take up quite a bit of + vertical space, to demonsCTableRowate how the vertical alignment works in the + preceding cells. + </CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Nesting</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Border styles, active styles, and table variants are not inherited by nested tables. + </p> + <DocsExample href="components/table#nesting"> + <CTable striped> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell colSpan="4"> + <CTable> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">Header</CTableHeaderCell> + <CTableHeaderCell scope="col">Header</CTableHeaderCell> + <CTableHeaderCell scope="col">Header</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">A</CTableHeaderCell> + <CTableDataCell>First</CTableDataCell> + <CTableDataCell>Last</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">B</CTableHeaderCell> + <CTableDataCell>First</CTableDataCell> + <CTableDataCell>Last</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">C</CTableHeaderCell> + <CTableDataCell>First</CTableDataCell> + <CTableDataCell>Last</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </CTableHeaderCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Table head</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Similar to tables and dark tables, use the modifier prop{' '} + <code>color="light"</code> or <code>color="dark"</code> to make{' '} + <code><CTableHead></code>s appear light or dark gray. + </p> + <DocsExample href="components/table#table-head"> + <CTable> + <CTableHead color="light"> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell>Larry</CTableDataCell> + <CTableDataCell>the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + <DocsExample href="components/table#table-head"> + <CTable> + <CTableHead color="dark"> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Table foot</small> + </CCardHeader> + <CCardBody> + <DocsExample href="components/table#table-foot"> + <CTable> + <CTableHead color="light"> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + <CTableHead> + <CTableRow> + <CTableDataCell>Footer</CTableDataCell> + <CTableDataCell>Footer</CTableDataCell> + <CTableDataCell>Footer</CTableDataCell> + <CTableDataCell>Footer</CTableDataCell> + </CTableRow> + </CTableHead> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Table</strong> <small>Captions</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + A <code><CTableCaption></code> functions like a heading for a table. It helps + users with screen readers to find a table and understand what it's about and + decide if they want to read it. + </p> + <DocsExample href="components/table#captions"> + <CTable> + <CTableCaption>List of users</CTableCaption> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell>Larry</CTableDataCell> + <CTableDataCell>the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + <p className="text-medium-emphasis small"> + You can also put the <code><CTableCaption></code> on the top of the table with{' '} + <code>caption="top"</code>. + </p> + <DocsExample href="components/table#captions"> + <CTable caption="top"> + <CTableCaption>List of users</CTableCaption> + <CTableHead> + <CTableRow> + <CTableHeaderCell scope="col">#</CTableHeaderCell> + <CTableHeaderCell scope="col">Class</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + <CTableHeaderCell scope="col">Heading</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + <CTableRow> + <CTableHeaderCell scope="row">1</CTableHeaderCell> + <CTableDataCell>Mark</CTableDataCell> + <CTableDataCell>Otto</CTableDataCell> + <CTableDataCell>@mdo</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">2</CTableHeaderCell> + <CTableDataCell>Jacob</CTableDataCell> + <CTableDataCell>Thornton</CTableDataCell> + <CTableDataCell>@fat</CTableDataCell> + </CTableRow> + <CTableRow> + <CTableHeaderCell scope="row">3</CTableHeaderCell> + <CTableDataCell>Larry</CTableDataCell> + <CTableDataCell>the Bird</CTableDataCell> + <CTableDataCell>@twitter</CTableDataCell> + </CTableRow> + </CTableBody> + </CTable> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Tables diff --git a/src/views/base/tooltips/Tooltips.js b/src/views/base/tooltips/Tooltips.js new file mode 100644 index 00000000..bdb4d9aa --- /dev/null +++ b/src/views/base/tooltips/Tooltips.js @@ -0,0 +1,79 @@ +import React from 'react' +import { CButton, CCard, CCardBody, CCardHeader, CLink, CTooltip, CRow, CCol } from '@coreui/react' +import { DocsExample } from 'src/components' + +const Tooltips = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Tooltip</strong> <small>Basic example</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Hover over the links below to see tooltips: + </p> + <DocsExample href="components/tooltip"> + <p className="text-medium-emphasis"> + Tight pants next level keffiyeh + <CTooltip content="Tooltip text"> + <CLink> you probably </CLink> + </CTooltip> + haven'theard of them. Photo booth beard raw denim letterpress vegan messenger + bag stumptown. Farm-to-table seitan, mcsweeney's fixie sustainable quinoa 8-bit + american apparel + <CTooltip content="Tooltip text"> + <CLink> have a </CLink> + </CTooltip> + terry richardson vinyl chambray. Beard stumptown, cardigans banh mi lomo + thundercats. Tofu biodiesel williamsburg marfa, four loko mcsweeney''s + cleanse vegan chambray. A really ironic artisan + <CTooltip content="Tooltip text"> + <CLink> whatever keytar </CLink> + </CTooltip> + scenester farm-to-table banksy Austin + <CTooltip content="Tooltip text"> + <CLink> twitter handle </CLink> + </CTooltip> + freegan cred raw denim single-origin coffee viral. + </p> + </DocsExample> + <p className="text-medium-emphasis small"> + Hover over the buttons below to see the four tooltips directions: top, right, bottom, + and left. Directions are mirrored when using CoreUI in RTL. + </p> + <DocsExample href="components/tooltip"> + <CTooltip + content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." + placement="top" + > + <CButton color="secondary">Tooltip on top</CButton> + </CTooltip> + <CTooltip + content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." + placement="right" + > + <CButton color="secondary">Tooltip on right</CButton> + </CTooltip> + <CTooltip + content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." + placement="bottom" + > + <CButton color="secondary">Tooltip on bottom</CButton> + </CTooltip> + <CTooltip + content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." + placement="left" + > + <CButton color="secondary">Tooltip on left</CButton> + </CTooltip> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Tooltips diff --git a/src/views/buttons/button-groups/ButtonGroups.js b/src/views/buttons/button-groups/ButtonGroups.js new file mode 100644 index 00000000..d48eb007 --- /dev/null +++ b/src/views/buttons/button-groups/ButtonGroups.js @@ -0,0 +1,439 @@ +import React from 'react' +import { + CButton, + CDropdown, + CDropdownDivider, + CDropdownItem, + CDropdownMenu, + CDropdownToggle, + CButtonGroup, + CButtonToolbar, + CCard, + CCardBody, + CCardHeader, + CCol, + CFormCheck, + CFormInput, + CInputGroup, + CInputGroupText, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const ButtonGroups = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button Group</strong> <span>Basic example</span> + </CCardHeader> + <CCardBody> + <p> + Wrap a series of <code><CButton></code> components in{' '} + <code><CButtonGroup></code>.{' '} + </p> + <DocsExample href="components/button-group"> + <CButtonGroup role="group" aria-label="Basic example"> + <CButton color="primary">Left</CButton> + <CButton color="primary">Middle</CButton> + <CButton color="primary">Right</CButton> + </CButtonGroup> + </DocsExample> + <p> + These classes can also be added to groups of links, as an alternative to the{' '} + <code><CNav></code> components. + </p> + <DocsExample href="components/button-group"> + <CButtonGroup> + <CButton href="#" color="primary" active> + Active link + </CButton> + <CButton href="#" color="primary"> + Link + </CButton> + <CButton href="#" color="primary"> + Link + </CButton> + </CButtonGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button Group</strong> <span>Mixed styles</span> + </CCardHeader> + <CCardBody> + <DocsExample href="components/button-group#mixed-styles"> + <CButtonGroup role="group" aria-label="Basic mixed styles example"> + <CButton color="danger">Left</CButton> + <CButton color="warning">Middle</CButton> + <CButton color="success">Right</CButton> + </CButtonGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button Group</strong> <span>Outlined styles</span> + </CCardHeader> + <CCardBody> + <DocsExample href="components/button-group#outlined-styles"> + <CButtonGroup role="group" aria-label="Basic outlined example"> + <CButton color="primary" variant="outline"> + Left + </CButton> + <CButton color="primary" variant="outline"> + Middle + </CButton> + <CButton color="primary" variant="outline"> + Right + </CButton> + </CButtonGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button Group</strong> <span>Checkbox and radio button groups</span> + </CCardHeader> + <CCardBody> + <p> + Combine button-like checkbox and radio toggle buttons into a seamless looking button + group. + </p> + <DocsExample href="components/button-group#checkbox-and-radio-button-groups"> + <CButtonGroup role="group" aria-label="Basic checkbox toggle button group"> + <CFormCheck + button={{ variant: 'outline' }} + id="btncheck1" + autoComplete="off" + label="Checkbox 1" + /> + <CFormCheck + button={{ variant: 'outline' }} + id="btncheck2" + autoComplete="off" + label="Checkbox 2" + /> + <CFormCheck + button={{ variant: 'outline' }} + id="btncheck3" + autoComplete="off" + label="Checkbox 3" + /> + </CButtonGroup> + </DocsExample> + <DocsExample href="components/button-group#checkbox-and-radio-button-groups"> + <CButtonGroup role="group" aria-label="Basic checkbox toggle button group"> + <CFormCheck + type="radio" + button={{ variant: 'outline' }} + name="btnradio" + id="btnradio1" + autoComplete="off" + label="Radio 1" + /> + <CFormCheck + type="radio" + button={{ variant: 'outline' }} + name="btnradio" + id="btnradio2" + autoComplete="off" + label="Radio 2" + /> + <CFormCheck + type="radio" + button={{ variant: 'outline' }} + name="btnradio" + id="btnradio3" + autoComplete="off" + label="Radio 3" + /> + </CButtonGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button Group</strong> <span>Button toolbar</span> + </CCardHeader> + <CCardBody> + <p> + Join sets of button groups into button toolbars for more complicated components. Use + utility classes as needed to space out groups, buttons, and more. + </p> + <DocsExample href="components/button-group#button-toolbar"> + <CButtonToolbar role="group" aria-label="Toolbar with button groups"> + <CButtonGroup className="me-2" role="group" aria-label="First group"> + <CButton color="primary">1</CButton> + <CButton color="primary">2</CButton> + <CButton color="primary">3</CButton> + <CButton color="primary">4</CButton> + </CButtonGroup> + <CButtonGroup className="me-2" role="group" aria-label="Second group"> + <CButton color="secondary">5</CButton> + <CButton color="secondary">6</CButton> + <CButton color="secondary">7</CButton> + </CButtonGroup> + <CButtonGroup className="me-2" role="group" aria-label="Third group"> + <CButton color="info">8</CButton> + </CButtonGroup> + </CButtonToolbar> + </DocsExample> + <p> + Feel free to combine input groups with button groups in your toolbars. Similar to the + example above, you’ll likely need some utilities through to space items correctly. + </p> + <DocsExample href="components/button-group#button-toolbar"> + <CButtonToolbar className="mb-3" role="group" aria-label="Toolbar with button groups"> + <CButtonGroup className="me-2" role="group" aria-label="First group"> + <CButton color="secondary" variant="outline"> + 1 + </CButton> + <CButton color="secondary" variant="outline"> + 2 + </CButton> + <CButton color="secondary" variant="outline"> + 3 + </CButton> + <CButton color="secondary" variant="outline"> + 4 + </CButton> + </CButtonGroup> + <CInputGroup> + <CInputGroupText>@</CInputGroupText> + <CFormInput + placeholder="Input group example" + aria-label="Input group example" + aria-describedby="btnGroupAddon" + /> + </CInputGroup> + </CButtonToolbar> + <CButtonToolbar + className="justify-content-between" + role="group" + aria-label="Toolbar with button groups" + > + <CButtonGroup className="me-2" role="group" aria-label="First group"> + <CButton color="secondary" variant="outline"> + 1 + </CButton> + <CButton color="secondary" variant="outline"> + 2 + </CButton> + <CButton color="secondary" variant="outline"> + 3 + </CButton> + <CButton color="secondary" variant="outline"> + 4 + </CButton> + </CButtonGroup> + <CInputGroup> + <CInputGroupText>@</CInputGroupText> + <CFormInput + placeholder="Input group example" + aria-label="Input group example" + aria-describedby="btnGroupAddon" + /> + </CInputGroup> + </CButtonToolbar> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button Group</strong> <span>Sizing</span> + </CCardHeader> + <CCardBody> + <p> + Alternatively, of implementing button sizing classes to each button in a group, set{' '} + <code>size</code> property to all <code><CButtonGroup></code>'s, including + each one when nesting multiple groups. + </p> + <DocsExample href="components/button-group#sizing"> + <CButtonGroup size="lg" role="group" aria-label="Large button group"> + <CButton color="dark" variant="outline"> + Left + </CButton> + <CButton color="dark" variant="outline"> + Middle + </CButton> + <CButton color="dark" variant="outline"> + Right + </CButton> + </CButtonGroup> + <br /> + <CButtonGroup role="group" aria-label="Default button group"> + <CButton color="dark" variant="outline"> + Left + </CButton> + <CButton color="dark" variant="outline"> + Middle + </CButton> + <CButton color="dark" variant="outline"> + Right + </CButton> + </CButtonGroup> + <br /> + <CButtonGroup size="sm" role="group" aria-label="Small button group"> + <CButton color="dark" variant="outline"> + Left + </CButton> + <CButton color="dark" variant="outline"> + Middle + </CButton> + <CButton color="dark" variant="outline"> + Right + </CButton> + </CButtonGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button Group</strong> <span>Nesting</span> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Put a <code><CButtonGroup></code> inside another{' '} + <code><CButtonGroup></code> when you need dropdown menus combined with a series + of buttons. + </p> + <DocsExample href="components/button-group#nesting"> + <CButtonGroup role="group" aria-label="Button group with nested dropdown"> + <CButton color="primary">1</CButton> + <CButton color="primary">2</CButton> + <CDropdown variant="btn-group"> + <CDropdownToggle color="primary">Dropdown</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </CButtonGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button Group</strong> <span>Vertical variation</span> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Create a set of buttons that appear vertically stacked rather than horizontally.{' '} + <strong>Split button dropdowns are not supported here.</strong> + </p> + <DocsExample href="components/button-group/#vertical-variation"> + <CButtonGroup vertical role="group" aria-label="Vertical button group"> + <CButton color="dark">Button</CButton> + <CButton color="dark">Button</CButton> + <CButton color="dark">Button</CButton> + <CButton color="dark">Button</CButton> + <CButton color="dark">Button</CButton> + <CButton color="dark">Button</CButton> + <CButton color="dark">Button</CButton> + </CButtonGroup> + </DocsExample> + <DocsExample href="components/button-group/#vertical-variation"> + <CButtonGroup vertical role="group" aria-label="Vertical button group"> + <CButton color="primary">Button</CButton> + <CButton color="primary">Button</CButton> + <CDropdown variant="btn-group"> + <CDropdownToggle color="primary">Dropdown</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CButton color="primary">Button</CButton> + <CButton color="primary">Button</CButton> + <CDropdown variant="btn-group"> + <CDropdownToggle color="primary">Dropdown</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CDropdown variant="btn-group"> + <CDropdownToggle color="primary">Dropdown</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CDropdown variant="btn-group"> + <CDropdownToggle color="primary">Dropdown</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </CButtonGroup> + </DocsExample> + <DocsExample href="components/button-group/#vertical-variation"> + <CButtonGroup vertical role="group" aria-label="Vertical button group"> + <CFormCheck + type="radio" + button={{ color: 'danger', variant: 'outline' }} + name="vbtnradio" + id="vbtnradio1" + autoComplete="off" + label="Radio 1" + defaultChecked + /> + <CFormCheck + type="radio" + button={{ color: 'danger', variant: 'outline' }} + name="vbtnradio" + id="vbtnradio2" + autoComplete="off" + label="Radio 2" + /> + <CFormCheck + type="radio" + button={{ color: 'danger', variant: 'outline' }} + name="vbtnradio" + id="vbtnradio3" + autoComplete="off" + label="Radio 3" + /> + </CButtonGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default ButtonGroups diff --git a/src/views/buttons/buttons/Buttons.js b/src/views/buttons/buttons/Buttons.js new file mode 100644 index 00000000..48f6fcf7 --- /dev/null +++ b/src/views/buttons/buttons/Buttons.js @@ -0,0 +1,401 @@ +import React from 'react' +import { CButton, CCard, CCardBody, CCardHeader, CCol, CRow } from '@coreui/react' +import CIcon from '@coreui/icons-react' +import { cilBell } from '@coreui/icons' +import { DocsExample } from 'src/components' + +const Buttons = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + CoreUI includes a bunch of predefined buttons components, each serving its own + semantic purpose. Buttons show what action will happen when the user clicks or touches + it. CoreUI buttons are used to initialize operations, both in the background or + foreground of an experience. + </p> + <DocsExample href="components/buttons"> + {['normal', 'active', 'disabled'].map((state, index) => ( + <CRow className="align-items-center mb-3" key={index}> + <CCol xs={12} xl={2} className="mb-3 mb-xl-0"> + {state.charAt(0).toUpperCase() + state.slice(1)} + </CCol> + <CCol xs> + {[ + 'primary', + 'secondary', + 'success', + 'danger', + 'warning', + 'info', + 'light', + 'dark', + ].map((color, index) => ( + <CButton + color={color} + key={index} + active={state === 'active'} + disabled={state === 'disabled'} + > + {color.charAt(0).toUpperCase() + color.slice(1)} + </CButton> + ))} + <CButton color="link">Link</CButton> + </CCol> + </CRow> + ))} + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button</strong> <small>with icons</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + You can combine button with our <a href="https://icons.coreui.io/">CoreUI Icons</a>. + </p> + <DocsExample href="components/buttons"> + {['normal', 'active', 'disabled'].map((state, index) => ( + <CRow className="align-items-center mb-3" key={index}> + <CCol xs={12} xl={2} className="mb-3 mb-xl-0"> + {state.charAt(0).toUpperCase() + state.slice(1)} + </CCol> + <CCol xs> + {[ + 'primary', + 'secondary', + 'success', + 'danger', + 'warning', + 'info', + 'light', + 'dark', + ].map((color, index) => ( + <CButton + color={color} + key={index} + active={state === 'active'} + disabled={state === 'disabled'} + > + <CIcon icon={cilBell} className="me-2" /> + {color.charAt(0).toUpperCase() + color.slice(1)} + </CButton> + ))} + <CButton color="link"> + <CIcon icon={cilBell} className="me-2" /> + Link + </CButton> + </CCol> + </CRow> + ))} + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button</strong> <small>Button components</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + The <code><CButton></code> component are designed for{' '} + <code><button></code> , <code><a></code> or <code><input></code>{' '} + elements (though some browsers may apply a slightly different rendering). + </p> + <p className="text-medium-emphasis small"> + If you're using <code><CButton></code> component as <code><a></code>{' '} + elements that are used to trigger functionality ex. collapsing content, these links + should be given a <code>role="button"</code> to adequately communicate their + meaning to assistive technologies such as screen readers. + </p> + <DocsExample href="components/buttons#button-components"> + <CButton component="a" color="primary" href="#" role="button"> + Link + </CButton> + <CButton type="submit" color="primary"> + Button + </CButton> + <CButton component="input" type="button" color="primary" value="Input" /> + <CButton component="input" type="submit" color="primary" value="Submit" /> + <CButton component="input" type="reset" color="primary" value="Reset" /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button</strong> <small>outline</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + If you need a button, but without the strong background colors. Set{' '} + <code>variant="outline"</code> prop to remove all background colors. + </p> + <DocsExample href="components/buttons#outline-buttons"> + {['normal', 'active', 'disabled'].map((state, index) => ( + <CRow className="align-items-center mb-3" key={index}> + <CCol xs={12} xl={2} className="mb-3 mb-xl-0"> + {state.charAt(0).toUpperCase() + state.slice(1)} + </CCol> + <CCol xs> + {[ + 'primary', + 'secondary', + 'success', + 'danger', + 'warning', + 'info', + 'light', + 'dark', + ].map((color, index) => ( + <CButton + color={color} + variant="outline" + key={index} + active={state === 'active'} + disabled={state === 'disabled'} + > + {color.charAt(0).toUpperCase() + color.slice(1)} + </CButton> + ))} + </CCol> + </CRow> + ))} + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button</strong> <small>ghost</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + If you need a ghost variant of button, set <code>variant="ghost"</code> prop + to remove all background colors. + </p> + <DocsExample href="components/buttons#ghost-buttons"> + {['normal', 'active', 'disabled'].map((state, index) => ( + <CRow className="align-items-center mb-3" key={index}> + <CCol xs={12} xl={2} className="mb-3 mb-xl-0"> + {state.charAt(0).toUpperCase() + state.slice(1)} + </CCol> + <CCol xs> + {[ + 'primary', + 'secondary', + 'success', + 'danger', + 'warning', + 'info', + 'light', + 'dark', + ].map((color, index) => ( + <CButton + color={color} + variant="ghost" + key={index} + active={state === 'active'} + disabled={state === 'disabled'} + > + {color.charAt(0).toUpperCase() + color.slice(1)} + </CButton> + ))} + </CCol> + </CRow> + ))} + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button</strong> <small>Sizes</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Larger or smaller buttons? Add <code>size="lg"</code> or{' '} + <code>size="sm"</code> for additional sizes. + </p> + <DocsExample href="components/buttons#sizes"> + <CButton color="primary" size="lg"> + Large button + </CButton> + <CButton color="secondary" size="lg"> + Large button + </CButton> + </DocsExample> + <DocsExample href="components/buttons#sizes"> + <CButton color="primary" size="sm"> + Small button + </CButton> + <CButton color="secondary" size="sm"> + Small button + </CButton> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button</strong> <small>Pill</small> + </CCardHeader> + <CCardBody> + <DocsExample href="components/buttons#pill-buttons"> + {[ + 'primary', + 'secondary', + 'success', + 'danger', + 'warning', + 'info', + 'light', + 'dark', + ].map((color, index) => ( + <CButton color={color} shape="rounded-pill" key={index}> + {color.charAt(0).toUpperCase() + color.slice(1)} + </CButton> + ))} + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button</strong> <small>Square</small> + </CCardHeader> + <CCardBody> + <DocsExample href="components/buttons#square"> + {[ + 'primary', + 'secondary', + 'success', + 'danger', + 'warning', + 'info', + 'light', + 'dark', + ].map((color, index) => ( + <CButton color={color} shape="rounded-0" key={index}> + {color.charAt(0).toUpperCase() + color.slice(1)} + </CButton> + ))} + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button</strong> <small>Disabled state</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add the <code>disabled</code> boolean prop to any <code><CButton></code>{' '} + component to make buttons look inactive. Disabled button has{' '} + <code>pointer-events: none</code> applied to, disabling hover and active states from + triggering. + </p> + <DocsExample href="components/buttons#disabled-state"> + <CButton color="primary" size="lg" disabled> + Primary button + </CButton> + <CButton color="secondary" size="lg" disabled> + Button + </CButton> + </DocsExample> + <p className="text-medium-emphasis small"> + Disabled buttons using the <code><a></code> component act a little different: + </p> + <p className="text-medium-emphasis small"> + <code><a></code>s don'tsupport the <code>disabled</code> attribute, so + CoreUI has to add <code>.disabled</code> className to make buttons look inactive. + CoreUI also has to add to the disabled button component{' '} + <code>aria-disabled="true"</code> attribute to show the state of the component + to assistive technologies. + </p> + <DocsExample href="components/buttons#disabled-state"> + <CButton component="a" href="#" color="primary" size="lg" disabled> + Primary link + </CButton> + <CButton component="a" href="#" color="secondary" size="lg" disabled> + Link + </CButton> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Button</strong> <small>Block buttons</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Create buttons that span the full width of a parent—by using utilities. + </p> + <DocsExample href="components/buttons#block-buttons"> + <div className="d-grid gap-2"> + <CButton color="primary">Button</CButton> + <CButton color="primary">Button</CButton> + </div> + </DocsExample> + <p className="text-medium-emphasis small"> + Here we create a responsive variation, starting with vertically stacked buttons until + the <code>md</code> breakpoint, where <code>.d-md-block</code> replaces the{' '} + <code>.d-grid</code> class, thus nullifying the <code>gap-2</code> utility. Resize + your browser to see them change. + </p> + <DocsExample href="components/buttons#block-buttons"> + <div className="d-grid gap-2 d-md-block"> + <CButton color="primary">Button</CButton> + <CButton color="primary">Button</CButton> + </div> + </DocsExample> + <p className="text-medium-emphasis small"> + You can adjust the width of your block buttons with grid column width classes. For + example, for a half-width "block button", use <code>.col-6</code>. Center it + horizontally with <code>.mx-auto</code>, too. + </p> + <DocsExample href="components/buttons#block-buttons"> + <div className="d-grid gap-2 col-6 mx-auto"> + <CButton color="primary">Button</CButton> + <CButton color="primary">Button</CButton> + </div> + </DocsExample> + <p className="text-medium-emphasis small"> + Additional utilities can be used to adjust the alignment of buttons when horizontal. + Here we've taken our previous responsive example and added some flex utilities and + a margin utility on the button to right align the buttons when they're no longer + stacked. + </p> + <DocsExample href="components/buttons#block-buttons"> + <div className="d-grid gap-2 d-md-flex justify-content-md-end"> + <CButton color="primary" className="me-md-2"> + Button + </CButton> + <CButton color="primary">Button</CButton> + </div> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Buttons diff --git a/src/views/buttons/dropdowns/Dropdowns.js b/src/views/buttons/dropdowns/Dropdowns.js new file mode 100644 index 00000000..414f651f --- /dev/null +++ b/src/views/buttons/dropdowns/Dropdowns.js @@ -0,0 +1,338 @@ +import React from 'react' +import { + CButton, + CButtonGroup, + CCard, + CCardBody, + CCardHeader, + CCol, + CDropdown, + CDropdownDivider, + CDropdownItem, + CDropdownMenu, + CDropdownToggle, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const Dropdowns = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Dropdown</strong> <small>Single button</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Here's how you can put them to work with either <code><button></code>{' '} + elements: + </p> + <DocsExample href="components/dropdown#single-button"> + <CDropdown> + <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </DocsExample> + <p className="text-medium-emphasis small"> + The best part is you can do this with any button variant, too: + </p> + <DocsExample href="components/dropdown#single-button"> + <> + {['primary', 'secondary', 'success', 'info', 'warning', 'danger'].map( + (color, index) => ( + <CDropdown variant="btn-group" key={index}> + <CDropdownToggle color={color}>{color}</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + ), + )} + </> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Dropdown</strong> <small>Split button</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Similarly, create split button dropdowns with virtually the same markup as single + button dropdowns, but with the addition of boolean prop <code>split</code> for proper + spacing around the dropdown caret. + </p> + <p className="text-medium-emphasis small"> + We use this extra class to reduce the horizontal <code>padding</code> on either side + of the caret by 25% and remove the <code>margin-left</code> that's attached for + normal button dropdowns. Those additional changes hold the caret centered in the split + button and implement a more properly sized hit area next to the main button. + </p> + <DocsExample href="components/dropdown#split-button"> + <> + {['primary', 'secondary', 'success', 'info', 'warning', 'danger'].map( + (color, index) => ( + <CDropdown variant="btn-group" key={index}> + <CButton color={color}>{color}</CButton> + <CDropdownToggle color={color} split /> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + ), + )} + </> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Dropdown</strong> <small>Sizing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Button dropdowns work with buttons of all sizes, including default and split dropdown + buttons. + </p> + <DocsExample href="components/dropdown#sizing"> + <CDropdown variant="btn-group"> + <CDropdownToggle color="secondary" size="lg"> + Large button + </CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CDropdown variant="btn-group"> + <CButton color="secondary" size="lg"> + Large split button + </CButton> + <CDropdownToggle color="secondary" size="lg" split /> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </DocsExample> + <DocsExample href="components/dropdown#sizing"> + <CDropdown variant="btn-group"> + <CDropdownToggle color="secondary" size="sm"> + Small button + </CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CDropdown variant="btn-group"> + <CButton color="secondary" size="sm"> + Small split button + </CButton> + <CDropdownToggle color="secondary" size="sm" split /> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Dropdown</strong> <small>Single button</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Opt into darker dropdowns to match a dark navbar or custom style by set{' '} + <code>dark</code> property. No changes are required to the dropdown items. + </p> + <DocsExample href="components/dropdown#dark-dropdowns"> + <CDropdown dark> + <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </DocsExample> + <p className="text-medium-emphasis small">And putting it to use in a navbar:</p> + <DocsExample href="components/dropdown#dark-dropdowns"> + <nav className="navbar navbar-expand-lg navbar-dark bg-dark"> + <div className="container-fluid"> + <a className="navbar-brand" href="https://coreui.io/react/"> + Navbar + </a> + <button + className="navbar-toggler" + type="button" + data-coreui-toggle="collapse" + data-coreui-target="#navbarNavDarkDropdown" + aria-controls="navbarNavDarkDropdown" + aria-expanded="false" + aria-label="Toggle navigation" + > + <span className="navbar-toggler-icon"></span> + </button> + <div className="collapse navbar-collapse" id="navbarNavDarkDropdown"> + <ul className="navbar-nav"> + <CDropdown dark component="li" variant="nav-item"> + <CDropdownToggle>Dropdown</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </ul> + </div> + </div> + </nav> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Dropdown</strong> <small>Dropup</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Trigger dropdown menus above elements by adding{' '} + <code>direction="dropup"</code> to the <code><CDropdown></code>{' '} + component. + </p> + <DocsExample href="components/dropdown#dropup"> + <CDropdown variant="btn-group" direction="dropup"> + <CDropdownToggle color="secondary">Dropdown</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CDropdown variant="btn-group" direction="dropup"> + <CButton color="secondary">Small split button</CButton> + <CDropdownToggle color="secondary" split /> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Dropdown</strong> <small>Dropright</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Trigger dropdown menus at the right of the elements by adding{' '} + <code>direction="dropend"</code> to the <code><CDropdown></code>{' '} + component. + </p> + <DocsExample href="components/dropdown#dropright"> + <CDropdown variant="btn-group" direction="dropend"> + <CDropdownToggle color="secondary">Dropdown</CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CDropdown variant="btn-group" direction="dropend"> + <CButton color="secondary">Small split button</CButton> + <CDropdownToggle color="secondary" split /> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Dropdown</strong> <small>Dropleft</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Trigger dropdown menus at the left of the elements by adding{' '} + <code>direction="dropstart"</code> to the <code><CDropdown></code>{' '} + component. + </p> + <DocsExample href="components/dropdown#dropleft"> + <CButtonGroup> + <CDropdown variant="btn-group" direction="dropstart"> + <CDropdownToggle color="secondary" split /> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CButton color="secondary">Small split button</CButton> + </CButtonGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Dropdowns diff --git a/src/views/buttons/index.js b/src/views/buttons/index.js new file mode 100644 index 00000000..6634d152 --- /dev/null +++ b/src/views/buttons/index.js @@ -0,0 +1,5 @@ +import ButtonDropdowns from './ButtonDropdowns' +import ButtonGroups from './ButtonGroups' +import Buttons from './Buttons' + +export { ButtonDropdowns, ButtonGroups, Buttons } diff --git a/src/views/charts/Charts.js b/src/views/charts/Charts.js new file mode 100644 index 00000000..a9e13f10 --- /dev/null +++ b/src/views/charts/Charts.js @@ -0,0 +1,176 @@ +import React from 'react' +import { CCard, CCardBody, CCol, CCardHeader, CRow } from '@coreui/react' +import { + CChartBar, + CChartDoughnut, + CChartLine, + CChartPie, + CChartPolarArea, + CChartRadar, +} from '@coreui/react-chartjs' +import { DocsCallout } from 'src/components' + +const Charts = () => { + const random = () => Math.round(Math.random() * 100) + + return ( + <CRow> + <CCol xs={12}> + <DocsCallout + name="Chart" + href="components/chart" + content="React wrapper component for Chart.js 3.0, the most popular charting library." + /> + </CCol> + <CCol xs={6}> + <CCard className="mb-4"> + <CCardHeader>Bar Chart</CCardHeader> + <CCardBody> + <CChartBar + data={{ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + label: 'GitHub Commits', + backgroundColor: '#f87979', + data: [40, 20, 12, 39, 10, 40, 39, 80, 40], + }, + ], + }} + labels="months" + /> + </CCardBody> + </CCard> + </CCol> + <CCol xs={6}> + <CCard className="mb-4"> + <CCardHeader>Line Chart</CCardHeader> + <CCardBody> + <CChartLine + data={{ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + label: 'My First dataset', + backgroundColor: 'rgba(220, 220, 220, 0.2)', + borderColor: 'rgba(220, 220, 220, 1)', + pointBackgroundColor: 'rgba(220, 220, 220, 1)', + pointBorderColor: '#fff', + data: [random(), random(), random(), random(), random(), random(), random()], + }, + { + label: 'My Second dataset', + backgroundColor: 'rgba(151, 187, 205, 0.2)', + borderColor: 'rgba(151, 187, 205, 1)', + pointBackgroundColor: 'rgba(151, 187, 205, 1)', + pointBorderColor: '#fff', + data: [random(), random(), random(), random(), random(), random(), random()], + }, + ], + }} + /> + </CCardBody> + </CCard> + </CCol> + <CCol xs={6}> + <CCard className="mb-4"> + <CCardHeader>Doughnut Chart</CCardHeader> + <CCardBody> + <CChartDoughnut + data={{ + labels: ['VueJs', 'EmberJs', 'ReactJs', 'AngularJs'], + datasets: [ + { + backgroundColor: ['#41B883', '#E46651', '#00D8FF', '#DD1B16'], + data: [40, 20, 80, 10], + }, + ], + }} + /> + </CCardBody> + </CCard> + </CCol> + <CCol xs={6}> + <CCard className="mb-4"> + <CCardHeader>Pie Chart</CCardHeader> + <CCardBody> + <CChartPie + data={{ + labels: ['Red', 'Green', 'Yellow'], + datasets: [ + { + data: [300, 50, 100], + backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], + hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], + }, + ], + }} + /> + </CCardBody> + </CCard> + </CCol> + <CCol xs={6}> + <CCard className="mb-4"> + <CCardHeader>Polar Area Chart</CCardHeader> + <CCardBody> + <CChartPolarArea + data={{ + labels: ['Red', 'Green', 'Yellow', 'Grey', 'Blue'], + datasets: [ + { + data: [11, 16, 7, 3, 14], + backgroundColor: ['#FF6384', '#4BC0C0', '#FFCE56', '#E7E9ED', '#36A2EB'], + }, + ], + }} + /> + </CCardBody> + </CCard> + </CCol> + <CCol xs={6}> + <CCard className="mb-4"> + <CCardHeader>Radar Chart</CCardHeader> + <CCardBody> + <CChartRadar + data={{ + labels: [ + 'Eating', + 'Drinking', + 'Sleeping', + 'Designing', + 'Coding', + 'Cycling', + 'Running', + ], + datasets: [ + { + label: 'My First dataset', + backgroundColor: 'rgba(220, 220, 220, 0.2)', + borderColor: 'rgba(220, 220, 220, 1)', + pointBackgroundColor: 'rgba(220, 220, 220, 1)', + pointBorderColor: '#fff', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(220, 220, 220, 1)', + data: [65, 59, 90, 81, 56, 55, 40], + }, + { + label: 'My Second dataset', + backgroundColor: 'rgba(151, 187, 205, 0.2)', + borderColor: 'rgba(151, 187, 205, 1)', + pointBackgroundColor: 'rgba(151, 187, 205, 1)', + pointBorderColor: '#fff', + pointHighlightFill: '#fff', + pointHighlightStroke: 'rgba(151, 187, 205, 1)', + data: [28, 48, 40, 19, 96, 27, 100], + }, + ], + }} + /> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Charts diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js new file mode 100644 index 00000000..e979a0c1 --- /dev/null +++ b/src/views/dashboard/Dashboard.js @@ -0,0 +1,461 @@ +import React from 'react' + +import { + CAvatar, + CButton, + CButtonGroup, + CCard, + CCardBody, + CCardFooter, + CCardHeader, + CCol, + CProgress, + CRow, + CTable, + CTableBody, + CTableDataCell, + CTableHead, + CTableHeaderCell, + CTableRow, +} from '@coreui/react' +import { CChartLine } from '@coreui/react-chartjs' +import { getStyle, hexToRgba } from '@coreui/utils' +import CIcon from '@coreui/icons-react' +import { + cibCcAmex, + cibCcApplePay, + cibCcMastercard, + cibCcPaypal, + cibCcStripe, + cibCcVisa, + cibGoogle, + cibFacebook, + cibLinkedin, + cifBr, + cifEs, + cifFr, + cifIn, + cifPl, + cifUs, + cibTwitter, + cilCloudDownload, + cilPeople, + cilUser, + cilUserFemale, +} from '@coreui/icons' + +import avatar1 from 'src/assets/images/avatars/1.jpg' +import avatar2 from 'src/assets/images/avatars/2.jpg' +import avatar3 from 'src/assets/images/avatars/3.jpg' +import avatar4 from 'src/assets/images/avatars/4.jpg' +import avatar5 from 'src/assets/images/avatars/5.jpg' +import avatar6 from 'src/assets/images/avatars/6.jpg' + +import WidgetsBrand from '../widgets/WidgetsBrand' +import WidgetsDropdown from '../widgets/WidgetsDropdown' + +const Dashboard = () => { + const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min) + + const progressExample = [ + { title: 'Visits', value: '29.703 Users', percent: 40, color: 'success' }, + { title: 'Unique', value: '24.093 Users', percent: 20, color: 'info' }, + { title: 'Pageviews', value: '78.706 Views', percent: 60, color: 'warning' }, + { title: 'New Users', value: '22.123 Users', percent: 80, color: 'danger' }, + { title: 'Bounce Rate', value: 'Average Rate', percent: 40.15, color: 'primary' }, + ] + + const progressGroupExample1 = [ + { title: 'Monday', value1: 34, value2: 78 }, + { title: 'Tuesday', value1: 56, value2: 94 }, + { title: 'Wednesday', value1: 12, value2: 67 }, + { title: 'Thursday', value1: 43, value2: 91 }, + { title: 'Friday', value1: 22, value2: 73 }, + { title: 'Saturday', value1: 53, value2: 82 }, + { title: 'Sunday', value1: 9, value2: 69 }, + ] + + const progressGroupExample2 = [ + { title: 'Male', icon: cilUser, value: 53 }, + { title: 'Female', icon: cilUserFemale, value: 43 }, + ] + + const progressGroupExample3 = [ + { title: 'Organic Search', icon: cibGoogle, percent: 56, value: '191,235' }, + { title: 'Facebook', icon: cibFacebook, percent: 15, value: '51,223' }, + { title: 'Twitter', icon: cibTwitter, percent: 11, value: '37,564' }, + { title: 'LinkedIn', icon: cibLinkedin, percent: 8, value: '27,319' }, + ] + + const tableExample = [ + { + avatar: { src: avatar1, status: 'success' }, + user: { + name: 'Yiorgos Avraamu', + new: true, + registered: 'Jan 1, 2021', + }, + country: { name: 'USA', flag: cifUs }, + usage: { + value: 50, + period: 'Jun 11, 2021 - Jul 10, 2021', + color: 'success', + }, + payment: { name: 'Mastercard', icon: cibCcMastercard }, + activity: '10 sec ago', + }, + { + avatar: { src: avatar2, status: 'danger' }, + user: { + name: 'Avram Tarasios', + new: false, + registered: 'Jan 1, 2021', + }, + country: { name: 'Brazil', flag: cifBr }, + usage: { + value: 22, + period: 'Jun 11, 2021 - Jul 10, 2021', + color: 'info', + }, + payment: { name: 'Visa', icon: cibCcVisa }, + activity: '5 minutes ago', + }, + { + avatar: { src: avatar3, status: 'warning' }, + user: { name: 'Quintin Ed', new: true, registered: 'Jan 1, 2021' }, + country: { name: 'India', flag: cifIn }, + usage: { + value: 74, + period: 'Jun 11, 2021 - Jul 10, 2021', + color: 'warning', + }, + payment: { name: 'Stripe', icon: cibCcStripe }, + activity: '1 hour ago', + }, + { + avatar: { src: avatar4, status: 'secondary' }, + user: { name: 'Enéas Kwadwo', new: true, registered: 'Jan 1, 2021' }, + country: { name: 'France', flag: cifFr }, + usage: { + value: 98, + period: 'Jun 11, 2021 - Jul 10, 2021', + color: 'danger', + }, + payment: { name: 'PayPal', icon: cibCcPaypal }, + activity: 'Last month', + }, + { + avatar: { src: avatar5, status: 'success' }, + user: { + name: 'Agapetus Tadeáš', + new: true, + registered: 'Jan 1, 2021', + }, + country: { name: 'Spain', flag: cifEs }, + usage: { + value: 22, + period: 'Jun 11, 2021 - Jul 10, 2021', + color: 'primary', + }, + payment: { name: 'Google Wallet', icon: cibCcApplePay }, + activity: 'Last week', + }, + { + avatar: { src: avatar6, status: 'danger' }, + user: { + name: 'Friderik Dávid', + new: true, + registered: 'Jan 1, 2021', + }, + country: { name: 'Poland', flag: cifPl }, + usage: { + value: 43, + period: 'Jun 11, 2021 - Jul 10, 2021', + color: 'success', + }, + payment: { name: 'Amex', icon: cibCcAmex }, + activity: 'Last week', + }, + ] + + return ( + <> + <WidgetsDropdown /> + <CCard className="mb-4"> + <CCardBody> + <CRow> + <CCol sm={5}> + <h4 id="traffic" className="card-title mb-0"> + Traffic + </h4> + <div className="small text-medium-emphasis">January - July 2021</div> + </CCol> + <CCol sm={7} className="d-none d-md-block"> + <CButton color="primary" className="float-end"> + <CIcon icon={cilCloudDownload} /> + </CButton> + <CButtonGroup className="float-end me-3"> + {['Day', 'Month', 'Year'].map((value) => ( + <CButton + color="outline-secondary" + key={value} + className="mx-0" + active={value === 'Month'} + > + {value} + </CButton> + ))} + </CButtonGroup> + </CCol> + </CRow> + <CChartLine + style={{ height: '300px', marginTop: '40px' }} + data={{ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + label: 'My First dataset', + backgroundColor: hexToRgba(getStyle('--cui-info'), 10), + borderColor: getStyle('--cui-info'), + pointHoverBackgroundColor: getStyle('--cui-info'), + borderWidth: 2, + data: [ + random(50, 200), + random(50, 200), + random(50, 200), + random(50, 200), + random(50, 200), + random(50, 200), + random(50, 200), + ], + fill: true, + }, + { + label: 'My Second dataset', + backgroundColor: 'transparent', + borderColor: getStyle('--cui-success'), + pointHoverBackgroundColor: getStyle('--cui-success'), + borderWidth: 2, + data: [ + random(50, 200), + random(50, 200), + random(50, 200), + random(50, 200), + random(50, 200), + random(50, 200), + random(50, 200), + ], + }, + { + label: 'My Third dataset', + backgroundColor: 'transparent', + borderColor: getStyle('--cui-danger'), + pointHoverBackgroundColor: getStyle('--cui-danger'), + borderWidth: 1, + borderDash: [8, 5], + data: [65, 65, 65, 65, 65, 65, 65], + }, + ], + }} + options={{ + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + }, + }, + scales: { + x: { + grid: { + drawOnChartArea: false, + }, + }, + y: { + ticks: { + beginAtZero: true, + maxTicksLimit: 5, + stepSize: Math.ceil(250 / 5), + max: 250, + }, + }, + }, + elements: { + line: { + tension: 0.4, + }, + point: { + radius: 0, + hitRadius: 10, + hoverRadius: 4, + hoverBorderWidth: 3, + }, + }, + }} + /> + </CCardBody> + <CCardFooter> + <CRow xs={{ cols: 1 }} md={{ cols: 5 }} className="text-center"> + {progressExample.map((item, index) => ( + <CCol className="mb-sm-2 mb-0" key={index}> + <div className="text-medium-emphasis">{item.title}</div> + <strong> + {item.value} ({item.percent}%) + </strong> + <CProgress thin className="mt-2" color={item.color} value={item.percent} /> + </CCol> + ))} + </CRow> + </CCardFooter> + </CCard> + + <WidgetsBrand withCharts /> + + <CRow> + <CCol xs> + <CCard className="mb-4"> + <CCardHeader>Traffic {' & '} Sales</CCardHeader> + <CCardBody> + <CRow> + <CCol xs={12} md={6} xl={6}> + <CRow> + <CCol sm={6}> + <div className="border-start border-start-4 border-start-info py-1 px-3"> + <div className="text-medium-emphasis small">New Clients</div> + <div className="fs-5 fw-semibold">9,123</div> + </div> + </CCol> + <CCol sm={6}> + <div className="border-start border-start-4 border-start-danger py-1 px-3 mb-3"> + <div className="text-medium-emphasis small">Recurring Clients</div> + <div className="fs-5 fw-semibold">22,643</div> + </div> + </CCol> + </CRow> + + <hr className="mt-0" /> + {progressGroupExample1.map((item, index) => ( + <div className="progress-group mb-4" key={index}> + <div className="progress-group-prepend"> + <span className="text-medium-emphasis small">{item.title}</span> + </div> + <div className="progress-group-bars"> + <CProgress thin color="info" value={item.value1} /> + <CProgress thin color="danger" value={item.value2} /> + </div> + </div> + ))} + </CCol> + + <CCol xs={12} md={6} xl={6}> + <CRow> + <CCol sm={6}> + <div className="border-start border-start-4 border-start-warning py-1 px-3 mb-3"> + <div className="text-medium-emphasis small">Pageviews</div> + <div className="fs-5 fw-semibold">78,623</div> + </div> + </CCol> + <CCol sm={6}> + <div className="border-start border-start-4 border-start-success py-1 px-3 mb-3"> + <div className="text-medium-emphasis small">Organic</div> + <div className="fs-5 fw-semibold">49,123</div> + </div> + </CCol> + </CRow> + + <hr className="mt-0" /> + + {progressGroupExample2.map((item, index) => ( + <div className="progress-group mb-4" key={index}> + <div className="progress-group-header"> + <CIcon className="me-2" icon={item.icon} size="lg" /> + <span>{item.title}</span> + <span className="ms-auto fw-semibold">{item.value}%</span> + </div> + <div className="progress-group-bars"> + <CProgress thin color="warning" value={item.value} /> + </div> + </div> + ))} + + <div className="mb-5"></div> + + {progressGroupExample3.map((item, index) => ( + <div className="progress-group" key={index}> + <div className="progress-group-header"> + <CIcon className="me-2" icon={item.icon} size="lg" /> + <span>{item.title}</span> + <span className="ms-auto fw-semibold"> + {item.value}{' '} + <span className="text-medium-emphasis small">({item.percent}%)</span> + </span> + </div> + <div className="progress-group-bars"> + <CProgress thin color="success" value={item.percent} /> + </div> + </div> + ))} + </CCol> + </CRow> + + <br /> + + <CTable align="middle" className="mb-0 border" hover responsive> + <CTableHead color="light"> + <CTableRow> + <CTableHeaderCell className="text-center"> + <CIcon icon={cilPeople} /> + </CTableHeaderCell> + <CTableHeaderCell>User</CTableHeaderCell> + <CTableHeaderCell className="text-center">Country</CTableHeaderCell> + <CTableHeaderCell>Usage</CTableHeaderCell> + <CTableHeaderCell className="text-center">Payment Method</CTableHeaderCell> + <CTableHeaderCell>Activity</CTableHeaderCell> + </CTableRow> + </CTableHead> + <CTableBody> + {tableExample.map((item, index) => ( + <CTableRow v-for="item in tableItems" key={index}> + <CTableDataCell className="text-center"> + <CAvatar size="md" src={item.avatar.src} status={item.avatar.status} /> + </CTableDataCell> + <CTableDataCell> + <div>{item.user.name}</div> + <div className="small text-medium-emphasis"> + <span>{item.user.new ? 'New' : 'Recurring'}</span> | Registered:{' '} + {item.user.registered} + </div> + </CTableDataCell> + <CTableDataCell className="text-center"> + <CIcon size="xl" icon={item.country.flag} title={item.country.name} /> + </CTableDataCell> + <CTableDataCell> + <div className="clearfix"> + <div className="float-start"> + <strong>{item.usage.value}%</strong> + </div> + <div className="float-end"> + <small className="text-medium-emphasis">{item.usage.period}</small> + </div> + </div> + <CProgress thin color={item.usage.color} value={item.usage.value} /> + </CTableDataCell> + <CTableDataCell className="text-center"> + <CIcon size="xl" icon={item.payment.icon} /> + </CTableDataCell> + <CTableDataCell> + <div className="small text-medium-emphasis">Last login</div> + <strong>{item.activity}</strong> + </CTableDataCell> + </CTableRow> + ))} + </CTableBody> + </CTable> + </CCardBody> + </CCard> + </CCol> + </CRow> + </> + ) +} + +export default Dashboard diff --git a/src/views/forms/checks-radios/ChecksRadios.js b/src/views/forms/checks-radios/ChecksRadios.js new file mode 100644 index 00000000..f35862ec --- /dev/null +++ b/src/views/forms/checks-radios/ChecksRadios.js @@ -0,0 +1,392 @@ +import React from 'react' +import { CCard, CCardBody, CCardHeader, CCol, CFormCheck, CFormSwitch, CRow } from '@coreui/react' +import { DocsExample } from 'src/components' + +const ChecksRadios = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Checkbox</strong> + </CCardHeader> + <CCardBody> + <DocsExample href="forms/checks-radios"> + <CFormCheck id="flexCheckDefault" label="Default checkbox" /> + <CFormCheck id="flexCheckChecked" label="Checked checkbox" defaultChecked /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Checkbox</strong> <small>Disabled</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add the <code>disabled</code> attribute and the associated <code><label></code>s + are automatically styled to match with a lighter color to help indicate the + input's state. + </p> + <DocsExample href="forms/checks-radios#disabled"> + <CFormCheck label="Disabled checkbox" disabled /> + <CFormCheck label="Disabled checked checkbox" defaultChecked disabled /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Radio</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add the <code>disabled</code> attribute and the associated <code><label></code>s + are automatically styled to match with a lighter color to help indicate the + input's state. + </p> + <DocsExample href="forms/checks-radios#radios"> + <CFormCheck + type="radio" + name="flexRadioDefault" + id="flexRadioDefault1" + label="Default radio" + /> + <CFormCheck + type="radio" + name="flexRadioDefault" + id="flexRadioDefault2" + label="Checked radio" + defaultChecked + /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Radio</strong> <small>Disabled</small> + </CCardHeader> + <CCardBody> + <DocsExample href="forms/checks-radios#disabled-1"> + <CFormCheck + type="radio" + name="flexRadioDisabled" + id="flexRadioDisabled" + label="Disabled radio" + disabled + /> + <CFormCheck + type="radio" + name="flexRadioDisabled" + id="flexRadioCheckedDisabled" + label="Disabled checked radio" + defaultChecked + disabled + /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Switches</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + A switch has the markup of a custom checkbox but uses the <code>switch</code> boolean + properly to render a toggle switch. Switches also support the <code>disabled</code>{' '} + attribute. + </p> + <DocsExample href="forms/checks-radios#switches"> + <CFormSwitch label="Default switch checkbox input" id="formSwitchCheckDefault" /> + <CFormSwitch + label="Checked switch checkbox input" + id="formSwitchCheckChecked" + defaultChecked + /> + <CFormSwitch + label="Disabled switch checkbox input" + id="formSwitchCheckDisabled" + disabled + /> + <CFormSwitch + label="Disabled checked switch checkbox input" + id="formSwitchCheckCheckedDisabled" + defaultChecked + disabled + /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Switches</strong> <small>Sizes</small> + </CCardHeader> + <CCardBody> + <DocsExample href="forms/checks-radios#sizes"> + <CFormSwitch label="Default switch checkbox input" id="formSwitchCheckDefault" /> + <CFormSwitch + size="lg" + label="Large switch checkbox input" + id="formSwitchCheckDefaultLg" + /> + <CFormSwitch + size="xl" + label="Extra large switch checkbox input" + id="formSwitchCheckDefaultXL" + /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Checks and Radios</strong> <small>Default layout (stacked)</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + By default, any number of checkboxes and radios that are immediate sibling will be + vertically stacked and appropriately spaced. + </p> + <DocsExample href="forms/checks-radios#default-stacked"> + <CFormCheck id="defaultCheck1" label="Default checkbox" /> + <CFormCheck id="defaultCheck2" label="Disabled checkbox" disabled /> + </DocsExample> + <DocsExample href="forms/checks-radios#default-stacked"> + <CFormCheck + type="radio" + name="exampleRadios" + id="exampleRadios1" + value="option1" + label="Default radio" + defaultChecked + /> + <CFormCheck + type="radio" + name="exampleRadios" + id="exampleRadios2" + value="option2" + label="Second default radio" + /> + <CFormCheck + type="radio" + name="exampleRadios" + id="exampleRadios3" + value="option3" + label="Disabled radio" + disabled + /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Checks and Radios</strong> <small>Inline</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Group checkboxes or radios on the same horizontal row by adding <code>inline</code>{' '} + boolean property to any <code><CFormCheck></code>. + </p> + <DocsExample href="forms/checks-radios#inline"> + <CFormCheck inline id="inlineCheckbox1" value="option1" label="1" /> + <CFormCheck inline id="inlineCheckbox2" value="option2" label="2" /> + <CFormCheck + inline + id="inlineCheckbox3" + value="option3" + label="3 (disabled)" + disabled + /> + </DocsExample> + <DocsExample href="forms/checks-radios#inline"> + <CFormCheck + inline + type="radio" + name="inlineRadioOptions" + id="inlineCheckbox1" + value="option1" + label="1" + /> + <CFormCheck + inline + type="radio" + name="inlineRadioOptions" + id="inlineCheckbox2" + value="option2" + label="2" + /> + <CFormCheck + inline + type="radio" + name="inlineRadioOptions" + id="inlineCheckbox3" + value="option3" + label="3 (disabled)" + disabled + /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Checks and Radios</strong> <small>Without labels</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Remember to still provide some form of accessible name for assistive technologies (for + instance, using <code>aria-label</code>). + </p> + <DocsExample href="forms/checks-radios#without-labels"> + <div> + <CFormCheck id="checkboxNoLabel" value="" aria-label="..." /> + </div> + <div> + <CFormCheck + type="radio" + name="radioNoLabel" + id="radioNoLabel" + value="" + aria-label="..." + /> + </div> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Toggle buttons</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Create button-like checkboxes and radio buttons by using <code>button</code> boolean + property on the <code><CFormCheck></code> component. These toggle buttons can + further be grouped in a button group if needed. + </p> + <DocsExample href="forms/checks-radios#toggle-buttons"> + <CFormCheck + button={{ color: 'primary ' }} + id="btn-check" + autoComplete="off" + label="Single toggle" + /> + </DocsExample> + <DocsExample href="forms/checks-radios#toggle-buttons"> + <CFormCheck + button={{ color: 'primary ' }} + id="btn-check-2" + autoComplete="off" + label="Checked" + defaultChecked + /> + </DocsExample> + <DocsExample href="forms/checks-radios#toggle-buttons"> + <CFormCheck + button={{ color: 'primary ' }} + id="btn-check-3" + autoComplete="off" + label="Disabled" + disabled + /> + </DocsExample> + <h3>Radio toggle buttons</h3> + <DocsExample href="forms/checks-radios#toggle-buttons"> + <CFormCheck + button={{ color: 'secondary' }} + type="radio" + name="options" + id="option1" + autoComplete="off" + label="Checked" + defaultChecked + /> + <CFormCheck + button={{ color: 'secondary' }} + type="radio" + name="options" + id="option2" + autoComplete="off" + label="Radio" + /> + <CFormCheck + button={{ color: 'secondary' }} + type="radio" + name="options" + id="option3" + autoComplete="off" + label="Radio" + disabled + /> + <CFormCheck + button={{ color: 'secondary' }} + type="radio" + name="options" + id="option4" + autoComplete="off" + label="Radio" + /> + </DocsExample> + <h3>Outlined styles</h3> + <p className="text-medium-emphasis small"> + Different variants of button, such at the various outlined styles, are supported. + </p> + <DocsExample href="forms/checks-radios#toggle-buttons"> + <div> + <CFormCheck + button={{ color: 'primary', variant: 'outline' }} + id="btn-check-outlined" + autoComplete="off" + label="Single toggle" + /> + </div> + <div> + <CFormCheck + button={{ color: 'secondary', variant: 'outline' }} + id="btn-check-2-outlined" + autoComplete="off" + label="Checked" + defaultChecked + /> + </div> + <div> + <CFormCheck + button={{ color: 'success', variant: 'outline' }} + type="radio" + name="options-outlined" + id="success-outlined" + autoComplete="off" + label="Radio" + defaultChecked + /> + <CFormCheck + button={{ color: 'danger', variant: 'outline' }} + type="radio" + name="options-outlined" + id="danger-outlined" + autoComplete="off" + label="Radio" + /> + </div> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default ChecksRadios diff --git a/src/views/forms/floating-labels/FloatingLabels.js b/src/views/forms/floating-labels/FloatingLabels.js new file mode 100644 index 00000000..d40f5b35 --- /dev/null +++ b/src/views/forms/floating-labels/FloatingLabels.js @@ -0,0 +1,170 @@ +import React from 'react' +import { + CCard, + CCardBody, + CCardHeader, + CCol, + CFormInput, + CFormLabel, + CFormFloating, + CFormSelect, + CFormTextarea, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const FloatingLabels = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Floating labels</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Wrap a pair of <code><CFormInput></code> and <code><CFormLabel></code>{' '} + elements in <code>CFormFloating</code> to enable floating labels with textual form + fields. A <code>placeholder</code> is required on each <code><CFormInput></code>{' '} + as our method of CSS-only floating labels uses the <code>:placeholder-shown</code>{' '} + pseudo-element. Also note that the <code><CFormInput></code> must come first so + we can utilize a sibling selector (e.g., <code>~</code>). + </p> + <DocsExample href="forms/floating-labels"> + <CFormFloating className="mb-3"> + <CFormInput type="email" id="floatingInput" placeholder="name@example.com" /> + <CFormLabel htmlFor="floatingInput">Email address</CFormLabel> + </CFormFloating> + <CFormFloating> + <CFormInput type="password" id="floatingPassword" placeholder="Password" /> + <CFormLabel htmlFor="floatingPassword">Password</CFormLabel> + </CFormFloating> + </DocsExample> + <p className="text-medium-emphasis small"> + When there's a <code>value</code> already defined, <code><CFormLabel></code> + s will automatically adjust to their floated position. + </p> + <DocsExample href="forms/floating-labels"> + <CFormFloating> + <CFormInput + type="email" + id="floatingInputValue" + placeholder="name@example.com" + defaultValue="test@example.com" + /> + <CFormLabel htmlFor="floatingInputValue">Input with value</CFormLabel> + </CFormFloating> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Floating labels</strong> <small>Textareas</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + By default, <code><CFormTextarea></code>s will be the same height as{' '} + <code><CFormInput></code>s. + </p> + <DocsExample href="forms/floating-labels#textareas"> + <CFormFloating> + <CFormTextarea + id="floatingTextarea" + placeholder="Leave a comment here" + ></CFormTextarea> + <CFormLabel htmlFor="floatingTextarea">Comments</CFormLabel> + </CFormFloating> + </DocsExample> + <p className="text-medium-emphasis small"> + To set a custom height on your <code><CFormTextarea;></code>, do not use the{' '} + <code>rows</code> attribute. Instead, set an explicit <code>height</code> (either + inline or via custom CSS). + </p> + <DocsExample href="forms/floating-labels#textareas"> + <CFormFloating> + <CFormTextarea + placeholder="Leave a comment here" + id="floatingTextarea2" + style={{ height: '100px' }} + ></CFormTextarea> + <CFormLabel htmlFor="floatingTextarea2">Comments</CFormLabel> + </CFormFloating> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Floating labels</strong> <small>Selects</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Other than <code><CFormInput></code>, floating labels are only available on{' '} + <code><CFormSelect></code>s. They work in the same way, but unlike{' '} + <code><CFormInput></code>s, they'll always show the{' '} + <code><CFormLabel></code> in its floated state.{' '} + <strong> + Selects with <code>size</code> and <code>multiple</code> are not supported. + </strong> + </p> + <DocsExample href="forms/floating-labels#selects"> + <CFormFloating> + <CFormSelect id="floatingSelect" aria-label="Floating label select example"> + <option>Open this select menu</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + <CFormLabel htmlFor="floatingSelect">Works with selects</CFormLabel> + </CFormFloating> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Floating labels</strong> <small>Layout</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + When working with the CoreUI for Bootstrap grid system, be sure to place form elements + within column classes. + </p> + <DocsExample href="forms/floating-labels#layout"> + <CRow xs={{ gutter: 2 }}> + <CCol md> + <CFormFloating> + <CFormInput + type="email" + id="floatingInputGrid" + placeholder="name@example.com" + defaultValue="email@example.com" + /> + <CFormLabel htmlFor="floatingInputGrid">Email address</CFormLabel> + </CFormFloating> + </CCol> + <CCol md> + <CFormFloating> + <CFormSelect id="floatingSelectGrid" aria-label="Floating label select example"> + <option>Open this select menu</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + <CFormLabel htmlFor="floatingSelectGrid">Works with selects</CFormLabel> + </CFormFloating> + </CCol> + </CRow> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default FloatingLabels diff --git a/src/views/forms/form-control/FormControl.js b/src/views/forms/form-control/FormControl.js new file mode 100644 index 00000000..9bdb1076 --- /dev/null +++ b/src/views/forms/form-control/FormControl.js @@ -0,0 +1,248 @@ +import React from 'react' +import { + CButton, + CCard, + CCardBody, + CCardHeader, + CCol, + CForm, + CFormInput, + CFormLabel, + CFormTextarea, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const FormControl = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Form Control</strong> + </CCardHeader> + <CCardBody> + <DocsExample href="forms/form-control"> + <CForm> + <div className="mb-3"> + <CFormLabel htmlFor="exampleFormControlInput1">Email address</CFormLabel> + <CFormInput + type="email" + id="exampleFormControlInput1" + placeholder="name@example.com" + /> + </div> + <div className="mb-3"> + <CFormLabel htmlFor="exampleFormControlTextarea1">Example textarea</CFormLabel> + <CFormTextarea id="exampleFormControlTextarea1" rows="3"></CFormTextarea> + </div> + </CForm> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Form Control</strong> <small>Sizing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Set heights using <code>size</code> property like <code>size="lg"</code> and{' '} + <code>size="sm"</code>. + </p> + <DocsExample href="forms/form-control#sizing"> + <CFormInput + type="text" + size="lg" + placeholder="Large input" + aria-label="lg input example" + /> + <br /> + <CFormInput + type="text" + placeholder="Default input" + aria-label="default input example" + /> + <br /> + <CFormInput + type="text" + size="sm" + placeholder="Small input" + aria-label="sm input example" + /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Form Control</strong> <small>Disabled</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add the <code>disabled</code> boolean attribute on an input to give it a grayed out + appearance and remove pointer events. + </p> + <DocsExample href="forms/form-control#disabled"> + <CFormInput + type="text" + placeholder="Disabled input" + aria-label="Disabled input example" + disabled + /> + <br /> + <CFormInput + type="text" + placeholder="Disabled readonly input" + aria-label="Disabled input example" + disabled + readOnly + /> + <br /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Form Control</strong> <small>Readonly</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add the <code>readOnly</code> boolean attribute on an input to prevent modification of + the input's value. Read-only inputs appear lighter (just like disabled inputs), + but retain the standard cursor. + </p> + <DocsExample href="forms/form-control#readonly"> + <CFormInput + type="text" + placeholder="Readonly input here..." + aria-label="readonly input example" + readOnly + /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Form Control</strong> <small>Readonly plain text</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + If you want to have <code><input readonly></code> elements in your form styled + as plain text, use the <code>plainText</code> boolean property to remove the default + form field styling and preserve the correct margin and padding. + </p> + <DocsExample href="components/accordion"> + <CRow className="mb-3"> + <CFormLabel htmlFor="staticEmail" className="col-sm-2 col-form-label"> + Email + </CFormLabel> + <div className="col-sm-10"> + <CFormInput + type="text" + id="staticEmail" + defaultValue="email@example.com" + readOnly + plainText + /> + </div> + </CRow> + <CRow className="mb-3"> + <CFormLabel htmlFor="inputPassword" className="col-sm-2 col-form-label"> + Password + </CFormLabel> + <div className="col-sm-10"> + <CFormInput type="password" id="inputPassword" /> + </div> + </CRow> + </DocsExample> + <DocsExample href="components/accordion"> + <CForm className="row g-3"> + <div className="col-auto"> + <CFormLabel htmlFor="staticEmail2" className="visually-hidden"> + Email + </CFormLabel> + <CFormInput + type="text" + id="staticEmail2" + defaultValue="email@example.com" + readOnly + plainText + /> + </div> + <div className="col-auto"> + <CFormLabel htmlFor="inputPassword2" className="visually-hidden"> + Password + </CFormLabel> + <CFormInput type="password" id="inputPassword2" placeholder="Password" /> + </div> + <div className="col-auto"> + <CButton type="submit" className="mb-3"> + Confirm identity + </CButton> + </div> + </CForm> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Form Control</strong> <small>File input</small> + </CCardHeader> + <CCardBody> + <DocsExample href="forms/form-control#file-input"> + <div className="mb-3"> + <CFormLabel htmlFor="formFile">Default file input example</CFormLabel> + <CFormInput type="file" id="formFile" /> + </div> + <div className="mb-3"> + <CFormLabel htmlFor="formFileMultiple">Multiple files input example</CFormLabel> + <CFormInput type="file" id="formFileMultiple" multiple /> + </div> + <div className="mb-3"> + <CFormLabel htmlFor="formFileDisabled">Disabled file input example</CFormLabel> + <CFormInput type="file" id="formFileDisabled" disabled /> + </div> + <div className="mb-3"> + <CFormLabel htmlFor="formFileSm">Small file input example</CFormLabel> + <CFormInput type="file" size="sm" id="formFileSm" /> + </div> + <div> + <CFormLabel htmlFor="formFileLg">Large file input example</CFormLabel> + <CFormInput type="file" size="lg" id="formFileLg" /> + </div> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Form Control</strong> <small>Color</small> + </CCardHeader> + <CCardBody> + <DocsExample href="forms/form-control#color"> + <CFormLabel htmlFor="exampleColorInput">Color picker</CFormLabel> + <CFormInput + type="color" + id="exampleColorInput" + defaultValue="#563d7c" + title="Choose your color" + /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default FormControl diff --git a/src/views/forms/input-group/InputGroup.js b/src/views/forms/input-group/InputGroup.js new file mode 100644 index 00000000..4b9da78d --- /dev/null +++ b/src/views/forms/input-group/InputGroup.js @@ -0,0 +1,503 @@ +import React from 'react' +import { + CButton, + CCard, + CCardBody, + CCardHeader, + CCol, + CDropdown, + CDropdownDivider, + CDropdownItem, + CDropdownMenu, + CDropdownToggle, + CFormCheck, + CFormInput, + CFormLabel, + CFormSelect, + CFormTextarea, + CInputGroup, + CInputGroupText, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const Select = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Input group</strong> <small>Basic example</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Place one add-on or button on either side of an input. You may also place one on both + sides of an input. Remember to place <code><CFormLabel></code>s outside the + input group. + </p> + <DocsExample href="forms/input-group"> + <CInputGroup className="mb-3"> + <CInputGroupText id="basic-addon1">@</CInputGroupText> + <CFormInput + placeholder="Username" + aria-label="Username" + aria-describedby="basic-addon1" + /> + </CInputGroup> + <CInputGroup className="mb-3"> + <CFormInput + placeholder="Recipient's username" + aria-label="Recipient's username" + aria-describedby="basic-addon2" + /> + <CInputGroupText id="basic-addon2">@example.com</CInputGroupText> + </CInputGroup> + <CFormLabel htmlFor="basic-url">Your vanity URL</CFormLabel> + <CInputGroup className="mb-3"> + <CInputGroupText id="basic-addon3">https://example.com/users/</CInputGroupText> + <CFormInput id="basic-url" aria-describedby="basic-addon3" /> + </CInputGroup> + <CInputGroup className="mb-3"> + <CInputGroupText>$</CInputGroupText> + <CFormInput aria-label="Amount (to the nearest dollar)" /> + <CInputGroupText>.00</CInputGroupText> + </CInputGroup> + <CInputGroup className="mb-3"> + <CFormInput placeholder="Username" aria-label="Username" /> + <CInputGroupText>@</CInputGroupText> + <CFormInput placeholder="Server" aria-label="Server" /> + </CInputGroup> + <CInputGroup> + <CInputGroupText>With textarea</CInputGroupText> + <CFormTextarea aria-label="With textarea"></CFormTextarea> + </CInputGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Input group</strong> <small>Wrapping</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Input groups wrap by default via <code>flex-wrap: wrap</code> in order to accommodate + custom form field validation within an input group. You may disable this with{' '} + <code>.flex-nowrap</code>. + </p> + <DocsExample href="forms/input-group#wrapping"> + <CInputGroup className="flex-nowrap"> + <CInputGroupText id="addon-wrapping">@</CInputGroupText> + <CFormInput + placeholder="Username" + aria-label="Username" + aria-describedby="addon-wrapping" + /> + </CInputGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Input group</strong> <small>Sizing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add the relative form sizing classes to the <code><CInputGroup></code> itself + and contents within will automatically resize—no need for repeating the form control + size classes on each element. + </p> + <p className="text-medium-emphasis small"> + <strong>Sizing on the individual input group elements isn'tsupported.</strong> + </p> + <DocsExample href="forms/input-group#sizing"> + <CInputGroup size="sm" className="mb-3"> + <CInputGroupText id="inputGroup-sizing-sm">Small</CInputGroupText> + <CFormInput + aria-label="Sizing example input" + aria-describedby="inputGroup-sizing-sm" + /> + </CInputGroup> + <CInputGroup className="mb-3"> + <CInputGroupText id="inputGroup-sizing-default">Default</CInputGroupText> + <CFormInput + aria-label="Sizing example input" + aria-describedby="inputGroup-sizing-default" + /> + </CInputGroup> + <CInputGroup size="lg"> + <CInputGroupText id="inputGroup-sizing-lg">Large</CInputGroupText> + <CFormInput + aria-label="Sizing example input" + aria-describedby="inputGroup-sizing-lg" + /> + </CInputGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Input group</strong> <small>Checkboxes and radios</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Place any checkbox or radio option within an input group's addon instead of text. + </p> + <DocsExample href="forms/input-group#checkboxes-and-radios"> + <CInputGroup className="mb-3"> + <CInputGroupText> + <CFormCheck + type="checkbox" + value="" + aria-label="Checkbox for following text input" + /> + </CInputGroupText> + <CFormInput aria-label="Text input with checkbox" /> + </CInputGroup> + <CInputGroup> + <CInputGroupText> + <CFormCheck + type="radio" + value="" + aria-label="Radio button for following text input" + /> + </CInputGroupText> + <CFormInput aria-label="Text input with radio button" /> + </CInputGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Input group</strong> <small>Multiple inputs</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + While multiple <code><CFormInput></code>s are supported visually, validation + styles are only available for input groups with a single{' '} + <code><CFormInput></code>. + </p> + <DocsExample href="forms/input-group#multiple-inputs"> + <CInputGroup> + <CInputGroupText>First and last name</CInputGroupText> + <CFormInput aria-label="First name" /> + <CFormInput aria-label="Last name" /> + </CInputGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Input group</strong> <small>Multiple addons</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Multiple add-ons are supported and can be mixed with checkbox and radio input + versions.. + </p> + <DocsExample href="forms/input-group#multiple-addons"> + <CInputGroup className="mb-3"> + <CInputGroupText>$</CInputGroupText> + <CInputGroupText>0.00</CInputGroupText> + <CFormInput aria-label="Dollar amount (with dot and two decimal places)" /> + </CInputGroup> + <CInputGroup> + <CFormInput aria-label="Dollar amount (with dot and two decimal places)" /> + <CInputGroupText>$</CInputGroupText> + <CInputGroupText>0.00</CInputGroupText> + </CInputGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Input group</strong> <small>Button addons</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Multiple add-ons are supported and can be mixed with checkbox and radio input + versions.. + </p> + <DocsExample href="forms/input-group#button-addons"> + <CInputGroup className="mb-3"> + <CButton type="button" color="secondary" variant="outline" id="button-addon1"> + Button + </CButton> + <CFormInput + placeholder="" + aria-label="Example text with button addon" + aria-describedby="button-addon1" + /> + </CInputGroup> + <CInputGroup className="mb-3"> + <CFormInput + placeholder="Recipient's username" + aria-label="Recipient's username" + aria-describedby="button-addon2" + /> + <CButton type="button" color="secondary" variant="outline" id="button-addon2"> + Button + </CButton> + </CInputGroup> + <CInputGroup className="mb-3"> + <CButton type="button" color="secondary" variant="outline"> + Button + </CButton> + <CButton type="button" color="secondary" variant="outline"> + Button + </CButton> + <CFormInput placeholder="" aria-label="Example text with two button addons" /> + </CInputGroup> + <CInputGroup> + <CFormInput + placeholder="Recipient's username" + aria-label="Recipient's username with two button addons" + /> + <CButton type="button" color="secondary" variant="outline"> + Button + </CButton> + <CButton type="button" color="secondary" variant="outline"> + Button + </CButton> + </CInputGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Input group</strong> <small>Buttons with dropdowns</small> + </CCardHeader> + <CCardBody> + <DocsExample href="forms/input-group#buttons-with-dropdowns"> + <CInputGroup className="mb-3"> + <CDropdown variant="input-group"> + <CDropdownToggle color="secondary" variant="outline"> + Dropdown + </CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CFormInput aria-label="Text input with dropdown button" /> + </CInputGroup> + <CInputGroup className="mb-3"> + <CFormInput aria-label="Text input with dropdown button" /> + <CDropdown alignment="end" variant="input-group"> + <CDropdownToggle color="secondary" variant="outline"> + Dropdown + </CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </CInputGroup> + <CInputGroup> + <CDropdown variant="input-group"> + <CDropdownToggle color="secondary" variant="outline"> + Dropdown + </CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CFormInput aria-label="Text input with 2 dropdown buttons" /> + <CDropdown alignment="end" variant="input-group"> + <CDropdownToggle color="secondary" variant="outline"> + Dropdown + </CDropdownToggle> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </CInputGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Input group</strong> <small>Segmented buttons</small> + </CCardHeader> + <CCardBody> + <DocsExample href="forms/input-group#segmented-buttons"> + <CInputGroup className="mb-3"> + <CDropdown variant="input-group"> + <CButton type="button" color="secondary" variant="outline"> + Action + </CButton> + <CDropdownToggle color="secondary" variant="outline" split /> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + <CFormInput aria-label="Text input with segmented dropdown button" /> + </CInputGroup> + <CInputGroup> + <CFormInput aria-label="Text input with segmented dropdown button" /> + <CDropdown alignment="end" variant="input-group"> + <CButton type="button" color="secondary" variant="outline"> + Action + </CButton> + <CDropdownToggle color="secondary" variant="outline" split /> + <CDropdownMenu> + <CDropdownItem href="#">Action</CDropdownItem> + <CDropdownItem href="#">Another action</CDropdownItem> + <CDropdownItem href="#">Something else here</CDropdownItem> + <CDropdownDivider /> + <CDropdownItem href="#">Separated link</CDropdownItem> + </CDropdownMenu> + </CDropdown> + </CInputGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Input group</strong> <small>Custom select</small> + </CCardHeader> + <CCardBody> + <DocsExample href="forms/input-group#custom-select"> + <CInputGroup className="mb-3"> + <CInputGroupText component="label" htmlFor="inputGroupSelect01"> + Options + </CInputGroupText> + <CFormSelect id="inputGroupSelect01"> + <option>Choose...</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + </CInputGroup> + <CInputGroup className="mb-3"> + <CFormSelect id="inputGroupSelect02"> + <option>Choose...</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + <CInputGroupText component="label" htmlFor="inputGroupSelect02"> + Options + </CInputGroupText> + </CInputGroup> + <CInputGroup className="mb-3"> + <CButton type="button" color="secondary" variant="outline"> + Button + </CButton> + <CFormSelect id="inputGroupSelect03" aria-label="Example select with button addon"> + <option>Choose...</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + </CInputGroup> + <CInputGroup> + <CFormSelect id="inputGroupSelect04" aria-label="Example select with button addon"> + <option>Choose...</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + <CButton type="button" color="secondary" variant="outline"> + Button + </CButton> + </CInputGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Input group</strong> <small>Custom file input</small> + </CCardHeader> + <CCardBody> + <DocsExample href="forms/input-group#custom-file-input"> + <CInputGroup className="mb-3"> + <CInputGroupText component="label" htmlFor="inputGroupFile01"> + Upload + </CInputGroupText> + <CFormInput type="file" id="inputGroupFile01" /> + </CInputGroup> + <CInputGroup className="mb-3"> + <CFormInput type="file" id="inputGroupFile02" /> + <CInputGroupText component="label" htmlFor="inputGroupFile02"> + Upload + </CInputGroupText> + </CInputGroup> + <CInputGroup className="mb-3"> + <CButton + type="button" + color="secondary" + variant="outline" + id="inputGroupFileAddon03" + > + Button + </CButton> + <CFormInput + type="file" + id="inputGroupFile03" + aria-describedby="inputGroupFileAddon03" + aria-label="Upload" + /> + </CInputGroup> + <CInputGroup> + <CFormInput + type="file" + id="inputGroupFile04" + aria-describedby="inputGroupFileAddon04" + aria-label="Upload" + /> + <CButton + type="button" + color="secondary" + variant="outline" + id="inputGroupFileAddon04" + > + Button + </CButton> + </CInputGroup> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Select diff --git a/src/views/forms/layout/Layout.js b/src/views/forms/layout/Layout.js new file mode 100644 index 00000000..27bae196 --- /dev/null +++ b/src/views/forms/layout/Layout.js @@ -0,0 +1,414 @@ +import React from 'react' +import { + CButton, + CCard, + CCardBody, + CCardHeader, + CCol, + CForm, + CFormCheck, + CFormInput, + CFormLabel, + CFormSelect, + CInputGroup, + CInputGroupText, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const Layout = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Layout</strong> <small>Form grid</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + More complex forms can be built using our grid classes. Use these for form layouts + that require multiple columns, varied widths, and additional alignment options. + </p> + <DocsExample href="forms/layout#form-grid"> + <CRow> + <CCol xs> + <CFormInput placeholder="First name" aria-label="First name" /> + </CCol> + <CCol xs> + <CFormInput placeholder="Last name" aria-label="Last name" /> + </CCol> + </CRow> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Layout</strong> <small>Gutters</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + By adding <a href="https://coreui.io/docs/layout/gutters/">gutter modifier classes</a> + , you can have control over the gutter width in as well the inline as block direction. + </p> + <DocsExample href="forms/layout#gutters"> + <CRow className="g-3"> + <CCol xs> + <CFormInput placeholder="First name" aria-label="First name" /> + </CCol> + <CCol xs> + <CFormInput placeholder="Last name" aria-label="Last name" /> + </CCol> + </CRow> + </DocsExample> + <p className="text-medium-emphasis small"> + More complex layouts can also be created with the grid system. + </p> + <DocsExample href="forms/layout#gutters"> + <CForm className="row g-3"> + <CCol md={6}> + <CFormLabel htmlFor="inputEmail4">Email</CFormLabel> + <CFormInput type="email" id="inputEmail4" /> + </CCol> + <CCol md={6}> + <CFormLabel htmlFor="inputPassword4">Password</CFormLabel> + <CFormInput type="password" id="inputPassword4" /> + </CCol> + <CCol xs={12}> + <CFormLabel htmlFor="inputAddress">Address</CFormLabel> + <CFormInput id="inputAddress" placeholder="1234 Main St" /> + </CCol> + <CCol xs={12}> + <CFormLabel htmlFor="inputAddress2">Address 2</CFormLabel> + <CFormInput id="inputAddress2" placeholder="Apartment, studio, or floor" /> + </CCol> + <CCol md={6}> + <CFormLabel htmlFor="inputCity">City</CFormLabel> + <CFormInput id="inputCity" /> + </CCol> + <CCol md={4}> + <CFormLabel htmlFor="inputState">State</CFormLabel> + <CFormSelect id="inputState"> + <option>Choose...</option> + <option>...</option> + </CFormSelect> + </CCol> + <CCol md={2}> + <CFormLabel htmlFor="inputZip">Zip</CFormLabel> + <CFormInput id="inputZip" /> + </CCol> + <CCol xs={12}> + <CFormCheck type="checkbox" id="gridCheck" label="Check me out" /> + </CCol> + <CCol xs={12}> + <CButton type="submit">Sign in</CButton> + </CCol> + </CForm> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Layout</strong> <small>Horizontal form</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Create horizontal forms with the grid by adding the <code>.row</code> class to form + groups and using the <code>.col-*-*</code> classes to specify the width of your labels + and controls. Be sure to add <code>.col-form-label</code> to your{' '} + <code><CFormLabel></code>s as well so they're vertically centered with their + associated form controls. + </p> + <p className="text-medium-emphasis small"> + At times, you maybe need to use margin or padding utilities to create that perfect + alignment you need. For example, we've removed the <code>padding-top</code> on our + stacked radio inputs label to better align the text baseline. + </p> + <DocsExample href="forms/layout#horizontal-form"> + <CForm> + <CRow className="mb-3"> + <CFormLabel htmlFor="inputEmail3" className="col-sm-2 col-form-label"> + Email + </CFormLabel> + <CCol sm={10}> + <CFormInput type="email" id="inputEmail3" /> + </CCol> + </CRow> + <CRow className="mb-3"> + <CFormLabel htmlFor="inputPassword3" className="col-sm-2 col-form-label"> + Password + </CFormLabel> + <CCol sm={10}> + <CFormInput type="password" id="inputPassword3" /> + </CCol> + </CRow> + <fieldset className="row mb-3"> + <legend className="col-form-label col-sm-2 pt-0">Radios</legend> + <CCol sm={10}> + <CFormCheck + type="radio" + name="gridRadios" + id="gridRadios1" + value="option1" + label="First radio" + defaultChecked + /> + <CFormCheck + type="radio" + name="gridRadios" + id="gridRadios2" + value="option2" + label="Second radio" + /> + <CFormCheck + type="radio" + name="gridRadios" + id="gridRadios3" + value="option3" + label="Third disabled radio" + disabled + /> + </CCol> + </fieldset> + <CRow className="mb-3"> + <div className="col-sm-10 offset-sm-2"> + <CFormCheck type="checkbox" id="gridCheck1" label="Example checkbox" /> + </div> + </CRow> + <CButton type="submit">Sign in</CButton> + </CForm> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Layout</strong> <small>Horizontal form label sizing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Be sure to use <code>.col-form-label-sm</code> or <code>.col-form-label-lg</code> to + your <code><CFormLabel></code>s or <code><legend></code>s to correctly + follow the size of <code>.form-control-lg</code> and <code>.form-control-sm</code>. + </p> + <DocsExample href="forms/layout#horizontal-form-label-sizing"> + <CRow className="mb-3"> + <CFormLabel + htmlFor="colFormLabelSm" + className="col-sm-2 col-form-label col-form-label-sm" + > + Email + </CFormLabel> + <CCol sm={10}> + <CFormInput + type="email" + className="form-control form-control-sm" + id="colFormLabelSm" + placeholder="col-form-label-sm" + /> + </CCol> + </CRow> + <CRow className="mb-3"> + <CFormLabel htmlFor="colFormLabel" className="col-sm-2 col-form-label"> + Email + </CFormLabel> + <CCol sm={10}> + <CFormInput type="email" id="colFormLabel" placeholder="col-form-label" /> + </CCol> + </CRow> + <CRow> + <CFormLabel + htmlFor="colFormLabelLg" + className="col-sm-2 col-form-label col-form-label-lg" + > + Email + </CFormLabel> + <CCol sm={10}> + <CFormInput + type="email" + className="form-control form-control-lg" + id="colFormLabelLg" + placeholder="col-form-label-lg" + /> + </CCol> + </CRow> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Layout</strong> <small>Column sizing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + As shown in the previous examples, our grid system allows you to place any number of{' '} + <code><CCol></code>s within a <code><CRow></code>. They'll split the + available width equally between them. You may also pick a subset of your columns to + take up more or less space, while the remaining <code><CCol></code>s equally + split the rest, with specific column classes like{' '} + <code><CCol sm="7"></code>. + </p> + <DocsExample href="forms/layout#column-sizing"> + <CRow className="g-3"> + <CCol sm={7}> + <CFormInput placeholder="City" aria-label="City" /> + </CCol> + <CCol sm> + <CFormInput placeholder="State" aria-label="State" /> + </CCol> + <CCol sm> + <CFormInput placeholder="Zip" aria-label="Zip" /> + </CCol> + </CRow> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Layout</strong> <small>Auto-sizing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + The example below uses a flexbox utility to vertically center the contents and changes{' '} + <code><CCol></code> to <code><CCol xs="auto"></code> so that your + columns only take up as much space as needed. Put another way, the column sizes itself + based on the contents. + </p> + <DocsExample href="forms/layout#auto-sizing"> + <CForm className="row gy-2 gx-3 align-items-center"> + <CCol xs="auto"> + <CFormLabel className="visually-hidden" htmlFor="autoSizingInput"> + Name + </CFormLabel> + <CFormInput id="autoSizingInput" placeholder="Jane Doe" /> + </CCol> + <CCol xs="auto"> + <CFormLabel className="visually-hidden" htmlFor="autoSizingInputGroup"> + Username + </CFormLabel> + <CInputGroup> + <CInputGroupText>@</CInputGroupText> + <CFormInput id="autoSizingInputGroup" placeholder="Username" /> + </CInputGroup> + </CCol> + <CCol xs="auto"> + <CFormLabel className="visually-hidden" htmlFor="autoSizingSelect"> + Preference + </CFormLabel> + <CFormSelect id="autoSizingSelect"> + <option>Choose...</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + </CCol> + <CCol xs="auto"> + <CFormCheck type="checkbox" id="autoSizingCheck" label="Remember me" /> + </CCol> + <CCol xs="auto"> + <CButton type="submit">Submit</CButton> + </CCol> + </CForm> + </DocsExample> + <p className="text-medium-emphasis small"> + You can then remix that once again with size-specific column classes. + </p> + <DocsExample href="forms/layout#auto-sizing"> + <CForm className="row gx-3 gy-2 align-items-center"> + <CCol sm={3}> + <CFormLabel className="visually-hidden" htmlFor="specificSizeInputName"> + Name + </CFormLabel> + <CFormInput id="specificSizeInputName" placeholder="Jane Doe" /> + </CCol> + <CCol sm={3}> + <CFormLabel className="visually-hidden" htmlFor="specificSizeInputGroupUsername"> + Username + </CFormLabel> + <CInputGroup> + <CInputGroupText>@</CInputGroupText> + <CFormInput id="specificSizeInputGroupUsername" placeholder="Username" /> + </CInputGroup> + </CCol> + <CCol sm={3}> + <CFormLabel className="visually-hidden" htmlFor="specificSizeSelect"> + Preference + </CFormLabel> + <CFormSelect id="specificSizeSelect"> + <option>Choose...</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + </CCol> + <CCol xs="auto"> + <CFormCheck type="checkbox" id="autoSizingCheck2" label="Remember me" /> + </CCol> + <CCol xs="auto"> + <CButton type="submit">Submit</CButton> + </CCol> + </CForm> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Layout</strong> <small>Inline forms</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use the <code><CCol xs="auto"></code> class to create horizontal + layouts. By adding{' '} + <a href="https://coreui.io/docs/layout/gutters/">gutter modifier classes</a>, we will + have gutters in horizontal and vertical directions. The{' '} + <code>.align-items-center</code> aligns the form elements to the middle, making the{' '} + <code><CFormCheck></code> align properly. + </p> + <DocsExample href="forms/layout#inline-forms"> + <CForm className="row row-cols-lg-auto g-3 align-items-center"> + <CCol xs={12}> + <CFormLabel className="visually-hidden" htmlFor="inlineFormInputGroupUsername"> + Username + </CFormLabel> + <CInputGroup> + <CInputGroupText>@</CInputGroupText> + <CFormInput id="inlineFormInputGroupUsername" placeholder="Username" /> + </CInputGroup> + </CCol> + <CCol xs={12}> + <CFormLabel className="visually-hidden" htmlFor="inlineFormSelectPref"> + Preference + </CFormLabel> + <CFormSelect id="inlineFormSelectPref"> + <option>Choose...</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + </CCol> + <CCol xs={12}> + <CFormCheck type="checkbox" id="inlineFormCheck" label="Remember me" /> + </CCol> + <CCol xs={12}> + <CButton type="submit">Submit</CButton> + </CCol> + </CForm> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Layout diff --git a/src/views/forms/range/Range.js b/src/views/forms/range/Range.js new file mode 100644 index 00000000..905c3134 --- /dev/null +++ b/src/views/forms/range/Range.js @@ -0,0 +1,82 @@ +import React from 'react' +import { CCard, CCardBody, CCardHeader, CCol, CFormLabel, CFormRange, CRow } from '@coreui/react' +import { DocsExample } from 'src/components' + +const Range = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Range</strong> <small></small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Create custom <code><input type="range"></code> controls with{' '} + <code><CFormRange></code>. + </p> + <DocsExample href="forms/range"> + <CFormLabel htmlFor="customRange1">Example range</CFormLabel> + <CFormRange id="customRange1" /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Range</strong> <small>Disabled</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add the <code>disabled</code> boolean attribute on an input to give it a grayed out + appearance and remove pointer events. + </p> + <DocsExample href="forms/range#disabled"> + <CFormLabel htmlFor="disabledRange">Disabled range</CFormLabel> + <CFormRange id="disabledRange" disabled /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Range</strong> <small>Min and max</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Range inputs have implicit values for <code>min</code> and <code>max</code>— + <code>0</code> and <code>100</code>, respectively. You may specify new values for + those using the <code>min</code> and <code>max</code> attributes. + </p> + <DocsExample href="forms/range#min-and-max"> + <CFormLabel htmlFor="customRange2">Example range</CFormLabel> + <CFormRange min="0" max="5" defaultValue="3" id="customRange2" /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Range</strong> <small>Steps</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + By default, range inputs "snap" to integer values. To change this, you can + specify a <code>step</code> value. In the example below, we double the number of steps + by using <code>step="0.5"</code>. + </p> + <DocsExample href="forms/range#steps"> + <CFormLabel htmlFor="customRange3">Example range</CFormLabel> + <CFormRange min="0" max="5" step="0.5" defaultValue="3" id="customRange3" /> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Range diff --git a/src/views/forms/select/Select.js b/src/views/forms/select/Select.js new file mode 100644 index 00000000..e81f6a56 --- /dev/null +++ b/src/views/forms/select/Select.js @@ -0,0 +1,99 @@ +import React from 'react' +import { CCard, CCardBody, CCardHeader, CCol, CFormSelect, CRow } from '@coreui/react' +import { DocsExample } from 'src/components' + +const Select = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Select</strong> <small>Default</small> + </CCardHeader> + <CCardBody> + <DocsExample href="forms/select"> + <CFormSelect aria-label="Default select example"> + <option>Open this select menu</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Select</strong> <small>Sizing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + You may also choose from small and large custom selects to match our similarly sized + text inputs. + </p> + <DocsExample href="forms/select#sizing"> + <CFormSelect size="lg" className="mb-3" aria-label="Large select example"> + <option>Open this select menu</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + <CFormSelect size="sm" className="mb-3" aria-label="Small select example"> + <option>Open this select menu</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + </DocsExample> + <p className="text-medium-emphasis small"> + The <code>multiple</code> attribute is also supported: + </p> + <DocsExample href="forms/select#sizing"> + <CFormSelect size="lg" multiple aria-label="Multiple select example"> + <option>Open this select menu</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + </DocsExample> + <p className="text-medium-emphasis small"> + As is the <code>htmlSize</code> property: + </p> + <DocsExample href="forms/select#sizing"> + <CFormSelect size="lg" multiple aria-label="Multiple select example"> + <option>Open this select menu</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Select</strong> <small>Disabled</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add the <code>disabled</code> boolean attribute on a select to give it a grayed out + appearance and remove pointer events. + </p> + <DocsExample href="forms/select#disabled"> + <CFormSelect aria-label="Disabled select example" disabled> + <option>Open this select menu</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Select diff --git a/src/views/forms/validation/Validation.js b/src/views/forms/validation/Validation.js new file mode 100644 index 00000000..7053aa3b --- /dev/null +++ b/src/views/forms/validation/Validation.js @@ -0,0 +1,503 @@ +import React, { useState } from 'react' +import { + CButton, + CCard, + CCardBody, + CCardHeader, + CCol, + CForm, + CFormCheck, + CFormInput, + CFormFeedback, + CFormLabel, + CFormSelect, + CFormTextarea, + CInputGroup, + CInputGroupText, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const CustomStyles = () => { + const [validated, setValidated] = useState(false) + const handleSubmit = (event) => { + const form = event.currentTarget + if (form.checkValidity() === false) { + event.preventDefault() + event.stopPropagation() + } + setValidated(true) + } + return ( + <CForm + className="row g-3 needs-validation" + noValidate + validated={validated} + onSubmit={handleSubmit} + > + <CCol md={4}> + <CFormLabel htmlFor="validationCustom01">Email</CFormLabel> + <CFormInput type="text" id="validationCustom01" defaultValue="Mark" required /> + <CFormFeedback valid>Looks good!</CFormFeedback> + </CCol> + <CCol md={4}> + <CFormLabel htmlFor="validationCustom02">Email</CFormLabel> + <CFormInput type="text" id="validationCustom02" defaultValue="Otto" required /> + <CFormFeedback valid>Looks good!</CFormFeedback> + </CCol> + <CCol md={4}> + <CFormLabel htmlFor="validationCustomUsername">Username</CFormLabel> + <CInputGroup className="has-validation"> + <CInputGroupText id="inputGroupPrepend">@</CInputGroupText> + <CFormInput + type="text" + id="validationCustomUsername" + defaultValue="" + aria-describedby="inputGroupPrepend" + required + /> + <CFormFeedback invalid>Please choose a username.</CFormFeedback> + </CInputGroup> + </CCol> + <CCol md={6}> + <CFormLabel htmlFor="validationCustom03">City</CFormLabel> + <CFormInput type="text" id="validationCustom03" required /> + <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> + </CCol> + <CCol md={3}> + <CFormLabel htmlFor="validationCustom04">City</CFormLabel> + <CFormSelect id="validationCustom04"> + <option disabled>Choose...</option> + <option>...</option> + </CFormSelect> + <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> + </CCol> + <CCol md={3}> + <CFormLabel htmlFor="validationCustom05">City</CFormLabel> + <CFormInput type="text" id="validationCustom05" required /> + <CFormFeedback invalid>Please provide a valid zip.</CFormFeedback> + </CCol> + <CCol xs={12}> + <CFormCheck + type="checkbox" + id="invalidCheck" + label="Agree to terms and conditions" + required + /> + <CFormFeedback invalid>You must agree before submitting.</CFormFeedback> + </CCol> + <CCol xs={12}> + <CButton color="primary" type="submit"> + Submit form + </CButton> + </CCol> + </CForm> + ) +} + +const BrowserDefaults = () => { + const [validated, setValidated] = useState(false) + const handleSubmit = (event) => { + const form = event.currentTarget + if (form.checkValidity() === false) { + event.preventDefault() + event.stopPropagation() + } + setValidated(true) + } + return ( + <CForm className="row g-3 needs-validation" validated={validated} onSubmit={handleSubmit}> + <CCol md={4}> + <CFormLabel htmlFor="validationDefault01">Email</CFormLabel> + <CFormInput type="text" id="validationDefault01" defaultValue="Mark" required /> + <CFormFeedback valid>Looks good!</CFormFeedback> + </CCol> + <CCol md={4}> + <CFormLabel htmlFor="validationDefault02">Email</CFormLabel> + <CFormInput type="text" id="validationDefault02" defaultValue="Otto" required /> + <CFormFeedback valid>Looks good!</CFormFeedback> + </CCol> + <CCol md={4}> + <CFormLabel htmlFor="validationDefaultUsername">Username</CFormLabel> + <CInputGroup className="has-validation"> + <CInputGroupText id="inputGroupPrepend02">@</CInputGroupText> + <CFormInput + type="text" + id="validationDefaultUsername" + defaultValue="" + aria-describedby="inputGroupPrepend02" + required + /> + <CFormFeedback invalid>Please choose a username.</CFormFeedback> + </CInputGroup> + </CCol> + <CCol md={6}> + <CFormLabel htmlFor="validationDefault03">City</CFormLabel> + <CFormInput type="text" id="validationDefault03" required /> + <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> + </CCol> + <CCol md={3}> + <CFormLabel htmlFor="validationDefault04">City</CFormLabel> + <CFormSelect id="validationDefault04"> + <option disabled>Choose...</option> + <option>...</option> + </CFormSelect> + <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> + </CCol> + <CCol md={3}> + <CFormLabel htmlFor="validationDefault05">City</CFormLabel> + <CFormInput type="text" id="validationDefault05" required /> + <CFormFeedback invalid>Please provide a valid zip.</CFormFeedback> + </CCol> + <CCol xs={12}> + <CFormCheck + type="checkbox" + id="invalidCheck" + label="Agree to terms and conditions" + required + /> + <CFormFeedback invalid>You must agree before submitting.</CFormFeedback> + </CCol> + <CCol xs={12}> + <CButton color="primary" type="submit"> + Submit form + </CButton> + </CCol> + </CForm> + ) +} + +const Tooltips = () => { + const [validated, setValidated] = useState(false) + const handleSubmit = (event) => { + const form = event.currentTarget + if (form.checkValidity() === false) { + event.preventDefault() + event.stopPropagation() + } + setValidated(true) + } + return ( + <CForm + className="row g-3 needs-validation" + noValidate + validated={validated} + onSubmit={handleSubmit} + > + <CCol md={4} className="position-relative"> + <CFormLabel htmlFor="validationTooltip01">Email</CFormLabel> + <CFormInput type="text" id="validationTooltip01" defaultValue="Mark" required /> + <CFormFeedback tooltip valid> + Looks good! + </CFormFeedback> + </CCol> + <CCol md={4} className="position-relative"> + <CFormLabel htmlFor="validationTooltip02">Email</CFormLabel> + <CFormInput type="text" id="validationTooltip02" defaultValue="Otto" required /> + <CFormFeedback tooltip valid> + Looks good! + </CFormFeedback> + </CCol> + <CCol md={4} className="position-relative"> + <CFormLabel htmlFor="validationTooltipUsername">Username</CFormLabel> + <CInputGroup className="has-validation"> + <CInputGroupText id="inputGroupPrepend">@</CInputGroupText> + <CFormInput + type="text" + id="validationTooltipUsername" + defaultValue="" + aria-describedby="inputGroupPrepend" + required + /> + <CFormFeedback tooltip invalid> + Please choose a username. + </CFormFeedback> + </CInputGroup> + </CCol> + <CCol md={6} className="position-relative"> + <CFormLabel htmlFor="validationTooltip03">City</CFormLabel> + <CFormInput type="text" id="validationTooltip03" required /> + <CFormFeedback tooltip invalid> + Please provide a valid city. + </CFormFeedback> + </CCol> + <CCol md={3} className="position-relative"> + <CFormLabel htmlFor="validationTooltip04">City</CFormLabel> + <CFormSelect id="validationTooltip04" required> + <option disabled defaultValue=""> + Choose... + </option> + <option>...</option> + </CFormSelect> + <CFormFeedback tooltip invalid> + Please provide a valid city. + </CFormFeedback> + </CCol> + <CCol md={3} className="position-relative"> + <CFormLabel htmlFor="validationTooltip05">City</CFormLabel> + <CFormInput type="text" id="validationTooltip05" required /> + <CFormFeedback tooltip invalid> + Please provide a valid zip. + </CFormFeedback> + </CCol> + <CCol xs={12} className="position-relative"> + <CButton color="primary" type="submit"> + Submit form + </CButton> + </CCol> + </CForm> + ) +} + +const Validation = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Validation</strong> <small>Custom styles</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + For custom CoreUI form validation messages, you'll need to add the{' '} + <code>noValidate</code> boolean property to your <code><CForm></code>. This + disables the browser default feedback tooltips, but still provides access to the form + validation APIs in JavaScript. Try to submit the form below; our JavaScript will + intercept the submit button and relay feedback to you. When attempting to submit, + you'll see the <code>:invalid</code> and <code>:valid</code> styles applied to + your form controls. + </p> + <p className="text-medium-emphasis small"> + Custom feedback styles apply custom colors, borders, focus styles, and background + icons to better communicate feedback.{' '} + </p> + <DocsExample href="forms/validation">{CustomStyles()}</DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Validation</strong> <small>Browser defaults</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Not interested in custom validation feedback messages or writing JavaScript to change + form behaviors? All good, you can use the browser defaults. Try submitting the form + below. Depending on your browser and OS, you'll see a slightly different style of + feedback. + </p> + <p className="text-medium-emphasis small"> + While these feedback styles cannot be styled with CSS, you can still customize the + feedback text through JavaScript. + </p> + <DocsExample href="forms/validation#browser-defaults">{BrowserDefaults()}</DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Validation</strong> <small>Server side</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + We recommend using client-side validation, but in case you require server-side + validation, you can indicate invalid and valid form fields with <code>invalid</code>{' '} + and <code>valid</code> boolean properties. + </p> + <p className="text-medium-emphasis small"> + For invalid fields, ensure that the invalid feedback/error message is associated with + the relevant form field using <code>aria-describedby</code> (noting that this + attribute allows more than one <code>id</code> to be referenced, in case the field + already points to additional form text). + </p> + <DocsExample href="forms/validation#server-side"> + <CForm className="row g-3 needs-validation"> + <CCol md={4}> + <CFormLabel htmlFor="validationServer01">Email</CFormLabel> + <CFormInput + type="text" + id="validationServer01" + defaultValue="Mark" + valid + required + /> + <CFormFeedback valid>Looks good!</CFormFeedback> + </CCol> + <CCol md={4}> + <CFormLabel htmlFor="validationServer02">Email</CFormLabel> + <CFormInput + type="text" + id="validationServer02" + defaultValue="Otto" + valid + required + /> + <CFormFeedback valid>Looks good!</CFormFeedback> + </CCol> + <CCol md={4}> + <CFormLabel htmlFor="validationServerUsername">Username</CFormLabel> + <CInputGroup className="has-validation"> + <CInputGroupText id="inputGroupPrepend03">@</CInputGroupText> + <CFormInput + type="text" + id="validationServerUsername" + defaultValue="" + aria-describedby="inputGroupPrepend03" + invalid + required + /> + <CFormFeedback invalid>Please choose a username.</CFormFeedback> + </CInputGroup> + </CCol> + <CCol md={6}> + <CFormLabel htmlFor="validationServer03">City</CFormLabel> + <CFormInput type="text" id="validationServer03" invalid required /> + <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> + </CCol> + <CCol md={3}> + <CFormLabel htmlFor="validationServer04">City</CFormLabel> + <CFormSelect id="validationServer04" invalid> + <option disabled>Choose...</option> + <option>...</option> + </CFormSelect> + <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> + </CCol> + <CCol md={3}> + <CFormLabel htmlFor="validationServer05">City</CFormLabel> + <CFormInput type="text" id="validationServer05" invalid required /> + <CFormFeedback invalid>Please provide a valid zip.</CFormFeedback> + </CCol> + <CCol xs={12}> + <CFormCheck + type="checkbox" + id="invalidCheck" + label="Agree to terms and conditions" + invalid + required + /> + <CFormFeedback invalid>You must agree before submitting.</CFormFeedback> + </CCol> + <CCol xs={12}> + <CButton color="primary" type="submit"> + Submit form + </CButton> + </CCol> + </CForm> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Validation</strong> <small>Supported elements</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Validation styles are available for the following form controls and components: + </p> + <ul> + <li> + <code><CFormInput></code>s + </li> + <li> + <code><CFormSelect></code>s + </li> + <li> + <code><CFormCheck></code>s + </li> + </ul> + <DocsExample href="forms/validation#supported-elements"> + <CForm validated={true}> + <div className="mb-3"> + <CFormLabel htmlFor="validationTextarea" className="form-label"> + Textarea + </CFormLabel> + <CFormTextarea + id="validationTextarea" + placeholder="Required example textarea" + invalid + required + ></CFormTextarea> + <CFormFeedback invalid>Please enter a message in the textarea.</CFormFeedback> + </div> + <CFormCheck + className="mb-3" + id="validationFormCheck1" + label="Check this checkbox" + required + /> + <CFormFeedback invalid>Example invalid feedback text</CFormFeedback> + + <CFormCheck + type="radio" + name="radio-stacked" + id="validationFormCheck2" + label="Check this checkbox" + required + /> + + <CFormCheck + className="mb-3" + type="radio" + name="radio-stacked" + id="validationFormCheck3" + label="Or toggle this other radio" + required + /> + <CFormFeedback invalid>More example invalid feedback text</CFormFeedback> + + <div className="mb-3"> + <CFormSelect required aria-label="select example"> + <option>Open this select menu</option> + <option value="1">One</option> + <option value="2">Two</option> + <option value="3">Three</option> + </CFormSelect> + <CFormFeedback invalid>Example invalid select feedback</CFormFeedback> + </div> + + <div className="mb-3"> + <CFormInput + type="file" + id="validationTextarea" + aria-label="file example" + required + /> + <CFormFeedback invalid>Example invalid form file feedback</CFormFeedback> + </div> + + <div className="mb-3"> + <CButton type="submit" color="primary" disabled> + Submit form + </CButton> + </div> + </CForm> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>Validation</strong> <small>Tooltips</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + If your form layout allows it, you can swap the text for the tooltip to display + validation feedback in a styled tooltip. Be sure to have a parent with{' '} + <code>position: relative</code> on it for tooltip positioning. In the example below, + our column classes have this already, but your project may require an alternative + setup. + </p> + <DocsExample href="forms/validation#tooltips">{Tooltips()}</DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Validation diff --git a/src/views/icons/brands/Brands.js b/src/views/icons/brands/Brands.js new file mode 100644 index 00000000..d44e81d8 --- /dev/null +++ b/src/views/icons/brands/Brands.js @@ -0,0 +1,38 @@ +import React from 'react' +import { CCard, CCardBody, CCardHeader, CCol, CRow } from '@coreui/react' +import CIcon from '@coreui/icons-react' +import { brandSet } from '@coreui/icons' +import { DocsCallout } from 'src/components' + +const toKebabCase = (str) => { + return str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase() +} + +export const getIconsView = (iconset) => { + return Object.entries(iconset).map(([name, value]) => ( + <CCol className="mb-5" xs={6} sm={4} md={3} xl={2} key={name}> + <CIcon icon={value} size="xxl" /> + <div>{toKebabCase(name)}</div> + </CCol> + )) +} + +const CoreUIIcons = () => { + return ( + <> + <DocsCallout + name="CoreUI Brand Icons" + href="components/chart" + content="CoreUI Brand Icons. CoreUI Icons package is delivered with more than 1500 icons in multiple formats SVG, PNG, and Webfonts. CoreUI Icons are beautifully crafted symbols for common actions and items. You can use them in your digital products for web or mobile app." + /> + <CCard className="mb-4"> + <CCardHeader>Brand Icons</CCardHeader> + <CCardBody> + <CRow className="text-center">{getIconsView(brandSet)}</CRow> + </CCardBody> + </CCard> + </> + ) +} + +export default CoreUIIcons diff --git a/src/views/icons/coreui-icons/CoreUIIcons.js b/src/views/icons/coreui-icons/CoreUIIcons.js new file mode 100644 index 00000000..d0a5969d --- /dev/null +++ b/src/views/icons/coreui-icons/CoreUIIcons.js @@ -0,0 +1,25 @@ +import React from 'react' +import { CCard, CCardBody, CCardHeader, CRow } from '@coreui/react' +import { freeSet } from '@coreui/icons' +import { getIconsView } from '../brands/Brands.js' +import { DocsCallout } from 'src/components' + +const CoreUIIcons = () => { + return ( + <> + <DocsCallout + name="CoreUI Icons" + href="components/chart" + content="CoreUI Icons. CoreUI Icons package is delivered with more than 1500 icons in multiple formats SVG, PNG, and Webfonts. CoreUI Icons are beautifully crafted symbols for common actions and items. You can use them in your digital products for web or mobile app." + /> + <CCard className="mb-4"> + <CCardHeader>Free Icons</CCardHeader> + <CCardBody> + <CRow className="text-center">{getIconsView(freeSet)}</CRow> + </CCardBody> + </CCard> + </> + ) +} + +export default CoreUIIcons diff --git a/src/views/icons/flags/Flags.js b/src/views/icons/flags/Flags.js new file mode 100644 index 00000000..a1179dfe --- /dev/null +++ b/src/views/icons/flags/Flags.js @@ -0,0 +1,25 @@ +import React from 'react' +import { CCard, CCardBody, CCardHeader, CRow } from '@coreui/react' +import { getIconsView } from '../brands/Brands.js' +import { flagSet } from '@coreui/icons' +import { DocsCallout } from 'src/components' + +const CoreUIIcons = () => { + return ( + <> + <DocsCallout + name="CoreUI Flag Icons" + href="components/chart" + content="CoreUI Flag Icons. CoreUI Icons package is delivered with more than 1500 icons in multiple formats SVG, PNG, and Webfonts. CoreUI Icons are beautifully crafted symbols for common actions and items. You can use them in your digital products for web or mobile app." + /> + <CCard className="mb-4"> + <CCardHeader>Flag Icons</CCardHeader> + <CCardBody> + <CRow className="text-center">{getIconsView(flagSet)}</CRow> + </CCardBody> + </CCard> + </> + ) +} + +export default CoreUIIcons diff --git a/src/views/icons/index.js b/src/views/icons/index.js new file mode 100644 index 00000000..92db64e5 --- /dev/null +++ b/src/views/icons/index.js @@ -0,0 +1,5 @@ +import CoreUIIcons from './coreui-icons' +import Flags from './flags' +import Brands from './brands' + +export { CoreUIIcons, Flags, Brands } diff --git a/src/views/notifications/alerts/Alerts.js b/src/views/notifications/alerts/Alerts.js new file mode 100644 index 00000000..6d0200b7 --- /dev/null +++ b/src/views/notifications/alerts/Alerts.js @@ -0,0 +1,147 @@ +import React from 'react' +import { + CAlert, + CAlertHeading, + CAlertLink, + CCard, + CCardBody, + CCardHeader, + CCol, + CRow, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const Alerts = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Alert</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + React Alert is prepared for any length of text, as well as an optional close button. + For a styling, use one of the <strong>required</strong> contextual <code>color</code>{' '} + props (e.g., <code>primary</code>). For inline dismissal, use the{' '} + <a href="https://coreui.io/react/docs/4.0/components/alert#dismissing"> + dismissing prop + </a> + . + </p> + <DocsExample href="components/alert"> + <CAlert color="primary">A simple primary alert—check it out!</CAlert> + <CAlert color="secondary">A simple secondary alert—check it out!</CAlert> + <CAlert color="success">A simple success alert—check it out!</CAlert> + <CAlert color="danger">A simple danger alert—check it out!</CAlert> + <CAlert color="warning">A simple warning alert—check it out!</CAlert> + <CAlert color="info">A simple info alert—check it out!</CAlert> + <CAlert color="light">A simple light alert—check it out!</CAlert> + <CAlert color="dark">A simple dark alert—check it out!</CAlert> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Alert</strong> <small>Link color</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Use the <code><CAlertLink></code> component to immediately give matching colored + links inside any alert. + </p> + <DocsExample href="components/alert#link-color"> + <CAlert color="primary"> + A simple primary alert with <CAlertLink href="#">an example link</CAlertLink>. Give + it a click if you like. + </CAlert> + <CAlert color="secondary"> + A simple secondary alert with <CAlertLink href="#">an example link</CAlertLink>. + Give it a click if you like. + </CAlert> + <CAlert color="success"> + A simple success alert with <CAlertLink href="#">an example link</CAlertLink>. Give + it a click if you like. + </CAlert> + <CAlert color="danger"> + A simple danger alert with <CAlertLink href="#">an example link</CAlertLink>. Give + it a click if you like. + </CAlert> + <CAlert color="warning"> + A simple warning alert with <CAlertLink href="#">an example link</CAlertLink>. Give + it a click if you like. + </CAlert> + <CAlert color="info"> + A simple info alert with <CAlertLink href="#">an example link</CAlertLink>. Give it + a click if you like. + </CAlert> + <CAlert color="light"> + A simple light alert with <CAlertLink href="#">an example link</CAlertLink>. Give it + a click if you like. + </CAlert> + <CAlert color="dark"> + A simple dark alert with <CAlertLink href="#">an example link</CAlertLink>. Give it + a click if you like. + </CAlert> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Alert</strong> <small>Additional content</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Alert can also incorporate supplementary components & elements like heading, + paragraph, and divider. + </p> + <DocsExample href="components/alert#additional-content"> + <CAlert color="success"> + <CAlertHeading tag="h4">Well done!</CAlertHeading> + <p> + Aww yeah, you successfully read this important alert message. This example text is + going to run a bit longer so that you can see how spacing within an alert works + with this kind of content. + </p> + <hr /> + <p className="mb-0"> + Whenever you need to, be sure to use margin utilities to keep things nice and + tidy. + </p> + </CAlert> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Alert</strong> <small>Dismissing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Alerts can also be easily dismissed. Just add the <code>dismissible</code> prop. + </p> + <DocsExample href="components/alert#dismissing"> + <CAlert + color="warning" + dismissible + onClose={() => { + alert('👋 Well, hi there! Thanks for dismissing me.') + }} + > + <strong>Go right ahead</strong> and click that dimiss over there on the right. + </CAlert> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Alerts diff --git a/src/views/notifications/badges/Badges.js b/src/views/notifications/badges/Badges.js new file mode 100644 index 00000000..f2c63b58 --- /dev/null +++ b/src/views/notifications/badges/Badges.js @@ -0,0 +1,122 @@ +import React from 'react' +import { CButton, CCard, CCardBody, CCardHeader, CCol, CBadge, CRow } from '@coreui/react' +import { DocsExample } from 'src/components' + +const Badges = () => { + return ( + <CRow> + <CCol lg={6}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Badges</strong> <small>Dismissing</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Bootstrap badge scale to suit the size of the parent element by using relative font + sizing and <code>em</code> units. + </p> + <DocsExample href="components/badge"> + <h1> + Example heading <CBadge color="secondary">New</CBadge> + </h1> + <h2> + Example heading <CBadge color="secondary">New</CBadge> + </h2> + <h3> + Example heading <CBadge color="secondary">New</CBadge> + </h3> + <h4> + Example heading <CBadge color="secondary">New</CBadge> + </h4> + <h5> + Example heading <CBadge color="secondary">New</CBadge> + </h5> + <h6> + Example heading <CBadge color="secondary">New</CBadge> + </h6> + </DocsExample> + <p className="text-medium-emphasis small"> + Badges can be used as part of links or buttons to provide a counter. + </p> + <DocsExample href="components/badge"> + <CButton color="primary"> + Notifications <CBadge color="secondary">4</CBadge> + </CButton> + </DocsExample> + <p className="text-medium-emphasis small"> + Remark that depending on how you use them, badges may be complicated for users of + screen readers and related assistive technologies. + </p> + <p className="text-medium-emphasis small"> + Unless the context is clear, consider including additional context with a visually + hidden piece of additional text. + </p> + <DocsExample href="components/badge"> + <CButton color="primary"> + Profile <CBadge color="secondary">9</CBadge> + <span className="visually-hidden">unread messages</span> + </CButton> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol lg={6}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Badges</strong> <small>Contextual variations</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add any of the below-mentioned <code>color</code> props to modify the presentation of + a badge. + </p> + <DocsExample href="components/badge#contextual-variations"> + <CBadge color="primary">primary</CBadge> + <CBadge color="success">success</CBadge> + <CBadge color="danger">danger</CBadge> + <CBadge color="warning">warning</CBadge> + <CBadge color="info">info</CBadge> + <CBadge color="light">light</CBadge> + <CBadge color="dark">dark</CBadge> + </DocsExample> + </CCardBody> + </CCard> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Badges</strong> <small>Pill badges</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Apply the <code>shape="rounded-pill"</code> prop to make badges rounded. + </p> + <DocsExample href="components/badge#pill-badges"> + <CBadge color="primary" shape="rounded-pill"> + primary + </CBadge> + <CBadge color="success" shape="rounded-pill"> + success + </CBadge> + <CBadge color="danger" shape="rounded-pill"> + danger + </CBadge> + <CBadge color="warning" shape="rounded-pill"> + warning + </CBadge> + <CBadge color="info" shape="rounded-pill"> + info + </CBadge> + <CBadge color="light" shape="rounded-pill"> + light + </CBadge> + <CBadge color="dark" shape="rounded-pill"> + dark + </CBadge> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Badges diff --git a/src/views/notifications/index.js b/src/views/notifications/index.js new file mode 100644 index 00000000..08e31cd7 --- /dev/null +++ b/src/views/notifications/index.js @@ -0,0 +1,6 @@ +import Alerts from './Alerts' +import Badges from './Badges' +import Modals from './Modals' +import Toaster from './toasts' + +export { Alerts, Badges, Modals, Toaster } diff --git a/src/views/notifications/modals/Modals.js b/src/views/notifications/modals/Modals.js new file mode 100644 index 00000000..fcd31116 --- /dev/null +++ b/src/views/notifications/modals/Modals.js @@ -0,0 +1,720 @@ +import React, { useState } from 'react' +import { + CButton, + CCard, + CCardBody, + CCardHeader, + CCol, + CLink, + CModal, + CModalBody, + CModalFooter, + CModalHeader, + CModalTitle, + CPopover, + CRow, + CTooltip, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const LiveDemo = () => { + const [visible, setVisible] = useState(false) + return ( + <> + <CButton onClick={() => setVisible(!visible)}>Launch demo modal</CButton> + <CModal visible={visible} onClose={() => setVisible(false)}> + <CModalHeader> + <CModalTitle>Modal title</CModalTitle> + </CModalHeader> + <CModalBody>Woohoo, you're reading this text in a modal!</CModalBody> + <CModalFooter> + <CButton color="secondary" onClick={() => setVisible(false)}> + Close + </CButton> + <CButton color="primary">Save changes</CButton> + </CModalFooter> + </CModal> + </> + ) +} + +const StaticBackdrop = () => { + const [visible, setVisible] = useState(false) + return ( + <> + <CButton onClick={() => setVisible(!visible)}>Launch static backdrop modal</CButton> + <CModal backdrop="static" visible={visible} onClose={() => setVisible(false)}> + <CModalHeader> + <CModalTitle>Modal title</CModalTitle> + </CModalHeader> + <CModalBody> + I will not close if you click outside me. Don'teven try to press escape key. + </CModalBody> + <CModalFooter> + <CButton color="secondary" onClick={() => setVisible(false)}> + Close + </CButton> + <CButton color="primary">Save changes</CButton> + </CModalFooter> + </CModal> + </> + ) +} + +const ScrollingLongContent = () => { + const [visible, setVisible] = useState(false) + return ( + <> + <CButton onClick={() => setVisible(!visible)}>Launch demo modal</CButton> + <CModal visible={visible} onClose={() => setVisible(false)}> + <CModalHeader> + <CModalTitle>Modal title</CModalTitle> + </CModalHeader> + <CModalBody> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + </CModalBody> + <CModalFooter> + <CButton color="secondary" onClick={() => setVisible(false)}> + Close + </CButton> + <CButton color="primary">Save changes</CButton> + </CModalFooter> + </CModal> + </> + ) +} + +const ScrollingLongContent2 = () => { + const [visible, setVisible] = useState(false) + return ( + <> + <CButton onClick={() => setVisible(!visible)}>Launch demo modal</CButton> + <CModal scrollable visible={visible} onClose={() => setVisible(false)}> + <CModalHeader> + <CModalTitle>Modal title</CModalTitle> + </CModalHeader> + <CModalBody> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + </CModalBody> + <CModalFooter> + <CButton color="secondary" onClick={() => setVisible(false)}> + Close + </CButton> + <CButton color="primary">Save changes</CButton> + </CModalFooter> + </CModal> + </> + ) +} + +const VerticallyCentered = () => { + const [visible, setVisible] = useState(false) + return ( + <> + <CButton onClick={() => setVisible(!visible)}>Vertically centered modal</CButton> + <CModal alignment="center" visible={visible} onClose={() => setVisible(false)}> + <CModalHeader> + <CModalTitle>Modal title</CModalTitle> + </CModalHeader> + <CModalBody> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </CModalBody> + <CModalFooter> + <CButton color="secondary" onClick={() => setVisible(false)}> + Close + </CButton> + <CButton color="primary">Save changes</CButton> + </CModalFooter> + </CModal> + </> + ) +} + +const VerticallyCentered2 = () => { + const [visible, setVisible] = useState(false) + return ( + <> + <CButton onClick={() => setVisible(!visible)}>Vertically centered scrollable modal</CButton> + <CModal alignment="center" scrollable visible={visible} onClose={() => setVisible(false)}> + <CModalHeader> + <CModalTitle>Modal title</CModalTitle> + </CModalHeader> + <CModalBody> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + <p> + Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel + scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus + auctor fringilla. + </p> + <p> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis + in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + </p> + <p> + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. + </p> + </CModalBody> + <CModalFooter> + <CButton color="secondary" onClick={() => setVisible(false)}> + Close + </CButton> + <CButton color="primary">Save changes</CButton> + </CModalFooter> + </CModal> + </> + ) +} + +const TooltipsPopovers = () => { + const [visible, setVisible] = useState(false) + return ( + <> + <CButton onClick={() => setVisible(!visible)}>Launch demo modal</CButton> + <CModal alignment="center" visible={visible} onClose={() => setVisible(false)}> + <CModalHeader> + <CModalTitle>Modal title</CModalTitle> + </CModalHeader> + <CModalBody> + <h5>Popover in a modal</h5> + <p> + This + <CPopover title="Popover title" content="Popover body content is set in this property."> + <CButton>button</CButton> + </CPopover>{' '} + triggers a popover on click. + </p> + <hr /> + <h5>Tooltips in a modal</h5> + <p> + <CTooltip content="Tooltip"> + <CLink>This link</CLink> + </CTooltip>{' '} + and + <CTooltip content="Tooltip"> + <CLink>that link</CLink> + </CTooltip>{' '} + have tooltips on hover. + </p> + </CModalBody> + <CModalFooter> + <CButton color="secondary" onClick={() => setVisible(false)}> + Close + </CButton> + <CButton color="primary">Save changes</CButton> + </CModalFooter> + </CModal> + </> + ) +} + +const OptionalSizes = () => { + const [visibleXL, setVisibleXL] = useState(false) + const [visibleLg, setVisibleLg] = useState(false) + const [visibleSm, setVisibleSm] = useState(false) + return ( + <> + <CButton onClick={() => setVisibleXL(!visibleXL)}>Extra large modal</CButton> + <CButton onClick={() => setVisibleLg(!visibleLg)}>Large modal</CButton> + <CButton onClick={() => setVisibleSm(!visibleSm)}>Small large modal</CButton> + <CModal size="xl" visible={visibleXL} onClose={() => setVisibleXL(false)}> + <CModalHeader> + <CModalTitle>Extra large modal</CModalTitle> + </CModalHeader> + <CModalBody>...</CModalBody> + </CModal> + <CModal size="lg" visible={visibleLg} onClose={() => setVisibleLg(false)}> + <CModalHeader> + <CModalTitle>Large modal</CModalTitle> + </CModalHeader> + <CModalBody>...</CModalBody> + </CModal> + <CModal size="sm" visible={visibleSm} onClose={() => setVisibleSm(false)}> + <CModalHeader> + <CModalTitle>Small modal</CModalTitle> + </CModalHeader> + <CModalBody>...</CModalBody> + </CModal> + </> + ) +} + +const FullscreenModal = () => { + const [visible, setVisible] = useState(false) + const [visibleSm, setVisibleSm] = useState(false) + const [visibleMd, setVisibleMd] = useState(false) + const [visibleLg, setVisibleLg] = useState(false) + const [visibleXL, setVisibleXL] = useState(false) + const [visibleXXL, setVisibleXXL] = useState(false) + + return ( + <> + <CButton onClick={() => setVisible(!visible)}>Full screen</CButton> + <CButton onClick={() => setVisibleSm(!visibleSm)}>Full screen below sm</CButton> + <CButton onClick={() => setVisibleMd(!visibleMd)}>Full screen below md</CButton> + <CButton onClick={() => setVisibleLg(!visibleLg)}>Full screen below lg</CButton> + <CButton onClick={() => setVisibleXL(!visibleXL)}>Full screen below xl</CButton> + <CButton onClick={() => setVisibleXXL(!visibleXXL)}>Full screen below xxl</CButton> + <CModal fullscreen visible={visible} onClose={() => setVisible(false)}> + <CModalHeader> + <CModalTitle>Full screen</CModalTitle> + </CModalHeader> + <CModalBody>...</CModalBody> + </CModal> + <CModal fullscreen="sm" visible={visibleSm} onClose={() => setVisibleSm(false)}> + <CModalHeader> + <CModalTitle>Full screen below sm</CModalTitle> + </CModalHeader> + <CModalBody>...</CModalBody> + </CModal> + <CModal fullscreen="md" visible={visibleMd} onClose={() => setVisibleMd(false)}> + <CModalHeader> + <CModalTitle>Full screen below md</CModalTitle> + </CModalHeader> + <CModalBody>...</CModalBody> + </CModal> + <CModal fullscreen="lg" visible={visibleLg} onClose={() => setVisibleLg(false)}> + <CModalHeader> + <CModalTitle>Full screen below lg</CModalTitle> + </CModalHeader> + <CModalBody>...</CModalBody> + </CModal> + <CModal fullscreen="xl" visible={visibleXL} onClose={() => setVisibleXL(false)}> + <CModalHeader> + <CModalTitle>Full screen below xl</CModalTitle> + </CModalHeader> + <CModalBody>...</CModalBody> + </CModal> + <CModal fullscreen="xxl" visible={visibleXXL} onClose={() => setVisibleXXL(false)}> + <CModalHeader> + <CModalTitle>Full screen below xxl</CModalTitle> + </CModalHeader> + <CModalBody>...</CModalBody> + </CModal> + </> + ) +} + +const Modals = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Modal</strong> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Below is a static modal example (meaning its <code>position</code> and{' '} + <code>display</code> have been overridden). Included are the modal header, modal body + (required for <code>padding</code>), and modal footer (optional). We ask that you + include modal headers with dismiss actions whenever possible, or provide another + explicit dismiss action. + </p> + <DocsExample href="components/modal"> + <CModal + className="show d-block position-static" + backdrop={false} + keyboard={false} + portal={false} + visible + > + <CModalHeader> + <CModalTitle>Modal title</CModalTitle> + </CModalHeader> + <CModalBody>Modal body text goes here.</CModalBody> + <CModalFooter> + <CButton color="secondary">Close</CButton> + <CButton color="primary">Save changes</CButton> + </CModalFooter> + </CModal> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Modal</strong> <small>Live demo</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Toggle a working modal demo by clicking the button below. It will slide down and fade + in from the top of the page. + </p> + <DocsExample href="components/modal#live-demo">{LiveDemo()}</DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Modal</strong> <small>Static backdrop</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + If you don’t provide an <code>onDimsiss</code> handler to the Modal component, your + modal will behave as though the backdrop is static, meaning it will not close when + clicking outside it. Click the button below to try it. + </p> + <DocsExample href="components/modal#static-backdrop">{StaticBackdrop()}</DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Modal</strong> <small>Scrolling long content</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + If you don’t provide an <code>onDimsiss</code> handler to the Modal component, your + modal will behave as though the backdrop is static, meaning it will not close when + clicking outside it. Click the button below to try it. + </p> + <DocsExample href="components/modal#scrolling-long-content"> + {ScrollingLongContent()} + </DocsExample> + <p className="text-medium-emphasis small"> + You can also create a scrollable modal that allows scroll the modal body by adding{' '} + <code>scrollable</code> prop. + </p> + <DocsExample href="components/modal#scrolling-long-content"> + {ScrollingLongContent2()} + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Modal</strong> <small>Vertically centered</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Add <code>alignment="center"</code> to <code><CModal></code> to + vertically center the modal. + </p> + <DocsExample href="components/modal#vertically-centered"> + {VerticallyCentered()} + </DocsExample> + <DocsExample href="components/modal#vertically-centered"> + {VerticallyCentered2()} + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Modal</strong> <small>Tooltips and popovers</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + <code><CTooltips></code> and <code><CPopovers></code> can be placed within + modals as needed. When modals are closed, any tooltips and popovers within are also + automatically dismissed. + </p> + <DocsExample href="components/modal#tooltips-and-popovers"> + {TooltipsPopovers()} + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Modal</strong> <small>Optional sizes</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Modals have three optional sizes, available via modifier classes to be placed on a{' '} + <code><CModal></code>. These sizes kick in at certain breakpoints to avoid + horizontal scrollbars on narrower viewports. + </p> + <table className="table"> + <thead> + <tr> + <th>Size</th> + <th>Property size</th> + <th>Modal max-width</th> + </tr> + </thead> + <tbody> + <tr> + <td>Small</td> + <td> + <code>'sm'</code> + </td> + <td> + <code>300px</code> + </td> + </tr> + <tr> + <td>Default</td> + <td className="text-medium-emphasis">None</td> + <td> + <code>500px</code> + </td> + </tr> + <tr> + <td>Large</td> + <td> + <code>'lg'</code> + </td> + <td> + <code>800px</code> + </td> + </tr> + <tr> + <td>Extra large</td> + <td> + <code>'xl'</code> + </td> + <td> + <code>1140px</code> + </td> + </tr> + </tbody> + </table> + <DocsExample href="components/modal#optional-sizes">{OptionalSizes()}</DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Modal</strong> <small>Fullscreen Modal</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Another override is the option to pop up a modal that covers the user viewport, + available via property <code>fullscrean</code>. + </p> + <table className="table"> + <thead> + <tr> + <th>Property fullscrean</th> + <th>Availability</th> + </tr> + </thead> + <tbody> + <tr> + <td> + <code>true</code> + </td> + <td>Always</td> + </tr> + <tr> + <td> + <code>'sm'</code> + </td> + <td> + Below <code>576px</code> + </td> + </tr> + <tr> + <td> + <code>'md'</code> + </td> + <td> + Below <code>768px</code> + </td> + </tr> + <tr> + <td> + <code>'lg'</code> + </td> + <td> + Below <code>992px</code> + </td> + </tr> + <tr> + <td> + <code>'xl'</code> + </td> + <td> + Below <code>1200px</code> + </td> + </tr> + <tr> + <td> + <code>'xxl'</code> + </td> + <td> + Below <code>1400px</code> + </td> + </tr> + </tbody> + </table> + <DocsExample href="components/modal#fullscreen-modal">{FullscreenModal()}</DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Modals diff --git a/src/views/notifications/toasts/Toasts.js b/src/views/notifications/toasts/Toasts.js new file mode 100644 index 00000000..09422abb --- /dev/null +++ b/src/views/notifications/toasts/Toasts.js @@ -0,0 +1,252 @@ +import React, { useRef, useState } from 'react' +import { + CCard, + CCardHeader, + CCardBody, + CButton, + CRow, + CCol, + CToast, + CToastBody, + CToastClose, + CToastHeader, + CToaster, +} from '@coreui/react' +import { DocsExample } from 'src/components' + +const ExampleToast = () => { + const [toast, addToast] = useState(0) + const toaster = useRef() + const exampleToast = ( + <CToast title="CoreUI for React.js"> + <CToastHeader closeButton> + <svg + className="rounded me-2" + width="20" + height="20" + xmlns="http://www.w3.org/2000/svg" + preserveAspectRatio="xMidYMid slice" + focusable="false" + role="img" + > + <rect width="100%" height="100%" fill="#007aff"></rect> + </svg> + <strong className="me-auto">CoreUI for React.js</strong> + <small>7 min ago</small> + </CToastHeader> + <CToastBody>Hello, world! This is a toast message.</CToastBody> + </CToast> + ) + return ( + <> + <CButton onClick={() => addToast(exampleToast)}>Send a toast</CButton> + <CToaster ref={toaster} push={toast} placement="top-end" /> + </> + ) +} + +const Toasts = () => { + return ( + <CRow> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Toast</strong> <small>Basic</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Toasts are as flexible as you need and have very little required markup. At a minimum, + we require a single element to contain your “toasted” content and strongly encourage a + dismiss button. + </p> + <DocsExample href="components/toast"> + <CToast title="CoreUI for React.js" autohide={false} visible={true}> + <CToastHeader closeButton> + <svg + className="rounded me-2" + width="20" + height="20" + xmlns="http://www.w3.org/2000/svg" + preserveAspectRatio="xMidYMid slice" + focusable="false" + role="img" + > + <rect width="100%" height="100%" fill="#007aff"></rect> + </svg> + <strong className="me-auto">CoreUI for React.js</strong> + <small>7 min ago</small> + </CToastHeader> + <CToastBody>Hello, world! This is a toast message.</CToastBody> + </CToast> + </DocsExample> + <DocsExample href="components/toast">{ExampleToast()}</DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Toast</strong> <small>Translucent</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Toasts are slightly translucent to blend in with what's below them. + </p> + <DocsExample href="components/toast#translucent"> + <div className="bg-dark p-3"> + <CToast title="CoreUI for React.js" autohide={false} visible={true}> + <CToastHeader closeButton> + <svg + className="rounded me-2" + width="20" + height="20" + xmlns="http://www.w3.org/2000/svg" + preserveAspectRatio="xMidYMid slice" + focusable="false" + role="img" + > + <rect width="100%" height="100%" fill="#007aff"></rect> + </svg> + <strong className="me-auto">CoreUI for React.js</strong> + <small>7 min ago</small> + </CToastHeader> + <CToastBody>Hello, world! This is a toast message.</CToastBody> + </CToast> + </div> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Toast</strong> <small>Stacking</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + You can stack toasts by wrapping them in a toast container, which will vertically add + some spacing. + </p> + <DocsExample href="components/toast#stacking"> + <CToaster> + <CToast title="CoreUI for React.js" autohide={false} visible={true}> + <CToastHeader closeButton> + <svg + className="rounded me-2" + width="20" + height="20" + xmlns="http://www.w3.org/2000/svg" + preserveAspectRatio="xMidYMid slice" + focusable="false" + role="img" + > + <rect width="100%" height="100%" fill="#007aff"></rect> + </svg> + <strong className="me-auto">CoreUI for React.js</strong> + <small>7 min ago</small> + </CToastHeader> + <CToastBody>Hello, world! This is a toast message.</CToastBody> + </CToast> + <CToast title="CoreUI for React.js" autohide={false} visible={true}> + <CToastHeader closeButton> + <svg + className="rounded me-2" + width="20" + height="20" + xmlns="http://www.w3.org/2000/svg" + preserveAspectRatio="xMidYMid slice" + focusable="false" + role="img" + > + <rect width="100%" height="100%" fill="#007aff"></rect> + </svg> + <strong className="me-auto">CoreUI for React.js</strong> + <small>7 min ago</small> + </CToastHeader> + <CToastBody>Hello, world! This is a toast message.</CToastBody> + </CToast> + </CToaster> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Toast</strong> <small>Custom content</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Customize your toasts by removing sub-components, tweaking them with{' '} + <a href="https://coreui.io/docs/4.0/utilities/api">utilities</a>, or by adding your + own markup. Here we've created a simpler toast by removing the default{' '} + <code><CToastHeader></code>, adding a custom hide icon from{' '} + <a href="https://icons.coreui.io">CoreUI Icons</a>, and using some{' '} + <a href="https://coreui.io/docs/4.0/utilities/flex">flexbox utilities</a> to adjust + the layout. + </p> + <DocsExample href="components/toast#custom-content"> + <CToast autohide={false} className="align-items-center" visible={true}> + <div className="d-flex"> + <CToastBody>Hello, world! This is a toast message.</CToastBody> + <CToastClose className="me-2 m-auto" /> + </div> + </CToast> + </DocsExample> + <p className="text-medium-emphasis small"> + Alternatively, you can also add additional controls and components to toasts. + </p> + <DocsExample href="components/toast#custom-content"> + <CToast autohide={false} visible={true}> + <CToastBody> + Hello, world! This is a toast message. + <div className="mt-2 pt-2 border-top"> + <CButton type="button" color="primary" size="sm"> + Take action + </CButton> + <CToastClose component={CButton} color="secondary" size="sm" className="ms-1"> + Close + </CToastClose> + </div> + </CToastBody> + </CToast> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + <CCol xs={12}> + <CCard className="mb-4"> + <CCardHeader> + <strong>React Toast</strong> <small>Custom content</small> + </CCardHeader> + <CCardBody> + <p className="text-medium-emphasis small"> + Building on the above example, you can create different toast color schemes with our{' '} + <a href="https://coreui.io/docs/4.0/utilities/colors">color</a> and{' '} + <a href="https://coreui.io/docs/4.0//utilities/background">background</a> utilities. + Here we've set <code>color="primary"</code> and added{' '} + <code>.text-white</code> class to the <code><Ctoast></code>, and then set{' '} + <code>white</code> property to our close button. For a crisp edge, we remove the + default border with <code>.border-0</code>. + </p> + <DocsExample href="components/toast#color-schemes"> + <CToast + autohide={false} + color="primary" + className="text-white align-items-center" + visible={true} + > + <div className="d-flex"> + <CToastBody>Hello, world! This is a toast message.</CToastBody> + <CToastClose className="me-2 m-auto" white /> + </div> + </CToast> + </DocsExample> + </CCardBody> + </CCard> + </CCol> + </CRow> + ) +} + +export default Toasts diff --git a/src/views/pages/login/Login.js b/src/views/pages/login/Login.js new file mode 100644 index 00000000..6b889d53 --- /dev/null +++ b/src/views/pages/login/Login.js @@ -0,0 +1,86 @@ +import React from 'react' +import { Link } from 'react-router-dom' +import { + CButton, + CCard, + CCardBody, + CCardGroup, + CCol, + CContainer, + CForm, + CFormInput, + CInputGroup, + CInputGroupText, + CRow, +} from '@coreui/react' +import CIcon from '@coreui/icons-react' +import { cilLockLocked, cilUser } from '@coreui/icons' + +const Login = () => { + return ( + <div className="bg-light min-vh-100 d-flex flex-row align-items-center"> + <CContainer> + <CRow className="justify-content-center"> + <CCol md={8}> + <CCardGroup> + <CCard className="p-4"> + <CCardBody> + <CForm> + <h1>Login</h1> + <p className="text-medium-emphasis">Sign In to your account</p> + <CInputGroup className="mb-3"> + <CInputGroupText> + <CIcon icon={cilUser} /> + </CInputGroupText> + <CFormInput placeholder="Username" autoComplete="username" /> + </CInputGroup> + <CInputGroup className="mb-4"> + <CInputGroupText> + <CIcon icon={cilLockLocked} /> + </CInputGroupText> + <CFormInput + type="password" + placeholder="Password" + autoComplete="current-password" + /> + </CInputGroup> + <CRow> + <CCol xs={6}> + <CButton color="primary" className="px-4"> + Login + </CButton> + </CCol> + <CCol xs={6} className="text-right"> + <CButton color="link" className="px-0"> + Forgot password? + </CButton> + </CCol> + </CRow> + </CForm> + </CCardBody> + </CCard> + <CCard className="text-white bg-primary py-5" style={{ width: '44%' }}> + <CCardBody className="text-center"> + <div> + <h2>Sign up</h2> + <p> + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. + </p> + <Link to="/register"> + <CButton color="primary" className="mt-3" active tabIndex={-1}> + Register Now! + </CButton> + </Link> + </div> + </CCardBody> + </CCard> + </CCardGroup> + </CCol> + </CRow> + </CContainer> + </div> + ) +} + +export default Login diff --git a/src/views/pages/page404/Page404.js b/src/views/pages/page404/Page404.js new file mode 100644 index 00000000..09e2cf4b --- /dev/null +++ b/src/views/pages/page404/Page404.js @@ -0,0 +1,41 @@ +import React from 'react' +import { + CButton, + CCol, + CContainer, + CFormInput, + CInputGroup, + CInputGroupText, + CRow, +} from '@coreui/react' +import CIcon from '@coreui/icons-react' +import { cilMagnifyingGlass } from '@coreui/icons' + +const Page404 = () => { + return ( + <div className="bg-light min-vh-100 d-flex flex-row align-items-center"> + <CContainer> + <CRow className="justify-content-center"> + <CCol md={6}> + <div className="clearfix"> + <h1 className="float-start display-3 me-4">404</h1> + <h4 className="pt-3">Oops! You{"'"}re lost.</h4> + <p className="text-medium-emphasis float-start"> + The page you are looking for was not found. + </p> + </div> + <CInputGroup className="input-prepend"> + <CInputGroupText> + <CIcon icon={cilMagnifyingGlass} /> + </CInputGroupText> + <CFormInput type="text" placeholder="What are you looking for?" /> + <CButton color="info">Search</CButton> + </CInputGroup> + </CCol> + </CRow> + </CContainer> + </div> + ) +} + +export default Page404 diff --git a/src/views/pages/page500/Page500.js b/src/views/pages/page500/Page500.js new file mode 100644 index 00000000..d7f6db30 --- /dev/null +++ b/src/views/pages/page500/Page500.js @@ -0,0 +1,41 @@ +import React from 'react' +import { + CButton, + CCol, + CContainer, + CFormInput, + CInputGroup, + CInputGroupText, + CRow, +} from '@coreui/react' +import CIcon from '@coreui/icons-react' +import { cilMagnifyingGlass } from '@coreui/icons' + +const Page500 = () => { + return ( + <div className="bg-light min-vh-100 d-flex flex-row align-items-center"> + <CContainer> + <CRow className="justify-content-center"> + <CCol md={6}> + <span className="clearfix"> + <h1 className="float-start display-3 me-4">500</h1> + <h4 className="pt-3">Houston, we have a problem!</h4> + <p className="text-medium-emphasis float-start"> + The page you are looking for is temporarily unavailable. + </p> + </span> + <CInputGroup className="input-prepend"> + <CInputGroupText> + <CIcon icon={cilMagnifyingGlass} /> + </CInputGroupText> + <CFormInput type="text" placeholder="What are you looking for?" /> + <CButton color="info">Search</CButton> + </CInputGroup> + </CCol> + </CRow> + </CContainer> + </div> + ) +} + +export default Page500 diff --git a/src/views/pages/register/Register.js b/src/views/pages/register/Register.js new file mode 100644 index 00000000..ee8afffb --- /dev/null +++ b/src/views/pages/register/Register.js @@ -0,0 +1,71 @@ +import React from 'react' +import { + CButton, + CCard, + CCardBody, + CCol, + CContainer, + CForm, + CFormInput, + CInputGroup, + CInputGroupText, + CRow, +} from '@coreui/react' +import CIcon from '@coreui/icons-react' +import { cilLockLocked, cilUser } from '@coreui/icons' + +const Register = () => { + return ( + <div className="bg-light min-vh-100 d-flex flex-row align-items-center"> + <CContainer> + <CRow className="justify-content-center"> + <CCol md={9} lg={7} xl={6}> + <CCard className="mx-4"> + <CCardBody className="p-4"> + <CForm> + <h1>Register</h1> + <p className="text-medium-emphasis">Create your account</p> + <CInputGroup className="mb-3"> + <CInputGroupText> + <CIcon icon={cilUser} /> + </CInputGroupText> + <CFormInput placeholder="Username" autoComplete="username" /> + </CInputGroup> + <CInputGroup className="mb-3"> + <CInputGroupText>@</CInputGroupText> + <CFormInput placeholder="Email" autoComplete="email" /> + </CInputGroup> + <CInputGroup className="mb-3"> + <CInputGroupText> + <CIcon icon={cilLockLocked} /> + </CInputGroupText> + <CFormInput + type="password" + placeholder="Password" + autoComplete="new-password" + /> + </CInputGroup> + <CInputGroup className="mb-4"> + <CInputGroupText> + <CIcon icon={cilLockLocked} /> + </CInputGroupText> + <CFormInput + type="password" + placeholder="Repeat password" + autoComplete="new-password" + /> + </CInputGroup> + <div className="d-grid"> + <CButton color="success">Create Account</CButton> + </div> + </CForm> + </CCardBody> + </CCard> + </CCol> + </CRow> + </CContainer> + </div> + ) +} + +export default Register diff --git a/src/views/theme/colors/Colors.js b/src/views/theme/colors/Colors.js new file mode 100644 index 00000000..9e51a986 --- /dev/null +++ b/src/views/theme/colors/Colors.js @@ -0,0 +1,91 @@ +import PropTypes from 'prop-types' +import React, { useEffect, useState, createRef } from 'react' +import classNames from 'classnames' +import { CRow, CCol, CCard, CCardHeader, CCardBody } from '@coreui/react' +import { rgbToHex } from '@coreui/utils' +import { DocsLink } from 'src/components' + +const ThemeView = () => { + const [color, setColor] = useState('rgb(255, 255, 255)') + const ref = createRef() + + useEffect(() => { + const el = ref.current.parentNode.firstChild + const varColor = window.getComputedStyle(el).getPropertyValue('background-color') + setColor(varColor) + }, [ref]) + + return ( + <table className="table w-100" ref={ref}> + <tbody> + <tr> + <td className="text-medium-emphasis">HEX:</td> + <td className="font-weight-bold">{rgbToHex(color)}</td> + </tr> + <tr> + <td className="text-medium-emphasis">RGB:</td> + <td className="font-weight-bold">{color}</td> + </tr> + </tbody> + </table> + ) +} + +const ThemeColor = ({ className, children }) => { + const classes = classNames(className, 'theme-color w-75 rounded mb-3') + return ( + <CCol xs={12} sm={6} md={4} xl={2} className="mb-4"> + <div className={classes} style={{ paddingTop: '75%' }}></div> + {children} + <ThemeView /> + </CCol> + ) +} + +ThemeColor.propTypes = { + children: PropTypes.node, + className: PropTypes.string, +} + +const Colors = () => { + return ( + <> + <CCard className="mb-4"> + <CCardHeader> + Theme colors + <DocsLink href="https://coreui.io/docs/utilities/colors/" /> + </CCardHeader> + <CCardBody> + <CRow> + <ThemeColor className="bg-primary"> + <h6>Brand Primary Color</h6> + </ThemeColor> + <ThemeColor className="bg-secondary"> + <h6>Brand Secondary Color</h6> + </ThemeColor> + <ThemeColor className="bg-success"> + <h6>Brand Success Color</h6> + </ThemeColor> + <ThemeColor className="bg-danger"> + <h6>Brand Danger Color</h6> + </ThemeColor> + <ThemeColor className="bg-warning"> + <h6>Brand Warning Color</h6> + </ThemeColor> + <ThemeColor className="bg-info"> + <h6>Brand Info Color</h6> + </ThemeColor> + <ThemeColor className="bg-light"> + <h6>Brand Light Color</h6> + </ThemeColor> + <ThemeColor className="bg-dark"> + <h6>Brand Dark Color</h6> + </ThemeColor> + </CRow> + </CCardBody> + </CCard> + </> + ) +} + +export default Colors diff --git a/src/views/theme/typography/Typography.js b/src/views/theme/typography/Typography.js new file mode 100644 index 00000000..1cae4f6c --- /dev/null +++ b/src/views/theme/typography/Typography.js @@ -0,0 +1,229 @@ +import React from 'react' +import { CCard, CCardHeader, CCardBody } from '@coreui/react' +import { DocsLink } from 'src/components' + +const Typography = () => { + return ( + <> + <CCard className="mb-4"> + <CCardHeader> + Headings + <DocsLink href="https://coreui.io/docs/content/typography/" /> + </CCardHeader> + <CCardBody> + <p> + Documentation and examples for Bootstrap typography, including global settings, + headings, body text, lists, and more. + </p> + <table className="table"> + <thead> + <tr> + <th>Heading</th> + <th>Example</th> + </tr> + </thead> + <tbody> + <tr> + <td> + <p> + <code className="highlighter-rouge"><h1></h1></code> + </p> + </td> + <td> + <span className="h1">h1. Bootstrap heading</span> + </td> + </tr> + <tr> + <td> + <p> + <code className="highlighter-rouge"><h2></h2></code> + </p> + </td> + <td> + <span className="h2">h2. Bootstrap heading</span> + </td> + </tr> + <tr> + <td> + <p> + <code className="highlighter-rouge"><h3></h3></code> + </p> + </td> + <td> + <span className="h3">h3. Bootstrap heading</span> + </td> + </tr> + <tr> + <td> + <p> + <code className="highlighter-rouge"><h4></h4></code> + </p> + </td> + <td> + <span className="h4">h4. Bootstrap heading</span> + </td> + </tr> + <tr> + <td> + <p> + <code className="highlighter-rouge"><h5></h5></code> + </p> + </td> + <td> + <span className="h5">h5. Bootstrap heading</span> + </td> + </tr> + <tr> + <td> + <p> + <code className="highlighter-rouge"><h6></h6></code> + </p> + </td> + <td> + <span className="h6">h6. Bootstrap heading</span> + </td> + </tr> + </tbody> + </table> + </CCardBody> + </CCard> + <CCard className="mb-4"> + <CCardHeader>Headings</CCardHeader> + <CCardBody> + <p> + <code className="highlighter-rouge">.h1</code> through + <code className="highlighter-rouge">.h6</code> + classes are also available, for when you want to match the font styling of a heading but + cannot use the associated HTML element. + </p> + <div className="bd-example"> + <p className="h1">h1. Bootstrap heading</p> + <p className="h2">h2. Bootstrap heading</p> + <p className="h3">h3. Bootstrap heading</p> + <p className="h4">h4. Bootstrap heading</p> + <p className="h5">h5. Bootstrap heading</p> + <p className="h6">h6. Bootstrap heading</p> + </div> + </CCardBody> + </CCard> + <CCard className="mb-4"> + <div className="card-header">Display headings</div> + <div className="card-body"> + <p> + Traditional heading elements are designed to work best in the meat of your page content. + When you need a heading to stand out, consider using a <strong>display heading</strong> + —a larger, slightly more opinionated heading style. + </p> + <div className="bd-example bd-example-type"> + <table className="table"> + <tbody> + <tr> + <td> + <span className="display-1">Display 1</span> + </td> + </tr> + <tr> + <td> + <span className="display-2">Display 2</span> + </td> + </tr> + <tr> + <td> + <span className="display-3">Display 3</span> + </td> + </tr> + <tr> + <td> + <span className="display-4">Display 4</span> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </CCard> + <CCard className="mb-4"> + <CCardHeader>Inline text elements</CCardHeader> + <CCardBody> + <p> + Traditional heading elements are designed to work best in the meat of your page content. + When you need a heading to stand out, consider using a <strong>display heading</strong> + —a larger, slightly more opinionated heading style. + </p> + <div className="bd-example"> + <p> + You can use the mark tag to <mark>highlight</mark> text. + </p> + <p> + <del>This line of text is meant to be treated as deleted text.</del> + </p> + <p> + <s>This line of text is meant to be treated as no longer accurate.</s> + </p> + <p> + <ins>This line of text is meant to be treated as an addition to the document.</ins> + </p> + <p> + <u>This line of text will render as underlined</u> + </p> + <p> + <small>This line of text is meant to be treated as fine print.</small> + </p> + <p> + <strong>This line rendered as bold text.</strong> + </p> + <p> + <em>This line rendered as italicized text.</em> + </p> + </div> + </CCardBody> + </CCard> + <CCard className="mb-4"> + <CCardHeader>Description list alignment</CCardHeader> + <CCardBody> + <p> + Align terms and descriptions horizontally by using our grid system’s predefined classes + (or semantic mixins). For longer terms, you can optionally add a{' '} + <code className="highlighter-rouge">.text-truncate</code> class to truncate the text + with an ellipsis. + </p> + <div className="bd-example"> + <dl className="row"> + <dt className="col-sm-3">Description lists</dt> + <dd className="col-sm-9">A description list is perfect for defining terms.</dd> + + <dt className="col-sm-3">Euismod</dt> + <dd className="col-sm-9"> + <p> + Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit. + </p> + <p>Donec id elit non mi porta gravida at eget metus.</p> + </dd> + + <dt className="col-sm-3">Malesuada porta</dt> + <dd className="col-sm-9">Etiam porta sem malesuada magna mollis euismod.</dd> + + <dt className="col-sm-3 text-truncate">Truncated term is truncated</dt> + <dd className="col-sm-9"> + Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut + fermentum massa justo sit amet risus. + </dd> + + <dt className="col-sm-3">Nesting</dt> + <dd className="col-sm-9"> + <dl className="row"> + <dt className="col-sm-4">Nested definition list</dt> + <dd className="col-sm-8"> + Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc. + </dd> + </dl> + </dd> + </dl> + </div> + </CCardBody> + </CCard> + </> + ) +} + +export default Typography diff --git a/src/views/widgets/Widgets.js b/src/views/widgets/Widgets.js new file mode 100644 index 00000000..44a2521b --- /dev/null +++ b/src/views/widgets/Widgets.js @@ -0,0 +1,936 @@ +import React from 'react' +import { + CCard, + CCardBody, + CCardGroup, + CCardHeader, + CCol, + CLink, + CRow, + CWidgetStatsB, + CWidgetStatsC, + CWidgetStatsE, + CWidgetStatsF, +} from '@coreui/react' +import { getStyle } from '@coreui/utils' +import CIcon from '@coreui/icons-react' +import { + cilArrowRight, + cilBasket, + cilBell, + cilChartPie, + cilMoon, + cilLaptop, + cilPeople, + cilSettings, + cilSpeech, + cilSpeedometer, + cilUser, + cilUserFollow, +} from '@coreui/icons' +import { CChartBar, CChartLine } from '@coreui/react-chartjs' +import { DocsExample } from 'src/components' + +import WidgetsBrand from './WidgetsBrand' +import WidgetsDropdown from './WidgetsDropdown' + +const Widgets = () => { + const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min) + + return ( + <CCard className="mb-4"> + <CCardHeader>Widgets</CCardHeader> + <CCardBody> + <DocsExample href="/components/widgets/#cwidgetstatsa"> + <WidgetsDropdown /> + </DocsExample> + <DocsExample href="/components/widgets/#cwidgetstatsb"> + <CRow> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsB + className="mb-4" + progress={{ color: 'success', value: 89.9 }} + text="Lorem ipsum dolor sit amet enim." + title="Widget title" + value="89.9%" + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsB + className="mb-4" + value="12.124" + title="Widget title" + progress={{ color: 'info', value: 89.9 }} + text="Lorem ipsum dolor sit amet enim." + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsB + className="mb-4" + value="$98.111,00" + title="Widget title" + progress={{ color: 'warning', value: 89.9 }} + text="Lorem ipsum dolor sit amet enim." + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsB + className="mb-4" + value="2 TB" + title="Widget title" + progress={{ color: 'primary', value: 89.9 }} + text="Lorem ipsum dolor sit amet enim." + /> + </CCol> + </CRow> + </DocsExample> + <DocsExample href="/components/widgets/#cwidgetstatsb"> + <CRow> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsB + className="mb-4" + color="success" + inverse + value="89.9%" + title="Widget title" + progress={{ value: 89.9 }} + text="Lorem ipsum dolor sit amet enim." + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsB + className="mb-4" + color="info" + inverse + value="12.124" + title="Widget title" + progress={{ value: 89.9 }} + text="Lorem ipsum dolor sit amet enim." + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsB + className="mb-4" + color="warning" + inverse + value="$98.111,00" + title="Widget title" + progress={{ value: 89.9 }} + text="Lorem ipsum dolor sit amet enim." + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsB + className="mb-4" + color="primary" + inverse + value="2 TB" + title="Widget title" + progress={{ value: 89.9 }} + text="Lorem ipsum dolor sit amet enim." + /> + </CCol> + </CRow> + </DocsExample> + <DocsExample href="/components/widgets/#cwidgetstatse"> + <CRow> + <CCol sm={4} lg={2}> + <CWidgetStatsE + chart={ + <CChartBar + className="mx-auto" + style={{ height: '40px', width: '80px' }} + data={{ + labels: [ + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + ], + datasets: [ + { + backgroundColor: getStyle('--cui-danger'), + borderColor: 'transparent', + borderWidth: 1, + data: [ + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + ], + }, + ], + }} + options={{ + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + }, + }, + scales: { + x: { + display: false, + }, + y: { + display: false, + }, + }, + }} + /> + } + className="mb-4" + title="title" + value="1,123" + /> + </CCol> + <CCol sm={4} lg={2}> + <CWidgetStatsE + chart={ + <CChartBar + className="mx-auto" + style={{ height: '40px', width: '80px' }} + data={{ + labels: [ + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + ], + datasets: [ + { + backgroundColor: getStyle('--cui-primary'), + borderColor: 'transparent', + borderWidth: 1, + data: [ + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + ], + }, + ], + }} + options={{ + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + }, + }, + scales: { + x: { + display: false, + }, + y: { + display: false, + }, + }, + }} + /> + } + className="mb-4" + title="title" + value="1,123" + /> + </CCol> + <CCol sm={4} lg={2}> + <CWidgetStatsE + chart={ + <CChartBar + className="mx-auto" + style={{ height: '40px', width: '80px' }} + data={{ + labels: [ + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + ], + datasets: [ + { + backgroundColor: getStyle('--cui-success'), + borderColor: 'transparent', + borderWidth: 1, + data: [ + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + ], + }, + ], + }} + options={{ + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + }, + }, + scales: { + x: { + display: false, + }, + y: { + display: false, + }, + }, + }} + /> + } + className="mb-4" + title="title" + value="1,123" + /> + </CCol> + <CCol sm={4} lg={2}> + <CWidgetStatsE + chart={ + <CChartLine + className="mx-auto" + style={{ height: '40px', width: '80px' }} + data={{ + labels: [ + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + ], + datasets: [ + { + backgroundColor: 'transparent', + borderColor: getStyle('--cui-danger'), + borderWidth: 2, + data: [ + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + ], + }, + ], + }} + options={{ + maintainAspectRatio: false, + elements: { + line: { + tension: 0.4, + }, + point: { + radius: 0, + }, + }, + plugins: { + legend: { + display: false, + }, + }, + scales: { + x: { + display: false, + }, + y: { + display: false, + }, + }, + }} + /> + } + className="mb-4" + title="title" + value="1,123" + /> + </CCol> + <CCol sm={4} lg={2}> + <CWidgetStatsE + chart={ + <CChartLine + className="mx-auto" + style={{ height: '40px', width: '80px' }} + data={{ + labels: [ + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + ], + datasets: [ + { + backgroundColor: 'transparent', + borderColor: getStyle('--cui-success'), + borderWidth: 2, + data: [ + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + ], + }, + ], + }} + options={{ + maintainAspectRatio: false, + elements: { + line: { + tension: 0.4, + }, + point: { + radius: 0, + }, + }, + plugins: { + legend: { + display: false, + }, + }, + scales: { + x: { + display: false, + }, + y: { + display: false, + }, + }, + }} + /> + } + className="mb-4" + title="title" + value="1,123" + /> + </CCol> + <CCol sm={4} lg={2}> + <CWidgetStatsE + chart={ + <CChartLine + className="mx-auto" + style={{ height: '40px', width: '80px' }} + data={{ + labels: [ + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + 'T', + 'W', + 'T', + 'F', + 'S', + 'S', + 'M', + ], + datasets: [ + { + backgroundColor: 'transparent', + borderColor: getStyle('--cui-info'), + borderWidth: 2, + data: [ + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + random(40, 100), + ], + }, + ], + }} + options={{ + maintainAspectRatio: false, + elements: { + line: { + tension: 0.4, + }, + point: { + radius: 0, + }, + }, + plugins: { + legend: { + display: false, + }, + }, + scales: { + x: { + display: false, + }, + y: { + display: false, + }, + }, + }} + /> + } + className="mb-4" + title="title" + value="1,123" + /> + </CCol> + </CRow> + </DocsExample> + <DocsExample href="/components/widgets/#cwidgetstatsf"> + <CRow> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilSettings} size="xl" />} + title="income" + value="$1.999,50" + color="primary" + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilUser} size="xl" />} + title="income" + value="$1.999,50" + color="info" + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilMoon} size="xl" />} + title="income" + value="$1.999,50" + color="warning" + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilBell} size="xl" />} + title="income" + value="$1.999,50" + color="danger" + /> + </CCol> + </CRow> + </DocsExample> + <DocsExample href="/components/widgets/#cwidgetstatsf"> + <CRow> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilSettings} size="xl" />} + title="income" + value="$1.999,50" + color="primary" + footer={ + <CLink + className="font-weight-bold font-xs text-medium-emphasis" + href="https://coreui.io/" + rel="noopener norefferer" + target="_blank" + > + View more + <CIcon icon={cilArrowRight} className="float-end" width={16} /> + </CLink> + } + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilLaptop} size="xl" />} + title="income" + value="$1.999,50" + color="info" + footer={ + <CLink + className="font-weight-bold font-xs text-medium-emphasis" + href="https://coreui.io/" + rel="noopener norefferer" + target="_blank" + > + View more + <CIcon icon={cilArrowRight} className="float-end" width={16} /> + </CLink> + } + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilMoon} size="xl" />} + title="income" + value="$1.999,50" + color="warning" + footer={ + <CLink + className="font-weight-bold font-xs text-medium-emphasis" + href="https://coreui.io/" + rel="noopener norefferer" + target="_blank" + > + View more + <CIcon icon={cilArrowRight} className="float-end" width={16} /> + </CLink> + } + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilBell} size="xl" />} + title="income" + value="$1.999,50" + color="danger" + footer={ + <CLink + className="font-weight-bold font-xs text-medium-emphasis" + href="https://coreui.io/" + rel="noopener norefferer" + target="_blank" + > + View more + <CIcon icon={cilArrowRight} className="float-end" width={16} /> + </CLink> + } + /> + </CCol> + </CRow> + </DocsExample> + <DocsExample href="/components/widgets/#cwidgetstatsf"> + <CRow> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilSettings} size="xl" />} + padding={false} + title="income" + value="$1.999,50" + color="primary" + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilUser} size="xl" />} + padding={false} + title="income" + value="$1.999,50" + color="info" + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilMoon} size="xl" />} + padding={false} + title="income" + value="$1.999,50" + color="warning" + /> + </CCol> + <CCol xs={12} sm={6} lg={3}> + <CWidgetStatsF + className="mb-3" + icon={<CIcon width={24} icon={cilBell} size="xl" />} + padding={false} + title="income" + value="$1.999,50" + color="danger" + /> + </CCol> + </CRow> + </DocsExample> + <DocsExample href="/components/widgets/#cwidgetstatsd"> + <WidgetsBrand /> + </DocsExample> + <DocsExample href="/components/widgets/#cwidgetstatsd"> + <WidgetsBrand withCharts /> + </DocsExample> + <DocsExample href="/components/widgets/#cwidgetstatsc"> + <CCardGroup className="mb-4"> + <CWidgetStatsC + icon={<CIcon icon={cilPeople} height={36} />} + value="87.500" + title="Visitors" + progress={{ color: 'info', value: 75 }} + /> + <CWidgetStatsC + icon={<CIcon icon={cilUserFollow} height={36} />} + value="385" + title="New Clients" + progress={{ color: 'success', value: 75 }} + /> + <CWidgetStatsC + icon={<CIcon icon={cilBasket} height={36} />} + value="1238" + title="Products sold" + progress={{ color: 'warning', value: 75 }} + /> + <CWidgetStatsC + icon={<CIcon icon={cilChartPie} height={36} />} + value="28%" + title="Returning Visitors" + progress={{ color: 'primary', value: 75 }} + /> + <CWidgetStatsC + icon={<CIcon icon={cilSpeedometer} height={36} />} + value="5:34:11" + title="Avg. Time" + progress={{ color: 'danger', value: 75 }} + /> + </CCardGroup> + </DocsExample> + <DocsExample href="/components/widgets/#cwidgetstatsc"> + <CRow> + <CCol sm={6} md={2}> + <CWidgetStatsC + icon={<CIcon icon={cilPeople} height={36} />} + value="87.500" + title="Visitors" + progress={{ color: 'info', value: 75 }} + className="mb-4" + /> + </CCol> + <CCol sm={6} md={2}> + <CWidgetStatsC + icon={<CIcon icon={cilUserFollow} height={36} />} + value="385" + title="New Clients" + progress={{ color: 'success', value: 75 }} + className="mb-4" + /> + </CCol> + <CCol sm={6} md={2}> + <CWidgetStatsC + icon={<CIcon icon={cilBasket} height={36} />} + value="1238" + title="Products sold" + progress={{ color: 'warning', value: 75 }} + className="mb-4" + /> + </CCol> + <CCol sm={6} md={2}> + <CWidgetStatsC + icon={<CIcon icon={cilChartPie} height={36} />} + value="28%" + title="Returning Visitors" + progress={{ color: 'primary', value: 75 }} + className="mb-4" + /> + </CCol> + <CCol sm={6} md={2}> + <CWidgetStatsC + icon={<CIcon icon={cilSpeedometer} height={36} />} + value="5:34:11" + title="Avg. Time" + progress={{ color: 'danger', value: 75 }} + className="mb-4" + /> + </CCol> + <CCol sm={6} md={2}> + <CWidgetStatsC + icon={<CIcon icon={cilSpeech} height={36} />} + value="972" + title="comments" + progress={{ color: 'info', value: 75 }} + className="mb-4" + /> + </CCol> + </CRow> + </DocsExample> + <DocsExample href="/components/widgets/#cwidgetstatsc"> + <CRow> + <CCol sm={6} md={2}> + <CWidgetStatsC + color="info" + icon={<CIcon icon={cilPeople} height={36} />} + value="87.500" + title="Visitors" + inverse + progress={{ value: 75 }} + className="mb-4" + /> + </CCol> + <CCol sm={6} md={2}> + <CWidgetStatsC + color="success" + icon={<CIcon icon={cilUserFollow} height={36} />} + value="385" + title="New Clients" + inverse + progress={{ value: 75 }} + className="mb-4" + /> + </CCol> + <CCol sm={6} md={2}> + <CWidgetStatsC + color="warning" + icon={<CIcon icon={cilBasket} height={36} />} + value="1238" + title="Products sold" + inverse + progress={{ value: 75 }} + className="mb-4" + /> + </CCol> + <CCol sm={6} md={2}> + <CWidgetStatsC + color="primary" + icon={<CIcon icon={cilChartPie} height={36} />} + value="28%" + title="Returning Visitors" + inverse + progress={{ value: 75 }} + className="mb-4" + /> + </CCol> + <CCol sm={6} md={2}> + <CWidgetStatsC + color="danger" + icon={<CIcon icon={cilSpeedometer} height={36} />} + value="5:34:11" + title="Avg. Time" + inverse + progress={{ value: 75 }} + className="mb-4" + /> + </CCol> + <CCol sm={6} md={2}> + <CWidgetStatsC + color="info" + icon={<CIcon icon={cilSpeech} height={36} />} + value="972" + title="comments" + inverse + progress={{ value: 75 }} + className="mb-4" + /> + </CCol> + </CRow> + </DocsExample> + </CCardBody> + </CCard> + ) +} + +export default Widgets diff --git a/src/views/widgets/WidgetsBrand.js b/src/views/widgets/WidgetsBrand.js new file mode 100644 index 00000000..b5eb528a --- /dev/null +++ b/src/views/widgets/WidgetsBrand.js @@ -0,0 +1,188 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { CWidgetStatsD, CRow, CCol } from '@coreui/react' +import CIcon from '@coreui/icons-react' +import { cibFacebook, cibLinkedin, cibTwitter, cilCalendar } from '@coreui/icons' +import { CChart } from '@coreui/react-chartjs' + +const WidgetsBrand = ({ withCharts }) => { + const chartOptions = { + elements: { + line: { + tension: 0.4, + }, + point: { + radius: 0, + hitRadius: 10, + hoverRadius: 4, + hoverBorderWidth: 3, + }, + }, + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + }, + }, + scales: { + x: { + display: false, + }, + y: { + display: false, + }, + }, + } + + return ( + <CRow> + <CCol sm={6} lg={3}> + <CWidgetStatsD + className="mb-4" + {...(withCharts && { + chart: ( + <CChart + className="position-absolute w-100 h-100" + type="line" + data={{ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + backgroundColor: 'rgba(255,255,255,.1)', + borderColor: 'rgba(255,255,255,.55)', + pointHoverBackgroundColor: '#fff', + borderWidth: 2, + data: [65, 59, 84, 84, 51, 55, 40], + fill: true, + }, + ], + }} + options={chartOptions} + /> + ), + })} + icon={<CIcon icon={cibFacebook} height={52} className="my-4 text-white" />} + values={[ + { title: 'friends', value: '89K' }, + { title: 'feeds', value: '459' }, + ]} + style={{ + '--cui-card-cap-bg': '#3b5998', + }} + /> + </CCol> + + <CCol sm={6} lg={3}> + <CWidgetStatsD + className="mb-4" + {...(withCharts && { + chart: ( + <CChart + className="position-absolute w-100 h-100" + type="line" + data={{ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + backgroundColor: 'rgba(255,255,255,.1)', + borderColor: 'rgba(255,255,255,.55)', + pointHoverBackgroundColor: '#fff', + borderWidth: 2, + data: [1, 13, 9, 17, 34, 41, 38], + fill: true, + }, + ], + }} + options={chartOptions} + /> + ), + })} + icon={<CIcon icon={cibTwitter} height={52} className="my-4 text-white" />} + values={[ + { title: 'followers', value: '973k' }, + { title: 'tweets', value: '1.792' }, + ]} + style={{ + '--cui-card-cap-bg': '#00aced', + }} + /> + </CCol> + + <CCol sm={6} lg={3}> + <CWidgetStatsD + className="mb-4" + {...(withCharts && { + chart: ( + <CChart + className="position-absolute w-100 h-100" + type="line" + data={{ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + backgroundColor: 'rgba(255,255,255,.1)', + borderColor: 'rgba(255,255,255,.55)', + pointHoverBackgroundColor: '#fff', + borderWidth: 2, + data: [78, 81, 80, 45, 34, 12, 40], + fill: true, + }, + ], + }} + options={chartOptions} + /> + ), + })} + icon={<CIcon icon={cibLinkedin} height={52} className="my-4 text-white" />} + values={[ + { title: 'contacts', value: '500' }, + { title: 'feeds', value: '1.292' }, + ]} + style={{ + '--cui-card-cap-bg': '#4875b4', + }} + /> + </CCol> + + <CCol sm={6} lg={3}> + <CWidgetStatsD + className="mb-4" + color="warning" + {...(withCharts && { + chart: ( + <CChart + className="position-absolute w-100 h-100" + type="line" + data={{ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + backgroundColor: 'rgba(255,255,255,.1)', + borderColor: 'rgba(255,255,255,.55)', + pointHoverBackgroundColor: '#fff', + borderWidth: 2, + data: [35, 23, 56, 22, 97, 23, 64], + fill: true, + }, + ], + }} + options={chartOptions} + /> + ), + })} + icon={<CIcon icon={cilCalendar} height={52} className="my-4 text-white" />} + values={[ + { title: 'events', value: '12+' }, + { title: 'meetings', value: '4' }, + ]} + /> + </CCol> + </CRow> + ) +} + +WidgetsBrand.propTypes = { + withCharts: PropTypes.bool, +} + +export default WidgetsBrand diff --git a/src/views/widgets/WidgetsDropdown.js b/src/views/widgets/WidgetsDropdown.js new file mode 100644 index 00000000..94bbb6f9 --- /dev/null +++ b/src/views/widgets/WidgetsDropdown.js @@ -0,0 +1,361 @@ +import React from 'react' +import { + CRow, + CCol, + CDropdown, + CDropdownMenu, + CDropdownItem, + CDropdownToggle, + CWidgetStatsA, +} from '@coreui/react' +import { getStyle } from '@coreui/utils' +import { CChartBar, CChartLine } from '@coreui/react-chartjs' +import CIcon from '@coreui/icons-react' +import { cilArrowBottom, cilArrowTop, cilOptions } from '@coreui/icons' + +const WidgetsDropdown = () => { + return ( + <CRow> + <CCol sm={6} lg={3}> + <CWidgetStatsA + className="mb-4" + color="primary" + value={ + <> + 26K{' '} + <span className="fs-6 fw-normal"> + (-12.4% <CIcon icon={cilArrowBottom} />) + </span> + </> + } + title="Users" + action={ + <CDropdown alignment="end"> + <CDropdownToggle color="transparent" caret={false} className="p-0"> + <CIcon icon={cilOptions} className="text-high-emphasis-inverse" /> + </CDropdownToggle> + <CDropdownMenu> + <CDropdownItem>Action</CDropdownItem> + <CDropdownItem>Another action</CDropdownItem> + <CDropdownItem>Something else here...</CDropdownItem> + <CDropdownItem disabled>Disabled action</CDropdownItem> + </CDropdownMenu> + </CDropdown> + } + chart={ + <CChartLine + className="mt-3 mx-3" + style={{ height: '70px' }} + data={{ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + label: 'My First dataset', + backgroundColor: 'transparent', + borderColor: 'rgba(255,255,255,.55)', + pointBackgroundColor: getStyle('--cui-primary'), + data: [65, 59, 84, 84, 51, 55, 40], + }, + ], + }} + options={{ + plugins: { + legend: { + display: false, + }, + }, + maintainAspectRatio: false, + scales: { + x: { + grid: { + display: false, + drawBorder: false, + }, + ticks: { + display: false, + }, + }, + y: { + min: 30, + max: 89, + display: false, + grid: { + display: false, + }, + ticks: { + display: false, + }, + }, + }, + elements: { + line: { + borderWidth: 1, + tension: 0.4, + }, + point: { + radius: 4, + hitRadius: 10, + hoverRadius: 4, + }, + }, + }} + /> + } + /> + </CCol> + <CCol sm={6} lg={3}> + <CWidgetStatsA + className="mb-4" + color="info" + value={ + <> + $6.200{' '} + <span className="fs-6 fw-normal"> + (40.9% <CIcon icon={cilArrowTop} />) + </span> + </> + } + title="Income" + action={ + <CDropdown alignment="end"> + <CDropdownToggle color="transparent" caret={false} className="p-0"> + <CIcon icon={cilOptions} className="text-high-emphasis-inverse" /> + </CDropdownToggle> + <CDropdownMenu> + <CDropdownItem>Action</CDropdownItem> + <CDropdownItem>Another action</CDropdownItem> + <CDropdownItem>Something else here...</CDropdownItem> + <CDropdownItem disabled>Disabled action</CDropdownItem> + </CDropdownMenu> + </CDropdown> + } + chart={ + <CChartLine + className="mt-3 mx-3" + style={{ height: '70px' }} + data={{ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + label: 'My First dataset', + backgroundColor: 'transparent', + borderColor: 'rgba(255,255,255,.55)', + pointBackgroundColor: getStyle('--cui-info'), + data: [1, 18, 9, 17, 34, 22, 11], + }, + ], + }} + options={{ + plugins: { + legend: { + display: false, + }, + }, + maintainAspectRatio: false, + scales: { + x: { + grid: { + display: false, + drawBorder: false, + }, + ticks: { + display: false, + }, + }, + y: { + min: -9, + max: 39, + display: false, + grid: { + display: false, + }, + ticks: { + display: false, + }, + }, + }, + elements: { + line: { + borderWidth: 1, + }, + point: { + radius: 4, + hitRadius: 10, + hoverRadius: 4, + }, + }, + }} + /> + } + /> + </CCol> + <CCol sm={6} lg={3}> + <CWidgetStatsA + className="mb-4" + color="warning" + value={ + <> + 2.49{' '} + <span className="fs-6 fw-normal"> + (84.7% <CIcon icon={cilArrowTop} />) + </span> + </> + } + title="Conversion Rate" + action={ + <CDropdown alignment="end"> + <CDropdownToggle color="transparent" caret={false} className="p-0"> + <CIcon icon={cilOptions} className="text-high-emphasis-inverse" /> + </CDropdownToggle> + <CDropdownMenu> + <CDropdownItem>Action</CDropdownItem> + <CDropdownItem>Another action</CDropdownItem> + <CDropdownItem>Something else here...</CDropdownItem> + <CDropdownItem disabled>Disabled action</CDropdownItem> + </CDropdownMenu> + </CDropdown> + } + chart={ + <CChartLine + className="mt-3" + style={{ height: '70px' }} + data={{ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [ + { + label: 'My First dataset', + backgroundColor: 'rgba(255,255,255,.2)', + borderColor: 'rgba(255,255,255,.55)', + data: [78, 81, 80, 45, 34, 12, 40], + fill: true, + }, + ], + }} + options={{ + plugins: { + legend: { + display: false, + }, + }, + maintainAspectRatio: false, + scales: { + x: { + display: false, + }, + y: { + display: false, + }, + }, + elements: { + line: { + borderWidth: 2, + tension: 0.4, + }, + point: { + radius: 0, + hitRadius: 10, + hoverRadius: 4, + }, + }, + }} + /> + } + /> + </CCol> + <CCol sm={6} lg={3}> + <CWidgetStatsA + className="mb-4" + color="danger" + value={ + <> + 44K{' '} + <span className="fs-6 fw-normal"> + (-23.6% <CIcon icon={cilArrowBottom} />) + </span> + </> + } + title="Sessions" + action={ + <CDropdown alignment="end"> + <CDropdownToggle color="transparent" caret={false} className="p-0"> + <CIcon icon={cilOptions} className="text-high-emphasis-inverse" /> + </CDropdownToggle> + <CDropdownMenu> + <CDropdownItem>Action</CDropdownItem> + <CDropdownItem>Another action</CDropdownItem> + <CDropdownItem>Something else here...</CDropdownItem> + <CDropdownItem disabled>Disabled action</CDropdownItem> + </CDropdownMenu> + </CDropdown> + } + chart={ + <CChartBar + className="mt-3 mx-3" + style={{ height: '70px' }} + data={{ + labels: [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + 'January', + 'February', + 'March', + 'April', + ], + datasets: [ + { + label: 'My First dataset', + backgroundColor: 'rgba(255,255,255,.2)', + borderColor: 'rgba(255,255,255,.55)', + data: [78, 81, 80, 45, 34, 12, 40, 85, 65, 23, 12, 98, 34, 84, 67, 82], + barPercentage: 0.6, + }, + ], + }} + options={{ + maintainAspectRatio: false, + plugins: { + legend: { + display: false, + }, + }, + scales: { + x: { + grid: { + display: false, + drawTicks: false, + }, + ticks: { + display: false, + }, + }, + y: { + grid: { + display: false, + drawBorder: false, + drawTicks: false, + }, + ticks: { + display: false, + }, + }, + }, + }} + /> + } + /> + </CCol> + </CRow> + ) +} + +export default WidgetsDropdown diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 940020c5..00000000 --- a/tsconfig.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "compilerOptions": { - "jsx": "react", - "outDir": "dist", - "module": "esnext", - "target": "es5", - "lib": ["dom", "es2015", "es2016", "es2017", "es2018", "es2019", "es2020", "es2021"], - "sourceMap": true, - "allowJs": false, - "declaration": true, - "moduleResolution": "node", - "forceConsistentCasingInFileNames": true, - "noImplicitReturns": true, - "noImplicitThis": true, - "noImplicitAny": true, - "strictNullChecks": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "esModuleInterop": true, - "paths": { - "@coreui/icons-react": ["./packages/coreui-icons-react/src"], - "@coreui/icons-react/*": ["./packages/coreui-icons-react/src/*"], - "@coreui/react": ["./packages/coreui-react/src"], - "@coreui/react/*": ["./packages/coreui-react/src/*"], - "@coreui/react-chartjs": ["./packages/coreui-react-chartjs/src"], - "@coreui/react-chartjs/*": ["./packages/coreui-react-chartjs/src/*"] - } - }, - "exclude": ["**/node_modules", "**/dist"] -} From 6eb68907de142c6db1049adb1a45244a9f35bfa5 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sat, 2 Dec 2023 14:42:01 +0100 Subject: [PATCH 03/44] first mvp commit --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f7f80858..32df3f2b 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# Portico UI \ No newline at end of file +# Portico UI + +MVP - todo \ No newline at end of file From 8333292a8866bdc9a3bae589a30b177b4fc06999 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sat, 2 Dec 2023 18:21:10 +0100 Subject: [PATCH 04/44] initial UI configuration --- .eslintrc.js | 126 +- package-lock.json | 19669 ++++++++++++++++ package.json | 1 + src/App.js | 6 +- src/_nav.js | 331 +- src/assets/brand/portico-logo-blue.svg | 527 + src/assets/brand/portico-logo-white.svg | 527 + src/components/AppFooter.js | 11 +- src/components/AppHeader.js | 45 +- src/components/AppSidebar.js | 19 +- src/routes.js | 99 +- src/views/base/accordion/Accordion.js | 177 - src/views/base/breadcrumbs/Breadcrumbs.js | 74 - src/views/base/cards/Cards.js | 906 - src/views/base/carousels/Carousels.js | 212 - src/views/base/collapses/Collapses.js | 126 - src/views/base/index.js | 31 - src/views/base/jumbotrons/Jumbotrons.js | 56 - src/views/base/list-groups/ListGroups.js | 346 - src/views/base/navbars/Navbars.js | 174 - src/views/base/navs/Navs.js | 397 - src/views/base/paginations/Paginations.js | 174 - src/views/base/placeholders/Placeholders.js | 193 - src/views/base/popovers/Popovers.js | 71 - src/views/base/progress/Progress.js | 186 - src/views/base/spinners/Spinners.js | 120 - src/views/base/tables/Tables.js | 986 - src/views/base/tooltips/Tooltips.js | 79 - .../buttons/button-groups/ButtonGroups.js | 439 - src/views/buttons/buttons/Buttons.js | 401 - src/views/buttons/dropdowns/Dropdowns.js | 338 - src/views/buttons/index.js | 5 - src/views/charts/Charts.js | 176 - .../ConfiguratorCollators.js | 10 + .../ConfiguratorCoretime.js | 10 + .../ConfiguratorRuntime.js | 10 + src/views/configurator/Configurator.js | 10 + src/views/coretime/Coretime.js | 12 + src/views/empty/Empty.js | 13 + src/views/forms/checks-radios/ChecksRadios.js | 392 - .../forms/floating-labels/FloatingLabels.js | 170 - src/views/forms/form-control/FormControl.js | 248 - src/views/forms/input-group/InputGroup.js | 503 - src/views/forms/layout/Layout.js | 414 - src/views/forms/range/Range.js | 82 - src/views/forms/select/Select.js | 99 - src/views/forms/validation/Validation.js | 503 - src/views/icons/brands/Brands.js | 38 - src/views/icons/coreui-icons/CoreUIIcons.js | 25 - src/views/icons/flags/Flags.js | 25 - src/views/icons/index.js | 5 - src/views/notifications/alerts/Alerts.js | 147 - src/views/notifications/badges/Badges.js | 122 - src/views/notifications/index.js | 6 - src/views/notifications/modals/Modals.js | 720 - src/views/notifications/toasts/Toasts.js | 252 - src/views/runtime-upgrade/RuntimeUpgrade.js | 12 + 57 files changed, 20950 insertions(+), 9906 deletions(-) create mode 100644 package-lock.json create mode 100644 src/assets/brand/portico-logo-blue.svg create mode 100644 src/assets/brand/portico-logo-white.svg delete mode 100644 src/views/base/accordion/Accordion.js delete mode 100644 src/views/base/breadcrumbs/Breadcrumbs.js delete mode 100644 src/views/base/cards/Cards.js delete mode 100644 src/views/base/carousels/Carousels.js delete mode 100644 src/views/base/collapses/Collapses.js delete mode 100644 src/views/base/index.js delete mode 100644 src/views/base/jumbotrons/Jumbotrons.js delete mode 100644 src/views/base/list-groups/ListGroups.js delete mode 100644 src/views/base/navbars/Navbars.js delete mode 100644 src/views/base/navs/Navs.js delete mode 100644 src/views/base/paginations/Paginations.js delete mode 100644 src/views/base/placeholders/Placeholders.js delete mode 100644 src/views/base/popovers/Popovers.js delete mode 100644 src/views/base/progress/Progress.js delete mode 100644 src/views/base/spinners/Spinners.js delete mode 100644 src/views/base/tables/Tables.js delete mode 100644 src/views/base/tooltips/Tooltips.js delete mode 100644 src/views/buttons/button-groups/ButtonGroups.js delete mode 100644 src/views/buttons/buttons/Buttons.js delete mode 100644 src/views/buttons/dropdowns/Dropdowns.js delete mode 100644 src/views/buttons/index.js delete mode 100644 src/views/charts/Charts.js create mode 100644 src/views/configurator-collators/ConfiguratorCollators.js create mode 100644 src/views/configurator-coretime/ConfiguratorCoretime.js create mode 100644 src/views/configurator-runtime/ConfiguratorRuntime.js create mode 100644 src/views/configurator/Configurator.js create mode 100644 src/views/coretime/Coretime.js create mode 100644 src/views/empty/Empty.js delete mode 100644 src/views/forms/checks-radios/ChecksRadios.js delete mode 100644 src/views/forms/floating-labels/FloatingLabels.js delete mode 100644 src/views/forms/form-control/FormControl.js delete mode 100644 src/views/forms/input-group/InputGroup.js delete mode 100644 src/views/forms/layout/Layout.js delete mode 100644 src/views/forms/range/Range.js delete mode 100644 src/views/forms/select/Select.js delete mode 100644 src/views/forms/validation/Validation.js delete mode 100644 src/views/icons/brands/Brands.js delete mode 100644 src/views/icons/coreui-icons/CoreUIIcons.js delete mode 100644 src/views/icons/flags/Flags.js delete mode 100644 src/views/icons/index.js delete mode 100644 src/views/notifications/alerts/Alerts.js delete mode 100644 src/views/notifications/badges/Badges.js delete mode 100644 src/views/notifications/index.js delete mode 100644 src/views/notifications/modals/Modals.js delete mode 100644 src/views/notifications/toasts/Toasts.js create mode 100644 src/views/runtime-upgrade/RuntimeUpgrade.js diff --git a/.eslintrc.js b/.eslintrc.js index 2f74cc21..adbb328c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -7,66 +7,66 @@ 'use strict' -module.exports = { - root: true, // So parent files don't get applied - env: { - es6: true, - browser: true, - node: true, - }, - extends: [ - 'plugin:react/recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', - 'plugin:unicorn/recommended', - ], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 2020, - sourceType: 'module', - ecmaFeatures: { - jsx: true, - }, - }, - plugins: ['@typescript-eslint', 'react', 'react-hooks'], - settings: { - react: { - pragma: 'React', - version: 'detect', - }, - }, - rules: { - 'unicorn/filename-case': 'off', - 'unicorn/no-array-for-each': 'off', - 'unicorn/no-null': 'off', - 'unicorn/prefer-dom-node-append': 'off', - 'unicorn/prefer-export-from': 'off', - 'unicorn/prefer-query-selector': 'off', - 'unicorn/prevent-abbreviations': 'off', - }, - overrides: [ - { - files: ['packages/docs/build/**'], - env: { - browser: false, - node: true, - }, - parserOptions: { - sourceType: 'script', - }, - rules: { - '@typescript-eslint/no-var-requires': 'off', - 'no-console': 'off', - 'unicorn/prefer-module': 'off', - 'unicorn/prefer-top-level-await': 'off', - }, - }, - { - files: ['packages/docs/**'], - rules: { - '@typescript-eslint/no-var-requires': 'off', - 'unicorn/prefer-module': 'off', - }, - }, - ], -} +// module.exports = { +// root: true, // So parent files don't get applied +// env: { +// es6: true, +// browser: true, +// node: true, +// }, +// extends: [ +// 'plugin:react/recommended', +// 'plugin:@typescript-eslint/recommended', +// 'plugin:prettier/recommended', +// 'plugin:unicorn/recommended', +// ], +// parser: '@typescript-eslint/parser', +// parserOptions: { +// ecmaVersion: 2020, +// sourceType: 'module', +// ecmaFeatures: { +// jsx: true, +// }, +// }, +// plugins: ['@typescript-eslint', 'react', 'react-hooks'], +// settings: { +// react: { +// pragma: 'React', +// version: 'detect', +// }, +// }, +// rules: { +// 'unicorn/filename-case': 'off', +// 'unicorn/no-array-for-each': 'off', +// 'unicorn/no-null': 'off', +// 'unicorn/prefer-dom-node-append': 'off', +// 'unicorn/prefer-export-from': 'off', +// 'unicorn/prefer-query-selector': 'off', +// 'unicorn/prevent-abbreviations': 'off', +// }, +// overrides: [ +// { +// files: ['packages/docs/build/**'], +// env: { +// browser: false, +// node: true, +// }, +// parserOptions: { +// sourceType: 'script', +// }, +// rules: { +// '@typescript-eslint/no-var-requires': 'off', +// 'no-console': 'off', +// 'unicorn/prefer-module': 'off', +// 'unicorn/prefer-top-level-await': 'off', +// }, +// }, +// { +// files: ['packages/docs/**'], +// rules: { +// '@typescript-eslint/no-var-requires': 'off', +// 'unicorn/prefer-module': 'off', +// }, +// }, +// ], +// } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..00ca0ecd --- /dev/null +++ b/package-lock.json @@ -0,0 +1,19669 @@ +{ + "name": "@coreui/coreui-free-react-admin-template", + "version": "4.5.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@coreui/coreui-free-react-admin-template", + "version": "4.5.0", + "license": "MIT", + "dependencies": { + "@coreui/chartjs": "^3.1.2", + "@coreui/coreui": "^4.2.6", + "@coreui/icons": "^3.0.1", + "@coreui/icons-react": "^2.1.0", + "@coreui/react": "^4.9.0-rc.0", + "@coreui/react-chartjs": "^2.1.3", + "@coreui/utils": "^2.0.2", + "chart.js": "^3.9.1", + "classnames": "^2.3.2", + "core-js": "^3.31.0", + "eslint": "^8.55.0", + "prop-types": "^15.8.1", + "react": "^18.2.0", + "react-app-polyfill": "^3.0.0", + "react-dom": "^18.2.0", + "react-redux": "^8.1.1", + "react-router-dom": "^6.14.0", + "redux": "4.2.1", + "simplebar-react": "^2.4.3" + }, + "devDependencies": { + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^14.0.0", + "@testing-library/user-event": "^14.4.3", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-prettier": "^4.2.1", + "prettier": "2.8.8", + "react-scripts": "5.0.1", + "sass": "^1.63.6", + "web-vitals": "^3.3.2" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.2.tgz", + "integrity": "sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw==", + "dev": true + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dev": true, + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", + "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.5", + "@babel/parser": "^7.23.5", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/eslint-parser": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.23.3.tgz", + "integrity": "sha512-9bTuNlyx7oSstodm1cR1bECj4fkiknsDa1YniISkJemMY3DGhJNYBECbe6QD/q54mp2J8VO66jW3/7uP//iFCw==", + "dev": true, + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0", + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@babel/eslint-parser/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", + "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz", + "integrity": "sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", + "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", + "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", + "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.5.tgz", + "integrity": "sha512-6IsY8jOeWibsengGlWIezp7cuZEFzNlAghFpzh9wiZwhQ42/hRcPnY/QV9HJoKTlujupinSlnQPiEy/u2C1ZfQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.23.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/plugin-syntax-decorators": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.23.3.tgz", + "integrity": "sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz", + "integrity": "sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", + "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz", + "integrity": "sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz", + "integrity": "sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-flow": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz", + "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", + "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", + "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz", + "integrity": "sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", + "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", + "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "dev": true, + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", + "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.4.tgz", + "integrity": "sha512-ITwqpb6V4btwUG0YJR82o2QvmWrLgDnx/p2A3CTPYGaRgULkDiC0DRA2C4jlRB9uXGUEfaSS/IGHfVW+ohzYDw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.5.tgz", + "integrity": "sha512-2fMkXEJkrmwgu2Bsv1Saxgj30IXZdJ+84lQcKKI7sm719oXs0BBw2ZENKdJdR1PjWndgLCEBNXJOri0fk7RYQA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.23.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.5.tgz", + "integrity": "sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.4", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.5", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", + "@babel/plugin-transform-for-of": "^7.23.3", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.3", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.23.4", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", + "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-transform-react-display-name": "^7.23.3", + "@babel/plugin-transform-react-jsx": "^7.22.15", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", + "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", + "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", + "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.5", + "@babel/types": "^7.23.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", + "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@coreui/chartjs": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@coreui/chartjs/-/chartjs-3.1.2.tgz", + "integrity": "sha512-d3MGk3KZNAt29VRKP/XYiGmT56KTqtuOhLEg5HNwb7P7ZmEgOJoHxFHVCVE4I36hfgQCjZZVknsuk2ZTfF/2fw==", + "dependencies": { + "@coreui/coreui": "^4.2.6", + "chart.js": "^3.9.1" + } + }, + "node_modules/@coreui/coreui": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@coreui/coreui/-/coreui-4.3.2.tgz", + "integrity": "sha512-SKGY6E6v7QGq0P3YTnZQRSrU8t0euLQ3UV/FH5j0JmHYBBu7Mv0Hd9g8AESnj8xrCelKZ5bdZKZhmKaIdG5clw==", + "dependencies": { + "postcss-combine-duplicated-selectors": "^10.0.3" + }, + "peerDependencies": { + "@popperjs/core": "^2.11.6" + } + }, + "node_modules/@coreui/icons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@coreui/icons/-/icons-3.0.1.tgz", + "integrity": "sha512-u9UKEcRMyY9pa4jUoLij8pAR03g5g6TLWV33/Mx2ix8sffyi0eO4fLV8DSTQljDCw938zt7KYog5cVKEAJUxxg==" + }, + "node_modules/@coreui/icons-react": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@coreui/icons-react/-/icons-react-2.2.1.tgz", + "integrity": "sha512-44bdKV5fZpVRpY6M7AL15tSAB2S4/xFzAojMsYe9k46mjyX7QLAKoowioEtLXxOqCRUBBBgxAXyjvJeeJlZwxg==", + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@coreui/react": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@coreui/react/-/react-4.11.0.tgz", + "integrity": "sha512-RFa3yBUHyIBvl1XX5hVb8MYqj24fU1FogAxZUtA+9yRrssiBs3Uy1W/AqMKnLiSArKyUm07Khjxe7I3Hc1iPdA==", + "peerDependencies": { + "@coreui/coreui": "4.3.0", + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@coreui/react-chartjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@coreui/react-chartjs/-/react-chartjs-2.1.3.tgz", + "integrity": "sha512-Boj2LhlGlAVIdPRDDIyF5nbupIg9ohhpdLXW28ch0A0ZMpJvf0AwBoibV4Uo6agcN7jSq2uvgudNC3aJTMg/8w==", + "dependencies": { + "@coreui/chartjs": "^3.1.1", + "chart.js": "3.9.1" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@coreui/utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@coreui/utils/-/utils-2.0.2.tgz", + "integrity": "sha512-tIFmyKzR96vSD3vqtw4H/4rH/Pctghj+Rp9kWncx1ec2vstC+yphcEUmMk/r+Mm86/Tradi0SIcuCaqvhkyqJA==" + }, + "node_modules/@csstools/normalize.css": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", + "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==", + "dev": true + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", + "dev": true, + "dependencies": { + "@csstools/selector-specificity": "^2.0.2", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-color-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", + "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", + "dev": true, + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", + "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", + "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-ic-unit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", + "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", + "dev": true, + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", + "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", + "dev": true, + "dependencies": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-nested-calc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", + "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", + "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", + "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", + "dev": true, + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", + "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", + "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", + "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", + "dev": true, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/console/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/console/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/console/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "dev": true, + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/environment/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/environment/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/environment/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/fake-timers/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/fake-timers/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/globals/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/globals/node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "dev": true, + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-result/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-result/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/test-result/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@juggle/resize-observer": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", + "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", + "dev": true + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dev": true, + "dependencies": { + "eslint-scope": "5.1.1" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz", + "integrity": "sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ==", + "dev": true, + "dependencies": { + "ansi-html-community": "^0.0.8", + "common-path-prefix": "^3.0.0", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "find-up": "^5.0.0", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.4", + "schema-utils": "^3.0.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "@types/webpack": "4.x || 5.x", + "react-refresh": ">=0.10.0 <1.0.0", + "sockjs-client": "^1.4.0", + "type-fest": ">=0.17.0 <5.0.0", + "webpack": ">=4.43.0 <6.0.0", + "webpack-dev-server": "3.x || 4.x", + "webpack-hot-middleware": "2.x", + "webpack-plugin-serve": "0.x || 1.x" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + }, + "sockjs-client": { + "optional": true + }, + "type-fest": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + }, + "webpack-hot-middleware": { + "optional": true + }, + "webpack-plugin-serve": { + "optional": true + } + } + }, + "node_modules/@remix-run/router": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.1.tgz", + "integrity": "sha512-so+DHzZKsoOcoXrILB4rqDkMDy7NLMErRdOxvzvOKb507YINKUP4Di+shbTZDhSE/pBZ+vr7XGIpcOO0VLSA+Q==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.0.tgz", + "integrity": "sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA==", + "dev": true + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dev": true, + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "dev": true, + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "dev": true, + "dependencies": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.12.6" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "dev": true, + "dependencies": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@testing-library/dom": { + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.3.tgz", + "integrity": "sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/dom/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", + "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "dev": true, + "dependencies": { + "@adobe/css-tools": "^4.0.1", + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=8", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/react": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.1.2.tgz", + "integrity": "sha512-z4p7DVBTPjKM5qDZ0t5ZjzkpSNb+fZy1u6bzO7kk8oeGagpPCAtgh4cx1syrfp7a+QWkM021jGqjJaxJJnXAZg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^9.0.0", + "@types/react-dom": "^18.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.5.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.1.tgz", + "integrity": "sha512-UCcUKrUYGj7ClomOo2SpNVvx4/fkd/2BbIHDCle8A0ax+P3bU7yJwDBDrS6ZwdTMARWTGODX1hEsCcO+7beJjg==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.7", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.7.tgz", + "integrity": "sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", + "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.44.8", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.8.tgz", + "integrity": "sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "dev": true + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.10", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.10.tgz", + "integrity": "sha512-tE4yxKEphEyxj9s4inideLHktW/x6DwesIwWZ9NN1FKf9zbJYsnhBoA9vrHA/IuIOKwPa5PcFBNV4lpMIOEzyQ==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/jest/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@types/jest/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.2.tgz", + "integrity": "sha512-37MXfxkb0vuIlRKHNxwCkb60PNBpR94u4efQuN4JgIAm66zfCDXGSAFCef9XUWFovX2R1ok6Z7MHhtdVXXkkIw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz", + "integrity": "sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true + }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "node_modules/@types/q": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", + "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.2.40", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.40.tgz", + "integrity": "sha512-H+BUhb9C1zBtogDLAk+KCNRKiHDrqSwQT/0z0PVTwMFBxqg3011ByLomADtgkgMkfwj4AMOiXBReyLTUBg681g==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.17", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz", + "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "node_modules/@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true + }, + "node_modules/@types/testing-library__jest-dom": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", + "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", + "dev": true, + "dependencies": { + "@types/jest": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.reduce": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz", + "integrity": "sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz", + "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true + }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.16", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", + "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001538", + "fraction.js": "^4.3.6", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-jest/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-loader": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", + "dev": true, + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-named-asset-import": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", + "dev": true, + "peerDependencies": { + "@babel/core": "^7.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", + "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.3", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz", + "integrity": "sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.3", + "core-js-compat": "^3.33.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", + "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.3" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==", + "dev": true + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-react-app": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", + "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/plugin-proposal-decorators": "^7.16.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", + "@babel/plugin-proposal-numeric-separator": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-private-methods": "^7.16.0", + "@babel/plugin-transform-flow-strip-types": "^7.16.0", + "@babel/plugin-transform-react-display-name": "^7.16.0", + "@babel/plugin-transform-runtime": "^7.16.4", + "@babel/preset-env": "^7.16.4", + "@babel/preset-react": "^7.16.0", + "@babel/preset-typescript": "^7.16.0", + "@babel/runtime": "^7.16.3", + "babel-plugin-macros": "^3.1.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true + }, + "node_modules/bfj": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.1.0.tgz", + "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", + "dev": true, + "dependencies": { + "bluebird": "^3.7.2", + "check-types": "^11.2.3", + "hoopy": "^0.1.4", + "jsonpath": "^1.1.1", + "tryer": "^1.0.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/bonjour-service": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", + "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "dev": true, + "dependencies": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/can-use-dom": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/can-use-dom/-/can-use-dom-0.1.0.tgz", + "integrity": "sha512-ceOhN1DL7Y4O6M0j9ICgmTYziV89WMd96SvSl0REd8PMgrY0B/WBOPoed5S1KUmJqXgUXh8gzSe6E3ae27upsQ==" + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001565", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", + "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chart.js": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.9.1.tgz", + "integrity": "sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w==" + }, + "node_modules/check-types": { + "version": "11.2.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz", + "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/coa/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/coa/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/coa/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/coa/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/core-js": { + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz", + "integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.3.tgz", + "integrity": "sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow==", + "dev": true, + "dependencies": { + "browserslist": "^4.22.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.33.3.tgz", + "integrity": "sha512-taJ00IDOP+XYQEA2dAe4ESkmHt1fL8wzYDo3mRWQey8uO9UojlBFMneA65kMyxfYP7106c6LzWaq7/haDT6BCQ==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/css-blank-pseudo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-blank-pseudo": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-declaration-sorter": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-has-pseudo": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-has-pseudo": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-loader": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", + "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.21", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.3", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "dev": true, + "dependencies": { + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", + "dev": true, + "bin": { + "css-prefers-color-scheme": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true + }, + "node_modules/cssdb": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.9.0.tgz", + "integrity": "sha512-WPMT9seTQq6fPAa1yN4zjgZZeoTriSN2LqW9C+otjar12DQIWA4LuSfFrvFJiKp4oD0xIk1vumDLw8K9ur4NBw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ] + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "dev": true, + "dependencies": { + "cssnano-preset-default": "^5.2.14", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-default": { + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "dev": true, + "dependencies": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.4", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "node_modules/csso/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "dev": true, + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==", + "dev": true + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "deprecated": "Use your platform's native DOMException instead", + "dev": true, + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "dev": true + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.601", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.601.tgz", + "integrity": "sha512-SpwUMDWe9tQu8JX5QCO1+p/hChAi9AE9UpoC3rcHVc+gdCGlbT3SGb5I1klgb952HRIyvt9wZhSz9bNBYz9swA==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dev": true, + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-abstract": { + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", + "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==", + "dev": true, + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.1", + "es-set-tostringtag": "^2.0.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.0.1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "dev": true + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", + "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-flowtype": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21", + "string-natural-compare": "^3.0.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@babel/plugin-syntax-flow": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.9", + "eslint": "^8.1.0" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", + "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", + "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.33.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", + "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.12", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-testing-library": { + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", + "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^5.58.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0", + "npm": ">=6" + }, + "peerDependencies": { + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "dev": true, + "dependencies": { + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0", + "webpack": "^5.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" + }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==", + "dev": true + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-entities": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", + "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", + "dev": true, + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "webpack": "^5.20.0" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "dev": true + }, + "node_modules/identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "dev": true, + "dependencies": { + "harmony-reflect": "^1.4.6" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", + "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "dev": true, + "dependencies": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-changed-files/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-changed-files/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-changed-files/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "dev": true, + "dependencies": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-cli/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-config/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-config/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-environment-jsdom/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-environment-node/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-environment-node/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-haste-map/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-haste-map/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-haste-map/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-jasmine2/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-jasmine2/node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "dev": true, + "dependencies": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-mock/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-mock/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-mock/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "dev": true, + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "dev": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watch-typeahead": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", + "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.1", + "chalk": "^4.0.0", + "jest-regex-util": "^28.0.0", + "jest-watcher": "^28.0.0", + "slash": "^4.0.0", + "string-length": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "jest": "^27.0.0 || ^28.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/console/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "dev": true, + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", + "dev": true + }, + "node_modules/jest-watch-typeahead/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-message-util/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-watch-typeahead/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "dev": true, + "dependencies": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", + "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", + "dev": true, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watcher/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watcher/node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "dev": true, + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/jsonpath/node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dev": true + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", + "dev": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.7.tgz", + "integrity": "sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g==", + "dev": true, + "dependencies": { + "array.prototype.reduce": "^1.0.6", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "safe-array-concat": "^1.0.0" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-browser-comments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "browserslist": ">=4", + "postcss": ">=8" + } + }, + "node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-rebeccapurple": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-colormin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-combine-duplicated-selectors": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/postcss-combine-duplicated-selectors/-/postcss-combine-duplicated-selectors-10.0.3.tgz", + "integrity": "sha512-IP0BmwFloCskv7DV7xqvzDXqMHpwdczJa6ZvIW8abgHdcIHs9mCJX2ltFhu3EwA51ozp13DByng30+Ke+eIExA==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-convert-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-custom-media": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/postcss-custom-properties": { + "version": "12.1.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", + "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", + "dev": true, + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-env-function": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-flexbugs-fixes": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "dev": true, + "peerDependencies": { + "postcss": "^8.1.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "dev": true, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", + "dev": true, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-image-set-function": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-initial": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "dev": true, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-lab-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", + "dev": true, + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", + "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/postcss-loader": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", + "dev": true, + "dependencies": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-logical": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", + "dev": true, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-media-minmax": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-rules": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "dev": true, + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-params": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nesting": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", + "dev": true, + "dependencies": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-normalize": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", + "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", + "dev": true, + "dependencies": { + "@csstools/normalize.css": "*", + "postcss-browser-comments": "^4", + "sanitize.css": "*" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "browserslist": ">= 4", + "postcss": ">= 8" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "dev": true, + "dependencies": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-opacity-percentage": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", + "dev": true, + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "dev": true, + "dependencies": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-overflow-shorthand": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "dev": true, + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-preset-env": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", + "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", + "dev": true, + "dependencies": { + "@csstools/postcss-cascade-layers": "^1.1.1", + "@csstools/postcss-color-function": "^1.1.1", + "@csstools/postcss-font-format-keywords": "^1.0.1", + "@csstools/postcss-hwb-function": "^1.0.2", + "@csstools/postcss-ic-unit": "^1.0.1", + "@csstools/postcss-is-pseudo-class": "^2.0.7", + "@csstools/postcss-nested-calc": "^1.0.0", + "@csstools/postcss-normalize-display-values": "^1.0.1", + "@csstools/postcss-oklab-function": "^1.1.1", + "@csstools/postcss-progressive-custom-properties": "^1.3.0", + "@csstools/postcss-stepped-value-functions": "^1.0.1", + "@csstools/postcss-text-decoration-shorthand": "^1.0.0", + "@csstools/postcss-trigonometric-functions": "^1.0.2", + "@csstools/postcss-unset-value": "^1.0.2", + "autoprefixer": "^10.4.13", + "browserslist": "^4.21.4", + "css-blank-pseudo": "^3.0.3", + "css-has-pseudo": "^3.0.4", + "css-prefers-color-scheme": "^6.0.3", + "cssdb": "^7.1.0", + "postcss-attribute-case-insensitive": "^5.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^4.2.4", + "postcss-color-hex-alpha": "^8.0.4", + "postcss-color-rebeccapurple": "^7.1.1", + "postcss-custom-media": "^8.0.2", + "postcss-custom-properties": "^12.1.10", + "postcss-custom-selectors": "^6.0.3", + "postcss-dir-pseudo-class": "^6.0.5", + "postcss-double-position-gradients": "^3.1.2", + "postcss-env-function": "^4.0.6", + "postcss-focus-visible": "^6.0.4", + "postcss-focus-within": "^5.0.4", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^3.0.5", + "postcss-image-set-function": "^4.0.7", + "postcss-initial": "^4.0.1", + "postcss-lab-function": "^4.2.1", + "postcss-logical": "^5.0.4", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.2.0", + "postcss-opacity-percentage": "^1.1.2", + "postcss-overflow-shorthand": "^3.0.4", + "postcss-page-break": "^3.0.4", + "postcss-place": "^7.0.5", + "postcss-pseudo-class-any-link": "^7.1.6", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "dev": true, + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/postcss-svgo/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "node_modules/postcss-svgo/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-svgo/node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dev": true, + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-app-polyfill": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", + "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", + "dependencies": { + "core-js": "^3.19.2", + "object-assign": "^4.1.1", + "promise": "^8.1.0", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.9", + "whatwg-fetch": "^3.6.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-app-polyfill/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/react-dev-utils/node_modules/loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==", + "dev": true + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/react-redux": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz", + "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4 || ^5.0.0-beta.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/react-refresh": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "6.20.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.20.1.tgz", + "integrity": "sha512-ccvLrB4QeT5DlaxSFFYi/KR8UMQ4fcD8zBcR71Zp1kaYTC5oJKYAp1cbavzGrogwxca+ubjkd7XjFZKBW8CxPA==", + "dependencies": { + "@remix-run/router": "1.13.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.20.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.20.1.tgz", + "integrity": "sha512-npzfPWcxfQN35psS7rJgi/EW0Gx6EsNjfdJSAk73U/HqMEJZ2k/8puxfwHFgDQhBGmS3+sjnGbMdMSV45axPQw==", + "dependencies": { + "@remix-run/router": "1.13.1", + "react-router": "6.20.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-scripts": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", + "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.16.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", + "@svgr/webpack": "^5.5.0", + "babel-jest": "^27.4.2", + "babel-loader": "^8.2.3", + "babel-plugin-named-asset-import": "^0.3.8", + "babel-preset-react-app": "^10.0.1", + "bfj": "^7.0.2", + "browserslist": "^4.18.1", + "camelcase": "^6.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "css-loader": "^6.5.1", + "css-minimizer-webpack-plugin": "^3.2.0", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "eslint": "^8.3.0", + "eslint-config-react-app": "^7.0.1", + "eslint-webpack-plugin": "^3.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "html-webpack-plugin": "^5.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.4.3", + "jest-resolve": "^27.4.2", + "jest-watch-typeahead": "^1.0.0", + "mini-css-extract-plugin": "^2.4.5", + "postcss": "^8.4.4", + "postcss-flexbugs-fixes": "^5.0.2", + "postcss-loader": "^6.2.1", + "postcss-normalize": "^10.0.1", + "postcss-preset-env": "^7.0.1", + "prompts": "^2.4.2", + "react-app-polyfill": "^3.0.0", + "react-dev-utils": "^12.0.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0", + "resolve-url-loader": "^4.0.0", + "sass-loader": "^12.3.0", + "semver": "^7.3.5", + "source-map-loader": "^3.0.0", + "style-loader": "^3.3.1", + "tailwindcss": "^3.0.2", + "terser-webpack-plugin": "^5.2.5", + "webpack": "^5.64.4", + "webpack-dev-server": "^4.6.0", + "webpack-manifest-plugin": "^4.0.2", + "workbox-webpack-plugin": "^6.4.1" + }, + "bin": { + "react-scripts": "bin/react-scripts.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + }, + "peerDependencies": { + "react": ">= 16", + "typescript": "^3.2.1 || ^4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", + "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==", + "dev": true + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dev": true, + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-url-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", + "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", + "dev": true, + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^7.0.35", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=8.9" + }, + "peerDependencies": { + "rework": "1.0.1", + "rework-visit": "1.0.0" + }, + "peerDependenciesMeta": { + "rework": { + "optional": true + }, + "rework-visit": { + "optional": true + } + } + }, + "node_modules/resolve-url-loader/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/resolve-url-loader/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/resolve-url-loader/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sanitize.css": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", + "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==", + "dev": true + }, + "node_modules/sass": { + "version": "1.69.5", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz", + "integrity": "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-loader": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", + "dev": true, + "dependencies": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/simplebar": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/simplebar/-/simplebar-5.3.9.tgz", + "integrity": "sha512-1vIIpjDvY9sVH14e0LGeiCiTFU3ILqAghzO6OI9axeG+mvU/vMSrvXeAXkBolqFFz3XYaY8n5ahH9MeP3sp2Ag==", + "dependencies": { + "@juggle/resize-observer": "^3.3.1", + "can-use-dom": "^0.1.0", + "core-js": "^3.0.1", + "lodash.debounce": "^4.0.8", + "lodash.memoize": "^4.1.2", + "lodash.throttle": "^4.1.1" + } + }, + "node_modules/simplebar-react": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/simplebar-react/-/simplebar-react-2.4.3.tgz", + "integrity": "sha512-Ep8gqAUZAS5IC2lT5RE4t1ZFUIVACqbrSRQvFV9a6NbVUzXzOMnc4P82Hl8Ak77AnPQvmgUwZS7aUKLyBoMAcg==", + "dependencies": { + "prop-types": "^15.6.1", + "simplebar": "^5.3.9" + }, + "peerDependencies": { + "react": "^0.14.9 || ^15.3.0 || ^16.0.0-rc || ^16.0 || ^17.0 || ^18.0.0", + "react-dom": "^0.14.9 || ^15.3.0 || ^16.0.0-rc || ^16.0 || ^17.0 || ^18.0.0" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", + "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", + "dev": true, + "dependencies": { + "abab": "^2.0.5", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "dev": true + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "dev": true + }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "dev": true, + "dependencies": { + "escodegen": "^1.8.1" + } + }, + "node_modules/static-eval/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/static-eval/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/static-eval/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-eval/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-natural-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-loader": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz", + "integrity": "sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/stylehacks": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/sucrase": { + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", + "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true + }, + "node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/svgo/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/svgo/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/svgo/node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/svgo/node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/svgo/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/svgo/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/svgo/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/svgo/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/tailwindcss": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.5.tgz", + "integrity": "sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.19.1", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.24.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.24.0.tgz", + "integrity": "sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/throat": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==", + "dev": true + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "dev": true + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", + "dev": true + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", + "dev": true, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-vitals": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.0.tgz", + "integrity": "sha512-f5YnCHVG9Y6uLCePD4tY8bO/Ge15NPEQWtvm3tPzDKygloiqtb4SVqRHBcrIAqo2ztqX5XueqDn97zHF0LdT6w==", + "dev": true + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, + "engines": { + "node": ">=10.4" + } + }, + "node_modules/webpack": { + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", + "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-manifest-plugin": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", + "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", + "dev": true, + "dependencies": { + "tapable": "^2.0.0", + "webpack-sources": "^2.2.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "peerDependencies": { + "webpack": "^4.44.2 || ^5.47.0" + } + }, + "node_modules/webpack-manifest-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.19", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz", + "integrity": "sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw==" + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dev": true, + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-background-sync": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", + "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", + "dev": true, + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-build": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", + "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", + "dev": true, + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.6.0", + "workbox-broadcast-update": "6.6.0", + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-google-analytics": "6.6.0", + "workbox-navigation-preload": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-range-requests": "6.6.0", + "workbox-recipes": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0", + "workbox-streams": "6.6.0", + "workbox-sw": "6.6.0", + "workbox-window": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/workbox-build/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/workbox-build/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dev": true, + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workbox-build/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/workbox-build/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "node_modules/workbox-build/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/workbox-cacheable-response": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", + "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", + "deprecated": "workbox-background-sync@6.6.0", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", + "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==", + "dev": true + }, + "node_modules/workbox-expiration": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "dev": true, + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-google-analytics": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", + "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "dev": true, + "dependencies": { + "workbox-background-sync": "6.6.0", + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-precaching": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-range-requests": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-recipes": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", + "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", + "dev": true, + "dependencies": { + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-routing": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-strategies": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-streams": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "dev": true, + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" + } + }, + "node_modules/workbox-sw": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", + "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==", + "dev": true + }, + "node_modules/workbox-webpack-plugin": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", + "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "webpack": "^4.4.0 || ^5.9.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/workbox-window": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", + "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", + "dev": true, + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.6.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json index 0dc80f3b..f71f0331 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "chart.js": "^3.9.1", "classnames": "^2.3.2", "core-js": "^3.31.0", + "eslint": "^8.55.0", "prop-types": "^15.8.1", "react": "^18.2.0", "react-app-polyfill": "^3.0.0", diff --git a/src/App.js b/src/App.js index 7c248818..83cbd0ce 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,5 @@ import React, { Component, Suspense } from 'react' -import { HashRouter, Route, Routes } from 'react-router-dom' +import { BrowserRouter, Route, Routes } from 'react-router-dom' import './scss/style.scss' const loading = ( @@ -20,7 +20,7 @@ const Page500 = React.lazy(() => import('./views/pages/page500/Page500')) class App extends Component { render() { return ( - <HashRouter> + <BrowserRouter> <Suspense fallback={loading}> <Routes> <Route exact path="/login" name="Login Page" element={<Login />} /> @@ -30,7 +30,7 @@ class App extends Component { <Route path="*" name="Home" element={<DefaultLayout />} /> </Routes> </Suspense> - </HashRouter> + </BrowserRouter> ) } } diff --git a/src/_nav.js b/src/_nav.js index 8f3d730d..178931db 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -1,305 +1,82 @@ import React from 'react' import CIcon from '@coreui/icons-react' import { - cilBell, - cilCalculator, - cilChartPie, - cilCursor, - cilDescription, - cilDrop, - cilNotes, - cilPencil, - cilPuzzle, cilSpeedometer, - cilStar, + cilWallet, + cilMemory, + cilMagnifyingGlass, + cilMonitor, + cilCog } from '@coreui/icons' -import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react' +import { CNavGroup, CNavItem, CNavTitle, CNavLink } from '@coreui/react' const _nav = [ - { - component: CNavItem, - name: 'Dashboard', - to: '/dashboard', - icon: <CIcon icon={cilSpeedometer} customClassName="nav-icon" />, - badge: { - color: 'info', - text: 'NEW', - }, + { + component: CNavTitle, + name: "Account" }, { component: CNavTitle, - name: 'Theme', + name: 'Current Deployment', }, { component: CNavItem, - name: 'Colors', - to: '/theme/colors', - icon: <CIcon icon={cilDrop} customClassName="nav-icon" />, + name: 'Dashboard', + to: '/dashboard', + icon: <CIcon icon={cilSpeedometer} customClassName="nav-icon" />, }, { component: CNavItem, - name: 'Typography', - to: '/theme/typography', - icon: <CIcon icon={cilPencil} customClassName="nav-icon" />, - }, - { - component: CNavTitle, - name: 'Components', - }, - { - component: CNavGroup, - name: 'Base', - to: '/base', - icon: <CIcon icon={cilPuzzle} customClassName="nav-icon" />, - items: [ - { - component: CNavItem, - name: 'Accordion', - to: '/base/accordion', - }, - { - component: CNavItem, - name: 'Breadcrumb', - to: '/base/breadcrumbs', - }, - { - component: CNavItem, - name: 'Cards', - to: '/base/cards', - }, - { - component: CNavItem, - name: 'Carousel', - to: '/base/carousels', - }, - { - component: CNavItem, - name: 'Collapse', - to: '/base/collapses', - }, - { - component: CNavItem, - name: 'List group', - to: '/base/list-groups', - }, - { - component: CNavItem, - name: 'Navs & Tabs', - to: '/base/navs', - }, - { - component: CNavItem, - name: 'Pagination', - to: '/base/paginations', - }, - { - component: CNavItem, - name: 'Placeholders', - to: '/base/placeholders', - }, - { - component: CNavItem, - name: 'Popovers', - to: '/base/popovers', - }, - { - component: CNavItem, - name: 'Progress', - to: '/base/progress', - }, - { - component: CNavItem, - name: 'Spinners', - to: '/base/spinners', - }, - { - component: CNavItem, - name: 'Tables', - to: '/base/tables', - }, - { - component: CNavItem, - name: 'Tooltips', - to: '/base/tooltips', - }, - ], - }, - { - component: CNavGroup, - name: 'Buttons', - to: '/buttons', - icon: <CIcon icon={cilCursor} customClassName="nav-icon" />, - items: [ - { - component: CNavItem, - name: 'Buttons', - to: '/buttons/buttons', - }, - { - component: CNavItem, - name: 'Buttons groups', - to: '/buttons/button-groups', - }, - { - component: CNavItem, - name: 'Dropdowns', - to: '/buttons/dropdowns', - }, - ], - }, - { - component: CNavGroup, - name: 'Forms', - icon: <CIcon icon={cilNotes} customClassName="nav-icon" />, - items: [ - { - component: CNavItem, - name: 'Form Control', - to: '/forms/form-control', - }, - { - component: CNavItem, - name: 'Select', - to: '/forms/select', - }, - { - component: CNavItem, - name: 'Checks & Radios', - to: '/forms/checks-radios', - }, - { - component: CNavItem, - name: 'Range', - to: '/forms/range', - }, - { - component: CNavItem, - name: 'Input Group', - to: '/forms/input-group', - }, - { - component: CNavItem, - name: 'Floating Labels', - to: '/forms/floating-labels', - }, - { - component: CNavItem, - name: 'Layout', - to: '/forms/layout', - }, - { - component: CNavItem, - name: 'Validation', - to: '/forms/validation', - }, - ], + name: 'Coretime Credits', + to: '/coretime', + icon: <CIcon icon={cilWallet} customClassName="nav-icon" />, }, { component: CNavItem, - name: 'Charts', - to: '/charts', - icon: <CIcon icon={cilChartPie} customClassName="nav-icon" />, - }, - { - component: CNavGroup, - name: 'Icons', - icon: <CIcon icon={cilStar} customClassName="nav-icon" />, - items: [ - { - component: CNavItem, - name: 'CoreUI Free', - to: '/icons/coreui-icons', - badge: { - color: 'success', - text: 'NEW', - }, - }, - { - component: CNavItem, - name: 'CoreUI Flags', - to: '/icons/flags', - }, - { - component: CNavItem, - name: 'CoreUI Brands', - to: '/icons/brands', - }, - ], - }, - { - component: CNavGroup, - name: 'Notifications', - icon: <CIcon icon={cilBell} customClassName="nav-icon" />, - items: [ - { - component: CNavItem, - name: 'Alerts', - to: '/notifications/alerts', - }, - { - component: CNavItem, - name: 'Badges', - to: '/notifications/badges', - }, - { - component: CNavItem, - name: 'Modal', - to: '/notifications/modals', - }, - { - component: CNavItem, - name: 'Toasts', - to: '/notifications/toasts', - }, - ], + name: 'Runtime Upgrades', + to: '/runtime-upgrade', + icon: <CIcon icon={cilMemory} customClassName="nav-icon" />, }, { component: CNavItem, - name: 'Widgets', - to: '/widgets', - icon: <CIcon icon={cilCalculator} customClassName="nav-icon" />, - badge: { - color: 'info', - text: 'NEW', - }, - }, - { - component: CNavTitle, - name: 'Extras', + name: 'Explorer', + to: 'https://google.com', + icon: <CIcon icon={cilMagnifyingGlass} customClassName="nav-icon" />, }, { - component: CNavGroup, - name: 'Pages', - icon: <CIcon icon={cilStar} customClassName="nav-icon" />, - items: [ - { - component: CNavItem, - name: 'Login', - to: '/login', - }, - { - component: CNavItem, - name: 'Register', - to: '/register', - }, - { - component: CNavItem, - name: 'Error 404', - to: '/404', - }, - { - component: CNavItem, - name: 'Error 500', - to: '/500', - }, - ], - }, - { - component: CNavItem, - name: 'Docs', - href: 'https://coreui.io/react/docs/templates/installation/', - icon: <CIcon icon={cilDescription} customClassName="nav-icon" />, + component: CNavLink, + name: 'Grafana', + href: 'https://google.com', + icon: <CIcon icon={cilMonitor} customClassName="nav-icon" />, }, + // TODO -> There could be some logic here to show one or the other menu depending on if there's an active deployment + // { + // component: CNavTitle, + // name: 'New Deployment', + // }, + // { + // component: CNavGroup, + // name: 'Configuration', + // to: '/configure', + // icon: <CIcon icon={cilCog} customClassName="nav-icon" />, + // items: [ + // { + // component: CNavItem, + // name: 'Runtime', + // to: '/configure/runtime', + // }, + // { + // component: CNavItem, + // name: 'Collators', + // to: '/configure/collators', + // }, + // { + // component: CNavItem, + // name: 'Coretime', + // to: '/configure/coretime', + // }, + // ], + // }, ] export default _nav diff --git a/src/assets/brand/portico-logo-blue.svg b/src/assets/brand/portico-logo-blue.svg new file mode 100644 index 00000000..be39d48e --- /dev/null +++ b/src/assets/brand/portico-logo-blue.svg @@ -0,0 +1,527 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" + "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg version="1.0" xmlns="http://www.w3.org/2000/svg" + width="300.000000pt" height="293.000000pt" viewBox="0 0 300.000000 293.000000" + preserveAspectRatio="xMidYMid meet"> +<g transform="translate(0.000000,293.000000) scale(0.100000,-0.100000)" +fill="#303c54" stroke="none"> +<path d="M1425 2856 c-64 -39 -439 -253 -820 -468 -82 -47 -239 -133 -347 +-193 -195 -106 -198 -108 -198 -141 0 -28 4 -34 34 -44 19 -6 36 -19 38 -28 3 +-11 28 -23 71 -36 66 -18 67 -19 67 -52 0 -28 -5 -36 -25 -44 -22 -8 -25 -15 +-25 -58 0 -27 3 -83 6 -125 7 -72 8 -77 35 -86 22 -7 29 -16 29 -35 0 -15 5 +-26 10 -26 14 0 14 -347 0 -355 -6 -3 -10 -22 -10 -41 0 -36 -18 -49 -80 -60 +-44 -8 -51 -13 -48 -36 2 -19 9 -23 40 -23 21 0 38 3 38 8 0 4 4 6 9 2 5 -3 +12 -1 16 5 15 24 25 6 25 -45 0 -30 5 -55 10 -55 6 0 10 -78 10 -215 0 -126 +-4 -215 -9 -215 -17 0 -42 -32 -37 -47 4 -9 -1 -17 -14 -20 -16 -4 -20 -14 +-20 -44 0 -35 -2 -39 -26 -39 -26 0 -26 -2 -22 -45 l6 -45 -34 0 -34 0 0 -50 +0 -50 -45 0 -45 0 1 -65 2 -65 1468 0 1469 0 0 65 0 65 -45 0 -45 0 0 50 c0 +49 -1 50 -30 50 -29 0 -30 2 -30 45 0 41 -2 45 -25 45 -22 0 -25 4 -25 40 0 +29 -4 40 -15 40 -9 0 -15 9 -15 24 0 14 -8 31 -19 38 -17 12 -19 33 -26 220 +-6 189 -5 207 10 216 15 8 17 19 13 61 -4 45 -3 51 11 45 55 -23 93 -27 108 +-11 22 21 4 43 -42 51 -19 4 -35 11 -35 16 0 6 -3 9 -7 9 -26 -4 -33 4 -33 41 +0 29 -4 40 -15 40 -13 0 -15 26 -15 175 0 149 2 175 15 175 9 0 15 9 15 25 0 +17 8 29 24 36 16 8 26 23 31 46 3 19 4 37 1 40 -3 3 -1 14 5 25 6 12 8 45 3 +84 -5 56 -10 67 -30 76 -18 9 -24 19 -24 43 0 32 2 33 70 51 54 14 70 22 72 +38 2 13 14 23 36 28 31 8 33 12 30 45 -3 36 -4 37 -193 140 -254 140 -532 295 +-630 353 -122 72 -614 350 -617 349 -2 0 -34 -20 -73 -43z m249 -97 c88 -51 +274 -156 411 -234 320 -182 559 -315 708 -394 71 -38 117 -69 117 -78 0 -11 +-7 -14 -25 -9 -34 9 -432 220 -725 386 -509 288 -641 360 -655 360 -12 0 -160 +-81 -640 -350 -261 -146 -499 -276 -648 -353 -90 -46 -109 -53 -114 -40 -8 20 +5 30 157 110 129 68 279 152 650 363 118 67 287 163 375 212 88 50 169 97 180 +104 11 8 26 14 33 14 8 0 87 -41 176 -91z m76 -141 c232 -125 360 -198 360 +-205 0 -4 -512 255 -575 292 l-30 18 -192 -101 c-245 -129 -433 -223 -433 +-218 0 8 124 78 380 215 l243 130 31 -16 c17 -9 114 -61 216 -115z m7 -55 +c142 -71 339 -166 438 -212 507 -238 645 -309 645 -330 0 -12 -4 -21 -9 -21 +-4 0 -167 72 -362 161 -195 89 -426 194 -514 234 -88 40 -226 105 -306 144 +l-147 71 -183 -89 c-101 -49 -332 -157 -514 -239 -181 -83 -399 -182 -482 +-220 -151 -70 -153 -70 -153 -45 0 22 25 36 282 162 156 76 387 186 513 245 +177 83 396 192 532 265 1 0 118 -56 260 -126z m-95 -84 c214 -99 736 -335 +1048 -475 35 -16 58 -30 50 -32 -15 -2 -596 254 -1053 465 l-208 96 -152 -73 +c-84 -39 -255 -118 -382 -175 -126 -56 -331 -149 -455 -205 -261 -118 -270 +-122 -270 -111 0 5 125 65 278 134 152 69 376 171 497 226 121 54 276 126 345 +159 69 34 130 61 137 61 6 1 80 -31 165 -70z m-176 -85 c-3 -8 -11 -14 -18 +-14 -18 0 -15 89 3 101 11 7 15 -1 17 -32 2 -23 1 -48 -2 -55z m64 36 c0 -27 +-4 -50 -10 -50 -5 0 -10 23 -10 50 0 28 5 50 10 50 6 0 10 -22 10 -50z m-120 +-25 c0 -25 -2 -45 -4 -45 -2 0 -11 -3 -20 -6 -13 -5 -16 2 -16 38 0 47 5 58 +27 58 9 0 13 -14 13 -45z m180 -6 c0 -31 -4 -48 -10 -44 -5 3 -10 26 -10 51 0 +24 5 44 10 44 6 0 10 -23 10 -51z m-262 -70 c-10 -6 -14 3 -16 38 -2 30 1 49 +10 54 10 6 14 -3 16 -38 2 -30 -1 -49 -10 -54z m322 45 c0 -24 -4 -44 -10 -44 +-5 0 -10 23 -10 51 0 31 4 48 10 44 6 -3 10 -26 10 -51z m-370 -24 c0 -38 -4 +-50 -15 -50 -11 0 -15 11 -15 43 0 24 3 47 7 50 16 17 23 3 23 -43z m432 -8 +c2 -26 0 -41 -7 -39 -5 2 -11 26 -13 53 -4 61 14 48 20 -14z m-492 -16 c0 -30 +-5 -46 -15 -50 -12 -4 -15 4 -15 38 0 23 3 46 7 49 15 16 23 4 23 -37z m558 +-10 c2 -36 0 -47 -10 -44 -8 3 -14 24 -16 52 -2 36 0 47 10 44 8 -3 14 -24 16 +-52z m-137 -27 c228 -99 819 -350 967 -411 109 -46 122 -53 122 -75 0 -20 -4 +-24 -17 -18 -10 4 -49 18 -88 32 -38 14 -155 63 -260 108 -104 46 -255 108 +-335 140 -80 31 -172 70 -205 85 -33 16 -123 55 -200 87 l-140 59 -152 -61 +c-83 -34 -157 -66 -165 -72 -7 -6 -121 -55 -253 -108 -132 -53 -244 -101 -250 +-105 -13 -10 -421 -180 -432 -180 -3 0 -3 12 -1 27 3 24 15 32 113 74 61 26 +254 108 430 183 425 180 685 293 692 300 4 3 7 6 8 6 1 0 76 -32 166 -71z +m-481 7 c0 -30 -5 -46 -15 -50 -12 -4 -15 4 -15 38 0 23 3 46 7 49 15 16 23 4 +23 -37z m678 -9 c3 -39 0 -46 -12 -41 -11 4 -16 20 -16 51 0 61 24 52 28 -10z +m-740 -19 c-4 -59 -28 -63 -28 -4 0 35 4 46 16 46 12 0 14 -9 12 -42z m802 -4 +c0 -59 -24 -55 -28 4 -2 33 0 42 12 42 12 0 16 -11 16 -46z m60 -31 c0 -61 +-24 -52 -28 10 -3 39 0 46 12 41 11 -4 16 -20 16 -51z m-920 8 c0 -25 -5 -41 +-15 -45 -12 -4 -15 4 -15 39 0 33 4 45 15 45 11 0 15 -11 15 -39z m-62 -23 +c-4 -55 -28 -64 -28 -10 0 21 3 42 7 45 16 17 24 4 21 -35z m638 -8 c76 -27 +139 -50 141 -50 2 0 3 -16 3 -36 0 -21 -4 -33 -10 -29 -5 3 -10 15 -10 26 0 +14 -13 25 -46 39 -79 34 -90 35 -120 5 -23 -23 -26 -32 -21 -68 3 -23 11 -43 +16 -45 6 -2 8 -9 5 -14 -4 -6 -2 -8 3 -5 6 4 16 0 23 -8 15 -18 71 -20 88 -3 +20 20 14 67 -13 93 -30 30 -61 32 -75 4 -15 -26 11 -69 41 -69 28 0 22 43 -6 +48 -20 4 -20 3 -1 -11 11 -8 15 -17 9 -20 -16 -10 -44 26 -33 43 13 21 58 -3 +66 -34 8 -32 -1 -46 -31 -46 -27 0 -75 51 -75 80 0 24 26 50 51 50 80 0 141 +-118 89 -170 -38 -38 -135 -13 -165 44 -22 40 -14 117 15 146 19 19 19 20 -27 +40 -25 11 -47 19 -47 18 -1 -2 1 -59 4 -128 l5 -124 98 -34 c53 -19 97 -39 97 +-43 0 -14 -13 -11 -114 25 l-96 34 -91 -34 c-95 -35 -119 -40 -119 -25 0 5 43 +24 95 42 l95 32 0 124 c0 67 -4 123 -9 123 -17 0 -76 -29 -60 -30 24 0 48 -32 +55 -71 4 -26 3 -30 -5 -19 -9 12 -11 11 -11 -8 0 -13 -7 -36 -15 -52 -9 -17 +-15 -32 -14 -36 0 -3 -3 -9 -7 -12 -4 -4 -4 0 0 8 5 9 2 8 -7 -2 -8 -10 -16 +-15 -19 -13 -3 3 -11 -1 -18 -10 -17 -20 -79 -19 -102 2 -29 26 -24 96 10 133 +35 39 98 52 118 25 20 -28 17 -50 -12 -85 -20 -23 -34 -30 -53 -28 -34 4 -41 +46 -12 72 22 20 51 15 51 -7 0 -20 -26 -41 -35 -27 -3 5 -1 10 4 10 6 0 11 5 +11 10 0 16 -17 11 -24 -7 -10 -24 8 -37 33 -24 26 14 28 57 3 70 -32 17 -81 +-24 -82 -69 0 -33 17 -50 50 -50 58 0 110 73 89 127 -19 50 -47 54 -133 22 +-44 -17 -55 -26 -53 -42 1 -11 -4 -22 -11 -24 -10 -4 -13 4 -10 28 3 32 6 34 +133 85 72 29 135 53 141 53 7 1 74 -21 150 -49z m402 2 c2 -33 0 -42 -12 -42 +-12 0 -16 11 -16 46 0 59 24 55 28 -4z m-1110 -63 c-10 -6 -14 2 -16 33 -2 26 +1 44 10 49 10 6 14 -2 16 -33 2 -26 -1 -44 -10 -49z m1162 35 c0 -27 -4 -43 +-10 -39 -5 3 -10 24 -10 46 0 21 5 39 10 39 6 0 10 -21 10 -46z m-1210 -19 c0 +-33 -4 -45 -15 -45 -11 0 -15 11 -15 38 0 21 3 42 7 45 16 16 23 4 23 -38z +m1270 -6 c0 -21 -4 -39 -10 -39 -5 0 -10 21 -10 46 0 27 4 43 10 39 6 -3 10 +-24 10 -46z m-1326 -15 c-1 -19 -6 -40 -13 -47 -8 -8 -11 1 -11 36 0 31 4 47 +13 47 7 0 12 -13 11 -36z m1376 -4 c0 -22 -4 -40 -10 -40 -5 0 -10 18 -10 40 +0 22 5 40 10 40 6 0 10 -18 10 -40z m-1432 -22 c-4 -55 -28 -64 -28 -10 0 21 +3 42 7 45 16 17 24 4 21 -35z m1482 2 c0 -22 -4 -40 -10 -40 -5 0 -10 18 -10 +40 0 22 5 40 10 40 6 0 10 -18 10 -40z m57 -30 c0 -25 -4 -39 -11 -37 -13 4 +-20 51 -12 73 10 27 23 6 23 -36z m-1587 0 c0 -29 -4 -40 -15 -40 -11 0 -15 +11 -15 40 0 29 4 40 15 40 11 0 15 -11 15 -40z m468 18 c-3 -7 -59 -35 -126 +-63 l-122 -49 0 -112 0 -113 55 -20 c30 -11 66 -23 80 -27 25 -6 35 -24 14 +-24 -6 0 -43 11 -82 25 l-70 26 -64 -26 c-65 -26 -93 -31 -93 -17 0 4 31 18 +70 31 l69 24 3 125 3 126 125 52 c138 58 143 59 138 42z m718 -24 c49 -20 106 +-45 127 -55 l38 -20 -7 -118 -7 -118 79 -28 c43 -16 83 -32 89 -37 17 -15 -20 +-8 -95 17 l-73 25 -61 -24 c-76 -30 -91 -33 -93 -21 -1 6 30 21 68 34 l69 25 +0 121 0 121 -112 46 c-62 25 -114 51 -116 57 -5 15 -7 16 94 -25z m454 -15 c0 +-21 -4 -39 -10 -39 -5 0 -10 21 -10 46 0 27 4 43 10 39 6 -3 10 -24 10 -46z +m-1690 1 c0 -29 -4 -40 -15 -40 -10 0 -15 10 -15 33 0 19 3 37 7 40 15 16 23 +5 23 -33z m-50 -19 c0 -25 -5 -41 -15 -45 -12 -4 -15 3 -15 33 0 21 3 41 7 44 +15 16 23 5 23 -32z m1790 -2 c0 -28 -4 -39 -12 -37 -17 6 -17 78 0 78 7 0 12 +-15 12 -41z m-477 -42 l22 -15 -30 -8 c-16 -4 -50 -15 -73 -26 -43 -18 -44 +-18 -68 1 -13 10 -21 20 -19 23 3 2 7 22 11 44 3 21 8 42 10 46 5 7 107 -38 +147 -65z m-1363 24 c0 -16 -7 -34 -15 -41 -13 -11 -15 -7 -15 27 0 22 3 43 6 +46 12 12 24 -4 24 -32z m633 32 c3 -5 8 -29 12 -55 6 -40 4 -48 -14 -57 -15 +-9 -29 -8 -58 4 -68 26 -117 33 -131 18 -7 -7 -18 -13 -25 -13 -17 1 34 39 53 +40 8 1 44 16 80 35 72 37 77 38 83 28z m1255 -37 c2 -28 0 -37 -10 -34 -7 3 +-14 22 -16 42 -2 28 0 37 10 34 7 -3 14 -22 16 -42z m52 -22 c0 -21 -4 -34 +-11 -32 -6 2 -10 7 -10 11 1 4 1 21 1 38 0 17 4 28 10 24 6 -3 10 -22 10 -41z +m-1990 2 c0 -21 -6 -36 -15 -40 -12 -4 -15 3 -15 34 0 29 4 40 15 40 10 0 15 +-10 15 -34z m400 14 c0 -6 -18 -19 -41 -29 -40 -18 -40 -19 -14 -25 60 -15 54 +-119 -12 -176 -39 -35 -75 -38 -103 -10 -47 47 0 150 69 150 45 0 69 -63 34 +-91 -10 -9 -14 -9 -10 -2 11 17 -2 61 -20 67 -37 14 -73 -37 -58 -83 9 -30 59 +-28 90 4 46 45 23 125 -36 125 -37 0 -89 -26 -89 -45 0 -7 -4 -17 -10 -20 -6 +-4 -10 6 -10 23 0 27 6 32 103 75 56 25 103 46 105 46 1 1 2 -4 2 -9z m1325 +-58 c22 -8 43 -20 47 -26 11 -16 10 -56 -2 -56 -5 0 -10 11 -10 24 0 19 -9 27 +-40 40 -54 21 -67 20 -95 -9 -28 -27 -32 -70 -10 -101 8 -12 12 -24 9 -26 -2 +-3 3 -11 13 -19 14 -12 16 -12 8 0 -6 11 -3 13 17 8 55 -14 82 53 39 96 -28 +28 -55 13 -59 -32 -4 -40 -22 -30 -22 13 0 91 114 64 127 -30 4 -34 1 -46 -17 +-64 -47 -47 -150 1 -150 71 0 40 23 93 49 111 21 15 20 16 -24 32 -25 10 -43 +22 -40 27 3 4 31 -3 63 -17 31 -14 75 -33 97 -42z m315 22 c0 -19 -4 -34 -10 +-34 -5 0 -10 18 -10 41 0 24 4 38 10 34 6 -3 10 -22 10 -41z m-2092 -1 c-4 +-48 -28 -57 -28 -10 0 18 3 37 7 40 16 16 24 4 21 -30z m-50 -20 c-4 -48 -28 +-57 -28 -10 0 18 3 37 7 40 16 16 24 4 21 -30z m2192 2 c0 -24 -5 -35 -15 -35 +-10 0 -15 11 -15 35 0 24 5 35 15 35 10 0 15 -11 15 -35z m-2240 -19 c0 -19 +-4 -38 -10 -41 -6 -4 -10 10 -10 34 0 23 5 41 10 41 6 0 10 -15 10 -34z m2285 +-4 c0 -46 -19 -44 -23 2 -3 28 0 37 10 34 7 -3 13 -19 13 -36z m-2333 -55 c-2 +-4 -8 -5 -13 -2 -11 7 -12 58 -1 69 7 8 21 -53 14 -67z m2378 32 c0 -24 -4 +-38 -10 -34 -5 3 -10 22 -10 41 0 19 5 34 10 34 6 0 10 -18 10 -41z m-1580 12 +c36 -15 46 -24 51 -50 8 -37 -6 -42 -15 -6 -7 26 -59 55 -99 55 -30 0 -57 -29 +-57 -62 0 -60 94 -106 120 -58 15 29 -13 80 -44 80 -29 0 -48 -22 -39 -45 4 +-13 3 -16 -5 -11 -16 9 -15 49 0 64 33 33 101 -7 112 -66 10 -60 -38 -86 -111 +-60 -57 21 -70 111 -23 158 24 24 51 24 110 1z m145 -39 c3 -7 5 -118 6 -245 +1 -358 1 -357 -16 -357 -8 0 -15 7 -15 16 0 8 -5 12 -11 9 -6 -4 -8 -13 -5 +-20 3 -8 -3 -17 -14 -20 -11 -3 -30 -19 -44 -36 -30 -36 -46 -37 -46 -4 0 14 +-4 25 -10 25 -6 0 -10 59 -10 157 0 121 3 154 12 145 7 -7 13 -54 15 -119 2 +-60 6 -113 8 -120 2 -7 17 -11 32 -10 28 2 28 4 28 67 0 138 -9 177 -56 232 +-37 44 -40 52 -26 60 10 5 17 20 17 34 0 16 8 28 24 35 33 15 46 49 46 119 0 +54 2 60 28 72 25 12 27 12 30 -7 2 -11 5 -26 7 -33z m500 42 c21 -14 25 -24 +25 -69 0 -70 13 -102 50 -123 22 -12 30 -24 30 -44 0 -18 5 -28 15 -28 23 0 +18 -25 -9 -39 -13 -8 -36 -35 -50 -61 -22 -40 -26 -59 -24 -122 1 -41 -1 -79 +-4 -84 -10 -17 8 -47 31 -49 32 -2 39 19 37 120 -1 64 2 99 14 120 14 28 15 +22 18 -129 2 -131 0 -161 -12 -168 -8 -5 -12 -16 -9 -28 8 -29 -14 -25 -43 9 +-14 17 -33 32 -42 35 -15 5 -17 20 -17 111 1 71 -3 105 -10 105 -8 0 -11 -32 +-10 -100 1 -86 -2 -100 -15 -98 -13 3 -15 38 -18 258 -3 234 3 400 14 400 3 0 +16 -7 29 -16z m249 -6 c19 -26 21 -58 5 -58 -7 0 -9 -11 -6 -30 6 -28 -4 -44 +-28 -45 -5 -1 -9 -5 -8 -11 1 -5 -6 -10 -15 -11 -9 -1 -31 -5 -48 -8 -67 -14 +-90 71 -33 120 41 34 92 32 97 -3 2 -13 0 -31 -4 -40 -6 -13 -8 -10 -13 13 -8 +39 -45 41 -73 5 -23 -31 -15 -58 18 -66 69 -18 125 93 63 126 -32 17 -117 -14 +-131 -49 -9 -21 -12 -23 -15 -8 -9 35 3 51 52 68 72 25 120 24 139 -3z m-514 +-54 c0 -32 2 -35 22 -29 17 6 20 4 15 -10 -4 -9 -7 -95 -7 -190 0 -159 -1 +-174 -17 -173 -10 0 -26 -3 -35 -7 -17 -7 -18 7 -18 213 0 219 1 228 33 231 4 +1 7 -15 7 -35z m950 -19 c47 -20 94 -38 105 -40 31 -4 199 -65 209 -76 15 -14 +-9 -11 -51 6 -19 8 -44 15 -54 15 -27 0 -49 -28 -49 -64 0 -27 6 -36 34 -51 +55 -30 94 2 61 51 -21 32 -57 29 -65 -6 -5 -22 -7 -23 -13 -7 -17 46 35 73 80 +42 42 -30 36 -109 -9 -120 -29 -7 -93 19 -102 40 -14 38 0 99 28 117 6 4 -2 +11 -18 18 -16 6 -33 13 -37 16 -5 3 -9 -39 -9 -94 l0 -99 63 -18 c75 -22 79 +-24 72 -35 -3 -5 -36 2 -73 14 l-69 24 -74 -24 c-85 -27 -92 -28 -87 -13 2 6 +35 21 73 33 l70 22 3 95 3 95 -108 45 c-58 25 -108 50 -111 57 -4 14 1 12 128 +-43z m-1770 38 c0 -8 -194 -93 -211 -93 -6 0 -9 -40 -7 -97 l3 -96 73 -25 c39 +-13 72 -28 72 -33 0 -11 7 -13 -81 15 -75 22 -78 23 -122 6 -65 -25 -97 -32 +-97 -21 0 5 29 20 65 33 l65 23 0 92 c0 51 -3 93 -7 93 -5 0 -18 -3 -29 -6 +-21 -6 -21 -6 2 -29 24 -25 32 -55 14 -55 -5 0 -10 -11 -10 -23 0 -45 -79 -89 +-119 -67 -29 15 -29 76 1 107 41 44 107 20 88 -32 -6 -17 -7 -16 -14 8 -8 32 +-35 36 -60 8 -37 -41 3 -88 51 -61 39 22 51 61 29 94 -20 31 -40 32 -100 6 +-32 -13 -46 -16 -46 -7 0 13 127 63 195 76 22 5 81 27 130 49 91 41 115 48 +115 35z m154 -19 c8 -22 -11 -54 -33 -54 -24 0 -34 26 -21 51 13 23 46 25 54 +3z m606 -204 c0 -213 -1 -220 -20 -220 -19 0 -20 7 -20 198 0 208 4 242 26 +242 12 0 14 -39 14 -220z m782 195 c8 -19 8 -29 0 -37 -23 -23 -61 14 -48 47 +9 23 35 18 48 -10z m-1127 -5 c17 -18 17 -22 4 -36 -20 -20 -49 -8 -49 20 0 +40 18 46 45 16z m283 -421 c-10 -7 -14 36 -16 208 -2 167 1 218 10 224 10 7 +14 -36 16 -208 2 -167 -1 -218 -10 -224z m206 243 c-2 -235 -1 -232 -14 -232 +-6 0 -10 78 -10 215 0 165 3 215 13 215 9 0 12 -46 11 -198z m363 172 c7 -20 +-22 -45 -43 -37 -17 6 -18 25 -2 41 17 17 38 15 45 -4z m-607 -208 c0 -181 -2 +-215 -15 -220 -13 -5 -15 23 -15 214 0 189 2 220 15 220 13 0 15 -30 15 -214z +m340 -1 c0 -137 -4 -215 -10 -215 -6 0 -10 78 -10 215 0 137 4 215 10 215 6 0 +10 -78 10 -215z m718 166 c5 -14 -74 -52 -93 -45 -12 5 -14 15 -9 43 4 20 8 +39 11 43 5 9 87 -28 91 -41z m-1700 -10 c4 -48 4 -48 -77 -14 l-35 15 39 24 +c54 33 69 28 73 -25z m-75 -47 c26 -9 47 -21 47 -27 0 -7 3 -23 7 -36 4 -17 3 +-22 -5 -17 -7 4 -12 16 -12 26 0 21 -55 50 -96 50 -29 0 -54 -25 -54 -55 0 +-54 87 -89 110 -45 9 17 6 25 -14 45 -30 30 -56 24 -56 -13 0 -19 -3 -23 -11 +-15 -6 6 -9 21 -7 34 2 19 10 25 35 27 42 4 73 -26 73 -72 0 -46 -20 -60 -74 +-52 -68 11 -94 63 -61 126 23 44 46 49 118 24z m1873 8 c26 -17 34 -49 19 -78 +-8 -15 -12 -31 -10 -34 3 -4 -5 -16 -17 -26 -14 -12 -18 -14 -13 -4 6 11 3 10 +-12 -2 -64 -57 -138 23 -80 86 28 31 58 40 81 23 15 -11 17 -20 11 -43 l-9 +-29 -4 27 c-4 33 -23 41 -51 22 -25 -18 -28 -62 -5 -71 25 -10 67 10 83 38 13 +24 13 29 -3 54 -15 23 -23 26 -49 22 -58 -10 -87 -25 -87 -47 0 -11 -5 -20 +-11 -20 -6 0 -9 12 -7 27 2 22 12 31 48 45 48 18 98 23 116 10z m-1746 -49 c0 +-14 7 -31 16 -37 11 -9 14 -26 12 -69 l-3 -58 -35 37 c-19 20 -29 34 -22 30 6 +-4 12 -2 12 3 0 6 -4 11 -10 11 -5 0 -10 5 -10 11 0 5 5 7 10 4 15 -9 12 4 -5 +21 -18 19 -20 71 -2 77 22 8 37 -5 37 -30z m1555 -20 c-2 -21 -4 -47 -4 -58 +-1 -14 -4 -16 -9 -7 -5 7 -7 33 -5 57 3 29 0 45 -7 45 -7 0 -10 -22 -9 -65 2 +-51 -2 -69 -16 -85 -10 -11 -22 -20 -27 -20 -15 0 -9 107 7 120 8 7 15 23 15 +35 0 27 17 36 41 24 12 -6 16 -19 14 -46z m-1951 1 c7 -19 -10 -44 -29 -44 +-20 0 -26 28 -9 45 20 19 30 19 38 -1z m2334 4 c16 -16 15 -48 -2 -48 -20 0 +-39 27 -32 45 7 18 18 19 34 3z m-2088 -13 c15 -18 5 -35 -21 -35 -14 0 -19 7 +-19 25 0 28 21 33 40 10z m356 -41 c12 5 14 -20 14 -165 0 -132 -3 -170 -12 +-166 -7 2 -23 0 -35 -4 l-23 -9 0 194 c0 147 3 195 13 199 7 2 15 -9 20 -25 5 +-20 13 -28 23 -24z m1096 23 c2 -18 8 -27 20 -27 17 0 18 -13 18 -167 l0 -168 +-35 -1 -35 -1 0 193 c0 145 3 193 13 197 16 6 17 5 19 -26z m398 13 c0 -23 +-26 -38 -41 -23 -14 14 0 43 22 43 12 0 19 -7 19 -20z m-1563 -192 c-2 -180 +-3 -193 -21 -196 -14 -3 -17 0 -12 13 3 9 6 97 6 196 0 149 2 179 14 179 13 0 +15 -31 13 -192z m123 2 c0 -145 -3 -190 -12 -190 -10 0 -12 43 -10 190 2 112 +7 190 12 190 6 0 10 -76 10 -190z m997 -2 c-2 -165 -4 -193 -18 -196 -13 -2 +-15 20 -17 172 -3 168 3 216 28 216 5 0 8 -82 7 -192z m121 2 c-2 -118 -7 +-190 -13 -190 -6 0 -11 72 -13 190 -2 166 0 190 13 190 13 0 15 -24 13 -190z +m-1288 -15 c0 -167 -2 -195 -15 -195 -13 0 -15 28 -15 188 0 104 3 192 7 195 +19 20 23 -10 23 -188z m230 -6 c0 -144 -3 -189 -12 -189 -10 0 -12 44 -10 195 +2 122 6 193 12 190 6 -4 10 -86 10 -196z m890 6 c0 -167 -2 -195 -15 -195 -13 +0 -15 28 -15 189 0 182 1 192 28 200 1 1 2 -87 2 -194z m230 -6 c0 -114 -4 +-189 -10 -189 -9 0 -20 377 -11 386 16 15 21 -32 21 -197z m92 99 c-28 -29 +-54 -49 -59 -44 -4 5 -2 11 6 14 8 2 32 24 54 48 22 24 43 42 45 39 3 -2 -18 +-28 -46 -57z m-1523 -25 c14 -13 21 -23 15 -23 -14 0 -94 80 -94 94 0 6 12 -2 +27 -19 14 -16 38 -40 52 -52z m1114 40 c-26 -34 -28 -43 -29 -142 -1 -58 -6 +-107 -11 -108 -7 -3 -9 77 -4 193 1 19 9 32 51 82 24 28 19 9 -7 -25z m-1200 +-18 c-4 -11 -1 -13 11 -9 12 5 19 1 22 -12 3 -11 20 -26 37 -35 l32 -16 3 +-116 c2 -71 -1 -117 -7 -117 -5 0 -11 -19 -13 -42 -2 -29 -8 -44 -18 -46 -13 +-2 -15 9 -13 68 2 52 -1 70 -9 68 -8 -3 -12 -30 -13 -75 0 -66 -2 -72 -31 -97 +-18 -14 -36 -26 -42 -26 -16 0 -22 66 -22 241 0 142 2 168 16 173 10 4 13 13 +9 25 -4 13 0 23 12 29 22 13 34 6 26 -13z m1685 13 c7 -7 12 -20 12 -31 0 -10 +7 -25 15 -33 12 -13 15 -48 15 -185 0 -106 -4 -169 -10 -169 -5 0 -10 -11 -10 +-25 0 -14 -4 -25 -9 -25 -4 0 -20 11 -35 25 -15 14 -31 25 -37 25 -5 0 -9 7 +-9 15 0 18 -17 20 -22 3 -9 -25 -28 5 -28 43 0 21 -4 39 -10 39 -6 0 -10 46 +-10 118 l0 118 34 14 c19 7 37 22 40 32 3 15 10 18 25 13 12 -4 21 -2 21 4 0 +6 -5 11 -11 11 -5 0 -7 5 -4 10 8 13 18 13 33 -2z m-1195 -50 c3 -18 6 -62 6 +-98 1 -36 4 -73 7 -84 4 -13 2 -17 -7 -14 -10 3 -15 28 -16 84 -2 43 -4 94 -6 +112 -2 17 0 32 4 32 4 0 9 -15 12 -32z m-713 -3 c0 -9 7 -18 15 -21 12 -5 15 +-32 15 -153 l0 -146 -24 -1 -25 -2 -3 162 c-2 88 -2 164 0 169 6 13 22 7 22 +-8z m2090 -11 c0 -19 4 -25 15 -20 13 5 15 -15 15 -142 l0 -147 -25 -1 -25 -2 +-2 122 c-1 66 -3 142 -3 169 -1 32 3 47 12 47 7 0 13 -11 13 -26z m-2130 -154 +c0 -144 -2 -170 -15 -170 -13 0 -15 25 -15 163 0 90 3 167 7 170 19 20 23 -8 +23 -163z m110 0 c0 -107 -4 -170 -10 -170 -6 0 -10 63 -10 170 0 107 4 170 10 +170 6 0 10 -63 10 -170z m1980 0 c0 -144 -2 -170 -15 -170 -13 0 -15 26 -15 +170 0 144 2 170 15 170 13 0 15 -26 15 -170z m101 157 c-1 -4 -1 -79 -1 -168 +0 -108 -3 -158 -10 -154 -14 9 -12 337 2 333 5 -2 9 -7 9 -11z m-2231 -167 c0 +-144 -2 -170 -15 -170 -13 0 -15 25 -15 164 0 157 2 167 28 175 1 1 2 -75 2 +-169z m210 -5 c0 -103 -4 -165 -10 -165 -6 0 -10 62 -10 165 0 103 4 165 10 +165 6 0 10 -62 10 -165z m1880 0 c0 -140 -2 -165 -15 -165 -13 0 -15 25 -15 +165 0 140 2 165 15 165 13 0 15 -25 15 -165z m200 0 c0 -103 -4 -165 -10 -165 +-6 0 -10 62 -10 165 0 103 4 165 10 165 6 0 10 -62 10 -165z m-1057 69 l92 +-25 0 -45 c0 -28 -4 -44 -12 -44 -8 0 -13 14 -13 34 0 33 -8 42 -52 52 -5 1 +-11 3 -15 4 -16 5 -29 7 -51 8 -13 1 -20 7 -17 12 3 6 4 10 1 10 -2 0 -11 3 +-20 6 -14 5 -16 -9 -16 -124 l0 -130 33 -5 c71 -10 153 -30 162 -39 11 -11 +-14 -7 -131 19 -68 15 -77 15 -168 -4 l-96 -20 0 52 c0 39 4 52 15 52 10 0 15 +-11 15 -32 l0 -32 75 15 75 15 0 104 c0 96 -1 105 -17 98 -10 -4 -36 -11 -58 +-16 -66 -13 -75 -19 -75 -50 0 -20 -5 -29 -16 -29 -12 0 -14 10 -12 47 l3 47 +85 22 c110 28 105 28 213 -2z m-143 -123 l0 -79 -50 -11 c-28 -6 -55 -11 -60 +-11 -4 0 -7 24 -5 53 2 28 4 64 4 78 1 25 14 31 104 48 4 0 7 -35 7 -78z m170 +59 c23 -6 25 -11 28 -80 2 -51 6 -70 12 -60 8 13 10 12 10 -2 0 -11 -8 -18 +-20 -18 -11 0 -20 3 -20 8 0 4 -16 8 -36 10 -20 1 -40 5 -45 8 -5 3 -9 39 -9 +80 l0 74 28 -6 c15 -4 38 -10 52 -14z m-537 -126 c-3 -10 -17 -8 -61 7 -31 11 +-61 24 -66 29 -22 22 -26 6 -26 -94 0 -71 4 -107 13 -114 6 -5 35 -13 62 -17 +55 -7 97 -25 60 -25 -11 0 -46 6 -78 14 -39 9 -72 11 -105 5 -26 -5 -62 -11 +-79 -14 l-33 -6 0 56 c0 30 5 55 10 55 10 0 15 -29 10 -59 -1 -11 9 -12 51 -7 +29 4 56 9 61 12 4 3 8 46 8 96 0 82 -2 89 -17 83 -10 -4 -37 -12 -61 -17 -36 +-8 -42 -13 -37 -29 4 -13 2 -19 -9 -19 -12 0 -16 10 -16 35 0 27 4 35 18 35 9 +0 44 8 77 18 59 18 60 18 141 -7 56 -16 81 -28 77 -37z m237 46 c0 -5 -8 -10 +-17 -11 -10 0 -26 -2 -35 -4 -10 -2 -18 1 -18 5 0 5 12 11 28 13 15 2 30 5 35 +6 4 0 7 -3 7 -9z m417 -5 c33 -10 58 -25 73 -45 13 -17 37 -34 53 -38 17 -4 +32 -13 35 -20 6 -20 -60 8 -85 35 -12 14 -23 29 -25 34 -2 6 -31 15 -66 22 +-34 6 -62 15 -62 19 0 12 20 10 77 -7z m403 -4 c57 -16 65 -21 68 -44 2 -16 +-2 -27 -9 -27 -6 0 -9 8 -6 19 3 14 1 18 -9 14 -8 -3 -14 0 -14 7 0 7 -7 10 +-15 7 -8 -4 -17 -2 -20 4 -4 5 -12 8 -18 7 -7 -1 -23 4 -35 11 -13 7 -24 11 +-25 9 -1 -2 -1 -53 1 -114 l3 -112 50 -6 c53 -7 105 -24 97 -31 -2 -2 -39 4 +-82 14 -70 17 -84 17 -149 5 -40 -8 -75 -14 -79 -14 -5 0 -8 27 -8 60 0 33 4 +60 10 60 6 0 10 -21 10 -46 0 -35 3 -45 14 -41 7 3 34 9 60 12 l46 7 0 93 0 +93 -60 -15 c-37 -10 -60 -21 -60 -29 0 -8 -5 -14 -11 -14 -6 0 -9 12 -7 27 3 +24 10 29 68 44 84 22 102 22 180 0z m-900 -11 c0 -5 -6 -10 -14 -10 -7 0 -25 +-9 -40 -21 -14 -11 -26 -16 -26 -10 0 6 5 11 10 11 6 0 10 6 10 14 0 13 16 22 +48 25 6 0 12 -3 12 -9z m20 -410 l-5 -255 -22 -3 c-19 -3 -23 -10 -23 -42 0 +-30 -5 -40 -20 -45 -11 -3 -20 -13 -20 -21 0 -8 -7 -14 -15 -14 -9 0 -15 9 +-15 25 0 18 -7 26 -25 31 l-25 6 0 229 c0 146 4 229 10 229 6 0 10 33 10 79 0 +75 1 79 25 85 13 3 36 22 51 41 14 19 29 33 33 31 4 -3 13 -1 21 4 22 13 26 +-73 20 -380z m492 378 c12 -7 35 -28 51 -45 16 -18 38 -33 48 -33 17 0 19 -8 +19 -80 0 -47 4 -80 10 -80 6 0 10 -83 10 -230 0 -222 -1 -230 -20 -230 -21 0 +-40 -27 -33 -47 3 -8 -4 -13 -17 -13 -12 0 -18 4 -15 10 3 5 -3 15 -15 22 -14 +9 -20 23 -20 49 0 32 -3 37 -30 42 l-29 6 -3 253 c-4 298 -1 388 13 388 5 0 +19 -6 31 -12z m-862 -68 c0 -60 -3 -70 -17 -70 -10 0 -28 -3 -41 -6 -23 -6 +-23 -5 -20 62 3 63 5 69 28 75 49 14 50 13 50 -61z m155 48 c15 -6 10 -7 -17 +-5 l-38 3 0 -42 c0 -37 3 -42 25 -46 14 -3 25 -1 25 3 0 5 7 9 15 9 9 0 15 +-10 15 -26 0 -23 -3 -25 -26 -20 -15 4 -38 9 -53 12 -25 5 -26 7 -23 70 4 64 +4 64 30 57 15 -3 36 -10 47 -15z m965 -48 c0 -38 -4 -70 -9 -70 -5 0 -23 -3 +-40 -6 -28 -6 -31 -4 -31 20 0 26 15 36 22 15 2 -5 11 -7 21 -4 12 5 17 18 17 +45 0 37 -1 39 -37 42 l-38 4 35 11 c60 19 60 19 60 -57z m139 59 c30 -11 31 +-13 31 -70 0 -38 4 -59 12 -59 6 0 9 -3 5 -6 -3 -4 -25 1 -47 10 -23 9 -46 14 +-51 11 -5 -4 -9 21 -9 59 0 72 3 74 59 55z m-1615 -49 c37 -12 64 -25 61 -30 +-3 -5 -19 -4 -38 1 -17 6 -41 12 -51 14 -11 3 -24 9 -30 15 -21 21 -26 7 -26 +-84 0 -104 -4 -98 75 -112 45 -7 82 -23 55 -24 -8 0 -42 7 -75 14 -56 14 -118 +10 -187 -10 -16 -5 -18 4 -18 99 l0 105 58 15 c78 21 100 20 176 -3z m576 9 +c-14 -6 -33 -12 -43 -14 -10 -2 -27 -7 -38 -10 -10 -4 -19 -2 -19 3 0 9 69 29 +105 30 16 1 15 -1 -5 -9z m1511 -5 c51 -14 56 -19 56 -42 0 -26 0 -26 -9 -5 +-7 13 -26 25 -53 32 -23 6 -50 13 -59 17 -14 5 -16 -5 -16 -89 l0 -96 58 -11 +c55 -12 100 -29 75 -30 -6 0 -40 7 -75 14 -54 13 -72 13 -128 1 -35 -7 -67 +-12 -71 -10 -3 2 -6 25 -7 50 -2 34 1 45 13 45 10 0 15 -10 15 -34 l0 -33 50 +10 50 10 0 79 c0 65 -3 79 -14 75 -8 -3 -31 -9 -50 -13 -22 -4 -36 -12 -36 +-21 0 -8 -6 -13 -12 -10 -7 2 -13 12 -13 23 0 15 13 23 60 36 77 21 96 21 166 +2z m-673 0 c27 -8 29 -23 2 -21 -11 1 -20 5 -20 10 0 4 -4 5 -10 2 -5 -3 -10 +-1 -10 4 0 12 6 13 38 5z m320 -18 c13 -3 34 -16 46 -29 15 -16 42 -28 84 -36 +72 -14 83 -26 17 -17 -53 8 -78 18 -124 51 -20 15 -48 25 -67 25 -19 0 -34 5 +-34 11 0 11 19 10 78 -5z m-1582 -34 c-9 -15 -70 -41 -112 -48 -22 -3 -42 -8 +-46 -11 -5 -2 -8 0 -8 6 0 11 19 18 75 27 22 3 51 14 65 24 25 19 37 19 26 2z +m1944 3 c23 -5 25 -11 25 -60 l0 -55 -35 6 c-50 9 -50 9 -50 70 0 48 2 55 18 +50 9 -3 28 -8 42 -11z m-2096 -1 c25 -10 19 -22 -9 -16 -22 4 -25 1 -25 -26 0 +-24 5 -31 26 -36 14 -4 34 -4 45 -1 15 5 19 1 19 -19 0 -31 -1 -31 -62 -9 +l-48 17 0 48 c0 50 11 58 54 42z m216 -64 c0 -40 4 -70 10 -70 6 0 10 -83 10 +-230 0 -215 -1 -230 -18 -230 -25 0 -42 -19 -42 -47 0 -14 -6 -23 -15 -23 -8 +0 -15 -6 -15 -14 0 -9 -7 -12 -21 -9 -11 3 -18 11 -15 19 3 7 -6 22 -19 33 +-25 19 -25 20 -25 197 0 99 3 223 7 276 6 94 7 97 32 103 14 3 42 19 61 35 19 +16 38 30 43 30 4 0 7 -31 7 -70z m758 4 c16 5 17 -12 14 -213 l-3 -218 -34 -1 +-35 -1 0 244 c0 224 1 244 18 247 13 3 18 -4 20 -30 3 -26 7 -32 20 -28z m766 +45 c20 -12 34 -25 31 -29 -3 -4 11 -11 30 -14 l35 -7 0 -64 c0 -37 4 -65 10 +-65 6 0 10 -78 10 -213 l0 -214 -25 -11 c-15 -7 -25 -20 -25 -32 0 -11 -5 -20 +-10 -20 -6 0 -15 -10 -20 -22 -8 -21 -9 -20 -9 10 -1 19 -6 32 -14 32 -7 0 +-17 15 -22 33 -7 22 -17 33 -32 35 l-23 3 0 230 c0 146 4 229 10 229 6 0 10 +30 10 70 0 39 2 70 4 70 3 0 21 -9 40 -21z m226 -33 c0 -40 -4 -55 -16 -60 +-28 -11 -54 -6 -54 9 0 9 9 15 25 15 22 0 25 4 25 35 0 33 -2 35 -25 29 -15 +-4 -25 -2 -25 4 0 11 20 19 53 21 14 1 17 -8 17 -53z m-1072 -451 c-2 -1 -20 +-5 -40 -9 l-38 -7 0 244 c0 208 2 246 15 251 13 5 15 -26 15 -236 0 -133 3 +-239 6 -236 3 4 6 110 7 237 2 194 4 233 17 241 13 8 15 -21 18 -237 1 -135 1 +-247 0 -248z m142 392 c0 -52 3 -162 7 -245 5 -137 5 -152 -10 -152 -15 0 -17 +24 -17 245 0 157 4 245 10 245 6 0 10 -38 10 -93z m-244 -404 c-3 -7 -10 -13 +-16 -13 -16 0 -14 487 3 493 9 3 13 -49 15 -232 1 -130 0 -241 -2 -248z m344 +232 c0 -157 -4 -245 -10 -245 -6 0 -10 88 -10 245 0 157 4 245 10 245 6 0 10 +-88 10 -245z m-1380 226 c0 -11 -94 -35 -112 -29 -7 3 14 11 47 20 33 8 61 16 +63 17 1 0 2 -3 2 -8z m2465 -8 c30 -9 55 -20 55 -24 0 -4 -26 1 -58 10 -31 10 +-63 16 -70 13 -6 -2 -12 1 -12 7 0 15 20 14 85 -6z m-1875 -287 c0 -190 -2 +-225 -15 -230 -13 -5 -15 24 -15 224 0 198 2 230 15 230 13 0 15 -32 15 -224z +m42 202 c2 -15 9 -22 21 -22 16 2 17 -14 17 -200 l0 -201 -35 -2 -35 -2 0 225 +c0 188 2 224 14 224 8 0 16 -10 18 -22z m1118 -3 c0 -18 5 -25 20 -25 19 0 20 +-7 20 -198 l0 -199 -35 -1 -35 -1 0 224 c0 193 2 225 15 225 9 0 15 -9 15 -25z +m-1210 -210 c0 -193 -2 -225 -15 -225 -13 0 -15 30 -15 209 0 115 3 216 6 225 +18 47 24 -5 24 -209z m170 5 c0 -134 -4 -220 -10 -220 -9 0 -20 427 -11 436 +17 17 21 -23 21 -216z m950 -5 c0 -193 -2 -225 -15 -225 -13 0 -15 31 -15 219 +0 212 1 222 28 230 1 1 2 -100 2 -224z m50 6 c0 -181 -2 -220 -14 -224 -8 -3 +-17 -3 -20 0 -8 8 -8 407 0 427 3 9 12 16 19 16 11 0 14 -44 15 -219z m117 -4 +c5 -196 4 -217 -11 -217 -14 0 -16 24 -16 221 0 156 3 220 11 217 7 -2 13 -77 +16 -221z m-1057 -7 c0 -140 -4 -220 -10 -220 -6 0 -10 80 -10 220 0 140 4 220 +10 220 6 0 10 -80 10 -220z m1120 0 c0 -134 -4 -220 -10 -220 -5 0 -10 88 -12 +220 -2 171 0 220 10 220 9 0 12 -51 12 -220z m-1738 155 c-3 -18 0 -25 12 -25 +14 0 16 -21 16 -184 0 -181 0 -184 -22 -189 -12 -4 -23 -5 -25 -4 -2 2 -5 386 +-3 420 0 4 6 7 14 7 9 0 12 -8 8 -25z m2088 0 c0 -16 6 -25 15 -25 13 0 15 +-27 15 -185 0 -194 2 -185 -41 -189 -8 -1 -11 55 -11 194 0 107 0 203 1 213 2 +27 21 20 21 -8z m-2130 -195 c0 -180 -2 -210 -15 -210 -13 0 -15 30 -15 210 0 +180 2 210 15 210 13 0 15 -30 15 -210z m110 0 c0 -133 -4 -210 -10 -210 -6 0 +-10 77 -10 210 0 133 4 210 10 210 6 0 10 -77 10 -210z m1980 0 c0 -180 -2 +-210 -15 -210 -13 0 -15 30 -15 210 0 180 2 210 15 210 13 0 15 -30 15 -210z +m100 16 c0 -107 3 -201 6 -210 4 -11 1 -16 -10 -16 -14 0 -16 24 -16 210 0 +133 4 210 10 210 6 0 10 -71 10 -194z m-2232 -23 c-2 -154 -6 -207 -15 -211 +-10 -3 -13 43 -13 207 0 182 2 211 15 211 13 0 15 -27 13 -207z m212 -3 c0 +-133 -4 -210 -10 -210 -6 0 -10 77 -10 210 0 133 4 210 10 210 6 0 10 -77 10 +-210z m1878 3 c-2 -154 -6 -207 -15 -211 -10 -3 -13 43 -13 207 0 182 2 211 +15 211 13 0 15 -27 13 -207z m202 -4 c0 -137 -3 -208 -10 -204 -6 4 -10 85 +-10 211 0 129 4 204 10 204 6 0 10 -77 10 -211z m-1043 -129 c110 -15 123 -18 +123 -36 0 -11 -8 -14 -32 -10 -18 3 -69 10 -113 16 -43 6 -83 16 -87 23 -6 9 +-8 8 -8 -4 0 -13 -22 -18 -112 -29 -133 -15 -133 -15 -133 8 0 31 216 51 362 +32z m-514 -75 c9 -4 17 -11 17 -17 0 -10 -90 -3 -147 12 -18 5 -33 5 -33 1 0 +-9 -180 -29 -186 -20 -7 12 21 28 61 32 53 7 265 0 288 -8z m522 -5 c154 -17 +155 -17 155 -51 0 -33 18 -33 -175 -8 -78 10 -164 7 -295 -11 -99 -14 -100 +-14 -100 20 0 17 1 30 3 31 12 5 286 36 297 33 8 -1 60 -8 115 -14z m544 10 +c100 -14 104 -34 6 -25 -44 4 -88 11 -97 16 -9 5 -18 5 -20 0 -2 -5 -43 -12 +-92 -16 -73 -6 -88 -5 -84 6 8 25 172 36 287 19z m-1632 -31 c43 -6 82 -15 88 +-20 11 -11 -44 -11 -105 1 -26 5 -68 4 -100 -1 -123 -21 -120 -21 -120 -5 0 +15 23 22 100 29 19 2 40 5 47 5 6 1 47 -3 90 -9z m2131 -5 c23 -4 42 -11 42 +-16 0 -7 -22 -8 -62 -3 -76 10 -82 10 -185 0 -58 -5 -83 -5 -83 3 0 6 19 13 +43 16 23 3 56 8 72 10 31 4 98 0 173 -10z m-1524 -30 c9 -3 16 -11 16 -16 0 +-11 -122 -2 -173 13 -44 12 -47 12 -47 -11 0 -26 -4 -27 -122 -35 l-98 -6 0 +24 c0 22 5 25 73 35 72 11 320 8 351 -4z m1094 0 c36 -6 42 -10 42 -30 0 -23 +-1 -24 -77 -18 -108 7 -123 11 -117 29 4 9 0 15 -10 15 -9 0 -16 -8 -16 -17 0 +-16 -11 -18 -115 -15 -90 3 -115 6 -115 17 0 8 14 16 33 19 17 3 43 8 57 10 +31 6 261 -2 318 -10z m-1590 -30 c33 -9 29 -35 -5 -28 -160 29 -183 31 -183 +13 0 -14 -13 -18 -62 -23 -35 -4 -80 -9 -102 -12 -36 -6 -38 -5 -31 17 4 13 8 +25 9 26 0 1 28 6 61 12 59 10 268 6 313 -5z m2060 0 c26 -5 32 -11 30 -28 -2 +-11 -9 -20 -15 -19 -7 2 -44 6 -83 9 -54 5 -70 10 -66 20 3 8 -1 14 -9 14 -8 +0 -15 -7 -15 -15 0 -12 -18 -15 -101 -15 -90 0 -100 2 -97 18 2 13 17 19 63 +23 67 8 242 3 293 -7z m-984 -28 c291 -24 570 -41 846 -51 191 -7 207 -11 213 +-42 4 -24 4 -24 -57 -18 -33 3 -185 10 -336 15 -151 6 -374 15 -495 21 -269 +13 -539 13 -813 -1 -114 -5 -333 -14 -487 -20 -154 -5 -301 -13 -327 -16 -47 +-6 -48 -6 -48 20 0 20 5 26 23 27 12 0 31 2 42 4 11 2 90 7 175 10 85 3 247 +12 360 20 113 8 284 19 380 25 96 6 177 13 179 16 9 8 169 4 345 -10z m141 +-121 c33 -2 143 -6 245 -9 102 -4 230 -9 285 -11 55 -2 172 -7 260 -11 199 -8 +190 -6 190 -33 0 -23 0 -23 -165 -22 -91 1 -298 6 -460 11 -377 12 -1091 12 +-1470 0 -162 -5 -362 -10 -445 -11 -134 -1 -150 1 -153 16 -2 9 0 21 5 25 4 4 +94 11 198 14 105 4 210 9 235 11 25 2 135 7 245 11 110 4 274 10 365 14 155 7 +531 4 665 -5z m820 -130 c33 -1 102 -3 153 -3 91 -2 92 -2 92 -27 l0 -25 +-1430 0 -1430 0 0 25 c0 23 4 25 48 26 475 14 2228 17 2567 4z"/> +<path d="M1222 1660 c0 -92 3 -160 9 -160 5 0 9 59 10 135 1 74 2 145 2 157 1 +12 -4 23 -10 25 -7 3 -11 -45 -11 -157z"/> +<path d="M1220 1440 c0 -27 4 -50 9 -50 12 0 17 27 13 68 -6 50 -22 38 -22 +-18z"/> +<path d="M1759 1909 c0 -2 -2 -75 -3 -161 -2 -112 0 -158 8 -158 13 0 15 304 +3 316 -4 4 -7 5 -8 3z"/> +<path d="M1753 1525 c0 -14 5 -25 12 -25 7 0 13 11 13 25 0 14 -6 25 -13 25 +-7 0 -12 -11 -12 -25z"/> +<path d="M1504 1660 c0 -96 2 -136 3 -87 2 48 2 126 0 175 -1 48 -3 8 -3 -88z"/> +<path d="M944 1480 c0 -80 2 -112 3 -72 2 39 2 105 0 145 -1 39 -3 7 -3 -73z"/> +<path d="M663 1450 c0 -16 6 -30 12 -30 6 0 12 14 12 30 0 17 -6 30 -12 30 -6 +0 -12 -13 -12 -30z"/> +<path d="M709 1478 c-8 -29 -5 -58 5 -58 7 0 13 12 13 30 0 17 -4 30 -9 30 -4 +0 -8 -1 -9 -2z"/> +<path d="M665 1253 c2 -77 21 -79 21 -3 1 39 -3 60 -11 60 -7 0 -11 -20 -10 +-57z"/> +<path d="M2272 1450 c1 -16 6 -30 13 -30 6 0 12 14 12 30 0 18 -6 30 -13 30 +-8 0 -12 -12 -12 -30z"/> +<path d="M2272 1379 c-1 -37 20 -34 24 4 2 17 -2 27 -10 27 -8 0 -13 -13 -14 +-31z"/> +<path d="M2273 1270 c-1 -48 2 -70 10 -70 8 0 12 23 12 70 0 93 -20 93 -22 0z"/> +<path d="M2313 1255 c0 -14 5 -25 12 -25 7 0 13 11 13 25 0 14 -6 25 -13 25 +-7 0 -12 -11 -12 -25z"/> +<path d="M463 1350 c0 -36 2 -50 4 -32 2 17 2 47 0 65 -2 17 -4 3 -4 -33z"/> +<path d="M2544 1360 c0 -58 1 -81 3 -52 2 28 2 76 0 105 -2 28 -3 5 -3 -53z"/> +<path d="M1388 1323 c-14 -3 -18 -15 -18 -50 0 -42 2 -45 23 -39 12 3 25 6 30 +6 4 0 7 20 7 45 0 45 -3 48 -42 38z"/> +<path d="M1570 1285 c0 -32 4 -45 14 -45 8 0 21 -3 30 -6 13 -5 16 2 16 39 0 +32 -5 47 -16 51 -36 14 -44 7 -44 -39z"/> +<path d="M1179 1148 c-6 -92 -3 -188 7 -188 8 0 11 31 11 100 0 55 -4 100 -8 +100 -5 0 -9 -6 -10 -12z"/> +<path d="M1219 1121 c-4 -88 -2 -125 9 -129 9 -3 12 15 12 62 0 36 0 69 1 73 +0 4 -4 9 -10 11 -6 2 -11 -6 -12 -17z"/> +<path d="M1178 913 c-10 -22 -1 -137 10 -141 10 -3 12 15 11 72 -1 66 -10 93 +-21 69z"/> +<path d="M1219 825 c-5 -23 -2 -49 7 -52 6 -2 11 10 12 27 0 16 -4 30 -9 30 +-5 0 -9 -2 -10 -5z"/> +<path d="M1166 744 c-31 -30 -9 -84 34 -84 17 0 50 34 50 52 0 13 -39 48 -54 +48 -8 0 -22 -7 -30 -16z m54 -34 c0 -13 -7 -20 -20 -20 -13 0 -20 7 -20 20 0 +13 7 20 20 20 13 0 20 -7 20 -20z"/> +<path d="M1755 988 c1 -130 5 -213 11 -215 6 -2 10 74 10 212 0 151 -3 215 +-11 215 -8 0 -11 -63 -10 -212z"/> +<path d="M1798 1143 c-2 -10 -4 -96 -3 -192 1 -123 5 -176 13 -179 8 -2 11 46 +9 187 -2 174 -8 230 -19 184z"/> +<path d="M1768 749 c-26 -15 -23 -65 3 -80 34 -18 69 3 69 40 0 42 -36 62 -72 +40z m50 -36 c5 -17 -26 -29 -40 -15 -6 6 -7 15 -3 22 9 14 37 9 43 -7z"/> +<path d="M847 1183 c-4 -3 -7 -23 -7 -44 0 -32 3 -36 20 -32 16 4 20 14 20 44 +0 37 -15 51 -33 32z"/> +<path d="M2122 1159 c2 -37 7 -45 26 -47 20 -3 22 1 22 37 0 23 -4 41 -9 41 +-5 0 -17 3 -26 6 -14 6 -16 0 -13 -37z"/> +<path d="M380 1136 l-45 -12 -3 -72 c-3 -80 -5 -78 71 -66 l37 7 0 78 c0 44 +-3 79 -7 78 -5 -1 -28 -6 -53 -13z m28 -127 c-7 -5 -23 -9 -35 -9 -21 0 -23 5 +-23 55 0 53 1 55 33 63 l32 8 3 -54 c2 -37 -1 -58 -10 -63z"/> +<path d="M377 1093 c-14 -13 -7 -63 8 -63 10 0 15 11 15 35 0 33 -8 43 -23 28z"/> +<path d="M2602 1068 c2 -22 9 -34 21 -36 14 -3 17 4 17 32 0 30 -4 36 -21 36 +-17 0 -20 -5 -17 -32z"/> +<path d="M708 1073 c-9 -20 -1 -107 10 -111 8 -2 11 14 10 57 -2 54 -10 76 +-20 54z"/> +<path d="M669 1049 c-8 -40 -5 -89 6 -89 14 0 16 72 3 86 -5 4 -8 5 -9 3z"/> +<path d="M664 860 c1 -58 5 -90 12 -90 7 0 11 32 11 90 -1 61 -4 90 -12 90 -8 +0 -11 -28 -11 -90z"/> +<path d="M704 860 c0 -60 4 -90 12 -90 7 0 11 30 11 90 -1 58 -5 90 -12 90 -7 +0 -11 -32 -11 -90z"/> +<path d="M674 740 c-28 -11 -36 -43 -17 -69 16 -24 55 -28 73 -7 29 36 -13 93 +-56 76z m42 -31 c3 -6 0 -17 -7 -25 -18 -17 -44 -2 -36 20 7 18 33 21 43 5z"/> +<path d="M1504 845 c0 -110 2 -156 3 -103 2 53 2 143 0 200 -1 57 -3 13 -3 +-97z"/> +<path d="M2273 940 c0 -91 4 -139 11 -137 14 5 14 269 0 274 -7 2 -11 -43 -11 +-137z"/> +<path d="M2311 990 c-1 -48 1 -60 14 -60 8 0 15 5 15 10 0 6 -6 10 -12 10 -9 +0 -8 4 2 10 13 9 13 11 0 20 -9 6 -10 10 -3 10 14 0 10 53 -4 57 -6 2 -11 -22 +-12 -57z"/> +<path d="M2313 895 c0 -14 5 -25 12 -25 7 0 13 11 13 25 0 14 -6 25 -13 25 -7 +0 -12 -11 -12 -25z"/> +<path d="M2312 829 c-1 -37 20 -34 24 4 2 17 -2 27 -10 27 -8 0 -13 -13 -14 +-31z"/> +<path d="M2288 743 c-22 -5 -35 -50 -21 -72 13 -21 57 -26 72 -7 27 33 -9 89 +-51 79z m37 -33 c4 -6 1 -18 -6 -26 -11 -13 -14 -13 -27 0 -8 8 -11 19 -8 25 +9 14 33 14 41 1z"/> +<path d="M944 745 c0 -88 2 -123 3 -77 2 46 2 118 0 160 -1 42 -3 5 -3 -83z"/> +<path d="M1568 223 c23 -2 61 -2 85 0 23 2 4 4 -43 4 -47 0 -66 -2 -42 -4z"/> +<path d="M1618 93 c34 -2 90 -2 125 0 34 2 6 3 -63 3 -69 0 -97 -1 -62 -3z"/> +<path d="M199 1694 c-5 -44 -2 -101 6 -107 6 -6 6 -10 -3 -14 -13 -5 -7 -23 9 +-23 11 0 7 136 -4 147 -4 3 -7 2 -8 -3z"/> +<path d="M2789 1620 c-1 -11 -2 -30 -2 -42 -1 -12 3 -23 9 -25 6 -2 11 15 11 +42 1 43 -16 66 -18 25z"/> +<path d="M2750 1547 c0 -20 0 -40 -1 -44 0 -4 4 -9 9 -11 11 -3 11 73 0 84 -5 +4 -8 -9 -8 -29z"/> +<path d="M235 1548 c2 -31 23 -34 23 -3 0 14 -6 25 -13 25 -6 0 -11 -10 -10 +-22z"/> +<path d="M2784 1435 c0 -27 5 -45 12 -45 6 0 11 18 10 45 0 25 -5 45 -11 45 +-6 0 -11 -19 -11 -45z"/> +<path d="M199 1445 c-5 -23 -2 -49 7 -52 6 -2 11 10 12 27 0 16 -4 30 -9 30 +-5 0 -9 -2 -10 -5z"/> +<path d="M239 1448 c0 -2 -2 -22 -3 -45 -2 -28 1 -43 9 -43 7 0 12 17 11 45 0 +25 -4 45 -8 45 -4 0 -8 -1 -9 -2z"/> +<path d="M2749 1445 c-5 -23 -2 -49 7 -52 6 -2 11 10 12 27 0 16 -4 30 -9 30 +-5 0 -9 -2 -10 -5z"/> +<path d="M2745 1243 c1 -85 5 -138 11 -140 7 -2 11 45 10 137 0 92 -3 140 -10 +140 -7 0 -11 -46 -11 -137z"/> +<path d="M199 1345 c-1 -3 -1 -14 -1 -25 0 -46 3 -60 12 -60 5 0 9 20 8 45 -1 +25 -6 45 -10 45 -4 0 -8 -2 -9 -5z"/> +<path d="M235 1220 c0 -71 3 -130 8 -130 10 0 10 -1 12 138 1 83 -2 122 -9 +122 -8 0 -11 -42 -11 -130z"/> +<path d="M2784 1323 c4 -38 25 -41 24 -4 -1 18 -6 31 -14 31 -8 0 -12 -10 -10 +-27z"/> +<path d="M2785 1210 c0 -46 4 -70 11 -70 8 0 12 24 11 70 0 43 -5 70 -11 70 +-7 0 -11 -27 -11 -70z"/> +<path d="M203 1236 c3 -7 0 -19 -6 -25 -8 -8 -8 -11 2 -11 7 0 9 -5 5 -12 -10 +-16 -12 -78 -2 -78 4 0 5 -7 2 -15 -4 -8 -2 -15 4 -15 6 0 10 35 11 85 1 56 +-3 85 -10 85 -6 0 -9 -6 -6 -14z"/> +<path d="M2789 1125 c-1 -3 -2 -14 -2 -25 -2 -29 18 -25 20 5 1 14 -2 25 -8 +25 -5 0 -9 -2 -10 -5z"/> +<path d="M199 985 c-5 -23 -2 -49 7 -52 6 -2 11 10 11 27 0 16 -4 30 -9 30 -4 +0 -8 -2 -9 -5z"/> +<path d="M238 983 c-2 -5 -3 -23 -3 -42 1 -53 21 -49 23 4 2 39 -10 60 -20 38z"/> +<path d="M2749 988 c-7 -19 -1 -118 7 -118 6 0 11 24 11 60 0 33 -4 60 -8 60 +-5 0 -9 -1 -10 -2z"/> +<path d="M2789 988 c0 -2 -2 -29 -3 -60 -2 -38 2 -58 9 -58 8 0 12 22 12 60 0 +33 -4 60 -8 60 -5 0 -9 -1 -10 -2z"/> +<path d="M195 880 c-3 -5 -1 -10 6 -10 8 0 8 -4 -1 -15 -10 -12 -10 -15 4 -15 +10 0 16 9 16 25 0 25 -14 33 -25 15z"/> +<path d="M2744 815 c0 -30 5 -45 13 -45 9 0 13 14 11 45 -1 26 -6 45 -12 45 +-7 0 -12 -18 -12 -45z"/> +<path d="M2785 818 c3 -58 22 -60 22 -3 0 29 -4 45 -12 45 -8 0 -11 -15 -10 +-42z"/> +<path d="M199 828 c-8 -31 -5 -58 6 -58 9 0 13 11 13 30 -1 17 -5 30 -10 30 +-4 0 -8 -1 -9 -2z"/> +<path d="M238 825 c-8 -8 3 -55 13 -55 5 0 9 14 9 30 0 28 -9 38 -22 25z"/> +<path d="M181 718 c-13 -33 9 -63 45 -63 35 0 56 43 34 69 -20 25 -69 20 -79 +-6z m65 -9 c3 -6 0 -17 -7 -25 -18 -17 -44 -2 -36 20 7 18 33 21 43 5z"/> +<path d="M2741 718 c-20 -52 57 -95 80 -45 16 36 -3 67 -42 67 -22 0 -32 -6 +-38 -22z m59 -17 c0 -21 -26 -36 -36 -20 -9 15 3 39 21 39 8 0 15 -9 15 -19z"/> +</g> +</svg> diff --git a/src/assets/brand/portico-logo-white.svg b/src/assets/brand/portico-logo-white.svg new file mode 100644 index 00000000..0946f82a --- /dev/null +++ b/src/assets/brand/portico-logo-white.svg @@ -0,0 +1,527 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" + "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg version="1.0" xmlns="http://www.w3.org/2000/svg" + width="300.000000pt" height="293.000000pt" viewBox="0 0 300.000000 293.000000" + preserveAspectRatio="xMidYMid meet"> +<g transform="translate(0.000000,293.000000) scale(0.100000,-0.100000)" +fill="#e3e3e3" stroke="none"> +<path d="M1425 2856 c-64 -39 -439 -253 -820 -468 -82 -47 -239 -133 -347 +-193 -195 -106 -198 -108 -198 -141 0 -28 4 -34 34 -44 19 -6 36 -19 38 -28 3 +-11 28 -23 71 -36 66 -18 67 -19 67 -52 0 -28 -5 -36 -25 -44 -22 -8 -25 -15 +-25 -58 0 -27 3 -83 6 -125 7 -72 8 -77 35 -86 22 -7 29 -16 29 -35 0 -15 5 +-26 10 -26 14 0 14 -347 0 -355 -6 -3 -10 -22 -10 -41 0 -36 -18 -49 -80 -60 +-44 -8 -51 -13 -48 -36 2 -19 9 -23 40 -23 21 0 38 3 38 8 0 4 4 6 9 2 5 -3 +12 -1 16 5 15 24 25 6 25 -45 0 -30 5 -55 10 -55 6 0 10 -78 10 -215 0 -126 +-4 -215 -9 -215 -17 0 -42 -32 -37 -47 4 -9 -1 -17 -14 -20 -16 -4 -20 -14 +-20 -44 0 -35 -2 -39 -26 -39 -26 0 -26 -2 -22 -45 l6 -45 -34 0 -34 0 0 -50 +0 -50 -45 0 -45 0 1 -65 2 -65 1468 0 1469 0 0 65 0 65 -45 0 -45 0 0 50 c0 +49 -1 50 -30 50 -29 0 -30 2 -30 45 0 41 -2 45 -25 45 -22 0 -25 4 -25 40 0 +29 -4 40 -15 40 -9 0 -15 9 -15 24 0 14 -8 31 -19 38 -17 12 -19 33 -26 220 +-6 189 -5 207 10 216 15 8 17 19 13 61 -4 45 -3 51 11 45 55 -23 93 -27 108 +-11 22 21 4 43 -42 51 -19 4 -35 11 -35 16 0 6 -3 9 -7 9 -26 -4 -33 4 -33 41 +0 29 -4 40 -15 40 -13 0 -15 26 -15 175 0 149 2 175 15 175 9 0 15 9 15 25 0 +17 8 29 24 36 16 8 26 23 31 46 3 19 4 37 1 40 -3 3 -1 14 5 25 6 12 8 45 3 +84 -5 56 -10 67 -30 76 -18 9 -24 19 -24 43 0 32 2 33 70 51 54 14 70 22 72 +38 2 13 14 23 36 28 31 8 33 12 30 45 -3 36 -4 37 -193 140 -254 140 -532 295 +-630 353 -122 72 -614 350 -617 349 -2 0 -34 -20 -73 -43z m249 -97 c88 -51 +274 -156 411 -234 320 -182 559 -315 708 -394 71 -38 117 -69 117 -78 0 -11 +-7 -14 -25 -9 -34 9 -432 220 -725 386 -509 288 -641 360 -655 360 -12 0 -160 +-81 -640 -350 -261 -146 -499 -276 -648 -353 -90 -46 -109 -53 -114 -40 -8 20 +5 30 157 110 129 68 279 152 650 363 118 67 287 163 375 212 88 50 169 97 180 +104 11 8 26 14 33 14 8 0 87 -41 176 -91z m76 -141 c232 -125 360 -198 360 +-205 0 -4 -512 255 -575 292 l-30 18 -192 -101 c-245 -129 -433 -223 -433 +-218 0 8 124 78 380 215 l243 130 31 -16 c17 -9 114 -61 216 -115z m7 -55 +c142 -71 339 -166 438 -212 507 -238 645 -309 645 -330 0 -12 -4 -21 -9 -21 +-4 0 -167 72 -362 161 -195 89 -426 194 -514 234 -88 40 -226 105 -306 144 +l-147 71 -183 -89 c-101 -49 -332 -157 -514 -239 -181 -83 -399 -182 -482 +-220 -151 -70 -153 -70 -153 -45 0 22 25 36 282 162 156 76 387 186 513 245 +177 83 396 192 532 265 1 0 118 -56 260 -126z m-95 -84 c214 -99 736 -335 +1048 -475 35 -16 58 -30 50 -32 -15 -2 -596 254 -1053 465 l-208 96 -152 -73 +c-84 -39 -255 -118 -382 -175 -126 -56 -331 -149 -455 -205 -261 -118 -270 +-122 -270 -111 0 5 125 65 278 134 152 69 376 171 497 226 121 54 276 126 345 +159 69 34 130 61 137 61 6 1 80 -31 165 -70z m-176 -85 c-3 -8 -11 -14 -18 +-14 -18 0 -15 89 3 101 11 7 15 -1 17 -32 2 -23 1 -48 -2 -55z m64 36 c0 -27 +-4 -50 -10 -50 -5 0 -10 23 -10 50 0 28 5 50 10 50 6 0 10 -22 10 -50z m-120 +-25 c0 -25 -2 -45 -4 -45 -2 0 -11 -3 -20 -6 -13 -5 -16 2 -16 38 0 47 5 58 +27 58 9 0 13 -14 13 -45z m180 -6 c0 -31 -4 -48 -10 -44 -5 3 -10 26 -10 51 0 +24 5 44 10 44 6 0 10 -23 10 -51z m-262 -70 c-10 -6 -14 3 -16 38 -2 30 1 49 +10 54 10 6 14 -3 16 -38 2 -30 -1 -49 -10 -54z m322 45 c0 -24 -4 -44 -10 -44 +-5 0 -10 23 -10 51 0 31 4 48 10 44 6 -3 10 -26 10 -51z m-370 -24 c0 -38 -4 +-50 -15 -50 -11 0 -15 11 -15 43 0 24 3 47 7 50 16 17 23 3 23 -43z m432 -8 +c2 -26 0 -41 -7 -39 -5 2 -11 26 -13 53 -4 61 14 48 20 -14z m-492 -16 c0 -30 +-5 -46 -15 -50 -12 -4 -15 4 -15 38 0 23 3 46 7 49 15 16 23 4 23 -37z m558 +-10 c2 -36 0 -47 -10 -44 -8 3 -14 24 -16 52 -2 36 0 47 10 44 8 -3 14 -24 16 +-52z m-137 -27 c228 -99 819 -350 967 -411 109 -46 122 -53 122 -75 0 -20 -4 +-24 -17 -18 -10 4 -49 18 -88 32 -38 14 -155 63 -260 108 -104 46 -255 108 +-335 140 -80 31 -172 70 -205 85 -33 16 -123 55 -200 87 l-140 59 -152 -61 +c-83 -34 -157 -66 -165 -72 -7 -6 -121 -55 -253 -108 -132 -53 -244 -101 -250 +-105 -13 -10 -421 -180 -432 -180 -3 0 -3 12 -1 27 3 24 15 32 113 74 61 26 +254 108 430 183 425 180 685 293 692 300 4 3 7 6 8 6 1 0 76 -32 166 -71z +m-481 7 c0 -30 -5 -46 -15 -50 -12 -4 -15 4 -15 38 0 23 3 46 7 49 15 16 23 4 +23 -37z m678 -9 c3 -39 0 -46 -12 -41 -11 4 -16 20 -16 51 0 61 24 52 28 -10z +m-740 -19 c-4 -59 -28 -63 -28 -4 0 35 4 46 16 46 12 0 14 -9 12 -42z m802 -4 +c0 -59 -24 -55 -28 4 -2 33 0 42 12 42 12 0 16 -11 16 -46z m60 -31 c0 -61 +-24 -52 -28 10 -3 39 0 46 12 41 11 -4 16 -20 16 -51z m-920 8 c0 -25 -5 -41 +-15 -45 -12 -4 -15 4 -15 39 0 33 4 45 15 45 11 0 15 -11 15 -39z m-62 -23 +c-4 -55 -28 -64 -28 -10 0 21 3 42 7 45 16 17 24 4 21 -35z m638 -8 c76 -27 +139 -50 141 -50 2 0 3 -16 3 -36 0 -21 -4 -33 -10 -29 -5 3 -10 15 -10 26 0 +14 -13 25 -46 39 -79 34 -90 35 -120 5 -23 -23 -26 -32 -21 -68 3 -23 11 -43 +16 -45 6 -2 8 -9 5 -14 -4 -6 -2 -8 3 -5 6 4 16 0 23 -8 15 -18 71 -20 88 -3 +20 20 14 67 -13 93 -30 30 -61 32 -75 4 -15 -26 11 -69 41 -69 28 0 22 43 -6 +48 -20 4 -20 3 -1 -11 11 -8 15 -17 9 -20 -16 -10 -44 26 -33 43 13 21 58 -3 +66 -34 8 -32 -1 -46 -31 -46 -27 0 -75 51 -75 80 0 24 26 50 51 50 80 0 141 +-118 89 -170 -38 -38 -135 -13 -165 44 -22 40 -14 117 15 146 19 19 19 20 -27 +40 -25 11 -47 19 -47 18 -1 -2 1 -59 4 -128 l5 -124 98 -34 c53 -19 97 -39 97 +-43 0 -14 -13 -11 -114 25 l-96 34 -91 -34 c-95 -35 -119 -40 -119 -25 0 5 43 +24 95 42 l95 32 0 124 c0 67 -4 123 -9 123 -17 0 -76 -29 -60 -30 24 0 48 -32 +55 -71 4 -26 3 -30 -5 -19 -9 12 -11 11 -11 -8 0 -13 -7 -36 -15 -52 -9 -17 +-15 -32 -14 -36 0 -3 -3 -9 -7 -12 -4 -4 -4 0 0 8 5 9 2 8 -7 -2 -8 -10 -16 +-15 -19 -13 -3 3 -11 -1 -18 -10 -17 -20 -79 -19 -102 2 -29 26 -24 96 10 133 +35 39 98 52 118 25 20 -28 17 -50 -12 -85 -20 -23 -34 -30 -53 -28 -34 4 -41 +46 -12 72 22 20 51 15 51 -7 0 -20 -26 -41 -35 -27 -3 5 -1 10 4 10 6 0 11 5 +11 10 0 16 -17 11 -24 -7 -10 -24 8 -37 33 -24 26 14 28 57 3 70 -32 17 -81 +-24 -82 -69 0 -33 17 -50 50 -50 58 0 110 73 89 127 -19 50 -47 54 -133 22 +-44 -17 -55 -26 -53 -42 1 -11 -4 -22 -11 -24 -10 -4 -13 4 -10 28 3 32 6 34 +133 85 72 29 135 53 141 53 7 1 74 -21 150 -49z m402 2 c2 -33 0 -42 -12 -42 +-12 0 -16 11 -16 46 0 59 24 55 28 -4z m-1110 -63 c-10 -6 -14 2 -16 33 -2 26 +1 44 10 49 10 6 14 -2 16 -33 2 -26 -1 -44 -10 -49z m1162 35 c0 -27 -4 -43 +-10 -39 -5 3 -10 24 -10 46 0 21 5 39 10 39 6 0 10 -21 10 -46z m-1210 -19 c0 +-33 -4 -45 -15 -45 -11 0 -15 11 -15 38 0 21 3 42 7 45 16 16 23 4 23 -38z +m1270 -6 c0 -21 -4 -39 -10 -39 -5 0 -10 21 -10 46 0 27 4 43 10 39 6 -3 10 +-24 10 -46z m-1326 -15 c-1 -19 -6 -40 -13 -47 -8 -8 -11 1 -11 36 0 31 4 47 +13 47 7 0 12 -13 11 -36z m1376 -4 c0 -22 -4 -40 -10 -40 -5 0 -10 18 -10 40 +0 22 5 40 10 40 6 0 10 -18 10 -40z m-1432 -22 c-4 -55 -28 -64 -28 -10 0 21 +3 42 7 45 16 17 24 4 21 -35z m1482 2 c0 -22 -4 -40 -10 -40 -5 0 -10 18 -10 +40 0 22 5 40 10 40 6 0 10 -18 10 -40z m57 -30 c0 -25 -4 -39 -11 -37 -13 4 +-20 51 -12 73 10 27 23 6 23 -36z m-1587 0 c0 -29 -4 -40 -15 -40 -11 0 -15 +11 -15 40 0 29 4 40 15 40 11 0 15 -11 15 -40z m468 18 c-3 -7 -59 -35 -126 +-63 l-122 -49 0 -112 0 -113 55 -20 c30 -11 66 -23 80 -27 25 -6 35 -24 14 +-24 -6 0 -43 11 -82 25 l-70 26 -64 -26 c-65 -26 -93 -31 -93 -17 0 4 31 18 +70 31 l69 24 3 125 3 126 125 52 c138 58 143 59 138 42z m718 -24 c49 -20 106 +-45 127 -55 l38 -20 -7 -118 -7 -118 79 -28 c43 -16 83 -32 89 -37 17 -15 -20 +-8 -95 17 l-73 25 -61 -24 c-76 -30 -91 -33 -93 -21 -1 6 30 21 68 34 l69 25 +0 121 0 121 -112 46 c-62 25 -114 51 -116 57 -5 15 -7 16 94 -25z m454 -15 c0 +-21 -4 -39 -10 -39 -5 0 -10 21 -10 46 0 27 4 43 10 39 6 -3 10 -24 10 -46z +m-1690 1 c0 -29 -4 -40 -15 -40 -10 0 -15 10 -15 33 0 19 3 37 7 40 15 16 23 +5 23 -33z m-50 -19 c0 -25 -5 -41 -15 -45 -12 -4 -15 3 -15 33 0 21 3 41 7 44 +15 16 23 5 23 -32z m1790 -2 c0 -28 -4 -39 -12 -37 -17 6 -17 78 0 78 7 0 12 +-15 12 -41z m-477 -42 l22 -15 -30 -8 c-16 -4 -50 -15 -73 -26 -43 -18 -44 +-18 -68 1 -13 10 -21 20 -19 23 3 2 7 22 11 44 3 21 8 42 10 46 5 7 107 -38 +147 -65z m-1363 24 c0 -16 -7 -34 -15 -41 -13 -11 -15 -7 -15 27 0 22 3 43 6 +46 12 12 24 -4 24 -32z m633 32 c3 -5 8 -29 12 -55 6 -40 4 -48 -14 -57 -15 +-9 -29 -8 -58 4 -68 26 -117 33 -131 18 -7 -7 -18 -13 -25 -13 -17 1 34 39 53 +40 8 1 44 16 80 35 72 37 77 38 83 28z m1255 -37 c2 -28 0 -37 -10 -34 -7 3 +-14 22 -16 42 -2 28 0 37 10 34 7 -3 14 -22 16 -42z m52 -22 c0 -21 -4 -34 +-11 -32 -6 2 -10 7 -10 11 1 4 1 21 1 38 0 17 4 28 10 24 6 -3 10 -22 10 -41z +m-1990 2 c0 -21 -6 -36 -15 -40 -12 -4 -15 3 -15 34 0 29 4 40 15 40 10 0 15 +-10 15 -34z m400 14 c0 -6 -18 -19 -41 -29 -40 -18 -40 -19 -14 -25 60 -15 54 +-119 -12 -176 -39 -35 -75 -38 -103 -10 -47 47 0 150 69 150 45 0 69 -63 34 +-91 -10 -9 -14 -9 -10 -2 11 17 -2 61 -20 67 -37 14 -73 -37 -58 -83 9 -30 59 +-28 90 4 46 45 23 125 -36 125 -37 0 -89 -26 -89 -45 0 -7 -4 -17 -10 -20 -6 +-4 -10 6 -10 23 0 27 6 32 103 75 56 25 103 46 105 46 1 1 2 -4 2 -9z m1325 +-58 c22 -8 43 -20 47 -26 11 -16 10 -56 -2 -56 -5 0 -10 11 -10 24 0 19 -9 27 +-40 40 -54 21 -67 20 -95 -9 -28 -27 -32 -70 -10 -101 8 -12 12 -24 9 -26 -2 +-3 3 -11 13 -19 14 -12 16 -12 8 0 -6 11 -3 13 17 8 55 -14 82 53 39 96 -28 +28 -55 13 -59 -32 -4 -40 -22 -30 -22 13 0 91 114 64 127 -30 4 -34 1 -46 -17 +-64 -47 -47 -150 1 -150 71 0 40 23 93 49 111 21 15 20 16 -24 32 -25 10 -43 +22 -40 27 3 4 31 -3 63 -17 31 -14 75 -33 97 -42z m315 22 c0 -19 -4 -34 -10 +-34 -5 0 -10 18 -10 41 0 24 4 38 10 34 6 -3 10 -22 10 -41z m-2092 -1 c-4 +-48 -28 -57 -28 -10 0 18 3 37 7 40 16 16 24 4 21 -30z m-50 -20 c-4 -48 -28 +-57 -28 -10 0 18 3 37 7 40 16 16 24 4 21 -30z m2192 2 c0 -24 -5 -35 -15 -35 +-10 0 -15 11 -15 35 0 24 5 35 15 35 10 0 15 -11 15 -35z m-2240 -19 c0 -19 +-4 -38 -10 -41 -6 -4 -10 10 -10 34 0 23 5 41 10 41 6 0 10 -15 10 -34z m2285 +-4 c0 -46 -19 -44 -23 2 -3 28 0 37 10 34 7 -3 13 -19 13 -36z m-2333 -55 c-2 +-4 -8 -5 -13 -2 -11 7 -12 58 -1 69 7 8 21 -53 14 -67z m2378 32 c0 -24 -4 +-38 -10 -34 -5 3 -10 22 -10 41 0 19 5 34 10 34 6 0 10 -18 10 -41z m-1580 12 +c36 -15 46 -24 51 -50 8 -37 -6 -42 -15 -6 -7 26 -59 55 -99 55 -30 0 -57 -29 +-57 -62 0 -60 94 -106 120 -58 15 29 -13 80 -44 80 -29 0 -48 -22 -39 -45 4 +-13 3 -16 -5 -11 -16 9 -15 49 0 64 33 33 101 -7 112 -66 10 -60 -38 -86 -111 +-60 -57 21 -70 111 -23 158 24 24 51 24 110 1z m145 -39 c3 -7 5 -118 6 -245 +1 -358 1 -357 -16 -357 -8 0 -15 7 -15 16 0 8 -5 12 -11 9 -6 -4 -8 -13 -5 +-20 3 -8 -3 -17 -14 -20 -11 -3 -30 -19 -44 -36 -30 -36 -46 -37 -46 -4 0 14 +-4 25 -10 25 -6 0 -10 59 -10 157 0 121 3 154 12 145 7 -7 13 -54 15 -119 2 +-60 6 -113 8 -120 2 -7 17 -11 32 -10 28 2 28 4 28 67 0 138 -9 177 -56 232 +-37 44 -40 52 -26 60 10 5 17 20 17 34 0 16 8 28 24 35 33 15 46 49 46 119 0 +54 2 60 28 72 25 12 27 12 30 -7 2 -11 5 -26 7 -33z m500 42 c21 -14 25 -24 +25 -69 0 -70 13 -102 50 -123 22 -12 30 -24 30 -44 0 -18 5 -28 15 -28 23 0 +18 -25 -9 -39 -13 -8 -36 -35 -50 -61 -22 -40 -26 -59 -24 -122 1 -41 -1 -79 +-4 -84 -10 -17 8 -47 31 -49 32 -2 39 19 37 120 -1 64 2 99 14 120 14 28 15 +22 18 -129 2 -131 0 -161 -12 -168 -8 -5 -12 -16 -9 -28 8 -29 -14 -25 -43 9 +-14 17 -33 32 -42 35 -15 5 -17 20 -17 111 1 71 -3 105 -10 105 -8 0 -11 -32 +-10 -100 1 -86 -2 -100 -15 -98 -13 3 -15 38 -18 258 -3 234 3 400 14 400 3 0 +16 -7 29 -16z m249 -6 c19 -26 21 -58 5 -58 -7 0 -9 -11 -6 -30 6 -28 -4 -44 +-28 -45 -5 -1 -9 -5 -8 -11 1 -5 -6 -10 -15 -11 -9 -1 -31 -5 -48 -8 -67 -14 +-90 71 -33 120 41 34 92 32 97 -3 2 -13 0 -31 -4 -40 -6 -13 -8 -10 -13 13 -8 +39 -45 41 -73 5 -23 -31 -15 -58 18 -66 69 -18 125 93 63 126 -32 17 -117 -14 +-131 -49 -9 -21 -12 -23 -15 -8 -9 35 3 51 52 68 72 25 120 24 139 -3z m-514 +-54 c0 -32 2 -35 22 -29 17 6 20 4 15 -10 -4 -9 -7 -95 -7 -190 0 -159 -1 +-174 -17 -173 -10 0 -26 -3 -35 -7 -17 -7 -18 7 -18 213 0 219 1 228 33 231 4 +1 7 -15 7 -35z m950 -19 c47 -20 94 -38 105 -40 31 -4 199 -65 209 -76 15 -14 +-9 -11 -51 6 -19 8 -44 15 -54 15 -27 0 -49 -28 -49 -64 0 -27 6 -36 34 -51 +55 -30 94 2 61 51 -21 32 -57 29 -65 -6 -5 -22 -7 -23 -13 -7 -17 46 35 73 80 +42 42 -30 36 -109 -9 -120 -29 -7 -93 19 -102 40 -14 38 0 99 28 117 6 4 -2 +11 -18 18 -16 6 -33 13 -37 16 -5 3 -9 -39 -9 -94 l0 -99 63 -18 c75 -22 79 +-24 72 -35 -3 -5 -36 2 -73 14 l-69 24 -74 -24 c-85 -27 -92 -28 -87 -13 2 6 +35 21 73 33 l70 22 3 95 3 95 -108 45 c-58 25 -108 50 -111 57 -4 14 1 12 128 +-43z m-1770 38 c0 -8 -194 -93 -211 -93 -6 0 -9 -40 -7 -97 l3 -96 73 -25 c39 +-13 72 -28 72 -33 0 -11 7 -13 -81 15 -75 22 -78 23 -122 6 -65 -25 -97 -32 +-97 -21 0 5 29 20 65 33 l65 23 0 92 c0 51 -3 93 -7 93 -5 0 -18 -3 -29 -6 +-21 -6 -21 -6 2 -29 24 -25 32 -55 14 -55 -5 0 -10 -11 -10 -23 0 -45 -79 -89 +-119 -67 -29 15 -29 76 1 107 41 44 107 20 88 -32 -6 -17 -7 -16 -14 8 -8 32 +-35 36 -60 8 -37 -41 3 -88 51 -61 39 22 51 61 29 94 -20 31 -40 32 -100 6 +-32 -13 -46 -16 -46 -7 0 13 127 63 195 76 22 5 81 27 130 49 91 41 115 48 +115 35z m154 -19 c8 -22 -11 -54 -33 -54 -24 0 -34 26 -21 51 13 23 46 25 54 +3z m606 -204 c0 -213 -1 -220 -20 -220 -19 0 -20 7 -20 198 0 208 4 242 26 +242 12 0 14 -39 14 -220z m782 195 c8 -19 8 -29 0 -37 -23 -23 -61 14 -48 47 +9 23 35 18 48 -10z m-1127 -5 c17 -18 17 -22 4 -36 -20 -20 -49 -8 -49 20 0 +40 18 46 45 16z m283 -421 c-10 -7 -14 36 -16 208 -2 167 1 218 10 224 10 7 +14 -36 16 -208 2 -167 -1 -218 -10 -224z m206 243 c-2 -235 -1 -232 -14 -232 +-6 0 -10 78 -10 215 0 165 3 215 13 215 9 0 12 -46 11 -198z m363 172 c7 -20 +-22 -45 -43 -37 -17 6 -18 25 -2 41 17 17 38 15 45 -4z m-607 -208 c0 -181 -2 +-215 -15 -220 -13 -5 -15 23 -15 214 0 189 2 220 15 220 13 0 15 -30 15 -214z +m340 -1 c0 -137 -4 -215 -10 -215 -6 0 -10 78 -10 215 0 137 4 215 10 215 6 0 +10 -78 10 -215z m718 166 c5 -14 -74 -52 -93 -45 -12 5 -14 15 -9 43 4 20 8 +39 11 43 5 9 87 -28 91 -41z m-1700 -10 c4 -48 4 -48 -77 -14 l-35 15 39 24 +c54 33 69 28 73 -25z m-75 -47 c26 -9 47 -21 47 -27 0 -7 3 -23 7 -36 4 -17 3 +-22 -5 -17 -7 4 -12 16 -12 26 0 21 -55 50 -96 50 -29 0 -54 -25 -54 -55 0 +-54 87 -89 110 -45 9 17 6 25 -14 45 -30 30 -56 24 -56 -13 0 -19 -3 -23 -11 +-15 -6 6 -9 21 -7 34 2 19 10 25 35 27 42 4 73 -26 73 -72 0 -46 -20 -60 -74 +-52 -68 11 -94 63 -61 126 23 44 46 49 118 24z m1873 8 c26 -17 34 -49 19 -78 +-8 -15 -12 -31 -10 -34 3 -4 -5 -16 -17 -26 -14 -12 -18 -14 -13 -4 6 11 3 10 +-12 -2 -64 -57 -138 23 -80 86 28 31 58 40 81 23 15 -11 17 -20 11 -43 l-9 +-29 -4 27 c-4 33 -23 41 -51 22 -25 -18 -28 -62 -5 -71 25 -10 67 10 83 38 13 +24 13 29 -3 54 -15 23 -23 26 -49 22 -58 -10 -87 -25 -87 -47 0 -11 -5 -20 +-11 -20 -6 0 -9 12 -7 27 2 22 12 31 48 45 48 18 98 23 116 10z m-1746 -49 c0 +-14 7 -31 16 -37 11 -9 14 -26 12 -69 l-3 -58 -35 37 c-19 20 -29 34 -22 30 6 +-4 12 -2 12 3 0 6 -4 11 -10 11 -5 0 -10 5 -10 11 0 5 5 7 10 4 15 -9 12 4 -5 +21 -18 19 -20 71 -2 77 22 8 37 -5 37 -30z m1555 -20 c-2 -21 -4 -47 -4 -58 +-1 -14 -4 -16 -9 -7 -5 7 -7 33 -5 57 3 29 0 45 -7 45 -7 0 -10 -22 -9 -65 2 +-51 -2 -69 -16 -85 -10 -11 -22 -20 -27 -20 -15 0 -9 107 7 120 8 7 15 23 15 +35 0 27 17 36 41 24 12 -6 16 -19 14 -46z m-1951 1 c7 -19 -10 -44 -29 -44 +-20 0 -26 28 -9 45 20 19 30 19 38 -1z m2334 4 c16 -16 15 -48 -2 -48 -20 0 +-39 27 -32 45 7 18 18 19 34 3z m-2088 -13 c15 -18 5 -35 -21 -35 -14 0 -19 7 +-19 25 0 28 21 33 40 10z m356 -41 c12 5 14 -20 14 -165 0 -132 -3 -170 -12 +-166 -7 2 -23 0 -35 -4 l-23 -9 0 194 c0 147 3 195 13 199 7 2 15 -9 20 -25 5 +-20 13 -28 23 -24z m1096 23 c2 -18 8 -27 20 -27 17 0 18 -13 18 -167 l0 -168 +-35 -1 -35 -1 0 193 c0 145 3 193 13 197 16 6 17 5 19 -26z m398 13 c0 -23 +-26 -38 -41 -23 -14 14 0 43 22 43 12 0 19 -7 19 -20z m-1563 -192 c-2 -180 +-3 -193 -21 -196 -14 -3 -17 0 -12 13 3 9 6 97 6 196 0 149 2 179 14 179 13 0 +15 -31 13 -192z m123 2 c0 -145 -3 -190 -12 -190 -10 0 -12 43 -10 190 2 112 +7 190 12 190 6 0 10 -76 10 -190z m997 -2 c-2 -165 -4 -193 -18 -196 -13 -2 +-15 20 -17 172 -3 168 3 216 28 216 5 0 8 -82 7 -192z m121 2 c-2 -118 -7 +-190 -13 -190 -6 0 -11 72 -13 190 -2 166 0 190 13 190 13 0 15 -24 13 -190z +m-1288 -15 c0 -167 -2 -195 -15 -195 -13 0 -15 28 -15 188 0 104 3 192 7 195 +19 20 23 -10 23 -188z m230 -6 c0 -144 -3 -189 -12 -189 -10 0 -12 44 -10 195 +2 122 6 193 12 190 6 -4 10 -86 10 -196z m890 6 c0 -167 -2 -195 -15 -195 -13 +0 -15 28 -15 189 0 182 1 192 28 200 1 1 2 -87 2 -194z m230 -6 c0 -114 -4 +-189 -10 -189 -9 0 -20 377 -11 386 16 15 21 -32 21 -197z m92 99 c-28 -29 +-54 -49 -59 -44 -4 5 -2 11 6 14 8 2 32 24 54 48 22 24 43 42 45 39 3 -2 -18 +-28 -46 -57z m-1523 -25 c14 -13 21 -23 15 -23 -14 0 -94 80 -94 94 0 6 12 -2 +27 -19 14 -16 38 -40 52 -52z m1114 40 c-26 -34 -28 -43 -29 -142 -1 -58 -6 +-107 -11 -108 -7 -3 -9 77 -4 193 1 19 9 32 51 82 24 28 19 9 -7 -25z m-1200 +-18 c-4 -11 -1 -13 11 -9 12 5 19 1 22 -12 3 -11 20 -26 37 -35 l32 -16 3 +-116 c2 -71 -1 -117 -7 -117 -5 0 -11 -19 -13 -42 -2 -29 -8 -44 -18 -46 -13 +-2 -15 9 -13 68 2 52 -1 70 -9 68 -8 -3 -12 -30 -13 -75 0 -66 -2 -72 -31 -97 +-18 -14 -36 -26 -42 -26 -16 0 -22 66 -22 241 0 142 2 168 16 173 10 4 13 13 +9 25 -4 13 0 23 12 29 22 13 34 6 26 -13z m1685 13 c7 -7 12 -20 12 -31 0 -10 +7 -25 15 -33 12 -13 15 -48 15 -185 0 -106 -4 -169 -10 -169 -5 0 -10 -11 -10 +-25 0 -14 -4 -25 -9 -25 -4 0 -20 11 -35 25 -15 14 -31 25 -37 25 -5 0 -9 7 +-9 15 0 18 -17 20 -22 3 -9 -25 -28 5 -28 43 0 21 -4 39 -10 39 -6 0 -10 46 +-10 118 l0 118 34 14 c19 7 37 22 40 32 3 15 10 18 25 13 12 -4 21 -2 21 4 0 +6 -5 11 -11 11 -5 0 -7 5 -4 10 8 13 18 13 33 -2z m-1195 -50 c3 -18 6 -62 6 +-98 1 -36 4 -73 7 -84 4 -13 2 -17 -7 -14 -10 3 -15 28 -16 84 -2 43 -4 94 -6 +112 -2 17 0 32 4 32 4 0 9 -15 12 -32z m-713 -3 c0 -9 7 -18 15 -21 12 -5 15 +-32 15 -153 l0 -146 -24 -1 -25 -2 -3 162 c-2 88 -2 164 0 169 6 13 22 7 22 +-8z m2090 -11 c0 -19 4 -25 15 -20 13 5 15 -15 15 -142 l0 -147 -25 -1 -25 -2 +-2 122 c-1 66 -3 142 -3 169 -1 32 3 47 12 47 7 0 13 -11 13 -26z m-2130 -154 +c0 -144 -2 -170 -15 -170 -13 0 -15 25 -15 163 0 90 3 167 7 170 19 20 23 -8 +23 -163z m110 0 c0 -107 -4 -170 -10 -170 -6 0 -10 63 -10 170 0 107 4 170 10 +170 6 0 10 -63 10 -170z m1980 0 c0 -144 -2 -170 -15 -170 -13 0 -15 26 -15 +170 0 144 2 170 15 170 13 0 15 -26 15 -170z m101 157 c-1 -4 -1 -79 -1 -168 +0 -108 -3 -158 -10 -154 -14 9 -12 337 2 333 5 -2 9 -7 9 -11z m-2231 -167 c0 +-144 -2 -170 -15 -170 -13 0 -15 25 -15 164 0 157 2 167 28 175 1 1 2 -75 2 +-169z m210 -5 c0 -103 -4 -165 -10 -165 -6 0 -10 62 -10 165 0 103 4 165 10 +165 6 0 10 -62 10 -165z m1880 0 c0 -140 -2 -165 -15 -165 -13 0 -15 25 -15 +165 0 140 2 165 15 165 13 0 15 -25 15 -165z m200 0 c0 -103 -4 -165 -10 -165 +-6 0 -10 62 -10 165 0 103 4 165 10 165 6 0 10 -62 10 -165z m-1057 69 l92 +-25 0 -45 c0 -28 -4 -44 -12 -44 -8 0 -13 14 -13 34 0 33 -8 42 -52 52 -5 1 +-11 3 -15 4 -16 5 -29 7 -51 8 -13 1 -20 7 -17 12 3 6 4 10 1 10 -2 0 -11 3 +-20 6 -14 5 -16 -9 -16 -124 l0 -130 33 -5 c71 -10 153 -30 162 -39 11 -11 +-14 -7 -131 19 -68 15 -77 15 -168 -4 l-96 -20 0 52 c0 39 4 52 15 52 10 0 15 +-11 15 -32 l0 -32 75 15 75 15 0 104 c0 96 -1 105 -17 98 -10 -4 -36 -11 -58 +-16 -66 -13 -75 -19 -75 -50 0 -20 -5 -29 -16 -29 -12 0 -14 10 -12 47 l3 47 +85 22 c110 28 105 28 213 -2z m-143 -123 l0 -79 -50 -11 c-28 -6 -55 -11 -60 +-11 -4 0 -7 24 -5 53 2 28 4 64 4 78 1 25 14 31 104 48 4 0 7 -35 7 -78z m170 +59 c23 -6 25 -11 28 -80 2 -51 6 -70 12 -60 8 13 10 12 10 -2 0 -11 -8 -18 +-20 -18 -11 0 -20 3 -20 8 0 4 -16 8 -36 10 -20 1 -40 5 -45 8 -5 3 -9 39 -9 +80 l0 74 28 -6 c15 -4 38 -10 52 -14z m-537 -126 c-3 -10 -17 -8 -61 7 -31 11 +-61 24 -66 29 -22 22 -26 6 -26 -94 0 -71 4 -107 13 -114 6 -5 35 -13 62 -17 +55 -7 97 -25 60 -25 -11 0 -46 6 -78 14 -39 9 -72 11 -105 5 -26 -5 -62 -11 +-79 -14 l-33 -6 0 56 c0 30 5 55 10 55 10 0 15 -29 10 -59 -1 -11 9 -12 51 -7 +29 4 56 9 61 12 4 3 8 46 8 96 0 82 -2 89 -17 83 -10 -4 -37 -12 -61 -17 -36 +-8 -42 -13 -37 -29 4 -13 2 -19 -9 -19 -12 0 -16 10 -16 35 0 27 4 35 18 35 9 +0 44 8 77 18 59 18 60 18 141 -7 56 -16 81 -28 77 -37z m237 46 c0 -5 -8 -10 +-17 -11 -10 0 -26 -2 -35 -4 -10 -2 -18 1 -18 5 0 5 12 11 28 13 15 2 30 5 35 +6 4 0 7 -3 7 -9z m417 -5 c33 -10 58 -25 73 -45 13 -17 37 -34 53 -38 17 -4 +32 -13 35 -20 6 -20 -60 8 -85 35 -12 14 -23 29 -25 34 -2 6 -31 15 -66 22 +-34 6 -62 15 -62 19 0 12 20 10 77 -7z m403 -4 c57 -16 65 -21 68 -44 2 -16 +-2 -27 -9 -27 -6 0 -9 8 -6 19 3 14 1 18 -9 14 -8 -3 -14 0 -14 7 0 7 -7 10 +-15 7 -8 -4 -17 -2 -20 4 -4 5 -12 8 -18 7 -7 -1 -23 4 -35 11 -13 7 -24 11 +-25 9 -1 -2 -1 -53 1 -114 l3 -112 50 -6 c53 -7 105 -24 97 -31 -2 -2 -39 4 +-82 14 -70 17 -84 17 -149 5 -40 -8 -75 -14 -79 -14 -5 0 -8 27 -8 60 0 33 4 +60 10 60 6 0 10 -21 10 -46 0 -35 3 -45 14 -41 7 3 34 9 60 12 l46 7 0 93 0 +93 -60 -15 c-37 -10 -60 -21 -60 -29 0 -8 -5 -14 -11 -14 -6 0 -9 12 -7 27 3 +24 10 29 68 44 84 22 102 22 180 0z m-900 -11 c0 -5 -6 -10 -14 -10 -7 0 -25 +-9 -40 -21 -14 -11 -26 -16 -26 -10 0 6 5 11 10 11 6 0 10 6 10 14 0 13 16 22 +48 25 6 0 12 -3 12 -9z m20 -410 l-5 -255 -22 -3 c-19 -3 -23 -10 -23 -42 0 +-30 -5 -40 -20 -45 -11 -3 -20 -13 -20 -21 0 -8 -7 -14 -15 -14 -9 0 -15 9 +-15 25 0 18 -7 26 -25 31 l-25 6 0 229 c0 146 4 229 10 229 6 0 10 33 10 79 0 +75 1 79 25 85 13 3 36 22 51 41 14 19 29 33 33 31 4 -3 13 -1 21 4 22 13 26 +-73 20 -380z m492 378 c12 -7 35 -28 51 -45 16 -18 38 -33 48 -33 17 0 19 -8 +19 -80 0 -47 4 -80 10 -80 6 0 10 -83 10 -230 0 -222 -1 -230 -20 -230 -21 0 +-40 -27 -33 -47 3 -8 -4 -13 -17 -13 -12 0 -18 4 -15 10 3 5 -3 15 -15 22 -14 +9 -20 23 -20 49 0 32 -3 37 -30 42 l-29 6 -3 253 c-4 298 -1 388 13 388 5 0 +19 -6 31 -12z m-862 -68 c0 -60 -3 -70 -17 -70 -10 0 -28 -3 -41 -6 -23 -6 +-23 -5 -20 62 3 63 5 69 28 75 49 14 50 13 50 -61z m155 48 c15 -6 10 -7 -17 +-5 l-38 3 0 -42 c0 -37 3 -42 25 -46 14 -3 25 -1 25 3 0 5 7 9 15 9 9 0 15 +-10 15 -26 0 -23 -3 -25 -26 -20 -15 4 -38 9 -53 12 -25 5 -26 7 -23 70 4 64 +4 64 30 57 15 -3 36 -10 47 -15z m965 -48 c0 -38 -4 -70 -9 -70 -5 0 -23 -3 +-40 -6 -28 -6 -31 -4 -31 20 0 26 15 36 22 15 2 -5 11 -7 21 -4 12 5 17 18 17 +45 0 37 -1 39 -37 42 l-38 4 35 11 c60 19 60 19 60 -57z m139 59 c30 -11 31 +-13 31 -70 0 -38 4 -59 12 -59 6 0 9 -3 5 -6 -3 -4 -25 1 -47 10 -23 9 -46 14 +-51 11 -5 -4 -9 21 -9 59 0 72 3 74 59 55z m-1615 -49 c37 -12 64 -25 61 -30 +-3 -5 -19 -4 -38 1 -17 6 -41 12 -51 14 -11 3 -24 9 -30 15 -21 21 -26 7 -26 +-84 0 -104 -4 -98 75 -112 45 -7 82 -23 55 -24 -8 0 -42 7 -75 14 -56 14 -118 +10 -187 -10 -16 -5 -18 4 -18 99 l0 105 58 15 c78 21 100 20 176 -3z m576 9 +c-14 -6 -33 -12 -43 -14 -10 -2 -27 -7 -38 -10 -10 -4 -19 -2 -19 3 0 9 69 29 +105 30 16 1 15 -1 -5 -9z m1511 -5 c51 -14 56 -19 56 -42 0 -26 0 -26 -9 -5 +-7 13 -26 25 -53 32 -23 6 -50 13 -59 17 -14 5 -16 -5 -16 -89 l0 -96 58 -11 +c55 -12 100 -29 75 -30 -6 0 -40 7 -75 14 -54 13 -72 13 -128 1 -35 -7 -67 +-12 -71 -10 -3 2 -6 25 -7 50 -2 34 1 45 13 45 10 0 15 -10 15 -34 l0 -33 50 +10 50 10 0 79 c0 65 -3 79 -14 75 -8 -3 -31 -9 -50 -13 -22 -4 -36 -12 -36 +-21 0 -8 -6 -13 -12 -10 -7 2 -13 12 -13 23 0 15 13 23 60 36 77 21 96 21 166 +2z m-673 0 c27 -8 29 -23 2 -21 -11 1 -20 5 -20 10 0 4 -4 5 -10 2 -5 -3 -10 +-1 -10 4 0 12 6 13 38 5z m320 -18 c13 -3 34 -16 46 -29 15 -16 42 -28 84 -36 +72 -14 83 -26 17 -17 -53 8 -78 18 -124 51 -20 15 -48 25 -67 25 -19 0 -34 5 +-34 11 0 11 19 10 78 -5z m-1582 -34 c-9 -15 -70 -41 -112 -48 -22 -3 -42 -8 +-46 -11 -5 -2 -8 0 -8 6 0 11 19 18 75 27 22 3 51 14 65 24 25 19 37 19 26 2z +m1944 3 c23 -5 25 -11 25 -60 l0 -55 -35 6 c-50 9 -50 9 -50 70 0 48 2 55 18 +50 9 -3 28 -8 42 -11z m-2096 -1 c25 -10 19 -22 -9 -16 -22 4 -25 1 -25 -26 0 +-24 5 -31 26 -36 14 -4 34 -4 45 -1 15 5 19 1 19 -19 0 -31 -1 -31 -62 -9 +l-48 17 0 48 c0 50 11 58 54 42z m216 -64 c0 -40 4 -70 10 -70 6 0 10 -83 10 +-230 0 -215 -1 -230 -18 -230 -25 0 -42 -19 -42 -47 0 -14 -6 -23 -15 -23 -8 +0 -15 -6 -15 -14 0 -9 -7 -12 -21 -9 -11 3 -18 11 -15 19 3 7 -6 22 -19 33 +-25 19 -25 20 -25 197 0 99 3 223 7 276 6 94 7 97 32 103 14 3 42 19 61 35 19 +16 38 30 43 30 4 0 7 -31 7 -70z m758 4 c16 5 17 -12 14 -213 l-3 -218 -34 -1 +-35 -1 0 244 c0 224 1 244 18 247 13 3 18 -4 20 -30 3 -26 7 -32 20 -28z m766 +45 c20 -12 34 -25 31 -29 -3 -4 11 -11 30 -14 l35 -7 0 -64 c0 -37 4 -65 10 +-65 6 0 10 -78 10 -213 l0 -214 -25 -11 c-15 -7 -25 -20 -25 -32 0 -11 -5 -20 +-10 -20 -6 0 -15 -10 -20 -22 -8 -21 -9 -20 -9 10 -1 19 -6 32 -14 32 -7 0 +-17 15 -22 33 -7 22 -17 33 -32 35 l-23 3 0 230 c0 146 4 229 10 229 6 0 10 +30 10 70 0 39 2 70 4 70 3 0 21 -9 40 -21z m226 -33 c0 -40 -4 -55 -16 -60 +-28 -11 -54 -6 -54 9 0 9 9 15 25 15 22 0 25 4 25 35 0 33 -2 35 -25 29 -15 +-4 -25 -2 -25 4 0 11 20 19 53 21 14 1 17 -8 17 -53z m-1072 -451 c-2 -1 -20 +-5 -40 -9 l-38 -7 0 244 c0 208 2 246 15 251 13 5 15 -26 15 -236 0 -133 3 +-239 6 -236 3 4 6 110 7 237 2 194 4 233 17 241 13 8 15 -21 18 -237 1 -135 1 +-247 0 -248z m142 392 c0 -52 3 -162 7 -245 5 -137 5 -152 -10 -152 -15 0 -17 +24 -17 245 0 157 4 245 10 245 6 0 10 -38 10 -93z m-244 -404 c-3 -7 -10 -13 +-16 -13 -16 0 -14 487 3 493 9 3 13 -49 15 -232 1 -130 0 -241 -2 -248z m344 +232 c0 -157 -4 -245 -10 -245 -6 0 -10 88 -10 245 0 157 4 245 10 245 6 0 10 +-88 10 -245z m-1380 226 c0 -11 -94 -35 -112 -29 -7 3 14 11 47 20 33 8 61 16 +63 17 1 0 2 -3 2 -8z m2465 -8 c30 -9 55 -20 55 -24 0 -4 -26 1 -58 10 -31 10 +-63 16 -70 13 -6 -2 -12 1 -12 7 0 15 20 14 85 -6z m-1875 -287 c0 -190 -2 +-225 -15 -230 -13 -5 -15 24 -15 224 0 198 2 230 15 230 13 0 15 -32 15 -224z +m42 202 c2 -15 9 -22 21 -22 16 2 17 -14 17 -200 l0 -201 -35 -2 -35 -2 0 225 +c0 188 2 224 14 224 8 0 16 -10 18 -22z m1118 -3 c0 -18 5 -25 20 -25 19 0 20 +-7 20 -198 l0 -199 -35 -1 -35 -1 0 224 c0 193 2 225 15 225 9 0 15 -9 15 -25z +m-1210 -210 c0 -193 -2 -225 -15 -225 -13 0 -15 30 -15 209 0 115 3 216 6 225 +18 47 24 -5 24 -209z m170 5 c0 -134 -4 -220 -10 -220 -9 0 -20 427 -11 436 +17 17 21 -23 21 -216z m950 -5 c0 -193 -2 -225 -15 -225 -13 0 -15 31 -15 219 +0 212 1 222 28 230 1 1 2 -100 2 -224z m50 6 c0 -181 -2 -220 -14 -224 -8 -3 +-17 -3 -20 0 -8 8 -8 407 0 427 3 9 12 16 19 16 11 0 14 -44 15 -219z m117 -4 +c5 -196 4 -217 -11 -217 -14 0 -16 24 -16 221 0 156 3 220 11 217 7 -2 13 -77 +16 -221z m-1057 -7 c0 -140 -4 -220 -10 -220 -6 0 -10 80 -10 220 0 140 4 220 +10 220 6 0 10 -80 10 -220z m1120 0 c0 -134 -4 -220 -10 -220 -5 0 -10 88 -12 +220 -2 171 0 220 10 220 9 0 12 -51 12 -220z m-1738 155 c-3 -18 0 -25 12 -25 +14 0 16 -21 16 -184 0 -181 0 -184 -22 -189 -12 -4 -23 -5 -25 -4 -2 2 -5 386 +-3 420 0 4 6 7 14 7 9 0 12 -8 8 -25z m2088 0 c0 -16 6 -25 15 -25 13 0 15 +-27 15 -185 0 -194 2 -185 -41 -189 -8 -1 -11 55 -11 194 0 107 0 203 1 213 2 +27 21 20 21 -8z m-2130 -195 c0 -180 -2 -210 -15 -210 -13 0 -15 30 -15 210 0 +180 2 210 15 210 13 0 15 -30 15 -210z m110 0 c0 -133 -4 -210 -10 -210 -6 0 +-10 77 -10 210 0 133 4 210 10 210 6 0 10 -77 10 -210z m1980 0 c0 -180 -2 +-210 -15 -210 -13 0 -15 30 -15 210 0 180 2 210 15 210 13 0 15 -30 15 -210z +m100 16 c0 -107 3 -201 6 -210 4 -11 1 -16 -10 -16 -14 0 -16 24 -16 210 0 +133 4 210 10 210 6 0 10 -71 10 -194z m-2232 -23 c-2 -154 -6 -207 -15 -211 +-10 -3 -13 43 -13 207 0 182 2 211 15 211 13 0 15 -27 13 -207z m212 -3 c0 +-133 -4 -210 -10 -210 -6 0 -10 77 -10 210 0 133 4 210 10 210 6 0 10 -77 10 +-210z m1878 3 c-2 -154 -6 -207 -15 -211 -10 -3 -13 43 -13 207 0 182 2 211 +15 211 13 0 15 -27 13 -207z m202 -4 c0 -137 -3 -208 -10 -204 -6 4 -10 85 +-10 211 0 129 4 204 10 204 6 0 10 -77 10 -211z m-1043 -129 c110 -15 123 -18 +123 -36 0 -11 -8 -14 -32 -10 -18 3 -69 10 -113 16 -43 6 -83 16 -87 23 -6 9 +-8 8 -8 -4 0 -13 -22 -18 -112 -29 -133 -15 -133 -15 -133 8 0 31 216 51 362 +32z m-514 -75 c9 -4 17 -11 17 -17 0 -10 -90 -3 -147 12 -18 5 -33 5 -33 1 0 +-9 -180 -29 -186 -20 -7 12 21 28 61 32 53 7 265 0 288 -8z m522 -5 c154 -17 +155 -17 155 -51 0 -33 18 -33 -175 -8 -78 10 -164 7 -295 -11 -99 -14 -100 +-14 -100 20 0 17 1 30 3 31 12 5 286 36 297 33 8 -1 60 -8 115 -14z m544 10 +c100 -14 104 -34 6 -25 -44 4 -88 11 -97 16 -9 5 -18 5 -20 0 -2 -5 -43 -12 +-92 -16 -73 -6 -88 -5 -84 6 8 25 172 36 287 19z m-1632 -31 c43 -6 82 -15 88 +-20 11 -11 -44 -11 -105 1 -26 5 -68 4 -100 -1 -123 -21 -120 -21 -120 -5 0 +15 23 22 100 29 19 2 40 5 47 5 6 1 47 -3 90 -9z m2131 -5 c23 -4 42 -11 42 +-16 0 -7 -22 -8 -62 -3 -76 10 -82 10 -185 0 -58 -5 -83 -5 -83 3 0 6 19 13 +43 16 23 3 56 8 72 10 31 4 98 0 173 -10z m-1524 -30 c9 -3 16 -11 16 -16 0 +-11 -122 -2 -173 13 -44 12 -47 12 -47 -11 0 -26 -4 -27 -122 -35 l-98 -6 0 +24 c0 22 5 25 73 35 72 11 320 8 351 -4z m1094 0 c36 -6 42 -10 42 -30 0 -23 +-1 -24 -77 -18 -108 7 -123 11 -117 29 4 9 0 15 -10 15 -9 0 -16 -8 -16 -17 0 +-16 -11 -18 -115 -15 -90 3 -115 6 -115 17 0 8 14 16 33 19 17 3 43 8 57 10 +31 6 261 -2 318 -10z m-1590 -30 c33 -9 29 -35 -5 -28 -160 29 -183 31 -183 +13 0 -14 -13 -18 -62 -23 -35 -4 -80 -9 -102 -12 -36 -6 -38 -5 -31 17 4 13 8 +25 9 26 0 1 28 6 61 12 59 10 268 6 313 -5z m2060 0 c26 -5 32 -11 30 -28 -2 +-11 -9 -20 -15 -19 -7 2 -44 6 -83 9 -54 5 -70 10 -66 20 3 8 -1 14 -9 14 -8 +0 -15 -7 -15 -15 0 -12 -18 -15 -101 -15 -90 0 -100 2 -97 18 2 13 17 19 63 +23 67 8 242 3 293 -7z m-984 -28 c291 -24 570 -41 846 -51 191 -7 207 -11 213 +-42 4 -24 4 -24 -57 -18 -33 3 -185 10 -336 15 -151 6 -374 15 -495 21 -269 +13 -539 13 -813 -1 -114 -5 -333 -14 -487 -20 -154 -5 -301 -13 -327 -16 -47 +-6 -48 -6 -48 20 0 20 5 26 23 27 12 0 31 2 42 4 11 2 90 7 175 10 85 3 247 +12 360 20 113 8 284 19 380 25 96 6 177 13 179 16 9 8 169 4 345 -10z m141 +-121 c33 -2 143 -6 245 -9 102 -4 230 -9 285 -11 55 -2 172 -7 260 -11 199 -8 +190 -6 190 -33 0 -23 0 -23 -165 -22 -91 1 -298 6 -460 11 -377 12 -1091 12 +-1470 0 -162 -5 -362 -10 -445 -11 -134 -1 -150 1 -153 16 -2 9 0 21 5 25 4 4 +94 11 198 14 105 4 210 9 235 11 25 2 135 7 245 11 110 4 274 10 365 14 155 7 +531 4 665 -5z m820 -130 c33 -1 102 -3 153 -3 91 -2 92 -2 92 -27 l0 -25 +-1430 0 -1430 0 0 25 c0 23 4 25 48 26 475 14 2228 17 2567 4z"/> +<path d="M1222 1660 c0 -92 3 -160 9 -160 5 0 9 59 10 135 1 74 2 145 2 157 1 +12 -4 23 -10 25 -7 3 -11 -45 -11 -157z"/> +<path d="M1220 1440 c0 -27 4 -50 9 -50 12 0 17 27 13 68 -6 50 -22 38 -22 +-18z"/> +<path d="M1759 1909 c0 -2 -2 -75 -3 -161 -2 -112 0 -158 8 -158 13 0 15 304 +3 316 -4 4 -7 5 -8 3z"/> +<path d="M1753 1525 c0 -14 5 -25 12 -25 7 0 13 11 13 25 0 14 -6 25 -13 25 +-7 0 -12 -11 -12 -25z"/> +<path d="M1504 1660 c0 -96 2 -136 3 -87 2 48 2 126 0 175 -1 48 -3 8 -3 -88z"/> +<path d="M944 1480 c0 -80 2 -112 3 -72 2 39 2 105 0 145 -1 39 -3 7 -3 -73z"/> +<path d="M663 1450 c0 -16 6 -30 12 -30 6 0 12 14 12 30 0 17 -6 30 -12 30 -6 +0 -12 -13 -12 -30z"/> +<path d="M709 1478 c-8 -29 -5 -58 5 -58 7 0 13 12 13 30 0 17 -4 30 -9 30 -4 +0 -8 -1 -9 -2z"/> +<path d="M665 1253 c2 -77 21 -79 21 -3 1 39 -3 60 -11 60 -7 0 -11 -20 -10 +-57z"/> +<path d="M2272 1450 c1 -16 6 -30 13 -30 6 0 12 14 12 30 0 18 -6 30 -13 30 +-8 0 -12 -12 -12 -30z"/> +<path d="M2272 1379 c-1 -37 20 -34 24 4 2 17 -2 27 -10 27 -8 0 -13 -13 -14 +-31z"/> +<path d="M2273 1270 c-1 -48 2 -70 10 -70 8 0 12 23 12 70 0 93 -20 93 -22 0z"/> +<path d="M2313 1255 c0 -14 5 -25 12 -25 7 0 13 11 13 25 0 14 -6 25 -13 25 +-7 0 -12 -11 -12 -25z"/> +<path d="M463 1350 c0 -36 2 -50 4 -32 2 17 2 47 0 65 -2 17 -4 3 -4 -33z"/> +<path d="M2544 1360 c0 -58 1 -81 3 -52 2 28 2 76 0 105 -2 28 -3 5 -3 -53z"/> +<path d="M1388 1323 c-14 -3 -18 -15 -18 -50 0 -42 2 -45 23 -39 12 3 25 6 30 +6 4 0 7 20 7 45 0 45 -3 48 -42 38z"/> +<path d="M1570 1285 c0 -32 4 -45 14 -45 8 0 21 -3 30 -6 13 -5 16 2 16 39 0 +32 -5 47 -16 51 -36 14 -44 7 -44 -39z"/> +<path d="M1179 1148 c-6 -92 -3 -188 7 -188 8 0 11 31 11 100 0 55 -4 100 -8 +100 -5 0 -9 -6 -10 -12z"/> +<path d="M1219 1121 c-4 -88 -2 -125 9 -129 9 -3 12 15 12 62 0 36 0 69 1 73 +0 4 -4 9 -10 11 -6 2 -11 -6 -12 -17z"/> +<path d="M1178 913 c-10 -22 -1 -137 10 -141 10 -3 12 15 11 72 -1 66 -10 93 +-21 69z"/> +<path d="M1219 825 c-5 -23 -2 -49 7 -52 6 -2 11 10 12 27 0 16 -4 30 -9 30 +-5 0 -9 -2 -10 -5z"/> +<path d="M1166 744 c-31 -30 -9 -84 34 -84 17 0 50 34 50 52 0 13 -39 48 -54 +48 -8 0 -22 -7 -30 -16z m54 -34 c0 -13 -7 -20 -20 -20 -13 0 -20 7 -20 20 0 +13 7 20 20 20 13 0 20 -7 20 -20z"/> +<path d="M1755 988 c1 -130 5 -213 11 -215 6 -2 10 74 10 212 0 151 -3 215 +-11 215 -8 0 -11 -63 -10 -212z"/> +<path d="M1798 1143 c-2 -10 -4 -96 -3 -192 1 -123 5 -176 13 -179 8 -2 11 46 +9 187 -2 174 -8 230 -19 184z"/> +<path d="M1768 749 c-26 -15 -23 -65 3 -80 34 -18 69 3 69 40 0 42 -36 62 -72 +40z m50 -36 c5 -17 -26 -29 -40 -15 -6 6 -7 15 -3 22 9 14 37 9 43 -7z"/> +<path d="M847 1183 c-4 -3 -7 -23 -7 -44 0 -32 3 -36 20 -32 16 4 20 14 20 44 +0 37 -15 51 -33 32z"/> +<path d="M2122 1159 c2 -37 7 -45 26 -47 20 -3 22 1 22 37 0 23 -4 41 -9 41 +-5 0 -17 3 -26 6 -14 6 -16 0 -13 -37z"/> +<path d="M380 1136 l-45 -12 -3 -72 c-3 -80 -5 -78 71 -66 l37 7 0 78 c0 44 +-3 79 -7 78 -5 -1 -28 -6 -53 -13z m28 -127 c-7 -5 -23 -9 -35 -9 -21 0 -23 5 +-23 55 0 53 1 55 33 63 l32 8 3 -54 c2 -37 -1 -58 -10 -63z"/> +<path d="M377 1093 c-14 -13 -7 -63 8 -63 10 0 15 11 15 35 0 33 -8 43 -23 28z"/> +<path d="M2602 1068 c2 -22 9 -34 21 -36 14 -3 17 4 17 32 0 30 -4 36 -21 36 +-17 0 -20 -5 -17 -32z"/> +<path d="M708 1073 c-9 -20 -1 -107 10 -111 8 -2 11 14 10 57 -2 54 -10 76 +-20 54z"/> +<path d="M669 1049 c-8 -40 -5 -89 6 -89 14 0 16 72 3 86 -5 4 -8 5 -9 3z"/> +<path d="M664 860 c1 -58 5 -90 12 -90 7 0 11 32 11 90 -1 61 -4 90 -12 90 -8 +0 -11 -28 -11 -90z"/> +<path d="M704 860 c0 -60 4 -90 12 -90 7 0 11 30 11 90 -1 58 -5 90 -12 90 -7 +0 -11 -32 -11 -90z"/> +<path d="M674 740 c-28 -11 -36 -43 -17 -69 16 -24 55 -28 73 -7 29 36 -13 93 +-56 76z m42 -31 c3 -6 0 -17 -7 -25 -18 -17 -44 -2 -36 20 7 18 33 21 43 5z"/> +<path d="M1504 845 c0 -110 2 -156 3 -103 2 53 2 143 0 200 -1 57 -3 13 -3 +-97z"/> +<path d="M2273 940 c0 -91 4 -139 11 -137 14 5 14 269 0 274 -7 2 -11 -43 -11 +-137z"/> +<path d="M2311 990 c-1 -48 1 -60 14 -60 8 0 15 5 15 10 0 6 -6 10 -12 10 -9 +0 -8 4 2 10 13 9 13 11 0 20 -9 6 -10 10 -3 10 14 0 10 53 -4 57 -6 2 -11 -22 +-12 -57z"/> +<path d="M2313 895 c0 -14 5 -25 12 -25 7 0 13 11 13 25 0 14 -6 25 -13 25 -7 +0 -12 -11 -12 -25z"/> +<path d="M2312 829 c-1 -37 20 -34 24 4 2 17 -2 27 -10 27 -8 0 -13 -13 -14 +-31z"/> +<path d="M2288 743 c-22 -5 -35 -50 -21 -72 13 -21 57 -26 72 -7 27 33 -9 89 +-51 79z m37 -33 c4 -6 1 -18 -6 -26 -11 -13 -14 -13 -27 0 -8 8 -11 19 -8 25 +9 14 33 14 41 1z"/> +<path d="M944 745 c0 -88 2 -123 3 -77 2 46 2 118 0 160 -1 42 -3 5 -3 -83z"/> +<path d="M1568 223 c23 -2 61 -2 85 0 23 2 4 4 -43 4 -47 0 -66 -2 -42 -4z"/> +<path d="M1618 93 c34 -2 90 -2 125 0 34 2 6 3 -63 3 -69 0 -97 -1 -62 -3z"/> +<path d="M199 1694 c-5 -44 -2 -101 6 -107 6 -6 6 -10 -3 -14 -13 -5 -7 -23 9 +-23 11 0 7 136 -4 147 -4 3 -7 2 -8 -3z"/> +<path d="M2789 1620 c-1 -11 -2 -30 -2 -42 -1 -12 3 -23 9 -25 6 -2 11 15 11 +42 1 43 -16 66 -18 25z"/> +<path d="M2750 1547 c0 -20 0 -40 -1 -44 0 -4 4 -9 9 -11 11 -3 11 73 0 84 -5 +4 -8 -9 -8 -29z"/> +<path d="M235 1548 c2 -31 23 -34 23 -3 0 14 -6 25 -13 25 -6 0 -11 -10 -10 +-22z"/> +<path d="M2784 1435 c0 -27 5 -45 12 -45 6 0 11 18 10 45 0 25 -5 45 -11 45 +-6 0 -11 -19 -11 -45z"/> +<path d="M199 1445 c-5 -23 -2 -49 7 -52 6 -2 11 10 12 27 0 16 -4 30 -9 30 +-5 0 -9 -2 -10 -5z"/> +<path d="M239 1448 c0 -2 -2 -22 -3 -45 -2 -28 1 -43 9 -43 7 0 12 17 11 45 0 +25 -4 45 -8 45 -4 0 -8 -1 -9 -2z"/> +<path d="M2749 1445 c-5 -23 -2 -49 7 -52 6 -2 11 10 12 27 0 16 -4 30 -9 30 +-5 0 -9 -2 -10 -5z"/> +<path d="M2745 1243 c1 -85 5 -138 11 -140 7 -2 11 45 10 137 0 92 -3 140 -10 +140 -7 0 -11 -46 -11 -137z"/> +<path d="M199 1345 c-1 -3 -1 -14 -1 -25 0 -46 3 -60 12 -60 5 0 9 20 8 45 -1 +25 -6 45 -10 45 -4 0 -8 -2 -9 -5z"/> +<path d="M235 1220 c0 -71 3 -130 8 -130 10 0 10 -1 12 138 1 83 -2 122 -9 +122 -8 0 -11 -42 -11 -130z"/> +<path d="M2784 1323 c4 -38 25 -41 24 -4 -1 18 -6 31 -14 31 -8 0 -12 -10 -10 +-27z"/> +<path d="M2785 1210 c0 -46 4 -70 11 -70 8 0 12 24 11 70 0 43 -5 70 -11 70 +-7 0 -11 -27 -11 -70z"/> +<path d="M203 1236 c3 -7 0 -19 -6 -25 -8 -8 -8 -11 2 -11 7 0 9 -5 5 -12 -10 +-16 -12 -78 -2 -78 4 0 5 -7 2 -15 -4 -8 -2 -15 4 -15 6 0 10 35 11 85 1 56 +-3 85 -10 85 -6 0 -9 -6 -6 -14z"/> +<path d="M2789 1125 c-1 -3 -2 -14 -2 -25 -2 -29 18 -25 20 5 1 14 -2 25 -8 +25 -5 0 -9 -2 -10 -5z"/> +<path d="M199 985 c-5 -23 -2 -49 7 -52 6 -2 11 10 11 27 0 16 -4 30 -9 30 -4 +0 -8 -2 -9 -5z"/> +<path d="M238 983 c-2 -5 -3 -23 -3 -42 1 -53 21 -49 23 4 2 39 -10 60 -20 38z"/> +<path d="M2749 988 c-7 -19 -1 -118 7 -118 6 0 11 24 11 60 0 33 -4 60 -8 60 +-5 0 -9 -1 -10 -2z"/> +<path d="M2789 988 c0 -2 -2 -29 -3 -60 -2 -38 2 -58 9 -58 8 0 12 22 12 60 0 +33 -4 60 -8 60 -5 0 -9 -1 -10 -2z"/> +<path d="M195 880 c-3 -5 -1 -10 6 -10 8 0 8 -4 -1 -15 -10 -12 -10 -15 4 -15 +10 0 16 9 16 25 0 25 -14 33 -25 15z"/> +<path d="M2744 815 c0 -30 5 -45 13 -45 9 0 13 14 11 45 -1 26 -6 45 -12 45 +-7 0 -12 -18 -12 -45z"/> +<path d="M2785 818 c3 -58 22 -60 22 -3 0 29 -4 45 -12 45 -8 0 -11 -15 -10 +-42z"/> +<path d="M199 828 c-8 -31 -5 -58 6 -58 9 0 13 11 13 30 -1 17 -5 30 -10 30 +-4 0 -8 -1 -9 -2z"/> +<path d="M238 825 c-8 -8 3 -55 13 -55 5 0 9 14 9 30 0 28 -9 38 -22 25z"/> +<path d="M181 718 c-13 -33 9 -63 45 -63 35 0 56 43 34 69 -20 25 -69 20 -79 +-6z m65 -9 c3 -6 0 -17 -7 -25 -18 -17 -44 -2 -36 20 7 18 33 21 43 5z"/> +<path d="M2741 718 c-20 -52 57 -95 80 -45 16 36 -3 67 -42 67 -22 0 -32 -6 +-38 -22z m59 -17 c0 -21 -26 -36 -36 -20 -9 15 3 39 21 39 8 0 15 -9 15 -19z"/> +</g> +</svg> diff --git a/src/components/AppFooter.js b/src/components/AppFooter.js index c853f5b8..58b1dbab 100644 --- a/src/components/AppFooter.js +++ b/src/components/AppFooter.js @@ -4,17 +4,8 @@ import { CFooter } from '@coreui/react' const AppFooter = () => { return ( <CFooter> - <div> - <a href="https://coreui.io" target="_blank" rel="noopener noreferrer"> - CoreUI - </a> - <span className="ms-1">© 2023 creativeLabs.</span> - </div> <div className="ms-auto"> - <span className="me-1">Powered by</span> - <a href="https://coreui.io/react" target="_blank" rel="noopener noreferrer"> - CoreUI React Admin & Dashboard Template - </a> + <span className="me-1">Made with ❤️ by Portico Labs</span> </div> </CFooter> ) diff --git a/src/components/AppHeader.js b/src/components/AppHeader.js index dd5f544e..fbd12353 100644 --- a/src/components/AppHeader.js +++ b/src/components/AppHeader.js @@ -1,22 +1,18 @@ import React from 'react' -import { NavLink } from 'react-router-dom' import { useSelector, useDispatch } from 'react-redux' import { CContainer, CHeader, CHeaderBrand, CHeaderDivider, - CHeaderNav, CHeaderToggler, - CNavLink, - CNavItem, } from '@coreui/react' import CIcon from '@coreui/icons-react' -import { cilBell, cilEnvelopeOpen, cilList, cilMenu } from '@coreui/icons' +import { cilMenu } from '@coreui/icons' +import porticoSVG from 'src/assets/brand/portico-logo-blue.svg' +import { CImage } from '@coreui/react' import { AppBreadcrumb } from './index' -import { AppHeaderDropdown } from './header/index' -import { logo } from 'src/assets/brand/logo' const AppHeader = () => { const dispatch = useDispatch() @@ -32,41 +28,8 @@ const AppHeader = () => { <CIcon icon={cilMenu} size="lg" /> </CHeaderToggler> <CHeaderBrand className="mx-auto d-md-none" to="/"> - <CIcon icon={logo} height={48} alt="Logo" /> + <CImage rounded align="center" src={porticoSVG} width={50} height={50} /> </CHeaderBrand> - <CHeaderNav className="d-none d-md-flex me-auto"> - <CNavItem> - <CNavLink to="/dashboard" component={NavLink}> - Dashboard - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Users</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Settings</CNavLink> - </CNavItem> - </CHeaderNav> - <CHeaderNav> - <CNavItem> - <CNavLink href="#"> - <CIcon icon={cilBell} size="lg" /> - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#"> - <CIcon icon={cilList} size="lg" /> - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#"> - <CIcon icon={cilEnvelopeOpen} size="lg" /> - </CNavLink> - </CNavItem> - </CHeaderNav> - <CHeaderNav className="ms-3"> - <AppHeaderDropdown /> - </CHeaderNav> </CContainer> <CHeaderDivider /> <CContainer fluid> diff --git a/src/components/AppSidebar.js b/src/components/AppSidebar.js index a75bf652..eccd90f1 100644 --- a/src/components/AppSidebar.js +++ b/src/components/AppSidebar.js @@ -1,13 +1,14 @@ import React from 'react' import { useSelector, useDispatch } from 'react-redux' -import { CSidebar, CSidebarBrand, CSidebarNav, CSidebarToggler } from '@coreui/react' -import CIcon from '@coreui/icons-react' +import { CSidebar, CSidebarBrand, CSidebarNav } from '@coreui/react' +// import CIcon from '@coreui/icons-react' + +import { CImage } from '@coreui/react' import { AppSidebarNav } from './AppSidebarNav' -import { logoNegative } from 'src/assets/brand/logo-negative' -import { sygnet } from 'src/assets/brand/sygnet' +import porticoSVG from 'src/assets/brand/portico-logo-white.svg' import SimpleBar from 'simplebar-react' import 'simplebar/dist/simplebar.min.css' @@ -30,18 +31,16 @@ const AppSidebar = () => { }} > <CSidebarBrand className="d-none d-md-flex" to="/"> - <CIcon className="sidebar-brand-full" icon={logoNegative} height={35} /> - <CIcon className="sidebar-brand-narrow" icon={sygnet} height={35} /> + <div className="clearfix" style={{"margin":"2rem"}}> + <CImage rounded align="center" src={porticoSVG} width={150} height={150} /> + <h3 style={{'text-align':'center', 'margin':'0'}}>PORTICO</h3> + </div> </CSidebarBrand> <CSidebarNav> <SimpleBar> <AppSidebarNav items={navigation} /> </SimpleBar> </CSidebarNav> - <CSidebarToggler - className="d-none d-lg-flex" - onClick={() => dispatch({ type: 'set', sidebarUnfoldable: !unfoldable })} - /> </CSidebar> ) } diff --git a/src/routes.js b/src/routes.js index d168b1ca..6972facd 100644 --- a/src/routes.js +++ b/src/routes.js @@ -4,97 +4,28 @@ const Dashboard = React.lazy(() => import('./views/dashboard/Dashboard')) const Colors = React.lazy(() => import('./views/theme/colors/Colors')) const Typography = React.lazy(() => import('./views/theme/typography/Typography')) -// Base -const Accordion = React.lazy(() => import('./views/base/accordion/Accordion')) -const Breadcrumbs = React.lazy(() => import('./views/base/breadcrumbs/Breadcrumbs')) -const Cards = React.lazy(() => import('./views/base/cards/Cards')) -const Carousels = React.lazy(() => import('./views/base/carousels/Carousels')) -const Collapses = React.lazy(() => import('./views/base/collapses/Collapses')) -const ListGroups = React.lazy(() => import('./views/base/list-groups/ListGroups')) -const Navs = React.lazy(() => import('./views/base/navs/Navs')) -const Paginations = React.lazy(() => import('./views/base/paginations/Paginations')) -const Placeholders = React.lazy(() => import('./views/base/placeholders/Placeholders')) -const Popovers = React.lazy(() => import('./views/base/popovers/Popovers')) -const Progress = React.lazy(() => import('./views/base/progress/Progress')) -const Spinners = React.lazy(() => import('./views/base/spinners/Spinners')) -const Tables = React.lazy(() => import('./views/base/tables/Tables')) -const Tooltips = React.lazy(() => import('./views/base/tooltips/Tooltips')) +//PORTICO +const Coretime = React.lazy(() => import('./views/coretime/Coretime')) +const RuntimeUpgrade = React.lazy(() => import('./views/runtime-upgrade/RuntimeUpgrade')) +const Empty = React.lazy(() => import('./views/empty/Empty')) +const Configurator = React.lazy(() => import('./views/configurator/Configurator')) +const ConfiguratorRuntime = React.lazy(() => import('./views/configurator-runtime/ConfiguratorRuntime')) +const ConfiguratorCollators = React.lazy(() => import('./views/configurator-collators/ConfiguratorCollators')) +const ConfiguratorCoretime = React.lazy(() => import('./views/configurator-coretime/ConfiguratorCoretime')) -// Buttons -const Buttons = React.lazy(() => import('./views/buttons/buttons/Buttons')) -const ButtonGroups = React.lazy(() => import('./views/buttons/button-groups/ButtonGroups')) -const Dropdowns = React.lazy(() => import('./views/buttons/dropdowns/Dropdowns')) - -//Forms -const ChecksRadios = React.lazy(() => import('./views/forms/checks-radios/ChecksRadios')) -const FloatingLabels = React.lazy(() => import('./views/forms/floating-labels/FloatingLabels')) -const FormControl = React.lazy(() => import('./views/forms/form-control/FormControl')) -const InputGroup = React.lazy(() => import('./views/forms/input-group/InputGroup')) -const Layout = React.lazy(() => import('./views/forms/layout/Layout')) -const Range = React.lazy(() => import('./views/forms/range/Range')) -const Select = React.lazy(() => import('./views/forms/select/Select')) -const Validation = React.lazy(() => import('./views/forms/validation/Validation')) - -const Charts = React.lazy(() => import('./views/charts/Charts')) - -// Icons -const CoreUIIcons = React.lazy(() => import('./views/icons/coreui-icons/CoreUIIcons')) -const Flags = React.lazy(() => import('./views/icons/flags/Flags')) -const Brands = React.lazy(() => import('./views/icons/brands/Brands')) - -// Notifications -const Alerts = React.lazy(() => import('./views/notifications/alerts/Alerts')) -const Badges = React.lazy(() => import('./views/notifications/badges/Badges')) -const Modals = React.lazy(() => import('./views/notifications/modals/Modals')) -const Toasts = React.lazy(() => import('./views/notifications/toasts/Toasts')) - -const Widgets = React.lazy(() => import('./views/widgets/Widgets')) const routes = [ - { path: '/', exact: true, name: 'Home' }, + { path: '/', exact: true, name: 'Welcome' , element: Empty}, { path: '/dashboard', name: 'Dashboard', element: Dashboard }, { path: '/theme', name: 'Theme', element: Colors, exact: true }, { path: '/theme/colors', name: 'Colors', element: Colors }, { path: '/theme/typography', name: 'Typography', element: Typography }, - { path: '/base', name: 'Base', element: Cards, exact: true }, - { path: '/base/accordion', name: 'Accordion', element: Accordion }, - { path: '/base/breadcrumbs', name: 'Breadcrumbs', element: Breadcrumbs }, - { path: '/base/cards', name: 'Cards', element: Cards }, - { path: '/base/carousels', name: 'Carousel', element: Carousels }, - { path: '/base/collapses', name: 'Collapse', element: Collapses }, - { path: '/base/list-groups', name: 'List Groups', element: ListGroups }, - { path: '/base/navs', name: 'Navs', element: Navs }, - { path: '/base/paginations', name: 'Paginations', element: Paginations }, - { path: '/base/placeholders', name: 'Placeholders', element: Placeholders }, - { path: '/base/popovers', name: 'Popovers', element: Popovers }, - { path: '/base/progress', name: 'Progress', element: Progress }, - { path: '/base/spinners', name: 'Spinners', element: Spinners }, - { path: '/base/tables', name: 'Tables', element: Tables }, - { path: '/base/tooltips', name: 'Tooltips', element: Tooltips }, - { path: '/buttons', name: 'Buttons', element: Buttons, exact: true }, - { path: '/buttons/buttons', name: 'Buttons', element: Buttons }, - { path: '/buttons/dropdowns', name: 'Dropdowns', element: Dropdowns }, - { path: '/buttons/button-groups', name: 'Button Groups', element: ButtonGroups }, - { path: '/charts', name: 'Charts', element: Charts }, - { path: '/forms', name: 'Forms', element: FormControl, exact: true }, - { path: '/forms/form-control', name: 'Form Control', element: FormControl }, - { path: '/forms/select', name: 'Select', element: Select }, - { path: '/forms/checks-radios', name: 'Checks & Radios', element: ChecksRadios }, - { path: '/forms/range', name: 'Range', element: Range }, - { path: '/forms/input-group', name: 'Input Group', element: InputGroup }, - { path: '/forms/floating-labels', name: 'Floating Labels', element: FloatingLabels }, - { path: '/forms/layout', name: 'Layout', element: Layout }, - { path: '/forms/validation', name: 'Validation', element: Validation }, - { path: '/icons', exact: true, name: 'Icons', element: CoreUIIcons }, - { path: '/icons/coreui-icons', name: 'CoreUI Icons', element: CoreUIIcons }, - { path: '/icons/flags', name: 'Flags', element: Flags }, - { path: '/icons/brands', name: 'Brands', element: Brands }, - { path: '/notifications', name: 'Notifications', element: Alerts, exact: true }, - { path: '/notifications/alerts', name: 'Alerts', element: Alerts }, - { path: '/notifications/badges', name: 'Badges', element: Badges }, - { path: '/notifications/modals', name: 'Modals', element: Modals }, - { path: '/notifications/toasts', name: 'Toasts', element: Toasts }, - { path: '/widgets', name: 'Widgets', element: Widgets }, + { path: '/coretime', name: 'Coretime', element: Coretime }, + { path: '/runtime-upgrade', name: 'Runtime Upgrade', element: RuntimeUpgrade }, + { path: '/configure', name: 'Configure Deployment', element: Configurator }, + { path: '/configure/runtime', name: 'Runtime', element: ConfiguratorRuntime }, + { path: '/configure/collators', name: 'Network Topology', element: ConfiguratorCollators }, + { path: '/configure/coretime', name: 'Coretime', element: ConfiguratorCoretime }, ] export default routes diff --git a/src/views/base/accordion/Accordion.js b/src/views/base/accordion/Accordion.js deleted file mode 100644 index 21e88215..00000000 --- a/src/views/base/accordion/Accordion.js +++ /dev/null @@ -1,177 +0,0 @@ -import React from 'react' -import { - CCard, - CCardBody, - CCardHeader, - CCol, - CRow, - CAccordion, - CAccordionBody, - CAccordionHeader, - CAccordionItem, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const Accordion = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Accordion</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Click the accordions below to expand/collapse the accordion content. - </p> - <DocsExample href="components/accordion"> - <CAccordion activeItemKey={2}> - <CAccordionItem itemKey={1}> - <CAccordionHeader>Accordion Item #1</CAccordionHeader> - <CAccordionBody> - <strong>This is the first item's accordion body.</strong> It is hidden by - default, until the collapse plugin adds the appropriate classes that we use to - style each element. These classes control the overall appearance, as well as the - showing and hiding via CSS transitions. You can modify any of this with custom - CSS or overriding our default variables. It's also worth noting that just - about any HTML can go within the <code>.accordion-body</code>, though the - transition does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={2}> - <CAccordionHeader>Accordion Item #2</CAccordionHeader> - <CAccordionBody> - <strong>This is the second item's accordion body.</strong> It is hidden by - default, until the collapse plugin adds the appropriate classes that we use to - style each element. These classes control the overall appearance, as well as the - showing and hiding via CSS transitions. You can modify any of this with custom - CSS or overriding our default variables. It's also worth noting that just - about any HTML can go within the <code>.accordion-body</code>, though the - transition does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={3}> - <CAccordionHeader>Accordion Item #3</CAccordionHeader> - <CAccordionBody> - <strong>This is the second item's accordion body.</strong> It is hidden by - default, until the collapse plugin adds the appropriate classes that we use to - style each element. These classes control the overall appearance, as well as the - showing and hiding via CSS transitions. You can modify any of this with custom - CSS or overriding our default variables. It's also worth noting that just - about any HTML can go within the <code>.accordion-body</code>, though the - transition does limit overflow. - </CAccordionBody> - </CAccordionItem> - </CAccordion> - </DocsExample> - </CCardBody> - </CCard> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Accordion</strong> <small>Flush</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>flush</code> to remove the default <code>background-color</code>, some - borders, and some rounded corners to render accordions edge-to-edge with their parent - container. - </p> - <DocsExample href="components/accordion#flush"> - <CAccordion flush> - <CAccordionItem itemKey={1}> - <CAccordionHeader>Accordion Item #1</CAccordionHeader> - <CAccordionBody> - <strong>This is the first item's accordion body.</strong> It is hidden by - default, until the collapse plugin adds the appropriate classes that we use to - style each element. These classes control the overall appearance, as well as the - showing and hiding via CSS transitions. You can modify any of this with custom - CSS or overriding our default variables. It's also worth noting that just - about any HTML can go within the <code>.accordion-body</code>, though the - transition does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={2}> - <CAccordionHeader>Accordion Item #2</CAccordionHeader> - <CAccordionBody> - <strong>This is the second item's accordion body.</strong> It is hidden by - default, until the collapse plugin adds the appropriate classes that we use to - style each element. These classes control the overall appearance, as well as the - showing and hiding via CSS transitions. You can modify any of this with custom - CSS or overriding our default variables. It's also worth noting that just - about any HTML can go within the <code>.accordion-body</code>, though the - transition does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={3}> - <CAccordionHeader>Accordion Item #3</CAccordionHeader> - <CAccordionBody> - <strong>This is the second item's accordion body.</strong> It is hidden by - default, until the collapse plugin adds the appropriate classes that we use to - style each element. These classes control the overall appearance, as well as the - showing and hiding via CSS transitions. You can modify any of this with custom - CSS or overriding our default variables. It's also worth noting that just - about any HTML can go within the <code>.accordion-body</code>, though the - transition does limit overflow. - </CAccordionBody> - </CAccordionItem> - </CAccordion> - </DocsExample> - </CCardBody> - </CCard> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Accordion</strong> <small>Always open</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>alwaysOpen</code> property to make accordion items stay open when another - item is opened. - </p> - <DocsExample href="components/accordion#flush"> - <CAccordion alwaysOpen> - <CAccordionItem itemKey={1}> - <CAccordionHeader>Accordion Item #1</CAccordionHeader> - <CAccordionBody> - <strong>This is the first item's accordion body.</strong> It is hidden by - default, until the collapse plugin adds the appropriate classes that we use to - style each element. These classes control the overall appearance, as well as the - showing and hiding via CSS transitions. You can modify any of this with custom - CSS or overriding our default variables. It's also worth noting that just - about any HTML can go within the <code>.accordion-body</code>, though the - transition does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={2}> - <CAccordionHeader>Accordion Item #2</CAccordionHeader> - <CAccordionBody> - <strong>This is the second item's accordion body.</strong> It is hidden by - default, until the collapse plugin adds the appropriate classes that we use to - style each element. These classes control the overall appearance, as well as the - showing and hiding via CSS transitions. You can modify any of this with custom - CSS or overriding our default variables. It's also worth noting that just - about any HTML can go within the <code>.accordion-body</code>, though the - transition does limit overflow. - </CAccordionBody> - </CAccordionItem> - <CAccordionItem itemKey={3}> - <CAccordionHeader>Accordion Item #3</CAccordionHeader> - <CAccordionBody> - <strong>This is the second item's accordion body.</strong> It is hidden by - default, until the collapse plugin adds the appropriate classes that we use to - style each element. These classes control the overall appearance, as well as the - showing and hiding via CSS transitions. You can modify any of this with custom - CSS or overriding our default variables. It's also worth noting that just - about any HTML can go within the <code>.accordion-body</code>, though the - transition does limit overflow. - </CAccordionBody> - </CAccordionItem> - </CAccordion> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Accordion diff --git a/src/views/base/breadcrumbs/Breadcrumbs.js b/src/views/base/breadcrumbs/Breadcrumbs.js deleted file mode 100644 index 8ddd0cc0..00000000 --- a/src/views/base/breadcrumbs/Breadcrumbs.js +++ /dev/null @@ -1,74 +0,0 @@ -import React from 'react' -import { - CBreadcrumb, - CBreadcrumbItem, - CCard, - CCardBody, - CCardHeader, - CCol, - CRow, - CLink, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const Breadcrumbs = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Breadcrumb</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - The breadcrumb navigation provides links back to each previous page the user navigated - through and shows the current location in a website or an application. You don’t have - to add separators, because they automatically added in CSS through{' '} - <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/::before"> - {' '} - <code>::before</code> - </a>{' '} - and{' '} - <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/content"> - {' '} - <code>content</code> - </a> - . - </p> - <DocsExample href="components/breadcrumb"> - <CBreadcrumb> - <CBreadcrumbItem> - <CLink href="#">Home</CLink> - </CBreadcrumbItem> - <CBreadcrumbItem active>Library</CBreadcrumbItem> - </CBreadcrumb> - <CBreadcrumb> - <CBreadcrumbItem> - <CLink href="#">Home</CLink> - </CBreadcrumbItem> - <CBreadcrumbItem> - <CLink href="#">Library</CLink> - </CBreadcrumbItem> - <CBreadcrumbItem active>Data</CBreadcrumbItem> - </CBreadcrumb> - <CBreadcrumb> - <CBreadcrumbItem> - <CLink href="#">Home</CLink> - </CBreadcrumbItem> - <CBreadcrumbItem> - <CLink href="#">Library</CLink> - </CBreadcrumbItem> - <CBreadcrumbItem> - <CLink href="#">Data</CLink> - </CBreadcrumbItem> - <CBreadcrumbItem active>Bootstrap</CBreadcrumbItem> - </CBreadcrumb> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Breadcrumbs diff --git a/src/views/base/cards/Cards.js b/src/views/base/cards/Cards.js deleted file mode 100644 index b9bdfffc..00000000 --- a/src/views/base/cards/Cards.js +++ /dev/null @@ -1,906 +0,0 @@ -import React from 'react' -import { - CButton, - CCard, - CCardBody, - CCardFooter, - CCardGroup, - CCardHeader, - CCardImage, - CCardLink, - CCardSubtitle, - CCardText, - CCardTitle, - CListGroup, - CListGroupItem, - CNav, - CNavItem, - CNavLink, - CCol, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -import ReactImg from 'src/assets/images/react.jpg' - -const Cards = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Example</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Cards are built with as little markup and styles as possible but still manage to - deliver a bunch of control and customization. Built with flexbox, they offer easy - alignment and mix well with other CoreUI components. Cards have no top, left, and - right margins by default, so use{' '} - <a href="https://coreui.io/docs/utilities/spacing">spacing utilities</a> as needed. - They have no fixed width to start, so they'll fill the full width of its parent. - </p> - <p className="text-medium-emphasis small"> - Below is an example of a basic card with mixed content and a fixed width. Cards have - no fixed width to start, so they'll naturally fill the full width of its parent - element. - </p> - <DocsExample href="components/card"> - <CCard style={{ width: '18rem' }}> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the - card's content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Body</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - The main block of a card is the <code><CCardBody></code>. Use it whenever you - need a padded section within a card. - </p> - <DocsExample href="components/card/#body"> - <CCard> - <CCardBody>This is some text within a card body.</CCardBody> - </CCard> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Titles, text, and links</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Card titles are managed by <code><CCardTitle></code> component. Identically, - links are attached and collected next to each other by <code><CCardLink></code>{' '} - component. - </p> - <p className="text-medium-emphasis small"> - Subtitles are managed by <code><CCardSubtitle></code> component. If the{' '} - <code><CCardTitle></code> also, the <code><CCardSubtitle></code> items are - stored in a <code><CCardBody></code> item, the card title, and subtitle are - arranged rightly. - </p> - <DocsExample href="components/card/#titles-text-and-links"> - <CCard style={{ width: '18rem' }}> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardSubtitle className="mb-2 text-medium-emphasis">Card subtitle</CCardSubtitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the - card's content. - </CCardText> - <CCardLink href="#">Card link</CCardLink> - <CCardLink href="#">Another link</CCardLink> - </CCardBody> - </CCard> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Images</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - <code>.card-img-top</code> places a picture to the top of the card. With{' '} - <code>.card-text</code>, text can be added to the card. Text within{' '} - <code>.card-text</code> can additionally be styled with the regular HTML tags. - </p> - <DocsExample href="components/card/#images"> - <CCard style={{ width: '18rem' }}> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the - card's content. - </CCardText> - </CCardBody> - </CCard> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>List groups</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Create lists of content in a card with a flush list group. - </p> - <DocsExample href="components/card/#list-groups"> - <CRow> - <CCol lg={4}> - <CCard> - <CListGroup flush> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> - </CCard> - </CCol> - <CCol lg={4}> - <CCard> - <CCardHeader>Header</CCardHeader> - <CListGroup flush> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> - </CCard> - </CCol> - <CCol lg={4}> - <CCard> - <CListGroup flush> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> - <CCardFooter>Footer</CCardFooter> - </CCard> - </CCol> - </CRow> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Kitchen sink</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Combine and match many content types to build the card you need, or throw everything - in there. Shown below are image styles, blocks, text styles, and a list group—all - wrapped in a fixed-width card. - </p> - <DocsExample href="components/card/#kitchen-sink"> - <CCard style={{ width: '18rem' }}> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the - card's content. - </CCardText> - </CCardBody> - <CListGroup flush> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> - <CCardBody> - <CCardLink href="#">Card link</CCardLink> - <CCardLink href="#">Another link</CCardLink> - </CCardBody> - </CCard> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Header and footer</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add an optional header and/or footer within a card. - </p> - <DocsExample href="components/card/#header-and-footer"> - <CCard> - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </DocsExample> - <p className="text-medium-emphasis small"> - Card headers can be styled by adding ex. <code>component="h5"</code>. - </p> - <DocsExample href="components/card/#header-and-footer"> - <CCard> - <CCardHeader component="h5">Header</CCardHeader> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </DocsExample> - <DocsExample href="components/card/#header-and-footer"> - <CCard> - <CCardHeader>Quote</CCardHeader> - <CCardBody> - <blockquote className="blockquote mb-0"> - <p> - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat - a ante. - </p> - <footer className="blockquote-footer"> - Someone famous in <cite title="Source Title">Source Title</cite> - </footer> - </blockquote> - </CCardBody> - </CCard> - </DocsExample> - <DocsExample href="components/card/#header-and-footer"> - <CCard className="text-center"> - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - <CCardFooter className="text-medium-emphasis">2 days ago</CCardFooter> - </CCard> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Body</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Cards assume no specific <code>width</code> to start, so they'll be 100% wide - unless otherwise stated. You can adjust this as required with custom CSS, grid - classes, grid Sass mixins, or services. - </p> - <h3>Using grid markup</h3> - <p className="text-medium-emphasis small"> - Using the grid, wrap cards in columns and rows as needed. - </p> - <DocsExample href="components/card/#sizing"> - <CRow> - <CCol sm={6}> - <CCard> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </CCol> - <CCol sm={6}> - <CCard> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </CCol> - </CRow> - </DocsExample> - <h3>Using utilities</h3> - <p className="text-medium-emphasis small"> - Use some of{' '} - <a href="https://coreui.io/docs/utilities/sizing/">available sizing utilities</a> to - rapidly set a card's width. - </p> - <DocsExample href="components/card/#sizing"> - <CCard className="w-75"> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - <CCard className="w-50"> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </DocsExample> - <strong>Using custom CSS</strong> - <p className="text-medium-emphasis small"> - Use custom CSS in your stylesheets or as inline styles to set a width. - </p> - <DocsExample href="components/card/#sizing"> - <CCard style={{ width: '18rem' }}> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Text alignment</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - You can instantly change the text arrangement of any card—in its whole or specific - parts—with{' '} - <a href="https://coreui.io/docs/utilities/text/#text-alignment">text align classes</a> - . - </p> - <DocsExample href="components/card/#text-alignment"> - <CCard style={{ width: '18rem' }}> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - <CCard className="text-center" style={{ width: '18rem' }}> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - <CCard className="text-end" style={{ width: '18rem' }}> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Navigation</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add some navigation to a <code><CCardHeader></code> with our{' '} - <code><CNav></code> component. - </p> - <DocsExample href="components/card/##navigation"> - <CCard className="text-center"> - <CCardHeader> - <CNav variant="tabs" className="card-header-tabs"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </CCardHeader> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </DocsExample> - <DocsExample href="components/card/##navigation"> - <CCard className="text-center"> - <CCardHeader> - <CNav variant="pills" className="card-header-pills"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </CCardHeader> - <CCardBody> - <CCardTitle>Special title treatment</CCardTitle> - <CCardText> - With supporting text below as a natural lead-in to additional content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Image caps</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Similar to headers and footers, cards can include top and bottom "image - caps"—images at the top or bottom of a card. - </p> - <DocsExample href="components/card/#image-caps"> - <CRow> - <CCol lg={6}> - <CCard className="mb-3"> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - <CCardText> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardText> - </CCardBody> - </CCard> - </CCol> - <CCol lg={6}> - <CCard className="mb-3"> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - <CCardText> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardText> - </CCardBody> - <CCardImage orientation="bottom" src={ReactImg} /> - </CCard> - </CCol> - </CRow> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Card styles</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Cards include various options for customizing their backgrounds, borders, and color. - </p> - <h3>Background and color</h3> - <p className="text-medium-emphasis small"> - Use <code>color</code> property to change the appearance of a card. - </p> - <DocsExample href="components/card/#background-and-color"> - <CRow> - {[ - { color: 'primary', textColor: 'white' }, - { color: 'secondary', textColor: 'white' }, - { color: 'success', textColor: 'white' }, - { color: 'danger', textColor: 'white' }, - { color: 'warning' }, - { color: 'info', textColor: 'white' }, - { color: 'light' }, - { color: 'dark', textColor: 'white' }, - ].map((item, index) => ( - <CCol lg={4} key={index}> - <CCard color={item.color} textColor={item.textColor} className="mb-3"> - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>{item.color} card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of - the card's content. - </CCardText> - </CCardBody> - </CCard> - </CCol> - ))} - </CRow> - </DocsExample> - <h3>Border</h3> - <p className="text-medium-emphasis small"> - Use <a href="https://coreui.io/docs/utilities/borders/">border utilities</a> to change - just the <code>border-color</code> of a card. Note that you can set{' '} - <code>textColor</code> property on the <code><CCard></code> or a subset of the - card's contents as shown below. - </p> - <DocsExample href="components/card/#border"> - <CRow> - {[ - { color: 'primary', textColor: 'primary' }, - { color: 'secondary', textColor: 'secondary' }, - { color: 'success', textColor: 'success' }, - { color: 'danger', textColor: 'danger' }, - { color: 'warning', textColor: 'warning' }, - { color: 'info', textColor: 'info' }, - { color: 'light' }, - { color: 'dark' }, - ].map((item, index) => ( - <CCol lg={4} key={index}> - <CCard textColor={item.textColor} className={`mb-3 border-${item.color}`}> - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>{item.color} card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of - the card's content. - </CCardText> - </CCardBody> - </CCard> - </CCol> - ))} - </CRow> - </DocsExample> - <h3>Top border</h3> - <p className="text-medium-emphasis small"> - Use <a href="https://coreui.io/docs/utilities/borders/">border utilities</a> to change - just the <code>border-color</code> of a card. Note that you can set{' '} - <code>textColor</code> property on the <code><CCard></code> or a subset of the - card's contents as shown below. - </p> - <DocsExample href="components/card/#top-border"> - <CRow> - {[ - { color: 'primary', textColor: 'primary' }, - { color: 'secondary', textColor: 'secondary' }, - { color: 'success', textColor: 'success' }, - { color: 'danger', textColor: 'danger' }, - { color: 'warning', textColor: 'warning' }, - { color: 'info', textColor: 'info' }, - { color: 'light' }, - { color: 'dark' }, - ].map((item, index) => ( - <CCol lg={4} key={index}> - <CCard - textColor={item.textColor} - className={`mb-3 border-top-${item.color} border-top-3`} - > - <CCardHeader>Header</CCardHeader> - <CCardBody> - <CCardTitle>{item.color} card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of - the card's content. - </CCardText> - </CCardBody> - </CCard> - </CCol> - ))} - </CRow> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Card groups</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use card groups to render cards as a single, attached element with equal width and - height columns. Card groups start off stacked and use <code>display: flex;</code> to - become attached with uniform dimensions starting at the <code>sm</code> breakpoint. - </p> - <DocsExample href="components/card/#card-groups"> - <CCardGroup> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - <CCardText> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardText> - </CCardBody> - </CCard> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This card has supporting text below as a natural lead-in to additional - content. - </CCardText> - <CCardText> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardText> - </CCardBody> - </CCard> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This card has even longer content than the first to show - that equal height action. - </CCardText> - <CCardText> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardText> - </CCardBody> - </CCard> - </CCardGroup> - </DocsExample> - <p className="text-medium-emphasis small"> - When using card groups with footers, their content will automatically line up. - </p> - <DocsExample href="components/card/#card-groups"> - <CCardGroup> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This card has supporting text below as a natural lead-in to additional - content. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This card has even longer content than the first to show - that equal height action. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCardGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Card</strong> <small>Grid cards</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use the <code>CRow</code> component and set{' '} - <code>{xs|sm|md|lg|xl|xxl}={{ cols: * }}</code> property - to control how many grid columns (wrapped around your cards) you show per row. For - example, here's <code>xs={{cols: 1}}</code> laying out the - cards on one column, and <code>md={{cols: 1}}</code> splitting - four cards to equal width across multiple rows, from the medium breakpoint up. - </p> - <DocsExample href="components/card/#grid-cards"> - <CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 2 }}> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - </CRow> - </DocsExample> - <p className="text-medium-emphasis small"> - Change it to <code>md={{ cols: 3}}</code> and you'll see the - fourth card wrap. - </p> - <DocsExample href="components/card/#grid-cards"> - <CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 3 }}> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - <CCol xs> - <CCard> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - This is a wider card with supporting text below as a natural lead-in to - additional content. This content is a little bit longer. - </CCardText> - </CCardBody> - <CCardFooter> - <small className="text-medium-emphasis">Last updated 3 mins ago</small> - </CCardFooter> - </CCard> - </CCol> - </CRow> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Cards diff --git a/src/views/base/carousels/Carousels.js b/src/views/base/carousels/Carousels.js deleted file mode 100644 index 3f09b3b3..00000000 --- a/src/views/base/carousels/Carousels.js +++ /dev/null @@ -1,212 +0,0 @@ -import React from 'react' -import { - CCard, - CCardBody, - CCardHeader, - CCarousel, - CCarouselCaption, - CCarouselItem, - CCol, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -import AngularImg from 'src/assets/images/angular.jpg' -import ReactImg from 'src/assets/images/react.jpg' -import VueImg from 'src/assets/images/vue.jpg' - -const slidesLight = [ - 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22800%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20800%20400%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_1607923e7e2%20text%20%7B%20fill%3A%23AAA%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A40pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_1607923e7e2%22%3E%3Crect%20width%3D%22800%22%20height%3D%22400%22%20fill%3D%22%23F5F5F5%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22285.9296875%22%20y%3D%22217.75625%22%3EFirst%20slide%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E', - 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22800%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20800%20400%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_15ba800aa20%20text%20%7B%20fill%3A%23BBB%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A40pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_15ba800aa20%22%3E%3Crect%20width%3D%22800%22%20height%3D%22400%22%20fill%3D%22%23EEE%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22247.3203125%22%20y%3D%22218.3%22%3ESecond%20slide%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E', - 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22800%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20800%20400%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_15ba800aa21%20text%20%7B%20fill%3A%23999%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A40pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_15ba800aa21%22%3E%3Crect%20width%3D%22800%22%20height%3D%22400%22%20fill%3D%22%23E5E5E5%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22277%22%20y%3D%22218.3%22%3EThird%20slide%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E', -] - -const Carousels = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Carousel</strong> <small>Slide only</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small">Here’s a carousel with slides</p> - <DocsExample href="components/carousel"> - <CCarousel> - <CCarouselItem> - <img className="d-block w-100" src={ReactImg} alt="slide 1" /> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={AngularImg} alt="slide 2" /> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={VueImg} alt="slide 3" /> - </CCarouselItem> - </CCarousel> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Carousel</strong> <small>With controls</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Adding in the previous and next controls by <code>controls</code> property. - </p> - <DocsExample href="components/carousel/#with-controls"> - <CCarousel controls> - <CCarouselItem> - <img className="d-block w-100" src={ReactImg} alt="slide 1" /> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={AngularImg} alt="slide 2" /> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={VueImg} alt="slide 3" /> - </CCarouselItem> - </CCarousel> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Carousel</strong> <small>With indicators</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - You can attach the indicators to the carousel, lengthwise the controls, too. - </p> - <DocsExample href="components/carousel/#with-indicators"> - <CCarousel controls indicators> - <CCarouselItem> - <img className="d-block w-100" src={ReactImg} alt="slide 1" /> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={AngularImg} alt="slide 2" /> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={VueImg} alt="slide 3" /> - </CCarouselItem> - </CCarousel> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Carousel</strong> <small>With captions</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - You can add captions to slides with the <code><CCarouselCaption></code> element - within any <code><CCarouselItem></code>. They can be immediately hidden on - smaller viewports, as shown below, with optional{' '} - <a href="https://coreui.io/4.0/utilities/display">display utilities</a>. We hide them - with <code>.d-none</code> and draw them back on medium-sized devices with{' '} - <code>.d-md-block</code>. - </p> - <DocsExample href="components/carousel/#with-captions"> - <CCarousel controls indicators> - <CCarouselItem> - <img className="d-block w-100" src={ReactImg} alt="slide 1" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>First slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={AngularImg} alt="slide 2" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Second slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={VueImg} alt="slide 3" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Third slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - </CCarousel> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Carousel</strong> <small>Crossfade</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>transition="crossfade"</code> to your carousel to animate slides - with a fade transition instead of a slide. - </p> - <DocsExample href="components/carousel/#crossfade"> - <CCarousel controls transition="crossfade"> - <CCarouselItem> - <img className="d-block w-100" src={ReactImg} alt="slide 1" /> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={AngularImg} alt="slide 2" /> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={VueImg} alt="slide 3" /> - </CCarouselItem> - </CCarousel> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Carousel</strong> <small>Dark variant</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>dark</code> property to the <code>CCarousel</code> for darker controls, - indicators, and captions. Controls have been inverted from their default white fill - with the <code>filter</code> CSS property. Captions and controls have additional Sass - variables that customize the <code>color</code> and <code>background-color</code>. - </p> - <DocsExample href="components/carousel/#dark-variant"> - <CCarousel controls indicators dark> - <CCarouselItem> - <img className="d-block w-100" src={slidesLight[0]} alt="slide 1" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>First slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={slidesLight[1]} alt="slide 2" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Second slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - <CCarouselItem> - <img className="d-block w-100" src={slidesLight[2]} alt="slide 3" /> - <CCarouselCaption className="d-none d-md-block"> - <h5>Third slide label</h5> - <p>Some representative placeholder content for the first slide.</p> - </CCarouselCaption> - </CCarouselItem> - </CCarousel> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Carousels diff --git a/src/views/base/collapses/Collapses.js b/src/views/base/collapses/Collapses.js deleted file mode 100644 index 37e608e0..00000000 --- a/src/views/base/collapses/Collapses.js +++ /dev/null @@ -1,126 +0,0 @@ -import React, { useState } from 'react' -import { CButton, CCard, CCardBody, CCardHeader, CCol, CCollapse, CRow } from '@coreui/react' -import { DocsExample } from 'src/components' - -const Collapses = () => { - const [visible, setVisible] = useState(false) - const [visibleHorizontal, setVisibleHorizontal] = useState(false) - const [visibleA, setVisibleA] = useState(false) - const [visibleB, setVisibleB] = useState(false) - - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Collapse</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small">You can use a link or a button component.</p> - <DocsExample href="components/collapse"> - <CButton - href="#" - onClick={(e) => { - e.preventDefault() - setVisible(!visible) - }} - > - Link - </CButton> - <CButton onClick={() => setVisible(!visible)}>Button</CButton> - <CCollapse visible={visible}> - <CCard className="mt-3"> - <CCardBody> - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry - richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes - anderson cred nesciunt sapiente ea proident. - </CCardBody> - </CCard> - </CCollapse> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Collapse</strong> <small> Horizontal</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small">You can use a link or a button component.</p> - <DocsExample href="components/collapse#horizontal"> - <CButton - className="mb-3" - onClick={() => setVisibleHorizontal(!visibleHorizontal)} - aria-expanded={visibleHorizontal} - aria-controls="collapseWidthExample" - > - Button - </CButton> - <div style={{ minHeight: '120px' }}> - <CCollapse id="collapseWidthExample" horizontal visible={visibleHorizontal}> - <CCard style={{ width: '300px' }}> - <CCardBody> - This is some placeholder content for a horizontal collapse. It's hidden by - default and shown when triggered. - </CCardBody> - </CCard> - </CCollapse> - </div> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Collapse</strong> <small> multi target</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - A <code><CButton></code> can show and hide multiple elements. - </p> - <DocsExample href="components/collapse#multiple-targets"> - <CButton onClick={() => setVisibleA(!visibleA)}>Toggle first element</CButton> - <CButton onClick={() => setVisibleB(!visibleB)}>Toggle second element</CButton> - <CButton - onClick={() => { - setVisibleA(!visibleA) - setVisibleB(!visibleB) - }} - > - Toggle both elements - </CButton> - <CRow> - <CCol xs={6}> - <CCollapse visible={visibleA}> - <CCard className="mt-3"> - <CCardBody> - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry - richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes - anderson cred nesciunt sapiente ea proident. - </CCardBody> - </CCard> - </CCollapse> - </CCol> - <CCol xs={6}> - <CCollapse visible={visibleB}> - <CCard className="mt-3"> - <CCardBody> - Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry - richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes - anderson cred nesciunt sapiente ea proident. - </CCardBody> - </CCard> - </CCollapse> - </CCol> - </CRow> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Collapses diff --git a/src/views/base/index.js b/src/views/base/index.js deleted file mode 100644 index 2b7656c8..00000000 --- a/src/views/base/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import Breadcrumbs from './Breadcrumbs' -import Cards from './Cards' -import Carousels from './Carousels' -import Collapses from './Collapses' -import Dropdowns from './Dropdowns' -import Jumbotrons from './Jumbotrons' -import ListGroups from './ListGroups' -import Navbars from './Navbars' -import Navs from './Navs' -import Paginations from './Paginations' -import Popovers from './Popovers' -import ProgressBar from './ProgressBar' -import Tabs from './Tabs' -import Tooltips from './Tooltips' - -export { - Breadcrumbs, - Cards, - Carousels, - Collapses, - Dropdowns, - Jumbotrons, - ListGroups, - Navbars, - Navs, - Popovers, - ProgressBar, - Tabs, - Tooltips, - Paginations, -} diff --git a/src/views/base/jumbotrons/Jumbotrons.js b/src/views/base/jumbotrons/Jumbotrons.js deleted file mode 100644 index 56068136..00000000 --- a/src/views/base/jumbotrons/Jumbotrons.js +++ /dev/null @@ -1,56 +0,0 @@ -import React from 'react' -import { CButton, CCard, CCardBody, CCardHeader, CCol, CContainer, CRow } from '@coreui/react' -import { DocsLink } from 'src/components' - -const Jumbotrons = () => { - return ( - <> - <CCard className="mb-4"> - <CCardHeader> - Jumbotron - <DocsLink name="CJumbotron" /> - </CCardHeader> - <CCardBody> - <CContainer className="py-5" fluid> - <h1 className="display-5 fw-bold">Custom jumbotron</h1> - <p className="col-md-8 fs-4"> - Using a series of utilities, you can create this jumbotron, just like the one in - previous versions of Bootstrap. Check out the examples below for how you can remix and - restyle it to your liking. - </p> - <CButton size="lg">Example button</CButton> - </CContainer> - <CRow className="align-items-md-stretch"> - <CCol md={6}> - <div className="h-100 p-5 text-white bg-dark rounded-3"> - <h2>Change the background</h2> - <p> - Swap the background-color utility and add a `.text-*` color utility to mix up the - jumbotron look. Then, mix and match with additional component themes and more. - </p> - <CButton color="light" variant="outline"> - DocsExample button - </CButton> - </div> - </CCol> - <CCol md={6}> - <div className="h-100 p-5 bg-light border rounded-3"> - <h2>Add borders</h2> - <p> - Or, keep it light and add a border for some added definition to the boundaries of - your content. Be sure to look under the hood at the source HTML here as we've - adjusted the alignment and sizing of both column's content for equal-height. - </p> - <CButton color="secondary" variant="outline"> - DocsExample button - </CButton> - </div> - </CCol> - </CRow> - </CCardBody> - </CCard> - </> - ) -} - -export default Jumbotrons diff --git a/src/views/base/list-groups/ListGroups.js b/src/views/base/list-groups/ListGroups.js deleted file mode 100644 index 91cfbf1e..00000000 --- a/src/views/base/list-groups/ListGroups.js +++ /dev/null @@ -1,346 +0,0 @@ -import React from 'react' -import { - CBadge, - CCard, - CCardBody, - CCardHeader, - CCol, - CFormCheck, - CListGroup, - CListGroupItem, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const ListGroups = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React List Group</strong> <small>Basic example</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - The default list group is an unordered list with items and the proper CSS classes. - Build upon it with the options that follow, or with your CSS as required. - </p> - <DocsExample href="components/list-group"> - <CListGroup> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Morbi leo risus</CListGroupItem> - <CListGroupItem>Porta ac consectetur ac</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React List Group</strong> <small>Active items</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>active</code> boolean property to a <code><CListGroupItem></code> to - show the current active selection. - </p> - <DocsExample href="components/list-group/#active-items"> - <CListGroup> - <CListGroupItem active>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Morbi leo risus</CListGroupItem> - <CListGroupItem>Porta ac consectetur ac</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React List Group</strong> <small>Disabled items</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>disabled</code> boolean property to a <code><CListGroupItem></code> to - make it appear disabled. - </p> - <DocsExample href="components/list-group/#disabled-items"> - <CListGroup> - <CListGroupItem disabled>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Morbi leo risus</CListGroupItem> - <CListGroupItem>Porta ac consectetur ac</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React List Group</strong> <small>Links and buttons</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use <code><a></code>s or <code><button></code>s to create{' '} - <em>actionable</em> list group items with hover, disabled, and active states by adding{' '} - <code>component="a|button"</code>. We separate these pseudo-classes to ensure - list groups made of non-interactive elements (like <code><li></code>s or{' '} - <code><div></code> - s) don'tprovide a click or tap affordance. - </p> - <DocsExample href="components/list-group/#links-and-buttons"> - <CListGroup> - <CListGroupItem component="a" href="#" active> - Cras justo odio - </CListGroupItem> - <CListGroupItem component="a" href="#"> - Dapibus ac facilisis in - </CListGroupItem> - <CListGroupItem component="a" href="#"> - Morbi leo risus - </CListGroupItem> - <CListGroupItem component="a" href="#"> - Porta ac consectetur ac - </CListGroupItem> - <CListGroupItem component="a" href="#" disabled> - Vestibulum at eros - </CListGroupItem> - </CListGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React List Group</strong> <small>Flush</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>flush</code> boolean property to remove some borders and rounded corners to - render list group items edge-to-edge in a parent container (e.g., cards). - </p> - <DocsExample href="components/list-group/#flush"> - <CListGroup flush> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Morbi leo risus</CListGroupItem> - <CListGroupItem>Porta ac consectetur ac</CListGroupItem> - <CListGroupItem>Vestibulum at eros</CListGroupItem> - </CListGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React List Group</strong> <small>Horizontal</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>layout="horizontal"</code> to change the layout of list group items - from vertical to horizontal across all breakpoints. Alternatively, choose a responsive - variant <code>.layout="horizontal-{sm | md | lg | xl | xxl}"</code>{' '} - to make a list group horizontal starting at that breakpoint's{' '} - <code>min-width</code>. Currently{' '} - <strong>horizontal list groups cannot be combined with flush list groups.</strong> - </p> - <DocsExample href="components/list-group/#flush"> - {['', '-sm', '-md', '-lg', '-xl', '-xxl'].map((breakpoint, index) => ( - <CListGroup className="mb-2" layout={`horizontal${breakpoint}`} key={index}> - <CListGroupItem>Cras justo odio</CListGroupItem> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - <CListGroupItem>Morbi leo risus</CListGroupItem> - </CListGroup> - ))} - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React List Group</strong> <small>Contextual classes</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use contextual classes to style list items with a stateful background and color. - </p> - <DocsExample href="components/list-group/#contextual-classes"> - <CListGroup> - <CListGroupItem>Dapibus ac facilisis in</CListGroupItem> - {[ - 'primary', - 'secondary', - 'success', - 'danger', - 'warning', - 'info', - 'light', - 'dark', - ].map((color, index) => ( - <CListGroupItem color={color} key={index}> - A simple {color} list group item - </CListGroupItem> - ))} - </CListGroup> - </DocsExample> - <p className="text-medium-emphasis small"> - Contextual classes also work with <code><a></code>s or{' '} - <code><button></code>s. Note the addition of the hover styles here not present - in the previous example. Also supported is the <code>active</code> state; apply it to - indicate an active selection on a contextual list group item. - </p> - <DocsExample href="components/list-group/#contextual-classes"> - <CListGroup> - <CListGroupItem component="a" href="#"> - Dapibus ac facilisis in - </CListGroupItem> - {[ - 'primary', - 'secondary', - 'success', - 'danger', - 'warning', - 'info', - 'light', - 'dark', - ].map((color, index) => ( - <CListGroupItem component="a" href="#" color={color} key={index}> - A simple {color} list group item - </CListGroupItem> - ))} - </CListGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React List Group</strong> <small>With badges</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add badges to any list group item to show unread counts, activity, and more. - </p> - <DocsExample href="components/list-group/#with-badges"> - <CListGroup> - <CListGroupItem className="d-flex justify-content-between align-items-center"> - Cras justo odio - <CBadge color="primary" shape="rounded-pill"> - 14 - </CBadge> - </CListGroupItem> - <CListGroupItem className="d-flex justify-content-between align-items-center"> - Dapibus ac facilisis in - <CBadge color="primary" shape="rounded-pill"> - 2 - </CBadge> - </CListGroupItem> - <CListGroupItem className="d-flex justify-content-between align-items-center"> - Morbi leo risus - <CBadge color="primary" shape="rounded-pill"> - 1 - </CBadge> - </CListGroupItem> - </CListGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React List Group</strong> <small>Custom content</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add nearly any HTML within, even for linked list groups like the one below, with the - help of <a href="https://coreui.io/docs/utilities/flex/">flexbox utilities</a>. - </p> - <DocsExample href="components/list-group/#custom-content"> - <CListGroup> - <CListGroupItem component="a" href="#" active> - <div className="d-flex w-100 justify-content-between"> - <h5 className="mb-1">List group item heading</h5> - <small>3 days ago</small> - </div> - <p className="mb-1"> - Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus - varius blandit. - </p> - <small>Donec id elit non mi porta.</small> - </CListGroupItem> - <CListGroupItem component="a" href="#"> - <div className="d-flex w-100 justify-content-between"> - <h5 className="mb-1">List group item heading</h5> - <small className="text-medium-emphasis">3 days ago</small> - </div> - <p className="mb-1"> - Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus - varius blandit. - </p> - <small className="text-medium-emphasis">Donec id elit non mi porta.</small> - </CListGroupItem> - <CListGroupItem component="a" href="#"> - <div className="d-flex w-100 justify-content-between"> - <h5 className="mb-1">List group item heading</h5> - <small className="text-medium-emphasis">3 days ago</small> - </div> - <p className="mb-1"> - Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus - varius blandit. - </p> - <small className="text-medium-emphasis">Donec id elit non mi porta.</small> - </CListGroupItem> - </CListGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React List Group</strong> <small>Checkboxes and radios</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Place CoreUI's checkboxes and radios within list group items and customize as - needed. - </p> - <DocsExample href="components/list-group/#checkboxes-and-radios"> - <CListGroup> - <CListGroupItem> - <CFormCheck label="Cras justo odio" /> - </CListGroupItem> - <CListGroupItem> - <CFormCheck label="Dapibus ac facilisis in" defaultChecked /> - </CListGroupItem> - <CListGroupItem> - <CFormCheck label="Morbi leo risus" defaultChecked /> - </CListGroupItem> - <CListGroupItem> - <CFormCheck label="orta ac consectetur ac" /> - </CListGroupItem> - <CListGroupItem> - <CFormCheck label="Vestibulum at eros" /> - </CListGroupItem> - </CListGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default ListGroups diff --git a/src/views/base/navbars/Navbars.js b/src/views/base/navbars/Navbars.js deleted file mode 100644 index e8b9fd08..00000000 --- a/src/views/base/navbars/Navbars.js +++ /dev/null @@ -1,174 +0,0 @@ -import React, { useState } from 'react' -import { - CCard, - CCardBody, - CCardHeader, - CCollapse, - CDropdownItem, - CDropdownMenu, - CDropdownToggle, - CForm, - CFormInput, - CImage, - CNavbar, - CNavbarNav, - CNavbarBrand, - CNavbarText, - CNavbarToggler, - CNavLink, - CDropdown, - CButton, -} from '@coreui/react' -import { DocsLink } from 'src/components' - -const CNavbars = () => { - const [visible, setVisible] = useState(false) - const [isOpenDropdown, setIsOpenDropdown] = useState(false) - const [navbarText, setNavbarText] = useState(false) - - return ( - <> - <CCard className="mb-4"> - <CCardHeader> - CNavbar - <DocsLink name="CNavbar" /> - </CCardHeader> - <CCardBody> - <CNavbar expandable="sm" color="info"> - <CNavbarToggler onClick={() => setVisible(!visible)} /> - <CNavbarBrand>NavbarBrand</CNavbarBrand> - <CCollapse show={visible} navbar> - <CNavbarNav> - <CNavLink>Home</CNavLink> - <CNavLink>Link</CNavLink> - </CNavbarNav> - <CNavbarNav className="ms-auto"> - <CForm className="d-flex"> - <CFormInput className="me-sm-2" placeholder="Search" size="sm" /> - <CButton color="light" className="my-2 my-sm-0" type="submit"> - Search - </CButton> - </CForm> - <CDropdown inNav> - <CDropdownToggle color="primary">Lang</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>EN</CDropdownItem> - <CDropdownItem>ES</CDropdownItem> - <CDropdownItem>RU</CDropdownItem> - <CDropdownItem>FA</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CDropdown inNav> - <CDropdownToggle color="primary">User</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>Account</CDropdownItem> - <CDropdownItem>Settings</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </CNavbarNav> - </CCollapse> - </CNavbar> - </CCardBody> - </CCard> - - <CCard className="mb-4"> - <CCardHeader>CNavbar brand</CCardHeader> - <CCardBody> - <CNavbar color="faded" light> - <CNavbarBrand> - <CImage - src="https://placekitten.com/g/30/30" - className="d-inline-block align-top" - alt="CoreuiVue" - /> - CoreUI React - </CNavbarBrand> - </CNavbar> - </CCardBody> - </CCard> - - <CCard className="mb-4"> - <CCardHeader>CNavbar text</CCardHeader> - <CCardBody> - <CNavbar toggleable="sm" light color="light"> - <CNavbarToggler - inNavbar - onClick={() => { - setNavbarText(!navbarText) - }} - /> - <CNavbarBrand>NavbarBrand</CNavbarBrand> - <CCollapse show={navbarText}> - <CNavbarNav> - <CNavbarText>Navbar text</CNavbarText> - </CNavbarNav> - </CCollapse> - </CNavbar> - </CCardBody> - </CCard> - - <CCard className="mb-4"> - <CCardHeader>CNavbar dropdown</CCardHeader> - <CCardBody> - <CNavbar expandable="false" color="primary"> - <CNavbarToggler - inNavbar - onClick={() => { - setIsOpenDropdown(!isOpenDropdown) - }} - /> - <CCollapse show={isOpenDropdown} navbar> - <CNavbarNav> - <CNavLink>Home</CNavLink> - <CNavLink>Link</CNavLink> - <CDropdown inNav> - <CDropdownToggle color="primary">Lang</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>EN</CDropdownItem> - <CDropdownItem>ES</CDropdownItem> - <CDropdownItem>RU</CDropdownItem> - <CDropdownItem>FA</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CDropdown inNav> - <CDropdownToggle color="primary">User</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem>Account</CDropdownItem> - <CDropdownItem>Settings</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </CNavbarNav> - </CCollapse> - </CNavbar> - </CCardBody> - </CCard> - - <CCard className="mb-4"> - <CCardHeader>CNavbar form</CCardHeader> - <CCardBody> - <CNavbar light color="light"> - <CForm className="d-flex"> - <CFormInput className="me-sm-2" placeholder="Search" size="sm" /> - <CButton color="outline-success" className="my-2 my-sm-0" type="submit"> - Search - </CButton> - </CForm> - </CNavbar> - </CCardBody> - </CCard> - - <CCard className="mb-4"> - <CCardHeader>CNavbar input group</CCardHeader> - <CCardBody> - <CNavbar light color="light"> - <CForm className="d-flex"> - <CFormInput className="me-sm-2" placeholder="Username" /> - </CForm> - </CNavbar> - </CCardBody> - </CCard> - </> - ) -} - -export default CNavbars diff --git a/src/views/base/navs/Navs.js b/src/views/base/navs/Navs.js deleted file mode 100644 index 89310faf..00000000 --- a/src/views/base/navs/Navs.js +++ /dev/null @@ -1,397 +0,0 @@ -import React from 'react' -import { - CRow, - CCol, - CCard, - CCardBody, - CCardHeader, - CDropdown, - CDropdownItem, - CDropdownMenu, - CDropdownToggle, - CNav, - CNavItem, - CNavLink, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const Navs = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Navs</strong> <small>Base navs</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - The base <code>.nav</code> component is built with flexbox and provide a strong - foundation for building all types of navigation components. It includes some style - overrides (for working with lists), some link padding for larger hit areas, and basic - disabled styling. - </p> - <DocsExample href="components/nav#base-nav"> - <CNav> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </DocsExample> - <p className="text-medium-emphasis small"> - Classes are used throughout, so your markup can be super flexible. Use{' '} - <code><ul></code>s like above, <code><ol></code> if the order of your - items is important, or roll your own with a <code><nav></code> element. Because - the .nav uses display: flex, the nav links behave the same as nav items would, but - without the extra markup. - </p> - <DocsExample href="components/nav#base-nav"> - <CNav component="nav"> - <CNavLink href="#" active> - Active - </CNavLink> - <CNavLink href="#">Link</CNavLink> - <CNavLink href="#">Link</CNavLink> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNav> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Navs</strong> <small>Horizontal alignment</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Change the horizontal alignment of your nav with{' '} - <a href="https://coreui.io/docs/layout/grid/#horizontal-alignment"> - flexbox utilities - </a> - . By default, navs are left-aligned, but you can easily change them to center or right - aligned. - </p> - <p className="text-medium-emphasis small"> - Centered with <code>.justify-content-center</code>: - </p> - <DocsExample href="components/nav#horizontal-alignment"> - <CNav className="justify-content-center"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </DocsExample> - <p className="text-medium-emphasis small"> - Right-aligned with <code>.justify-content-end</code>: - </p> - <DocsExample href="components/nav#base-nav"> - <CNav className="justify-content-end"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Navs</strong> <small>Vertical</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Stack your navigation by changing the flex item direction with the{' '} - <code>.flex-column</code> utility. Need to stack them on some viewports but not - others? Use the responsive versions (e.g., <code>.flex-sm-column</code>). - </p> - <DocsExample href="components/nav#vertical"> - <CNav className="flex-column"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Navs</strong> <small>Tabs</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Takes the basic nav from above and adds the <code>variant="tabs"</code> class - to generate a tabbed interface - </p> - <DocsExample href="components/nav#tabs"> - <CNav variant="tabs"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Navs</strong> <small>Pills</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Take that same HTML, but use <code>variant="pills"</code> instead: - </p> - <DocsExample href="components/nav#pills"> - <CNav variant="pills"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Navs</strong> <small>Fill and justify</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Force your <code>.nav</code>'s contents to extend the full available width one of - two modifier classes. To proportionately fill all available space with your{' '} - <code>.nav-item</code>s, use <code>layout="fill"</code>. Notice that all - horizontal space is occupied, but not every nav item has the same width. - </p> - <DocsExample href="components/nav#fill-and-justify"> - <CNav variant="pills" layout="fill"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </DocsExample> - <p className="text-medium-emphasis small"> - For equal-width elements, use <code>layout="justified"</code>. All horizontal - space will be occupied by nav links, but unlike the .nav-fill above, every nav item - will be the same width. - </p> - <DocsExample href="components/nav#fill-and-justify"> - <CNav variant="pills" layout="justified"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Navs</strong> <small>Working with flex utilities</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - If you need responsive nav variations, consider using a series of{' '} - <a href="https://coreui.io/docs/utilities/flex">flexbox utilities</a>. While more - verbose, these utilities offer greater customization across responsive breakpoints. In - the example below, our nav will be stacked on the lowest breakpoint, then adapt to a - horizontal layout that fills the available width starting from the small breakpoint. - </p> - <DocsExample href="components/nav#working-with-flex-utilities"> - <CNav component="nav" variant="pills" className="flex-column flex-sm-row"> - <CNavLink href="#" active> - Active - </CNavLink> - <CNavLink href="#">Link</CNavLink> - <CNavLink href="#">Link</CNavLink> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNav> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Navs</strong> <small>Tabs with dropdowns</small> - </CCardHeader> - <CCardBody> - <DocsExample href="components/nav#tabs-with-dropdowns"> - <CNav> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CDropdown variant="nav-item"> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Navs</strong> <small>Pills with dropdowns</small> - </CCardHeader> - <CCardBody> - <DocsExample href="components/nav#pills-with-dropdowns"> - <CNav variant="pills"> - <CNavItem> - <CNavLink href="#" active> - Active - </CNavLink> - </CNavItem> - <CDropdown variant="nav-item"> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CNavItem> - <CNavLink href="#">Link</CNavLink> - </CNavItem> - <CNavItem> - <CNavLink href="#" disabled> - Disabled - </CNavLink> - </CNavItem> - </CNav> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Navs diff --git a/src/views/base/paginations/Paginations.js b/src/views/base/paginations/Paginations.js deleted file mode 100644 index f8596150..00000000 --- a/src/views/base/paginations/Paginations.js +++ /dev/null @@ -1,174 +0,0 @@ -import React from 'react' -import { - CCard, - CCardBody, - CCardHeader, - CCol, - CPagination, - CPaginationItem, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const Paginations = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Pagination</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - We use a large block of connected links for our pagination, making links hard to miss - and easily scalable—all while providing large hit areas. Pagination is built with list - HTML elements so screen readers can announce the number of available links. Use a - wrapping <code><nav></code> element to identify it as a navigation section to - screen readers and other assistive technologies. - </p> - <p className="text-medium-emphasis small"> - In addition, as pages likely have more than one such navigation section, it's - advisable to provide a descriptive <code>aria-label</code> for the{' '} - <code><nav></code> to reflect its purpose. For example, if the pagination - component is used to navigate between a set of search results, an appropriate label - could be <code>aria-label="Search results pages"</code>. - </p> - <DocsExample href="components/pagination"> - <CPagination aria-label="Page navigation example"> - <CPaginationItem>Previous</CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem>Next</CPaginationItem> - </CPagination> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Pagination</strong> <small>Working with icons</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Looking to use an icon or symbol in place of text for some pagination links? Be sure - to provide proper screen reader support with <code>aria</code> attributes. - </p> - <DocsExample href="components/pagination#working-with-icons"> - <CPagination aria-label="Page navigation example"> - <CPaginationItem aria-label="Previous"> - <span aria-hidden="true">«</span> - </CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem aria-label="Next"> - <span aria-hidden="true">»</span> - </CPaginationItem> - </CPagination> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Pagination</strong> <small>Disabled and active states</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Pagination links are customizable for different circumstances. Use{' '} - <code>disabled</code> for links that appear un-clickable and <code>.active</code> to - indicate the current page. - </p> - <p className="text-medium-emphasis small"> - While the <code>disabled</code> prop uses <code>pointer-events: none</code> to{' '} - <em>try</em> to disable the link functionality of <code><a></code>s, that CSS - property is not yet standardized and doesn'taccount for keyboard navigation. As - such, we always add <code>tabindex="-1"</code> on disabled links and use - custom JavaScript to fully disable their functionality. - </p> - <DocsExample href="components/pagination#disabled-and-active-states"> - <CPagination aria-label="Page navigation example"> - <CPaginationItem aria-label="Previous" disabled> - <span aria-hidden="true">«</span> - </CPaginationItem> - <CPaginationItem active>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem aria-label="Next"> - <span aria-hidden="true">»</span> - </CPaginationItem> - </CPagination> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Pagination</strong> <small>Sizing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Fancy larger or smaller pagination? Add <code>size="lg"</code> or{' '} - <code>size="sm"</code> for additional sizes. - </p> - <DocsExample href="components/pagination#sizing"> - <CPagination size="lg" aria-label="Page navigation example"> - <CPaginationItem>Previous</CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem>Next</CPaginationItem> - </CPagination> - </DocsExample> - <DocsExample href="components/pagination#sizing"> - <CPagination size="sm" aria-label="Page navigation example"> - <CPaginationItem>Previous</CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem>Next</CPaginationItem> - </CPagination> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Pagination</strong> <small>Alignment</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Change the alignment of pagination components with{' '} - <a href="https://coreui.io/docs/utilities/flex/">flexbox utilities</a>. - </p> - <DocsExample href="components/pagination#aligment"> - <CPagination className="justify-content-center" aria-label="Page navigation example"> - <CPaginationItem disabled>Previous</CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem>Next</CPaginationItem> - </CPagination> - </DocsExample> - <DocsExample href="components/pagination#aligment"> - <CPagination className="justify-content-end" aria-label="Page navigation example"> - <CPaginationItem disabled>Previous</CPaginationItem> - <CPaginationItem>1</CPaginationItem> - <CPaginationItem>2</CPaginationItem> - <CPaginationItem>3</CPaginationItem> - <CPaginationItem>Next</CPaginationItem> - </CPagination> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Paginations diff --git a/src/views/base/placeholders/Placeholders.js b/src/views/base/placeholders/Placeholders.js deleted file mode 100644 index 5342f221..00000000 --- a/src/views/base/placeholders/Placeholders.js +++ /dev/null @@ -1,193 +0,0 @@ -import React from 'react' -import { - CButton, - CCard, - CCardBody, - CCardHeader, - CCardImage, - CCardText, - CCardTitle, - CCol, - CPlaceholder, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -import ReactImg from 'src/assets/images/react.jpg' - -const Placeholders = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Placeholder</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - In the example below, we take a typical card component and recreate it with - placeholders applied to create a "loading card". Size and proportions are the - same between the two. - </p> - <DocsExample href="components/placeholder"> - <div className="d-flex justify-content-around p-3"> - <CCard style={{ width: '18rem' }}> - <CCardImage orientation="top" src={ReactImg} /> - <CCardBody> - <CCardTitle>Card title</CCardTitle> - <CCardText> - Some quick example text to build on the card title and make up the bulk of the - card's content. - </CCardText> - <CButton href="#">Go somewhere</CButton> - </CCardBody> - </CCard> - <CCard style={{ width: '18rem' }}> - <CCardImage - component="svg" - orientation="top" - width="100%" - height="162" - xmlns="http://www.w3.org/2000/svg" - role="img" - aria-label="Placeholder" - preserveAspectRatio="xMidYMid slice" - focusable="false" - > - <title>Placeholder</title> - <rect width="100%" height="100%" fill="#868e96"></rect> - </CCardImage> - <CCardBody> - <CPlaceholder component={CCardTitle} animation="glow" xs={7}> - <CPlaceholder xs={6} /> - </CPlaceholder> - <CPlaceholder component={CCardText} animation="glow"> - <CPlaceholder xs={7} /> - <CPlaceholder xs={4} /> - <CPlaceholder xs={4} /> - <CPlaceholder xs={6} /> - <CPlaceholder xs={8} /> - </CPlaceholder> - <CPlaceholder - component={CButton} - disabled - href="#" - tabIndex={-1} - xs={6} - ></CPlaceholder> - </CCardBody> - </CCard> - </div> - </DocsExample> - </CCardBody> - </CCard> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Placeholder</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Create placeholders with the <code><CPlaceholder></code> component and a grid - column propx (e.g., <code>xs={6}</code>) to set the <code>width</code>. They can - replace the text inside an element or be added as a modifier class to an existing - component. - </p> - <DocsExample href="components/placeholder"> - <p aria-hidden="true"> - <CPlaceholder xs={6} /> - </p> - <CPlaceholder - component={CButton} - aria-hidden="true" - disabled - href="#" - tabIndex={-1} - xs={4} - ></CPlaceholder> - </DocsExample> - </CCardBody> - </CCard> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Placeholder</strong> <small> Width</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - You can change the <code>width</code> through grid column classes, width utilities, or - inline styles. - </p> - <DocsExample href="components/placeholder#width"> - <CPlaceholder xs={6} /> - <CPlaceholder className="w-75" /> - <CPlaceholder style={{ width: '30%' }} /> - </DocsExample> - </CCardBody> - </CCard> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Placeholder</strong> <small> Color</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - By default, the <code><CPlaceholder></code> uses <code>currentColor</code>. This - can be overridden with a custom color or utility class. - </p> - <DocsExample href="components/placeholder#color"> - <CPlaceholder xs={12} /> - - <CPlaceholder color="primary" xs={12} /> - <CPlaceholder color="secondary" xs={12} /> - <CPlaceholder color="success" xs={12} /> - <CPlaceholder color="danger" xs={12} /> - <CPlaceholder color="warning" xs={12} /> - <CPlaceholder color="info" xs={12} /> - <CPlaceholder color="light" xs={12} /> - <CPlaceholder color="dark" xs={12} /> - </DocsExample> - </CCardBody> - </CCard> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Placeholder</strong> <small> Sizing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - The size of <code><CPlaceholder></code>s are based on the typographic style of - the parent element. Customize them with <code>size</code> prop: <code>lg</code>,{' '} - <code>sm</code>, or <code>xs</code>. - </p> - <DocsExample href="components/placeholder#sizing"> - <CPlaceholder xs={12} size="lg" /> - <CPlaceholder xs={12} /> - <CPlaceholder xs={12} size="sm" /> - <CPlaceholder xs={12} size="xs" /> - </DocsExample> - </CCardBody> - </CCard> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Placeholder</strong> <small> Animation</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Animate placeholders with <code>animation="glow"</code> or{' '} - <code>animation="wave"</code> to better convey the perception of something - being <em>actively</em> loaded. - </p> - <DocsExample href="components/placeholder#animation"> - <CPlaceholder component="p" animation="glow"> - <CPlaceholder xs={12} /> - </CPlaceholder> - - <CPlaceholder component="p" animation="wave"> - <CPlaceholder xs={12} /> - </CPlaceholder> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Placeholders diff --git a/src/views/base/popovers/Popovers.js b/src/views/base/popovers/Popovers.js deleted file mode 100644 index 8d98e0de..00000000 --- a/src/views/base/popovers/Popovers.js +++ /dev/null @@ -1,71 +0,0 @@ -import React from 'react' -import { CButton, CCard, CCardBody, CCardHeader, CPopover, CRow, CCol } from '@coreui/react' -import { DocsExample } from 'src/components' - -const Popovers = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Popover</strong> <small>Basic example</small> - </CCardHeader> - <CCardBody> - <DocsExample href="components/popover"> - <CPopover - title="Popover title" - content="And here’s some amazing content. It’s very engaging. Right?" - placement="right" - > - <CButton color="danger" size="lg"> - Click to toggle popover - </CButton> - </CPopover> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Popover</strong> <small>Four directions</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Four options are available: top, right, bottom, and left aligned. Directions are - mirrored when using CoreUI for React in RTL. - </p> - <DocsExample href="components/popover#four-directions"> - <CPopover - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="top" - > - <CButton color="secondary">Popover on top</CButton> - </CPopover> - <CPopover - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="right" - > - <CButton color="secondary">Popover on right</CButton> - </CPopover> - <CPopover - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="bottom" - > - <CButton color="secondary">Popover on bottom</CButton> - </CPopover> - <CPopover - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="left" - > - <CButton color="secondary">Popover on left</CButton> - </CPopover> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Popovers diff --git a/src/views/base/progress/Progress.js b/src/views/base/progress/Progress.js deleted file mode 100644 index 42b9819f..00000000 --- a/src/views/base/progress/Progress.js +++ /dev/null @@ -1,186 +0,0 @@ -import React from 'react' -import { CCard, CCardBody, CCardHeader, CCol, CProgress, CProgressBar, CRow } from '@coreui/react' -import { DocsExample } from 'src/components' - -const Progress = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Progress</strong> <small>Basic example</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Progress components are built with two HTML elements, some CSS to set the width, and a - few attributes. We don'tuse{' '} - <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress"> - the HTML5 <code><progress></code> element - </a> - , ensuring you can stack progress bars, animate them, and place text labels over them. - </p> - <DocsExample href="components/progress"> - <CProgress className="mb-3"> - <CProgressBar value={0} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar value={25} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar value={50} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar value={75} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar value={100} /> - </CProgress> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Progress</strong> <small>Labels</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add labels to your progress bars by placing text within the{' '} - <code><CProgressBar></code>. - </p> - <DocsExample href="components/progress#labels"> - <CProgress className="mb-3"> - <CProgressBar value={25}>25%</CProgressBar> - </CProgress> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Progress</strong> <small>Height</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - We only set a <code>height</code> value on the <code><CProgress></code>, so if - you change that value the inner <code><CProgressBar></code> will automatically - resize accordingly. - </p> - <DocsExample href="components/progress#height"> - <CProgress height={1} className="mb-3"> - <CProgressBar value={25}></CProgressBar> - </CProgress> - <CProgress height={20} className="mb-3"> - <CProgressBar value={25}></CProgressBar> - </CProgress> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Progress</strong> <small>Backgrounds</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use <code>color</code> prop to change the appearance of individual progress bars. - </p> - <DocsExample href="components/progress#backgrounds"> - <CProgress className="mb-3"> - <CProgressBar color="success" value={25} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar color="info" value={50} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar color="warning" value={75} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar color="danger" value={100} /> - </CProgress> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Progress</strong> <small>Multiple bars</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Include multiple progress bars in a progress component if you need. - </p> - <DocsExample href="components/progress#multiple-bars"> - <CProgress className="mb-3"> - <CProgressBar value={15} /> - <CProgressBar color="success" value={30} /> - <CProgressBar color="info" value={20} /> - </CProgress> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Progress</strong> <small>Striped</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>variant="striped"</code> to any <code><CProgressBar></code> to - apply a stripe via CSS gradient over the progress bar's background color. - </p> - <DocsExample href="components/progress#striped"> - <CProgress className="mb-3"> - <CProgressBar color="success" variant="striped" value={25} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar color="info" variant="striped" value={50} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar color="warning" variant="striped" value={75} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar color="danger" variant="striped" value={100} /> - </CProgress> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Progress</strong> <small>Animated stripes</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - The striped gradient can also be animated. Add <code>animated</code> property to{' '} - <code><CProgressBar></code> to animate the stripes right to left via CSS3 - animations. - </p> - <DocsExample href="components/progress#animated-stripes"> - <CProgress className="mb-3"> - <CProgressBar color="success" variant="striped" animated value={25} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar color="info" variant="striped" animated value={50} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar color="warning" variant="striped" animated value={75} /> - </CProgress> - <CProgress className="mb-3"> - <CProgressBar color="danger" variant="striped" animated value={100} /> - </CProgress> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Progress diff --git a/src/views/base/spinners/Spinners.js b/src/views/base/spinners/Spinners.js deleted file mode 100644 index 918c2713..00000000 --- a/src/views/base/spinners/Spinners.js +++ /dev/null @@ -1,120 +0,0 @@ -import React from 'react' -import { CButton, CCard, CCardBody, CCardHeader, CCol, CSpinner, CRow } from '@coreui/react' -import { DocsExample } from 'src/components' - -const Accordion = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Spinner</strong> <small>Border</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use the border spinners for a lightweight loading indicator. - </p> - <DocsExample href="components/spinner"> - <CSpinner /> - </DocsExample> - <p className="text-medium-emphasis small"> - The border spinner uses <code>currentColor</code> for its <code>border-color</code>. - You can use any of our text color utilities on the standard spinner. - </p> - <DocsExample href="components/spinner#colors"> - <CSpinner color="primary" /> - <CSpinner color="secondary" /> - <CSpinner color="success" /> - <CSpinner color="danger" /> - <CSpinner color="warning" /> - <CSpinner color="info" /> - <CSpinner color="light" /> - <CSpinner color="dark" /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Spinner</strong> <small>Growing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - If you don'tfancy a border spinner, switch to the grow spinner. While it - doesn't technically spin, it does repeatedly grow! - </p> - <DocsExample href="components/spinner#growing-spinner"> - <CSpinner variant="grow" /> - </DocsExample> - <p className="text-medium-emphasis small"> - Once again, this spinner is built with <code>currentColor</code>, so you can easily - change its appearance. Here it is in blue, along with the supported variants. - </p> - <DocsExample href="components/spinner#growing-spinner"> - <CSpinner color="primary" variant="grow" /> - <CSpinner color="secondary" variant="grow" /> - <CSpinner color="success" variant="grow" /> - <CSpinner color="danger" variant="grow" /> - <CSpinner color="warning" variant="grow" /> - <CSpinner color="info" variant="grow" /> - <CSpinner color="light" variant="grow" /> - <CSpinner color="dark" variant="grow" /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Spinner</strong> <small>Size</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>size="sm"</code> property to make a smaller spinner that can quickly - be used within other components. - </p> - <DocsExample href="components/spinner#size"> - <CSpinner size="sm" /> - <CSpinner size="sm" variant="grow" /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Spinner</strong> <small>Buttons</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use spinners within buttons to indicate an action is currently processing or taking - place. You may also swap the text out of the spinner element and utilize button text - as needed. - </p> - <DocsExample href="components/spinner#buttons"> - <CButton disabled> - <CSpinner component="span" size="sm" aria-hidden="true" /> - </CButton> - <CButton disabled> - <CSpinner component="span" size="sm" aria-hidden="true" /> - Loading... - </CButton> - </DocsExample> - <DocsExample href="components/spinner#buttons"> - <CButton disabled> - <CSpinner component="span" size="sm" variant="grow" aria-hidden="true" /> - </CButton> - <CButton disabled> - <CSpinner component="span" size="sm" variant="grow" aria-hidden="true" /> - Loading... - </CButton> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Accordion diff --git a/src/views/base/tables/Tables.js b/src/views/base/tables/Tables.js deleted file mode 100644 index f06843d0..00000000 --- a/src/views/base/tables/Tables.js +++ /dev/null @@ -1,986 +0,0 @@ -import React from 'react' -import { - CCard, - CCardBody, - CCardHeader, - CCol, - CRow, - CTable, - CTableBody, - CTableCaption, - CTableDataCell, - CTableHead, - CTableHeaderCell, - CTableRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const Tables = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Basic example</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Using the most basic table CoreUI, here's how <code><CTable></code>-based - tables look in CoreUI. - </p> - <DocsExample href="components/table"> - <CTable> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Variants</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use contextual classes to color tables, table rows or individual cells. - </p> - <DocsExample href="components/table#variants"> - <CTable> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">Default</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="primary"> - <CTableHeaderCell scope="row">Primary</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="secondary"> - <CTableHeaderCell scope="row">Secondary</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="success"> - <CTableHeaderCell scope="row">Success</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="danger"> - <CTableHeaderCell scope="row">Danger</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="warning"> - <CTableHeaderCell scope="row">Warning</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="info"> - <CTableHeaderCell scope="row">Info</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="light"> - <CTableHeaderCell scope="row">Light</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - <CTableRow color="dark"> - <CTableHeaderCell scope="row">Dark</CTableHeaderCell> - <CTableDataCell>Cell</CTableDataCell> - <CTableDataCell>Cell</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Striped rows</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use <code>striped</code> property to add zebra-striping to any table row within the{' '} - <code><CTableBody></code>. - </p> - <DocsExample href="components/table#striped-rows"> - <CTable striped> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - <p className="text-medium-emphasis small"> - These classes can also be added to table variants: - </p> - <DocsExample href="components/table#striped-rows"> - <CTable color="dark" striped> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - <DocsExample href="components/table#striped-rows"> - <CTable color="success" striped> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Hoverable rows</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use <code>hover</code> property to enable a hover state on table rows within a{' '} - <code><CTableBody></code>. - </p> - <DocsExample href="components/table#hoverable-rows"> - <CTable hover> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - <DocsExample href="components/table#hoverable-rows"> - <CTable color="dark" hover> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - <DocsExample href="components/table#hoverable-rows"> - <CTable striped hover> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Active tables</small> - </CCardHeader> - <CCardBody> - <DocsExample href="components/table#active-tables"> - <CTable> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow active> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2" active> - Larry the Bird - </CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - <DocsExample href="components/table#active-tables"> - <CTable color="dark"> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow active> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2" active> - Larry the Bird - </CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Bordered tables</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>bordered</code> property for borders on all sides of the table and cells. - </p> - <DocsExample href="components/table#bordered-tables"> - <CTable bordered> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - <p className="text-medium-emphasis small"> - <a href="https://coreui.io/docs/4.0/utilities/borders#border-color"> - Border color utilities - </a>{' '} - can be added to change colors: - </p> - <DocsExample href="components/table#bordered-tables"> - <CTable bordered borderColor="primary"> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Tables without borders</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>borderless</code> property for a table without borders. - </p> - <DocsExample href="components/table#tables-without-borders"> - <CTable borderless> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - <DocsExample href="components/table#tables-without-borders"> - <CTable color="dark" borderless> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Small tables</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>small</code> property to make any <code><CTable></code> more compact - by cutting all cell <code>padding</code> in half. - </p> - <DocsExample href="components/table#small-tables"> - <CTable small> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Vertical alignment</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Table cells of <code><CTableHead></code> are always vertical aligned to the - bottom. Table cells in <code><CTableBody></code> inherit their alignment from{' '} - <code><CTable></code> and are aligned to the the top by default. Use the align - property to re-align where needed. - </p> - <DocsExample href="components/table#vertical-alignment"> - <CTable align="middle" responsive> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col" className="w-25"> - Heading 1 - </CTableHeaderCell> - <CTableHeaderCell scope="col" className="w-25"> - Heading 2 - </CTableHeaderCell> - <CTableHeaderCell scope="col" className="w-25"> - Heading 3 - </CTableHeaderCell> - <CTableHeaderCell scope="col" className="w-25"> - Heading 4 - </CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableDataCell> - This cell inherits <code>vertical-align: middle;</code> from the table - </CTableDataCell> - <CTableDataCell> - This cell inherits <code>vertical-align: middle;</code> from the table - </CTableDataCell> - <CTableDataCell> - This cell inherits <code>vertical-align: middle;</code> from the table - </CTableDataCell> - <CTableDataCell> - This here is some placeholder text, intended to take up quite a bit of - vertical space, to demonsCTableRowate how the vertical alignment works in the - preceding cells. - </CTableDataCell> - </CTableRow> - <CTableRow align="bottom"> - <CTableDataCell> - This cell inherits <code>vertical-align: bottom;</code> from the table row - </CTableDataCell> - <CTableDataCell> - This cell inherits <code>vertical-align: bottom;</code> from the table row - </CTableDataCell> - <CTableDataCell> - This cell inherits <code>vertical-align: bottom;</code> from the table row - </CTableDataCell> - <CTableDataCell> - This here is some placeholder text, intended to take up quite a bit of - vertical space, to demonsCTableRowate how the vertical alignment works in the - preceding cells. - </CTableDataCell> - </CTableRow> - <CTableRow> - <CTableDataCell> - This cell inherits <code>vertical-align: middle;</code> from the table - </CTableDataCell> - <CTableDataCell> - This cell inherits <code>vertical-align: middle;</code> from the table - </CTableDataCell> - <CTableDataCell align="top">This cell is aligned to the top.</CTableDataCell> - <CTableDataCell> - This here is some placeholder text, intended to take up quite a bit of - vertical space, to demonsCTableRowate how the vertical alignment works in the - preceding cells. - </CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Nesting</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Border styles, active styles, and table variants are not inherited by nested tables. - </p> - <DocsExample href="components/table#nesting"> - <CTable striped> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell colSpan="4"> - <CTable> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">Header</CTableHeaderCell> - <CTableHeaderCell scope="col">Header</CTableHeaderCell> - <CTableHeaderCell scope="col">Header</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">A</CTableHeaderCell> - <CTableDataCell>First</CTableDataCell> - <CTableDataCell>Last</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">B</CTableHeaderCell> - <CTableDataCell>First</CTableDataCell> - <CTableDataCell>Last</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">C</CTableHeaderCell> - <CTableDataCell>First</CTableDataCell> - <CTableDataCell>Last</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </CTableHeaderCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Table head</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Similar to tables and dark tables, use the modifier prop{' '} - <code>color="light"</code> or <code>color="dark"</code> to make{' '} - <code><CTableHead></code>s appear light or dark gray. - </p> - <DocsExample href="components/table#table-head"> - <CTable> - <CTableHead color="light"> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell>Larry</CTableDataCell> - <CTableDataCell>the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - <DocsExample href="components/table#table-head"> - <CTable> - <CTableHead color="dark"> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Table foot</small> - </CCardHeader> - <CCardBody> - <DocsExample href="components/table#table-foot"> - <CTable> - <CTableHead color="light"> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell colSpan="2">Larry the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - <CTableHead> - <CTableRow> - <CTableDataCell>Footer</CTableDataCell> - <CTableDataCell>Footer</CTableDataCell> - <CTableDataCell>Footer</CTableDataCell> - <CTableDataCell>Footer</CTableDataCell> - </CTableRow> - </CTableHead> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Table</strong> <small>Captions</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - A <code><CTableCaption></code> functions like a heading for a table. It helps - users with screen readers to find a table and understand what it's about and - decide if they want to read it. - </p> - <DocsExample href="components/table#captions"> - <CTable> - <CTableCaption>List of users</CTableCaption> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell>Larry</CTableDataCell> - <CTableDataCell>the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - <p className="text-medium-emphasis small"> - You can also put the <code><CTableCaption></code> on the top of the table with{' '} - <code>caption="top"</code>. - </p> - <DocsExample href="components/table#captions"> - <CTable caption="top"> - <CTableCaption>List of users</CTableCaption> - <CTableHead> - <CTableRow> - <CTableHeaderCell scope="col">#</CTableHeaderCell> - <CTableHeaderCell scope="col">Class</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - <CTableHeaderCell scope="col">Heading</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - <CTableRow> - <CTableHeaderCell scope="row">1</CTableHeaderCell> - <CTableDataCell>Mark</CTableDataCell> - <CTableDataCell>Otto</CTableDataCell> - <CTableDataCell>@mdo</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">2</CTableHeaderCell> - <CTableDataCell>Jacob</CTableDataCell> - <CTableDataCell>Thornton</CTableDataCell> - <CTableDataCell>@fat</CTableDataCell> - </CTableRow> - <CTableRow> - <CTableHeaderCell scope="row">3</CTableHeaderCell> - <CTableDataCell>Larry</CTableDataCell> - <CTableDataCell>the Bird</CTableDataCell> - <CTableDataCell>@twitter</CTableDataCell> - </CTableRow> - </CTableBody> - </CTable> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Tables diff --git a/src/views/base/tooltips/Tooltips.js b/src/views/base/tooltips/Tooltips.js deleted file mode 100644 index bdb4d9aa..00000000 --- a/src/views/base/tooltips/Tooltips.js +++ /dev/null @@ -1,79 +0,0 @@ -import React from 'react' -import { CButton, CCard, CCardBody, CCardHeader, CLink, CTooltip, CRow, CCol } from '@coreui/react' -import { DocsExample } from 'src/components' - -const Tooltips = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Tooltip</strong> <small>Basic example</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Hover over the links below to see tooltips: - </p> - <DocsExample href="components/tooltip"> - <p className="text-medium-emphasis"> - Tight pants next level keffiyeh - <CTooltip content="Tooltip text"> - <CLink> you probably </CLink> - </CTooltip> - haven'theard of them. Photo booth beard raw denim letterpress vegan messenger - bag stumptown. Farm-to-table seitan, mcsweeney's fixie sustainable quinoa 8-bit - american apparel - <CTooltip content="Tooltip text"> - <CLink> have a </CLink> - </CTooltip> - terry richardson vinyl chambray. Beard stumptown, cardigans banh mi lomo - thundercats. Tofu biodiesel williamsburg marfa, four loko mcsweeney''s - cleanse vegan chambray. A really ironic artisan - <CTooltip content="Tooltip text"> - <CLink> whatever keytar </CLink> - </CTooltip> - scenester farm-to-table banksy Austin - <CTooltip content="Tooltip text"> - <CLink> twitter handle </CLink> - </CTooltip> - freegan cred raw denim single-origin coffee viral. - </p> - </DocsExample> - <p className="text-medium-emphasis small"> - Hover over the buttons below to see the four tooltips directions: top, right, bottom, - and left. Directions are mirrored when using CoreUI in RTL. - </p> - <DocsExample href="components/tooltip"> - <CTooltip - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="top" - > - <CButton color="secondary">Tooltip on top</CButton> - </CTooltip> - <CTooltip - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="right" - > - <CButton color="secondary">Tooltip on right</CButton> - </CTooltip> - <CTooltip - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="bottom" - > - <CButton color="secondary">Tooltip on bottom</CButton> - </CTooltip> - <CTooltip - content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus." - placement="left" - > - <CButton color="secondary">Tooltip on left</CButton> - </CTooltip> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Tooltips diff --git a/src/views/buttons/button-groups/ButtonGroups.js b/src/views/buttons/button-groups/ButtonGroups.js deleted file mode 100644 index d48eb007..00000000 --- a/src/views/buttons/button-groups/ButtonGroups.js +++ /dev/null @@ -1,439 +0,0 @@ -import React from 'react' -import { - CButton, - CDropdown, - CDropdownDivider, - CDropdownItem, - CDropdownMenu, - CDropdownToggle, - CButtonGroup, - CButtonToolbar, - CCard, - CCardBody, - CCardHeader, - CCol, - CFormCheck, - CFormInput, - CInputGroup, - CInputGroupText, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const ButtonGroups = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button Group</strong> <span>Basic example</span> - </CCardHeader> - <CCardBody> - <p> - Wrap a series of <code><CButton></code> components in{' '} - <code><CButtonGroup></code>.{' '} - </p> - <DocsExample href="components/button-group"> - <CButtonGroup role="group" aria-label="Basic example"> - <CButton color="primary">Left</CButton> - <CButton color="primary">Middle</CButton> - <CButton color="primary">Right</CButton> - </CButtonGroup> - </DocsExample> - <p> - These classes can also be added to groups of links, as an alternative to the{' '} - <code><CNav></code> components. - </p> - <DocsExample href="components/button-group"> - <CButtonGroup> - <CButton href="#" color="primary" active> - Active link - </CButton> - <CButton href="#" color="primary"> - Link - </CButton> - <CButton href="#" color="primary"> - Link - </CButton> - </CButtonGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button Group</strong> <span>Mixed styles</span> - </CCardHeader> - <CCardBody> - <DocsExample href="components/button-group#mixed-styles"> - <CButtonGroup role="group" aria-label="Basic mixed styles example"> - <CButton color="danger">Left</CButton> - <CButton color="warning">Middle</CButton> - <CButton color="success">Right</CButton> - </CButtonGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button Group</strong> <span>Outlined styles</span> - </CCardHeader> - <CCardBody> - <DocsExample href="components/button-group#outlined-styles"> - <CButtonGroup role="group" aria-label="Basic outlined example"> - <CButton color="primary" variant="outline"> - Left - </CButton> - <CButton color="primary" variant="outline"> - Middle - </CButton> - <CButton color="primary" variant="outline"> - Right - </CButton> - </CButtonGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button Group</strong> <span>Checkbox and radio button groups</span> - </CCardHeader> - <CCardBody> - <p> - Combine button-like checkbox and radio toggle buttons into a seamless looking button - group. - </p> - <DocsExample href="components/button-group#checkbox-and-radio-button-groups"> - <CButtonGroup role="group" aria-label="Basic checkbox toggle button group"> - <CFormCheck - button={{ variant: 'outline' }} - id="btncheck1" - autoComplete="off" - label="Checkbox 1" - /> - <CFormCheck - button={{ variant: 'outline' }} - id="btncheck2" - autoComplete="off" - label="Checkbox 2" - /> - <CFormCheck - button={{ variant: 'outline' }} - id="btncheck3" - autoComplete="off" - label="Checkbox 3" - /> - </CButtonGroup> - </DocsExample> - <DocsExample href="components/button-group#checkbox-and-radio-button-groups"> - <CButtonGroup role="group" aria-label="Basic checkbox toggle button group"> - <CFormCheck - type="radio" - button={{ variant: 'outline' }} - name="btnradio" - id="btnradio1" - autoComplete="off" - label="Radio 1" - /> - <CFormCheck - type="radio" - button={{ variant: 'outline' }} - name="btnradio" - id="btnradio2" - autoComplete="off" - label="Radio 2" - /> - <CFormCheck - type="radio" - button={{ variant: 'outline' }} - name="btnradio" - id="btnradio3" - autoComplete="off" - label="Radio 3" - /> - </CButtonGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button Group</strong> <span>Button toolbar</span> - </CCardHeader> - <CCardBody> - <p> - Join sets of button groups into button toolbars for more complicated components. Use - utility classes as needed to space out groups, buttons, and more. - </p> - <DocsExample href="components/button-group#button-toolbar"> - <CButtonToolbar role="group" aria-label="Toolbar with button groups"> - <CButtonGroup className="me-2" role="group" aria-label="First group"> - <CButton color="primary">1</CButton> - <CButton color="primary">2</CButton> - <CButton color="primary">3</CButton> - <CButton color="primary">4</CButton> - </CButtonGroup> - <CButtonGroup className="me-2" role="group" aria-label="Second group"> - <CButton color="secondary">5</CButton> - <CButton color="secondary">6</CButton> - <CButton color="secondary">7</CButton> - </CButtonGroup> - <CButtonGroup className="me-2" role="group" aria-label="Third group"> - <CButton color="info">8</CButton> - </CButtonGroup> - </CButtonToolbar> - </DocsExample> - <p> - Feel free to combine input groups with button groups in your toolbars. Similar to the - example above, you’ll likely need some utilities through to space items correctly. - </p> - <DocsExample href="components/button-group#button-toolbar"> - <CButtonToolbar className="mb-3" role="group" aria-label="Toolbar with button groups"> - <CButtonGroup className="me-2" role="group" aria-label="First group"> - <CButton color="secondary" variant="outline"> - 1 - </CButton> - <CButton color="secondary" variant="outline"> - 2 - </CButton> - <CButton color="secondary" variant="outline"> - 3 - </CButton> - <CButton color="secondary" variant="outline"> - 4 - </CButton> - </CButtonGroup> - <CInputGroup> - <CInputGroupText>@</CInputGroupText> - <CFormInput - placeholder="Input group example" - aria-label="Input group example" - aria-describedby="btnGroupAddon" - /> - </CInputGroup> - </CButtonToolbar> - <CButtonToolbar - className="justify-content-between" - role="group" - aria-label="Toolbar with button groups" - > - <CButtonGroup className="me-2" role="group" aria-label="First group"> - <CButton color="secondary" variant="outline"> - 1 - </CButton> - <CButton color="secondary" variant="outline"> - 2 - </CButton> - <CButton color="secondary" variant="outline"> - 3 - </CButton> - <CButton color="secondary" variant="outline"> - 4 - </CButton> - </CButtonGroup> - <CInputGroup> - <CInputGroupText>@</CInputGroupText> - <CFormInput - placeholder="Input group example" - aria-label="Input group example" - aria-describedby="btnGroupAddon" - /> - </CInputGroup> - </CButtonToolbar> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button Group</strong> <span>Sizing</span> - </CCardHeader> - <CCardBody> - <p> - Alternatively, of implementing button sizing classes to each button in a group, set{' '} - <code>size</code> property to all <code><CButtonGroup></code>'s, including - each one when nesting multiple groups. - </p> - <DocsExample href="components/button-group#sizing"> - <CButtonGroup size="lg" role="group" aria-label="Large button group"> - <CButton color="dark" variant="outline"> - Left - </CButton> - <CButton color="dark" variant="outline"> - Middle - </CButton> - <CButton color="dark" variant="outline"> - Right - </CButton> - </CButtonGroup> - <br /> - <CButtonGroup role="group" aria-label="Default button group"> - <CButton color="dark" variant="outline"> - Left - </CButton> - <CButton color="dark" variant="outline"> - Middle - </CButton> - <CButton color="dark" variant="outline"> - Right - </CButton> - </CButtonGroup> - <br /> - <CButtonGroup size="sm" role="group" aria-label="Small button group"> - <CButton color="dark" variant="outline"> - Left - </CButton> - <CButton color="dark" variant="outline"> - Middle - </CButton> - <CButton color="dark" variant="outline"> - Right - </CButton> - </CButtonGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button Group</strong> <span>Nesting</span> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Put a <code><CButtonGroup></code> inside another{' '} - <code><CButtonGroup></code> when you need dropdown menus combined with a series - of buttons. - </p> - <DocsExample href="components/button-group#nesting"> - <CButtonGroup role="group" aria-label="Button group with nested dropdown"> - <CButton color="primary">1</CButton> - <CButton color="primary">2</CButton> - <CDropdown variant="btn-group"> - <CDropdownToggle color="primary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </CButtonGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button Group</strong> <span>Vertical variation</span> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Create a set of buttons that appear vertically stacked rather than horizontally.{' '} - <strong>Split button dropdowns are not supported here.</strong> - </p> - <DocsExample href="components/button-group/#vertical-variation"> - <CButtonGroup vertical role="group" aria-label="Vertical button group"> - <CButton color="dark">Button</CButton> - <CButton color="dark">Button</CButton> - <CButton color="dark">Button</CButton> - <CButton color="dark">Button</CButton> - <CButton color="dark">Button</CButton> - <CButton color="dark">Button</CButton> - <CButton color="dark">Button</CButton> - </CButtonGroup> - </DocsExample> - <DocsExample href="components/button-group/#vertical-variation"> - <CButtonGroup vertical role="group" aria-label="Vertical button group"> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - <CDropdown variant="btn-group"> - <CDropdownToggle color="primary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - <CDropdown variant="btn-group"> - <CDropdownToggle color="primary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CDropdown variant="btn-group"> - <CDropdownToggle color="primary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CDropdown variant="btn-group"> - <CDropdownToggle color="primary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </CButtonGroup> - </DocsExample> - <DocsExample href="components/button-group/#vertical-variation"> - <CButtonGroup vertical role="group" aria-label="Vertical button group"> - <CFormCheck - type="radio" - button={{ color: 'danger', variant: 'outline' }} - name="vbtnradio" - id="vbtnradio1" - autoComplete="off" - label="Radio 1" - defaultChecked - /> - <CFormCheck - type="radio" - button={{ color: 'danger', variant: 'outline' }} - name="vbtnradio" - id="vbtnradio2" - autoComplete="off" - label="Radio 2" - /> - <CFormCheck - type="radio" - button={{ color: 'danger', variant: 'outline' }} - name="vbtnradio" - id="vbtnradio3" - autoComplete="off" - label="Radio 3" - /> - </CButtonGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default ButtonGroups diff --git a/src/views/buttons/buttons/Buttons.js b/src/views/buttons/buttons/Buttons.js deleted file mode 100644 index 48f6fcf7..00000000 --- a/src/views/buttons/buttons/Buttons.js +++ /dev/null @@ -1,401 +0,0 @@ -import React from 'react' -import { CButton, CCard, CCardBody, CCardHeader, CCol, CRow } from '@coreui/react' -import CIcon from '@coreui/icons-react' -import { cilBell } from '@coreui/icons' -import { DocsExample } from 'src/components' - -const Buttons = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - CoreUI includes a bunch of predefined buttons components, each serving its own - semantic purpose. Buttons show what action will happen when the user clicks or touches - it. CoreUI buttons are used to initialize operations, both in the background or - foreground of an experience. - </p> - <DocsExample href="components/buttons"> - {['normal', 'active', 'disabled'].map((state, index) => ( - <CRow className="align-items-center mb-3" key={index}> - <CCol xs={12} xl={2} className="mb-3 mb-xl-0"> - {state.charAt(0).toUpperCase() + state.slice(1)} - </CCol> - <CCol xs> - {[ - 'primary', - 'secondary', - 'success', - 'danger', - 'warning', - 'info', - 'light', - 'dark', - ].map((color, index) => ( - <CButton - color={color} - key={index} - active={state === 'active'} - disabled={state === 'disabled'} - > - {color.charAt(0).toUpperCase() + color.slice(1)} - </CButton> - ))} - <CButton color="link">Link</CButton> - </CCol> - </CRow> - ))} - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button</strong> <small>with icons</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - You can combine button with our <a href="https://icons.coreui.io/">CoreUI Icons</a>. - </p> - <DocsExample href="components/buttons"> - {['normal', 'active', 'disabled'].map((state, index) => ( - <CRow className="align-items-center mb-3" key={index}> - <CCol xs={12} xl={2} className="mb-3 mb-xl-0"> - {state.charAt(0).toUpperCase() + state.slice(1)} - </CCol> - <CCol xs> - {[ - 'primary', - 'secondary', - 'success', - 'danger', - 'warning', - 'info', - 'light', - 'dark', - ].map((color, index) => ( - <CButton - color={color} - key={index} - active={state === 'active'} - disabled={state === 'disabled'} - > - <CIcon icon={cilBell} className="me-2" /> - {color.charAt(0).toUpperCase() + color.slice(1)} - </CButton> - ))} - <CButton color="link"> - <CIcon icon={cilBell} className="me-2" /> - Link - </CButton> - </CCol> - </CRow> - ))} - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button</strong> <small>Button components</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - The <code><CButton></code> component are designed for{' '} - <code><button></code> , <code><a></code> or <code><input></code>{' '} - elements (though some browsers may apply a slightly different rendering). - </p> - <p className="text-medium-emphasis small"> - If you're using <code><CButton></code> component as <code><a></code>{' '} - elements that are used to trigger functionality ex. collapsing content, these links - should be given a <code>role="button"</code> to adequately communicate their - meaning to assistive technologies such as screen readers. - </p> - <DocsExample href="components/buttons#button-components"> - <CButton component="a" color="primary" href="#" role="button"> - Link - </CButton> - <CButton type="submit" color="primary"> - Button - </CButton> - <CButton component="input" type="button" color="primary" value="Input" /> - <CButton component="input" type="submit" color="primary" value="Submit" /> - <CButton component="input" type="reset" color="primary" value="Reset" /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button</strong> <small>outline</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - If you need a button, but without the strong background colors. Set{' '} - <code>variant="outline"</code> prop to remove all background colors. - </p> - <DocsExample href="components/buttons#outline-buttons"> - {['normal', 'active', 'disabled'].map((state, index) => ( - <CRow className="align-items-center mb-3" key={index}> - <CCol xs={12} xl={2} className="mb-3 mb-xl-0"> - {state.charAt(0).toUpperCase() + state.slice(1)} - </CCol> - <CCol xs> - {[ - 'primary', - 'secondary', - 'success', - 'danger', - 'warning', - 'info', - 'light', - 'dark', - ].map((color, index) => ( - <CButton - color={color} - variant="outline" - key={index} - active={state === 'active'} - disabled={state === 'disabled'} - > - {color.charAt(0).toUpperCase() + color.slice(1)} - </CButton> - ))} - </CCol> - </CRow> - ))} - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button</strong> <small>ghost</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - If you need a ghost variant of button, set <code>variant="ghost"</code> prop - to remove all background colors. - </p> - <DocsExample href="components/buttons#ghost-buttons"> - {['normal', 'active', 'disabled'].map((state, index) => ( - <CRow className="align-items-center mb-3" key={index}> - <CCol xs={12} xl={2} className="mb-3 mb-xl-0"> - {state.charAt(0).toUpperCase() + state.slice(1)} - </CCol> - <CCol xs> - {[ - 'primary', - 'secondary', - 'success', - 'danger', - 'warning', - 'info', - 'light', - 'dark', - ].map((color, index) => ( - <CButton - color={color} - variant="ghost" - key={index} - active={state === 'active'} - disabled={state === 'disabled'} - > - {color.charAt(0).toUpperCase() + color.slice(1)} - </CButton> - ))} - </CCol> - </CRow> - ))} - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button</strong> <small>Sizes</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Larger or smaller buttons? Add <code>size="lg"</code> or{' '} - <code>size="sm"</code> for additional sizes. - </p> - <DocsExample href="components/buttons#sizes"> - <CButton color="primary" size="lg"> - Large button - </CButton> - <CButton color="secondary" size="lg"> - Large button - </CButton> - </DocsExample> - <DocsExample href="components/buttons#sizes"> - <CButton color="primary" size="sm"> - Small button - </CButton> - <CButton color="secondary" size="sm"> - Small button - </CButton> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button</strong> <small>Pill</small> - </CCardHeader> - <CCardBody> - <DocsExample href="components/buttons#pill-buttons"> - {[ - 'primary', - 'secondary', - 'success', - 'danger', - 'warning', - 'info', - 'light', - 'dark', - ].map((color, index) => ( - <CButton color={color} shape="rounded-pill" key={index}> - {color.charAt(0).toUpperCase() + color.slice(1)} - </CButton> - ))} - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button</strong> <small>Square</small> - </CCardHeader> - <CCardBody> - <DocsExample href="components/buttons#square"> - {[ - 'primary', - 'secondary', - 'success', - 'danger', - 'warning', - 'info', - 'light', - 'dark', - ].map((color, index) => ( - <CButton color={color} shape="rounded-0" key={index}> - {color.charAt(0).toUpperCase() + color.slice(1)} - </CButton> - ))} - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button</strong> <small>Disabled state</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add the <code>disabled</code> boolean prop to any <code><CButton></code>{' '} - component to make buttons look inactive. Disabled button has{' '} - <code>pointer-events: none</code> applied to, disabling hover and active states from - triggering. - </p> - <DocsExample href="components/buttons#disabled-state"> - <CButton color="primary" size="lg" disabled> - Primary button - </CButton> - <CButton color="secondary" size="lg" disabled> - Button - </CButton> - </DocsExample> - <p className="text-medium-emphasis small"> - Disabled buttons using the <code><a></code> component act a little different: - </p> - <p className="text-medium-emphasis small"> - <code><a></code>s don'tsupport the <code>disabled</code> attribute, so - CoreUI has to add <code>.disabled</code> className to make buttons look inactive. - CoreUI also has to add to the disabled button component{' '} - <code>aria-disabled="true"</code> attribute to show the state of the component - to assistive technologies. - </p> - <DocsExample href="components/buttons#disabled-state"> - <CButton component="a" href="#" color="primary" size="lg" disabled> - Primary link - </CButton> - <CButton component="a" href="#" color="secondary" size="lg" disabled> - Link - </CButton> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Button</strong> <small>Block buttons</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Create buttons that span the full width of a parent—by using utilities. - </p> - <DocsExample href="components/buttons#block-buttons"> - <div className="d-grid gap-2"> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - </div> - </DocsExample> - <p className="text-medium-emphasis small"> - Here we create a responsive variation, starting with vertically stacked buttons until - the <code>md</code> breakpoint, where <code>.d-md-block</code> replaces the{' '} - <code>.d-grid</code> class, thus nullifying the <code>gap-2</code> utility. Resize - your browser to see them change. - </p> - <DocsExample href="components/buttons#block-buttons"> - <div className="d-grid gap-2 d-md-block"> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - </div> - </DocsExample> - <p className="text-medium-emphasis small"> - You can adjust the width of your block buttons with grid column width classes. For - example, for a half-width "block button", use <code>.col-6</code>. Center it - horizontally with <code>.mx-auto</code>, too. - </p> - <DocsExample href="components/buttons#block-buttons"> - <div className="d-grid gap-2 col-6 mx-auto"> - <CButton color="primary">Button</CButton> - <CButton color="primary">Button</CButton> - </div> - </DocsExample> - <p className="text-medium-emphasis small"> - Additional utilities can be used to adjust the alignment of buttons when horizontal. - Here we've taken our previous responsive example and added some flex utilities and - a margin utility on the button to right align the buttons when they're no longer - stacked. - </p> - <DocsExample href="components/buttons#block-buttons"> - <div className="d-grid gap-2 d-md-flex justify-content-md-end"> - <CButton color="primary" className="me-md-2"> - Button - </CButton> - <CButton color="primary">Button</CButton> - </div> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Buttons diff --git a/src/views/buttons/dropdowns/Dropdowns.js b/src/views/buttons/dropdowns/Dropdowns.js deleted file mode 100644 index 414f651f..00000000 --- a/src/views/buttons/dropdowns/Dropdowns.js +++ /dev/null @@ -1,338 +0,0 @@ -import React from 'react' -import { - CButton, - CButtonGroup, - CCard, - CCardBody, - CCardHeader, - CCol, - CDropdown, - CDropdownDivider, - CDropdownItem, - CDropdownMenu, - CDropdownToggle, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const Dropdowns = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Dropdown</strong> <small>Single button</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Here's how you can put them to work with either <code><button></code>{' '} - elements: - </p> - <DocsExample href="components/dropdown#single-button"> - <CDropdown> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </DocsExample> - <p className="text-medium-emphasis small"> - The best part is you can do this with any button variant, too: - </p> - <DocsExample href="components/dropdown#single-button"> - <> - {['primary', 'secondary', 'success', 'info', 'warning', 'danger'].map( - (color, index) => ( - <CDropdown variant="btn-group" key={index}> - <CDropdownToggle color={color}>{color}</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - ), - )} - </> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Dropdown</strong> <small>Split button</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Similarly, create split button dropdowns with virtually the same markup as single - button dropdowns, but with the addition of boolean prop <code>split</code> for proper - spacing around the dropdown caret. - </p> - <p className="text-medium-emphasis small"> - We use this extra class to reduce the horizontal <code>padding</code> on either side - of the caret by 25% and remove the <code>margin-left</code> that's attached for - normal button dropdowns. Those additional changes hold the caret centered in the split - button and implement a more properly sized hit area next to the main button. - </p> - <DocsExample href="components/dropdown#split-button"> - <> - {['primary', 'secondary', 'success', 'info', 'warning', 'danger'].map( - (color, index) => ( - <CDropdown variant="btn-group" key={index}> - <CButton color={color}>{color}</CButton> - <CDropdownToggle color={color} split /> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - ), - )} - </> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Dropdown</strong> <small>Sizing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Button dropdowns work with buttons of all sizes, including default and split dropdown - buttons. - </p> - <DocsExample href="components/dropdown#sizing"> - <CDropdown variant="btn-group"> - <CDropdownToggle color="secondary" size="lg"> - Large button - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CDropdown variant="btn-group"> - <CButton color="secondary" size="lg"> - Large split button - </CButton> - <CDropdownToggle color="secondary" size="lg" split /> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </DocsExample> - <DocsExample href="components/dropdown#sizing"> - <CDropdown variant="btn-group"> - <CDropdownToggle color="secondary" size="sm"> - Small button - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CDropdown variant="btn-group"> - <CButton color="secondary" size="sm"> - Small split button - </CButton> - <CDropdownToggle color="secondary" size="sm" split /> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Dropdown</strong> <small>Single button</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Opt into darker dropdowns to match a dark navbar or custom style by set{' '} - <code>dark</code> property. No changes are required to the dropdown items. - </p> - <DocsExample href="components/dropdown#dark-dropdowns"> - <CDropdown dark> - <CDropdownToggle color="secondary">Dropdown button</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </DocsExample> - <p className="text-medium-emphasis small">And putting it to use in a navbar:</p> - <DocsExample href="components/dropdown#dark-dropdowns"> - <nav className="navbar navbar-expand-lg navbar-dark bg-dark"> - <div className="container-fluid"> - <a className="navbar-brand" href="https://coreui.io/react/"> - Navbar - </a> - <button - className="navbar-toggler" - type="button" - data-coreui-toggle="collapse" - data-coreui-target="#navbarNavDarkDropdown" - aria-controls="navbarNavDarkDropdown" - aria-expanded="false" - aria-label="Toggle navigation" - > - <span className="navbar-toggler-icon"></span> - </button> - <div className="collapse navbar-collapse" id="navbarNavDarkDropdown"> - <ul className="navbar-nav"> - <CDropdown dark component="li" variant="nav-item"> - <CDropdownToggle>Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </ul> - </div> - </div> - </nav> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Dropdown</strong> <small>Dropup</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Trigger dropdown menus above elements by adding{' '} - <code>direction="dropup"</code> to the <code><CDropdown></code>{' '} - component. - </p> - <DocsExample href="components/dropdown#dropup"> - <CDropdown variant="btn-group" direction="dropup"> - <CDropdownToggle color="secondary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CDropdown variant="btn-group" direction="dropup"> - <CButton color="secondary">Small split button</CButton> - <CDropdownToggle color="secondary" split /> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Dropdown</strong> <small>Dropright</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Trigger dropdown menus at the right of the elements by adding{' '} - <code>direction="dropend"</code> to the <code><CDropdown></code>{' '} - component. - </p> - <DocsExample href="components/dropdown#dropright"> - <CDropdown variant="btn-group" direction="dropend"> - <CDropdownToggle color="secondary">Dropdown</CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CDropdown variant="btn-group" direction="dropend"> - <CButton color="secondary">Small split button</CButton> - <CDropdownToggle color="secondary" split /> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Dropdown</strong> <small>Dropleft</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Trigger dropdown menus at the left of the elements by adding{' '} - <code>direction="dropstart"</code> to the <code><CDropdown></code>{' '} - component. - </p> - <DocsExample href="components/dropdown#dropleft"> - <CButtonGroup> - <CDropdown variant="btn-group" direction="dropstart"> - <CDropdownToggle color="secondary" split /> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CButton color="secondary">Small split button</CButton> - </CButtonGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Dropdowns diff --git a/src/views/buttons/index.js b/src/views/buttons/index.js deleted file mode 100644 index 6634d152..00000000 --- a/src/views/buttons/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import ButtonDropdowns from './ButtonDropdowns' -import ButtonGroups from './ButtonGroups' -import Buttons from './Buttons' - -export { ButtonDropdowns, ButtonGroups, Buttons } diff --git a/src/views/charts/Charts.js b/src/views/charts/Charts.js deleted file mode 100644 index a9e13f10..00000000 --- a/src/views/charts/Charts.js +++ /dev/null @@ -1,176 +0,0 @@ -import React from 'react' -import { CCard, CCardBody, CCol, CCardHeader, CRow } from '@coreui/react' -import { - CChartBar, - CChartDoughnut, - CChartLine, - CChartPie, - CChartPolarArea, - CChartRadar, -} from '@coreui/react-chartjs' -import { DocsCallout } from 'src/components' - -const Charts = () => { - const random = () => Math.round(Math.random() * 100) - - return ( - <CRow> - <CCol xs={12}> - <DocsCallout - name="Chart" - href="components/chart" - content="React wrapper component for Chart.js 3.0, the most popular charting library." - /> - </CCol> - <CCol xs={6}> - <CCard className="mb-4"> - <CCardHeader>Bar Chart</CCardHeader> - <CCardBody> - <CChartBar - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - label: 'GitHub Commits', - backgroundColor: '#f87979', - data: [40, 20, 12, 39, 10, 40, 39, 80, 40], - }, - ], - }} - labels="months" - /> - </CCardBody> - </CCard> - </CCol> - <CCol xs={6}> - <CCard className="mb-4"> - <CCardHeader>Line Chart</CCardHeader> - <CCardBody> - <CChartLine - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'rgba(220, 220, 220, 0.2)', - borderColor: 'rgba(220, 220, 220, 1)', - pointBackgroundColor: 'rgba(220, 220, 220, 1)', - pointBorderColor: '#fff', - data: [random(), random(), random(), random(), random(), random(), random()], - }, - { - label: 'My Second dataset', - backgroundColor: 'rgba(151, 187, 205, 0.2)', - borderColor: 'rgba(151, 187, 205, 1)', - pointBackgroundColor: 'rgba(151, 187, 205, 1)', - pointBorderColor: '#fff', - data: [random(), random(), random(), random(), random(), random(), random()], - }, - ], - }} - /> - </CCardBody> - </CCard> - </CCol> - <CCol xs={6}> - <CCard className="mb-4"> - <CCardHeader>Doughnut Chart</CCardHeader> - <CCardBody> - <CChartDoughnut - data={{ - labels: ['VueJs', 'EmberJs', 'ReactJs', 'AngularJs'], - datasets: [ - { - backgroundColor: ['#41B883', '#E46651', '#00D8FF', '#DD1B16'], - data: [40, 20, 80, 10], - }, - ], - }} - /> - </CCardBody> - </CCard> - </CCol> - <CCol xs={6}> - <CCard className="mb-4"> - <CCardHeader>Pie Chart</CCardHeader> - <CCardBody> - <CChartPie - data={{ - labels: ['Red', 'Green', 'Yellow'], - datasets: [ - { - data: [300, 50, 100], - backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], - hoverBackgroundColor: ['#FF6384', '#36A2EB', '#FFCE56'], - }, - ], - }} - /> - </CCardBody> - </CCard> - </CCol> - <CCol xs={6}> - <CCard className="mb-4"> - <CCardHeader>Polar Area Chart</CCardHeader> - <CCardBody> - <CChartPolarArea - data={{ - labels: ['Red', 'Green', 'Yellow', 'Grey', 'Blue'], - datasets: [ - { - data: [11, 16, 7, 3, 14], - backgroundColor: ['#FF6384', '#4BC0C0', '#FFCE56', '#E7E9ED', '#36A2EB'], - }, - ], - }} - /> - </CCardBody> - </CCard> - </CCol> - <CCol xs={6}> - <CCard className="mb-4"> - <CCardHeader>Radar Chart</CCardHeader> - <CCardBody> - <CChartRadar - data={{ - labels: [ - 'Eating', - 'Drinking', - 'Sleeping', - 'Designing', - 'Coding', - 'Cycling', - 'Running', - ], - datasets: [ - { - label: 'My First dataset', - backgroundColor: 'rgba(220, 220, 220, 0.2)', - borderColor: 'rgba(220, 220, 220, 1)', - pointBackgroundColor: 'rgba(220, 220, 220, 1)', - pointBorderColor: '#fff', - pointHighlightFill: '#fff', - pointHighlightStroke: 'rgba(220, 220, 220, 1)', - data: [65, 59, 90, 81, 56, 55, 40], - }, - { - label: 'My Second dataset', - backgroundColor: 'rgba(151, 187, 205, 0.2)', - borderColor: 'rgba(151, 187, 205, 1)', - pointBackgroundColor: 'rgba(151, 187, 205, 1)', - pointBorderColor: '#fff', - pointHighlightFill: '#fff', - pointHighlightStroke: 'rgba(151, 187, 205, 1)', - data: [28, 48, 40, 19, 96, 27, 100], - }, - ], - }} - /> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Charts diff --git a/src/views/configurator-collators/ConfiguratorCollators.js b/src/views/configurator-collators/ConfiguratorCollators.js new file mode 100644 index 00000000..9a6f99eb --- /dev/null +++ b/src/views/configurator-collators/ConfiguratorCollators.js @@ -0,0 +1,10 @@ +import React from 'react' + +const ConfiguratorCollators = () => { + + return ( + <h1>Configure Collators</h1> + ) +} + +export default ConfiguratorCollators diff --git a/src/views/configurator-coretime/ConfiguratorCoretime.js b/src/views/configurator-coretime/ConfiguratorCoretime.js new file mode 100644 index 00000000..62f39313 --- /dev/null +++ b/src/views/configurator-coretime/ConfiguratorCoretime.js @@ -0,0 +1,10 @@ +import React from 'react' + +const ConfiguratorCoretime = () => { + + return ( + <h1>Configure Coretime</h1> + ) +} + +export default ConfiguratorCoretime diff --git a/src/views/configurator-runtime/ConfiguratorRuntime.js b/src/views/configurator-runtime/ConfiguratorRuntime.js new file mode 100644 index 00000000..123250a8 --- /dev/null +++ b/src/views/configurator-runtime/ConfiguratorRuntime.js @@ -0,0 +1,10 @@ +import React from 'react' + +const ConfiguratorRuntime = () => { + + return ( + <h1>Configure Runtime</h1> + ) +} + +export default ConfiguratorRuntime diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js new file mode 100644 index 00000000..ea849422 --- /dev/null +++ b/src/views/configurator/Configurator.js @@ -0,0 +1,10 @@ +import React from 'react' + +const Configurator = () => { + + return ( + <h1>CONFIGURE DEPLOYMENT</h1> + ) +} + +export default Configurator diff --git a/src/views/coretime/Coretime.js b/src/views/coretime/Coretime.js new file mode 100644 index 00000000..516276f3 --- /dev/null +++ b/src/views/coretime/Coretime.js @@ -0,0 +1,12 @@ +import React from 'react' + +const Coretime = () => { + + return ( + <h1> + THIS IS CORETIME BABY + </h1> + ) +} + +export default Coretime diff --git a/src/views/empty/Empty.js b/src/views/empty/Empty.js new file mode 100644 index 00000000..75cdf479 --- /dev/null +++ b/src/views/empty/Empty.js @@ -0,0 +1,13 @@ +import React from 'react' + +const Empty = () => { + + return ( + <h1> + There's no deployment available. + Let's get started! + </h1> + ) +} + +export default Empty diff --git a/src/views/forms/checks-radios/ChecksRadios.js b/src/views/forms/checks-radios/ChecksRadios.js deleted file mode 100644 index f35862ec..00000000 --- a/src/views/forms/checks-radios/ChecksRadios.js +++ /dev/null @@ -1,392 +0,0 @@ -import React from 'react' -import { CCard, CCardBody, CCardHeader, CCol, CFormCheck, CFormSwitch, CRow } from '@coreui/react' -import { DocsExample } from 'src/components' - -const ChecksRadios = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Checkbox</strong> - </CCardHeader> - <CCardBody> - <DocsExample href="forms/checks-radios"> - <CFormCheck id="flexCheckDefault" label="Default checkbox" /> - <CFormCheck id="flexCheckChecked" label="Checked checkbox" defaultChecked /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Checkbox</strong> <small>Disabled</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add the <code>disabled</code> attribute and the associated <code><label></code>s - are automatically styled to match with a lighter color to help indicate the - input's state. - </p> - <DocsExample href="forms/checks-radios#disabled"> - <CFormCheck label="Disabled checkbox" disabled /> - <CFormCheck label="Disabled checked checkbox" defaultChecked disabled /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Radio</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add the <code>disabled</code> attribute and the associated <code><label></code>s - are automatically styled to match with a lighter color to help indicate the - input's state. - </p> - <DocsExample href="forms/checks-radios#radios"> - <CFormCheck - type="radio" - name="flexRadioDefault" - id="flexRadioDefault1" - label="Default radio" - /> - <CFormCheck - type="radio" - name="flexRadioDefault" - id="flexRadioDefault2" - label="Checked radio" - defaultChecked - /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Radio</strong> <small>Disabled</small> - </CCardHeader> - <CCardBody> - <DocsExample href="forms/checks-radios#disabled-1"> - <CFormCheck - type="radio" - name="flexRadioDisabled" - id="flexRadioDisabled" - label="Disabled radio" - disabled - /> - <CFormCheck - type="radio" - name="flexRadioDisabled" - id="flexRadioCheckedDisabled" - label="Disabled checked radio" - defaultChecked - disabled - /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Switches</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - A switch has the markup of a custom checkbox but uses the <code>switch</code> boolean - properly to render a toggle switch. Switches also support the <code>disabled</code>{' '} - attribute. - </p> - <DocsExample href="forms/checks-radios#switches"> - <CFormSwitch label="Default switch checkbox input" id="formSwitchCheckDefault" /> - <CFormSwitch - label="Checked switch checkbox input" - id="formSwitchCheckChecked" - defaultChecked - /> - <CFormSwitch - label="Disabled switch checkbox input" - id="formSwitchCheckDisabled" - disabled - /> - <CFormSwitch - label="Disabled checked switch checkbox input" - id="formSwitchCheckCheckedDisabled" - defaultChecked - disabled - /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Switches</strong> <small>Sizes</small> - </CCardHeader> - <CCardBody> - <DocsExample href="forms/checks-radios#sizes"> - <CFormSwitch label="Default switch checkbox input" id="formSwitchCheckDefault" /> - <CFormSwitch - size="lg" - label="Large switch checkbox input" - id="formSwitchCheckDefaultLg" - /> - <CFormSwitch - size="xl" - label="Extra large switch checkbox input" - id="formSwitchCheckDefaultXL" - /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Checks and Radios</strong> <small>Default layout (stacked)</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - By default, any number of checkboxes and radios that are immediate sibling will be - vertically stacked and appropriately spaced. - </p> - <DocsExample href="forms/checks-radios#default-stacked"> - <CFormCheck id="defaultCheck1" label="Default checkbox" /> - <CFormCheck id="defaultCheck2" label="Disabled checkbox" disabled /> - </DocsExample> - <DocsExample href="forms/checks-radios#default-stacked"> - <CFormCheck - type="radio" - name="exampleRadios" - id="exampleRadios1" - value="option1" - label="Default radio" - defaultChecked - /> - <CFormCheck - type="radio" - name="exampleRadios" - id="exampleRadios2" - value="option2" - label="Second default radio" - /> - <CFormCheck - type="radio" - name="exampleRadios" - id="exampleRadios3" - value="option3" - label="Disabled radio" - disabled - /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Checks and Radios</strong> <small>Inline</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Group checkboxes or radios on the same horizontal row by adding <code>inline</code>{' '} - boolean property to any <code><CFormCheck></code>. - </p> - <DocsExample href="forms/checks-radios#inline"> - <CFormCheck inline id="inlineCheckbox1" value="option1" label="1" /> - <CFormCheck inline id="inlineCheckbox2" value="option2" label="2" /> - <CFormCheck - inline - id="inlineCheckbox3" - value="option3" - label="3 (disabled)" - disabled - /> - </DocsExample> - <DocsExample href="forms/checks-radios#inline"> - <CFormCheck - inline - type="radio" - name="inlineRadioOptions" - id="inlineCheckbox1" - value="option1" - label="1" - /> - <CFormCheck - inline - type="radio" - name="inlineRadioOptions" - id="inlineCheckbox2" - value="option2" - label="2" - /> - <CFormCheck - inline - type="radio" - name="inlineRadioOptions" - id="inlineCheckbox3" - value="option3" - label="3 (disabled)" - disabled - /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Checks and Radios</strong> <small>Without labels</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Remember to still provide some form of accessible name for assistive technologies (for - instance, using <code>aria-label</code>). - </p> - <DocsExample href="forms/checks-radios#without-labels"> - <div> - <CFormCheck id="checkboxNoLabel" value="" aria-label="..." /> - </div> - <div> - <CFormCheck - type="radio" - name="radioNoLabel" - id="radioNoLabel" - value="" - aria-label="..." - /> - </div> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Toggle buttons</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Create button-like checkboxes and radio buttons by using <code>button</code> boolean - property on the <code><CFormCheck></code> component. These toggle buttons can - further be grouped in a button group if needed. - </p> - <DocsExample href="forms/checks-radios#toggle-buttons"> - <CFormCheck - button={{ color: 'primary ' }} - id="btn-check" - autoComplete="off" - label="Single toggle" - /> - </DocsExample> - <DocsExample href="forms/checks-radios#toggle-buttons"> - <CFormCheck - button={{ color: 'primary ' }} - id="btn-check-2" - autoComplete="off" - label="Checked" - defaultChecked - /> - </DocsExample> - <DocsExample href="forms/checks-radios#toggle-buttons"> - <CFormCheck - button={{ color: 'primary ' }} - id="btn-check-3" - autoComplete="off" - label="Disabled" - disabled - /> - </DocsExample> - <h3>Radio toggle buttons</h3> - <DocsExample href="forms/checks-radios#toggle-buttons"> - <CFormCheck - button={{ color: 'secondary' }} - type="radio" - name="options" - id="option1" - autoComplete="off" - label="Checked" - defaultChecked - /> - <CFormCheck - button={{ color: 'secondary' }} - type="radio" - name="options" - id="option2" - autoComplete="off" - label="Radio" - /> - <CFormCheck - button={{ color: 'secondary' }} - type="radio" - name="options" - id="option3" - autoComplete="off" - label="Radio" - disabled - /> - <CFormCheck - button={{ color: 'secondary' }} - type="radio" - name="options" - id="option4" - autoComplete="off" - label="Radio" - /> - </DocsExample> - <h3>Outlined styles</h3> - <p className="text-medium-emphasis small"> - Different variants of button, such at the various outlined styles, are supported. - </p> - <DocsExample href="forms/checks-radios#toggle-buttons"> - <div> - <CFormCheck - button={{ color: 'primary', variant: 'outline' }} - id="btn-check-outlined" - autoComplete="off" - label="Single toggle" - /> - </div> - <div> - <CFormCheck - button={{ color: 'secondary', variant: 'outline' }} - id="btn-check-2-outlined" - autoComplete="off" - label="Checked" - defaultChecked - /> - </div> - <div> - <CFormCheck - button={{ color: 'success', variant: 'outline' }} - type="radio" - name="options-outlined" - id="success-outlined" - autoComplete="off" - label="Radio" - defaultChecked - /> - <CFormCheck - button={{ color: 'danger', variant: 'outline' }} - type="radio" - name="options-outlined" - id="danger-outlined" - autoComplete="off" - label="Radio" - /> - </div> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default ChecksRadios diff --git a/src/views/forms/floating-labels/FloatingLabels.js b/src/views/forms/floating-labels/FloatingLabels.js deleted file mode 100644 index d40f5b35..00000000 --- a/src/views/forms/floating-labels/FloatingLabels.js +++ /dev/null @@ -1,170 +0,0 @@ -import React from 'react' -import { - CCard, - CCardBody, - CCardHeader, - CCol, - CFormInput, - CFormLabel, - CFormFloating, - CFormSelect, - CFormTextarea, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const FloatingLabels = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Floating labels</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Wrap a pair of <code><CFormInput></code> and <code><CFormLabel></code>{' '} - elements in <code>CFormFloating</code> to enable floating labels with textual form - fields. A <code>placeholder</code> is required on each <code><CFormInput></code>{' '} - as our method of CSS-only floating labels uses the <code>:placeholder-shown</code>{' '} - pseudo-element. Also note that the <code><CFormInput></code> must come first so - we can utilize a sibling selector (e.g., <code>~</code>). - </p> - <DocsExample href="forms/floating-labels"> - <CFormFloating className="mb-3"> - <CFormInput type="email" id="floatingInput" placeholder="name@example.com" /> - <CFormLabel htmlFor="floatingInput">Email address</CFormLabel> - </CFormFloating> - <CFormFloating> - <CFormInput type="password" id="floatingPassword" placeholder="Password" /> - <CFormLabel htmlFor="floatingPassword">Password</CFormLabel> - </CFormFloating> - </DocsExample> - <p className="text-medium-emphasis small"> - When there's a <code>value</code> already defined, <code><CFormLabel></code> - s will automatically adjust to their floated position. - </p> - <DocsExample href="forms/floating-labels"> - <CFormFloating> - <CFormInput - type="email" - id="floatingInputValue" - placeholder="name@example.com" - defaultValue="test@example.com" - /> - <CFormLabel htmlFor="floatingInputValue">Input with value</CFormLabel> - </CFormFloating> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Floating labels</strong> <small>Textareas</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - By default, <code><CFormTextarea></code>s will be the same height as{' '} - <code><CFormInput></code>s. - </p> - <DocsExample href="forms/floating-labels#textareas"> - <CFormFloating> - <CFormTextarea - id="floatingTextarea" - placeholder="Leave a comment here" - ></CFormTextarea> - <CFormLabel htmlFor="floatingTextarea">Comments</CFormLabel> - </CFormFloating> - </DocsExample> - <p className="text-medium-emphasis small"> - To set a custom height on your <code><CFormTextarea;></code>, do not use the{' '} - <code>rows</code> attribute. Instead, set an explicit <code>height</code> (either - inline or via custom CSS). - </p> - <DocsExample href="forms/floating-labels#textareas"> - <CFormFloating> - <CFormTextarea - placeholder="Leave a comment here" - id="floatingTextarea2" - style={{ height: '100px' }} - ></CFormTextarea> - <CFormLabel htmlFor="floatingTextarea2">Comments</CFormLabel> - </CFormFloating> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Floating labels</strong> <small>Selects</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Other than <code><CFormInput></code>, floating labels are only available on{' '} - <code><CFormSelect></code>s. They work in the same way, but unlike{' '} - <code><CFormInput></code>s, they'll always show the{' '} - <code><CFormLabel></code> in its floated state.{' '} - <strong> - Selects with <code>size</code> and <code>multiple</code> are not supported. - </strong> - </p> - <DocsExample href="forms/floating-labels#selects"> - <CFormFloating> - <CFormSelect id="floatingSelect" aria-label="Floating label select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - <CFormLabel htmlFor="floatingSelect">Works with selects</CFormLabel> - </CFormFloating> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Floating labels</strong> <small>Layout</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - When working with the CoreUI for Bootstrap grid system, be sure to place form elements - within column classes. - </p> - <DocsExample href="forms/floating-labels#layout"> - <CRow xs={{ gutter: 2 }}> - <CCol md> - <CFormFloating> - <CFormInput - type="email" - id="floatingInputGrid" - placeholder="name@example.com" - defaultValue="email@example.com" - /> - <CFormLabel htmlFor="floatingInputGrid">Email address</CFormLabel> - </CFormFloating> - </CCol> - <CCol md> - <CFormFloating> - <CFormSelect id="floatingSelectGrid" aria-label="Floating label select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - <CFormLabel htmlFor="floatingSelectGrid">Works with selects</CFormLabel> - </CFormFloating> - </CCol> - </CRow> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default FloatingLabels diff --git a/src/views/forms/form-control/FormControl.js b/src/views/forms/form-control/FormControl.js deleted file mode 100644 index 9bdb1076..00000000 --- a/src/views/forms/form-control/FormControl.js +++ /dev/null @@ -1,248 +0,0 @@ -import React from 'react' -import { - CButton, - CCard, - CCardBody, - CCardHeader, - CCol, - CForm, - CFormInput, - CFormLabel, - CFormTextarea, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const FormControl = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Form Control</strong> - </CCardHeader> - <CCardBody> - <DocsExample href="forms/form-control"> - <CForm> - <div className="mb-3"> - <CFormLabel htmlFor="exampleFormControlInput1">Email address</CFormLabel> - <CFormInput - type="email" - id="exampleFormControlInput1" - placeholder="name@example.com" - /> - </div> - <div className="mb-3"> - <CFormLabel htmlFor="exampleFormControlTextarea1">Example textarea</CFormLabel> - <CFormTextarea id="exampleFormControlTextarea1" rows="3"></CFormTextarea> - </div> - </CForm> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Form Control</strong> <small>Sizing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Set heights using <code>size</code> property like <code>size="lg"</code> and{' '} - <code>size="sm"</code>. - </p> - <DocsExample href="forms/form-control#sizing"> - <CFormInput - type="text" - size="lg" - placeholder="Large input" - aria-label="lg input example" - /> - <br /> - <CFormInput - type="text" - placeholder="Default input" - aria-label="default input example" - /> - <br /> - <CFormInput - type="text" - size="sm" - placeholder="Small input" - aria-label="sm input example" - /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Form Control</strong> <small>Disabled</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add the <code>disabled</code> boolean attribute on an input to give it a grayed out - appearance and remove pointer events. - </p> - <DocsExample href="forms/form-control#disabled"> - <CFormInput - type="text" - placeholder="Disabled input" - aria-label="Disabled input example" - disabled - /> - <br /> - <CFormInput - type="text" - placeholder="Disabled readonly input" - aria-label="Disabled input example" - disabled - readOnly - /> - <br /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Form Control</strong> <small>Readonly</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add the <code>readOnly</code> boolean attribute on an input to prevent modification of - the input's value. Read-only inputs appear lighter (just like disabled inputs), - but retain the standard cursor. - </p> - <DocsExample href="forms/form-control#readonly"> - <CFormInput - type="text" - placeholder="Readonly input here..." - aria-label="readonly input example" - readOnly - /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Form Control</strong> <small>Readonly plain text</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - If you want to have <code><input readonly></code> elements in your form styled - as plain text, use the <code>plainText</code> boolean property to remove the default - form field styling and preserve the correct margin and padding. - </p> - <DocsExample href="components/accordion"> - <CRow className="mb-3"> - <CFormLabel htmlFor="staticEmail" className="col-sm-2 col-form-label"> - Email - </CFormLabel> - <div className="col-sm-10"> - <CFormInput - type="text" - id="staticEmail" - defaultValue="email@example.com" - readOnly - plainText - /> - </div> - </CRow> - <CRow className="mb-3"> - <CFormLabel htmlFor="inputPassword" className="col-sm-2 col-form-label"> - Password - </CFormLabel> - <div className="col-sm-10"> - <CFormInput type="password" id="inputPassword" /> - </div> - </CRow> - </DocsExample> - <DocsExample href="components/accordion"> - <CForm className="row g-3"> - <div className="col-auto"> - <CFormLabel htmlFor="staticEmail2" className="visually-hidden"> - Email - </CFormLabel> - <CFormInput - type="text" - id="staticEmail2" - defaultValue="email@example.com" - readOnly - plainText - /> - </div> - <div className="col-auto"> - <CFormLabel htmlFor="inputPassword2" className="visually-hidden"> - Password - </CFormLabel> - <CFormInput type="password" id="inputPassword2" placeholder="Password" /> - </div> - <div className="col-auto"> - <CButton type="submit" className="mb-3"> - Confirm identity - </CButton> - </div> - </CForm> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Form Control</strong> <small>File input</small> - </CCardHeader> - <CCardBody> - <DocsExample href="forms/form-control#file-input"> - <div className="mb-3"> - <CFormLabel htmlFor="formFile">Default file input example</CFormLabel> - <CFormInput type="file" id="formFile" /> - </div> - <div className="mb-3"> - <CFormLabel htmlFor="formFileMultiple">Multiple files input example</CFormLabel> - <CFormInput type="file" id="formFileMultiple" multiple /> - </div> - <div className="mb-3"> - <CFormLabel htmlFor="formFileDisabled">Disabled file input example</CFormLabel> - <CFormInput type="file" id="formFileDisabled" disabled /> - </div> - <div className="mb-3"> - <CFormLabel htmlFor="formFileSm">Small file input example</CFormLabel> - <CFormInput type="file" size="sm" id="formFileSm" /> - </div> - <div> - <CFormLabel htmlFor="formFileLg">Large file input example</CFormLabel> - <CFormInput type="file" size="lg" id="formFileLg" /> - </div> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Form Control</strong> <small>Color</small> - </CCardHeader> - <CCardBody> - <DocsExample href="forms/form-control#color"> - <CFormLabel htmlFor="exampleColorInput">Color picker</CFormLabel> - <CFormInput - type="color" - id="exampleColorInput" - defaultValue="#563d7c" - title="Choose your color" - /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default FormControl diff --git a/src/views/forms/input-group/InputGroup.js b/src/views/forms/input-group/InputGroup.js deleted file mode 100644 index 4b9da78d..00000000 --- a/src/views/forms/input-group/InputGroup.js +++ /dev/null @@ -1,503 +0,0 @@ -import React from 'react' -import { - CButton, - CCard, - CCardBody, - CCardHeader, - CCol, - CDropdown, - CDropdownDivider, - CDropdownItem, - CDropdownMenu, - CDropdownToggle, - CFormCheck, - CFormInput, - CFormLabel, - CFormSelect, - CFormTextarea, - CInputGroup, - CInputGroupText, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const Select = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Input group</strong> <small>Basic example</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Place one add-on or button on either side of an input. You may also place one on both - sides of an input. Remember to place <code><CFormLabel></code>s outside the - input group. - </p> - <DocsExample href="forms/input-group"> - <CInputGroup className="mb-3"> - <CInputGroupText id="basic-addon1">@</CInputGroupText> - <CFormInput - placeholder="Username" - aria-label="Username" - aria-describedby="basic-addon1" - /> - </CInputGroup> - <CInputGroup className="mb-3"> - <CFormInput - placeholder="Recipient's username" - aria-label="Recipient's username" - aria-describedby="basic-addon2" - /> - <CInputGroupText id="basic-addon2">@example.com</CInputGroupText> - </CInputGroup> - <CFormLabel htmlFor="basic-url">Your vanity URL</CFormLabel> - <CInputGroup className="mb-3"> - <CInputGroupText id="basic-addon3">https://example.com/users/</CInputGroupText> - <CFormInput id="basic-url" aria-describedby="basic-addon3" /> - </CInputGroup> - <CInputGroup className="mb-3"> - <CInputGroupText>$</CInputGroupText> - <CFormInput aria-label="Amount (to the nearest dollar)" /> - <CInputGroupText>.00</CInputGroupText> - </CInputGroup> - <CInputGroup className="mb-3"> - <CFormInput placeholder="Username" aria-label="Username" /> - <CInputGroupText>@</CInputGroupText> - <CFormInput placeholder="Server" aria-label="Server" /> - </CInputGroup> - <CInputGroup> - <CInputGroupText>With textarea</CInputGroupText> - <CFormTextarea aria-label="With textarea"></CFormTextarea> - </CInputGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Input group</strong> <small>Wrapping</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Input groups wrap by default via <code>flex-wrap: wrap</code> in order to accommodate - custom form field validation within an input group. You may disable this with{' '} - <code>.flex-nowrap</code>. - </p> - <DocsExample href="forms/input-group#wrapping"> - <CInputGroup className="flex-nowrap"> - <CInputGroupText id="addon-wrapping">@</CInputGroupText> - <CFormInput - placeholder="Username" - aria-label="Username" - aria-describedby="addon-wrapping" - /> - </CInputGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Input group</strong> <small>Sizing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add the relative form sizing classes to the <code><CInputGroup></code> itself - and contents within will automatically resize—no need for repeating the form control - size classes on each element. - </p> - <p className="text-medium-emphasis small"> - <strong>Sizing on the individual input group elements isn'tsupported.</strong> - </p> - <DocsExample href="forms/input-group#sizing"> - <CInputGroup size="sm" className="mb-3"> - <CInputGroupText id="inputGroup-sizing-sm">Small</CInputGroupText> - <CFormInput - aria-label="Sizing example input" - aria-describedby="inputGroup-sizing-sm" - /> - </CInputGroup> - <CInputGroup className="mb-3"> - <CInputGroupText id="inputGroup-sizing-default">Default</CInputGroupText> - <CFormInput - aria-label="Sizing example input" - aria-describedby="inputGroup-sizing-default" - /> - </CInputGroup> - <CInputGroup size="lg"> - <CInputGroupText id="inputGroup-sizing-lg">Large</CInputGroupText> - <CFormInput - aria-label="Sizing example input" - aria-describedby="inputGroup-sizing-lg" - /> - </CInputGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Input group</strong> <small>Checkboxes and radios</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Place any checkbox or radio option within an input group's addon instead of text. - </p> - <DocsExample href="forms/input-group#checkboxes-and-radios"> - <CInputGroup className="mb-3"> - <CInputGroupText> - <CFormCheck - type="checkbox" - value="" - aria-label="Checkbox for following text input" - /> - </CInputGroupText> - <CFormInput aria-label="Text input with checkbox" /> - </CInputGroup> - <CInputGroup> - <CInputGroupText> - <CFormCheck - type="radio" - value="" - aria-label="Radio button for following text input" - /> - </CInputGroupText> - <CFormInput aria-label="Text input with radio button" /> - </CInputGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Input group</strong> <small>Multiple inputs</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - While multiple <code><CFormInput></code>s are supported visually, validation - styles are only available for input groups with a single{' '} - <code><CFormInput></code>. - </p> - <DocsExample href="forms/input-group#multiple-inputs"> - <CInputGroup> - <CInputGroupText>First and last name</CInputGroupText> - <CFormInput aria-label="First name" /> - <CFormInput aria-label="Last name" /> - </CInputGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Input group</strong> <small>Multiple addons</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Multiple add-ons are supported and can be mixed with checkbox and radio input - versions.. - </p> - <DocsExample href="forms/input-group#multiple-addons"> - <CInputGroup className="mb-3"> - <CInputGroupText>$</CInputGroupText> - <CInputGroupText>0.00</CInputGroupText> - <CFormInput aria-label="Dollar amount (with dot and two decimal places)" /> - </CInputGroup> - <CInputGroup> - <CFormInput aria-label="Dollar amount (with dot and two decimal places)" /> - <CInputGroupText>$</CInputGroupText> - <CInputGroupText>0.00</CInputGroupText> - </CInputGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Input group</strong> <small>Button addons</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Multiple add-ons are supported and can be mixed with checkbox and radio input - versions.. - </p> - <DocsExample href="forms/input-group#button-addons"> - <CInputGroup className="mb-3"> - <CButton type="button" color="secondary" variant="outline" id="button-addon1"> - Button - </CButton> - <CFormInput - placeholder="" - aria-label="Example text with button addon" - aria-describedby="button-addon1" - /> - </CInputGroup> - <CInputGroup className="mb-3"> - <CFormInput - placeholder="Recipient's username" - aria-label="Recipient's username" - aria-describedby="button-addon2" - /> - <CButton type="button" color="secondary" variant="outline" id="button-addon2"> - Button - </CButton> - </CInputGroup> - <CInputGroup className="mb-3"> - <CButton type="button" color="secondary" variant="outline"> - Button - </CButton> - <CButton type="button" color="secondary" variant="outline"> - Button - </CButton> - <CFormInput placeholder="" aria-label="Example text with two button addons" /> - </CInputGroup> - <CInputGroup> - <CFormInput - placeholder="Recipient's username" - aria-label="Recipient's username with two button addons" - /> - <CButton type="button" color="secondary" variant="outline"> - Button - </CButton> - <CButton type="button" color="secondary" variant="outline"> - Button - </CButton> - </CInputGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Input group</strong> <small>Buttons with dropdowns</small> - </CCardHeader> - <CCardBody> - <DocsExample href="forms/input-group#buttons-with-dropdowns"> - <CInputGroup className="mb-3"> - <CDropdown variant="input-group"> - <CDropdownToggle color="secondary" variant="outline"> - Dropdown - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CFormInput aria-label="Text input with dropdown button" /> - </CInputGroup> - <CInputGroup className="mb-3"> - <CFormInput aria-label="Text input with dropdown button" /> - <CDropdown alignment="end" variant="input-group"> - <CDropdownToggle color="secondary" variant="outline"> - Dropdown - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </CInputGroup> - <CInputGroup> - <CDropdown variant="input-group"> - <CDropdownToggle color="secondary" variant="outline"> - Dropdown - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CFormInput aria-label="Text input with 2 dropdown buttons" /> - <CDropdown alignment="end" variant="input-group"> - <CDropdownToggle color="secondary" variant="outline"> - Dropdown - </CDropdownToggle> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </CInputGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Input group</strong> <small>Segmented buttons</small> - </CCardHeader> - <CCardBody> - <DocsExample href="forms/input-group#segmented-buttons"> - <CInputGroup className="mb-3"> - <CDropdown variant="input-group"> - <CButton type="button" color="secondary" variant="outline"> - Action - </CButton> - <CDropdownToggle color="secondary" variant="outline" split /> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - <CFormInput aria-label="Text input with segmented dropdown button" /> - </CInputGroup> - <CInputGroup> - <CFormInput aria-label="Text input with segmented dropdown button" /> - <CDropdown alignment="end" variant="input-group"> - <CButton type="button" color="secondary" variant="outline"> - Action - </CButton> - <CDropdownToggle color="secondary" variant="outline" split /> - <CDropdownMenu> - <CDropdownItem href="#">Action</CDropdownItem> - <CDropdownItem href="#">Another action</CDropdownItem> - <CDropdownItem href="#">Something else here</CDropdownItem> - <CDropdownDivider /> - <CDropdownItem href="#">Separated link</CDropdownItem> - </CDropdownMenu> - </CDropdown> - </CInputGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Input group</strong> <small>Custom select</small> - </CCardHeader> - <CCardBody> - <DocsExample href="forms/input-group#custom-select"> - <CInputGroup className="mb-3"> - <CInputGroupText component="label" htmlFor="inputGroupSelect01"> - Options - </CInputGroupText> - <CFormSelect id="inputGroupSelect01"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </CInputGroup> - <CInputGroup className="mb-3"> - <CFormSelect id="inputGroupSelect02"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - <CInputGroupText component="label" htmlFor="inputGroupSelect02"> - Options - </CInputGroupText> - </CInputGroup> - <CInputGroup className="mb-3"> - <CButton type="button" color="secondary" variant="outline"> - Button - </CButton> - <CFormSelect id="inputGroupSelect03" aria-label="Example select with button addon"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </CInputGroup> - <CInputGroup> - <CFormSelect id="inputGroupSelect04" aria-label="Example select with button addon"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - <CButton type="button" color="secondary" variant="outline"> - Button - </CButton> - </CInputGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Input group</strong> <small>Custom file input</small> - </CCardHeader> - <CCardBody> - <DocsExample href="forms/input-group#custom-file-input"> - <CInputGroup className="mb-3"> - <CInputGroupText component="label" htmlFor="inputGroupFile01"> - Upload - </CInputGroupText> - <CFormInput type="file" id="inputGroupFile01" /> - </CInputGroup> - <CInputGroup className="mb-3"> - <CFormInput type="file" id="inputGroupFile02" /> - <CInputGroupText component="label" htmlFor="inputGroupFile02"> - Upload - </CInputGroupText> - </CInputGroup> - <CInputGroup className="mb-3"> - <CButton - type="button" - color="secondary" - variant="outline" - id="inputGroupFileAddon03" - > - Button - </CButton> - <CFormInput - type="file" - id="inputGroupFile03" - aria-describedby="inputGroupFileAddon03" - aria-label="Upload" - /> - </CInputGroup> - <CInputGroup> - <CFormInput - type="file" - id="inputGroupFile04" - aria-describedby="inputGroupFileAddon04" - aria-label="Upload" - /> - <CButton - type="button" - color="secondary" - variant="outline" - id="inputGroupFileAddon04" - > - Button - </CButton> - </CInputGroup> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Select diff --git a/src/views/forms/layout/Layout.js b/src/views/forms/layout/Layout.js deleted file mode 100644 index 27bae196..00000000 --- a/src/views/forms/layout/Layout.js +++ /dev/null @@ -1,414 +0,0 @@ -import React from 'react' -import { - CButton, - CCard, - CCardBody, - CCardHeader, - CCol, - CForm, - CFormCheck, - CFormInput, - CFormLabel, - CFormSelect, - CInputGroup, - CInputGroupText, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const Layout = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Layout</strong> <small>Form grid</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - More complex forms can be built using our grid classes. Use these for form layouts - that require multiple columns, varied widths, and additional alignment options. - </p> - <DocsExample href="forms/layout#form-grid"> - <CRow> - <CCol xs> - <CFormInput placeholder="First name" aria-label="First name" /> - </CCol> - <CCol xs> - <CFormInput placeholder="Last name" aria-label="Last name" /> - </CCol> - </CRow> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Layout</strong> <small>Gutters</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - By adding <a href="https://coreui.io/docs/layout/gutters/">gutter modifier classes</a> - , you can have control over the gutter width in as well the inline as block direction. - </p> - <DocsExample href="forms/layout#gutters"> - <CRow className="g-3"> - <CCol xs> - <CFormInput placeholder="First name" aria-label="First name" /> - </CCol> - <CCol xs> - <CFormInput placeholder="Last name" aria-label="Last name" /> - </CCol> - </CRow> - </DocsExample> - <p className="text-medium-emphasis small"> - More complex layouts can also be created with the grid system. - </p> - <DocsExample href="forms/layout#gutters"> - <CForm className="row g-3"> - <CCol md={6}> - <CFormLabel htmlFor="inputEmail4">Email</CFormLabel> - <CFormInput type="email" id="inputEmail4" /> - </CCol> - <CCol md={6}> - <CFormLabel htmlFor="inputPassword4">Password</CFormLabel> - <CFormInput type="password" id="inputPassword4" /> - </CCol> - <CCol xs={12}> - <CFormLabel htmlFor="inputAddress">Address</CFormLabel> - <CFormInput id="inputAddress" placeholder="1234 Main St" /> - </CCol> - <CCol xs={12}> - <CFormLabel htmlFor="inputAddress2">Address 2</CFormLabel> - <CFormInput id="inputAddress2" placeholder="Apartment, studio, or floor" /> - </CCol> - <CCol md={6}> - <CFormLabel htmlFor="inputCity">City</CFormLabel> - <CFormInput id="inputCity" /> - </CCol> - <CCol md={4}> - <CFormLabel htmlFor="inputState">State</CFormLabel> - <CFormSelect id="inputState"> - <option>Choose...</option> - <option>...</option> - </CFormSelect> - </CCol> - <CCol md={2}> - <CFormLabel htmlFor="inputZip">Zip</CFormLabel> - <CFormInput id="inputZip" /> - </CCol> - <CCol xs={12}> - <CFormCheck type="checkbox" id="gridCheck" label="Check me out" /> - </CCol> - <CCol xs={12}> - <CButton type="submit">Sign in</CButton> - </CCol> - </CForm> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Layout</strong> <small>Horizontal form</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Create horizontal forms with the grid by adding the <code>.row</code> class to form - groups and using the <code>.col-*-*</code> classes to specify the width of your labels - and controls. Be sure to add <code>.col-form-label</code> to your{' '} - <code><CFormLabel></code>s as well so they're vertically centered with their - associated form controls. - </p> - <p className="text-medium-emphasis small"> - At times, you maybe need to use margin or padding utilities to create that perfect - alignment you need. For example, we've removed the <code>padding-top</code> on our - stacked radio inputs label to better align the text baseline. - </p> - <DocsExample href="forms/layout#horizontal-form"> - <CForm> - <CRow className="mb-3"> - <CFormLabel htmlFor="inputEmail3" className="col-sm-2 col-form-label"> - Email - </CFormLabel> - <CCol sm={10}> - <CFormInput type="email" id="inputEmail3" /> - </CCol> - </CRow> - <CRow className="mb-3"> - <CFormLabel htmlFor="inputPassword3" className="col-sm-2 col-form-label"> - Password - </CFormLabel> - <CCol sm={10}> - <CFormInput type="password" id="inputPassword3" /> - </CCol> - </CRow> - <fieldset className="row mb-3"> - <legend className="col-form-label col-sm-2 pt-0">Radios</legend> - <CCol sm={10}> - <CFormCheck - type="radio" - name="gridRadios" - id="gridRadios1" - value="option1" - label="First radio" - defaultChecked - /> - <CFormCheck - type="radio" - name="gridRadios" - id="gridRadios2" - value="option2" - label="Second radio" - /> - <CFormCheck - type="radio" - name="gridRadios" - id="gridRadios3" - value="option3" - label="Third disabled radio" - disabled - /> - </CCol> - </fieldset> - <CRow className="mb-3"> - <div className="col-sm-10 offset-sm-2"> - <CFormCheck type="checkbox" id="gridCheck1" label="Example checkbox" /> - </div> - </CRow> - <CButton type="submit">Sign in</CButton> - </CForm> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Layout</strong> <small>Horizontal form label sizing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Be sure to use <code>.col-form-label-sm</code> or <code>.col-form-label-lg</code> to - your <code><CFormLabel></code>s or <code><legend></code>s to correctly - follow the size of <code>.form-control-lg</code> and <code>.form-control-sm</code>. - </p> - <DocsExample href="forms/layout#horizontal-form-label-sizing"> - <CRow className="mb-3"> - <CFormLabel - htmlFor="colFormLabelSm" - className="col-sm-2 col-form-label col-form-label-sm" - > - Email - </CFormLabel> - <CCol sm={10}> - <CFormInput - type="email" - className="form-control form-control-sm" - id="colFormLabelSm" - placeholder="col-form-label-sm" - /> - </CCol> - </CRow> - <CRow className="mb-3"> - <CFormLabel htmlFor="colFormLabel" className="col-sm-2 col-form-label"> - Email - </CFormLabel> - <CCol sm={10}> - <CFormInput type="email" id="colFormLabel" placeholder="col-form-label" /> - </CCol> - </CRow> - <CRow> - <CFormLabel - htmlFor="colFormLabelLg" - className="col-sm-2 col-form-label col-form-label-lg" - > - Email - </CFormLabel> - <CCol sm={10}> - <CFormInput - type="email" - className="form-control form-control-lg" - id="colFormLabelLg" - placeholder="col-form-label-lg" - /> - </CCol> - </CRow> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Layout</strong> <small>Column sizing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - As shown in the previous examples, our grid system allows you to place any number of{' '} - <code><CCol></code>s within a <code><CRow></code>. They'll split the - available width equally between them. You may also pick a subset of your columns to - take up more or less space, while the remaining <code><CCol></code>s equally - split the rest, with specific column classes like{' '} - <code><CCol sm="7"></code>. - </p> - <DocsExample href="forms/layout#column-sizing"> - <CRow className="g-3"> - <CCol sm={7}> - <CFormInput placeholder="City" aria-label="City" /> - </CCol> - <CCol sm> - <CFormInput placeholder="State" aria-label="State" /> - </CCol> - <CCol sm> - <CFormInput placeholder="Zip" aria-label="Zip" /> - </CCol> - </CRow> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Layout</strong> <small>Auto-sizing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - The example below uses a flexbox utility to vertically center the contents and changes{' '} - <code><CCol></code> to <code><CCol xs="auto"></code> so that your - columns only take up as much space as needed. Put another way, the column sizes itself - based on the contents. - </p> - <DocsExample href="forms/layout#auto-sizing"> - <CForm className="row gy-2 gx-3 align-items-center"> - <CCol xs="auto"> - <CFormLabel className="visually-hidden" htmlFor="autoSizingInput"> - Name - </CFormLabel> - <CFormInput id="autoSizingInput" placeholder="Jane Doe" /> - </CCol> - <CCol xs="auto"> - <CFormLabel className="visually-hidden" htmlFor="autoSizingInputGroup"> - Username - </CFormLabel> - <CInputGroup> - <CInputGroupText>@</CInputGroupText> - <CFormInput id="autoSizingInputGroup" placeholder="Username" /> - </CInputGroup> - </CCol> - <CCol xs="auto"> - <CFormLabel className="visually-hidden" htmlFor="autoSizingSelect"> - Preference - </CFormLabel> - <CFormSelect id="autoSizingSelect"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </CCol> - <CCol xs="auto"> - <CFormCheck type="checkbox" id="autoSizingCheck" label="Remember me" /> - </CCol> - <CCol xs="auto"> - <CButton type="submit">Submit</CButton> - </CCol> - </CForm> - </DocsExample> - <p className="text-medium-emphasis small"> - You can then remix that once again with size-specific column classes. - </p> - <DocsExample href="forms/layout#auto-sizing"> - <CForm className="row gx-3 gy-2 align-items-center"> - <CCol sm={3}> - <CFormLabel className="visually-hidden" htmlFor="specificSizeInputName"> - Name - </CFormLabel> - <CFormInput id="specificSizeInputName" placeholder="Jane Doe" /> - </CCol> - <CCol sm={3}> - <CFormLabel className="visually-hidden" htmlFor="specificSizeInputGroupUsername"> - Username - </CFormLabel> - <CInputGroup> - <CInputGroupText>@</CInputGroupText> - <CFormInput id="specificSizeInputGroupUsername" placeholder="Username" /> - </CInputGroup> - </CCol> - <CCol sm={3}> - <CFormLabel className="visually-hidden" htmlFor="specificSizeSelect"> - Preference - </CFormLabel> - <CFormSelect id="specificSizeSelect"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </CCol> - <CCol xs="auto"> - <CFormCheck type="checkbox" id="autoSizingCheck2" label="Remember me" /> - </CCol> - <CCol xs="auto"> - <CButton type="submit">Submit</CButton> - </CCol> - </CForm> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Layout</strong> <small>Inline forms</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use the <code><CCol xs="auto"></code> class to create horizontal - layouts. By adding{' '} - <a href="https://coreui.io/docs/layout/gutters/">gutter modifier classes</a>, we will - have gutters in horizontal and vertical directions. The{' '} - <code>.align-items-center</code> aligns the form elements to the middle, making the{' '} - <code><CFormCheck></code> align properly. - </p> - <DocsExample href="forms/layout#inline-forms"> - <CForm className="row row-cols-lg-auto g-3 align-items-center"> - <CCol xs={12}> - <CFormLabel className="visually-hidden" htmlFor="inlineFormInputGroupUsername"> - Username - </CFormLabel> - <CInputGroup> - <CInputGroupText>@</CInputGroupText> - <CFormInput id="inlineFormInputGroupUsername" placeholder="Username" /> - </CInputGroup> - </CCol> - <CCol xs={12}> - <CFormLabel className="visually-hidden" htmlFor="inlineFormSelectPref"> - Preference - </CFormLabel> - <CFormSelect id="inlineFormSelectPref"> - <option>Choose...</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </CCol> - <CCol xs={12}> - <CFormCheck type="checkbox" id="inlineFormCheck" label="Remember me" /> - </CCol> - <CCol xs={12}> - <CButton type="submit">Submit</CButton> - </CCol> - </CForm> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Layout diff --git a/src/views/forms/range/Range.js b/src/views/forms/range/Range.js deleted file mode 100644 index 905c3134..00000000 --- a/src/views/forms/range/Range.js +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react' -import { CCard, CCardBody, CCardHeader, CCol, CFormLabel, CFormRange, CRow } from '@coreui/react' -import { DocsExample } from 'src/components' - -const Range = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Range</strong> <small></small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Create custom <code><input type="range"></code> controls with{' '} - <code><CFormRange></code>. - </p> - <DocsExample href="forms/range"> - <CFormLabel htmlFor="customRange1">Example range</CFormLabel> - <CFormRange id="customRange1" /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Range</strong> <small>Disabled</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add the <code>disabled</code> boolean attribute on an input to give it a grayed out - appearance and remove pointer events. - </p> - <DocsExample href="forms/range#disabled"> - <CFormLabel htmlFor="disabledRange">Disabled range</CFormLabel> - <CFormRange id="disabledRange" disabled /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Range</strong> <small>Min and max</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Range inputs have implicit values for <code>min</code> and <code>max</code>— - <code>0</code> and <code>100</code>, respectively. You may specify new values for - those using the <code>min</code> and <code>max</code> attributes. - </p> - <DocsExample href="forms/range#min-and-max"> - <CFormLabel htmlFor="customRange2">Example range</CFormLabel> - <CFormRange min="0" max="5" defaultValue="3" id="customRange2" /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Range</strong> <small>Steps</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - By default, range inputs "snap" to integer values. To change this, you can - specify a <code>step</code> value. In the example below, we double the number of steps - by using <code>step="0.5"</code>. - </p> - <DocsExample href="forms/range#steps"> - <CFormLabel htmlFor="customRange3">Example range</CFormLabel> - <CFormRange min="0" max="5" step="0.5" defaultValue="3" id="customRange3" /> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Range diff --git a/src/views/forms/select/Select.js b/src/views/forms/select/Select.js deleted file mode 100644 index e81f6a56..00000000 --- a/src/views/forms/select/Select.js +++ /dev/null @@ -1,99 +0,0 @@ -import React from 'react' -import { CCard, CCardBody, CCardHeader, CCol, CFormSelect, CRow } from '@coreui/react' -import { DocsExample } from 'src/components' - -const Select = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Select</strong> <small>Default</small> - </CCardHeader> - <CCardBody> - <DocsExample href="forms/select"> - <CFormSelect aria-label="Default select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Select</strong> <small>Sizing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - You may also choose from small and large custom selects to match our similarly sized - text inputs. - </p> - <DocsExample href="forms/select#sizing"> - <CFormSelect size="lg" className="mb-3" aria-label="Large select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - <CFormSelect size="sm" className="mb-3" aria-label="Small select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </DocsExample> - <p className="text-medium-emphasis small"> - The <code>multiple</code> attribute is also supported: - </p> - <DocsExample href="forms/select#sizing"> - <CFormSelect size="lg" multiple aria-label="Multiple select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </DocsExample> - <p className="text-medium-emphasis small"> - As is the <code>htmlSize</code> property: - </p> - <DocsExample href="forms/select#sizing"> - <CFormSelect size="lg" multiple aria-label="Multiple select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Select</strong> <small>Disabled</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add the <code>disabled</code> boolean attribute on a select to give it a grayed out - appearance and remove pointer events. - </p> - <DocsExample href="forms/select#disabled"> - <CFormSelect aria-label="Disabled select example" disabled> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Select diff --git a/src/views/forms/validation/Validation.js b/src/views/forms/validation/Validation.js deleted file mode 100644 index 7053aa3b..00000000 --- a/src/views/forms/validation/Validation.js +++ /dev/null @@ -1,503 +0,0 @@ -import React, { useState } from 'react' -import { - CButton, - CCard, - CCardBody, - CCardHeader, - CCol, - CForm, - CFormCheck, - CFormInput, - CFormFeedback, - CFormLabel, - CFormSelect, - CFormTextarea, - CInputGroup, - CInputGroupText, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const CustomStyles = () => { - const [validated, setValidated] = useState(false) - const handleSubmit = (event) => { - const form = event.currentTarget - if (form.checkValidity() === false) { - event.preventDefault() - event.stopPropagation() - } - setValidated(true) - } - return ( - <CForm - className="row g-3 needs-validation" - noValidate - validated={validated} - onSubmit={handleSubmit} - > - <CCol md={4}> - <CFormLabel htmlFor="validationCustom01">Email</CFormLabel> - <CFormInput type="text" id="validationCustom01" defaultValue="Mark" required /> - <CFormFeedback valid>Looks good!</CFormFeedback> - </CCol> - <CCol md={4}> - <CFormLabel htmlFor="validationCustom02">Email</CFormLabel> - <CFormInput type="text" id="validationCustom02" defaultValue="Otto" required /> - <CFormFeedback valid>Looks good!</CFormFeedback> - </CCol> - <CCol md={4}> - <CFormLabel htmlFor="validationCustomUsername">Username</CFormLabel> - <CInputGroup className="has-validation"> - <CInputGroupText id="inputGroupPrepend">@</CInputGroupText> - <CFormInput - type="text" - id="validationCustomUsername" - defaultValue="" - aria-describedby="inputGroupPrepend" - required - /> - <CFormFeedback invalid>Please choose a username.</CFormFeedback> - </CInputGroup> - </CCol> - <CCol md={6}> - <CFormLabel htmlFor="validationCustom03">City</CFormLabel> - <CFormInput type="text" id="validationCustom03" required /> - <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> - </CCol> - <CCol md={3}> - <CFormLabel htmlFor="validationCustom04">City</CFormLabel> - <CFormSelect id="validationCustom04"> - <option disabled>Choose...</option> - <option>...</option> - </CFormSelect> - <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> - </CCol> - <CCol md={3}> - <CFormLabel htmlFor="validationCustom05">City</CFormLabel> - <CFormInput type="text" id="validationCustom05" required /> - <CFormFeedback invalid>Please provide a valid zip.</CFormFeedback> - </CCol> - <CCol xs={12}> - <CFormCheck - type="checkbox" - id="invalidCheck" - label="Agree to terms and conditions" - required - /> - <CFormFeedback invalid>You must agree before submitting.</CFormFeedback> - </CCol> - <CCol xs={12}> - <CButton color="primary" type="submit"> - Submit form - </CButton> - </CCol> - </CForm> - ) -} - -const BrowserDefaults = () => { - const [validated, setValidated] = useState(false) - const handleSubmit = (event) => { - const form = event.currentTarget - if (form.checkValidity() === false) { - event.preventDefault() - event.stopPropagation() - } - setValidated(true) - } - return ( - <CForm className="row g-3 needs-validation" validated={validated} onSubmit={handleSubmit}> - <CCol md={4}> - <CFormLabel htmlFor="validationDefault01">Email</CFormLabel> - <CFormInput type="text" id="validationDefault01" defaultValue="Mark" required /> - <CFormFeedback valid>Looks good!</CFormFeedback> - </CCol> - <CCol md={4}> - <CFormLabel htmlFor="validationDefault02">Email</CFormLabel> - <CFormInput type="text" id="validationDefault02" defaultValue="Otto" required /> - <CFormFeedback valid>Looks good!</CFormFeedback> - </CCol> - <CCol md={4}> - <CFormLabel htmlFor="validationDefaultUsername">Username</CFormLabel> - <CInputGroup className="has-validation"> - <CInputGroupText id="inputGroupPrepend02">@</CInputGroupText> - <CFormInput - type="text" - id="validationDefaultUsername" - defaultValue="" - aria-describedby="inputGroupPrepend02" - required - /> - <CFormFeedback invalid>Please choose a username.</CFormFeedback> - </CInputGroup> - </CCol> - <CCol md={6}> - <CFormLabel htmlFor="validationDefault03">City</CFormLabel> - <CFormInput type="text" id="validationDefault03" required /> - <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> - </CCol> - <CCol md={3}> - <CFormLabel htmlFor="validationDefault04">City</CFormLabel> - <CFormSelect id="validationDefault04"> - <option disabled>Choose...</option> - <option>...</option> - </CFormSelect> - <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> - </CCol> - <CCol md={3}> - <CFormLabel htmlFor="validationDefault05">City</CFormLabel> - <CFormInput type="text" id="validationDefault05" required /> - <CFormFeedback invalid>Please provide a valid zip.</CFormFeedback> - </CCol> - <CCol xs={12}> - <CFormCheck - type="checkbox" - id="invalidCheck" - label="Agree to terms and conditions" - required - /> - <CFormFeedback invalid>You must agree before submitting.</CFormFeedback> - </CCol> - <CCol xs={12}> - <CButton color="primary" type="submit"> - Submit form - </CButton> - </CCol> - </CForm> - ) -} - -const Tooltips = () => { - const [validated, setValidated] = useState(false) - const handleSubmit = (event) => { - const form = event.currentTarget - if (form.checkValidity() === false) { - event.preventDefault() - event.stopPropagation() - } - setValidated(true) - } - return ( - <CForm - className="row g-3 needs-validation" - noValidate - validated={validated} - onSubmit={handleSubmit} - > - <CCol md={4} className="position-relative"> - <CFormLabel htmlFor="validationTooltip01">Email</CFormLabel> - <CFormInput type="text" id="validationTooltip01" defaultValue="Mark" required /> - <CFormFeedback tooltip valid> - Looks good! - </CFormFeedback> - </CCol> - <CCol md={4} className="position-relative"> - <CFormLabel htmlFor="validationTooltip02">Email</CFormLabel> - <CFormInput type="text" id="validationTooltip02" defaultValue="Otto" required /> - <CFormFeedback tooltip valid> - Looks good! - </CFormFeedback> - </CCol> - <CCol md={4} className="position-relative"> - <CFormLabel htmlFor="validationTooltipUsername">Username</CFormLabel> - <CInputGroup className="has-validation"> - <CInputGroupText id="inputGroupPrepend">@</CInputGroupText> - <CFormInput - type="text" - id="validationTooltipUsername" - defaultValue="" - aria-describedby="inputGroupPrepend" - required - /> - <CFormFeedback tooltip invalid> - Please choose a username. - </CFormFeedback> - </CInputGroup> - </CCol> - <CCol md={6} className="position-relative"> - <CFormLabel htmlFor="validationTooltip03">City</CFormLabel> - <CFormInput type="text" id="validationTooltip03" required /> - <CFormFeedback tooltip invalid> - Please provide a valid city. - </CFormFeedback> - </CCol> - <CCol md={3} className="position-relative"> - <CFormLabel htmlFor="validationTooltip04">City</CFormLabel> - <CFormSelect id="validationTooltip04" required> - <option disabled defaultValue=""> - Choose... - </option> - <option>...</option> - </CFormSelect> - <CFormFeedback tooltip invalid> - Please provide a valid city. - </CFormFeedback> - </CCol> - <CCol md={3} className="position-relative"> - <CFormLabel htmlFor="validationTooltip05">City</CFormLabel> - <CFormInput type="text" id="validationTooltip05" required /> - <CFormFeedback tooltip invalid> - Please provide a valid zip. - </CFormFeedback> - </CCol> - <CCol xs={12} className="position-relative"> - <CButton color="primary" type="submit"> - Submit form - </CButton> - </CCol> - </CForm> - ) -} - -const Validation = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Validation</strong> <small>Custom styles</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - For custom CoreUI form validation messages, you'll need to add the{' '} - <code>noValidate</code> boolean property to your <code><CForm></code>. This - disables the browser default feedback tooltips, but still provides access to the form - validation APIs in JavaScript. Try to submit the form below; our JavaScript will - intercept the submit button and relay feedback to you. When attempting to submit, - you'll see the <code>:invalid</code> and <code>:valid</code> styles applied to - your form controls. - </p> - <p className="text-medium-emphasis small"> - Custom feedback styles apply custom colors, borders, focus styles, and background - icons to better communicate feedback.{' '} - </p> - <DocsExample href="forms/validation">{CustomStyles()}</DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Validation</strong> <small>Browser defaults</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Not interested in custom validation feedback messages or writing JavaScript to change - form behaviors? All good, you can use the browser defaults. Try submitting the form - below. Depending on your browser and OS, you'll see a slightly different style of - feedback. - </p> - <p className="text-medium-emphasis small"> - While these feedback styles cannot be styled with CSS, you can still customize the - feedback text through JavaScript. - </p> - <DocsExample href="forms/validation#browser-defaults">{BrowserDefaults()}</DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Validation</strong> <small>Server side</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - We recommend using client-side validation, but in case you require server-side - validation, you can indicate invalid and valid form fields with <code>invalid</code>{' '} - and <code>valid</code> boolean properties. - </p> - <p className="text-medium-emphasis small"> - For invalid fields, ensure that the invalid feedback/error message is associated with - the relevant form field using <code>aria-describedby</code> (noting that this - attribute allows more than one <code>id</code> to be referenced, in case the field - already points to additional form text). - </p> - <DocsExample href="forms/validation#server-side"> - <CForm className="row g-3 needs-validation"> - <CCol md={4}> - <CFormLabel htmlFor="validationServer01">Email</CFormLabel> - <CFormInput - type="text" - id="validationServer01" - defaultValue="Mark" - valid - required - /> - <CFormFeedback valid>Looks good!</CFormFeedback> - </CCol> - <CCol md={4}> - <CFormLabel htmlFor="validationServer02">Email</CFormLabel> - <CFormInput - type="text" - id="validationServer02" - defaultValue="Otto" - valid - required - /> - <CFormFeedback valid>Looks good!</CFormFeedback> - </CCol> - <CCol md={4}> - <CFormLabel htmlFor="validationServerUsername">Username</CFormLabel> - <CInputGroup className="has-validation"> - <CInputGroupText id="inputGroupPrepend03">@</CInputGroupText> - <CFormInput - type="text" - id="validationServerUsername" - defaultValue="" - aria-describedby="inputGroupPrepend03" - invalid - required - /> - <CFormFeedback invalid>Please choose a username.</CFormFeedback> - </CInputGroup> - </CCol> - <CCol md={6}> - <CFormLabel htmlFor="validationServer03">City</CFormLabel> - <CFormInput type="text" id="validationServer03" invalid required /> - <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> - </CCol> - <CCol md={3}> - <CFormLabel htmlFor="validationServer04">City</CFormLabel> - <CFormSelect id="validationServer04" invalid> - <option disabled>Choose...</option> - <option>...</option> - </CFormSelect> - <CFormFeedback invalid>Please provide a valid city.</CFormFeedback> - </CCol> - <CCol md={3}> - <CFormLabel htmlFor="validationServer05">City</CFormLabel> - <CFormInput type="text" id="validationServer05" invalid required /> - <CFormFeedback invalid>Please provide a valid zip.</CFormFeedback> - </CCol> - <CCol xs={12}> - <CFormCheck - type="checkbox" - id="invalidCheck" - label="Agree to terms and conditions" - invalid - required - /> - <CFormFeedback invalid>You must agree before submitting.</CFormFeedback> - </CCol> - <CCol xs={12}> - <CButton color="primary" type="submit"> - Submit form - </CButton> - </CCol> - </CForm> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Validation</strong> <small>Supported elements</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Validation styles are available for the following form controls and components: - </p> - <ul> - <li> - <code><CFormInput></code>s - </li> - <li> - <code><CFormSelect></code>s - </li> - <li> - <code><CFormCheck></code>s - </li> - </ul> - <DocsExample href="forms/validation#supported-elements"> - <CForm validated={true}> - <div className="mb-3"> - <CFormLabel htmlFor="validationTextarea" className="form-label"> - Textarea - </CFormLabel> - <CFormTextarea - id="validationTextarea" - placeholder="Required example textarea" - invalid - required - ></CFormTextarea> - <CFormFeedback invalid>Please enter a message in the textarea.</CFormFeedback> - </div> - <CFormCheck - className="mb-3" - id="validationFormCheck1" - label="Check this checkbox" - required - /> - <CFormFeedback invalid>Example invalid feedback text</CFormFeedback> - - <CFormCheck - type="radio" - name="radio-stacked" - id="validationFormCheck2" - label="Check this checkbox" - required - /> - - <CFormCheck - className="mb-3" - type="radio" - name="radio-stacked" - id="validationFormCheck3" - label="Or toggle this other radio" - required - /> - <CFormFeedback invalid>More example invalid feedback text</CFormFeedback> - - <div className="mb-3"> - <CFormSelect required aria-label="select example"> - <option>Open this select menu</option> - <option value="1">One</option> - <option value="2">Two</option> - <option value="3">Three</option> - </CFormSelect> - <CFormFeedback invalid>Example invalid select feedback</CFormFeedback> - </div> - - <div className="mb-3"> - <CFormInput - type="file" - id="validationTextarea" - aria-label="file example" - required - /> - <CFormFeedback invalid>Example invalid form file feedback</CFormFeedback> - </div> - - <div className="mb-3"> - <CButton type="submit" color="primary" disabled> - Submit form - </CButton> - </div> - </CForm> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>Validation</strong> <small>Tooltips</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - If your form layout allows it, you can swap the text for the tooltip to display - validation feedback in a styled tooltip. Be sure to have a parent with{' '} - <code>position: relative</code> on it for tooltip positioning. In the example below, - our column classes have this already, but your project may require an alternative - setup. - </p> - <DocsExample href="forms/validation#tooltips">{Tooltips()}</DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Validation diff --git a/src/views/icons/brands/Brands.js b/src/views/icons/brands/Brands.js deleted file mode 100644 index d44e81d8..00000000 --- a/src/views/icons/brands/Brands.js +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' -import { CCard, CCardBody, CCardHeader, CCol, CRow } from '@coreui/react' -import CIcon from '@coreui/icons-react' -import { brandSet } from '@coreui/icons' -import { DocsCallout } from 'src/components' - -const toKebabCase = (str) => { - return str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase() -} - -export const getIconsView = (iconset) => { - return Object.entries(iconset).map(([name, value]) => ( - <CCol className="mb-5" xs={6} sm={4} md={3} xl={2} key={name}> - <CIcon icon={value} size="xxl" /> - <div>{toKebabCase(name)}</div> - </CCol> - )) -} - -const CoreUIIcons = () => { - return ( - <> - <DocsCallout - name="CoreUI Brand Icons" - href="components/chart" - content="CoreUI Brand Icons. CoreUI Icons package is delivered with more than 1500 icons in multiple formats SVG, PNG, and Webfonts. CoreUI Icons are beautifully crafted symbols for common actions and items. You can use them in your digital products for web or mobile app." - /> - <CCard className="mb-4"> - <CCardHeader>Brand Icons</CCardHeader> - <CCardBody> - <CRow className="text-center">{getIconsView(brandSet)}</CRow> - </CCardBody> - </CCard> - </> - ) -} - -export default CoreUIIcons diff --git a/src/views/icons/coreui-icons/CoreUIIcons.js b/src/views/icons/coreui-icons/CoreUIIcons.js deleted file mode 100644 index d0a5969d..00000000 --- a/src/views/icons/coreui-icons/CoreUIIcons.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react' -import { CCard, CCardBody, CCardHeader, CRow } from '@coreui/react' -import { freeSet } from '@coreui/icons' -import { getIconsView } from '../brands/Brands.js' -import { DocsCallout } from 'src/components' - -const CoreUIIcons = () => { - return ( - <> - <DocsCallout - name="CoreUI Icons" - href="components/chart" - content="CoreUI Icons. CoreUI Icons package is delivered with more than 1500 icons in multiple formats SVG, PNG, and Webfonts. CoreUI Icons are beautifully crafted symbols for common actions and items. You can use them in your digital products for web or mobile app." - /> - <CCard className="mb-4"> - <CCardHeader>Free Icons</CCardHeader> - <CCardBody> - <CRow className="text-center">{getIconsView(freeSet)}</CRow> - </CCardBody> - </CCard> - </> - ) -} - -export default CoreUIIcons diff --git a/src/views/icons/flags/Flags.js b/src/views/icons/flags/Flags.js deleted file mode 100644 index a1179dfe..00000000 --- a/src/views/icons/flags/Flags.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react' -import { CCard, CCardBody, CCardHeader, CRow } from '@coreui/react' -import { getIconsView } from '../brands/Brands.js' -import { flagSet } from '@coreui/icons' -import { DocsCallout } from 'src/components' - -const CoreUIIcons = () => { - return ( - <> - <DocsCallout - name="CoreUI Flag Icons" - href="components/chart" - content="CoreUI Flag Icons. CoreUI Icons package is delivered with more than 1500 icons in multiple formats SVG, PNG, and Webfonts. CoreUI Icons are beautifully crafted symbols for common actions and items. You can use them in your digital products for web or mobile app." - /> - <CCard className="mb-4"> - <CCardHeader>Flag Icons</CCardHeader> - <CCardBody> - <CRow className="text-center">{getIconsView(flagSet)}</CRow> - </CCardBody> - </CCard> - </> - ) -} - -export default CoreUIIcons diff --git a/src/views/icons/index.js b/src/views/icons/index.js deleted file mode 100644 index 92db64e5..00000000 --- a/src/views/icons/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import CoreUIIcons from './coreui-icons' -import Flags from './flags' -import Brands from './brands' - -export { CoreUIIcons, Flags, Brands } diff --git a/src/views/notifications/alerts/Alerts.js b/src/views/notifications/alerts/Alerts.js deleted file mode 100644 index 6d0200b7..00000000 --- a/src/views/notifications/alerts/Alerts.js +++ /dev/null @@ -1,147 +0,0 @@ -import React from 'react' -import { - CAlert, - CAlertHeading, - CAlertLink, - CCard, - CCardBody, - CCardHeader, - CCol, - CRow, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const Alerts = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Alert</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - React Alert is prepared for any length of text, as well as an optional close button. - For a styling, use one of the <strong>required</strong> contextual <code>color</code>{' '} - props (e.g., <code>primary</code>). For inline dismissal, use the{' '} - <a href="https://coreui.io/react/docs/4.0/components/alert#dismissing"> - dismissing prop - </a> - . - </p> - <DocsExample href="components/alert"> - <CAlert color="primary">A simple primary alert—check it out!</CAlert> - <CAlert color="secondary">A simple secondary alert—check it out!</CAlert> - <CAlert color="success">A simple success alert—check it out!</CAlert> - <CAlert color="danger">A simple danger alert—check it out!</CAlert> - <CAlert color="warning">A simple warning alert—check it out!</CAlert> - <CAlert color="info">A simple info alert—check it out!</CAlert> - <CAlert color="light">A simple light alert—check it out!</CAlert> - <CAlert color="dark">A simple dark alert—check it out!</CAlert> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Alert</strong> <small>Link color</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Use the <code><CAlertLink></code> component to immediately give matching colored - links inside any alert. - </p> - <DocsExample href="components/alert#link-color"> - <CAlert color="primary"> - A simple primary alert with <CAlertLink href="#">an example link</CAlertLink>. Give - it a click if you like. - </CAlert> - <CAlert color="secondary"> - A simple secondary alert with <CAlertLink href="#">an example link</CAlertLink>. - Give it a click if you like. - </CAlert> - <CAlert color="success"> - A simple success alert with <CAlertLink href="#">an example link</CAlertLink>. Give - it a click if you like. - </CAlert> - <CAlert color="danger"> - A simple danger alert with <CAlertLink href="#">an example link</CAlertLink>. Give - it a click if you like. - </CAlert> - <CAlert color="warning"> - A simple warning alert with <CAlertLink href="#">an example link</CAlertLink>. Give - it a click if you like. - </CAlert> - <CAlert color="info"> - A simple info alert with <CAlertLink href="#">an example link</CAlertLink>. Give it - a click if you like. - </CAlert> - <CAlert color="light"> - A simple light alert with <CAlertLink href="#">an example link</CAlertLink>. Give it - a click if you like. - </CAlert> - <CAlert color="dark"> - A simple dark alert with <CAlertLink href="#">an example link</CAlertLink>. Give it - a click if you like. - </CAlert> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Alert</strong> <small>Additional content</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Alert can also incorporate supplementary components & elements like heading, - paragraph, and divider. - </p> - <DocsExample href="components/alert#additional-content"> - <CAlert color="success"> - <CAlertHeading tag="h4">Well done!</CAlertHeading> - <p> - Aww yeah, you successfully read this important alert message. This example text is - going to run a bit longer so that you can see how spacing within an alert works - with this kind of content. - </p> - <hr /> - <p className="mb-0"> - Whenever you need to, be sure to use margin utilities to keep things nice and - tidy. - </p> - </CAlert> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Alert</strong> <small>Dismissing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Alerts can also be easily dismissed. Just add the <code>dismissible</code> prop. - </p> - <DocsExample href="components/alert#dismissing"> - <CAlert - color="warning" - dismissible - onClose={() => { - alert('👋 Well, hi there! Thanks for dismissing me.') - }} - > - <strong>Go right ahead</strong> and click that dimiss over there on the right. - </CAlert> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Alerts diff --git a/src/views/notifications/badges/Badges.js b/src/views/notifications/badges/Badges.js deleted file mode 100644 index f2c63b58..00000000 --- a/src/views/notifications/badges/Badges.js +++ /dev/null @@ -1,122 +0,0 @@ -import React from 'react' -import { CButton, CCard, CCardBody, CCardHeader, CCol, CBadge, CRow } from '@coreui/react' -import { DocsExample } from 'src/components' - -const Badges = () => { - return ( - <CRow> - <CCol lg={6}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Badges</strong> <small>Dismissing</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Bootstrap badge scale to suit the size of the parent element by using relative font - sizing and <code>em</code> units. - </p> - <DocsExample href="components/badge"> - <h1> - Example heading <CBadge color="secondary">New</CBadge> - </h1> - <h2> - Example heading <CBadge color="secondary">New</CBadge> - </h2> - <h3> - Example heading <CBadge color="secondary">New</CBadge> - </h3> - <h4> - Example heading <CBadge color="secondary">New</CBadge> - </h4> - <h5> - Example heading <CBadge color="secondary">New</CBadge> - </h5> - <h6> - Example heading <CBadge color="secondary">New</CBadge> - </h6> - </DocsExample> - <p className="text-medium-emphasis small"> - Badges can be used as part of links or buttons to provide a counter. - </p> - <DocsExample href="components/badge"> - <CButton color="primary"> - Notifications <CBadge color="secondary">4</CBadge> - </CButton> - </DocsExample> - <p className="text-medium-emphasis small"> - Remark that depending on how you use them, badges may be complicated for users of - screen readers and related assistive technologies. - </p> - <p className="text-medium-emphasis small"> - Unless the context is clear, consider including additional context with a visually - hidden piece of additional text. - </p> - <DocsExample href="components/badge"> - <CButton color="primary"> - Profile <CBadge color="secondary">9</CBadge> - <span className="visually-hidden">unread messages</span> - </CButton> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol lg={6}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Badges</strong> <small>Contextual variations</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add any of the below-mentioned <code>color</code> props to modify the presentation of - a badge. - </p> - <DocsExample href="components/badge#contextual-variations"> - <CBadge color="primary">primary</CBadge> - <CBadge color="success">success</CBadge> - <CBadge color="danger">danger</CBadge> - <CBadge color="warning">warning</CBadge> - <CBadge color="info">info</CBadge> - <CBadge color="light">light</CBadge> - <CBadge color="dark">dark</CBadge> - </DocsExample> - </CCardBody> - </CCard> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Badges</strong> <small>Pill badges</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Apply the <code>shape="rounded-pill"</code> prop to make badges rounded. - </p> - <DocsExample href="components/badge#pill-badges"> - <CBadge color="primary" shape="rounded-pill"> - primary - </CBadge> - <CBadge color="success" shape="rounded-pill"> - success - </CBadge> - <CBadge color="danger" shape="rounded-pill"> - danger - </CBadge> - <CBadge color="warning" shape="rounded-pill"> - warning - </CBadge> - <CBadge color="info" shape="rounded-pill"> - info - </CBadge> - <CBadge color="light" shape="rounded-pill"> - light - </CBadge> - <CBadge color="dark" shape="rounded-pill"> - dark - </CBadge> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Badges diff --git a/src/views/notifications/index.js b/src/views/notifications/index.js deleted file mode 100644 index 08e31cd7..00000000 --- a/src/views/notifications/index.js +++ /dev/null @@ -1,6 +0,0 @@ -import Alerts from './Alerts' -import Badges from './Badges' -import Modals from './Modals' -import Toaster from './toasts' - -export { Alerts, Badges, Modals, Toaster } diff --git a/src/views/notifications/modals/Modals.js b/src/views/notifications/modals/Modals.js deleted file mode 100644 index fcd31116..00000000 --- a/src/views/notifications/modals/Modals.js +++ /dev/null @@ -1,720 +0,0 @@ -import React, { useState } from 'react' -import { - CButton, - CCard, - CCardBody, - CCardHeader, - CCol, - CLink, - CModal, - CModalBody, - CModalFooter, - CModalHeader, - CModalTitle, - CPopover, - CRow, - CTooltip, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const LiveDemo = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal visible={visible} onClose={() => setVisible(false)}> - <CModalHeader> - <CModalTitle>Modal title</CModalTitle> - </CModalHeader> - <CModalBody>Woohoo, you're reading this text in a modal!</CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -const StaticBackdrop = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton onClick={() => setVisible(!visible)}>Launch static backdrop modal</CButton> - <CModal backdrop="static" visible={visible} onClose={() => setVisible(false)}> - <CModalHeader> - <CModalTitle>Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - I will not close if you click outside me. Don'teven try to press escape key. - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -const ScrollingLongContent = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal visible={visible} onClose={() => setVisible(false)}> - <CModalHeader> - <CModalTitle>Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -const ScrollingLongContent2 = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal scrollable visible={visible} onClose={() => setVisible(false)}> - <CModalHeader> - <CModalTitle>Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -const VerticallyCentered = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton onClick={() => setVisible(!visible)}>Vertically centered modal</CButton> - <CModal alignment="center" visible={visible} onClose={() => setVisible(false)}> - <CModalHeader> - <CModalTitle>Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -const VerticallyCentered2 = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton onClick={() => setVisible(!visible)}>Vertically centered scrollable modal</CButton> - <CModal alignment="center" scrollable visible={visible} onClose={() => setVisible(false)}> - <CModalHeader> - <CModalTitle>Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - <p> - Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel - scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus - auctor fringilla. - </p> - <p> - Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis - in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. - </p> - <p> - Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis - lacus vel augue laoreet rutrum faucibus dolor auctor. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -const TooltipsPopovers = () => { - const [visible, setVisible] = useState(false) - return ( - <> - <CButton onClick={() => setVisible(!visible)}>Launch demo modal</CButton> - <CModal alignment="center" visible={visible} onClose={() => setVisible(false)}> - <CModalHeader> - <CModalTitle>Modal title</CModalTitle> - </CModalHeader> - <CModalBody> - <h5>Popover in a modal</h5> - <p> - This - <CPopover title="Popover title" content="Popover body content is set in this property."> - <CButton>button</CButton> - </CPopover>{' '} - triggers a popover on click. - </p> - <hr /> - <h5>Tooltips in a modal</h5> - <p> - <CTooltip content="Tooltip"> - <CLink>This link</CLink> - </CTooltip>{' '} - and - <CTooltip content="Tooltip"> - <CLink>that link</CLink> - </CTooltip>{' '} - have tooltips on hover. - </p> - </CModalBody> - <CModalFooter> - <CButton color="secondary" onClick={() => setVisible(false)}> - Close - </CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </> - ) -} - -const OptionalSizes = () => { - const [visibleXL, setVisibleXL] = useState(false) - const [visibleLg, setVisibleLg] = useState(false) - const [visibleSm, setVisibleSm] = useState(false) - return ( - <> - <CButton onClick={() => setVisibleXL(!visibleXL)}>Extra large modal</CButton> - <CButton onClick={() => setVisibleLg(!visibleLg)}>Large modal</CButton> - <CButton onClick={() => setVisibleSm(!visibleSm)}>Small large modal</CButton> - <CModal size="xl" visible={visibleXL} onClose={() => setVisibleXL(false)}> - <CModalHeader> - <CModalTitle>Extra large modal</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal size="lg" visible={visibleLg} onClose={() => setVisibleLg(false)}> - <CModalHeader> - <CModalTitle>Large modal</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal size="sm" visible={visibleSm} onClose={() => setVisibleSm(false)}> - <CModalHeader> - <CModalTitle>Small modal</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - </> - ) -} - -const FullscreenModal = () => { - const [visible, setVisible] = useState(false) - const [visibleSm, setVisibleSm] = useState(false) - const [visibleMd, setVisibleMd] = useState(false) - const [visibleLg, setVisibleLg] = useState(false) - const [visibleXL, setVisibleXL] = useState(false) - const [visibleXXL, setVisibleXXL] = useState(false) - - return ( - <> - <CButton onClick={() => setVisible(!visible)}>Full screen</CButton> - <CButton onClick={() => setVisibleSm(!visibleSm)}>Full screen below sm</CButton> - <CButton onClick={() => setVisibleMd(!visibleMd)}>Full screen below md</CButton> - <CButton onClick={() => setVisibleLg(!visibleLg)}>Full screen below lg</CButton> - <CButton onClick={() => setVisibleXL(!visibleXL)}>Full screen below xl</CButton> - <CButton onClick={() => setVisibleXXL(!visibleXXL)}>Full screen below xxl</CButton> - <CModal fullscreen visible={visible} onClose={() => setVisible(false)}> - <CModalHeader> - <CModalTitle>Full screen</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal fullscreen="sm" visible={visibleSm} onClose={() => setVisibleSm(false)}> - <CModalHeader> - <CModalTitle>Full screen below sm</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal fullscreen="md" visible={visibleMd} onClose={() => setVisibleMd(false)}> - <CModalHeader> - <CModalTitle>Full screen below md</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal fullscreen="lg" visible={visibleLg} onClose={() => setVisibleLg(false)}> - <CModalHeader> - <CModalTitle>Full screen below lg</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal fullscreen="xl" visible={visibleXL} onClose={() => setVisibleXL(false)}> - <CModalHeader> - <CModalTitle>Full screen below xl</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - <CModal fullscreen="xxl" visible={visibleXXL} onClose={() => setVisibleXXL(false)}> - <CModalHeader> - <CModalTitle>Full screen below xxl</CModalTitle> - </CModalHeader> - <CModalBody>...</CModalBody> - </CModal> - </> - ) -} - -const Modals = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Modal</strong> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Below is a static modal example (meaning its <code>position</code> and{' '} - <code>display</code> have been overridden). Included are the modal header, modal body - (required for <code>padding</code>), and modal footer (optional). We ask that you - include modal headers with dismiss actions whenever possible, or provide another - explicit dismiss action. - </p> - <DocsExample href="components/modal"> - <CModal - className="show d-block position-static" - backdrop={false} - keyboard={false} - portal={false} - visible - > - <CModalHeader> - <CModalTitle>Modal title</CModalTitle> - </CModalHeader> - <CModalBody>Modal body text goes here.</CModalBody> - <CModalFooter> - <CButton color="secondary">Close</CButton> - <CButton color="primary">Save changes</CButton> - </CModalFooter> - </CModal> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Modal</strong> <small>Live demo</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Toggle a working modal demo by clicking the button below. It will slide down and fade - in from the top of the page. - </p> - <DocsExample href="components/modal#live-demo">{LiveDemo()}</DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Modal</strong> <small>Static backdrop</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - If you don’t provide an <code>onDimsiss</code> handler to the Modal component, your - modal will behave as though the backdrop is static, meaning it will not close when - clicking outside it. Click the button below to try it. - </p> - <DocsExample href="components/modal#static-backdrop">{StaticBackdrop()}</DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Modal</strong> <small>Scrolling long content</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - If you don’t provide an <code>onDimsiss</code> handler to the Modal component, your - modal will behave as though the backdrop is static, meaning it will not close when - clicking outside it. Click the button below to try it. - </p> - <DocsExample href="components/modal#scrolling-long-content"> - {ScrollingLongContent()} - </DocsExample> - <p className="text-medium-emphasis small"> - You can also create a scrollable modal that allows scroll the modal body by adding{' '} - <code>scrollable</code> prop. - </p> - <DocsExample href="components/modal#scrolling-long-content"> - {ScrollingLongContent2()} - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Modal</strong> <small>Vertically centered</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Add <code>alignment="center"</code> to <code><CModal></code> to - vertically center the modal. - </p> - <DocsExample href="components/modal#vertically-centered"> - {VerticallyCentered()} - </DocsExample> - <DocsExample href="components/modal#vertically-centered"> - {VerticallyCentered2()} - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Modal</strong> <small>Tooltips and popovers</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - <code><CTooltips></code> and <code><CPopovers></code> can be placed within - modals as needed. When modals are closed, any tooltips and popovers within are also - automatically dismissed. - </p> - <DocsExample href="components/modal#tooltips-and-popovers"> - {TooltipsPopovers()} - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Modal</strong> <small>Optional sizes</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Modals have three optional sizes, available via modifier classes to be placed on a{' '} - <code><CModal></code>. These sizes kick in at certain breakpoints to avoid - horizontal scrollbars on narrower viewports. - </p> - <table className="table"> - <thead> - <tr> - <th>Size</th> - <th>Property size</th> - <th>Modal max-width</th> - </tr> - </thead> - <tbody> - <tr> - <td>Small</td> - <td> - <code>'sm'</code> - </td> - <td> - <code>300px</code> - </td> - </tr> - <tr> - <td>Default</td> - <td className="text-medium-emphasis">None</td> - <td> - <code>500px</code> - </td> - </tr> - <tr> - <td>Large</td> - <td> - <code>'lg'</code> - </td> - <td> - <code>800px</code> - </td> - </tr> - <tr> - <td>Extra large</td> - <td> - <code>'xl'</code> - </td> - <td> - <code>1140px</code> - </td> - </tr> - </tbody> - </table> - <DocsExample href="components/modal#optional-sizes">{OptionalSizes()}</DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Modal</strong> <small>Fullscreen Modal</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Another override is the option to pop up a modal that covers the user viewport, - available via property <code>fullscrean</code>. - </p> - <table className="table"> - <thead> - <tr> - <th>Property fullscrean</th> - <th>Availability</th> - </tr> - </thead> - <tbody> - <tr> - <td> - <code>true</code> - </td> - <td>Always</td> - </tr> - <tr> - <td> - <code>'sm'</code> - </td> - <td> - Below <code>576px</code> - </td> - </tr> - <tr> - <td> - <code>'md'</code> - </td> - <td> - Below <code>768px</code> - </td> - </tr> - <tr> - <td> - <code>'lg'</code> - </td> - <td> - Below <code>992px</code> - </td> - </tr> - <tr> - <td> - <code>'xl'</code> - </td> - <td> - Below <code>1200px</code> - </td> - </tr> - <tr> - <td> - <code>'xxl'</code> - </td> - <td> - Below <code>1400px</code> - </td> - </tr> - </tbody> - </table> - <DocsExample href="components/modal#fullscreen-modal">{FullscreenModal()}</DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Modals diff --git a/src/views/notifications/toasts/Toasts.js b/src/views/notifications/toasts/Toasts.js deleted file mode 100644 index 09422abb..00000000 --- a/src/views/notifications/toasts/Toasts.js +++ /dev/null @@ -1,252 +0,0 @@ -import React, { useRef, useState } from 'react' -import { - CCard, - CCardHeader, - CCardBody, - CButton, - CRow, - CCol, - CToast, - CToastBody, - CToastClose, - CToastHeader, - CToaster, -} from '@coreui/react' -import { DocsExample } from 'src/components' - -const ExampleToast = () => { - const [toast, addToast] = useState(0) - const toaster = useRef() - const exampleToast = ( - <CToast title="CoreUI for React.js"> - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <strong className="me-auto">CoreUI for React.js</strong> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - </CToast> - ) - return ( - <> - <CButton onClick={() => addToast(exampleToast)}>Send a toast</CButton> - <CToaster ref={toaster} push={toast} placement="top-end" /> - </> - ) -} - -const Toasts = () => { - return ( - <CRow> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Toast</strong> <small>Basic</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Toasts are as flexible as you need and have very little required markup. At a minimum, - we require a single element to contain your “toasted” content and strongly encourage a - dismiss button. - </p> - <DocsExample href="components/toast"> - <CToast title="CoreUI for React.js" autohide={false} visible={true}> - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <strong className="me-auto">CoreUI for React.js</strong> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - </CToast> - </DocsExample> - <DocsExample href="components/toast">{ExampleToast()}</DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Toast</strong> <small>Translucent</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Toasts are slightly translucent to blend in with what's below them. - </p> - <DocsExample href="components/toast#translucent"> - <div className="bg-dark p-3"> - <CToast title="CoreUI for React.js" autohide={false} visible={true}> - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <strong className="me-auto">CoreUI for React.js</strong> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - </CToast> - </div> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Toast</strong> <small>Stacking</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - You can stack toasts by wrapping them in a toast container, which will vertically add - some spacing. - </p> - <DocsExample href="components/toast#stacking"> - <CToaster> - <CToast title="CoreUI for React.js" autohide={false} visible={true}> - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <strong className="me-auto">CoreUI for React.js</strong> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - </CToast> - <CToast title="CoreUI for React.js" autohide={false} visible={true}> - <CToastHeader closeButton> - <svg - className="rounded me-2" - width="20" - height="20" - xmlns="http://www.w3.org/2000/svg" - preserveAspectRatio="xMidYMid slice" - focusable="false" - role="img" - > - <rect width="100%" height="100%" fill="#007aff"></rect> - </svg> - <strong className="me-auto">CoreUI for React.js</strong> - <small>7 min ago</small> - </CToastHeader> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - </CToast> - </CToaster> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Toast</strong> <small>Custom content</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Customize your toasts by removing sub-components, tweaking them with{' '} - <a href="https://coreui.io/docs/4.0/utilities/api">utilities</a>, or by adding your - own markup. Here we've created a simpler toast by removing the default{' '} - <code><CToastHeader></code>, adding a custom hide icon from{' '} - <a href="https://icons.coreui.io">CoreUI Icons</a>, and using some{' '} - <a href="https://coreui.io/docs/4.0/utilities/flex">flexbox utilities</a> to adjust - the layout. - </p> - <DocsExample href="components/toast#custom-content"> - <CToast autohide={false} className="align-items-center" visible={true}> - <div className="d-flex"> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - <CToastClose className="me-2 m-auto" /> - </div> - </CToast> - </DocsExample> - <p className="text-medium-emphasis small"> - Alternatively, you can also add additional controls and components to toasts. - </p> - <DocsExample href="components/toast#custom-content"> - <CToast autohide={false} visible={true}> - <CToastBody> - Hello, world! This is a toast message. - <div className="mt-2 pt-2 border-top"> - <CButton type="button" color="primary" size="sm"> - Take action - </CButton> - <CToastClose component={CButton} color="secondary" size="sm" className="ms-1"> - Close - </CToastClose> - </div> - </CToastBody> - </CToast> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - <CCol xs={12}> - <CCard className="mb-4"> - <CCardHeader> - <strong>React Toast</strong> <small>Custom content</small> - </CCardHeader> - <CCardBody> - <p className="text-medium-emphasis small"> - Building on the above example, you can create different toast color schemes with our{' '} - <a href="https://coreui.io/docs/4.0/utilities/colors">color</a> and{' '} - <a href="https://coreui.io/docs/4.0//utilities/background">background</a> utilities. - Here we've set <code>color="primary"</code> and added{' '} - <code>.text-white</code> class to the <code><Ctoast></code>, and then set{' '} - <code>white</code> property to our close button. For a crisp edge, we remove the - default border with <code>.border-0</code>. - </p> - <DocsExample href="components/toast#color-schemes"> - <CToast - autohide={false} - color="primary" - className="text-white align-items-center" - visible={true} - > - <div className="d-flex"> - <CToastBody>Hello, world! This is a toast message.</CToastBody> - <CToastClose className="me-2 m-auto" white /> - </div> - </CToast> - </DocsExample> - </CCardBody> - </CCard> - </CCol> - </CRow> - ) -} - -export default Toasts diff --git a/src/views/runtime-upgrade/RuntimeUpgrade.js b/src/views/runtime-upgrade/RuntimeUpgrade.js new file mode 100644 index 00000000..f463c14b --- /dev/null +++ b/src/views/runtime-upgrade/RuntimeUpgrade.js @@ -0,0 +1,12 @@ +import React from 'react' + +const RuntimeUpgrade = () => { + + return ( + <h1> + THIS IS RUNTIME UPGRADE BABY + </h1> + ) +} + +export default RuntimeUpgrade From e86a4daf457c11f61218e9d75c59590886615775 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Sat, 2 Dec 2023 19:40:23 +0100 Subject: [PATCH 05/44] Adding initials of LocalStorage management --- src/App.js | 3 ++ src/contexts/LocalStorageContext.js | 48 +++++++++++++++++++ .../ConfiguratorCollators.js | 27 +++++++++-- .../ConfiguratorCoretime.js | 10 ++++ 4 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/contexts/LocalStorageContext.js diff --git a/src/App.js b/src/App.js index 83cbd0ce..4be91416 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,6 @@ import React, { Component, Suspense } from 'react' import { BrowserRouter, Route, Routes } from 'react-router-dom' +import { LocalStorageContextProvider } from './contexts/LocalStorageContext' import './scss/style.scss' const loading = ( @@ -21,6 +22,7 @@ class App extends Component { render() { return ( <BrowserRouter> + <LocalStorageContextProvider> <Suspense fallback={loading}> <Routes> <Route exact path="/login" name="Login Page" element={<Login />} /> @@ -30,6 +32,7 @@ class App extends Component { <Route path="*" name="Home" element={<DefaultLayout />} /> </Routes> </Suspense> + </LocalStorageContextProvider> </BrowserRouter> ) } diff --git a/src/contexts/LocalStorageContext.js b/src/contexts/LocalStorageContext.js new file mode 100644 index 00000000..d8b5753c --- /dev/null +++ b/src/contexts/LocalStorageContext.js @@ -0,0 +1,48 @@ +import React, { createContext, useContext, useState, useEffect } from 'react'; + +// Helper functions to manage localStorage +const getLocalStorageItem = (key, initialValue) => { + const storedValue = localStorage.getItem(key); + return storedValue ? JSON.parse(storedValue) : initialValue; +}; + +const setLocalStorageItem = (key, value) => { + localStorage.setItem(key, JSON.stringify(value)); +}; + +// Create the context +const LocalStorageContext = createContext(); + +// Define the context provider component +export const LocalStorageContextProvider = ({ children }) => { + const [collators, setCollators] = useState(() => getLocalStorageItem('collators', [])); + const [coretime, setCoretime] = useState(() => getLocalStorageItem('coretime', {})); + + // Update localStorage when collators or coretime changes + useEffect(() => { + setLocalStorageItem('collators', collators); + }, [collators]); + + useEffect(() => { + setLocalStorageItem('coretime', coretime); + }, [coretime]); + + // Context value + const contextValue = { + collators, + setCollators, + coretime, + setCoretime + }; + + return ( + <LocalStorageContext.Provider value={contextValue}> + {children} + </LocalStorageContext.Provider> + ); +}; + +// Custom hook to use the context +export function useLocalStorageContext() { + return useContext(LocalStorageContext); +} diff --git a/src/views/configurator-collators/ConfiguratorCollators.js b/src/views/configurator-collators/ConfiguratorCollators.js index 9a6f99eb..59b7620f 100644 --- a/src/views/configurator-collators/ConfiguratorCollators.js +++ b/src/views/configurator-collators/ConfiguratorCollators.js @@ -1,10 +1,31 @@ import React from 'react' +import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' const ConfiguratorCollators = () => { + const { collators, setCollators } = useLocalStorageContext(); + + // Example function to update collators + const addCollator = (newCollator) => { + setCollators([...collators, newCollator]); + }; + + return ( - <h1>Configure Collators</h1> - ) -} + <div> + <h1>Configure Collators</h1> + <ul> + {collators.map((collator, index) => { + // If collator is an object, make sure to render a property of the object + return <li key={index}>{collator.time || collator}</li>; // Adjust based on the structure of collator + })} + </ul> + <button onClick={() => addCollator({ ...collators, time: new Date().toISOString() })}> + Add Collator + </button> + </div> + ); +}; export default ConfiguratorCollators + diff --git a/src/views/configurator-coretime/ConfiguratorCoretime.js b/src/views/configurator-coretime/ConfiguratorCoretime.js index 62f39313..6b47ade3 100644 --- a/src/views/configurator-coretime/ConfiguratorCoretime.js +++ b/src/views/configurator-coretime/ConfiguratorCoretime.js @@ -1,9 +1,19 @@ import React from 'react' +import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' const ConfiguratorCoretime = () => { + const { collators } = useLocalStorageContext(); return ( + <> <h1>Configure Coretime</h1> + <ul> + {collators.map((collator, index) => { + // If collator is an object, make sure to render a property of the object + return <li key={index}>{collator.time || collator}</li>; // Adjust based on the structure of collator + })} + </ul> + </> ) } From a914557a7c7f8e80958d1883d8fbf6e38bcd0578 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sat, 2 Dec 2023 19:50:32 +0100 Subject: [PATCH 06/44] no deploy view + font --- src/components/AppSidebar.js | 2 +- src/index.css | 6 ++++++ src/index.js | 1 + src/routes.js | 2 +- src/views/empty/Empty.js | 15 +++++++++++---- 5 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 src/index.css diff --git a/src/components/AppSidebar.js b/src/components/AppSidebar.js index eccd90f1..cb70bb55 100644 --- a/src/components/AppSidebar.js +++ b/src/components/AppSidebar.js @@ -33,7 +33,7 @@ const AppSidebar = () => { <CSidebarBrand className="d-none d-md-flex" to="/"> <div className="clearfix" style={{"margin":"2rem"}}> <CImage rounded align="center" src={porticoSVG} width={150} height={150} /> - <h3 style={{'text-align':'center', 'margin':'0'}}>PORTICO</h3> + <h3 style={{'textAlign':'center', 'margin':'0'}}>PORTICO</h3> </div> </CSidebarBrand> <CSidebarNav> diff --git a/src/index.css b/src/index.css new file mode 100644 index 00000000..8bcf5701 --- /dev/null +++ b/src/index.css @@ -0,0 +1,6 @@ +@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400&display=swap'); + +body { + font-family: 'Roboto', sans-serif; + font-weight: 100; +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index d19a3bcd..54f6df2a 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import App from './App' import reportWebVitals from './reportWebVitals' import { Provider } from 'react-redux' import store from './store' +import './index.css' createRoot(document.getElementById('root')).render( <Provider store={store}> diff --git a/src/routes.js b/src/routes.js index 6972facd..f94a5e82 100644 --- a/src/routes.js +++ b/src/routes.js @@ -15,7 +15,7 @@ const ConfiguratorCoretime = React.lazy(() => import('./views/configurator-coret const routes = [ - { path: '/', exact: true, name: 'Welcome' , element: Empty}, + { path: '/', exact: true, name: 'Start Building' , element: Empty}, { path: '/dashboard', name: 'Dashboard', element: Dashboard }, { path: '/theme', name: 'Theme', element: Colors, exact: true }, { path: '/theme/colors', name: 'Colors', element: Colors }, diff --git a/src/views/empty/Empty.js b/src/views/empty/Empty.js index 75cdf479..7befbabc 100644 --- a/src/views/empty/Empty.js +++ b/src/views/empty/Empty.js @@ -1,12 +1,19 @@ import React from 'react' +import { CContainer, CCol, CRow, CButton } from '@coreui/react' const Empty = () => { return ( - <h1> - There's no deployment available. - Let's get started! - </h1> + <CContainer fluid> + <CRow className="align-items-center"> + <CCol> + <h1 style={{"textAlign":"center", "marginTop": "4rem", "marginBottom": "4rem", "fontWeight":"300"}}>No active deployment</h1> + </CCol> + </CRow> + <CRow className="align-items-center"> + <CButton className="col-3 mx-auto" color="success" size="lg" variant="outline">Start Building</CButton> + </CRow> + </CContainer> ) } From 43d1278a72866cefc5174a699a01cbe429c785f1 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sat, 2 Dec 2023 23:57:13 +0100 Subject: [PATCH 07/44] config view + runtime select + some UI changes --- src/assets/runtimes/runtime.json | 22 +++++ src/components/AppBreadcrumb.js | 12 ++- src/components/AppSidebar.js | 2 +- src/contexts/LocalStorageContext.js | 9 ++- .../ConfiguratorRuntime.js | 41 +++++++++- src/views/configurator/Configurator.js | 81 ++++++++++++++++++- src/views/empty/Empty.js | 10 ++- 7 files changed, 167 insertions(+), 10 deletions(-) create mode 100644 src/assets/runtimes/runtime.json diff --git a/src/assets/runtimes/runtime.json b/src/assets/runtimes/runtime.json new file mode 100644 index 00000000..9b5af376 --- /dev/null +++ b/src/assets/runtimes/runtime.json @@ -0,0 +1,22 @@ +[ + { + "name":"Extended Parachain Template", + "developer":"Parity Technologies", + "tags":["Assets", "XCM", "Governance", "SUDO"], + "shortDescription":"The Extended Parachain Template is a ready-to-use parachain template, pre-configured with the Assets pallet, a simple Governance system (Collective & Motion pallets), and other useful base features.", + "longDescription":"The Extended Parachain Tempalte has been developed by Parity Technologies to allow users to quickly develop a parachain. It has simple yet powerful features like the Assets Pallet which gives the parachain the ability to manage different assets. It also has a simple Governance system that contains of Motions and Collectives, allowing for parachain builders to experience first hand how to manage on-chain Governance. It also has SUDO functionality enabled for first-time parachain developers, as well as an intial XCM Configuration for cross-chain messaging.", + "github":"https://github.com/paritytech/extended-parachain-template", + "img":"https://media.licdn.com/dms/image/C4E0BAQEQCf-N1FDWLw/company-logo_200_200/0/1631365010727/paritytech_logo?e=2147483647&v=beta&t=RT4zbwHB40-kFmiak5cR_9TL6m-MHyMlcgLlrmCdhhE", + "id":1 + }, + { + "name":"EVM Parachain Template", + "developer":"Parity Technologies", + "tags":["EVM", "XCM", "Governance", "SUDO"], + "shortDescription":"The Frontier Parachain Template is a ready-to-use EVM-based parachain (based on the Frontier project), pre-configured with the Assets pallet, a simple Governance system (Collective & Motion pallets), and EVM precompiles.", + "longDescription":" Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam sit amet urna a augue sagittis posuere. Aenean feugiat venenatis nunc, at blandit velit. Sed eu ornare est. Duis vitae nisl imperdiet, euismod ipsum non, ultricies libero. Pellentesque consequat eu tellus eu laoreet. Vivamus eu velit id sapien malesuada semper. Ut at accumsan diam. Sed fermentum turpis sed velit eleifend, at tincidunt quam elementum. Integer commodo, dui id consequat tristique, nulla nulla luctus ipsum, ut pulvinar ex magna sed tellus. Etiam pellentesque nisl non quam eleifend, sed commodo est lobortis. Proin efficitur est eget ex interdum, at sodales nulla accumsan.", + "github":"https://github.com/paritytech/frontier-parachain-template", + "id":2, + "img":"https://media.licdn.com/dms/image/C4E0BAQEQCf-N1FDWLw/company-logo_200_200/0/1631365010727/paritytech_logo?e=2147483647&v=beta&t=RT4zbwHB40-kFmiak5cR_9TL6m-MHyMlcgLlrmCdhhE" + } +] \ No newline at end of file diff --git a/src/components/AppBreadcrumb.js b/src/components/AppBreadcrumb.js index 35be72c3..8340f2ad 100644 --- a/src/components/AppBreadcrumb.js +++ b/src/components/AppBreadcrumb.js @@ -1,5 +1,5 @@ import React from 'react' -import { useLocation } from 'react-router-dom' +import { useLocation, Link } from 'react-router-dom' import routes from '../routes' @@ -33,14 +33,18 @@ const AppBreadcrumb = () => { return ( <CBreadcrumb className="m-0 ms-2"> - <CBreadcrumbItem href="/">Home</CBreadcrumbItem> + <CBreadcrumbItem><Link to="/">Home</Link></CBreadcrumbItem> {breadcrumbs.map((breadcrumb, index) => { + console.log(index, breadcrumb) return ( <CBreadcrumbItem - {...(breadcrumb.active ? { active: true } : { href: breadcrumb.pathname })} + {...(breadcrumb.active ? { active: true } : "")} key={index} > - {breadcrumb.name} + { breadcrumb.active ? + breadcrumb.name : + <Link to={`${breadcrumb.pathname}`}> {breadcrumb.name} </Link> + } </CBreadcrumbItem> ) })} diff --git a/src/components/AppSidebar.js b/src/components/AppSidebar.js index cb70bb55..e3998445 100644 --- a/src/components/AppSidebar.js +++ b/src/components/AppSidebar.js @@ -33,7 +33,7 @@ const AppSidebar = () => { <CSidebarBrand className="d-none d-md-flex" to="/"> <div className="clearfix" style={{"margin":"2rem"}}> <CImage rounded align="center" src={porticoSVG} width={150} height={150} /> - <h3 style={{'textAlign':'center', 'margin':'0'}}>PORTICO</h3> + <h3 style={{'textAlign':'center', 'margin':'0', 'fontWeight':'200'}}>PORTICO</h3> </div> </CSidebarBrand> <CSidebarNav> diff --git a/src/contexts/LocalStorageContext.js b/src/contexts/LocalStorageContext.js index d8b5753c..8a1ff31a 100644 --- a/src/contexts/LocalStorageContext.js +++ b/src/contexts/LocalStorageContext.js @@ -17,6 +17,7 @@ const LocalStorageContext = createContext(); export const LocalStorageContextProvider = ({ children }) => { const [collators, setCollators] = useState(() => getLocalStorageItem('collators', [])); const [coretime, setCoretime] = useState(() => getLocalStorageItem('coretime', {})); + const [runtime, setRuntime] = useState(() => getLocalStorageItem('runtime', {})); // Update localStorage when collators or coretime changes useEffect(() => { @@ -26,13 +27,19 @@ export const LocalStorageContextProvider = ({ children }) => { useEffect(() => { setLocalStorageItem('coretime', coretime); }, [coretime]); + + useEffect(() => { + setLocalStorageItem('runtime', runtime); + }, [runtime]); // Context value const contextValue = { collators, setCollators, coretime, - setCoretime + setCoretime, + runtime, + setRuntime }; return ( diff --git a/src/views/configurator-runtime/ConfiguratorRuntime.js b/src/views/configurator-runtime/ConfiguratorRuntime.js index 123250a8..5cbea67f 100644 --- a/src/views/configurator-runtime/ConfiguratorRuntime.js +++ b/src/views/configurator-runtime/ConfiguratorRuntime.js @@ -1,9 +1,48 @@ import React from 'react' +import runtimes from 'src/assets/runtimes/runtime.json' +import {Link} from 'react-router-dom' +import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' + + +import { CButton, CCard, CCardImage, CCardBody, CCardFooter, CCardTitle, CCardText, CAccordion, CAccordionHeader, CAccordionItem, CAccordionBody, CRow, CCol, CAvatar, CBadge} from '@coreui/react' +import CIcon from '@coreui/icons-react' +import {cibGithub} from '@coreui/icons' const ConfiguratorRuntime = () => { + const { runtime, setRuntime } = useLocalStorageContext(); + + + const handleClick = (runtimeInfo) => { + setRuntime(runtimeInfo) + } + console.log('runtime', runtime) + // console.log(runtimes) + return ( - <h1>Configure Runtime</h1> + <CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 4 }}> + {runtimes.map(runtimeInfo => { + return ( + <CCol key={runtimeInfo.id} xs> + <CCard className={runtimeInfo.id === runtime.id ? 'border-success h-100' : 'h-100'}> + <CCardImage orientation="top" src={runtimeInfo.img} /> + <CCardBody> + <CCardTitle>{runtimeInfo.name}</CCardTitle> + <CCardText> + {runtimeInfo.shortDescription} + </CCardText> + <CButton onClick={() => handleClick(runtimeInfo)}>Select</CButton> + </CCardBody> + <CCardFooter> + <Link target="_blank" to={`${runtimeInfo.github}`}> + <CIcon size="lg" className="text-secondary" icon={cibGithub}/> + </Link> + </CCardFooter> + </CCard> + </CCol> + ) + })} + </CRow> ) } diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index ea849422..d004a1c0 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -1,9 +1,88 @@ import React from 'react' +import { CContainer, CCol, CRow, CCard, CCardBody, CCardText, CCardTitle, CAvatar, CButton } from '@coreui/react' +import {Link} from 'react-router-dom' +import {cilArrowCircleRight} from '@coreui/icons' +import CIcon from '@coreui/icons-react' + +import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' + const Configurator = () => { + const { collators, runtime, coretime } = useLocalStorageContext(); + + const handleClick = () => { + console.log('clicked') + } + return ( - <h1>CONFIGURE DEPLOYMENT</h1> + <CContainer fluid > + <CCard className="mb-3 col-md-10"> + <CRow className="g-0 p-3"> + <CCol md={1} className="d-flex justify-content-center align-items-center"> + <CAvatar color="light" size="xl">1</CAvatar> + </CCol> + <CCol md={10}> + <CCardBody> + <CCardTitle>Select Runtime</CCardTitle> + <CCardText> + {runtime.name ? runtime.name : "Please Select a Runtime"} + </CCardText> + </CCardBody> + </CCol> + <CCol md={1} className="d-flex justify-content-center align-items-center"> + <Link to='/configure/runtime'> + <CIcon size="xxl" className="text-secondary" icon={cilArrowCircleRight} /> + </Link> + </CCol> + </CRow> + </CCard> + <CCard className="mb-3 col-md-10"> + <CRow className="g-0 p-3"> + <CCol md={1} className="d-flex justify-content-center align-items-center"> + <CAvatar color="light" size="xl">2</CAvatar> + </CCol> + <CCol md={10}> + <CCardBody> + <CCardTitle>Network Topology</CCardTitle> + <CCardText> + {collators.length ? collators.length : "Please configure Network Topology"} + </CCardText> + </CCardBody> + </CCol> + <CCol md={1} className="d-flex justify-content-center align-items-center"> + <Link to='/configure/runtime'> + <CIcon size="xxl" className="text-secondary" icon={cilArrowCircleRight} /> + </Link> + </CCol> + </CRow> + </CCard> + <CCard className="mb-3 col-md-10"> + <CRow className="g-0 p-3"> + <CCol md={1} className="d-flex justify-content-center align-items-center"> + <CAvatar color="light" size="xl">3</CAvatar> + </CCol> + <CCol md={10}> + <CCardBody> + <CCardTitle>Coretime</CCardTitle> + <CCardText> + {coretime.amount ? coretime.amount : "Please configure Coretime needs"} + </CCardText> + </CCardBody> + </CCol> + <CCol md={1} className="d-flex justify-content-center align-items-center"> + <Link to='/configure/runtime'> + <CIcon size="xxl" className="text-secondary" icon={cilArrowCircleRight} /> + </Link> + </CCol> + </CRow> + </CCard> + <CRow className="g-0 p-3 col-md-10"> + <CButton onClick={() => handleClick()}className="col-3 mx-auto" color="success" size="lg" variant="outline" style={{"fontWeight":"200"}}> + Deploy + </CButton> + </CRow> + </CContainer> ) } diff --git a/src/views/empty/Empty.js b/src/views/empty/Empty.js index 7befbabc..b27a5491 100644 --- a/src/views/empty/Empty.js +++ b/src/views/empty/Empty.js @@ -1,5 +1,6 @@ import React from 'react' import { CContainer, CCol, CRow, CButton } from '@coreui/react' +import {Link } from "react-router-dom"; const Empty = () => { @@ -7,11 +8,16 @@ const Empty = () => { <CContainer fluid> <CRow className="align-items-center"> <CCol> - <h1 style={{"textAlign":"center", "marginTop": "4rem", "marginBottom": "4rem", "fontWeight":"300"}}>No active deployment</h1> + <h1 style={{"textAlign":"center", "marginTop": "4rem", "marginBottom": "4rem", "fontWeight":"200"}}>No active deployment</h1> </CCol> </CRow> <CRow className="align-items-center"> - <CButton className="col-3 mx-auto" color="success" size="lg" variant="outline">Start Building</CButton> + {/* <CButton component="a" href="/configure" className="col-3 mx-auto" color="success" size="lg" variant="outline" style={{"fontWeight":"200"}}>Start Building</CButton> */} + <Link to="/configure" style={{"display":"contents"}}> + <CButton className="col-3 mx-auto" color="success" size="lg" variant="outline" style={{"fontWeight":"200"}}> + Start Building + </CButton> + </Link> </CRow> </CContainer> ) From 26132e9c3d0528667495ad85541122968fceac51 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Sun, 3 Dec 2023 11:40:09 +0100 Subject: [PATCH 08/44] Adding form context --- src/App.js | 23 +++++++------ src/contexts/ConfiguratorFormContext.js | 33 +++++++++++++++++++ .../ConfiguratorRuntime.js | 2 +- .../configurator-runtime}/runtime.json | 0 src/views/configurator/Configurator.js | 6 ++-- 5 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 src/contexts/ConfiguratorFormContext.js rename src/{assets/runtimes => views/configurator-runtime}/runtime.json (100%) diff --git a/src/App.js b/src/App.js index 4be91416..a3b730b8 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,7 @@ import React, { Component, Suspense } from 'react' import { BrowserRouter, Route, Routes } from 'react-router-dom' import { LocalStorageContextProvider } from './contexts/LocalStorageContext' +import { ConfiguratorFormContextProvider } from './contexts/ConfiguratorFormContext' import './scss/style.scss' const loading = ( @@ -22,16 +23,18 @@ class App extends Component { render() { return ( <BrowserRouter> - <LocalStorageContextProvider> - <Suspense fallback={loading}> - <Routes> - <Route exact path="/login" name="Login Page" element={<Login />} /> - <Route exact path="/register" name="Register Page" element={<Register />} /> - <Route exact path="/404" name="Page 404" element={<Page404 />} /> - <Route exact path="/500" name="Page 500" element={<Page500 />} /> - <Route path="*" name="Home" element={<DefaultLayout />} /> - </Routes> - </Suspense> + <LocalStorageContextProvider> + <ConfiguratorFormContextProvider> + <Suspense fallback={loading}> + <Routes> + <Route exact path="/login" name="Login Page" element={<Login />} /> + <Route exact path="/register" name="Register Page" element={<Register />} /> + <Route exact path="/404" name="Page 404" element={<Page404 />} /> + <Route exact path="/500" name="Page 500" element={<Page500 />} /> + <Route path="*" name="Home" element={<DefaultLayout />} /> + </Routes> + </Suspense> + </ConfiguratorFormContextProvider> </LocalStorageContextProvider> </BrowserRouter> ) diff --git a/src/contexts/ConfiguratorFormContext.js b/src/contexts/ConfiguratorFormContext.js new file mode 100644 index 00000000..59cbbfa8 --- /dev/null +++ b/src/contexts/ConfiguratorFormContext.js @@ -0,0 +1,33 @@ +import React, { createContext, useContext, useState, useEffect } from 'react'; + + +// Create the context +const ConfiguratorFormContext = createContext(); + +// Define the context provider component +export const ConfiguratorFormContextProvider = ({ children }) => { + const [collators, setCollators] = useState(null); + const [coretime, setCoretime] = useState({every: null, amount: null }); + const [runtime, setRuntime] = useState({template: null}); + + // Context value + const contextValue = { + collators, + setCollators, + coretime, + setCoretime, + runtime, + setRuntime + }; + + return ( + <ConfiguratorFormContext.Provider value={contextValue}> + {children} + </ConfiguratorFormContext.Provider> + ); +}; + +// Custom hook to use the context +export function useConfiguratorFormContext() { + return useContext(ConfiguratorFormContext); +} diff --git a/src/views/configurator-runtime/ConfiguratorRuntime.js b/src/views/configurator-runtime/ConfiguratorRuntime.js index 5cbea67f..59880bd7 100644 --- a/src/views/configurator-runtime/ConfiguratorRuntime.js +++ b/src/views/configurator-runtime/ConfiguratorRuntime.js @@ -1,5 +1,5 @@ import React from 'react' -import runtimes from 'src/assets/runtimes/runtime.json' +import runtimes from './runtime.json' import {Link} from 'react-router-dom' import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' diff --git a/src/assets/runtimes/runtime.json b/src/views/configurator-runtime/runtime.json similarity index 100% rename from src/assets/runtimes/runtime.json rename to src/views/configurator-runtime/runtime.json diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index d004a1c0..ead2b1f4 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -4,12 +4,12 @@ import {Link} from 'react-router-dom' import {cilArrowCircleRight} from '@coreui/icons' import CIcon from '@coreui/icons-react' -import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' +import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext' const Configurator = () => { - const { collators, runtime, coretime } = useLocalStorageContext(); + const { collators, runtime, coretime } = useConfiguratorFormContext(); const handleClick = () => { console.log('clicked') @@ -46,7 +46,7 @@ const Configurator = () => { <CCardBody> <CCardTitle>Network Topology</CCardTitle> <CCardText> - {collators.length ? collators.length : "Please configure Network Topology"} + {collators ? collators : "Please configure Network Topology"} </CCardText> </CCardBody> </CCol> From 672c99b7878c65ada3334e7d3f3109ad9648036a Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 11:45:00 +0100 Subject: [PATCH 09/44] first commit --- .../ConfiguratorCollators.js | 43 +++++++++---- .../ConfiguratorRuntime.js | 61 +++++++++++-------- src/views/configurator/Configurator.js | 10 +-- 3 files changed, 70 insertions(+), 44 deletions(-) diff --git a/src/views/configurator-collators/ConfiguratorCollators.js b/src/views/configurator-collators/ConfiguratorCollators.js index 59b7620f..04484c1f 100644 --- a/src/views/configurator-collators/ConfiguratorCollators.js +++ b/src/views/configurator-collators/ConfiguratorCollators.js @@ -1,5 +1,9 @@ import React from 'react' import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' +import {Link} from 'react-router-dom' +import CIcon from '@coreui/icons-react' +import {cilArrowLeft} from '@coreui/icons' +import { CCol, CButtonToolbar, CButtonGroup, CButton} from '@coreui/react' const ConfiguratorCollators = () => { @@ -10,20 +14,35 @@ const ConfiguratorCollators = () => { setCollators([...collators, newCollator]); }; + const handleClick = (qty) => { + console.log("number of collators", qty) + } return ( - <div> - <h1>Configure Collators</h1> - <ul> - {collators.map((collator, index) => { - // If collator is an object, make sure to render a property of the object - return <li key={index}>{collator.time || collator}</li>; // Adjust based on the structure of collator - })} - </ul> - <button onClick={() => addCollator({ ...collators, time: new Date().toISOString() })}> - Add Collator - </button> - </div> + <> + <CCol md={1}> + <Link to='/configure'> + <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> + </Link> + </CCol> + <CCol> + <p className='fs-5 fw-light'>Pick the number of collators to be deployed.</p> + <CButtonToolbar role="group" aria-label="Large button group"> + <CButtonGroup className="me-2" role="group" aria-label="Third group"> + <CButton active={1 === 1 ? true : false} onClick={() => handleClick(1)} color="info" variant="outline">1 Collator</CButton> + <CButton active={1 === 2 ? true : false} onClick={() => handleClick(2)} color="info" variant="outline">2 Collators</CButton> + <CButton active={1 === 3 ? true : false} onClick={() => handleClick(3)} color="info" variant="outline">3 Collators</CButton> + <CButton active={1 === 4 ? true : false} onClick={() => handleClick(4)} color="info" variant="outline">4 Collators</CButton> + <CButton active={1 === 5 ? true : false} onClick={() => handleClick(5)} color="info" variant="outline">5 Collators</CButton> + <CButton active={1 === 6 ? true : false} onClick={() => handleClick(6)} color="info" variant="outline">6 Collators</CButton> + <CButton active={1 === 7 ? true : false} onClick={() => handleClick(7)} color="info" variant="outline">7 Collators</CButton> + <CButton active={1 === 8 ? true : false} onClick={() => handleClick(8)} color="info" variant="outline">8 Collators</CButton> + <CButton active={1 === 9 ? true : false} onClick={() => handleClick(9)} color="info" variant="outline">9 Collators</CButton> + <CButton active={1 === 10 ? true : false} onClick={() => handleClick(10)} color="info" variant="outline">10 Collators</CButton> + </CButtonGroup> + </CButtonToolbar> + </CCol> + </> ); }; diff --git a/src/views/configurator-runtime/ConfiguratorRuntime.js b/src/views/configurator-runtime/ConfiguratorRuntime.js index 5cbea67f..a8ecc511 100644 --- a/src/views/configurator-runtime/ConfiguratorRuntime.js +++ b/src/views/configurator-runtime/ConfiguratorRuntime.js @@ -4,9 +4,9 @@ import {Link} from 'react-router-dom' import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' -import { CButton, CCard, CCardImage, CCardBody, CCardFooter, CCardTitle, CCardText, CAccordion, CAccordionHeader, CAccordionItem, CAccordionBody, CRow, CCol, CAvatar, CBadge} from '@coreui/react' +import { CButton, CCard, CCardImage, CCardBody, CCardFooter, CCardTitle, CCardText, CRow, CCol} from '@coreui/react' import CIcon from '@coreui/icons-react' -import {cibGithub} from '@coreui/icons' +import {cibGithub, cilArrowLeft} from '@coreui/icons' const ConfiguratorRuntime = () => { @@ -16,33 +16,40 @@ const ConfiguratorRuntime = () => { const handleClick = (runtimeInfo) => { setRuntime(runtimeInfo) } - console.log('runtime', runtime) - // console.log(runtimes) return ( - <CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 4 }}> - {runtimes.map(runtimeInfo => { - return ( - <CCol key={runtimeInfo.id} xs> - <CCard className={runtimeInfo.id === runtime.id ? 'border-success h-100' : 'h-100'}> - <CCardImage orientation="top" src={runtimeInfo.img} /> - <CCardBody> - <CCardTitle>{runtimeInfo.name}</CCardTitle> - <CCardText> - {runtimeInfo.shortDescription} - </CCardText> - <CButton onClick={() => handleClick(runtimeInfo)}>Select</CButton> - </CCardBody> - <CCardFooter> - <Link target="_blank" to={`${runtimeInfo.github}`}> - <CIcon size="lg" className="text-secondary" icon={cibGithub}/> - </Link> - </CCardFooter> - </CCard> - </CCol> - ) - })} - </CRow> + <> + <CCol md={1}> + <Link to='/configure'> + <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> + </Link> + </CCol> + <CCol md={11}> + <CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 4 }}> + {runtimes.map(runtimeInfo => { + return ( + <CCol key={runtimeInfo.id} xs> + <CCard className={runtimeInfo.id === runtime.id ? 'border-start border-start-4 border-start-success h-100' : 'h-100'}> + <CCardImage orientation="top" src={runtimeInfo.img} /> + <CCardBody> + <CCardTitle>{runtimeInfo.name}</CCardTitle> + <CCardText> + {runtimeInfo.shortDescription} + </CCardText> + <CButton onClick={() => handleClick(runtimeInfo)}>Select</CButton> + </CCardBody> + <CCardFooter> + <Link target="_blank" to={`${runtimeInfo.github}`}> + <CIcon size="lg" className="text-secondary" icon={cibGithub}/> + </Link> + </CCardFooter> + </CCard> + </CCol> + ) + })} + </CRow> + </CCol> + </> ) } diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index d004a1c0..b79a89b2 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -20,7 +20,7 @@ const Configurator = () => { <CCard className="mb-3 col-md-10"> <CRow className="g-0 p-3"> <CCol md={1} className="d-flex justify-content-center align-items-center"> - <CAvatar color="light" size="xl">1</CAvatar> + <CAvatar color={runtime.name ? 'success' : 'light'} size="xl">1</CAvatar> </CCol> <CCol md={10}> <CCardBody> @@ -40,7 +40,7 @@ const Configurator = () => { <CCard className="mb-3 col-md-10"> <CRow className="g-0 p-3"> <CCol md={1} className="d-flex justify-content-center align-items-center"> - <CAvatar color="light" size="xl">2</CAvatar> + <CAvatar color={collators.length ? 'success' : 'light'} size="xl">2</CAvatar> </CCol> <CCol md={10}> <CCardBody> @@ -51,7 +51,7 @@ const Configurator = () => { </CCardBody> </CCol> <CCol md={1} className="d-flex justify-content-center align-items-center"> - <Link to='/configure/runtime'> + <Link to='/configure/collators'> <CIcon size="xxl" className="text-secondary" icon={cilArrowCircleRight} /> </Link> </CCol> @@ -60,7 +60,7 @@ const Configurator = () => { <CCard className="mb-3 col-md-10"> <CRow className="g-0 p-3"> <CCol md={1} className="d-flex justify-content-center align-items-center"> - <CAvatar color="light" size="xl">3</CAvatar> + <CAvatar color={coretime.amount ? 'success' : 'light'} size="xl">3</CAvatar> </CCol> <CCol md={10}> <CCardBody> @@ -71,7 +71,7 @@ const Configurator = () => { </CCardBody> </CCol> <CCol md={1} className="d-flex justify-content-center align-items-center"> - <Link to='/configure/runtime'> + <Link to='/configure/coretime'> <CIcon size="xxl" className="text-secondary" icon={cilArrowCircleRight} /> </Link> </CCol> From 1b10b9d1c7cedf284d6c384c38850af67d07feef Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 12:49:54 +0100 Subject: [PATCH 10/44] done network topology --- src/components/AppBreadcrumb.js | 1 - src/contexts/ConfiguratorFormContext.js | 2 +- .../ConfiguratorCollators.js | 63 ++++++++++--------- .../ConfiguratorRuntime.js | 19 ++++-- src/views/configurator/Configurator.js | 29 ++++++--- 5 files changed, 67 insertions(+), 47 deletions(-) diff --git a/src/components/AppBreadcrumb.js b/src/components/AppBreadcrumb.js index 8340f2ad..7f0b74ac 100644 --- a/src/components/AppBreadcrumb.js +++ b/src/components/AppBreadcrumb.js @@ -35,7 +35,6 @@ const AppBreadcrumb = () => { <CBreadcrumb className="m-0 ms-2"> <CBreadcrumbItem><Link to="/">Home</Link></CBreadcrumbItem> {breadcrumbs.map((breadcrumb, index) => { - console.log(index, breadcrumb) return ( <CBreadcrumbItem {...(breadcrumb.active ? { active: true } : "")} diff --git a/src/contexts/ConfiguratorFormContext.js b/src/contexts/ConfiguratorFormContext.js index 59cbbfa8..e17e2d73 100644 --- a/src/contexts/ConfiguratorFormContext.js +++ b/src/contexts/ConfiguratorFormContext.js @@ -6,7 +6,7 @@ const ConfiguratorFormContext = createContext(); // Define the context provider component export const ConfiguratorFormContextProvider = ({ children }) => { - const [collators, setCollators] = useState(null); + const [collators, setCollators] = useState(0); const [coretime, setCoretime] = useState({every: null, amount: null }); const [runtime, setRuntime] = useState({template: null}); diff --git a/src/views/configurator-collators/ConfiguratorCollators.js b/src/views/configurator-collators/ConfiguratorCollators.js index 04484c1f..7d691935 100644 --- a/src/views/configurator-collators/ConfiguratorCollators.js +++ b/src/views/configurator-collators/ConfiguratorCollators.js @@ -1,47 +1,50 @@ import React from 'react' -import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' +import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext' import {Link} from 'react-router-dom' import CIcon from '@coreui/icons-react' import {cilArrowLeft} from '@coreui/icons' -import { CCol, CButtonToolbar, CButtonGroup, CButton} from '@coreui/react' +import { CContainer, CRow, CCol, CButtonToolbar, CButtonGroup, CButton} from '@coreui/react' const ConfiguratorCollators = () => { - const { collators, setCollators } = useLocalStorageContext(); - - // Example function to update collators - const addCollator = (newCollator) => { - setCollators([...collators, newCollator]); - }; + const { collators, setCollators } = useConfiguratorFormContext(); const handleClick = (qty) => { - console.log("number of collators", qty) + console.log(typeof qty) + setCollators(qty) } return ( <> - <CCol md={1}> - <Link to='/configure'> - <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> + <CRow className='d-flex flex-row'> + <CCol md={1}> + <Link to='/configure'> + <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> + </Link> + </CCol> + <CCol> + <p className='fs-5 fw-light'>Pick the number of collators to be deployed.</p> + <CButtonToolbar className='mt-4' role="group" aria-label="Large button group"> + <CButtonGroup role="group" aria-label="Third group"> + <CButton className='fw-light' active={collators === 1 ? true : false} onClick={() => handleClick(1)} color="info" variant="outline">1 Collator</CButton> + <CButton className='fw-light' active={collators === 2 ? true : false} onClick={() => handleClick(2)} color="info" variant="outline">2 Collators</CButton> + <CButton className='fw-light' active={collators === 3 ? true : false} onClick={() => handleClick(3)} color="info" variant="outline">3 Collators</CButton> + <CButton className='fw-light' active={collators === 4 ? true : false} onClick={() => handleClick(4)} color="info" variant="outline">4 Collators</CButton> + <CButton className='fw-light' active={collators === 5 ? true : false} onClick={() => handleClick(5)} color="info" variant="outline">5 Collators</CButton> + <CButton className='fw-light' active={collators === 6 ? true : false} onClick={() => handleClick(6)} color="info" variant="outline">6 Collators</CButton> + <CButton className='fw-light' active={collators === 7 ? true : false} onClick={() => handleClick(7)} color="info" variant="outline">7 Collators</CButton> + <CButton className='fw-light' active={collators === 8 ? true : false} onClick={() => handleClick(8)} color="info" variant="outline">8 Collators</CButton> + <CButton className='fw-light' active={collators === 9 ? true : false} onClick={() => handleClick(9)} color="info" variant="outline">9 Collators</CButton> + <CButton className='fw-light' active={collators === 10 ? true : false} onClick={() => handleClick(10)} color="info" variant="outline">10 Collators</CButton> + </CButtonGroup> + </CButtonToolbar> + </CCol> + </CRow> + <CRow className='mt-4'> + <Link className='text-center' to="/configure"> + <CButton className='fw-light'>Confirm</CButton> </Link> - </CCol> - <CCol> - <p className='fs-5 fw-light'>Pick the number of collators to be deployed.</p> - <CButtonToolbar role="group" aria-label="Large button group"> - <CButtonGroup className="me-2" role="group" aria-label="Third group"> - <CButton active={1 === 1 ? true : false} onClick={() => handleClick(1)} color="info" variant="outline">1 Collator</CButton> - <CButton active={1 === 2 ? true : false} onClick={() => handleClick(2)} color="info" variant="outline">2 Collators</CButton> - <CButton active={1 === 3 ? true : false} onClick={() => handleClick(3)} color="info" variant="outline">3 Collators</CButton> - <CButton active={1 === 4 ? true : false} onClick={() => handleClick(4)} color="info" variant="outline">4 Collators</CButton> - <CButton active={1 === 5 ? true : false} onClick={() => handleClick(5)} color="info" variant="outline">5 Collators</CButton> - <CButton active={1 === 6 ? true : false} onClick={() => handleClick(6)} color="info" variant="outline">6 Collators</CButton> - <CButton active={1 === 7 ? true : false} onClick={() => handleClick(7)} color="info" variant="outline">7 Collators</CButton> - <CButton active={1 === 8 ? true : false} onClick={() => handleClick(8)} color="info" variant="outline">8 Collators</CButton> - <CButton active={1 === 9 ? true : false} onClick={() => handleClick(9)} color="info" variant="outline">9 Collators</CButton> - <CButton active={1 === 10 ? true : false} onClick={() => handleClick(10)} color="info" variant="outline">10 Collators</CButton> - </CButtonGroup> - </CButtonToolbar> - </CCol> + </CRow> </> ); }; diff --git a/src/views/configurator-runtime/ConfiguratorRuntime.js b/src/views/configurator-runtime/ConfiguratorRuntime.js index e413c047..4de84a2b 100644 --- a/src/views/configurator-runtime/ConfiguratorRuntime.js +++ b/src/views/configurator-runtime/ConfiguratorRuntime.js @@ -1,7 +1,7 @@ import React from 'react' import runtimes from './runtime.json' import {Link} from 'react-router-dom' -import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' +import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext' import { CButton, CCard, CCardImage, CCardBody, CCardFooter, CCardTitle, CCardText, CRow, CCol} from '@coreui/react' @@ -10,15 +10,16 @@ import {cibGithub, cilArrowLeft} from '@coreui/icons' const ConfiguratorRuntime = () => { - const { runtime, setRuntime } = useLocalStorageContext(); + const { runtime, setRuntime } = useConfiguratorFormContext(); const handleClick = (runtimeInfo) => { - setRuntime(runtimeInfo) + setRuntime({template: runtimeInfo}) } return ( <> + <CRow> <CCol md={1}> <Link to='/configure'> <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> @@ -29,14 +30,14 @@ const ConfiguratorRuntime = () => { {runtimes.map(runtimeInfo => { return ( <CCol key={runtimeInfo.id} xs> - <CCard className={runtimeInfo.id === runtime.id ? 'border-start border-start-4 border-start-success h-100' : 'h-100'}> + <CCard className={(runtime.template && runtimeInfo.id === runtime.template.id) ? 'border-start border-start-4 border-start-success h-100' : 'h-100'}> <CCardImage orientation="top" src={runtimeInfo.img} /> <CCardBody> <CCardTitle>{runtimeInfo.name}</CCardTitle> <CCardText> {runtimeInfo.shortDescription} - </CCardText> - <CButton onClick={() => handleClick(runtimeInfo)}>Select</CButton> + </CCardText > + <CButton variant="outline" className='fw-light' onClick={() => handleClick(runtimeInfo)}>Use</CButton> </CCardBody> <CCardFooter> <Link target="_blank" to={`${runtimeInfo.github}`}> @@ -49,6 +50,12 @@ const ConfiguratorRuntime = () => { })} </CRow> </CCol> + </CRow> + <CRow className='mt-4'> + <Link className='text-center' to="/configure"> + <CButton className='fw-light'>Confirm</CButton> + </Link> + </CRow> </> ) } diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index 9399f995..973e4ceb 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, {useState} from 'react' import { CContainer, CCol, CRow, CCard, CCardBody, CCardText, CCardTitle, CAvatar, CButton } from '@coreui/react' import {Link} from 'react-router-dom' import {cilArrowCircleRight} from '@coreui/icons' @@ -8,25 +8,28 @@ import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext const Configurator = () => { + const [ready, setReady] = useState(false); const { collators, runtime, coretime } = useConfiguratorFormContext(); const handleClick = () => { console.log('clicked') } + + //TODO: Logic of ready/setReady to send request return ( <CContainer fluid > <CCard className="mb-3 col-md-10"> <CRow className="g-0 p-3"> <CCol md={1} className="d-flex justify-content-center align-items-center"> - <CAvatar color={runtime.name ? 'success' : 'light'} size="xl">1</CAvatar> + <CAvatar className={runtime.template ? 'text-white fw-light': 'fw-light'} color={runtime.template ? 'success' : 'light'} size="xl">1</CAvatar> </CCol> <CCol md={10}> <CCardBody> <CCardTitle>Select Runtime</CCardTitle> <CCardText> - {runtime.name ? runtime.name : "Please Select a Runtime"} + {runtime.template ? runtime.template.name : "Please Select a Runtime"} </CCardText> </CCardBody> </CCol> @@ -40,13 +43,13 @@ const Configurator = () => { <CCard className="mb-3 col-md-10"> <CRow className="g-0 p-3"> <CCol md={1} className="d-flex justify-content-center align-items-center"> - <CAvatar color={collators.length ? 'success' : 'light'} size="xl">2</CAvatar> + <CAvatar className={collators ? 'text-white fw-light': 'fw-light'} color={collators ? 'success' : 'light'} size="xl">2</CAvatar> </CCol> <CCol md={10}> <CCardBody> <CCardTitle>Network Topology</CCardTitle> <CCardText> - {collators ? collators : "Please configure Network Topology"} + {collators ? (collators > 1 ? `${collators} Collators` : "1 Collator") : "Please configure Network Topology"} </CCardText> </CCardBody> </CCol> @@ -60,7 +63,7 @@ const Configurator = () => { <CCard className="mb-3 col-md-10"> <CRow className="g-0 p-3"> <CCol md={1} className="d-flex justify-content-center align-items-center"> - <CAvatar color={coretime.amount ? 'success' : 'light'} size="xl">3</CAvatar> + <CAvatar className={coretime.amount ? 'text-white fw-light': 'fw-light'} color={coretime.amount ? 'success' : 'light'} size="xl">3</CAvatar> </CCol> <CCol md={10}> <CCardBody> @@ -78,9 +81,17 @@ const Configurator = () => { </CRow> </CCard> <CRow className="g-0 p-3 col-md-10"> - <CButton onClick={() => handleClick()}className="col-3 mx-auto" color="success" size="lg" variant="outline" style={{"fontWeight":"200"}}> - Deploy - </CButton> + { + ready ? + <CButton onClick={() => handleClick()} className="col-3 mx-auto" color="success" size="lg" variant="outline" style={{"fontWeight":"200"}}> + Deploy + </CButton> + : + <CButton onClick={() => handleClick()} disabled className="col-3 mx-auto" color="danger" size="lg" variant="outline" style={{"fontWeight":"200"}}> + Deploy + </CButton> + } + </CRow> </CContainer> ) From 3b9cba6e4a442f3be313fe194b28997eaf9af39c Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Sun, 3 Dec 2023 12:52:11 +0100 Subject: [PATCH 11/44] Pushing the server call to spawn network --- .env | 1 + src/index.js | 1 + src/views/configurator/Configurator.js | 27 +++++++++--- src/views/configurator/submit.js | 61 ++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 .env create mode 100644 src/views/configurator/submit.js diff --git a/.env b/.env new file mode 100644 index 00000000..90165b6c --- /dev/null +++ b/.env @@ -0,0 +1 @@ +REACT_APP_API_URL=http://localhost:4000 diff --git a/src/index.js b/src/index.js index 54f6df2a..96c14d4b 100644 --- a/src/index.js +++ b/src/index.js @@ -8,6 +8,7 @@ import { Provider } from 'react-redux' import store from './store' import './index.css' + createRoot(document.getElementById('root')).render( <Provider store={store}> <App /> diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index ead2b1f4..9bb089d9 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -1,19 +1,32 @@ -import React from 'react' +import {React, useState, useCallback} from 'react' import { CContainer, CCol, CRow, CCard, CCardBody, CCardText, CCardTitle, CAvatar, CButton } from '@coreui/react' import {Link} from 'react-router-dom' import {cilArrowCircleRight} from '@coreui/icons' import CIcon from '@coreui/icons-react' +import submit from './submit' + import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext' const Configurator = () => { + const [formStatus, setStateStatus] = useState({executing: '', status: '', message: ''}); + const configurationContext = useConfiguratorFormContext(); + + const {collators, runtime, coretime } = configurationContext; + const {setCollators, setRuntime, setCoretime } = configurationContext; + + + const handleSubmit = useCallback(() => { + submit({...configurationContext, setStateStatus}) + }, [configurationContext,setStateStatus]); - const { collators, runtime, coretime } = useConfiguratorFormContext(); + const testState = useCallback(() => { + setCollators(3) + setRuntime({template: 'parachain'}) + setCoretime({every: 2, amount: 10 }) + }, [configurationContext,setStateStatus]); - const handleClick = () => { - console.log('clicked') - } return ( <CContainer fluid > @@ -26,7 +39,7 @@ const Configurator = () => { <CCardBody> <CCardTitle>Select Runtime</CCardTitle> <CCardText> - {runtime.name ? runtime.name : "Please Select a Runtime"} + {runtime.template ? runtime.template : "Please Select a Runtime"} </CCardText> </CCardBody> </CCol> @@ -78,7 +91,7 @@ const Configurator = () => { </CRow> </CCard> <CRow className="g-0 p-3 col-md-10"> - <CButton onClick={() => handleClick()}className="col-3 mx-auto" color="success" size="lg" variant="outline" style={{"fontWeight":"200"}}> + <CButton onClick={() => handleSubmit()}className="col-3 mx-auto" color="success" size="lg" variant="outline" style={{"fontWeight":"200"}}> Deploy </CButton> </CRow> diff --git a/src/views/configurator/submit.js b/src/views/configurator/submit.js new file mode 100644 index 00000000..21757353 --- /dev/null +++ b/src/views/configurator/submit.js @@ -0,0 +1,61 @@ + +// Your JSON data +let jsonData = { + "settings": { + "provider": "native" + }, + "relaychain": { + "chain": "rococo-local", + "default_command": "./bin/polkadot", + "nodes": [ + { + "name": "alice", + }, + { + "name": "bob", + } + ] + }, + "parachains": [ + { + "id": 2100, + "cumulus_based": true, + "chain": "local", + "add_to_genesis": false, + "onboard_as_parachain": false, + "collators": [] + } + ] +}; + +const submit = async ({collators, runtime, coretime, setStateStatus }) => { + + jsonData.parachains[0].collators = Array.from({ length: collators }, (_, i) => ({ + "name": `parachain-collator${(i + 1).toString().padStart(2, '0')}`, + "command": "./bin/parachain-template-node" + })); + + setStateStatus({executing: 'executing', status: 'info', message: 'Submitting Configuration'}); + + const response = await fetch(`${process.env.REACT_APP_API_URL}/network`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(jsonData) + }); + + const data = await response.json(); + + console.log('submit data', data); + + if (data.result === 'OK') { + setStateStatus({executing: 'success', status: 'success', message: 'Configuration Submitted'}); + } else { + setStateStatus({executing: 'failed', status: 'danger', message: 'Configuration Submission Failed'}); + } + + return data; +} + +export default submit; \ No newline at end of file From 5774182a6c2646237d454979a634dfb5245b66c1 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Sun, 3 Dec 2023 12:56:58 +0100 Subject: [PATCH 12/44] fix --- src/views/configurator/Configurator.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index 9bb089d9..5cb0470b 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -20,13 +20,6 @@ const Configurator = () => { const handleSubmit = useCallback(() => { submit({...configurationContext, setStateStatus}) }, [configurationContext,setStateStatus]); - - const testState = useCallback(() => { - setCollators(3) - setRuntime({template: 'parachain'}) - setCoretime({every: 2, amount: 10 }) - }, [configurationContext,setStateStatus]); - return ( <CContainer fluid > From 52e375d10e0c38fdd734c2f981d818b8a902066d Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 16:15:55 +0100 Subject: [PATCH 13/44] coretime configuration view --- .../ConfiguratorCollators.js | 4 +- .../ConfiguratorCoretime.js | 122 ++++++++++++++++-- src/views/configurator/Configurator.js | 6 +- 3 files changed, 115 insertions(+), 17 deletions(-) diff --git a/src/views/configurator-collators/ConfiguratorCollators.js b/src/views/configurator-collators/ConfiguratorCollators.js index 7d691935..c96d9b1d 100644 --- a/src/views/configurator-collators/ConfiguratorCollators.js +++ b/src/views/configurator-collators/ConfiguratorCollators.js @@ -3,7 +3,7 @@ import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext import {Link} from 'react-router-dom' import CIcon from '@coreui/icons-react' import {cilArrowLeft} from '@coreui/icons' -import { CContainer, CRow, CCol, CButtonToolbar, CButtonGroup, CButton} from '@coreui/react' +import { CRow, CCol, CButtonToolbar, CButtonGroup, CButton} from '@coreui/react' const ConfiguratorCollators = () => { @@ -22,7 +22,7 @@ const ConfiguratorCollators = () => { <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> </Link> </CCol> - <CCol> + <CCol md={11}> <p className='fs-5 fw-light'>Pick the number of collators to be deployed.</p> <CButtonToolbar className='mt-4' role="group" aria-label="Large button group"> <CButtonGroup role="group" aria-label="Third group"> diff --git a/src/views/configurator-coretime/ConfiguratorCoretime.js b/src/views/configurator-coretime/ConfiguratorCoretime.js index 6b47ade3..64d69ba3 100644 --- a/src/views/configurator-coretime/ConfiguratorCoretime.js +++ b/src/views/configurator-coretime/ConfiguratorCoretime.js @@ -1,20 +1,114 @@ -import React from 'react' -import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' +import React, {useState} from 'react' +import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext' +import {Link, useNavigate} from 'react-router-dom' +import CIcon from '@coreui/icons-react' +import {cilArrowLeft} from '@coreui/icons' +import { CFormInput, CRow, CCol, CButton, CForm } from '@coreui/react' const ConfiguratorCoretime = () => { - const { collators } = useLocalStorageContext(); + const [validAmount, setValidAmount] = useState(true) + const [validEvery, setValidEvery] = useState(true) + const [validated, setValidated] = useState(true) + const { coretime, setCoretime } = useConfiguratorFormContext(); + + const navigate = useNavigate() + + const handleAmountChange = (event) => { + let amount = Math.floor(Number(event.target.valueAsNumber)); + if (event.target.valueAsNumber > 10000){ + setValidAmount(false) + } else { + setValidAmount(true) + } + setCoretime({...coretime, amount}) + } + + const handleEveryChange = (event) => { + let every = Math.floor(Number(event.target.valueAsNumber)); + if (event.target.valueAsNumber > 1000){ + setValidEvery(false) + } else { + setValidEvery(true) + } + setCoretime({...coretime, every}) + } + + const handleSubmit = (event) => { + const form = event.currentTarget + if (!form.checkValidity()) { + event.preventDefault() + event.stopPropagation() + } else { + event.preventDefault() + navigate("/configure") + } + setValidated(true) + } return ( - <> - <h1>Configure Coretime</h1> - <ul> - {collators.map((collator, index) => { - // If collator is an object, make sure to render a property of the object - return <li key={index}>{collator.time || collator}</li>; // Adjust based on the structure of collator - })} - </ul> - </> - ) -} + <CForm className="needs-validation" noValidate onSubmit={handleSubmit} validated={validated}> + <CRow className='d-flex flex-row'> + <CCol md={1}> + <Link to='/configure'> + <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> + </Link> + </CCol> + <CCol md={11}> + <CRow className='mb-3'> + <p>In order to configure your Coretime needs, you need to select: <strong>Amount</strong> and <strong>Frequency</strong> of validation.</p> + <p><strong>Amount</strong> dictates how many blocks of your parachain you want to pre-configure to be validated by the Relay Chain. For the purposes of this MVP the cap is 10_000 blocks.</p> + <p><strong>Frequency</strong> configures every how many blocks of the Relay Chain you wish to submit a Parachain Block.</p> + <p className='mt-2'><strong>Example</strong>. Objective is to have one thousand Parachain blocks validated by the Relay Chain, and this to happen every 10 Relay Chain blocks. Configuration would look as follows:</p> + <ul className='ms-4'> + <li>Amount: 1_000</li> + <li>Frequency: 10</li> + </ul> + </CRow> + <CRow> + <CCol md={7}> + <CFormInput + max={10000} + onChange={() => handleAmountChange(event)} + invalid={!validAmount} + step={1} + type="number" + value={coretime.amount ? coretime.amount : ""} + size="lg" + aria-label="lg input example" + required + feedbackInvalid={validAmount ? "" : "Please make it an integer below 10_000"} + label="Amount: Parachain Blocks to be validated" + /> + </CCol> + </CRow> + <CRow className='mt-4'> + <CCol md={7}> + <CFormInput + max={1000} + step={1} + onChange={(event) => handleEveryChange(event)} + invalid={!validEvery} + label="Frequency: Every how many Relaychan Blocks should Parachain blocks be validated" + type="number" + value={coretime.every ? coretime.every : ""} + size="lg" + aria-label="lg input example" + required + feedbackInvalid={validEvery ? "" : "Please make it an integer below 1_000"} + /> + </CCol> + </CRow> + </CCol> + </CRow> + <CRow className='mt-4'> + <CCol className='d-flex justify-content-center'> + <CButton type="submit" className='fw-light'>Confirm</CButton> + </CCol> + </CRow> + </CForm> + ); +}; export default ConfiguratorCoretime + + diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index 0308b70d..e9c010b9 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -73,7 +73,11 @@ const Configurator = () => { <CCardBody> <CCardTitle>Coretime</CCardTitle> <CCardText> - {coretime.amount ? coretime.amount : "Please configure Coretime needs"} + {coretime.amount + ? + `Amount: ${coretime.amount}. Frequency: ${coretime.every}.` + : + "Please configure Coretime needs"} </CCardText> </CCardBody> </CCol> From f5a661e978f0c21dceeade17b2e7bf82f77fc84f Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Sun, 3 Dec 2023 16:52:51 +0100 Subject: [PATCH 14/44] WIP --- src/contexts/LocalStorageContext.js | 12 +- src/routes.js | 5 + .../ConfiguratorRuntime.js | 4 +- .../ConfiguratorRuntimeSpecs.js | 114 ++++++++++++++++++ src/views/configurator-runtime/runtime.json | 2 + src/views/configurator/Configurator.js | 4 +- src/views/configurator/submit.js | 51 ++------ 7 files changed, 143 insertions(+), 49 deletions(-) create mode 100644 src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js diff --git a/src/contexts/LocalStorageContext.js b/src/contexts/LocalStorageContext.js index 8a1ff31a..e2875193 100644 --- a/src/contexts/LocalStorageContext.js +++ b/src/contexts/LocalStorageContext.js @@ -15,14 +15,14 @@ const LocalStorageContext = createContext(); // Define the context provider component export const LocalStorageContextProvider = ({ children }) => { - const [collators, setCollators] = useState(() => getLocalStorageItem('collators', [])); + const [network, setNetwork] = useState(() => getLocalStorageItem('network', {})); const [coretime, setCoretime] = useState(() => getLocalStorageItem('coretime', {})); const [runtime, setRuntime] = useState(() => getLocalStorageItem('runtime', {})); - // Update localStorage when collators or coretime changes + // Update localStorage when network or coretime changes useEffect(() => { - setLocalStorageItem('collators', collators); - }, [collators]); + setLocalStorageItem('network', network); + }, [network]); useEffect(() => { setLocalStorageItem('coretime', coretime); @@ -34,8 +34,8 @@ export const LocalStorageContextProvider = ({ children }) => { // Context value const contextValue = { - collators, - setCollators, + network, + setNetwork, coretime, setCoretime, runtime, diff --git a/src/routes.js b/src/routes.js index f94a5e82..926b95c3 100644 --- a/src/routes.js +++ b/src/routes.js @@ -10,10 +10,12 @@ const RuntimeUpgrade = React.lazy(() => import('./views/runtime-upgrade/RuntimeU const Empty = React.lazy(() => import('./views/empty/Empty')) const Configurator = React.lazy(() => import('./views/configurator/Configurator')) const ConfiguratorRuntime = React.lazy(() => import('./views/configurator-runtime/ConfiguratorRuntime')) +const ConfiguratorRuntimeSpecs = React.lazy(() => import('./views/configurator-runtime/ConfiguratorRuntimeSpecs')) const ConfiguratorCollators = React.lazy(() => import('./views/configurator-collators/ConfiguratorCollators')) const ConfiguratorCoretime = React.lazy(() => import('./views/configurator-coretime/ConfiguratorCoretime')) + const routes = [ { path: '/', exact: true, name: 'Start Building' , element: Empty}, { path: '/dashboard', name: 'Dashboard', element: Dashboard }, @@ -24,8 +26,11 @@ const routes = [ { path: '/runtime-upgrade', name: 'Runtime Upgrade', element: RuntimeUpgrade }, { path: '/configure', name: 'Configure Deployment', element: Configurator }, { path: '/configure/runtime', name: 'Runtime', element: ConfiguratorRuntime }, + { path: '/configure/runtime-specs', name: 'Runtime Specs', element: ConfiguratorRuntimeSpecs}, { path: '/configure/collators', name: 'Network Topology', element: ConfiguratorCollators }, { path: '/configure/coretime', name: 'Coretime', element: ConfiguratorCoretime }, + + ] export default routes diff --git a/src/views/configurator-runtime/ConfiguratorRuntime.js b/src/views/configurator-runtime/ConfiguratorRuntime.js index 4de84a2b..b0bb576e 100644 --- a/src/views/configurator-runtime/ConfiguratorRuntime.js +++ b/src/views/configurator-runtime/ConfiguratorRuntime.js @@ -52,8 +52,8 @@ const ConfiguratorRuntime = () => { </CCol> </CRow> <CRow className='mt-4'> - <Link className='text-center' to="/configure"> - <CButton className='fw-light'>Confirm</CButton> + <Link className='text-center' to="/configure/runtime-specs"> + <CButton className='fw-light'>Next</CButton> </Link> </CRow> </> diff --git a/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js b/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js new file mode 100644 index 00000000..f0ecc853 --- /dev/null +++ b/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js @@ -0,0 +1,114 @@ +import React,{useState} from 'react' +import runtimes from './runtime.json' +import {Link} from 'react-router-dom' +import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext' +import { useNavigate } from 'react-router-dom'; + +import { CButton, CCard, CCardImage, CCardBody, CCardFooter, CCardTitle, CCardText, CRow, CCol,CFormInput,CForm} from '@coreui/react' +import CIcon from '@coreui/icons-react' +import {cibGithub, cilArrowLeft} from '@coreui/icons' + +const ConfiguratorRuntimeSpecs = () => { + const navigate = useNavigate(); + const { runtime, setRuntime } = useConfiguratorFormContext(); + const [validated, setValidated] = useState(false) + const [ss58Prefix, setSs58Prefix] = useState(); + const [decimals, setDecimals] = useState(); + const [tokenSymbol, setTokenSymbol] = useState(); + const [paraId, setParaId] = useState() + + const handleSubmit = (event) => { + event.preventDefault(); + const form = event.currentTarget; + + // Check if the form is valid + if (ss58Prefix && decimals && tokenSymbol && paraId ) { + // If the form is valid, navigate to the next page + navigate("/configure"); + } else { + // If the form is not valid, prevent navigation and enable validation feedback + event.stopPropagation(); + } + + // Set the validated state to true to trigger the display of validation feedback + setValidated(true); + }; + + console.log('!paraId',!paraId) + + const handleInputNumberChangeHandler = (maxValue, setter) => (e) => { + const value = parseFloat(e.target.value); + if (!isNaN(value) && Number.isInteger(value) && value <= maxValue) { + setter(value.toString()); + } + }; + + return ( + <> + <CRow> + <CCol md={1}> + <Link to='/configure'> + <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> + </Link> + </CCol> + <CCol md={11}> + <CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 4 }}> + <CForm + noValidate + validated={validated} + onSubmit={handleSubmit} + > + <CFormInput + type="number" + id="paraId" + invalid={true} + feedbackInvalid={ "Please make it an integer below 10_000"} + label="Para Id" + placeholder="Para Id" + value={paraId} + text="" + aria-describedby="Para Id" + onChange={handleInputNumberChangeHandler(10000,setParaId)} + /> + <CFormInput + type="text" + id="tokenSymbol" + label="Token Symbol" + placeholder="PORT" + value={tokenSymbol} + onChange={(e) => setTokenSymbol(e.target.value)} + text="" + aria-describedby="tokenSymbol" + /> + <CFormInput + type="number" + id="ss58Prefix" + label="ss58Prefix" + placeholder="42" + value={ss58Prefix} + onChange={handleInputNumberChangeHandler(100,setSs58Prefix)} + aria-describedby="ss58Prefix" + /> + <CFormInput + type="number" + id="decimals" + label="Decimals" + placeholder="12" + value={decimals} + text="" + aria-describedby="Decimals" + onChange={handleInputNumberChangeHandler(50,setDecimals)} + /> + <CRow className='mt-4'> + <CButton type="submit" className='fw-light'>Confirm</CButton> + </CRow> + </CForm> + </CRow> + </CCol> + </CRow> + + </> + ) +} + +export default ConfiguratorRuntimeSpecs diff --git a/src/views/configurator-runtime/runtime.json b/src/views/configurator-runtime/runtime.json index 9b5af376..f804595b 100644 --- a/src/views/configurator-runtime/runtime.json +++ b/src/views/configurator-runtime/runtime.json @@ -1,6 +1,7 @@ [ { "name":"Extended Parachain Template", + "value": "parity-extended-template", "developer":"Parity Technologies", "tags":["Assets", "XCM", "Governance", "SUDO"], "shortDescription":"The Extended Parachain Template is a ready-to-use parachain template, pre-configured with the Assets pallet, a simple Governance system (Collective & Motion pallets), and other useful base features.", @@ -11,6 +12,7 @@ }, { "name":"EVM Parachain Template", + "value": "parity-frontier-template", "developer":"Parity Technologies", "tags":["EVM", "XCM", "Governance", "SUDO"], "shortDescription":"The Frontier Parachain Template is a ready-to-use EVM-based parachain (based on the Frontier project), pre-configured with the Assets pallet, a simple Governance system (Collective & Motion pallets), and EVM precompiles.", diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index 0308b70d..6645205f 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -15,11 +15,9 @@ const Configurator = () => { const [ready, setReady] = useState(false); const {collators, runtime, coretime } = configurationContext; - const {setCollators, setRuntime, setCoretime } = configurationContext; - const handleSubmit = useCallback(() => { - submit({...configurationContext, setStateStatus}) + submit({...configurationContext, setStateStatus,configurationContext}) }, [configurationContext,setStateStatus]); return ( diff --git a/src/views/configurator/submit.js b/src/views/configurator/submit.js index 21757353..4c80439a 100644 --- a/src/views/configurator/submit.js +++ b/src/views/configurator/submit.js @@ -1,39 +1,15 @@ - -// Your JSON data -let jsonData = { - "settings": { - "provider": "native" - }, - "relaychain": { - "chain": "rococo-local", - "default_command": "./bin/polkadot", - "nodes": [ - { - "name": "alice", - }, - { - "name": "bob", - } - ] - }, - "parachains": [ - { - "id": 2100, - "cumulus_based": true, - "chain": "local", - "add_to_genesis": false, - "onboard_as_parachain": false, - "collators": [] - } - ] -}; - -const submit = async ({collators, runtime, coretime, setStateStatus }) => { - - jsonData.parachains[0].collators = Array.from({ length: collators }, (_, i) => ({ - "name": `parachain-collator${(i + 1).toString().padStart(2, '0')}`, - "command": "./bin/parachain-template-node" - })); +const submit = async ({collators, runtime, setStateStatus, paraId, configurationContext }) => { + + let jsonData = { + paraId, + template: runtime.template.value, + collators_count: collators, + properties: { + symbol: "PORT", + ss58: number, + decimals : number + }, + } setStateStatus({executing: 'executing', status: 'info', message: 'Submitting Configuration'}); @@ -46,10 +22,9 @@ const submit = async ({collators, runtime, coretime, setStateStatus }) => { }); const data = await response.json(); - - console.log('submit data', data); if (data.result === 'OK') { + configurationContext.setNetwork(data.network); setStateStatus({executing: 'success', status: 'success', message: 'Configuration Submitted'}); } else { setStateStatus({executing: 'failed', status: 'danger', message: 'Configuration Submission Failed'}); From 779cb2e7c083be92940ebbd648d3954e416d43ac Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 18:22:33 +0100 Subject: [PATCH 15/44] added configurator deploy logic --- src/views/configurator/Configurator.js | 32 ++++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index e9c010b9..3b89c741 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -1,4 +1,4 @@ -import {React, useState, useCallback} from 'react' +import {React, useState, useCallback, useEffect} from 'react' import { CContainer, CCol, CRow, CCard, CCardBody, CCardText, CCardTitle, CAvatar, CButton } from '@coreui/react' import {Link} from 'react-router-dom' import {cilArrowCircleRight} from '@coreui/icons' @@ -15,7 +15,15 @@ const Configurator = () => { const [ready, setReady] = useState(false); const {collators, runtime, coretime } = configurationContext; - const {setCollators, setRuntime, setCoretime } = configurationContext; + // const {setCollators, setRuntime, setCoretime } = configurationContext; + + useEffect(() => { + // This function will run after every render (initial render + updates) + if (collators && runtime && coretime) { + setReady(true) + } + }, [collators, runtime, coretime]); + const handleSubmit = useCallback(() => { @@ -89,16 +97,16 @@ const Configurator = () => { </CRow> </CCard> <CRow className="g-0 p-3 col-md-10"> - { - ready ? - <CButton onClick={() => handleClick()} className="col-3 mx-auto" color="success" size="lg" variant="outline" style={{"fontWeight":"200"}}> - Deploy - </CButton> - : - <CButton onClick={() => handleClick()} disabled className="col-3 mx-auto" color="danger" size="lg" variant="outline" style={{"fontWeight":"200"}}> - Deploy - </CButton> - } + <CButton + onClick={() => handleSubmit()} + disabled={!ready} + className="col-3 mx-auto" + color={ready ? "success" : "danger"} + size="lg" variant="outline" + style={{"fontWeight":"200"}} + > + Deploy + </CButton> </CRow> </CContainer> From 4b8c8a52ff9a2c5a7d642157bfd8df34fd1f34ef Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Sun, 3 Dec 2023 18:32:46 +0100 Subject: [PATCH 16/44] Setting new backend details and loading local storage with results --- src/contexts/ConfiguratorFormContext.js | 2 +- .../ConfiguratorCollators.js | 1 - .../ConfiguratorRuntime.js | 2 +- .../ConfiguratorRuntimeSpecs.js | 241 +++++++++++------- src/views/configurator/Configurator.js | 11 +- src/views/configurator/submit.js | 15 +- 6 files changed, 169 insertions(+), 103 deletions(-) diff --git a/src/contexts/ConfiguratorFormContext.js b/src/contexts/ConfiguratorFormContext.js index e17e2d73..ecf007fa 100644 --- a/src/contexts/ConfiguratorFormContext.js +++ b/src/contexts/ConfiguratorFormContext.js @@ -8,7 +8,7 @@ const ConfiguratorFormContext = createContext(); export const ConfiguratorFormContextProvider = ({ children }) => { const [collators, setCollators] = useState(0); const [coretime, setCoretime] = useState({every: null, amount: null }); - const [runtime, setRuntime] = useState({template: null}); + const [runtime, setRuntime] = useState({template: null, specs: {paraId:null, ss58:null, tokenSymbol:null, decimals:null}}); // Context value const contextValue = { diff --git a/src/views/configurator-collators/ConfiguratorCollators.js b/src/views/configurator-collators/ConfiguratorCollators.js index c96d9b1d..1fc80d2f 100644 --- a/src/views/configurator-collators/ConfiguratorCollators.js +++ b/src/views/configurator-collators/ConfiguratorCollators.js @@ -10,7 +10,6 @@ const ConfiguratorCollators = () => { const { collators, setCollators } = useConfiguratorFormContext(); const handleClick = (qty) => { - console.log(typeof qty) setCollators(qty) } diff --git a/src/views/configurator-runtime/ConfiguratorRuntime.js b/src/views/configurator-runtime/ConfiguratorRuntime.js index b0bb576e..891dd5fa 100644 --- a/src/views/configurator-runtime/ConfiguratorRuntime.js +++ b/src/views/configurator-runtime/ConfiguratorRuntime.js @@ -14,7 +14,7 @@ const ConfiguratorRuntime = () => { const handleClick = (runtimeInfo) => { - setRuntime({template: runtimeInfo}) + setRuntime((runtime) => ({template: runtimeInfo, specs: runtime.specs})) } return ( diff --git a/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js b/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js index f0ecc853..37d9f5c4 100644 --- a/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js +++ b/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js @@ -9,106 +9,169 @@ import CIcon from '@coreui/icons-react' import {cibGithub, cilArrowLeft} from '@coreui/icons' const ConfiguratorRuntimeSpecs = () => { - const navigate = useNavigate(); + const [ss58Valid, setSs58Valid] = useState(true) + const [paraIdValid, setParaIdValid] = useState(true) + const [tokenSymbolValid, setTokenSymbolValid] = useState(true) + const [decimalsValid, setDecimalsValid] = useState(true) + + const [validated, setValidated] = useState(true) const { runtime, setRuntime } = useConfiguratorFormContext(); - const [validated, setValidated] = useState(false) - const [ss58Prefix, setSs58Prefix] = useState(); - const [decimals, setDecimals] = useState(); - const [tokenSymbol, setTokenSymbol] = useState(); - const [paraId, setParaId] = useState() - const handleSubmit = (event) => { - event.preventDefault(); - const form = event.currentTarget; - - // Check if the form is valid - if (ss58Prefix && decimals && tokenSymbol && paraId ) { - // If the form is valid, navigate to the next page - navigate("/configure"); + const navigate = useNavigate() + + + + const handleAmountChange = (event, max, setter, path) => { + const amount = Math.floor(Number(event.target.valueAsNumber)); + if (event.target.valueAsNumber > max) { + setter(false); } else { - // If the form is not valid, prevent navigation and enable validation feedback - event.stopPropagation(); + setter(true); + setRuntime(runtime => { + + // Clone the runtime object to avoid direct mutation + let newRuntime = JSON.parse(JSON.stringify(runtime)); + + + // Split the path and reduce it to the specific property + path.split('.').reduce((obj, key, index, array) => { + if (index === array.length - 1) { + obj[key] = amount; + } else { + return obj[key]; + } + }, newRuntime); + + return newRuntime; + }); } - - // Set the validated state to true to trigger the display of validation feedback - setValidated(true); - }; +}; + +const handleTokenSymbolChange = (event, max, setter) => { + const value = event.target.value; + if (value.length > max) { + setter(false); + } else { + setter(true); + setRuntime(runtime => { + // Clone the runtime object to avoid direct mutation + let newRuntime = JSON.parse(JSON.stringify(runtime)); + let { template, specs } = newRuntime; - console.log('!paraId',!paraId) + specs.tokenSymbol = value; + return { template, specs }; + }); + } +} - const handleInputNumberChangeHandler = (maxValue, setter) => (e) => { - const value = parseFloat(e.target.value); - if (!isNaN(value) && Number.isInteger(value) && value <= maxValue) { - setter(value.toString()); + const handleSubmit = (event) => { + const form = event.currentTarget + if (!form.checkValidity()) { + event.preventDefault() + event.stopPropagation() + } else { + event.preventDefault() + navigate("/configure") } - }; + setValidated(true) + } return ( - <> - <CRow> - <CCol md={1}> - <Link to='/configure'> - <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> - </Link> - </CCol> - <CCol md={11}> - <CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 4 }}> - <CForm - noValidate - validated={validated} - onSubmit={handleSubmit} - > - <CFormInput - type="number" - id="paraId" - invalid={true} - feedbackInvalid={ "Please make it an integer below 10_000"} - label="Para Id" - placeholder="Para Id" - value={paraId} - text="" - aria-describedby="Para Id" - onChange={handleInputNumberChangeHandler(10000,setParaId)} - /> - <CFormInput - type="text" - id="tokenSymbol" - label="Token Symbol" - placeholder="PORT" - value={tokenSymbol} - onChange={(e) => setTokenSymbol(e.target.value)} - text="" - aria-describedby="tokenSymbol" - /> - <CFormInput - type="number" - id="ss58Prefix" - label="ss58Prefix" - placeholder="42" - value={ss58Prefix} - onChange={handleInputNumberChangeHandler(100,setSs58Prefix)} - aria-describedby="ss58Prefix" - /> - <CFormInput - type="number" - id="decimals" - label="Decimals" - placeholder="12" - value={decimals} - text="" - aria-describedby="Decimals" - onChange={handleInputNumberChangeHandler(50,setDecimals)} - /> + <CForm className="needs-validation" noValidate onSubmit={handleSubmit} validated={validated}> + <CRow className='d-flex flex-row'> + <CCol md={1}> + <Link to='/configure'> + <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> + </Link> + </CCol> + <CCol md={11}> + <CRow className='mb-3'> + <p>In order to configure your Coretime needs, you need to select: <strong>Amount</strong> and <strong>Frequency</strong> of validation.</p> + <p><strong>Amount</strong> dictates how many blocks of your parachain you want to pre-configure to be validated by the Relay Chain. For the purposes of this MVP the cap is 10_000 blocks.</p> + <p><strong>Frequency</strong> configures every how many blocks of the Relay Chain you wish to submit a Parachain Block.</p> + <p className='mt-2'><strong>Example</strong>. Objective is to have one thousand Parachain blocks validated by the Relay Chain, and this to happen every 10 Relay Chain blocks. Configuration would look as follows:</p> + <ul className='ms-4'> + <li>Amount: 1_000</li> + <li>Frequency: 10</li> + </ul> + </CRow> + <CRow> + <CCol md={7}> + <CFormInput + max={10000} + onChange={() => handleAmountChange(event, 10000, setParaIdValid, 'specs.paraId')} + invalid={!paraIdValid} + step={1} + type="number" + value={runtime?.specs?.paraId ? runtime.specs.paraId : ""} + size="lg" + aria-label="lg input example" + required + feedbackInvalid={paraIdValid ? "" : "Please make it an integer below 10_000"} + label="ParaId: Parachain Id" + /> + </CCol> + </CRow> <CRow className='mt-4'> - <CButton type="submit" className='fw-light'>Confirm</CButton> + <CCol md={7}> + <CFormInput + max={100} + step={1} + onChange={() => handleAmountChange(event, 100, setSs58Valid, 'specs.ss58')} + invalid={!ss58Valid} + label="ss58 Format" + type="number" + value={runtime?.specs?.ss58 ? runtime.specs.ss58 : ""} + size="lg" + aria-label="lg input example" + required + feedbackInvalid={ss58Valid ? "" : "Please make it an integer below 100"} + /> + </CCol> </CRow> - </CForm> - </CRow> - </CCol> - </CRow> - - </> - ) + <CRow className='mt-4'> + <CCol md={7}> + <CFormInput + max={8} + step={1} + onChange={(event) => handleTokenSymbolChange(event, 8, setTokenSymbolValid)} + invalid={!tokenSymbolValid} + label="TokenSymbol" + type="text" + value={runtime?.specs?.tokenSymbol ? runtime.specs.tokenSymbol : ""} + size="lg" + aria-label="lg input example" + required + feedbackInvalid={tokenSymbolValid ? "" : "Please make the len below 8"} + /> + </CCol> + </CRow> + <CRow className='mt-4'> + <CCol md={7}> + <CFormInput + max={30} + step={1} + onChange={(event) => handleAmountChange(event, 1000, setDecimalsValid, 'specs.decimals')} + invalid={!decimalsValid} + label="Decimals: Amount of decimals for the token" + type="number" + value={runtime?.specs?.decimals ? runtime.specs.decimals : ""} + size="lg" + aria-label="lg input example" + required + feedbackInvalid={decimalsValid ? "" : "Please make it an integer below 1_000"} + /> + </CCol> + </CRow> + </CCol> + </CRow> + <CRow className='mt-4'> + <CCol className='d-flex justify-content-center'> + <CButton type="submit" className='fw-light'>Confirm</CButton> + </CCol> + </CRow> + </CForm> + ); } export default ConfiguratorRuntimeSpecs diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index d0461f44..b42e6c20 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -7,18 +7,21 @@ import CIcon from '@coreui/icons-react' import submit from './submit' import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext' +import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' const Configurator = () => { const [formStatus, setStateStatus] = useState({executing: '', status: '', message: ''}); const configurationContext = useConfiguratorFormContext(); - const [ready, setReady] = useState(false); + const localStorageContext = useLocalStorageContext(); + const [ready, setReady] = useState(true); const {collators, runtime, coretime } = configurationContext; const handleSubmit = useCallback(() => { - submit({...configurationContext, setStateStatus,configurationContext}) + submit({setStateStatus,localStorageContext, configurationContext }) }, [configurationContext,setStateStatus]); + return ( <CContainer fluid > @@ -89,11 +92,11 @@ const Configurator = () => { <CRow className="g-0 p-3 col-md-10"> { ready ? - <CButton onClick={() => handleClick()} className="col-3 mx-auto" color="success" size="lg" variant="outline" style={{"fontWeight":"200"}}> + <CButton onClick={() => handleSubmit()} className="col-3 mx-auto" color="success" size="lg" variant="outline" style={{"fontWeight":"200"}}> Deploy </CButton> : - <CButton onClick={() => handleClick()} disabled className="col-3 mx-auto" color="danger" size="lg" variant="outline" style={{"fontWeight":"200"}}> + <CButton onClick={() => handleSubmit()} disabled className="col-3 mx-auto" color="danger" size="lg" variant="outline" style={{"fontWeight":"200"}}> Deploy </CButton> } diff --git a/src/views/configurator/submit.js b/src/views/configurator/submit.js index 4c80439a..4ae42f87 100644 --- a/src/views/configurator/submit.js +++ b/src/views/configurator/submit.js @@ -1,13 +1,14 @@ -const submit = async ({collators, runtime, setStateStatus, paraId, configurationContext }) => { - +const submit = async ({setStateStatus,localStorageContext, configurationContext}) => { + const {collators, runtime } = configurationContext; + const {paraId, ss58, tokenSymbol, decimals} = runtime.specs; let jsonData = { - paraId, + para_id: paraId, template: runtime.template.value, collators_count: collators, properties: { - symbol: "PORT", - ss58: number, - decimals : number + symbol: tokenSymbol, + ss58, + decimals, }, } @@ -24,7 +25,7 @@ const submit = async ({collators, runtime, setStateStatus, paraId, configuration const data = await response.json(); if (data.result === 'OK') { - configurationContext.setNetwork(data.network); + localStorageContext.setNetwork(data.network); setStateStatus({executing: 'success', status: 'success', message: 'Configuration Submitted'}); } else { setStateStatus({executing: 'failed', status: 'danger', message: 'Configuration Submission Failed'}); From 76ded84b9d8b2b659bdbf956bc1b3192894522f9 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 19:57:21 +0100 Subject: [PATCH 17/44] menu disabled if no deployment --- src/components/AppSidebarNav.js | 10 ++++++++++ src/contexts/LocalStorageContext.js | 11 ++++++++++- src/views/configurator/submit.js | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/components/AppSidebarNav.js b/src/components/AppSidebarNav.js index 2063d9e7..f4d54e6e 100644 --- a/src/components/AppSidebarNav.js +++ b/src/components/AppSidebarNav.js @@ -4,7 +4,13 @@ import PropTypes from 'prop-types' import { CBadge } from '@coreui/react' +import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' + export const AppSidebarNav = ({ items }) => { + + const localStorageContext = useLocalStorageContext(); + const { networkStatus } = localStorageContext; + const location = useLocation() const navLink = (name, icon, badge) => { return ( @@ -20,6 +26,9 @@ export const AppSidebarNav = ({ items }) => { ) } + console.log(networkStatus) + console.log(networkStatus === 'OK') + const navItem = (item, index) => { const { component, name, badge, icon, ...rest } = item const Component = component @@ -31,6 +40,7 @@ export const AppSidebarNav = ({ items }) => { })} key={index} {...rest} + disabled={networkStatus === 'OK' ? false : true} > {navLink(name, icon, badge)} </Component> diff --git a/src/contexts/LocalStorageContext.js b/src/contexts/LocalStorageContext.js index e2875193..bbbe27ed 100644 --- a/src/contexts/LocalStorageContext.js +++ b/src/contexts/LocalStorageContext.js @@ -17,8 +17,11 @@ const LocalStorageContext = createContext(); export const LocalStorageContextProvider = ({ children }) => { const [network, setNetwork] = useState(() => getLocalStorageItem('network', {})); const [coretime, setCoretime] = useState(() => getLocalStorageItem('coretime', {})); + //TODO: this might need to be deleted const [runtime, setRuntime] = useState(() => getLocalStorageItem('runtime', {})); + const [networkStatus, setNetworkStatus] = useState(() => getLocalStorageItem('networkStatus', {})); + // Update localStorage when network or coretime changes useEffect(() => { setLocalStorageItem('network', network); @@ -32,6 +35,10 @@ export const LocalStorageContextProvider = ({ children }) => { setLocalStorageItem('runtime', runtime); }, [runtime]); + useEffect(() => { + setLocalStorageItem('networkStatus', networkStatus); + }, [networkStatus]); + // Context value const contextValue = { network, @@ -39,7 +46,9 @@ export const LocalStorageContextProvider = ({ children }) => { coretime, setCoretime, runtime, - setRuntime + setRuntime, + networkStatus, + setNetworkStatus }; return ( diff --git a/src/views/configurator/submit.js b/src/views/configurator/submit.js index 4ae42f87..a909253c 100644 --- a/src/views/configurator/submit.js +++ b/src/views/configurator/submit.js @@ -23,6 +23,7 @@ const submit = async ({setStateStatus,localStorageContext, configurationContext} }); const data = await response.json(); + localStorageContext.setNetworkStatus(data.result); if (data.result === 'OK') { localStorageContext.setNetwork(data.network); From c81c318d0aeabcb4477679c547309e87c3ebe027 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 20:44:02 +0100 Subject: [PATCH 18/44] added deployed Ok logic to breadcrumbs --- src/components/AppBreadcrumb.js | 8 +++++++- src/components/AppSidebarNav.js | 3 --- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/AppBreadcrumb.js b/src/components/AppBreadcrumb.js index 7f0b74ac..54cb57fd 100644 --- a/src/components/AppBreadcrumb.js +++ b/src/components/AppBreadcrumb.js @@ -5,9 +5,15 @@ import routes from '../routes' import { CBreadcrumb, CBreadcrumbItem } from '@coreui/react' +import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' + + const AppBreadcrumb = () => { const currentLocation = useLocation().pathname + const localStorageContext = useLocalStorageContext(); + const { networkStatus } = localStorageContext; + const getRouteName = (pathname, routes) => { const currentRoute = routes.find((route) => route.path === pathname) return currentRoute ? currentRoute.name : false @@ -33,7 +39,7 @@ const AppBreadcrumb = () => { return ( <CBreadcrumb className="m-0 ms-2"> - <CBreadcrumbItem><Link to="/">Home</Link></CBreadcrumbItem> + <CBreadcrumbItem><Link to={networkStatus === 'OK' ? '/dashboard' : '/'}>Home</Link></CBreadcrumbItem> {breadcrumbs.map((breadcrumb, index) => { return ( <CBreadcrumbItem diff --git a/src/components/AppSidebarNav.js b/src/components/AppSidebarNav.js index f4d54e6e..774b2b12 100644 --- a/src/components/AppSidebarNav.js +++ b/src/components/AppSidebarNav.js @@ -26,9 +26,6 @@ export const AppSidebarNav = ({ items }) => { ) } - console.log(networkStatus) - console.log(networkStatus === 'OK') - const navItem = (item, index) => { const { component, name, badge, icon, ...rest } = item const Component = component From 7b22139e0c91f91cde6bd37f9243d15b6aa7fbfd Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 21:15:03 +0100 Subject: [PATCH 19/44] dinamically creates explorer links to collators and validators --- src/_nav.js | 222 ++++++++++++++++++++++++----------- src/components/AppSidebar.js | 9 +- 2 files changed, 162 insertions(+), 69 deletions(-) diff --git a/src/_nav.js b/src/_nav.js index 178931db..5596a13a 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -10,73 +10,159 @@ import { } from '@coreui/icons' import { CNavGroup, CNavItem, CNavTitle, CNavLink } from '@coreui/react' -const _nav = [ +const generateNav = (networkInfo, networkStatus) => { + let relayChainValidators = []; + let paraCollators = []; + + if (networkStatus === 'OK') { + //this means that we have successfully launched the networks. + //objective is to generate now the rest of the nav array with the information of the collators and validators + relayChainValidators = networkInfo.relay.map(node => { + return { + component: CNavItem, + name: node.name, + to: `https://polkadot.js.org/apps/?rpc=${node.wsUri}#/explorer` + } + }) + + paraCollators = networkInfo.paras[1].map(node => { + return { + component: CNavItem, + name: node.name, + to: `https://polkadot.js.org/apps/?rpc=${node.wsUri}#/explorer` + } + }) + } + + + const nav = [ + { + component: CNavTitle, + name: "Account" + }, + { + component: CNavTitle, + name: 'Current Deployment', + }, + { + component: CNavItem, + name: 'Dashboard', + to: '/dashboard', + icon: <CIcon icon={cilSpeedometer} customClassName="nav-icon" />, + }, { - component: CNavTitle, - name: "Account" - }, - { - component: CNavTitle, - name: 'Current Deployment', - }, - { - component: CNavItem, - name: 'Dashboard', - to: '/dashboard', - icon: <CIcon icon={cilSpeedometer} customClassName="nav-icon" />, - }, - { - component: CNavItem, - name: 'Coretime Credits', - to: '/coretime', - icon: <CIcon icon={cilWallet} customClassName="nav-icon" />, - }, - { - component: CNavItem, - name: 'Runtime Upgrades', - to: '/runtime-upgrade', - icon: <CIcon icon={cilMemory} customClassName="nav-icon" />, - }, - { - component: CNavItem, - name: 'Explorer', - to: 'https://google.com', - icon: <CIcon icon={cilMagnifyingGlass} customClassName="nav-icon" />, - }, - { - component: CNavLink, - name: 'Grafana', - href: 'https://google.com', - icon: <CIcon icon={cilMonitor} customClassName="nav-icon" />, - }, - // TODO -> There could be some logic here to show one or the other menu depending on if there's an active deployment - // { - // component: CNavTitle, - // name: 'New Deployment', - // }, - // { - // component: CNavGroup, - // name: 'Configuration', - // to: '/configure', - // icon: <CIcon icon={cilCog} customClassName="nav-icon" />, - // items: [ - // { - // component: CNavItem, - // name: 'Runtime', - // to: '/configure/runtime', - // }, - // { - // component: CNavItem, - // name: 'Collators', - // to: '/configure/collators', - // }, - // { - // component: CNavItem, - // name: 'Coretime', - // to: '/configure/coretime', - // }, - // ], - // }, -] + component: CNavItem, + name: 'Coretime Credits', + to: '/coretime', + icon: <CIcon icon={cilWallet} customClassName="nav-icon" />, + }, + { + component: CNavItem, + name: 'Runtime Upgrades', + to: '/runtime-upgrade', + icon: <CIcon icon={cilMemory} customClassName="nav-icon" />, + }, + { + component: CNavGroup, + name: 'Explorer', + icon: <CIcon icon={cilMagnifyingGlass} customClassName="nav-icon" />, + items: [ + { + component: CNavGroup, + name: 'Relaychain', + items:relayChainValidators + }, + { + component: CNavGroup, + name: 'Parachain', + items:paraCollators + } + ] + } + ] + + return nav + +} + +// const _nav = [ +// { +// component: CNavTitle, +// name: "Account" +// }, +// { +// component: CNavTitle, +// name: 'Current Deployment', +// }, +// { +// component: CNavItem, +// name: 'Dashboard', +// to: '/dashboard', +// icon: <CIcon icon={cilSpeedometer} customClassName="nav-icon" />, +// }, +// { +// component: CNavItem, +// name: 'Coretime Credits', +// to: '/coretime', +// icon: <CIcon icon={cilWallet} customClassName="nav-icon" />, +// }, +// { +// component: CNavItem, +// name: 'Runtime Upgrades', +// to: '/runtime-upgrade', +// icon: <CIcon icon={cilMemory} customClassName="nav-icon" />, +// }, +// { +// component: CNavGroup, +// name: 'Explorer', +// icon: <CIcon icon={cilCog} customClassName="nav-icon" />, +// items: [ +// { +// component: CNavGroup, +// name: 'Relay Chain', +// items: [ +// { +// component: CNavItem, +// name: 'Validator - 01', +// to: '/' +// }, +// { +// component: CNavItem, +// name: 'Validator - 02', +// to: '/' +// }, +// ] +// }, +// { +// component: CNavGroup, +// name: 'Parachain', +// items: [ +// { +// component: CNavItem, +// name: 'Collator - 01', +// to: '/' +// }, +// { +// component: CNavItem, +// name: 'Collator - 02', +// to: '/' +// }, +// ] +// }, +// ] +// }, +// { +// component: CNavItem, +// name: 'Explorer', +// to: 'https://google.com', +// icon: <CIcon icon={cilMagnifyingGlass} customClassName="nav-icon" />, +// }, +// { +// component: CNavLink, +// name: 'Grafana', +// href: 'https://google.com', +// icon: <CIcon icon={cilMonitor} customClassName="nav-icon" />, +// }, +// ] -export default _nav +export default generateNav diff --git a/src/components/AppSidebar.js b/src/components/AppSidebar.js index e3998445..fd64a3b2 100644 --- a/src/components/AppSidebar.js +++ b/src/components/AppSidebar.js @@ -13,14 +13,21 @@ import porticoSVG from 'src/assets/brand/portico-logo-white.svg' import SimpleBar from 'simplebar-react' import 'simplebar/dist/simplebar.min.css' +import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' + // sidebar nav config -import navigation from '../_nav' +import generateNav from '../_nav' const AppSidebar = () => { const dispatch = useDispatch() const unfoldable = useSelector((state) => state.sidebarUnfoldable) const sidebarShow = useSelector((state) => state.sidebarShow) + const localStorageContext = useLocalStorageContext(); + const { networkStatus, network } = localStorageContext; + + const navigation = generateNav(network, networkStatus) + return ( <CSidebar position="fixed" From b8dceb6e9f1fecfd7207b2be781df53763c2152c Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 21:26:45 +0100 Subject: [PATCH 20/44] opens explorer links on new tab --- src/components/AppSidebarNav.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/AppSidebarNav.js b/src/components/AppSidebarNav.js index 774b2b12..c1449e5e 100644 --- a/src/components/AppSidebarNav.js +++ b/src/components/AppSidebarNav.js @@ -29,6 +29,7 @@ export const AppSidebarNav = ({ items }) => { const navItem = (item, index) => { const { component, name, badge, icon, ...rest } = item const Component = component + const newWindow = {...rest}.to && {...rest}.to.includes("polkadot") ? "_blank" : ""; return ( <Component {...(rest.to && @@ -37,6 +38,7 @@ export const AppSidebarNav = ({ items }) => { })} key={index} {...rest} + target={newWindow} disabled={networkStatus === 'OK' ? false : true} > {navLink(name, icon, badge)} From 22c7192d7d68f029b94799ebf01d85905a808aaf Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 22:19:35 +0100 Subject: [PATCH 21/44] fix --- src/_nav.js | 22 +++++++++++++++------- src/components/AppSidebarNav.js | 4 +++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/_nav.js b/src/_nav.js index 5596a13a..02fa4104 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -24,14 +24,22 @@ const generateNav = (networkInfo, networkStatus) => { to: `https://polkadot.js.org/apps/?rpc=${node.wsUri}#/explorer` } }) + + console.log("networkInfo", networkInfo) + + for (const para in networkInfo.paras) { + //each para is an an array of paranodes + paraCollators = networkInfo.paras[para].map(node => { + return { + component: CNavItem, + name: node.name, + to: `https://polkadot.js.org/apps/?rpc=${node.wsUri}#/explorer` + } + }) + + } + - paraCollators = networkInfo.paras[1].map(node => { - return { - component: CNavItem, - name: node.name, - to: `https://polkadot.js.org/apps/?rpc=${node.wsUri}#/explorer` - } - }) } diff --git a/src/components/AppSidebarNav.js b/src/components/AppSidebarNav.js index c1449e5e..4ac2b485 100644 --- a/src/components/AppSidebarNav.js +++ b/src/components/AppSidebarNav.js @@ -11,6 +11,8 @@ export const AppSidebarNav = ({ items }) => { const localStorageContext = useLocalStorageContext(); const { networkStatus } = localStorageContext; + console.log(networkStatus === 'OK') + const location = useLocation() const navLink = (name, icon, badge) => { return ( @@ -52,7 +54,7 @@ export const AppSidebarNav = ({ items }) => { <Component idx={String(index)} key={index} - toggler={navLink(name, icon)} + toggler={networkStatus === 'OK' ? navLink(name, icon): false} visible={location.pathname.startsWith(to)} {...rest} > From 311c2a514ae3dcc05e7d5bb9b6bd67a338dae193 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 22:51:16 +0100 Subject: [PATCH 22/44] spinner and remove arrow back on configurators --- .../ConfiguratorCollators.js | 6 +++--- .../ConfiguratorCoretime.js | 6 +++--- .../ConfiguratorRuntime.js | 8 ++++---- .../ConfiguratorRuntimeSpecs.js | 8 ++++---- src/views/configurator/Configurator.js | 20 +++++++++++-------- 5 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/views/configurator-collators/ConfiguratorCollators.js b/src/views/configurator-collators/ConfiguratorCollators.js index 1fc80d2f..2d3e6e71 100644 --- a/src/views/configurator-collators/ConfiguratorCollators.js +++ b/src/views/configurator-collators/ConfiguratorCollators.js @@ -16,12 +16,12 @@ const ConfiguratorCollators = () => { return ( <> <CRow className='d-flex flex-row'> - <CCol md={1}> + {/* <CCol md={1}> <Link to='/configure'> <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> </Link> </CCol> - <CCol md={11}> + <CCol md={11}> */} <p className='fs-5 fw-light'>Pick the number of collators to be deployed.</p> <CButtonToolbar className='mt-4' role="group" aria-label="Large button group"> <CButtonGroup role="group" aria-label="Third group"> @@ -37,7 +37,7 @@ const ConfiguratorCollators = () => { <CButton className='fw-light' active={collators === 10 ? true : false} onClick={() => handleClick(10)} color="info" variant="outline">10 Collators</CButton> </CButtonGroup> </CButtonToolbar> - </CCol> + {/* </CCol> */} </CRow> <CRow className='mt-4'> <Link className='text-center' to="/configure"> diff --git a/src/views/configurator-coretime/ConfiguratorCoretime.js b/src/views/configurator-coretime/ConfiguratorCoretime.js index 64d69ba3..7519e0a3 100644 --- a/src/views/configurator-coretime/ConfiguratorCoretime.js +++ b/src/views/configurator-coretime/ConfiguratorCoretime.js @@ -48,12 +48,12 @@ const ConfiguratorCoretime = () => { return ( <CForm className="needs-validation" noValidate onSubmit={handleSubmit} validated={validated}> <CRow className='d-flex flex-row'> - <CCol md={1}> + {/* <CCol md={1}> <Link to='/configure'> <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> </Link> </CCol> - <CCol md={11}> + <CCol md={11}> */} <CRow className='mb-3'> <p>In order to configure your Coretime needs, you need to select: <strong>Amount</strong> and <strong>Frequency</strong> of validation.</p> <p><strong>Amount</strong> dictates how many blocks of your parachain you want to pre-configure to be validated by the Relay Chain. For the purposes of this MVP the cap is 10_000 blocks.</p> @@ -98,7 +98,7 @@ const ConfiguratorCoretime = () => { /> </CCol> </CRow> - </CCol> + {/* </CCol> */} </CRow> <CRow className='mt-4'> <CCol className='d-flex justify-content-center'> diff --git a/src/views/configurator-runtime/ConfiguratorRuntime.js b/src/views/configurator-runtime/ConfiguratorRuntime.js index 891dd5fa..a2a9a1db 100644 --- a/src/views/configurator-runtime/ConfiguratorRuntime.js +++ b/src/views/configurator-runtime/ConfiguratorRuntime.js @@ -20,12 +20,12 @@ const ConfiguratorRuntime = () => { return ( <> <CRow> - <CCol md={1}> + {/* <CCol md={1}> <Link to='/configure'> <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> </Link> - </CCol> - <CCol md={11}> + </CCol> */} + {/* <CCol md={11}> */} <CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 4 }}> {runtimes.map(runtimeInfo => { return ( @@ -49,7 +49,7 @@ const ConfiguratorRuntime = () => { ) })} </CRow> - </CCol> + {/* </CCol> */} </CRow> <CRow className='mt-4'> <Link className='text-center' to="/configure/runtime-specs"> diff --git a/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js b/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js index 37d9f5c4..49dd069d 100644 --- a/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js +++ b/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js @@ -79,12 +79,12 @@ const handleTokenSymbolChange = (event, max, setter) => { return ( <CForm className="needs-validation" noValidate onSubmit={handleSubmit} validated={validated}> <CRow className='d-flex flex-row'> - <CCol md={1}> + {/* <CCol md={1}> <Link to='/configure'> <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> </Link> - </CCol> - <CCol md={11}> + </CCol> */} + {/* <CCol md={11}> */} <CRow className='mb-3'> <p>In order to configure your Coretime needs, you need to select: <strong>Amount</strong> and <strong>Frequency</strong> of validation.</p> <p><strong>Amount</strong> dictates how many blocks of your parachain you want to pre-configure to be validated by the Relay Chain. For the purposes of this MVP the cap is 10_000 blocks.</p> @@ -163,7 +163,7 @@ const handleTokenSymbolChange = (event, max, setter) => { /> </CCol> </CRow> - </CCol> + {/* </CCol> */} </CRow> <CRow className='mt-4'> <CCol className='d-flex justify-content-center'> diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index 3933eb7e..dd951de9 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -1,6 +1,6 @@ import {React, useState, useCallback, useEffect} from 'react' -import { CContainer, CCol, CRow, CCard, CCardBody, CCardText, CCardTitle, CAvatar, CButton } from '@coreui/react' -import {Link} from 'react-router-dom' +import { CContainer, CCol, CRow, CCard, CCardBody, CCardText, CCardTitle, CAvatar, CButton, CSpinner } from '@coreui/react' +import {Link, useNavigate} from 'react-router-dom' import {cilArrowCircleRight} from '@coreui/icons' import CIcon from '@coreui/icons-react' @@ -14,19 +14,22 @@ const Configurator = () => { const [formStatus, setStateStatus] = useState({executing: '', status: '', message: ''}); const configurationContext = useConfiguratorFormContext(); const localStorageContext = useLocalStorageContext(); - const [ready, setReady] = useState(true); + const [ready, setReady] = useState(false); const {collators, runtime, coretime } = configurationContext; // const {setCollators, setRuntime, setCoretime } = configurationContext; + const navigate = useNavigate() + useEffect(() => { // This function will run after every render (initial render + updates) - if (collators && runtime && coretime) { + if (collators && runtime.template && coretime.amount && coretime.every) { setReady(true) } - }, [collators, runtime, coretime]); - - + if(formStatus.executing === 'success') { + navigate("/dashboard") + } + }, [collators, runtime, coretime, formStatus]); const handleSubmit = useCallback(() => { submit({setStateStatus,localStorageContext, configurationContext }) @@ -102,13 +105,14 @@ const Configurator = () => { <CRow className="g-0 p-3 col-md-10"> <CButton onClick={() => handleSubmit()} - disabled={!ready} + disabled={!ready || formStatus.executing === 'executing' || formStatus.status === 'success'} className="col-3 mx-auto" color={ready ? "success" : "danger"} size="lg" variant="outline" style={{"fontWeight":"200"}} > Deploy + { formStatus.executing === 'executing' && <CSpinner component="span" className='ms-3' size="sm" aria-hidden="true" /> } </CButton> </CRow> </CContainer> From 51cdb642fdc5371179987544afde82c2639d3904 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 22:55:25 +0100 Subject: [PATCH 23/44] sort collators by name --- src/_nav.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/_nav.js b/src/_nav.js index 02fa4104..a4fe8266 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -35,11 +35,8 @@ const generateNav = (networkInfo, networkStatus) => { name: node.name, to: `https://polkadot.js.org/apps/?rpc=${node.wsUri}#/explorer` } - }) - + }).sort((node1, node2) => Number(node1.name.split("-")[2]) - Number(node2.name.split("-")[2])) } - - } From 67aa9b2433c732d042456ebad3f3213f5edcc19d Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 22:56:53 +0100 Subject: [PATCH 24/44] cleanup --- src/_nav.js | 84 +---------------------------------------------------- 1 file changed, 1 insertion(+), 83 deletions(-) diff --git a/src/_nav.js b/src/_nav.js index a4fe8266..bdf8eae5 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -3,9 +3,7 @@ import CIcon from '@coreui/icons-react' import { cilSpeedometer, cilWallet, - cilMemory, cilMagnifyingGlass, - cilMonitor, cilCog } from '@coreui/icons' import { CNavGroup, CNavItem, CNavTitle, CNavLink } from '@coreui/react' @@ -65,7 +63,7 @@ const generateNav = (networkInfo, networkStatus) => { component: CNavItem, name: 'Runtime Upgrades', to: '/runtime-upgrade', - icon: <CIcon icon={cilMemory} customClassName="nav-icon" />, + icon: <CIcon icon={cilCog} customClassName="nav-icon" />, }, { component: CNavGroup, @@ -90,84 +88,4 @@ const generateNav = (networkInfo, networkStatus) => { } -// const _nav = [ -// { -// component: CNavTitle, -// name: "Account" -// }, -// { -// component: CNavTitle, -// name: 'Current Deployment', -// }, -// { -// component: CNavItem, -// name: 'Dashboard', -// to: '/dashboard', -// icon: <CIcon icon={cilSpeedometer} customClassName="nav-icon" />, -// }, -// { -// component: CNavItem, -// name: 'Coretime Credits', -// to: '/coretime', -// icon: <CIcon icon={cilWallet} customClassName="nav-icon" />, -// }, -// { -// component: CNavItem, -// name: 'Runtime Upgrades', -// to: '/runtime-upgrade', -// icon: <CIcon icon={cilMemory} customClassName="nav-icon" />, -// }, -// { -// component: CNavGroup, -// name: 'Explorer', -// icon: <CIcon icon={cilCog} customClassName="nav-icon" />, -// items: [ -// { -// component: CNavGroup, -// name: 'Relay Chain', -// items: [ -// { -// component: CNavItem, -// name: 'Validator - 01', -// to: '/' -// }, -// { -// component: CNavItem, -// name: 'Validator - 02', -// to: '/' -// }, -// ] -// }, -// { -// component: CNavGroup, -// name: 'Parachain', -// items: [ -// { -// component: CNavItem, -// name: 'Collator - 01', -// to: '/' -// }, -// { -// component: CNavItem, -// name: 'Collator - 02', -// to: '/' -// }, -// ] -// }, -// ] -// }, -// { -// component: CNavItem, -// name: 'Explorer', -// to: 'https://google.com', -// icon: <CIcon icon={cilMagnifyingGlass} customClassName="nav-icon" />, -// }, -// { -// component: CNavLink, -// name: 'Grafana', -// href: 'https://google.com', -// icon: <CIcon icon={cilMonitor} customClassName="nav-icon" />, -// }, -// ] - export default generateNav From d08b8c38e52495b1a079bdfea940ded0e26ef486 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 22:57:25 +0100 Subject: [PATCH 25/44] more cleanup --- src/components/AppSidebarNav.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/AppSidebarNav.js b/src/components/AppSidebarNav.js index 4ac2b485..ddaed3b0 100644 --- a/src/components/AppSidebarNav.js +++ b/src/components/AppSidebarNav.js @@ -11,8 +11,6 @@ export const AppSidebarNav = ({ items }) => { const localStorageContext = useLocalStorageContext(); const { networkStatus } = localStorageContext; - console.log(networkStatus === 'OK') - const location = useLocation() const navLink = (name, icon, badge) => { return ( From efccc2ffcea1d1f368b274adcf79b4a67cb7cdca Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Sun, 3 Dec 2023 23:09:43 +0100 Subject: [PATCH 26/44] one last cleanup --- src/_nav.js | 2 -- .../ConfiguratorCollators.js | 11 +------ .../ConfiguratorCoretime.js | 11 +------ .../ConfiguratorRuntime.js | 9 +----- .../ConfiguratorRuntimeSpecs.js | 32 +++++-------------- 5 files changed, 11 insertions(+), 54 deletions(-) diff --git a/src/_nav.js b/src/_nav.js index bdf8eae5..c602fa4c 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -23,8 +23,6 @@ const generateNav = (networkInfo, networkStatus) => { } }) - console.log("networkInfo", networkInfo) - for (const para in networkInfo.paras) { //each para is an an array of paranodes paraCollators = networkInfo.paras[para].map(node => { diff --git a/src/views/configurator-collators/ConfiguratorCollators.js b/src/views/configurator-collators/ConfiguratorCollators.js index 2d3e6e71..4abf0fbe 100644 --- a/src/views/configurator-collators/ConfiguratorCollators.js +++ b/src/views/configurator-collators/ConfiguratorCollators.js @@ -1,9 +1,7 @@ import React from 'react' import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext' import {Link} from 'react-router-dom' -import CIcon from '@coreui/icons-react' -import {cilArrowLeft} from '@coreui/icons' -import { CRow, CCol, CButtonToolbar, CButtonGroup, CButton} from '@coreui/react' +import { CRow, CButtonToolbar, CButtonGroup, CButton} from '@coreui/react' const ConfiguratorCollators = () => { @@ -16,12 +14,6 @@ const ConfiguratorCollators = () => { return ( <> <CRow className='d-flex flex-row'> - {/* <CCol md={1}> - <Link to='/configure'> - <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> - </Link> - </CCol> - <CCol md={11}> */} <p className='fs-5 fw-light'>Pick the number of collators to be deployed.</p> <CButtonToolbar className='mt-4' role="group" aria-label="Large button group"> <CButtonGroup role="group" aria-label="Third group"> @@ -37,7 +29,6 @@ const ConfiguratorCollators = () => { <CButton className='fw-light' active={collators === 10 ? true : false} onClick={() => handleClick(10)} color="info" variant="outline">10 Collators</CButton> </CButtonGroup> </CButtonToolbar> - {/* </CCol> */} </CRow> <CRow className='mt-4'> <Link className='text-center' to="/configure"> diff --git a/src/views/configurator-coretime/ConfiguratorCoretime.js b/src/views/configurator-coretime/ConfiguratorCoretime.js index 7519e0a3..d7eb8a7f 100644 --- a/src/views/configurator-coretime/ConfiguratorCoretime.js +++ b/src/views/configurator-coretime/ConfiguratorCoretime.js @@ -1,8 +1,6 @@ import React, {useState} from 'react' import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext' -import {Link, useNavigate} from 'react-router-dom' -import CIcon from '@coreui/icons-react' -import {cilArrowLeft} from '@coreui/icons' +import {useNavigate} from 'react-router-dom' import { CFormInput, CRow, CCol, CButton, CForm } from '@coreui/react' const ConfiguratorCoretime = () => { @@ -48,12 +46,6 @@ const ConfiguratorCoretime = () => { return ( <CForm className="needs-validation" noValidate onSubmit={handleSubmit} validated={validated}> <CRow className='d-flex flex-row'> - {/* <CCol md={1}> - <Link to='/configure'> - <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> - </Link> - </CCol> - <CCol md={11}> */} <CRow className='mb-3'> <p>In order to configure your Coretime needs, you need to select: <strong>Amount</strong> and <strong>Frequency</strong> of validation.</p> <p><strong>Amount</strong> dictates how many blocks of your parachain you want to pre-configure to be validated by the Relay Chain. For the purposes of this MVP the cap is 10_000 blocks.</p> @@ -98,7 +90,6 @@ const ConfiguratorCoretime = () => { /> </CCol> </CRow> - {/* </CCol> */} </CRow> <CRow className='mt-4'> <CCol className='d-flex justify-content-center'> diff --git a/src/views/configurator-runtime/ConfiguratorRuntime.js b/src/views/configurator-runtime/ConfiguratorRuntime.js index a2a9a1db..e104552e 100644 --- a/src/views/configurator-runtime/ConfiguratorRuntime.js +++ b/src/views/configurator-runtime/ConfiguratorRuntime.js @@ -6,7 +6,7 @@ import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext import { CButton, CCard, CCardImage, CCardBody, CCardFooter, CCardTitle, CCardText, CRow, CCol} from '@coreui/react' import CIcon from '@coreui/icons-react' -import {cibGithub, cilArrowLeft} from '@coreui/icons' +import {cibGithub} from '@coreui/icons' const ConfiguratorRuntime = () => { @@ -20,12 +20,6 @@ const ConfiguratorRuntime = () => { return ( <> <CRow> - {/* <CCol md={1}> - <Link to='/configure'> - <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> - </Link> - </CCol> */} - {/* <CCol md={11}> */} <CRow xs={{ cols: 1, gutter: 4 }} md={{ cols: 4 }}> {runtimes.map(runtimeInfo => { return ( @@ -49,7 +43,6 @@ const ConfiguratorRuntime = () => { ) })} </CRow> - {/* </CCol> */} </CRow> <CRow className='mt-4'> <Link className='text-center' to="/configure/runtime-specs"> diff --git a/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js b/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js index 49dd069d..9919e208 100644 --- a/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js +++ b/src/views/configurator-runtime/ConfiguratorRuntimeSpecs.js @@ -1,12 +1,8 @@ import React,{useState} from 'react' -import runtimes from './runtime.json' -import {Link} from 'react-router-dom' import { useConfiguratorFormContext } from 'src/contexts/ConfiguratorFormContext' import { useNavigate } from 'react-router-dom'; -import { CButton, CCard, CCardImage, CCardBody, CCardFooter, CCardTitle, CCardText, CRow, CCol,CFormInput,CForm} from '@coreui/react' -import CIcon from '@coreui/icons-react' -import {cibGithub, cilArrowLeft} from '@coreui/icons' +import { CButton, CRow, CCol,CFormInput,CForm} from '@coreui/react' const ConfiguratorRuntimeSpecs = () => { const [ss58Valid, setSs58Valid] = useState(true) @@ -19,8 +15,6 @@ const ConfiguratorRuntimeSpecs = () => { const navigate = useNavigate() - - const handleAmountChange = (event, max, setter, path) => { const amount = Math.floor(Number(event.target.valueAsNumber)); if (event.target.valueAsNumber > max) { @@ -79,21 +73,12 @@ const handleTokenSymbolChange = (event, max, setter) => { return ( <CForm className="needs-validation" noValidate onSubmit={handleSubmit} validated={validated}> <CRow className='d-flex flex-row'> - {/* <CCol md={1}> - <Link to='/configure'> - <CIcon size="lg" className="text-secondary" icon={cilArrowLeft}/> - </Link> - </CCol> */} - {/* <CCol md={11}> */} <CRow className='mb-3'> - <p>In order to configure your Coretime needs, you need to select: <strong>Amount</strong> and <strong>Frequency</strong> of validation.</p> - <p><strong>Amount</strong> dictates how many blocks of your parachain you want to pre-configure to be validated by the Relay Chain. For the purposes of this MVP the cap is 10_000 blocks.</p> - <p><strong>Frequency</strong> configures every how many blocks of the Relay Chain you wish to submit a Parachain Block.</p> - <p className='mt-2'><strong>Example</strong>. Objective is to have one thousand Parachain blocks validated by the Relay Chain, and this to happen every 10 Relay Chain blocks. Configuration would look as follows:</p> - <ul className='ms-4'> - <li>Amount: 1_000</li> - <li>Frequency: 10</li> - </ul> + <p>The following is a basic configuration of your runtime parameters.</p> + <p><strong>ParaId</strong> refers to the ID your Parachain will have on the Relaychain.</p> + <p><strong>ss58 Format</strong> is the prefix allowing to identify an address belonging to this parachain.</p> + <p><strong>tokenSymbol</strong> refers to the ticker of the token of this parachain.</p> + <p><strong>Decimals</strong> is the amount of decimals for the token of this parachain.</p> </CRow> <CRow> <CCol md={7}> @@ -108,7 +93,7 @@ const handleTokenSymbolChange = (event, max, setter) => { aria-label="lg input example" required feedbackInvalid={paraIdValid ? "" : "Please make it an integer below 10_000"} - label="ParaId: Parachain Id" + label="ParaId" /> </CCol> </CRow> @@ -153,7 +138,7 @@ const handleTokenSymbolChange = (event, max, setter) => { step={1} onChange={(event) => handleAmountChange(event, 1000, setDecimalsValid, 'specs.decimals')} invalid={!decimalsValid} - label="Decimals: Amount of decimals for the token" + label="Decimals" type="number" value={runtime?.specs?.decimals ? runtime.specs.decimals : ""} size="lg" @@ -163,7 +148,6 @@ const handleTokenSymbolChange = (event, max, setter) => { /> </CCol> </CRow> - {/* </CCol> */} </CRow> <CRow className='mt-4'> <CCol className='d-flex justify-content-center'> From b36d76b62d4124f03e1de6778a67c76642596909 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Mon, 4 Dec 2023 11:17:09 +0100 Subject: [PATCH 27/44] fixed sort --- src/_nav.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_nav.js b/src/_nav.js index c602fa4c..c7b0948b 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -31,7 +31,7 @@ const generateNav = (networkInfo, networkStatus) => { name: node.name, to: `https://polkadot.js.org/apps/?rpc=${node.wsUri}#/explorer` } - }).sort((node1, node2) => Number(node1.name.split("-")[2]) - Number(node2.name.split("-")[2])) + }).sort((node1, node2) => node1-node2) } } From 80f731c0bd51d9a5ad500f82a4db4c440b9a4bf8 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Mon, 4 Dec 2023 19:49:40 +0100 Subject: [PATCH 28/44] hooked dummy polkadot-js --- package-lock.json | 737 +++++++++++++++++- package.json | 1 + src/App.js | 24 +- src/views/dashboard/Dashboard.js | 8 +- src/views/dashboard/polkadot-js-dummy-para.js | 63 ++ src/views/dashboard/polkadot-js-dummy-rc.js | 64 ++ 6 files changed, 882 insertions(+), 15 deletions(-) create mode 100644 src/views/dashboard/polkadot-js-dummy-para.js create mode 100644 src/views/dashboard/polkadot-js-dummy-rc.js diff --git a/package-lock.json b/package-lock.json index 00ca0ecd..e0c2807b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@coreui/react": "^4.9.0-rc.0", "@coreui/react-chartjs": "^2.1.3", "@coreui/utils": "^2.0.2", + "@polkadot/api": "^10.11.1", "chart.js": "^3.9.1", "classnames": "^2.3.2", "core-js": "^3.31.0", @@ -3869,6 +3870,28 @@ "node": ">=4.0" } }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3951,6 +3974,514 @@ } } }, + "node_modules/@polkadot/api": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-10.11.1.tgz", + "integrity": "sha512-WEgUYvY90AHX9drmsvWQ4DDuqlE7h4x3f28K5eOoJF4dQ5AkWsFogxwJ4TH57POWLfyi8AIn6/f1vsqPtReDhA==", + "dependencies": { + "@polkadot/api-augment": "10.11.1", + "@polkadot/api-base": "10.11.1", + "@polkadot/api-derive": "10.11.1", + "@polkadot/keyring": "^12.6.1", + "@polkadot/rpc-augment": "10.11.1", + "@polkadot/rpc-core": "10.11.1", + "@polkadot/rpc-provider": "10.11.1", + "@polkadot/types": "10.11.1", + "@polkadot/types-augment": "10.11.1", + "@polkadot/types-codec": "10.11.1", + "@polkadot/types-create": "10.11.1", + "@polkadot/types-known": "10.11.1", + "@polkadot/util": "^12.6.1", + "@polkadot/util-crypto": "^12.6.1", + "eventemitter3": "^5.0.1", + "rxjs": "^7.8.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-augment": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-10.11.1.tgz", + "integrity": "sha512-9Sk7fi6wzvxAoxvGJPcMt0hU4WzuIAlBy4Rng6WPiS6Ed0HJLr1dkZaqFFmV5my2pb3tu//1JGYkt+MUVB0Kqw==", + "dependencies": { + "@polkadot/api-base": "10.11.1", + "@polkadot/rpc-augment": "10.11.1", + "@polkadot/types": "10.11.1", + "@polkadot/types-augment": "10.11.1", + "@polkadot/types-codec": "10.11.1", + "@polkadot/util": "^12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-base": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/api-base/-/api-base-10.11.1.tgz", + "integrity": "sha512-A645Hj9bGtq0EOEWcwTaGoD40vp8/ih1suwinl5il8Psg+bdDmzodnVH5Jhuwe1dNKOuXuvxZvOmbYUPWyIqyg==", + "dependencies": { + "@polkadot/rpc-core": "10.11.1", + "@polkadot/types": "10.11.1", + "@polkadot/util": "^12.6.1", + "rxjs": "^7.8.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api-derive": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-10.11.1.tgz", + "integrity": "sha512-i48okJr0l1IrFTPa9KVkoJnDL2EHKExR6XC0Z7I9+kW9noxYWqo0tIoi5s1bNVD475xWK/rUjT7qHxiDbPaCUQ==", + "dependencies": { + "@polkadot/api": "10.11.1", + "@polkadot/api-augment": "10.11.1", + "@polkadot/api-base": "10.11.1", + "@polkadot/rpc-core": "10.11.1", + "@polkadot/types": "10.11.1", + "@polkadot/types-codec": "10.11.1", + "@polkadot/util": "^12.6.1", + "@polkadot/util-crypto": "^12.6.1", + "rxjs": "^7.8.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/api/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "node_modules/@polkadot/keyring": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-12.6.1.tgz", + "integrity": "sha512-cicTctZr5Jy5vgNT2FsNiKoTZnz6zQkgDoIYv79NI+p1Fhwc9C+DN/iMCnk3Cm9vR2gSAd2fSV+Y5iKVDhAmUw==", + "dependencies": { + "@polkadot/util": "12.6.1", + "@polkadot/util-crypto": "12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "12.6.1", + "@polkadot/util-crypto": "12.6.1" + } + }, + "node_modules/@polkadot/networks": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-12.6.1.tgz", + "integrity": "sha512-pzyirxTYAnsx+6kyLYcUk26e4TLz3cX6p2KhTgAVW77YnpGX5VTKTbYykyXC8fXFd/migeQsLaa2raFN47mwoA==", + "dependencies": { + "@polkadot/util": "12.6.1", + "@substrate/ss58-registry": "^1.44.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-augment": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-10.11.1.tgz", + "integrity": "sha512-wrtxHnEwqS3b1GuZ3sA1pzLuUjjLnW4FPawOklONRcIuKbGmFuvu7QvEIHmxBV1FAS/fs8gbvp8ImKWUPnT93Q==", + "dependencies": { + "@polkadot/rpc-core": "10.11.1", + "@polkadot/types": "10.11.1", + "@polkadot/types-codec": "10.11.1", + "@polkadot/util": "^12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-core": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-10.11.1.tgz", + "integrity": "sha512-3l4l+zL7MDWzQx3WnaieXXUKsbeA1Miu4wsje5trYJEE+hm+nMW8h7fiFKfYzXBi7ty/wMS+S7BfQPTrDkYHxA==", + "dependencies": { + "@polkadot/rpc-augment": "10.11.1", + "@polkadot/rpc-provider": "10.11.1", + "@polkadot/types": "10.11.1", + "@polkadot/util": "^12.6.1", + "rxjs": "^7.8.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/rpc-provider": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-10.11.1.tgz", + "integrity": "sha512-86aDUOnaG42si0jSOAgn6Fs3F3rz57x+iNBK1JpM0PLL2XvmPuoMZL5dZwzqSIey3nVdGJqRYfnFquWuyQpnOQ==", + "dependencies": { + "@polkadot/keyring": "^12.6.1", + "@polkadot/types": "10.11.1", + "@polkadot/types-support": "10.11.1", + "@polkadot/util": "^12.6.1", + "@polkadot/util-crypto": "^12.6.1", + "@polkadot/x-fetch": "^12.6.1", + "@polkadot/x-global": "^12.6.1", + "@polkadot/x-ws": "^12.6.1", + "eventemitter3": "^5.0.1", + "mock-socket": "^9.3.1", + "nock": "^13.3.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@substrate/connect": "0.7.35" + } + }, + "node_modules/@polkadot/rpc-provider/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "node_modules/@polkadot/types": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-10.11.1.tgz", + "integrity": "sha512-4uKnzW2GZqNA5qRZpTPJ7z+G/ARTvXI89etv9xXXVttUdfTaYZsMf4rMuMThOAE/mAUn70LoH0JKthZLwzVgNQ==", + "dependencies": { + "@polkadot/keyring": "^12.6.1", + "@polkadot/types-augment": "10.11.1", + "@polkadot/types-codec": "10.11.1", + "@polkadot/types-create": "10.11.1", + "@polkadot/util": "^12.6.1", + "@polkadot/util-crypto": "^12.6.1", + "rxjs": "^7.8.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-augment": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-10.11.1.tgz", + "integrity": "sha512-Exd5mMCuSOXXz73iWqy8ocScWTrwAPqHz0Kxpz5OWlAu+5usipMuhjoeaZA803FHQntZh9lHUN31fuc50Exhew==", + "dependencies": { + "@polkadot/types": "10.11.1", + "@polkadot/types-codec": "10.11.1", + "@polkadot/util": "^12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-codec": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-10.11.1.tgz", + "integrity": "sha512-B9Fu2hq3cRpJpGPcgfZ8Qi1OSX9u82J46adlbIG95ktoA+70eZ83VS3Zvtt9ACsdLVGETCJfDjSO25XptjhZKQ==", + "dependencies": { + "@polkadot/util": "^12.6.1", + "@polkadot/x-bigint": "^12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-create": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-10.11.1.tgz", + "integrity": "sha512-oeaI185F3XeWSz9/fe//qZ0KsQyE6C6c13WuOa+5cX/Yuz7cSAXawrhl58HRaU+fueaE/ijEHLcuK1sdM6e1JQ==", + "dependencies": { + "@polkadot/types-codec": "10.11.1", + "@polkadot/util": "^12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-known": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-10.11.1.tgz", + "integrity": "sha512-BPHI7EbdRaznZR4RVVrQC5epyxL6caJ5dkluZP6rRwx7VmQK0FTGIwgh3UP724mzQhM8rT77MD3h2ftnq1cteg==", + "dependencies": { + "@polkadot/networks": "^12.6.1", + "@polkadot/types": "10.11.1", + "@polkadot/types-codec": "10.11.1", + "@polkadot/types-create": "10.11.1", + "@polkadot/util": "^12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/types-support": { + "version": "10.11.1", + "resolved": "https://registry.npmjs.org/@polkadot/types-support/-/types-support-10.11.1.tgz", + "integrity": "sha512-eCvWjdpELsHvXiTq201DdbIeOIaEr53zTD7HqC2wR/Z1bkQuw79Z+CyIU4sp79GL1vZ1PxS7vUH9M3FKNaTl1Q==", + "dependencies": { + "@polkadot/util": "^12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-12.6.1.tgz", + "integrity": "sha512-10ra3VfXtK8ZSnWI7zjhvRrhupg3rd4iFC3zCaXmRpOU+AmfIoCFVEmuUuC66gyXiz2/g6k5E6j0lWQCOProSQ==", + "dependencies": { + "@polkadot/x-bigint": "12.6.1", + "@polkadot/x-global": "12.6.1", + "@polkadot/x-textdecoder": "12.6.1", + "@polkadot/x-textencoder": "12.6.1", + "@types/bn.js": "^5.1.5", + "bn.js": "^5.2.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/util-crypto": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-12.6.1.tgz", + "integrity": "sha512-2ezWFLmdgeDXqB9NAUdgpp3s2rQztNrZLY+y0SJYNOG4ch+PyodTW/qSksnOrVGVdRhZ5OESRE9xvo9LYV5UAw==", + "dependencies": { + "@noble/curves": "^1.2.0", + "@noble/hashes": "^1.3.2", + "@polkadot/networks": "12.6.1", + "@polkadot/util": "12.6.1", + "@polkadot/wasm-crypto": "^7.3.1", + "@polkadot/wasm-util": "^7.3.1", + "@polkadot/x-bigint": "12.6.1", + "@polkadot/x-randomvalues": "12.6.1", + "@scure/base": "^1.1.3", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "12.6.1" + } + }, + "node_modules/@polkadot/wasm-bridge": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.3.1.tgz", + "integrity": "sha512-wPtDkGaOQx5BUIYP+kJv5aV3BnCQ+HXr36khGKYrRQAMBrG+ybCNPOTVXDQnSbraPQRSw7fSIJmiQpEmFsIz0w==", + "dependencies": { + "@polkadot/wasm-util": "7.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*", + "@polkadot/x-randomvalues": "*" + } + }, + "node_modules/@polkadot/wasm-crypto": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.3.1.tgz", + "integrity": "sha512-BSK0YyCN4ohjtwbiHG71fgf+7ufgfLrHxjn7pKsvXhyeiEVuDhbDreNcpUf3eGOJ5tNk75aSbKGF4a3EJGIiNA==", + "dependencies": { + "@polkadot/wasm-bridge": "7.3.1", + "@polkadot/wasm-crypto-asmjs": "7.3.1", + "@polkadot/wasm-crypto-init": "7.3.1", + "@polkadot/wasm-crypto-wasm": "7.3.1", + "@polkadot/wasm-util": "7.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*", + "@polkadot/x-randomvalues": "*" + } + }, + "node_modules/@polkadot/wasm-crypto-asmjs": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.3.1.tgz", + "integrity": "sha512-pTUOCIP0nUc4tjzdG1vtEBztKEWde4DBEZm7NaxBLvwNUxsbYhLKYvuhASEyEIz0ZyE4rOBWEmRF4Buic8oO+g==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*" + } + }, + "node_modules/@polkadot/wasm-crypto-init": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.3.1.tgz", + "integrity": "sha512-Fx15ItLcxCe7uJCWZVXhFbsrXqHUKAp9KGYQFKBRK7r1C2va4Y7qnirjwkxoMHQcunusLe2KdbrD+YJuzh4wlA==", + "dependencies": { + "@polkadot/wasm-bridge": "7.3.1", + "@polkadot/wasm-crypto-asmjs": "7.3.1", + "@polkadot/wasm-crypto-wasm": "7.3.1", + "@polkadot/wasm-util": "7.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*", + "@polkadot/x-randomvalues": "*" + } + }, + "node_modules/@polkadot/wasm-crypto-wasm": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.3.1.tgz", + "integrity": "sha512-hBMRwrBLCfVsFHSdnwwIxEPshoZdW/dHehYRxMSpUdmqOxtD1gnjocXGE1KZUYGX675+EFuR+Ch6OoTKFJxwTA==", + "dependencies": { + "@polkadot/wasm-util": "7.3.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*" + } + }, + "node_modules/@polkadot/wasm-util": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.3.1.tgz", + "integrity": "sha512-0m6ozYwBrJgnGl6QvS37ZiGRu4FFPPEtMYEVssfo1Tz4skHJlByWaHWhRNoNCVFAKiGEBu+rfx5HAQMAhoPkvg==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "*" + } + }, + "node_modules/@polkadot/x-bigint": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-12.6.1.tgz", + "integrity": "sha512-YlABeVIlgYQZJ4ZpW/+akFGGxw5jMGt4g5vaP7EumlORGneJHzzWJYDmI5v2y7j1zvC9ofOle7z4tRmtN/QDew==", + "dependencies": { + "@polkadot/x-global": "12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-fetch": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-12.6.1.tgz", + "integrity": "sha512-iyBv0ecfCsqGSv26CPJk9vSoKtry/Fn7x549ysA4hlc9KboraMHxOHTpcNZYC/OdgvbFZl40zIXCY0SA1ai8aw==", + "dependencies": { + "@polkadot/x-global": "12.6.1", + "node-fetch": "^3.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-global": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-12.6.1.tgz", + "integrity": "sha512-w5t19HIdBPuyu7X/AiCyH2DsKqxBF0KpF4Ymolnx8PfcSIgnq9ZOmgs74McPR6FgEmeEkr9uNKujZrsfURi1ug==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-randomvalues": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-12.6.1.tgz", + "integrity": "sha512-1uVKlfYYbgIgGV5v1Dgn960cGovenWm5pmg+aTMeUGXVYiJwRD2zOpLyC1i/tP454iA74j74pmWb8Nkn0tJZUQ==", + "dependencies": { + "@polkadot/x-global": "12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@polkadot/util": "12.6.1", + "@polkadot/wasm-util": "*" + } + }, + "node_modules/@polkadot/x-textdecoder": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-12.6.1.tgz", + "integrity": "sha512-IasodJeV1f2Nr/VtA207+LXCQEqYcG8y9qB/EQcRsrEP58NbwwxM5Z2obV0lSjJOxRTJ4/OlhUwnLHwcbIp6+g==", + "dependencies": { + "@polkadot/x-global": "12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-textencoder": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-12.6.1.tgz", + "integrity": "sha512-sTq/+tXqBhGe01a1rjieSHFh3y935vuRgtahVgVJZnfqh5SmLPgSN5tTPxZWzyx7gHIfotle8laTJbJarv7V1A==", + "dependencies": { + "@polkadot/x-global": "12.6.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-ws": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-12.6.1.tgz", + "integrity": "sha512-fs9V+XekjJLpVLLwxnqq3llqSZu2T/b9brvld8anvzS/htDLPbi7+c5W3VGJ9Po8fS67IsU3HCt0Gu6F6mGrMA==", + "dependencies": { + "@polkadot/x-global": "12.6.1", + "tslib": "^2.6.2", + "ws": "^8.14.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polkadot/x-ws/node_modules/ws": { + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/@remix-run/router": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.13.1.tgz", @@ -4044,6 +4575,14 @@ "integrity": "sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA==", "dev": true }, + "node_modules/@scure/base": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.3.tgz", + "integrity": "sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -4068,6 +4607,28 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@substrate/connect": { + "version": "0.7.35", + "resolved": "https://registry.npmjs.org/@substrate/connect/-/connect-0.7.35.tgz", + "integrity": "sha512-Io8vkalbwaye+7yXfG1Nj52tOOoJln2bMlc7Q9Yy3vEWqZEVkgKmcPVzbwV0CWL3QD+KMPDA2Dnw/X7EdwgoLw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@substrate/connect-extension-protocol": "^1.0.1", + "smoldot": "2.0.7" + } + }, + "node_modules/@substrate/connect-extension-protocol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-1.0.1.tgz", + "integrity": "sha512-161JhCC1csjH3GE5mPLEd7HbWtwNSPJBg3p1Ksz9SFlTzj/bgEwudiRN2y5i0MoLGCIJRYKyKGMxVnd29PzNjg==", + "optional": true + }, + "node_modules/@substrate/ss58-registry": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.44.0.tgz", + "integrity": "sha512-7lQ/7mMCzVNSEfDS4BCqnRnKCFKpcOaPrxMeGTXHX1YQzM/m2BBHjbK2C3dJvjv7GYxMiaTq/HdWQj1xS6ss+A==" + }, "node_modules/@surma/rollup-plugin-off-main-thread": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", @@ -4463,6 +5024,14 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/bn.js": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", + "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", @@ -4678,7 +5247,6 @@ "version": "20.10.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.2.tgz", "integrity": "sha512-37MXfxkb0vuIlRKHNxwCkb60PNBpR94u4efQuN4JgIAm66zfCDXGSAFCef9XUWFovX2R1ok6Z7MHhtdVXXkkIw==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -6107,6 +6675,11 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -7309,6 +7882,14 @@ "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, "node_modules/data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -8889,6 +9470,28 @@ "bser": "2.1.1" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -9210,6 +9813,17 @@ "node": ">= 6" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -13139,6 +13753,11 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -13696,6 +14315,14 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mock-socket": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.3.1.tgz", + "integrity": "sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==", + "engines": { + "node": ">= 8" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -13779,6 +14406,54 @@ "tslib": "^2.0.3" } }, + "node_modules/nock": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.4.0.tgz", + "integrity": "sha512-W8NVHjO/LCTNA64yxAPHV/K47LpGYcVzgKd3Q0n6owhwvD0Dgoterc25R4rnZbckJEb6Loxz1f5QMuJpJnbSyQ==", + "dependencies": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "propagate": "^2.0.0" + }, + "engines": { + "node": ">= 10.13" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -15850,6 +16525,14 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "engines": { + "node": ">= 8" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -16717,6 +17400,14 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-array-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", @@ -17203,6 +17894,36 @@ "node": ">=8" } }, + "node_modules/smoldot": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-2.0.7.tgz", + "integrity": "sha512-VAOBqEen6vises36/zgrmAT1GWk2qE3X8AGnO7lmQFdskbKx8EovnwS22rtPAG+Y1Rk23/S22kDJUdPANyPkBA==", + "optional": true, + "dependencies": { + "ws": "^8.8.1" + } + }, + "node_modules/smoldot/node_modules/ws": { + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "optional": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -18285,8 +19006,7 @@ "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -18452,8 +19172,7 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", @@ -18723,6 +19442,14 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "engines": { + "node": ">= 8" + } + }, "node_modules/web-vitals": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.0.tgz", diff --git a/package.json b/package.json index f71f0331..90e89474 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@coreui/react": "^4.9.0-rc.0", "@coreui/react-chartjs": "^2.1.3", "@coreui/utils": "^2.0.2", + "@polkadot/api": "^10.11.1", "chart.js": "^3.9.1", "classnames": "^2.3.2", "core-js": "^3.31.0", diff --git a/src/App.js b/src/App.js index a3b730b8..0cb51d6c 100644 --- a/src/App.js +++ b/src/App.js @@ -2,6 +2,8 @@ import React, { Component, Suspense } from 'react' import { BrowserRouter, Route, Routes } from 'react-router-dom' import { LocalStorageContextProvider } from './contexts/LocalStorageContext' import { ConfiguratorFormContextProvider } from './contexts/ConfiguratorFormContext' +import { ApiConnectRC } from './views/dashboard/polkadot-js-dummy-rc' +import { ApiConnectPara } from './views/dashboard/polkadot-js-dummy-para' import './scss/style.scss' const loading = ( @@ -25,15 +27,19 @@ class App extends Component { <BrowserRouter> <LocalStorageContextProvider> <ConfiguratorFormContextProvider> - <Suspense fallback={loading}> - <Routes> - <Route exact path="/login" name="Login Page" element={<Login />} /> - <Route exact path="/register" name="Register Page" element={<Register />} /> - <Route exact path="/404" name="Page 404" element={<Page404 />} /> - <Route exact path="/500" name="Page 500" element={<Page500 />} /> - <Route path="*" name="Home" element={<DefaultLayout />} /> - </Routes> - </Suspense> + <ApiConnectRC> + <ApiConnectPara> + <Suspense fallback={loading}> + <Routes> + <Route exact path="/login" name="Login Page" element={<Login />} /> + <Route exact path="/register" name="Register Page" element={<Register />} /> + <Route exact path="/404" name="Page 404" element={<Page404 />} /> + <Route exact path="/500" name="Page 500" element={<Page500 />} /> + <Route path="*" name="Home" element={<DefaultLayout />} /> + </Routes> + </Suspense> + </ApiConnectPara> + </ApiConnectRC> </ConfiguratorFormContextProvider> </LocalStorageContextProvider> </BrowserRouter> diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js index e979a0c1..7fd1745e 100644 --- a/src/views/dashboard/Dashboard.js +++ b/src/views/dashboard/Dashboard.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, {useContext} from 'react' import { CAvatar, @@ -54,9 +54,15 @@ import avatar6 from 'src/assets/images/avatars/6.jpg' import WidgetsBrand from '../widgets/WidgetsBrand' import WidgetsDropdown from '../widgets/WidgetsDropdown' +//CONTEXT +import { useApiContextRC } from './polkadot-js-dummy-rc' + const Dashboard = () => { const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min) + const apiContextRC = useApiContextRC() + + const progressExample = [ { title: 'Visits', value: '29.703 Users', percent: 40, color: 'success' }, { title: 'Unique', value: '24.093 Users', percent: 20, color: 'info' }, diff --git a/src/views/dashboard/polkadot-js-dummy-para.js b/src/views/dashboard/polkadot-js-dummy-para.js new file mode 100644 index 00000000..1802d046 --- /dev/null +++ b/src/views/dashboard/polkadot-js-dummy-para.js @@ -0,0 +1,63 @@ +//this is just a dummy file to prepare for when the real api is connected +//it will use Rococo as a relay chain and rococo asset-hub as a parachain +//this one is for the Rococo-Relaychain + +//Dependencies + +import React, { createContext, useState, useEffect, useContext } from 'react'; +import { ApiPromise, WsProvider } from "@polkadot/api"; + +// const ROCOCO_RPC ='wss://rococo-rpc.polkadot.io' +const AH_ROCOCO_RPC ='wss://rococo-asset-hub-rpc.polkadot.io' + +const ApiContextPara = createContext(); + +export function ApiConnectPara ({ children }) { + const [api, setConnectedApi] = useState(null); + const [isReady, setIsReady] = useState(false); + const [provider, setProvider] = useState(null); + + // by default this connects to Polkadot + useEffect(() =>{ + const startApi = async () => { + await selectNetworkRPC(AH_ROCOCO_RPC); + } + if(!provider){ + startApi(); + } + }) + + //CONNECTS TO RPC + const selectNetworkRPC = async (rpc) => { + + //If user changes network it will first disconnect the current ws connection. + if(provider){ + await provider.disconnect(); + } + + if(rpc){ + const newProvider = new WsProvider(rpc); + setProvider(newProvider) + const _api = await ApiPromise.create({ provider: newProvider }); + setIsReady(_api._isReady); + setConnectedApi(_api) + } + }; + + //State cleaner to be used when changing networks + const cleanupState = () => { + setIsReady(false); + setConnectedApi(null); + setProvider(null) + } + + return ( + <ApiContextPara.Provider value={{api, isReady}}> + { children } + </ApiContextPara.Provider> + ); +}; + +export function useApiContextPara () { + return useContext(ApiContextPara) +} \ No newline at end of file diff --git a/src/views/dashboard/polkadot-js-dummy-rc.js b/src/views/dashboard/polkadot-js-dummy-rc.js new file mode 100644 index 00000000..6d9060db --- /dev/null +++ b/src/views/dashboard/polkadot-js-dummy-rc.js @@ -0,0 +1,64 @@ +//this is just a dummy file to prepare for when the real api is connected +//it will use Rococo as a relay chain and rococo asset-hub as a parachain +//this one is for the Rococo-Relaychain + +//Dependencies + +import React, { createContext, useState, useEffect, useContext } from 'react'; +import { ApiPromise, WsProvider } from "@polkadot/api"; + +const ROCOCO_RPC ='wss://rococo-rpc.polkadot.io' +// const AH_ROCOCO_RPC ='wss://rococo-asset-hub-rpc.polkadot.io' + +const ApiContextRC = createContext(); + +export function ApiConnectRC ({ children }) { + const [api, setConnectedApi] = useState(null); + const [isReady, setIsReady] = useState(false); + const [provider, setProvider] = useState(null); + + // by default this connects to Polkadot + useEffect(() =>{ + const startApi = async () => { + console.log('im running') + await selectNetworkRPC(ROCOCO_RPC); + } + if(!provider){ + startApi(); + } + }) + + //CONNECTS TO RPC + const selectNetworkRPC = async (rpc) => { + + //If user changes network it will first disconnect the current ws connection. + if(provider){ + await provider.disconnect(); + } + + if(rpc){ + const newProvider = new WsProvider(rpc); + setProvider(newProvider) + const _api = await ApiPromise.create({ provider: newProvider }); + setIsReady(_api._isReady); + setConnectedApi(_api) + } + }; + + //State cleaner to be used when changing networks + const cleanupState = () => { + setIsReady(false); + setConnectedApi(null); + setProvider(null) + } + + return ( + <ApiContextRC.Provider value={{api, isReady}}> + { children } + </ApiContextRC.Provider> + ); +}; + +export function useApiContextRC () { + return useContext(ApiContextRC) +} \ No newline at end of file From 34461d533b8404cb85affc8e4fc5089c15acbb8a Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Tue, 5 Dec 2023 10:31:38 +0100 Subject: [PATCH 29/44] added polkadotKS context and public folder --- .gitignore | 1 - public/favicon.ico | Bin 0 -> 3870 bytes public/index.html | 43 ++++++++++++++++++ public/logo192.png | Bin 0 -> 5347 bytes public/logo512.png | Bin 0 -> 9664 bytes public/manifest.json | 25 ++++++++++ public/robots.txt | 3 ++ src/App.js | 4 +- .../ConnectParaContext.js} | 8 +--- .../ConnectRelayContext.js} | 9 +--- src/views/dashboard/Dashboard.js | 6 ++- 11 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 public/favicon.ico create mode 100644 public/index.html create mode 100644 public/logo192.png create mode 100644 public/logo512.png create mode 100644 public/manifest.json create mode 100644 public/robots.txt rename src/{views/dashboard/polkadot-js-dummy-para.js => contexts/ConnectParaContext.js} (86%) rename src/{views/dashboard/polkadot-js-dummy-rc.js => contexts/ConnectRelayContext.js} (83%) diff --git a/.gitignore b/.gitignore index 70f24f47..c41bcd3d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ coverage/ dist/ node_modules/ -public/ yarn.lock # IDEs and editors diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a11777cc471a4344702741ab1c8a588998b1311a GIT binary patch literal 3870 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 baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ literal 0 HcmV?d00001 diff --git a/public/index.html b/public/index.html new file mode 100644 index 00000000..aa069f27 --- /dev/null +++ b/public/index.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#000000" /> + <meta + name="description" + content="Web site created using create-react-app" + /> + <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> + <!-- + manifest.json provides metadata used when your web app is installed on a + user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ + --> + <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> + <!-- + Notice the use of %PUBLIC_URL% in the tags above. + It will be replaced with the URL of the `public` folder during the build. + Only files inside the `public` folder can be referenced from the HTML. + + Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will + work correctly both with client-side routing and a non-root public URL. + Learn how to configure a non-root public URL by running `npm run build`. + --> + <title>React App</title> + </head> + <body> + <noscript>You need to enable JavaScript to run this app.</noscript> + <div id="root"></div> + <!-- + This HTML file is a template. + If you open it directly in the browser, you will see an empty page. + + You can add webfonts, meta tags, or analytics to this file. + The build step will place the bundled scripts into the <body> tag. + + To begin the development, run `npm start` or `yarn start`. + To create a production bundle, use `npm run build` or `yarn build`. + --> + </body> +</html> diff --git a/public/logo192.png b/public/logo192.png new file mode 100644 index 0000000000000000000000000000000000000000..fc44b0a3796c0e0a64c3d858ca038bd4570465d9 GIT binary patch literal 5347 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 X@eDJUQo;Ye2mwlRs<JiGX2Jghdw)}T literal 0 HcmV?d00001 diff --git a/public/logo512.png b/public/logo512.png new file mode 100644 index 0000000000000000000000000000000000000000..a4e47a6545bc15971f8f63fba70e4013df88a664 GIT binary patch literal 9664 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 b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN literal 0 HcmV?d00001 diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 00000000..080d6c77 --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 00000000..e9e57dc4 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/src/App.js b/src/App.js index 0cb51d6c..e23735c1 100644 --- a/src/App.js +++ b/src/App.js @@ -2,8 +2,8 @@ import React, { Component, Suspense } from 'react' import { BrowserRouter, Route, Routes } from 'react-router-dom' import { LocalStorageContextProvider } from './contexts/LocalStorageContext' import { ConfiguratorFormContextProvider } from './contexts/ConfiguratorFormContext' -import { ApiConnectRC } from './views/dashboard/polkadot-js-dummy-rc' -import { ApiConnectPara } from './views/dashboard/polkadot-js-dummy-para' +import { ApiConnectRC } from './contexts/ConnectRelayContext' +import { ApiConnectPara } from './contexts/ConnectParaContext' import './scss/style.scss' const loading = ( diff --git a/src/views/dashboard/polkadot-js-dummy-para.js b/src/contexts/ConnectParaContext.js similarity index 86% rename from src/views/dashboard/polkadot-js-dummy-para.js rename to src/contexts/ConnectParaContext.js index 1802d046..d4a6ae16 100644 --- a/src/views/dashboard/polkadot-js-dummy-para.js +++ b/src/contexts/ConnectParaContext.js @@ -1,13 +1,7 @@ -//this is just a dummy file to prepare for when the real api is connected -//it will use Rococo as a relay chain and rococo asset-hub as a parachain -//this one is for the Rococo-Relaychain - -//Dependencies - import React, { createContext, useState, useEffect, useContext } from 'react'; import { ApiPromise, WsProvider } from "@polkadot/api"; -// const ROCOCO_RPC ='wss://rococo-rpc.polkadot.io' +//ToDo: change logic to make this connect to the parachain node spawned by Portico const AH_ROCOCO_RPC ='wss://rococo-asset-hub-rpc.polkadot.io' const ApiContextPara = createContext(); diff --git a/src/views/dashboard/polkadot-js-dummy-rc.js b/src/contexts/ConnectRelayContext.js similarity index 83% rename from src/views/dashboard/polkadot-js-dummy-rc.js rename to src/contexts/ConnectRelayContext.js index 6d9060db..ffa3682d 100644 --- a/src/views/dashboard/polkadot-js-dummy-rc.js +++ b/src/contexts/ConnectRelayContext.js @@ -1,14 +1,8 @@ -//this is just a dummy file to prepare for when the real api is connected -//it will use Rococo as a relay chain and rococo asset-hub as a parachain -//this one is for the Rococo-Relaychain - -//Dependencies - import React, { createContext, useState, useEffect, useContext } from 'react'; import { ApiPromise, WsProvider } from "@polkadot/api"; +//ToDo: change logic to make this connect to the relaychain node spawned by Portico const ROCOCO_RPC ='wss://rococo-rpc.polkadot.io' -// const AH_ROCOCO_RPC ='wss://rococo-asset-hub-rpc.polkadot.io' const ApiContextRC = createContext(); @@ -20,7 +14,6 @@ export function ApiConnectRC ({ children }) { // by default this connects to Polkadot useEffect(() =>{ const startApi = async () => { - console.log('im running') await selectNetworkRPC(ROCOCO_RPC); } if(!provider){ diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js index 7fd1745e..6bf72864 100644 --- a/src/views/dashboard/Dashboard.js +++ b/src/views/dashboard/Dashboard.js @@ -1,4 +1,4 @@ -import React, {useContext} from 'react' +import React from 'react' import { CAvatar, @@ -55,12 +55,14 @@ import WidgetsBrand from '../widgets/WidgetsBrand' import WidgetsDropdown from '../widgets/WidgetsDropdown' //CONTEXT -import { useApiContextRC } from './polkadot-js-dummy-rc' +import { useApiContextRC } from '../../contexts/ConnectRelayContext' +import { useApiContextPara } from '../../contexts/ConnectParaContext' const Dashboard = () => { const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min) const apiContextRC = useApiContextRC() + const apiContextPara = useApiContextPara() const progressExample = [ From 0349487e2895787d5c8f64083cd310f21d7e0488 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Tue, 5 Dec 2023 11:48:40 +0100 Subject: [PATCH 30/44] Adding PolkadotJS conenction from real nodes --- src/contexts/ConnectParaContext.js | 18 ++++++++++-------- src/contexts/ConnectRelayContext.js | 12 ++++++------ src/views/dashboard/Dashboard.js | 4 ++++ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/contexts/ConnectParaContext.js b/src/contexts/ConnectParaContext.js index d4a6ae16..1db84105 100644 --- a/src/contexts/ConnectParaContext.js +++ b/src/contexts/ConnectParaContext.js @@ -1,25 +1,27 @@ import React, { createContext, useState, useEffect, useContext } from 'react'; import { ApiPromise, WsProvider } from "@polkadot/api"; - -//ToDo: change logic to make this connect to the parachain node spawned by Portico -const AH_ROCOCO_RPC ='wss://rococo-asset-hub-rpc.polkadot.io' +import { useLocalStorageContext } from './LocalStorageContext'; const ApiContextPara = createContext(); export function ApiConnectPara ({ children }) { + const { network } = useLocalStorageContext(); const [api, setConnectedApi] = useState(null); const [isReady, setIsReady] = useState(false); const [provider, setProvider] = useState(null); // by default this connects to Polkadot useEffect(() =>{ - const startApi = async () => { - await selectNetworkRPC(AH_ROCOCO_RPC); + const startApi = async (wsUri) => { + await selectNetworkRPC(wsUri); } - if(!provider){ - startApi(); + + const firstParasKey = Object.keys(network?.paras || {})[0]; + const wsUri = network?.paras?.[firstParasKey]?.[0]?.wsUri; + if(!provider && wsUri){ + startApi(wsUri); } - }) + }, [network]) //CONNECTS TO RPC const selectNetworkRPC = async (rpc) => { diff --git a/src/contexts/ConnectRelayContext.js b/src/contexts/ConnectRelayContext.js index ffa3682d..44dc6f09 100644 --- a/src/contexts/ConnectRelayContext.js +++ b/src/contexts/ConnectRelayContext.js @@ -1,12 +1,11 @@ import React, { createContext, useState, useEffect, useContext } from 'react'; import { ApiPromise, WsProvider } from "@polkadot/api"; - -//ToDo: change logic to make this connect to the relaychain node spawned by Portico -const ROCOCO_RPC ='wss://rococo-rpc.polkadot.io' +import { useLocalStorageContext } from './LocalStorageContext'; const ApiContextRC = createContext(); export function ApiConnectRC ({ children }) { + const { network } = useLocalStorageContext(); const [api, setConnectedApi] = useState(null); const [isReady, setIsReady] = useState(false); const [provider, setProvider] = useState(null); @@ -14,10 +13,11 @@ export function ApiConnectRC ({ children }) { // by default this connects to Polkadot useEffect(() =>{ const startApi = async () => { - await selectNetworkRPC(ROCOCO_RPC); + await selectNetworkRPC(wsUri); } - if(!provider){ - startApi(); + const wsUri = network?.relay?.[0]?.wsUri; + if(!provider && wsUri){ + startApi(wsUri); } }) diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js index 6bf72864..174a95dd 100644 --- a/src/views/dashboard/Dashboard.js +++ b/src/views/dashboard/Dashboard.js @@ -64,6 +64,10 @@ const Dashboard = () => { const apiContextRC = useApiContextRC() const apiContextPara = useApiContextPara() + console.log('apiContextRC', apiContextRC) + console.log('apiContextPara', apiContextPara) + + const progressExample = [ { title: 'Visits', value: '29.703 Users', percent: 40, color: 'success' }, From b44e08823c1d22e1e2ac6d9c5d4596e68ccdba42 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Tue, 5 Dec 2023 14:41:32 +0100 Subject: [PATCH 31/44] first dashboard layout --- src/views/dashboard/Dashboard.js | 538 ++++++++----------------------- 1 file changed, 127 insertions(+), 411 deletions(-) diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js index 6bf72864..4a2d2951 100644 --- a/src/views/dashboard/Dashboard.js +++ b/src/views/dashboard/Dashboard.js @@ -1,11 +1,11 @@ import React from 'react' import { - CAvatar, - CButton, - CButtonGroup, CCard, CCardBody, + CCardTitle, + CCardSubtitle, + CCardText, CCardFooter, CCardHeader, CCol, @@ -18,450 +18,166 @@ import { CTableHeaderCell, CTableRow, } from '@coreui/react' -import { CChartLine } from '@coreui/react-chartjs' -import { getStyle, hexToRgba } from '@coreui/utils' -import CIcon from '@coreui/icons-react' -import { - cibCcAmex, - cibCcApplePay, - cibCcMastercard, - cibCcPaypal, - cibCcStripe, - cibCcVisa, - cibGoogle, - cibFacebook, - cibLinkedin, - cifBr, - cifEs, - cifFr, - cifIn, - cifPl, - cifUs, - cibTwitter, - cilCloudDownload, - cilPeople, - cilUser, - cilUserFemale, -} from '@coreui/icons' -import avatar1 from 'src/assets/images/avatars/1.jpg' -import avatar2 from 'src/assets/images/avatars/2.jpg' -import avatar3 from 'src/assets/images/avatars/3.jpg' -import avatar4 from 'src/assets/images/avatars/4.jpg' -import avatar5 from 'src/assets/images/avatars/5.jpg' -import avatar6 from 'src/assets/images/avatars/6.jpg' - -import WidgetsBrand from '../widgets/WidgetsBrand' -import WidgetsDropdown from '../widgets/WidgetsDropdown' +import CIcon from '@coreui/icons-react' +import { cilPlus, cilCloudDownload, cilCog } from '@coreui/icons' //CONTEXT import { useApiContextRC } from '../../contexts/ConnectRelayContext' import { useApiContextPara } from '../../contexts/ConnectParaContext' -const Dashboard = () => { - const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min) - - const apiContextRC = useApiContextRC() - const apiContextPara = useApiContextPara() - - - const progressExample = [ - { title: 'Visits', value: '29.703 Users', percent: 40, color: 'success' }, - { title: 'Unique', value: '24.093 Users', percent: 20, color: 'info' }, - { title: 'Pageviews', value: '78.706 Views', percent: 60, color: 'warning' }, - { title: 'New Users', value: '22.123 Users', percent: 80, color: 'danger' }, - { title: 'Bounce Rate', value: 'Average Rate', percent: 40.15, color: 'primary' }, - ] - const progressGroupExample1 = [ - { title: 'Monday', value1: 34, value2: 78 }, - { title: 'Tuesday', value1: 56, value2: 94 }, - { title: 'Wednesday', value1: 12, value2: 67 }, - { title: 'Thursday', value1: 43, value2: 91 }, - { title: 'Friday', value1: 22, value2: 73 }, - { title: 'Saturday', value1: 53, value2: 82 }, - { title: 'Sunday', value1: 9, value2: 69 }, - ] - - const progressGroupExample2 = [ - { title: 'Male', icon: cilUser, value: 53 }, - { title: 'Female', icon: cilUserFemale, value: 43 }, - ] +const Dashboard = () => { - const progressGroupExample3 = [ - { title: 'Organic Search', icon: cibGoogle, percent: 56, value: '191,235' }, - { title: 'Facebook', icon: cibFacebook, percent: 15, value: '51,223' }, - { title: 'Twitter', icon: cibTwitter, percent: 11, value: '37,564' }, - { title: 'LinkedIn', icon: cibLinkedin, percent: 8, value: '27,319' }, + const blockColumns = [ + { + key: 'numb', + label: 'Number', + _props: { scope: 'col' }, + }, + { + key: 'hash', + label:'Block Hash', + _props: { scope: 'col' }, + }, ] - const tableExample = [ + const blockItems = [ + { + numb: 1, + hash: '0x00', + _cellProps: { id: { scope: 'row' } }, + }, { - avatar: { src: avatar1, status: 'success' }, - user: { - name: 'Yiorgos Avraamu', - new: true, - registered: 'Jan 1, 2021', - }, - country: { name: 'USA', flag: cifUs }, - usage: { - value: 50, - period: 'Jun 11, 2021 - Jul 10, 2021', - color: 'success', - }, - payment: { name: 'Mastercard', icon: cibCcMastercard }, - activity: '10 sec ago', + numb: 2, + hash: '0x01', + _cellProps: { id: { scope: 'row' } }, }, { - avatar: { src: avatar2, status: 'danger' }, - user: { - name: 'Avram Tarasios', - new: false, - registered: 'Jan 1, 2021', - }, - country: { name: 'Brazil', flag: cifBr }, - usage: { - value: 22, - period: 'Jun 11, 2021 - Jul 10, 2021', - color: 'info', - }, - payment: { name: 'Visa', icon: cibCcVisa }, - activity: '5 minutes ago', + numb: 3, + hash: '0x02', + _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, }, + ] + + const collatorsColumns = [ { - avatar: { src: avatar3, status: 'warning' }, - user: { name: 'Quintin Ed', new: true, registered: 'Jan 1, 2021' }, - country: { name: 'India', flag: cifIn }, - usage: { - value: 74, - period: 'Jun 11, 2021 - Jul 10, 2021', - color: 'warning', - }, - payment: { name: 'Stripe', icon: cibCcStripe }, - activity: '1 hour ago', + key: 'name', + label: 'Name', + _props: { scope: 'col' }, }, { - avatar: { src: avatar4, status: 'secondary' }, - user: { name: 'Enéas Kwadwo', new: true, registered: 'Jan 1, 2021' }, - country: { name: 'France', flag: cifFr }, - usage: { - value: 98, - period: 'Jun 11, 2021 - Jul 10, 2021', - color: 'danger', - }, - payment: { name: 'PayPal', icon: cibCcPaypal }, - activity: 'Last month', + key: 'address', + label:'Address', + _props: { scope: 'col' }, }, { - avatar: { src: avatar5, status: 'success' }, - user: { - name: 'Agapetus Tadeáš', - new: true, - registered: 'Jan 1, 2021', - }, - country: { name: 'Spain', flag: cifEs }, - usage: { - value: 22, - period: 'Jun 11, 2021 - Jul 10, 2021', - color: 'primary', - }, - payment: { name: 'Google Wallet', icon: cibCcApplePay }, - activity: 'Last week', + key: 'ws', + label:'WebSocket', + _props: { scope: 'col' }, }, + ] + + const collatorItems = [ { - avatar: { src: avatar6, status: 'danger' }, - user: { - name: 'Friderik Dávid', - new: true, - registered: 'Jan 1, 2021', - }, - country: { name: 'Poland', flag: cifPl }, - usage: { - value: 43, - period: 'Jun 11, 2021 - Jul 10, 2021', - color: 'success', - }, - payment: { name: 'Amex', icon: cibCcAmex }, - activity: 'Last week', + name: 1, + address: '0x00', + ws: 'ws://', + _cellProps: { id: { scope: 'row' } }, }, ] + const apiContextRC = useApiContextRC() + const apiContextPara = useApiContextPara() + return ( <> - <WidgetsDropdown /> - <CCard className="mb-4"> - <CCardBody> + <CRow> + <CCol> + {/*this is project name*/} + </CCol> + <CCol> + {/*this is option to kill or whatever*/} + </CCol> + </CRow> + <CRow> + <CCol> + {/*this is parachain meta info*/} <CRow> - <CCol sm={5}> - <h4 id="traffic" className="card-title mb-0"> - Traffic - </h4> - <div className="small text-medium-emphasis">January - July 2021</div> + <CCol> + <CCard> + <CCardBody> + <CCardTitle>ParachainID</CCardTitle> + {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} + <CCardText> + 2000 + </CCardText> + </CCardBody> + </CCard> </CCol> - <CCol sm={7} className="d-none d-md-block"> - <CButton color="primary" className="float-end"> - <CIcon icon={cilCloudDownload} /> - </CButton> - <CButtonGroup className="float-end me-3"> - {['Day', 'Month', 'Year'].map((value) => ( - <CButton - color="outline-secondary" - key={value} - className="mx-0" - active={value === 'Month'} - > - {value} - </CButton> - ))} - </CButtonGroup> + <CCol> + <CCard> + <CCardBody> + <CCardTitle className='d-flex align-items-center'> + <CCol md={10}>Coretime</CCol> + <CCol md={2} className='d-flex justify-content-end'> + <CIcon size='lg' icon={cilPlus} /> + </CCol> + </CCardTitle> + {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} + <CCardText> + 1000 blocks + </CCardText> + </CCardBody> + </CCard> </CCol> </CRow> - <CChartLine - style={{ height: '300px', marginTop: '40px' }} - data={{ - labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], - datasets: [ - { - label: 'My First dataset', - backgroundColor: hexToRgba(getStyle('--cui-info'), 10), - borderColor: getStyle('--cui-info'), - pointHoverBackgroundColor: getStyle('--cui-info'), - borderWidth: 2, - data: [ - random(50, 200), - random(50, 200), - random(50, 200), - random(50, 200), - random(50, 200), - random(50, 200), - random(50, 200), - ], - fill: true, - }, - { - label: 'My Second dataset', - backgroundColor: 'transparent', - borderColor: getStyle('--cui-success'), - pointHoverBackgroundColor: getStyle('--cui-success'), - borderWidth: 2, - data: [ - random(50, 200), - random(50, 200), - random(50, 200), - random(50, 200), - random(50, 200), - random(50, 200), - random(50, 200), - ], - }, - { - label: 'My Third dataset', - backgroundColor: 'transparent', - borderColor: getStyle('--cui-danger'), - pointHoverBackgroundColor: getStyle('--cui-danger'), - borderWidth: 1, - borderDash: [8, 5], - data: [65, 65, 65, 65, 65, 65, 65], - }, - ], - }} - options={{ - maintainAspectRatio: false, - plugins: { - legend: { - display: false, - }, - }, - scales: { - x: { - grid: { - drawOnChartArea: false, - }, - }, - y: { - ticks: { - beginAtZero: true, - maxTicksLimit: 5, - stepSize: Math.ceil(250 / 5), - max: 250, - }, - }, - }, - elements: { - line: { - tension: 0.4, - }, - point: { - radius: 0, - hitRadius: 10, - hoverRadius: 4, - hoverBorderWidth: 3, - }, - }, - }} - /> - </CCardBody> - <CCardFooter> - <CRow xs={{ cols: 1 }} md={{ cols: 5 }} className="text-center"> - {progressExample.map((item, index) => ( - <CCol className="mb-sm-2 mb-0" key={index}> - <div className="text-medium-emphasis">{item.title}</div> - <strong> - {item.value} ({item.percent}%) - </strong> - <CProgress thin className="mt-2" color={item.color} value={item.percent} /> - </CCol> - ))} + <CRow> + <CCard> + <CCardBody> + <CCardTitle>Parachain Head</CCardTitle> + {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} + <CCardText> + 0x0000 + </CCardText> + </CCardBody> + </CCard> + </CRow> + <CRow> + <CCard> + <CCardBody> + <CCardTitle className='d-flex align-items-center'> + <CCol md={10}> Parachain Code Hash </CCol> + <CCol md={2} className='d-flex justify-content-end align-items-center align-items-center'> + <CIcon className='me-2' size='lg' icon={cilCloudDownload} /> + <CIcon size='lg' icon={cilCog} /> + </CCol> + </CCardTitle> + {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} + <CCardText> + 0x0000 + </CCardText> + </CCardBody> + </CCard> </CRow> - </CCardFooter> - </CCard> - - <WidgetsBrand withCharts /> - - <CRow> - <CCol xs> - <CCard className="mb-4"> - <CCardHeader>Traffic {' & '} Sales</CCardHeader> + </CCol> + <CCol> + <CCard> <CCardBody> - <CRow> - <CCol xs={12} md={6} xl={6}> - <CRow> - <CCol sm={6}> - <div className="border-start border-start-4 border-start-info py-1 px-3"> - <div className="text-medium-emphasis small">New Clients</div> - <div className="fs-5 fw-semibold">9,123</div> - </div> - </CCol> - <CCol sm={6}> - <div className="border-start border-start-4 border-start-danger py-1 px-3 mb-3"> - <div className="text-medium-emphasis small">Recurring Clients</div> - <div className="fs-5 fw-semibold">22,643</div> - </div> - </CCol> - </CRow> - - <hr className="mt-0" /> - {progressGroupExample1.map((item, index) => ( - <div className="progress-group mb-4" key={index}> - <div className="progress-group-prepend"> - <span className="text-medium-emphasis small">{item.title}</span> - </div> - <div className="progress-group-bars"> - <CProgress thin color="info" value={item.value1} /> - <CProgress thin color="danger" value={item.value2} /> - </div> - </div> - ))} - </CCol> - - <CCol xs={12} md={6} xl={6}> - <CRow> - <CCol sm={6}> - <div className="border-start border-start-4 border-start-warning py-1 px-3 mb-3"> - <div className="text-medium-emphasis small">Pageviews</div> - <div className="fs-5 fw-semibold">78,623</div> - </div> - </CCol> - <CCol sm={6}> - <div className="border-start border-start-4 border-start-success py-1 px-3 mb-3"> - <div className="text-medium-emphasis small">Organic</div> - <div className="fs-5 fw-semibold">49,123</div> - </div> - </CCol> - </CRow> - - <hr className="mt-0" /> - - {progressGroupExample2.map((item, index) => ( - <div className="progress-group mb-4" key={index}> - <div className="progress-group-header"> - <CIcon className="me-2" icon={item.icon} size="lg" /> - <span>{item.title}</span> - <span className="ms-auto fw-semibold">{item.value}%</span> - </div> - <div className="progress-group-bars"> - <CProgress thin color="warning" value={item.value} /> - </div> - </div> - ))} - - <div className="mb-5"></div> - - {progressGroupExample3.map((item, index) => ( - <div className="progress-group" key={index}> - <div className="progress-group-header"> - <CIcon className="me-2" icon={item.icon} size="lg" /> - <span>{item.title}</span> - <span className="ms-auto fw-semibold"> - {item.value}{' '} - <span className="text-medium-emphasis small">({item.percent}%)</span> - </span> - </div> - <div className="progress-group-bars"> - <CProgress thin color="success" value={item.percent} /> - </div> - </div> - ))} - </CCol> - </CRow> - - <br /> - - <CTable align="middle" className="mb-0 border" hover responsive> - <CTableHead color="light"> - <CTableRow> - <CTableHeaderCell className="text-center"> - <CIcon icon={cilPeople} /> - </CTableHeaderCell> - <CTableHeaderCell>User</CTableHeaderCell> - <CTableHeaderCell className="text-center">Country</CTableHeaderCell> - <CTableHeaderCell>Usage</CTableHeaderCell> - <CTableHeaderCell className="text-center">Payment Method</CTableHeaderCell> - <CTableHeaderCell>Activity</CTableHeaderCell> - </CTableRow> - </CTableHead> - <CTableBody> - {tableExample.map((item, index) => ( - <CTableRow v-for="item in tableItems" key={index}> - <CTableDataCell className="text-center"> - <CAvatar size="md" src={item.avatar.src} status={item.avatar.status} /> - </CTableDataCell> - <CTableDataCell> - <div>{item.user.name}</div> - <div className="small text-medium-emphasis"> - <span>{item.user.new ? 'New' : 'Recurring'}</span> | Registered:{' '} - {item.user.registered} - </div> - </CTableDataCell> - <CTableDataCell className="text-center"> - <CIcon size="xl" icon={item.country.flag} title={item.country.name} /> - </CTableDataCell> - <CTableDataCell> - <div className="clearfix"> - <div className="float-start"> - <strong>{item.usage.value}%</strong> - </div> - <div className="float-end"> - <small className="text-medium-emphasis">{item.usage.period}</small> - </div> - </div> - <CProgress thin color={item.usage.color} value={item.usage.value} /> - </CTableDataCell> - <CTableDataCell className="text-center"> - <CIcon size="xl" icon={item.payment.icon} /> - </CTableDataCell> - <CTableDataCell> - <div className="small text-medium-emphasis">Last login</div> - <strong>{item.activity}</strong> - </CTableDataCell> - </CTableRow> - ))} - </CTableBody> - </CTable> + <CCardTitle>Recent Parachain Blocks</CCardTitle> + <CTable columns={blockColumns} items={blockItems} /> </CCardBody> </CCard> </CCol> </CRow> + <CRow> + <CCard> + <CCardBody> + <CCardTitle>Collator Nodes</CCardTitle> + <CTable className='mt-2' columns={collatorsColumns} items={collatorItems} /> + </CCardBody> + </CCard> + </CRow> </> ) } From 38bf5653cb60f96d861bae8476c35893b87580ab Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Tue, 5 Dec 2023 20:03:31 +0100 Subject: [PATCH 32/44] Restarts local storage state if no connection --- src/components/AppBreadcrumb.js | 4 +-- src/contexts/ConfiguratorFormContext.js | 21 +++++++++--- src/contexts/ConnectParaContext.js | 9 +++-- src/contexts/ConnectRelayContext.js | 8 +++-- src/contexts/LocalStorageContext.js | 15 +++++++-- src/hooks/useHealhCheck.js | 44 +++++++++++++++++++++++++ src/views/configurator/Configurator.js | 1 - src/views/configurator/submit.js | 1 + 8 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 src/hooks/useHealhCheck.js diff --git a/src/components/AppBreadcrumb.js b/src/components/AppBreadcrumb.js index 54cb57fd..0cb57e32 100644 --- a/src/components/AppBreadcrumb.js +++ b/src/components/AppBreadcrumb.js @@ -36,10 +36,10 @@ const AppBreadcrumb = () => { } const breadcrumbs = getBreadcrumbs(currentLocation) - +console.log('networkStatus', networkStatus) return ( <CBreadcrumb className="m-0 ms-2"> - <CBreadcrumbItem><Link to={networkStatus === 'OK' ? '/dashboard' : '/'}>Home</Link></CBreadcrumbItem> + <CBreadcrumbItem><Link to={networkStatus === 'OK' ? '/dashboard' : '/'}>Home</Link></CBreadcrumbItem> {breadcrumbs.map((breadcrumb, index) => { return ( <CBreadcrumbItem diff --git a/src/contexts/ConfiguratorFormContext.js b/src/contexts/ConfiguratorFormContext.js index ecf007fa..73b5c4c2 100644 --- a/src/contexts/ConfiguratorFormContext.js +++ b/src/contexts/ConfiguratorFormContext.js @@ -4,11 +4,23 @@ import React, { createContext, useContext, useState, useEffect } from 'react'; // Create the context const ConfiguratorFormContext = createContext(); +const initialState = { + collators: 0, + coretime: {every: null, amount: null }, + runtime: {template: null, specs: {paraId:null, ss58:null, tokenSymbol:null, decimals:null}} +} + // Define the context provider component export const ConfiguratorFormContextProvider = ({ children }) => { - const [collators, setCollators] = useState(0); - const [coretime, setCoretime] = useState({every: null, amount: null }); - const [runtime, setRuntime] = useState({template: null, specs: {paraId:null, ss58:null, tokenSymbol:null, decimals:null}}); + const [collators, setCollators] = useState(initialState.collators); + const [coretime, setCoretime] = useState(initialState.coretime); + const [runtime, setRuntime] = useState(initialState.runtime); + +const restartForm = () => { + setCollators(initialState.collators); + setCoretime(initialState.coretime); + setRuntime(initialState.runtime); +} // Context value const contextValue = { @@ -17,7 +29,8 @@ export const ConfiguratorFormContextProvider = ({ children }) => { coretime, setCoretime, runtime, - setRuntime + setRuntime, + restartForm }; return ( diff --git a/src/contexts/ConnectParaContext.js b/src/contexts/ConnectParaContext.js index 1db84105..c165432c 100644 --- a/src/contexts/ConnectParaContext.js +++ b/src/contexts/ConnectParaContext.js @@ -1,11 +1,12 @@ import React, { createContext, useState, useEffect, useContext } from 'react'; import { ApiPromise, WsProvider } from "@polkadot/api"; import { useLocalStorageContext } from './LocalStorageContext'; +import useHealthCheck from '../hooks/useHealhCheck'; const ApiContextPara = createContext(); export function ApiConnectPara ({ children }) { - const { network } = useLocalStorageContext(); + const { network, restart} = useLocalStorageContext(); const [api, setConnectedApi] = useState(null); const [isReady, setIsReady] = useState(false); const [provider, setProvider] = useState(null); @@ -23,6 +24,9 @@ export function ApiConnectPara ({ children }) { } }, [network]) + + useHealthCheck(async ()=> {restart(); cleanupState()},network); + //CONNECTS TO RPC const selectNetworkRPC = async (rpc) => { @@ -41,10 +45,11 @@ export function ApiConnectPara ({ children }) { }; //State cleaner to be used when changing networks - const cleanupState = () => { + const cleanupState = async () => { setIsReady(false); setConnectedApi(null); setProvider(null) + await provider.disconnect(); } return ( diff --git a/src/contexts/ConnectRelayContext.js b/src/contexts/ConnectRelayContext.js index 44dc6f09..c91692b9 100644 --- a/src/contexts/ConnectRelayContext.js +++ b/src/contexts/ConnectRelayContext.js @@ -1,11 +1,12 @@ import React, { createContext, useState, useEffect, useContext } from 'react'; import { ApiPromise, WsProvider } from "@polkadot/api"; import { useLocalStorageContext } from './LocalStorageContext'; +import useHealthCheck from '../hooks/useHealhCheck'; const ApiContextRC = createContext(); export function ApiConnectRC ({ children }) { - const { network } = useLocalStorageContext(); + const { network, restart } = useLocalStorageContext(); const [api, setConnectedApi] = useState(null); const [isReady, setIsReady] = useState(false); const [provider, setProvider] = useState(null); @@ -21,6 +22,8 @@ export function ApiConnectRC ({ children }) { } }) + useHealthCheck(async ()=> {restart(); cleanupState()},network); + //CONNECTS TO RPC const selectNetworkRPC = async (rpc) => { @@ -39,10 +42,11 @@ export function ApiConnectRC ({ children }) { }; //State cleaner to be used when changing networks - const cleanupState = () => { + const cleanupState = async () => { setIsReady(false); setConnectedApi(null); setProvider(null) + await provider.disconnect(); } return ( diff --git a/src/contexts/LocalStorageContext.js b/src/contexts/LocalStorageContext.js index bbbe27ed..6a545339 100644 --- a/src/contexts/LocalStorageContext.js +++ b/src/contexts/LocalStorageContext.js @@ -12,7 +12,6 @@ const setLocalStorageItem = (key, value) => { // Create the context const LocalStorageContext = createContext(); - // Define the context provider component export const LocalStorageContextProvider = ({ children }) => { const [network, setNetwork] = useState(() => getLocalStorageItem('network', {})); @@ -39,6 +38,17 @@ export const LocalStorageContextProvider = ({ children }) => { setLocalStorageItem('networkStatus', networkStatus); }, [networkStatus]); + const restart = () => { + setNetwork({}); + setLocalStorageItem('network', {}); + setCoretime({}); + setLocalStorageItem('coretime', {}); + setRuntime({}); + setLocalStorageItem('runtime', {}); + setNetworkStatus({}); + setLocalStorageItem('networkStatus', {}); + } + // Context value const contextValue = { network, @@ -48,7 +58,8 @@ export const LocalStorageContextProvider = ({ children }) => { runtime, setRuntime, networkStatus, - setNetworkStatus + setNetworkStatus, + restart }; return ( diff --git a/src/hooks/useHealhCheck.js b/src/hooks/useHealhCheck.js new file mode 100644 index 00000000..832855e4 --- /dev/null +++ b/src/hooks/useHealhCheck.js @@ -0,0 +1,44 @@ +import { useEffect, useState } from 'react'; +import { useNavigate} from 'react-router-dom' + + +const useHealthCheck = (callback,network) => { + const navigate = useNavigate() + const [failureCount, setFailureCount] = useState(0); + + + useEffect(() => { + // Check if the network object is not empty + if (network && Object.keys(network).length > 0) { + const interval = setInterval(async () => { + try { + const response = await fetch(`${process.env.REACT_APP_API_URL}/network`); + const data = await response.json(); + + if (!data.running) { + setFailureCount(prevCount => prevCount + 1); + if (failureCount >= 2) { // 0, 1, 2 - three attempts + await callback(data.msg); + setFailureCount(0); // Reset the counter after the callback + } + } else { + setFailureCount(0); // Reset the counter if it's running + } + } catch (error) { + setFailureCount(prevCount => prevCount + 1); + if (failureCount >= 2) { + await callback('API did not respond.'); + setFailureCount(0); // Reset the counter after the callback + navigate("/configure") + } + } + }, 2000); + + return () => clearInterval(interval); + } + }, [callback, network,failureCount]); + + +}; + +export default useHealthCheck; diff --git a/src/views/configurator/Configurator.js b/src/views/configurator/Configurator.js index dd951de9..64edbc88 100644 --- a/src/views/configurator/Configurator.js +++ b/src/views/configurator/Configurator.js @@ -17,7 +17,6 @@ const Configurator = () => { const [ready, setReady] = useState(false); const {collators, runtime, coretime } = configurationContext; - // const {setCollators, setRuntime, setCoretime } = configurationContext; const navigate = useNavigate() diff --git a/src/views/configurator/submit.js b/src/views/configurator/submit.js index a909253c..098e282b 100644 --- a/src/views/configurator/submit.js +++ b/src/views/configurator/submit.js @@ -27,6 +27,7 @@ const submit = async ({setStateStatus,localStorageContext, configurationContext} if (data.result === 'OK') { localStorageContext.setNetwork(data.network); + configurationContext.restartForm(); setStateStatus({executing: 'success', status: 'success', message: 'Configuration Submitted'}); } else { setStateStatus({executing: 'failed', status: 'danger', message: 'Configuration Submission Failed'}); From 37e7545c94a30e8f6c1e969d618b08856036d1c2 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Tue, 5 Dec 2023 21:43:53 +0100 Subject: [PATCH 33/44] alingment of components --- src/views/dashboard/Dashboard.js | 65 ++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js index 4a2d2951..52e236cc 100644 --- a/src/views/dashboard/Dashboard.js +++ b/src/views/dashboard/Dashboard.js @@ -20,7 +20,7 @@ import { } from '@coreui/react' import CIcon from '@coreui/icons-react' -import { cilPlus, cilCloudDownload, cilCog } from '@coreui/icons' +import { cilPlus, cilCloudDownload, cilCog, cilExitToApp } from '@coreui/icons' //CONTEXT import { useApiContextRC } from '../../contexts/ConnectRelayContext' @@ -58,6 +58,41 @@ const Dashboard = () => { hash: '0x02', _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, }, + { + numb: 3, + hash: '0x02', + _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, + }, + { + numb: 3, + hash: '0x02', + _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, + }, + { + numb: 3, + hash: '0x02', + _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, + }, + { + numb: 3, + hash: '0x02', + _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, + }, + { + numb: 3, + hash: '0x02', + _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, + }, + { + numb: 3, + hash: '0x02', + _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, + }, + { + numb: 3, + hash: '0x02', + _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, + } ] const collatorsColumns = [ @@ -92,19 +127,19 @@ const Dashboard = () => { return ( <> - <CRow> - <CCol> - {/*this is project name*/} + <CRow className='d-flex align-items-center mb-4'> + <CCol className={'ps-5'} md={10}> + <h3>Project X</h3> </CCol> - <CCol> - {/*this is option to kill or whatever*/} + <CCol md={2} className='d-flex justify-content-end pe-5'> + <CIcon className="text-danger" size="xl" icon={cilExitToApp} /> </CCol> </CRow> - <CRow> + <CRow className='mb-3'> <CCol> {/*this is parachain meta info*/} - <CRow> - <CCol> + <CRow className='mb-3 d-flex justify-content-between'> + <CCol className='p-0 me-2'> <CCard> <CCardBody> <CCardTitle>ParachainID</CCardTitle> @@ -115,7 +150,7 @@ const Dashboard = () => { </CCardBody> </CCard> </CCol> - <CCol> + <CCol className='p-0 ms-2'> <CCard> <CCardBody> <CCardTitle className='d-flex align-items-center'> @@ -132,7 +167,7 @@ const Dashboard = () => { </CCard> </CCol> </CRow> - <CRow> + <CRow className='mb-3'> <CCard> <CCardBody> <CCardTitle>Parachain Head</CCardTitle> @@ -165,16 +200,16 @@ const Dashboard = () => { <CCard> <CCardBody> <CCardTitle>Recent Parachain Blocks</CCardTitle> - <CTable columns={blockColumns} items={blockItems} /> + <CTable className='overflow-auto' columns={blockColumns} items={blockItems} /> </CCardBody> </CCard> </CCol> </CRow> - <CRow> + <CRow className='me-0'> <CCard> - <CCardBody> + <CCardBody > <CCardTitle>Collator Nodes</CCardTitle> - <CTable className='mt-2' columns={collatorsColumns} items={collatorItems} /> + <CTable className='mt-2 overflow-auto' columns={collatorsColumns} items={collatorItems} /> </CCardBody> </CCard> </CRow> From 30bd8964be1ab0df25bdbcc49feba7cb5757a8f1 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Tue, 5 Dec 2023 23:16:21 +0100 Subject: [PATCH 34/44] fix --- src/components/AppBreadcrumb.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AppBreadcrumb.js b/src/components/AppBreadcrumb.js index 0cb57e32..d9ef0629 100644 --- a/src/components/AppBreadcrumb.js +++ b/src/components/AppBreadcrumb.js @@ -36,7 +36,7 @@ const AppBreadcrumb = () => { } const breadcrumbs = getBreadcrumbs(currentLocation) -console.log('networkStatus', networkStatus) + return ( <CBreadcrumb className="m-0 ms-2"> <CBreadcrumbItem><Link to={networkStatus === 'OK' ? '/dashboard' : '/'}>Home</Link></CBreadcrumbItem> From 026e87e696c9fa0df59758ecdb5ea956f97d4de9 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Wed, 6 Dec 2023 16:41:25 +0100 Subject: [PATCH 35/44] added Coretime, paraID, paraHead, paraCode and paraBlocks --- src/contexts/ConnectParaContext.js | 1 - src/contexts/ConnectRelayContext.js | 3 +- src/hooks/unSubHook.js | 24 +++ src/views/dashboard/Dashboard.js | 215 +++++++++++++++++---------- src/views/dashboard/exportWasm.js | 33 ++++ src/views/dashboard/handleHash.js | 5 + src/views/dashboard/parseSchedule.js | 24 +++ 7 files changed, 227 insertions(+), 78 deletions(-) create mode 100644 src/hooks/unSubHook.js create mode 100644 src/views/dashboard/exportWasm.js create mode 100644 src/views/dashboard/handleHash.js create mode 100644 src/views/dashboard/parseSchedule.js diff --git a/src/contexts/ConnectParaContext.js b/src/contexts/ConnectParaContext.js index c165432c..b77081a1 100644 --- a/src/contexts/ConnectParaContext.js +++ b/src/contexts/ConnectParaContext.js @@ -11,7 +11,6 @@ export function ApiConnectPara ({ children }) { const [isReady, setIsReady] = useState(false); const [provider, setProvider] = useState(null); - // by default this connects to Polkadot useEffect(() =>{ const startApi = async (wsUri) => { await selectNetworkRPC(wsUri); diff --git a/src/contexts/ConnectRelayContext.js b/src/contexts/ConnectRelayContext.js index c91692b9..fd6a7dae 100644 --- a/src/contexts/ConnectRelayContext.js +++ b/src/contexts/ConnectRelayContext.js @@ -11,7 +11,6 @@ export function ApiConnectRC ({ children }) { const [isReady, setIsReady] = useState(false); const [provider, setProvider] = useState(null); - // by default this connects to Polkadot useEffect(() =>{ const startApi = async () => { await selectNetworkRPC(wsUri); @@ -20,7 +19,7 @@ export function ApiConnectRC ({ children }) { if(!provider && wsUri){ startApi(wsUri); } - }) + }, [network]) useHealthCheck(async ()=> {restart(); cleanupState()},network); diff --git a/src/hooks/unSubHook.js b/src/hooks/unSubHook.js new file mode 100644 index 00000000..0dd06923 --- /dev/null +++ b/src/hooks/unSubHook.js @@ -0,0 +1,24 @@ +import { useEffect } from 'react'; + +export default function useApiSubscription(fn, isReady) { + useEffect(() => { + if (!isReady) { + return; + } + + try { + const unsub = fn(); + return () => { + isReady && + unsub && + unsub + .then((u) => u()) + .catch((e) => { + console.error('error unsubscribing', e); + }); + }; + } catch (e) { + console.error('error executing subscription', e); + } + }, [fn, isReady]); +} \ No newline at end of file diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js index 52e236cc..084e2b07 100644 --- a/src/views/dashboard/Dashboard.js +++ b/src/views/dashboard/Dashboard.js @@ -1,99 +1,161 @@ -import React from 'react' +import React, {useState, useEffect, useCallback, useRef} from 'react' import { CCard, CCardBody, CCardTitle, - CCardSubtitle, CCardText, - CCardFooter, - CCardHeader, CCol, - CProgress, CRow, CTable, - CTableBody, - CTableDataCell, - CTableHead, - CTableHeaderCell, - CTableRow, + CSpinner, + CToaster, + CToast, + CToastHeader, + CToastClose, + CToastBody } from '@coreui/react' import CIcon from '@coreui/icons-react' -import { cilPlus, cilCloudDownload, cilCog, cilExitToApp } from '@coreui/icons' +import { cilPlus, cilCog, cilExitToApp, cilCopy } from '@coreui/icons' + +import ExportWasm from './exportWasm' //CONTEXT import { useApiContextRC } from '../../contexts/ConnectRelayContext' import { useApiContextPara } from '../../contexts/ConnectParaContext' +//HOOKS +import useApiSubscription from '../../hooks/unSubHook'; + +//UTILITIES +import {parseSchedule} from './parseSchedule' +import { cutHash } from './handleHash' const Dashboard = () => { + // STATE MANAGEMENT + const [paraHeadInfo, setParaHeadInfo] = useState([]) + const [rcHeadInfo, setrcHeadInfo] = useState(null) + const [paraID, setParaID] = useState(null) + const [coretimeLeft, setCoretimeLeft] = useState(null) + const [paraHead, setParaHead] = useState(null) + const [paraCodeHash, setParaCodeHash] = useState(null) + const [toast, setToast] = useState(0) + + const toaster = useRef() + + //API Info + const apiContextRC = useApiContextRC() + const apiContextPara = useApiContextPara() + + const paraApi = apiContextPara.api + const paraIsReady = apiContextPara.isReady + + const rcApi = apiContextRC.api + const rcIsReady = apiContextRC.isReady + + //Values on Parachain + useEffect(() =>{ + const getParaID = async () => { + const _paraID = (await paraApi.query.parachainInfo.parachainId()).toNumber() + setParaID(_paraID) + } + + if(paraApi) { + getParaID(); + } + + },[paraApi]); + + //Values on Relaychain + useEffect(() =>{ + + const getSchedule = async () => { + const schedule = await rcApi.query.scheduler.agenda.entries(); + const _coretimeLeft = parseSchedule(schedule, rcApi, paraID) + setCoretimeLeft(_coretimeLeft) + } + + const getParaHead = async () => { + const _paraHead = await (await rcApi.query.paras.heads(paraID)).toHuman() + setParaHead(_paraHead) + } + + const getParaCodeHash = async () => { + const _paraCodeHash = await (await rcApi.query.paras.currentCodeHash(paraID)).toHuman() + setParaCodeHash(_paraCodeHash) + } + + if(rcApi) { + getSchedule(); + getParaHead(); + getParaCodeHash(); + } + + },[rcApi, paraID, rcHeadInfo]); + + //Get parachainHead information + const getNewParaHeads = useCallback(() => { + if(paraApi){ + return paraApi.rpc.chain.subscribeNewHeads((lastHeader) => { + const head = lastHeader.toHuman().number + const headHash = lastHeader.hash.toHuman() + //TODO: have state saved only until 10 blocks, no need to show more. + + setParaHeadInfo(oldHeadInfo => [{head, headHash}, ...oldHeadInfo]) + // if (blocksCount < 11){ + // setParaHeadInfo(oldHeadInfo => [{head, headHash}, ...oldHeadInfo]) + // const newBlockCount = blocksCount + 1 + // console.log(newBlockCount) + // setBlocksCount(newBlockCount) + // } else { + // setParaHeadInfo(oldHeadInfo => [{head, headHash}, ...oldHeadInfo.slice(0,9)]) + // } + }) + } + }, [paraApi]); + + useApiSubscription(getNewParaHeads, paraIsReady); + + //Get relaychainHead information + const getNewRCHeads = useCallback(() => { + if(rcApi){ + return rcApi.rpc.chain.subscribeNewHeads((lastHeader) => { + const head = lastHeader.toHuman().number + setrcHeadInfo(head) + }) + } + }, [rcApi]); + + useApiSubscription(getNewRCHeads, rcIsReady); + + const handleCopyClick = () => { + navigator.clipboard.writeText(paraHead) + const message = ( + <CToast autohide={true} visible={true} color="success" className="text-white align-items-center"> + <div className="d-flex"> + <CToastBody>Copied to Clipboard!</CToastBody> + <CToastClose className="me-2 m-auto" white /> + </div> + </CToast> + ) + setToast(message) + } + const blockColumns = [ { - key: 'numb', + key: 'head', label: 'Number', _props: { scope: 'col' }, }, { - key: 'hash', + key: 'headHash', label:'Block Hash', _props: { scope: 'col' }, }, ] - - const blockItems = [ - { - numb: 1, - hash: '0x00', - _cellProps: { id: { scope: 'row' } }, - }, - { - numb: 2, - hash: '0x01', - _cellProps: { id: { scope: 'row' } }, - }, - { - numb: 3, - hash: '0x02', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - }, - { - numb: 3, - hash: '0x02', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - }, - { - numb: 3, - hash: '0x02', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - }, - { - numb: 3, - hash: '0x02', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - }, - { - numb: 3, - hash: '0x02', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - }, - { - numb: 3, - hash: '0x02', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - }, - { - numb: 3, - hash: '0x02', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - }, - { - numb: 3, - hash: '0x02', - _cellProps: { id: { scope: 'row' }, class: { colSpan: 2 } }, - } - ] + const blockItems = paraHeadInfo.slice(0,10) const collatorsColumns = [ { @@ -122,9 +184,6 @@ const Dashboard = () => { }, ] - const apiContextRC = useApiContextRC() - const apiContextPara = useApiContextPara() - return ( <> <CRow className='d-flex align-items-center mb-4'> @@ -145,7 +204,7 @@ const Dashboard = () => { <CCardTitle>ParachainID</CCardTitle> {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} <CCardText> - 2000 + {paraID ? paraID : ""} </CCardText> </CCardBody> </CCard> @@ -161,7 +220,7 @@ const Dashboard = () => { </CCardTitle> {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} <CCardText> - 1000 blocks + {coretimeLeft ? coretimeLeft : ""} </CCardText> </CCardBody> </CCard> @@ -170,10 +229,16 @@ const Dashboard = () => { <CRow className='mb-3'> <CCard> <CCardBody> - <CCardTitle>Parachain Head</CCardTitle> + <CCardTitle className='d-flex align-items-center'> + <CCol md={10}> Parachain Head </CCol> + <CCol md={2} className='d-flex justify-content-end align-items-center align-items-center'> + <CIcon size='lg' onClick={() => handleCopyClick()} icon={cilCopy} /> + <CToaster ref={toaster} push={toast} placement="top-end" /> + </CCol> + </CCardTitle> {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} <CCardText> - 0x0000 + {paraHead ? cutHash(paraHead) : ""} </CCardText> </CCardBody> </CCard> @@ -184,13 +249,13 @@ const Dashboard = () => { <CCardTitle className='d-flex align-items-center'> <CCol md={10}> Parachain Code Hash </CCol> <CCol md={2} className='d-flex justify-content-end align-items-center align-items-center'> - <CIcon className='me-2' size='lg' icon={cilCloudDownload} /> + <ExportWasm wasmHash={paraCodeHash} paraID={paraID} /> <CIcon size='lg' icon={cilCog} /> </CCol> </CCardTitle> {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} <CCardText> - 0x0000 + {paraCodeHash ? paraCodeHash : ""} </CCardText> </CCardBody> </CCard> diff --git a/src/views/dashboard/exportWasm.js b/src/views/dashboard/exportWasm.js new file mode 100644 index 00000000..b01c3e83 --- /dev/null +++ b/src/views/dashboard/exportWasm.js @@ -0,0 +1,33 @@ +//This component will help export a wasm given a particular hash. + +import CIcon from '@coreui/icons-react' +import { cilCloudDownload } from '@coreui/icons' + +//CONTEXT +import { useApiContextRC } from '../../contexts/ConnectRelayContext' + + +const ExportWasm = ({wasmHash, paraID}) => { + + const apiContextRC = useApiContextRC() + const rcApi = apiContextRC.api + + const exportWasm = async () => { + const element = document.createElement("a"); + const wasm = await (await rcApi.query.paras.codeByHash(wasmHash)).toHuman(); + const file = new Blob([wasm], {type: 'text/plain;charset=utf-8'}); + element.href = URL.createObjectURL(file); + element.download = `[PORTICO] wasm-paraID-${paraID}.txt`; + document.body.appendChild(element); + element.click(); + } + + + return ( + <CIcon onClick={() => exportWasm()} className='me-2' size='lg' icon={cilCloudDownload}/> + ); + +} + + +export default ExportWasm; \ No newline at end of file diff --git a/src/views/dashboard/handleHash.js b/src/views/dashboard/handleHash.js new file mode 100644 index 00000000..b99e9091 --- /dev/null +++ b/src/views/dashboard/handleHash.js @@ -0,0 +1,5 @@ +export const cutHash = (hash) => { + const start = hash.slice(0,8) + const end = hash.slice(hash.length-8,hash.length) + return `${start}...${end}` +} \ No newline at end of file diff --git a/src/views/dashboard/parseSchedule.js b/src/views/dashboard/parseSchedule.js new file mode 100644 index 00000000..5882e201 --- /dev/null +++ b/src/views/dashboard/parseSchedule.js @@ -0,0 +1,24 @@ +//This function will return just the onCoreDemand schedule + +export const parseSchedule = (schedule, api, paraID) => { + let data; + schedule.forEach(([block_execution, call_data])=>{ + //block_execution has the information of the block at which the scheduler is scheduled to be triggered + //call_data is an array of the calls that will be triggered at the block_execution height + //filter only for calls that are to create a onDemandAssignmentProvider for a paraID. + //It returns the amount left to be executed. + const actions = call_data.toHuman(); + actions.map(value =>{ + if(value && value.call.Inline){ + const tx = api.createType('Call', value.call.Inline); + const humanTx = tx.toHuman(); + const paraTargetNumber = Number(humanTx.args.para_id.split(",").join("")) + if (humanTx.section === "onDemandAssignmentProvider" && paraTargetNumber === paraID){ + data = value.maybePeriodic[1] + } + } + }) + }) + + return data +} \ No newline at end of file From 001311de06f433563bb4b3eed816cceae57e9eb0 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Wed, 6 Dec 2023 18:04:19 +0100 Subject: [PATCH 36/44] dashboard refactor --- src/App.js | 8 +- src/contexts/ConnectParaContext.js | 32 +++- src/contexts/ConnectRelayContext.js | 49 +++++- .../dashboard => utilities}/handleHash.js | 0 .../dashboard => utilities}/parseSchedule.js | 0 src/views/dashboard/Dashboard.js | 141 ++---------------- src/views/dashboard/blockTableConfig.js | 12 ++ src/views/dashboard/collatorTableConfig.js | 17 +++ 8 files changed, 117 insertions(+), 142 deletions(-) rename src/{views/dashboard => utilities}/handleHash.js (100%) rename src/{views/dashboard => utilities}/parseSchedule.js (100%) create mode 100644 src/views/dashboard/blockTableConfig.js create mode 100644 src/views/dashboard/collatorTableConfig.js diff --git a/src/App.js b/src/App.js index e23735c1..27ec6f15 100644 --- a/src/App.js +++ b/src/App.js @@ -27,8 +27,8 @@ class App extends Component { <BrowserRouter> <LocalStorageContextProvider> <ConfiguratorFormContextProvider> - <ApiConnectRC> - <ApiConnectPara> + <ApiConnectPara> + <ApiConnectRC> <Suspense fallback={loading}> <Routes> <Route exact path="/login" name="Login Page" element={<Login />} /> @@ -38,8 +38,8 @@ class App extends Component { <Route path="*" name="Home" element={<DefaultLayout />} /> </Routes> </Suspense> - </ApiConnectPara> - </ApiConnectRC> + </ApiConnectRC> + </ApiConnectPara> </ConfiguratorFormContextProvider> </LocalStorageContextProvider> </BrowserRouter> diff --git a/src/contexts/ConnectParaContext.js b/src/contexts/ConnectParaContext.js index b77081a1..6a716159 100644 --- a/src/contexts/ConnectParaContext.js +++ b/src/contexts/ConnectParaContext.js @@ -1,7 +1,8 @@ -import React, { createContext, useState, useEffect, useContext } from 'react'; +import React, { createContext, useState, useEffect, useContext, useCallback } from 'react'; import { ApiPromise, WsProvider } from "@polkadot/api"; import { useLocalStorageContext } from './LocalStorageContext'; import useHealthCheck from '../hooks/useHealhCheck'; +import useApiSubscription from '../hooks/unSubHook'; const ApiContextPara = createContext(); @@ -10,19 +11,44 @@ export function ApiConnectPara ({ children }) { const [api, setConnectedApi] = useState(null); const [isReady, setIsReady] = useState(false); const [provider, setProvider] = useState(null); + const [paraID, setParaID] = useState(null); + const [paraHeadInfo, setParaHeadInfo] = useState([]) useEffect(() =>{ const startApi = async (wsUri) => { await selectNetworkRPC(wsUri); } + const getParaID = async () => { + const _paraID = (await api.query.parachainInfo.parachainId()).toNumber() + setParaID(_paraID) + } + const firstParasKey = Object.keys(network?.paras || {})[0]; const wsUri = network?.paras?.[firstParasKey]?.[0]?.wsUri; if(!provider && wsUri){ startApi(wsUri); } - }, [network]) + if (api) { + getParaID(); + } + + }, [network, api, isReady]) + + const getNewParaHeads = useCallback(() => { + if(api){ + return api.rpc.chain.subscribeNewHeads((lastHeader) => { + const head = lastHeader.toHuman().number + const headHash = lastHeader.hash.toHuman() + //TODO: have state saved only until 10 blocks, no need to show more. + setParaHeadInfo(oldHeadInfo => [{head, headHash}, ...oldHeadInfo]) + }) + } + }, [api]); + + + useApiSubscription(getNewParaHeads, isReady); useHealthCheck(async ()=> {restart(); cleanupState()},network); @@ -52,7 +78,7 @@ export function ApiConnectPara ({ children }) { } return ( - <ApiContextPara.Provider value={{api, isReady}}> + <ApiContextPara.Provider value={{api, isReady, paraID, paraHeadInfo}}> { children } </ApiContextPara.Provider> ); diff --git a/src/contexts/ConnectRelayContext.js b/src/contexts/ConnectRelayContext.js index fd6a7dae..7dd54a0e 100644 --- a/src/contexts/ConnectRelayContext.js +++ b/src/contexts/ConnectRelayContext.js @@ -1,15 +1,25 @@ -import React, { createContext, useState, useEffect, useContext } from 'react'; +import React, { createContext, useState, useEffect, useContext, useCallback } from 'react'; import { ApiPromise, WsProvider } from "@polkadot/api"; import { useLocalStorageContext } from './LocalStorageContext'; +import { useApiContextPara } from './ConnectParaContext' import useHealthCheck from '../hooks/useHealhCheck'; +import useApiSubscription from '../hooks/unSubHook'; + +import { parseSchedule } from '../utilities/parseSchedule' const ApiContextRC = createContext(); export function ApiConnectRC ({ children }) { const { network, restart } = useLocalStorageContext(); + const { paraID } = useApiContextPara(); + const [api, setConnectedApi] = useState(null); const [isReady, setIsReady] = useState(false); const [provider, setProvider] = useState(null); + const [rcHeadInfo, setrcHeadInfo] = useState(null); + const [coretimeLeft, setCoretimeLeft] = useState(null); + const [paraHead, setParaHead] = useState(null); + const [paraCodeHash, setParaCodeHash] = useState(null); useEffect(() =>{ const startApi = async () => { @@ -19,7 +29,40 @@ export function ApiConnectRC ({ children }) { if(!provider && wsUri){ startApi(wsUri); } - }, [network]) + const getSchedule = async () => { + const schedule = await api.query.scheduler.agenda.entries(); + const _coretimeLeft = parseSchedule(schedule, api, paraID) + setCoretimeLeft(_coretimeLeft) + } + + const getParaHead = async () => { + const _paraHead = await (await api.query.paras.heads(paraID)).toHuman() + setParaHead(_paraHead) + } + + const getParaCodeHash = async () => { + const _paraCodeHash = await (await api.query.paras.currentCodeHash(paraID)).toHuman() + setParaCodeHash(_paraCodeHash) + } + + if(api && paraID) { + getSchedule(); + getParaHead(); + getParaCodeHash(); + } + }, [network, api, paraID, rcHeadInfo]) + + //Get relaychainHead information + const getNewRCHeads = useCallback(() => { + if(api){ + return api.rpc.chain.subscribeNewHeads((lastHeader) => { + const head = lastHeader.toHuman().number + setrcHeadInfo(head) + }) + } + }, [api]); + + useApiSubscription(getNewRCHeads, isReady); useHealthCheck(async ()=> {restart(); cleanupState()},network); @@ -49,7 +92,7 @@ export function ApiConnectRC ({ children }) { } return ( - <ApiContextRC.Provider value={{api, isReady}}> + <ApiContextRC.Provider value={{api, isReady, coretimeLeft, paraHead, paraCodeHash}}> { children } </ApiContextRC.Provider> ); diff --git a/src/views/dashboard/handleHash.js b/src/utilities/handleHash.js similarity index 100% rename from src/views/dashboard/handleHash.js rename to src/utilities/handleHash.js diff --git a/src/views/dashboard/parseSchedule.js b/src/utilities/parseSchedule.js similarity index 100% rename from src/views/dashboard/parseSchedule.js rename to src/utilities/parseSchedule.js diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js index 084e2b07..f45664d4 100644 --- a/src/views/dashboard/Dashboard.js +++ b/src/views/dashboard/Dashboard.js @@ -1,4 +1,4 @@ -import React, {useState, useEffect, useCallback, useRef} from 'react' +import React, {useState, useRef} from 'react' import { CCard, @@ -11,125 +11,33 @@ import { CSpinner, CToaster, CToast, - CToastHeader, CToastClose, CToastBody } from '@coreui/react' import CIcon from '@coreui/icons-react' import { cilPlus, cilCog, cilExitToApp, cilCopy } from '@coreui/icons' - import ExportWasm from './exportWasm' +import { blockColumns } from './blockTableConfig' +import { collatorsColumns } from './collatorTableConfig' + //CONTEXT import { useApiContextRC } from '../../contexts/ConnectRelayContext' import { useApiContextPara } from '../../contexts/ConnectParaContext' -//HOOKS -import useApiSubscription from '../../hooks/unSubHook'; - //UTILITIES -import {parseSchedule} from './parseSchedule' -import { cutHash } from './handleHash' +import { cutHash } from '../../utilities/handleHash' const Dashboard = () => { + + const {paraID, paraHeadInfo} = useApiContextPara(); + const {coretimeLeft, paraHead, paraCodeHash} = useApiContextRC(); // STATE MANAGEMENT - const [paraHeadInfo, setParaHeadInfo] = useState([]) - const [rcHeadInfo, setrcHeadInfo] = useState(null) - const [paraID, setParaID] = useState(null) - const [coretimeLeft, setCoretimeLeft] = useState(null) - const [paraHead, setParaHead] = useState(null) - const [paraCodeHash, setParaCodeHash] = useState(null) const [toast, setToast] = useState(0) - const toaster = useRef() - //API Info - const apiContextRC = useApiContextRC() - const apiContextPara = useApiContextPara() - - const paraApi = apiContextPara.api - const paraIsReady = apiContextPara.isReady - - const rcApi = apiContextRC.api - const rcIsReady = apiContextRC.isReady - - //Values on Parachain - useEffect(() =>{ - const getParaID = async () => { - const _paraID = (await paraApi.query.parachainInfo.parachainId()).toNumber() - setParaID(_paraID) - } - - if(paraApi) { - getParaID(); - } - - },[paraApi]); - - //Values on Relaychain - useEffect(() =>{ - - const getSchedule = async () => { - const schedule = await rcApi.query.scheduler.agenda.entries(); - const _coretimeLeft = parseSchedule(schedule, rcApi, paraID) - setCoretimeLeft(_coretimeLeft) - } - - const getParaHead = async () => { - const _paraHead = await (await rcApi.query.paras.heads(paraID)).toHuman() - setParaHead(_paraHead) - } - - const getParaCodeHash = async () => { - const _paraCodeHash = await (await rcApi.query.paras.currentCodeHash(paraID)).toHuman() - setParaCodeHash(_paraCodeHash) - } - - if(rcApi) { - getSchedule(); - getParaHead(); - getParaCodeHash(); - } - - },[rcApi, paraID, rcHeadInfo]); - - //Get parachainHead information - const getNewParaHeads = useCallback(() => { - if(paraApi){ - return paraApi.rpc.chain.subscribeNewHeads((lastHeader) => { - const head = lastHeader.toHuman().number - const headHash = lastHeader.hash.toHuman() - //TODO: have state saved only until 10 blocks, no need to show more. - - setParaHeadInfo(oldHeadInfo => [{head, headHash}, ...oldHeadInfo]) - // if (blocksCount < 11){ - // setParaHeadInfo(oldHeadInfo => [{head, headHash}, ...oldHeadInfo]) - // const newBlockCount = blocksCount + 1 - // console.log(newBlockCount) - // setBlocksCount(newBlockCount) - // } else { - // setParaHeadInfo(oldHeadInfo => [{head, headHash}, ...oldHeadInfo.slice(0,9)]) - // } - }) - } - }, [paraApi]); - - useApiSubscription(getNewParaHeads, paraIsReady); - - //Get relaychainHead information - const getNewRCHeads = useCallback(() => { - if(rcApi){ - return rcApi.rpc.chain.subscribeNewHeads((lastHeader) => { - const head = lastHeader.toHuman().number - setrcHeadInfo(head) - }) - } - }, [rcApi]); - - useApiSubscription(getNewRCHeads, rcIsReady); - const handleCopyClick = () => { navigator.clipboard.writeText(paraHead) const message = ( @@ -142,38 +50,7 @@ const Dashboard = () => { ) setToast(message) } - - const blockColumns = [ - { - key: 'head', - label: 'Number', - _props: { scope: 'col' }, - }, - { - key: 'headHash', - label:'Block Hash', - _props: { scope: 'col' }, - }, - ] - const blockItems = paraHeadInfo.slice(0,10) - - const collatorsColumns = [ - { - key: 'name', - label: 'Name', - _props: { scope: 'col' }, - }, - { - key: 'address', - label:'Address', - _props: { scope: 'col' }, - }, - { - key: 'ws', - label:'WebSocket', - _props: { scope: 'col' }, - }, - ] + const blockItems = paraHeadInfo ? paraHeadInfo.slice(0,10) : [] const collatorItems = [ { diff --git a/src/views/dashboard/blockTableConfig.js b/src/views/dashboard/blockTableConfig.js new file mode 100644 index 00000000..148c73bf --- /dev/null +++ b/src/views/dashboard/blockTableConfig.js @@ -0,0 +1,12 @@ +export const blockColumns = [ + { + key: 'head', + label: 'Number', + _props: { scope: 'col' }, + }, + { + key: 'headHash', + label:'Block Hash', + _props: { scope: 'col' }, + }, +] \ No newline at end of file diff --git a/src/views/dashboard/collatorTableConfig.js b/src/views/dashboard/collatorTableConfig.js new file mode 100644 index 00000000..a291e4b5 --- /dev/null +++ b/src/views/dashboard/collatorTableConfig.js @@ -0,0 +1,17 @@ +export const collatorsColumns = [ + { + key: 'name', + label: 'Name', + _props: { scope: 'col' }, + }, + { + key: 'address', + label:'Address', + _props: { scope: 'col' }, + }, + { + key: 'ws', + label:'WebSocket', + _props: { scope: 'col' }, + }, +] \ No newline at end of file From b37b37e3b57be66272ad1b66be3f4b20a34a0434 Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Wed, 6 Dec 2023 19:17:54 +0100 Subject: [PATCH 37/44] dashboard views with data --- src/_nav.js | 2 +- src/views/dashboard/Dashboard.js | 15 +++++---------- src/views/dashboard/collatorTableConfig.js | 10 +++++----- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/_nav.js b/src/_nav.js index c7b0948b..23b37846 100644 --- a/src/_nav.js +++ b/src/_nav.js @@ -31,7 +31,7 @@ const generateNav = (networkInfo, networkStatus) => { name: node.name, to: `https://polkadot.js.org/apps/?rpc=${node.wsUri}#/explorer` } - }).sort((node1, node2) => node1-node2) + }).sort((node1, node2) => node1.name > node2.name ) } } diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js index f45664d4..794c2a42 100644 --- a/src/views/dashboard/Dashboard.js +++ b/src/views/dashboard/Dashboard.js @@ -25,6 +25,7 @@ import { collatorsColumns } from './collatorTableConfig' //CONTEXT import { useApiContextRC } from '../../contexts/ConnectRelayContext' import { useApiContextPara } from '../../contexts/ConnectParaContext' +import { useLocalStorageContext } from 'src/contexts/LocalStorageContext' //UTILITIES import { cutHash } from '../../utilities/handleHash' @@ -33,6 +34,9 @@ const Dashboard = () => { const {paraID, paraHeadInfo} = useApiContextPara(); const {coretimeLeft, paraHead, paraCodeHash} = useApiContextRC(); + const paraNodes = useLocalStorageContext().network?.paras?.[paraID]?.map(node =>{ + return {...node, address:""} + }).sort((node1, node2) => node1.name > node2.name) // STATE MANAGEMENT const [toast, setToast] = useState(0) @@ -52,15 +56,6 @@ const Dashboard = () => { } const blockItems = paraHeadInfo ? paraHeadInfo.slice(0,10) : [] - const collatorItems = [ - { - name: 1, - address: '0x00', - ws: 'ws://', - _cellProps: { id: { scope: 'row' } }, - }, - ] - return ( <> <CRow className='d-flex align-items-center mb-4'> @@ -151,7 +146,7 @@ const Dashboard = () => { <CCard> <CCardBody > <CCardTitle>Collator Nodes</CCardTitle> - <CTable className='mt-2 overflow-auto' columns={collatorsColumns} items={collatorItems} /> + <CTable className='mt-2 overflow-auto' columns={collatorsColumns} items={paraNodes ? paraNodes : []} /> </CCardBody> </CCard> </CRow> diff --git a/src/views/dashboard/collatorTableConfig.js b/src/views/dashboard/collatorTableConfig.js index a291e4b5..43b01cb0 100644 --- a/src/views/dashboard/collatorTableConfig.js +++ b/src/views/dashboard/collatorTableConfig.js @@ -5,13 +5,13 @@ export const collatorsColumns = [ _props: { scope: 'col' }, }, { - key: 'address', - label:'Address', + key: 'wsUri', + label:'WebSocket URI', _props: { scope: 'col' }, }, { - key: 'ws', - label:'WebSocket', + key: 'address', + label:'Address', _props: { scope: 'col' }, - }, + } ] \ No newline at end of file From 3dfbded9c77a46867c30ff4da489c1e73deded94 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Wed, 6 Dec 2023 20:09:52 +0100 Subject: [PATCH 38/44] working version --- src/contexts/ConnectRelayContext.js | 42 +++++++++++++++++++++++++++-- src/contexts/LocalStorageContext.js | 2 +- src/views/configurator/submit.js | 3 ++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/contexts/ConnectRelayContext.js b/src/contexts/ConnectRelayContext.js index 7dd54a0e..d33d7d82 100644 --- a/src/contexts/ConnectRelayContext.js +++ b/src/contexts/ConnectRelayContext.js @@ -4,13 +4,14 @@ import { useLocalStorageContext } from './LocalStorageContext'; import { useApiContextPara } from './ConnectParaContext' import useHealthCheck from '../hooks/useHealhCheck'; import useApiSubscription from '../hooks/unSubHook'; +import { Keyring } from "@polkadot/keyring"; import { parseSchedule } from '../utilities/parseSchedule' const ApiContextRC = createContext(); export function ApiConnectRC ({ children }) { - const { network, restart } = useLocalStorageContext(); + const { network, restart, setCoretime, coretime } = useLocalStorageContext(); const { paraID } = useApiContextPara(); const [api, setConnectedApi] = useState(null); @@ -91,8 +92,45 @@ export function ApiConnectRC ({ children }) { await provider.disconnect(); } + const scheduleCall = async () => { + if(!paraID) return; + const lastScheduledBlock = rcHeadInfo * (coretime.amount * coretime.every); + const scheduledBlock = parseInt(rcHeadInfo) + parseInt(10); + const id = [212,53,147,199,21,253,211,28,97,20,26,189,4,169,159,214,130,44,133,88,133,76,205,227,154,86,132,231,165,109,162,125]; + const keyring = new Keyring({ type: 'sr25519' }) + const alice = keyring.addFromUri('//Alice'); + const onDemandCall = api.tx.onDemandAssignmentProvider.forcePlaceOrder(alice.address,10000001, paraID); + const schedule = api.tx.scheduler.scheduleNamed(id, scheduledBlock, [coretime.every,coretime.amount], 0, onDemandCall); + + await api.tx.sudo + .sudo( + schedule + ) + .signAndSend(alice,({ events = [], status }) => { + if (status.isInBlock) { + console.log('Successful schedule with hash ' + status.asInBlock.toHex()); + setCoretime({...coretime, scheduled: true, lastBlock: lastScheduledBlock}) + } else { + console.log('Status of schedule: ' + status.type); + } + + events.forEach(({ phase, event: { data, method, section } }) => { + console.log(phase.toString() + ' : ' + section + '.' + method + ' ' + data.toString()); + }); + }); + } + + useEffect(() => { + const schedule = async () => { + await scheduleCall() + } + if (isReady && api && coretime.scheduled === false) { + schedule() + } + },[isReady,api,rcHeadInfo]) + return ( - <ApiContextRC.Provider value={{api, isReady, coretimeLeft, paraHead, paraCodeHash}}> + <ApiContextRC.Provider value={{api, isReady, coretimeLeft, paraHead, paraCodeHash, scheduleCall}}> { children } </ApiContextRC.Provider> ); diff --git a/src/contexts/LocalStorageContext.js b/src/contexts/LocalStorageContext.js index 6a545339..6ff6715e 100644 --- a/src/contexts/LocalStorageContext.js +++ b/src/contexts/LocalStorageContext.js @@ -15,7 +15,7 @@ const LocalStorageContext = createContext(); // Define the context provider component export const LocalStorageContextProvider = ({ children }) => { const [network, setNetwork] = useState(() => getLocalStorageItem('network', {})); - const [coretime, setCoretime] = useState(() => getLocalStorageItem('coretime', {})); + const [coretime, setCoretime] = useState(() => getLocalStorageItem('coretime', {amount: null, every: null, scheduled: false, lastBlock: null})); //TODO: this might need to be deleted const [runtime, setRuntime] = useState(() => getLocalStorageItem('runtime', {})); diff --git a/src/views/configurator/submit.js b/src/views/configurator/submit.js index 098e282b..805a4886 100644 --- a/src/views/configurator/submit.js +++ b/src/views/configurator/submit.js @@ -1,5 +1,5 @@ const submit = async ({setStateStatus,localStorageContext, configurationContext}) => { - const {collators, runtime } = configurationContext; + const {collators, runtime, coretime } = configurationContext; const {paraId, ss58, tokenSymbol, decimals} = runtime.specs; let jsonData = { para_id: paraId, @@ -27,6 +27,7 @@ const submit = async ({setStateStatus,localStorageContext, configurationContext} if (data.result === 'OK') { localStorageContext.setNetwork(data.network); + localStorageContext.setCoretime({...coretime, scheduled: false, lastBlock: null}); configurationContext.restartForm(); setStateStatus({executing: 'success', status: 'success', message: 'Configuration Submitted'}); } else { From d6a0bfc21903926c3b1d0e2cd1725574d077771d Mon Sep 17 00:00:00 2001 From: Fidel <fidel.codes@gmail.com> Date: Wed, 6 Dec 2023 22:20:26 +0100 Subject: [PATCH 39/44] dashboard view done --- src/views/dashboard/Dashboard.js | 94 +++++++++++++++++++------------ src/views/dashboard/exportWasm.js | 5 +- 2 files changed, 62 insertions(+), 37 deletions(-) diff --git a/src/views/dashboard/Dashboard.js b/src/views/dashboard/Dashboard.js index 794c2a42..d3113dca 100644 --- a/src/views/dashboard/Dashboard.js +++ b/src/views/dashboard/Dashboard.js @@ -1,4 +1,5 @@ import React, {useState, useRef} from 'react' +import { Link } from 'react-router-dom' import { CCard, @@ -12,7 +13,10 @@ import { CToaster, CToast, CToastClose, - CToastBody + CToastBody, + CContainer, + CPopover, + CButton } from '@coreui/react' import CIcon from '@coreui/icons-react' @@ -57,72 +61,88 @@ const Dashboard = () => { const blockItems = paraHeadInfo ? paraHeadInfo.slice(0,10) : [] return ( - <> + <CContainer> <CRow className='d-flex align-items-center mb-4'> - <CCol className={'ps-5'} md={10}> + <CCol xl={{span : 10}}> <h3>Project X</h3> </CCol> - <CCol md={2} className='d-flex justify-content-end pe-5'> + <CCol xl={{span: 2}} className='d-flex justify-content-end pe-5'> <CIcon className="text-danger" size="xl" icon={cilExitToApp} /> </CCol> </CRow> - <CRow className='mb-3'> - <CCol> - {/*this is parachain meta info*/} - <CRow className='mb-3 d-flex justify-content-between'> - <CCol className='p-0 me-2'> - <CCard> + <CRow className='d-flex' xl={{ gutterX: 5 }}> + <CCol className='mb-2' xl={{ span: 5}}> + <CRow className='d-flex justify-content-between mb-2'> + <CCard style={{width:"49%"}}> <CCardBody> <CCardTitle>ParachainID</CCardTitle> - {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} <CCardText> {paraID ? paraID : ""} </CCardText> </CCardBody> </CCard> - </CCol> - <CCol className='p-0 ms-2'> - <CCard> + <CCard style={{width:"49%"}}> <CCardBody> <CCardTitle className='d-flex align-items-center'> - <CCol md={10}>Coretime</CCol> + <CCol md={10}> + <CPopover className={'fw-lighter'} content="Remaining Coretime credits" placement="top" trigger={['hover', 'focus']}> + <span className="d-inline-block" tabIndex={0}> + Coretime + </span> + </CPopover> + </CCol> <CCol md={2} className='d-flex justify-content-end'> - <CIcon size='lg' icon={cilPlus} /> + <Link to='/coretime'> + <CIcon size='lg' className="text-dark" icon={cilPlus} /> + </Link> </CCol> </CCardTitle> - {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} <CCardText> {coretimeLeft ? coretimeLeft : ""} </CCardText> </CCardBody> </CCard> - </CCol> </CRow> - <CRow className='mb-3'> + <CRow className='mb-2'> <CCard> <CCardBody> <CCardTitle className='d-flex align-items-center'> - <CCol md={10}> Parachain Head </CCol> + <CCol md={10}> + <CPopover className={'fw-lighter'} content="Latest head of the parachain stored on the relaychain." placement="top" trigger={['hover', 'focus']}> + <span className="d-inline-block " tabIndex={0}> + Parachain Head + </span> + </CPopover> + </CCol> <CCol md={2} className='d-flex justify-content-end align-items-center align-items-center'> - <CIcon size='lg' onClick={() => handleCopyClick()} icon={cilCopy} /> + <CButton color="link" className='text-nowrap pe-0' onClick={() => handleCopyClick()}> + <CIcon size='lg' className="text-dark" icon={cilCopy} /> + </CButton> <CToaster ref={toaster} push={toast} placement="top-end" /> </CCol> </CCardTitle> - {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} <CCardText> {paraHead ? cutHash(paraHead) : ""} </CCardText> </CCardBody> </CCard> </CRow> - <CRow> + <CRow className='mb-2'> <CCard> <CCardBody> <CCardTitle className='d-flex align-items-center'> - <CCol md={10}> Parachain Code Hash </CCol> + <CCol md={10}> + <CPopover className={'fw-lighter'} content="Hash of the parachain code stored on the relaychain." placement="top" trigger={['hover', 'focus']}> + <span className="d-inline-block" tabIndex={0}> + Parachain Code Hash + </span> + </CPopover> + </CCol> <CCol md={2} className='d-flex justify-content-end align-items-center align-items-center'> <ExportWasm wasmHash={paraCodeHash} paraID={paraID} /> - <CIcon size='lg' icon={cilCog} /> + <Link to='/runtime-upgrade'> + <CIcon size='lg' className="text-dark" icon={cilCog} /> + </Link> </CCol> </CCardTitle> {/* <CCardSubtitle className="mb-2 text-medium-emphasis">ID of Parachain on the Relaychain.</CCardSubtitle> */} @@ -133,24 +153,26 @@ const Dashboard = () => { </CCard> </CRow> </CCol> - <CCol> - <CCard> - <CCardBody> - <CCardTitle>Recent Parachain Blocks</CCardTitle> - <CTable className='overflow-auto' columns={blockColumns} items={blockItems} /> - </CCardBody> - </CCard> + <CCol className='mb-2' xl={{ span: 7 }}> + <CRow> + <CCard> + <CCardBody className={'overflow-scroll'}> + <CCardTitle>Recent Parachain Blocks</CCardTitle> + <CTable columns={blockColumns} items={blockItems} /> + </CCardBody> + </CCard> + </CRow> </CCol> </CRow> - <CRow className='me-0'> + <CRow className='mb-4'> <CCard> - <CCardBody > + <CCardBody className={'overflow-scroll'}> <CCardTitle>Collator Nodes</CCardTitle> - <CTable className='mt-2 overflow-auto' columns={collatorsColumns} items={paraNodes ? paraNodes : []} /> + <CTable columns={collatorsColumns} items={paraNodes ? paraNodes : []} /> </CCardBody> </CCard> </CRow> - </> + </CContainer> ) } diff --git a/src/views/dashboard/exportWasm.js b/src/views/dashboard/exportWasm.js index b01c3e83..ef172a83 100644 --- a/src/views/dashboard/exportWasm.js +++ b/src/views/dashboard/exportWasm.js @@ -1,5 +1,6 @@ //This component will help export a wasm given a particular hash. +import { CButton } from '@coreui/react' import CIcon from '@coreui/icons-react' import { cilCloudDownload } from '@coreui/icons' @@ -24,7 +25,9 @@ const ExportWasm = ({wasmHash, paraID}) => { return ( - <CIcon onClick={() => exportWasm()} className='me-2' size='lg' icon={cilCloudDownload}/> + <CButton color="link" className='text-nowrap pe-1 d-inline-flex' > + <CIcon onClick={() => exportWasm()} className='me-2 text-dark' size='lg' icon={cilCloudDownload}/> + </CButton> ); } From 37029eed83b6d87f547e3466874f0f3f16ca7800 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Thu, 7 Dec 2023 20:15:13 +0100 Subject: [PATCH 40/44] working chopsticks --- package.json | 2 + src/views/runtime-upgrade/RuntimeUpgrade.js | 117 +++++++++++++++++++- src/views/runtime-upgrade/devnet.wasm | 1 + 3 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 src/views/runtime-upgrade/devnet.wasm diff --git a/package.json b/package.json index 90e89474..179cb83c 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "test:debug": "react-scripts --inspect-brk test --runInBand" }, "dependencies": { + "@acala-network/chopsticks-core": "^0.9.3", + "@acala-network/chopsticks-db": "^0.9.3", "@coreui/chartjs": "^3.1.2", "@coreui/coreui": "^4.2.6", "@coreui/icons": "^3.0.1", diff --git a/src/views/runtime-upgrade/RuntimeUpgrade.js b/src/views/runtime-upgrade/RuntimeUpgrade.js index f463c14b..b1fc53f4 100644 --- a/src/views/runtime-upgrade/RuntimeUpgrade.js +++ b/src/views/runtime-upgrade/RuntimeUpgrade.js @@ -1,11 +1,120 @@ -import React from 'react' +import React, {useState, useEffect} from 'react' +import { createTestPairs } from '@polkadot/keyring' +import { ChopsticksProvider, setStorage, setup } from '@acala-network/chopsticks-core' +import { IdbDatabase } from '@acala-network/chopsticks-db/browser' +import { ApiPromise } from '@polkadot/api' +import { useLocalStorageContext } from '../../contexts/LocalStorageContext' const RuntimeUpgrade = () => { + const {network} = useLocalStorageContext(); + const [dryRunLoading, setDryRunLoading] = useState(false) + const [chainLoading, setChainLoading] = useState(false) + const [config, setConfig] = useState({ + endpoint: 'ws://127.0.0.1:50877', + block: 10, + }) + const [blocks, setBlocks] = useState([]) + const [bobBalance, setBobBalance] = useState('') + const [transferDisabled, setTransferDisabled] = useState(false) + const [chopsticksApi, setChopsticksApi] = useState(null) + const [chain, setChain] = useState(null) + const [fileContent, setFileContent] = useState(''); + const [loading, setLoading] = useState(false); + const { alice, bob } = createTestPairs() + const [runtimeVersions, setRuntimeVersions] = useState([]) + + + + const handleFileChange = (event) => { + const file = event.target.files[0]; + if (!file) { + return; + } + + setLoading(true); + const reader = new FileReader(); + + reader.onload = (e) => { + setFileContent(e.target.result); + setLoading(false); + }; + + reader.onerror = (e) => { + console.error('Error reading file:', e); + setLoading(false); + }; + + reader.readAsText(file); + }; + + useEffect(() => { + setupChain() + },[]) + + + const setupChain = async () => { + setChainLoading(true) + const chain = await setup({ + endpoint: config.endpoint, + block: config.block, + mockSignatureHost: true, + db: new IdbDatabase('cache'), + }) + setChain(chain) + + const provider = new ChopsticksProvider(chain) + const api = new ApiPromise({ provider, noInitWarn: true }) + await api.isReadyOrError + setChopsticksApi(api) + + let specVersion = await api.rpc.state.getRuntimeVersion() + + let spec = {runtime: specVersion.toJSON().specVersion, block:chain.head.number} + setRuntimeVersions([spec]) + console.log('specVersion', specVersion.toJSON().specVersion) + + setChainLoading(false) + setBlocks([{ number: chain.head.number, hash: chain.head.hash }]) + return api + } + + const disconnect = async () => { + await chopsticksApi.disconnect() + } + + const runtimeUpgrade = async () => { + const runtime = fileContent + + // expect(await chain.head.runtimeVersion).toEqual(expect.objectContaining({ specVersion: 1000 })) + await chopsticksApi.tx.sudo.sudoUncheckedWeight(chopsticksApi.tx.system.setCode(runtime), (0,0)).signAndSend(alice) + await chain.newBlock({ count: 3 }) + + await chopsticksApi.tx.balances.transferKeepAlive(bob.address, 1e12).signAndSend(alice) + await chain.newBlock() + + await disconnect() + await setupChain(chain) + + let bob_balance = await chopsticksApi.query.system.account(bob.address) + + let specVersion = await chopsticksApi.rpc.state.getRuntimeVersion() + let spec = {runtime:specVersion.toJSON().specVersion, block:chain.head.number} + setRuntimeVersions((old) => [...old,spec]) + await chopsticksApi.tx.newPallet.doSomething(10).signAndSend(alice) + } + return ( - <h1> - THIS IS RUNTIME UPGRADE BABY - </h1> + <> + <h1> + Runtime Upgrade + </h1> + <button onClick={runtimeUpgrade}>Runtime Upgrade</button> + <input type="file" onChange={handleFileChange} /> + {loading && <p>Loading file...</p>} + {runtimeVersions.map(({runtime,block}) => <p>number: {runtime}, block: {block}</p>)} + </> + ) } diff --git a/src/views/runtime-upgrade/devnet.wasm b/src/views/runtime-upgrade/devnet.wasm new file mode 100644 index 00000000..8ab161c6 --- /dev/null +++ b/src/views/runtime-upgrade/devnet.wasm @@ -0,0 +1 @@ +0x52bc537646db8e0528b52ffd00586c4b058e5886ae1351106879930e82e137a9a28917bb8b139ee8df0146571a324464844bd174961f3b8bd304d3139cfb4b0a9463a10f630424c9e02304eb25fc87767a37e1694caa97eb1f4edb9add84ec2dc9967b4b29534a016c159612ca122676ab8d490cf9bb3222ccebf0c8753f2b26053c489346145c885922683dba9fa3162c814412da5013461a5982d6974af6eda941b2d7485e118b567fcbe3c29bd7295a8bdcb3977c6b95f44b5e18462be625c7aecb9d67adc2dcb9bc26bfc466e6ac15d1f1af5319ad9997fc9afbd92c728fb9e45e76a66beecbb95fc2664fab7681549e67778eaadb33ad9643772e1db335f719c01e67117c9d6f8bd61fdef29d353a6de18d7cda5e3759a7bc53ce2fe7e9d44581dcce372b3f11b769d3a6cdd7a35fb76691fb759eb153edac092d8574eb54fbc6d3d3aa7d54abfc9da776887be7fe25863190ebdb5319e9dbe504c136e47cbf32d2f7efea0835cf17d8767584996724207e6965a4770ed4f2676567ab093ddf39e5fdfa9b46b65f77b31ebdf3dd21f5f98e91d23f4a74faf525e3837cdd365f7f27cb6063e7df46c03a6b444eb4bda33c8c24864760d324b03d871e8d00f3edd95644d2b7ebc0a9d329aea8675f2d02ffb8486ecb6d29373b723be4eeb0edaa88d5c3df951533bf37d2f9f6d44dfa76e9a61529577bb41efd73372bbb323ac826a45575fb75148fe9cc69424735481021eec79190909082da81dc8f07b5d7d0aaf8ed36ec10f77de2b112e67fb42ac726e189b8cd5725bf1a912df3ebd265efcbcba01430b334212e5766cdd03f1b64258b7c1643b8ed7c98d64f3b64e92e10e7ed40eed1d7a93dda6a10a016b2e6db83b0f9f6185ac5fc33fc26c133caf07b2190346c2e75927cc3b69a038efebd23661a762069700d48e2c6ecb677b6de9a0d473fb494c8e8d76b3b2fd5828832bf2b22c03c22b0fc9392351b8efee82d2a9d26043bb3a0cf5784df8aadda21c26fb945f7d9e1e4df9e4787b67e42d2c03ec45e9d37cf9e19302f11b93764ff5e9e9ac64e3977fea055a4bd553b44da9d3bcb19fa90f3e796e5b1556d650fd4407dc4cc62e4deb0c91311699e0d474c63a79e3f97a7a0cd793b91d13f22fe473920b7ddc9f5ec89627bceb9e4ec39263266536e4fddd53b9794d9b7d78740e382b4aace3043ab9e3becdd1065bc73db3b2cf55e6cd5507bec143bfbf6cfe67c9c3f5ae3afbbd94e3d7f9d62afd9b66a574350f1eb4f08323f1bb4be5a3b50b346a4fdd198b5aa77d54590db925fc05cb6d3928d83d89881d8d8817a7f08114608299c73e7dc39c7e69d73cef5b82865545955a9f2deaaf6ea3d264872df5eb3afde41357b109800cbef2a88333f80df55105f5e9eb6e7b5eae86b3bfb9121a63b47deb3bf67ff01090909e9fb3d5fcd48fde19f3f4a34c4be5faf67dfaac8eda941be46e7b34136cbf99b6cbb0aa2cbef2a08a43fc0ef0a8831df9a9004b6ba6d5bd6aaf6f66d5574cbdb636b42d1b25c72c62f59b35c5ab38889845ea79e1bd9de72d66ad8b77c35a1ed54cd9e21ad470f63742017677d5f9f17b9bf7c3521e8402de56a8e562aef3cceea1fdd9a753bf5c347afdba90ae5a357cbb753b5878f0ee4dcbc281195776ecdfd382bcf3f979c5d73df9afbab2179efe02472effccded14d3d7a98b9d1819dba19bd6f7e4e75945f0ec72b9db5449f0ec26fb6a46e0f3f7dc3f6a4e2257036038b0ed0a08293ed5aa9afaf6f61f2b20b67c7ffbf60f07559e6f5fcd8813402c907da0ce82f00ce4beb0adb306b65d2125fda6e5d763ab768524e6d7b356f1cf06559d5f06c835c0c6bebe98dc56f1f2afcbd3b66adb6bfcf5d72af675c93b8c3881b440f625afd67b63e405ab4eedbbe7ced99d26c474f9c6c80bc4746abfdd4de9329efcadb5aff62850af26f43ae558b3e1e81ba8590a72bfdbb99bee11b311c9ce5302db0a09e9ebfbf6d7aaf5f6c81ea3fbd9f6a9dbb3d7ed77327bc03967e666e740cdce79fb73e79c6377dcedf19bee1c697fde6c84bd696d77cd1c04b93dd5bf5d6e0136b941b6ed548ddfee5823f20312121210ef5ac5deaaed543b50bbf93ad50ec3c6febc5dea48ceb656b5ebb48abf1dd52a27e4de9cd2e3a51cc5678fcf74e708fb73f6478bf81ddd4ed5f7ebab0931adfcec400dd4dbd374c87f7d1c39e631727f7beaf6ed32b6aaeee8896263afd9b774f3c7c6ee7c7d3524ec438ec64ead3f9efdab9f62693b240a233d11039ebd5d76b63b84bd3adf4eadc756557ee7ebd2cdd8a9f5016cced7572bf23ab5ee68ecd43a50cbce78becf76481456f344d74fc179f6766d874461a42762c04fc99ebdddb443a230d21331e0a758cfde7eda215118e98918f0ecedd2653cdd6b3b240a233d11037e8af5ecedd90e89c2667e4af6eceda61d1285919e8801cfdebe1a928784f4ec40cd9a910de9d9b356edb7af6684919e1da8811aa8817ae7766a7d7b9a0e6dbf3e8e9a3b09725b6ecb3dc0c6bebe584f151653c5aad4b3444f123ed0f880420f928f343ed4f041051f4ff0d1c687147ca4e1230a3edef0e1858f241f5df870818f257c58f191c5c7151f48d02ce8183e8ef081021f587ca48016e1a38a0f241f4050237c0441912812540a540d5d837a31c15031740ab407940a34890a818ea1625030e81b7445dbf810820281fe8092a155f830820681aa41b9a05ad01b502be81434053e86a02aa044986fcc34a69799c51cc25c511f4c1e502126169308530b1a85f98586a161d02f6817748bb9c56c3385e083053e92a06850265029281468147407d38c49661681a6a1405037669a8986b2a168e812280f2812e813e618d40b05339d409330d5a069502ce811bc8c17c1c93811fc0c1fc3931c082e8673e15e7818cf817771267aa8e148780a7a48a1c71b3daad0a34d0f377ab0e141f458e3480e84bfc09b702e3db2d0030b3daed0c30a8e821e6d381637c2abf04c8147083c54702b2e846be9410567018f9a1e51e081050f1ef0e8010f18f0708207171e2fe0d1040f26786ce1b1040f17f068010f2d3c58c0630a1e52f08082c70c7878e191031e61f010c3030c1e5ff0b882070e7858c1a30a1e32e0f1048f18f008c3c30b1e5df0e082c78ac7163cb4e091050f303c54c0e3081e28e06185c7159e363c9078dee041048f22789c80c70d9e27f0a4e171020f1a9e347894c0b3049e3578c4e049e2d182270b9e1cf06cc103039e17f0b880470b0f113b50d849b3a3c64e117688b003849d2a76a8d8b9c18e0d769ed8e1b2a36547899d16f460b3c3829d19ec20b193c40e0a7680d8c9b2e30b1e40ecf0a28ba013840e528e1de4c002e5462c43070a7460d181046a85da42070e740ca1830a1d26d071031d44e8b8a2e38858e54ae372e3bac295e6b2c2a5e67a23838225859c1ae08081f385ce09b432a81ce4204287105057a080c881851c57400d91230b39d8e47823871b6c458e21506266193ed6f0a1e6460d3d83529113c5ce151f53d0b2b8b18293217d90c38853181e26602ac0b4602c300901a70a2c05b2888b0d941a971ad104571422126a0a5c058e1cb4b0440b2d6881052d24217990c386670c9411a813e8acd1a9428e0b725461c716120bd9031d363a6ee85cc14ab3a3031d2276bedcb4a1034534425b21c70dbf8153e155e850e1660af20bcd0639a6b0030caa8d16d29038d0a4d05123879a1d3c38c120a7053a6c48306ea47002730305d31993124c4b303121a709e904792687899c17e470d959e336d889819bb1d36567898b8d090c1906cf0067093a6ba09e804ab35346a3426eb1238b1d5ac4256ea290b3c44d1ada1472a55571f3841d2ba9857603d9c58d1a524cce969b34328c66456c4174c10d15ae2c5c5390604e5b7412a7d5290bb9039e22180a3861342e32073b5838cde0f4c44e10385e98a8a0630c53528603541a382b4045c124c68546a70a0a0aa835e40cdc083ec4b85903a70b4c89ab8d9b2a9882b073c50e0ea4179e25471b928b1c3272bac80923078c9c22e4002107093947c8299353468e193967e41821e7073962e4f42047083962729272bcc8192387083963728690e3039c2ae05001870d9c3572bec809424e989c24e490b9c1c24d166eae10cfd0be4433b42b76aec069b41d6839d0f183a6a26fd036e8295a8aae4147d134e82e0d45cfa065d04f740c1a06ed4473e9177413cd446fe925da053b61f00c01a54666e12bd0a1c18e0bfc081f423641a291a34b0e282410726cc9c1440e17e46822470b7270c9f102f904090599864c23d1c82848356410621939860f2264124381a3031c2fcd824b0a580b70b4502c5033f20894143017988050da72ad715501c332ad801aa3738326733541078d8e1438596c65706ea053032c4b09881ec2c5845210db117480d089224381bc02870a59c585060f1beb08d6171618561856112c31960fe4102c349613ac26a070e0266833161a27274e2fc00183b3832c05ee820c4b36c485051e26e01144890dce1697133c089910281ef09cb9a0c063e6a282ce10d7133215ecc002e7091a10d9113a636446ecac4c6a74640195942306395a784e1081c081028e1ee0b460c70b765cd9d1c4c9063ab0608d41bff858014f154c6b9c6e90e3891d31322b2629d02d1ad20e9813153a607650515263678b1c5e6049646d767091359056e4e8c224665261e704385ce88891d36687155f62471531081d1ee00003c7175a123b5ee07cc171410e1de4f082d3836e032707396fa0ac284561e708d409f3095a961c329046e05c81b3048f184d891c5f4c66724401270d6dc2894bfbc0470b4a69b0156851cc28a0aac0c102c70a5a8613b183085a846904190535427602d314bc05f30a3a26a035e0b9b215619ea19334b3c0c306d6e66a33dda05998645033b22b3b8ac0595d67ae353c60f06461c704590ca81272a891430a59123838302541278b0c891c61b22c282fd90a36229490e61a130a383cc0d1424788ac888c883ed34d70307a8d76424fa1d9682ab49a4683278846421fa1cb7412fa0c1e2f784cd0493c6178ba682134193d06cf106ca6b7e855a7a0bbe82c1a4c7f692d5a078da58f68143412ad82068287096e83afc063442bc123045b81a5c051602ab01a9e424f0a9a0b9e2aac045e021f819fc0d304af990005d80cbe0153c1f3054f0fbc0c8e8269300211fc10822915490e38f09608701608f4e001254932f0004e829938e2002333d450848850031e88010b9081a5e02e3e40044080d492cb8be45f368dc1da3191b2840349a02c61d2439224921d0f4f98244952020224e70a3b24f1a1034f8c3871e243038a7660e2c4890f0d1840ce9a20395670e264c90e4e9c2c69401b3d1479e00913275558264c3a90c487a224453d78a0099310f8e4b0b1529c345952c48487244c9874e0851c2aac0f1d78d2248908a230010151922650bee809930f8860090e9eb3c632d9e1890f4f922c49d204ca33d9e1890f0f287a02021f76d8e179e44c81071f7660c2438f1c352b45044c86924891220226479ef8d0448a142612983952d8103481f251980c45f1a10248664e14360913103001010472e08189073cb0248701e4a8b152867660d2c30e69564ad113265198f4f0a489e740e149930eece43c61776822e5499328453f304922022750a02c491285090f4e9a80206868071f9c04f1e4a4b15276e4a0d9254978729cb01f48b2a468090f4b8a98dc7093d384113471b2a4495193274d70e4a001821d98fcc00427e7cc46f1a101590e13560a9326454da2f8d043110896e4e42c619ff8d0a468491410f090a4c8072752923481f24ba280e071683ed8a11d7c70c281244c8a96f0d0c4c99229a665264e38b0a4e809083a90a4680726519af0f0a44992243a5cb89c706109c3892bbf4772574848cf474e8775e9e0d20143e1eb5d2e08c0854b00970b2e5cd7755d0eb6a9df73bdadd3fd2074f0bd074f8e97b71f8410425eee5e08213b08dfbee56d0821bc60c3ee76db0ebef756db18dd05e1f65e0b21dc6d087723e6706234696e61a350ae4def99faea52dcd76db9b6b0f7a015fbf5ba86eff542b8bd6fdb19e96ee8b2d82f3e2deebad72ef2d8767061f6b6bd5fb77b176fb75b6c1b2e2fc3750eee7bcd35bcd3ebbeb2e5669e165aa75fb7d06e7391219be23a8c63bf5deede876d4576bbe16b189dc3b0dde89ca6394d73ae31ac3bc6e8a27b2fbee722e6a07350c334ecc12cbac6765d6f582f91de6de139e7761de6ae18b19ef1f9eeee0e84af3bcb36f6c320742f42d83d57dc76b79dd0bbdc73d1d1d080acbb7db2e783f1737083bbdbfb1e8c0e6e66bd7e37a552d0f6c6d47befed7bef3d7efd7899b977dfc39ec9c57e6fb763e76c67d139d7ec70b6b566ee006cbf968e79636f8c26a7edb8d8ee5dfd3a3e87d31884d9c61cce59b0175aef39b7ae773bd5ebb46eed9f69777b21d0ba171f8f2c5bd8fd76bb6177c3d8b061678f013c7a21bce0e522f7ee0decee5efa5c33bf7eeef55bf8de730f856a5433f3bec7ebda5d6edf75edeed5dd2df9bdee07df7bbb59efee02de29eac4b8afb3ecc423e3ee659773cadc0bd949013a3aa7ac85f75ebbbdba9dd67db917dd7539d733478e1c39707018c2b7bb0ff62e849bedba76affbc1eedd76dbdbbb2e9e6690e1f1608ec7c4336477b9b963f7cd0da5ade35e48c0e91480ee86bbbbdbbbf0bd7eafdf6bc8ddef3dd7ae638c118bb179bbb7dfc2eeed6eb8fc7a218457737737846e17ee7bdd6e5df72eefb6db6ed711c2cbbdeedd5d179d668a0ec3899665bd17bbe17398eb5dd86e21bc5c74d7eeb5bbeff572bbf7dc46ace776f70edcedeee7625c08bbf7bd850f3af72ec80ef2f59c63f8de7bddfd9e73efb5eb8e58bbdd85dd5008dc11e37b0fc22b5eb0b71f00a8766c6e070200b0c33133bcae0d427841d813033c005f8f2fdeae08a1f6de6b08216cf81ef383b02f0877a1059f730e73cfb9b7b05ff7ebeeb6da5df035dced9e2a3d43b89c6d1144f1e1034c3e60c5a0e2f1830f21287241850003380e0314c0034f9af42065490f6e001e984461c243141f92a810608024066032b4c4090792306912a548000770d2642848015e08928221a5e3878e170820002041727870d2a4871d92143901c1920e30e1c1c77f60c2c39326499e3459d2c30e1de8800fd4003e7e142d89c2e409130f4401805c03309122854914281ff061872451984cf161072651922c91c2c30e4c9214604885000340d98189941f1f1d681285c99424092800021060001e9824f1a1088a08a2ece0a3e484c914264e92fcb0e4033d5af0800f4e9278e049130f78c007273af803bb056012a50349a2f850b464071f9c3859c2c3e4034d8a9e80200abd11d2812210f0b8f981490f498a9e34890225c90e529a7c20ca9222292fe448d1e16b001f7c88b2636887251c70e2c487280218c0122651768880c95092a21f983c71a14711130fe8c021a5484a931f98f0585b80273e3429da618994274ba21425296af2810ff890d2b106f8a14907984481426fa22c61e264879d294f98b89c2d4092273e34911285c994243c3c610205ca92244c3cb0248a0f45529214fdc08467ca13262e95a1d16b6474ed51c9c8c8e8e828c6cbc8c8c8c8c8694a8ef86464f45c2b59a3a7e4888d8cdae8a89518f19191917b4747eee83a6223a323a9c4888f58899191d19191d1d191b547989223366223a356b24625a7e4888d58c91a191919f55154b246ace488f7c8c8e8888f2e256b647474f49418f12ad923eb082a39e25572c44747ed94ecd1d1d1d153b24747ade4888f58c91eb112073c357877f90352966cda91d2474d2b22ddf9e3fd17999daf649a1047979ad093324ee952c6e82eba0ed1dd7320f78abae790c98d3e6e2946cee15c42d26c04cbe09ce550c94defe491565afb4b579e3d46eaa6f3eae850c94d1e1d66ab15715fb78fd71115a3574bf0ec8f3e6bf97a795147377a9ed5fdf3a719719ff911cffafef27ede58be5e44ee2b6b486a7ff4e7dbaa16ae965e4dee1cad7ce52f2fb9674fd2a2fe8c0e7135653a7e72479dc7cab3966886c3a3b3768389bde4719698ee98dc487446129d5d8756397fce565806f647bbe6f0cb2b5f79e7f2a41579ce74c8b15feee2ab39a863a76945a20f3d5a39467627c1fc6493e5316c0ed4cb3054b6f2cf2fad4874e9d7647ff3f21666e638a6e63a73f3d3bc9154874e5d8e9333774a2e7dffe438387c32826560672add97bc5eec3d33d88afa4b7408f3e899d7924bce7cb51ba26339192ddd80e3268ae1d09d925f1efd729ecebdc92fcf8afad96b51bfc94f5eb7cc67becdedd4e637f3756a8b7eb956d41ffd44eb96f9cb2dad08fb90896a0e3524d93347d73cfbccd90896613ff3a709657ce5e7eb14a72c2fcdd729cbb169790c5bec141b911f291bc1305c161dda701847078c83ad6edd4e84bc8b45ee8de03c11c60a9efd4d27429ecd90d29d4b864e137214ceed949bdedc4348f67d97e5ba9b48f3851b452071c5ca0a822aead16c6b4e417e9471810a9aa80113d29041904551ce837a1e94fb01726662aa8647c30fcaf9b0d7f8ee27078c0d98b04ab252054d90fb59c0192c10830b247e10061941f0070f4b0f89f0503e84e121f420cfd11aafd6b448b21ab240d62de37fe22e0dfd1383d671e89fe87c30b0ed4a0a347ff3bbaa011bbf9afb39b2b2842b949001163540e2094115f596af0adef2d72ad35b537c79eb2df75611e02d4fb99f17647910f6cdfd1c1541a6082d6802d20fd650429045ab13210fa953d415db066d0cedc3ee6610f7f382d897f2f060db47fdaea6e0f2a5dfd51456bea2be87af6e324ec0008a186a90e56bac4f8a3531ee8a0665fc931a9cf91a6b50e6b4aaf75cf73bd7ff4351f887585e9d3be75c513f14d1e5b20db61a63145cbe3d8ba28bd37268a420cce56a96fb89d44a0cc2bc9db33bb7130a8c5ab3fef0cf778740af963bba43858ddf72f607e75051ffa353dc3bcff9a71d79e11d854204d15bcbe12121b19603232105455f2d875d05450ad46ef5db8206629899d9316b3bb305d2ee68f0850655fcd0b62b183cf1f5fdd2608a8fcedbfa5dd1000a3682ac33ca882adfced3d33fadd3299d9faa1ed6e9379d5fb315c8086c12feae6010c6b40578ef85afbfab22927687d42047b03e5a8dfe79c56e5826f8cee870be095d156a822245da2060795eb1772ff86a1778e183b0107e7eae3c7f6f3210bfbe63f956b11283a2637e4d2b31e8f29dd52887460a8a8ecd2184045d53de43df31c25c1ec27af43b16c5e1f2fd1cb6a0685994e8f49042118fde399063a48fd77447b01b053f5bdeb4f2829ebb99c316f47cd7394a747a28de9bddcc440b9cdb753f2ed8758e5646fad5906c53de3fe7bb6e7781acf3127223900d401249e16f8c0eb16349a8f9da517881402f8a4fb46d5efa6a44322f957cb51af6250501ea8b50cfb404e41a9bfb3c5302e933c75cbaace7961ceb598fba3367cd08e69956e472e93ca56333f3a71d89cece741708d7a698cb59fbd9b129f189dc1b48bf7ecd5ac4471637149eb33f1fc027f1e52d7738e8904415b7c3ed58ee3d29253d2041ef9106426666cb5d0d990ea8156343abf8619631ff1eae98320f7d5bb5e3eb9e79682181f2edcb5e64f5e4ef691511b7f997f18cb25e641d49f2ed56fb72d3dd1f2c34849532d6883877b9bc6625c15b4ea5041d8d9a48bb5b8cd6f6a148abf3f56a599666c4d19d23b504dfbedfeddeaa9ece25b73bc2163dc2dea8565d0e9de79abb2a2269d359ad00cc5b135a0edd78e38d5fadcdfe58b726b7f9d590f64723fd6a461a08c898175967f83db9e6eb3aad2af93aaa55d2d779bca755d1d753adb2fce84b53f3388fa42c4907ea6cee44c75c63f3cfa514ffbcb4e59f6369e4320bb65da920cd2f2bb1ed4a0565feb9e612cbacf95cca23b666859e61d8849233289dc8bd3ccd0d5a4dfad0ce91cba15f9776e4b9f4cb741d89d765baa4479758c9f7b11225121d736c083a46338f931f638d48c9b19286e479890e41afcfa51cbde5504322e5e8331fb2903cbf68b53ca3185c59ca56cb68a5f2995bb3beb7fc345d0fb15b000eaa72f221760b60390701b96c962811957f6e4de7a7b941b2949de60695dcd7a349e48e607448f3e79aaf26d4e3c4a6b973a06eedc83322dda255734977a45f0e7db523cf35ba23e991e896354b3e14af781d8957c468b55cba1c2a55cbb3155cf9e7d2656772d6cc7730df976ecd1d8c12812e5dd2ca6ff9be745969665ef933e9984bba0ba44a778ed105523177496bc9ad291dc8c1c96ff197e63ec66fd5187eeb0c3163191a885f37051162c447a5ce60a082275e143251b8f0f4126ceb35933bdf9b56cd4fc1f9dddddddddddddd28118a17fef52e10cb9ff3bcdc9a95bddd6944d82f5a39ee1c61bf9cfda2eca567b9d26550ae63abddd290947ebdb443da9f8644d2d202e9eb9a8cf4d6acf1bb817048b717b6e6429660632fc965176ccf7793e2d9dfa40f59726b3664de933d9b435da49d9b55b0ed0a0b982fc120cb973e73295dc65a91e8989766c57c487aa9e4edb2e78ee6efddaf6664437acd7bf66b57f676819c1c7a4f939f66eda7116937d1caad1169df1cc86d73e748bbc9db4d74ee1c297d7be99bee5820eedadccf0639ef7972d3a521297de63b768873a821d95920ce33bac3e4a6c948bf5a114682e2c6817a733f37749d8ff393e543ed25af0ed4361c6d512a01b57c5a0d40ce1a11f6d68cb497864a0bc4b95c200ee97781b80a6c0f0988d7dcb9c4a4464fbe0b043bb9099bd5bd74933461d2b519c574ca1ca84f999ba496392633bafb4352cc4bdeecdb13de5c74eb9445e943aa63ea2b095982edfdaeb0c8a0041bfc5d61e1b20bc447f734220de7dc32dda5f587df9e1f700efb049aa669994bd7344dd37c7b343652cab8f303524a297d7b641b188661d12fc7300cc37c7b3035d775c59d1fb8aeeb7a82dcd9ed92b586af53d0392e10e83b3f001db6437f71879c918bed1021e71b835c26dbbb5c9e9c3be79c736e9db35cb215e7d0b62b2c480f5de859d62c625dde35389d4e26d73c73e9a7d3e9745a8294f27229a59465c8dd5de6d716c835b3057239cfa1cd7258e35f97673ba4fd726d87ec5fde7363b7ed41e414f844fe9e689bd24ff49e47677b9a07b93aa491cbafe7d763964707ea877974ebbd6861535e730aff9b53f863f4ab7d816ca443d12d7f3744b7305a8f1ef3179f4707726fd6e78cb98cccfc3c32337b7ced91993f3691fb26c1d6ceeda7f5b9f37aee3c7fb306a0dffdf132be2e27e236518a322846947cf4b845fc9a35fad0f3cbe57347a310ad1a24a42fc2f9e8ce15651f914079cc81ba34a31031e07b813c2fb2bed4ff1c9b514a5e647df4d58e2479cc7b3ce6a549c480e705f21e46777fb44604fa73d6842c5a8fdef237639cec957f1dcedace511e8df428720cc2419770eeb3e65cb2c670729820e922ad471fb9b6bbebbafc72d79488caba9bfb8e7d1239be9c88e77219bb5eaf53d7bc22bd2c37abf329db3b7948407c8d4e74b101a2cd4f891f9d67c586fca2716697d7182fafd18962952080f82853ae9772f497b326743990bba6e5b116f597dc2a512266f30f9b45fdcfe98e115e7d7b6b42edd6e47ab9e53da77474ababe544eef89a7ead33d36bbaaefcd123adeceb971b715fa51c3d917dffe8d011764787d67b31be84f0801bb26ead2181e6ebfba764ab9b76d27688999f9299903c24a46747da6f439e8c586eb9c5a5e8ebd157238279dc4a734a6b4ee1affc98f39cc28f61b24d4c7d815813a343d1e5d62acb335f67adc42f57135a78b375aae4411e733e7a1e8a2e4bbe43389bbe40d6b75605d93ab5f1ad23d1253ded7593f973cc59a3b239a7185d6719678d8e95683dfa92f3accc8e3990e359b9e45296b0189f1d9b97b53fdae1db1fed98af46e43d63d3f5fe68af0e38dae2797fb43be0688bdffdd18e95169b24d89c6feff6af09e4adc9d3a9f5c8599c153afb35779812f15b94270c12d20fe02fb6ce900ecb3f771304db10f417be42ca573ab5ef5cf29556ed3f67b243a2047928d68fb609cebe4b2d5a65082041965bc909bad22a9d7fbea3e789ad3a79bed2a9e741beea7c5d3420b04155ac285be52bffbc2e1aff9ccafae67caab045072fd00115669090822c7f413c915e0d501083206090455095218004b15bc9095aaf3244075d6e650141ecd6b4b280202a53e4c04e0507e7f39c93feb9e554a6c8e1728b5201723ecf2f4a658a1c2c674ac59dcf738b0659e753e3d75dadd8eb266d1b448401851a6644a10421f83fef8162dba0a324c664d144135c94610515823668bd06c9c1919082f84aab5ef8e78ce5d787511f753f2eb268733ece677d71c82047a72d3d7fcfe89d3313fe5158ade7177d62d16ab91357859a87d4f2fa9cdd72379faf76648380c45b148a08bd1a7d85b3427772b4e5af271b042c0fbd8ee0ad8b3ed9330fad270aa8b27a4893ba680103195dd0fa0312653ccfef0a092c5e7606271454d68d4e6ddab4d9128411b9366d1e0a241e47c8200b972800e0720331484550f6cc43810403195d204d514095d50f481b042c41eb75040f83d833411845da3341eb95ca435ad9ddc2507775c41a5fc40f05520b48a8c204692021052da5b26ef4a409278c00041b24a4a04891aa202105add7a77ab442597fd3796b1480810c2eda50e046094898c11b2668d32648e7dba88f605b534876c9dbc5eb74ea88190172dd87ad3d93eebd099df982d072e71784505a9347632e3a6b1c407f4244dce69f5b94a75390ee7b93ff750f41b2c71dc2d488205ea753cee30e712eb4e2f916c836dd4e45c77cc57adc21d0d72574eca23bcb9de5ce6388967367b973ce214fa72c979dbdb90f855a8be740ddac59bef39cbf7fe7656139bc284fa72c38f95f5c20db6964fbdb213d574760f13a27f6b74398f2e09d6781305d226ed345f689b80d5c207bd4cc45c875e86f8758be0e7708cf209d82fee57f740afa6a6eb5fa03e57e4a3bc4174874e8a9566d9d8a98432fcd6d9fe8ee7e628ee87e74da273af4cdf23976083f748ba753d15d0eace9d19d233daa5391b5e83b97bbefdfb92811b7f9cb77750415bfab2370f03a9d8a6e11bdc7284fa7e235e102595fed2d9075a0b626bf111fc17653487e2959132a79e6cfafa9f9ee10e9d0a59c448e7e3522d7d0e5ebd9ac97b34b76fe7e574748f16f81684466bb362fc7267f7b8caecde8d8e475a08eb3f22fadd1d7656771b6748e0ed4d2657176462b7fe632f3d58a645e922f8bb37db52299cb1b34cf688d9f61ce1ad10f55820002e9896a08b2e0469b97b2495db218f1eb528e7ee966329bfbdaac3fbcbc41a3f587979e2dadfceb99438d48e9bde4406e85323a542252f2a54454beba2fbda443d1bb346b5ced487b24e2368f3990036a6c7fce23c9cf0bb91ad89e57d4c3e8ad821e43ab763cf423aa3c749e56f5c3200f510f7d6b553b749d563987eb10faf6403ab4ab2a52025b8e5c789375eae9e0d0aaea665cf8ba649e43bf22f4bf2c4701b5aac61a5a553725adba7c8656edf8cb75b802e62fcf40abde5f6ecbf88b8790bf7c5bc5e3eb8ef90b3a50f3c89e171bc6c25fde8f5af397cb6d5e6722e236bf5bab9c5faed3aae797c756b15f7ef9f65c7468d5b82e723bb0ed0a0b96af715730b8e29defb7bb7675fbe743a9569d004d45a1789cbfec8bec9a280e2981ad0523d23817d43bbe83740cdfce834315214a80042192b008010612ce04adf311e2c7b0620563d05cc10a5c04c5be81b44616022424cbb7cf4043ff7010cfceb7f3b40a7ad36c35a6d9efea0455fe519d4eb14b815c1e496c353e7b3b6a8714b1ab133cf1ed3a25d87cb7b8e39d6f66de79cc309002a4e625b6bec1efaa89237cbfe077b5458b4ffdae9688c2bbe469a4c8046abe1e81b1be8220055ffcfa8997d85c17bf2b2d523c87f95d2981e67ffcae94c0c25a911210cc3c91925f2f5252d3c4131999be162d0109a8177c2deaf202b984af45275802fc2ac50839180016495fa57c497a2311094933f290907edbfcfae49727ffed24c23c24e3d9e58988ffb97c13ba5cadc8a395593be2bc698d41d23f6f6f8dc8737620d7731f4e9e3b472019ff1c92f155cad13f87de9368dbb469d347df0e9378d876e5c4153f7fbeecac678f871392f1ac15f16f7f730a0ea6457dc4bf1da88fcca1f6e7b267e587de5a116ef344dc063aba6384dd791176478be4ae6030e68bfa21aded53f89d1fbd9befe6e459247ffd0872af913040fad2b3cb2eed902125199661a8717f2cf6d921403050c102d9af2b03100cb02c0cfb4d2b3b6b48e433ad463fa5df0351f8d9319dd226b32c6a539e69574e9079a2d36987ac1befdc621976bff657eb9dcb97ed0e61240b6cec92351db6961c84ee30ac09113d24a435f3bec032d6996519184d995f6f2eb10c0fe9d7e595398dc896b9628cd1ea181dc718612a97139dfeda5c0992cb373a859f290f9db23237ebb37ae8946511b1d5d4bb98dd4c06d329cb83b81f5e391fcb1d85da2cfeb2c616c38d6f7e39f457d94c95b7bca568d50db52ebace699e5f6858b5d157fd2b9b413db1f516d6f296d718302d7de52dcbe5a656cb0cef3c0c97315dde5a3254bce5d9b651671783bcaed57aac6c5ea841f3e5cb15af80b776e5051a8b63e618be15ddb2dc398f9a103bb90c9feb657f72fb7236b343aab46a35dfd576796ea782748a69063437b37863f25d7151c6f2ca66f84b19306a56adaa9b14068b985655cef2965bce66dc0f14e763b995a55527b71cc8e9740aba36a3b0e58c058afb89ebe3dcf27525aae62d5752a3e519c0669c3858de5468ed8218e9722567759328df7ee94e7e30b23f28e7235d8e9132c24bdf955e57092fa39a976cbc64b3d7c5938b31bf697e572b332f598b343e6bef65913e985db3c6f0ec4f138a3406e8b8e142cbb463c4fae8ef23ad467f754a66f14667b51af355c84b8733b4ca816a701783723f6f7dd8335ab378455a799e512fb1b0f51145754afa86fa45fd7abc305f8cbadcae2ba606e9364879d1e7a8564597be9a50bc5c3292f5468f44e978be79f6a853796acfaf67bbd73b50d7c81e460baafc86a1858d1fc06f185ac46891aab6e7fc356a35ec3f8a62ad7abf23c8e521691506162a9c9a6f97ec56d12b2af5bc4a722bf7c367daa7bd53905647719a6fc7e8ea1b8bad278a8dcb7cc36733cc66f3d42fe655c7e5f5e679c586ec387f0fd98cf3d1849c99c668456d663e6333169a1dc2438858cd4be3cdb4ea4282f93373a6556876c811ccf9a35f17addba92c75bde7d4dc40b214829458cbb6ab15982fb9bf3c612e93748879cceb4dc59e9df74788f3c19c59132a39b3e420ffbe350ef2429ce65626e431f9b2c82597ce5c2a398dfb31cf400f09d89fe87c30dfb84085f1988ff1986fab24b6673e4d69fe98413a85796b4292a63a85f9ba1b76e835f5980b71982524938ec58cd64d7a09f34b2be25f2ab9dcbec98408d921ee31c730197b30cb05723d76e113acb6d0f2f277b58511dd021b2ec7119e0f581a826501e1c2e141344d813d1a946e7e575a6891d94e2e62db9516561efb5d65f1c6b3ccb29d465bf6bbca628d4c96b07859f0b9e6d54c6f06181a27a01a7a80029734648c68030a576c60cb0c8a00840fd228c145191c6c65bca00940398ae7a805356823066a34810537d0810f8a60042f667ad0451b4ca4f142192c3e8444fa82136af0831d9021852b6b2c13b22003191431c6097a108531d91965dcfc602d94894bc81ebf3fa8f5e11f20d7a9ea23cc6f1144f1b019608c20e65743c2c697b3f7d48b02758add8990afa1534c43a7b4305d0e74cd1aaeebba5667dce0afbfcc20c25fd77579105a9d08e10205679037ddf544f5b40f3bff784ec256839520f7b32b4e65910514efe3779545952448063e8baf17660c993248b25d0f79bfce3b6487b06b8f7788f0b3f7f3cb61b33aee2664061a5a1583902035747b0c9bfb29d284279a20c5d6842bbc09605266dc96d6a912fd7afc1566bf2e1f5bbe412fa8670bd07ef97c0fe0db01b008682fb3b9b5ce07764fa7da3bd58e6a31df6e43abaae7802603616ad8950edd61bebd2e9a6fa7c1dd4f913360d667211d13e4fb0c1921dfde489de255f3fa0d81e59dc7d684b692d3847284cc70daac9a654234a1193a5543a79cfc45ed468619c478cc02715e214ac7ca50f2f59d1d82f93acf0e89be2e6406c7b2316fe99f1a60785701f04b85f0d81f949827de39dfe4b4e038e050030e36e0e0da0a8e1c6dc5ba6e4e271c39daca3b6f0107c781ba06f71371c07179f2d5843613d571a01e5e85d402f8fcf3e98257f8cf9765e0e1d5fa177fc76bf6ee3ab6df0e41f973d40ed9e18f562733fc73219d02ea627b5e8514990168cceab8bc07ad3d5c98165820ce79cc0b300cce7966063ae57c672ae994739f3cb4cfefa04e168873d4d4618138e733a82de309d4e4246e014723bd284685f2e7bb2acbdf8bcf58dc4f8f3b1d54faba9fe9edd6f493a3e6762a870339d3dcef9945d078627df67dcc226848b13efb741641e38af5d99773ce226880599ffd9e15f539666da45f35de790b13c7acf175a610f7b3399fd5b67fe5e04c4ed2846e288be99473cb3ab33e9b667df6d160030d36dbe4319d4aea148b61c25619cb737e41ce594bab96d5bcc9683ab542a02c1a61d667c7accf3e1a64d028f3e3f965679d497f74d3e6ce91e7975f74c8e48fea3ca7e99493d334dfa62e4a54e4fd11f71685c28a4b56c36832c043ab9ce8a0a40728adaa2ba6863365ce9c3993e60c1bd78c9757f8ebfb126610be1d72bd5f93df7a4454be775399d37758facaf6e3df1936ebb355e2952d0beaa7081aa9555dfefc6942efc7dbd029c7629c8f7314ea5162b60c315bc6bbf82cc6fd6cd0574ec27e19ef2a27bd13e37e188d98cb6b8eaf2c4607d7c69dd138e7d162349fe32f5a73fce50ed4f2f2d2e485e1726cba0572799c6f815c707d2e773c50e0e0f24efbcb2b6b79072ff09caef3b1384ba7184ba770a035f060d92aa379e775c5bc734e83858d56319b565521685aa5a65595a9e035d575f92ae49d5716f358dc4f912654599fbdb23efb16cdc2a54813b6accf7ee52eaf91bee1118fa65990db539b8a7f3ec45675fef9fbc18d1dd2efbc91e8ae31f2022dbfab206cf9da58fe39ab79ce5fdc4f743ecf5156fe35d23f5e13e3b6a1dc53a9205fe357fef28f7fafe934a14b6674a786fdcc8bec677ef472567fe96e56255f9ad994a589c96979691ebd9b45f0311a67ed326fd5f83a9d7afe9056d4f7179bf31a9b8ad7859a1dd2bc1005e417003ca6b8e7eb3a3854966ab7e595a17d81bcf79e6373db2845dbc2f09ea98efbc1b13ecf63f8e7b507907f00f8c7e39fceba9f94f3819e798dd2ebf6a55dd56eaaf6a83d1e42a14d89ff3ce57e70703ed0a3a475fb9a2ad18afa9a7ae81207176312ad38928ccc6f97bddc26a63a9b721e67b629e7d78cfb36b529e784c8f6fdfddd94880a14563c48a339740a874e415f35b12d1948e872c7f9e5554cc06d82a6d8212d4d706ad3a64d9ba037779cf76b9fe784a0b878660b04ba3587884155aa0ce141bb07a8370f7d882041bb05a8390f5d5b0440e733b68a12b262eb0558f1a08b66d6dc2097f5f695cd793bb7bb22b7a5d116e6d7b748fa5d202f106ded3ba06cbb2a4296af5986c456a7c022d8832990dd7b22e4879c672ebb3c7a5bfebc3a11f271c64e85d92edf6f6cc65ff713833a2299c2cff43d11f2161d7a4eddd6279065309218179020e24c0ad24871041382ead6affa751cdccf0b5a17e27e1ece104ca83983082b5658085a5f263f461b121212104153b4ef73cefe76f43cb1b5efbfd7ed98b5bcbd6851a7d88b0dbaf34d71fb8b1784b4a8adf7ab5974c748433aa5ffb1eb31e4360c92b5ca09b91e3a85c52b5ed1fd446cce0bc68772fdda75b7ebc8d61a38496e39d1b0eb7b6f4d371f9d73d06143075dbf76ddedfabdcb82f09a45f6a3f57cb531d0f2f820bcde052f07e1b31e7cefc1f78230d683ef3df8c2b02c330f2e907ecccccccccccccccc3fd876adb9d78de5ac67bdf71c74cf39f75c16f0a178dcb22ce730b6c460c39db1e62e10c7901f104a2e25e659964d86f1b5eb6e27f98a41b74bd3ddcebdd7bdbdac83760e42f86e74e854745444f1389c1076f3bf07e1ee3ee7a07bceed5a6c61b13def59b3c8fe0577c8fceb9445b34eb56bb7de73599eb366b05d17848f2d7ef0f163666686fcc4f83fd8d7e535fed66cfb8db37dcd5f7e799c5de55742907937773504151f675b4d33ba75eab98bc6753c0f21e4eb82300bf407219cf53ddc56455a5f8c0eb2c5a87f70eebf07fdf2224fcfd9bd29e5a897d5fc76aab93f6b553fdacd59babbe5ae5b6e5ededddded652ee406d9a0f3b35cb60663063a1531bf3c66db832e3d737969421984ceef793bcf926b2e2d4d48a30f6a361cfd8b1a3f9c5bd6299ece390877378b73eb76d7d1aa232d0beedb9afa761bdba777f7edcdba20195f52ac18323cd8528f64d62a2cd874d69a65c58da9df4e797d7f04d459d6295ecdb2e8ab56e5277e57585879e7dbef6a076b3e0b6b37f86bd5db3aa5f32e5adf05e68adf150faebc73d4ef6a07665e3a9de7ec59a5bdbdd94ef1d5a64d9b37fec12114414742422a825a38e71cbb73dcae8c1645fd602321212115f51933bc19b470fedcb57bed7a3e67cd15f51bb9b1122606cfced4c90c7f63250c0c1e5bc14d7947cf131bbb26d4cc539e4b58b2b21ffe729ed7c723bed2a9a3a644d75ff5e82fe8d6dc56b1638c44071a43a79e5f33fc4b75ea799c3f3af5dc9a413af5bc85fc7306b345afa87f5e53ff9ca77fa840414242420a1ac283d8083e00fb7b950a85408ec87d57a3bfdc6a30db76ea59fe3cdb5a05af5d41195871e6e7efca8ad59535f3dbafceafe6993fc84c5fa756bb5ccace5863baefcb3e4b8de1642c36e7e33cc695d3f679eeb30eb6a1cbe1577fe93da91f416210d2aa79c27c35c954874ef1fb8b023948b74e39375913b5e9a064ef835ff61f84ecbc83cdf2baa158071b03d15043aba03bb701871c746895c948f695bfb2110cc3911554bc155dde390d3b66b5125d4dc8f4306d66b41639496ba9f275d15ad490d62db3667e7d1c695c6282e46cfb65d745dd9671ce465c9b414d88e9bc2ebef234a10b0c907b9a105b96b726646dab207dd7a543ab8ce02badba84dc35f721910f276b428eeae0f6b709058e9f2614563c08c7a516fd4bd2ebf85d7db9e2a5cb2097b7c569e92cfc166379e73a58ce4b55738b428d083fc4dcad47cb71ac762bf3cd4d7ec327b7dccd9e28368cb25f4b6b692b32e4fcbd890e61d4743d0dfe95d121cc4d474c9d3946879cc3771a12f82eb3a0946ef26b62b4667f5d9e4de9b29b8983235d7665371beab5b98f33731c9bd12f6c5e7e3373b4c99f730135cebc71d3cc5c62b3668ff9609e396b9297db993477dabc99b17db089ba68a542811c74e9fc8290c83d742148eb7b2377646a1310a77d73a85aeedce859a793bf2765bb937599bc23e658e627294f529e1cc89d30cfe650c9f7f9a49d4e986727cf3049815a2b95fc74a379e675730d838d234f381a463593d637b26e27e99a9b345a33896174df5eb45af0796bcbcc97275e00bf2b1dacd1019ae714fcaebc9079d2d7f94efbfee5ebd1a2a6232a96e3e0385bb11ce7b9690e55cca11bbd35ab7b76cc71701e90c3d20f716e805eaaef6f3c5e37f06746300c965b27c79975fb232a261c9309c7811c8e85e3a739a4e16c2693e3e0587ec2f19365a244ee4d0ed4dbac463fc4ae398e03b59fbce6f816af1f1cd09fef30e1b8e59be398db3e1bb56e68513f16bd6ebeadba81be3d1d5ad46fa255ca51cda145fd38d4e49bdfd07aa245fd6cb24afe5c9b6c443637ed88fc12ad58a4d02dd7e954c3478df8e8a6af1be4400c77432f6ad9ed25cc1be077e5058b66b55bd0add6e610111547e4de7a1a91a3bf5c5a9a66b56b9ae540ce6aebf95abe52d3dcb22c771a2572cf3738cdd757839a7b41ca41199a36a16b9943af6d72cd1ab2e873597227b77cb34cb408f353468bdc4b0abd84454b27d3fa9ac11560aec8f2f2f4da8b5a28075ffe00bfab1c5479b9d2f1ceba751675b8f8dd1c22a2f297ef3bcd88fbe77cad57a6db0e35a1cbd9f8177e57578c79a1cb59bbf16a9dbc4a8fbefdb3f9e53773dbe7d24c3e15fa696ea74c34a3db298b16b9b75c9c3d515834bad38a5874c8d1c668f4d8ce465c7488dd7268419a756ae5bfa63aa68636d0f889795a984babb61d2c2b95d8ca43a436c3dedb8642395a9b366b5a119397fcb58addbe7b58f6db9f964c13ead27c9ad073252ec7abdf784dc969721d3970788edfb8949abb59b73fa25272257f594aaea8b5397472a3e7e561eee6d1faf213bba0d1da7f721768edbf1ca879d6a7e59b9d69fba932e5937337ad7f44a5d96af6f7c457cbe710bbd1b7bbdcec59df5bae39d7eadbf2d52ab1f3686e5d5e2ad1fab4bce545fd5dca29951c74d0c1767639a51caf6dc641074b25671d5e630eaf1b0ee7034fedeebabce90e0fb7bce441dc8f921ebec31d35bd851dd749e1dcd0ce0f4bab4aeefc656119da9dd63d516cf569716e797d5abee4a6935644f3a643ed2737692557e282d7f83bbefdb3e393bad3ba790f5a633bef51729ad33c2b39f420ae5d2bd1f61e2ed01650aeddf21d4fcc69368f6bf6d029e8316ccdfdb2146137b935dbddb49c6766a6297d6756ffba664cf461e99415c4f940df416bd4416b44d1bae5a0756b8156140e5a513ab47a0eadfe38b4a66e684d6ddb15b58d99f9a243d14bbe29c13258ae6ba3f9a6d6a93df3867fa2439a5f5ecab8542add70b9e634c66ddb9f5d9fd2e61aad5c043ffa467730b7fcf220ee873a7425d0f9d42d03005e9d7a45f9f0baf538002863713ed0abf7c4e883ae5b3394aef3a9a8925bbee3bdd7dce4b5cdfc45217ccd2dcf345a19cbe59a437f4a94fce4d9456bd1fb929b686d336f311614aa6e0fd7a7c6d7682d825f72cb1f96a7c4d3529a4a3a051d9b3c740a7a8c61ab6be6e1459f120c8345b753cce5d787d13be2d13c53d0f2febba2e24a15657c90df55155dfe066c7e00bf2b1b1001e6b37f1ec1fcbba2ca23e0778583318f832d9ffa5d59c1c6e3408a97cf7ce5dfe53998afcb6be2b8cc32df5665bedd78d4eaa3eca6484197f7e67c167b6e76743e3d87a6b887420497e3f8dd7e2fe769fad572d895f64e08302567466808158c51861a3249cc600a48628898821b52ec800c25d8402a6107ce0c75454e9c800a339c40a28a96231cb0c1821720a60883c51b4a60425342142f094a8841962a58b6ac69c11b4755b049029736b628c18c0b94804543821288c05a48228a59cb08cfbde70e0004122e10a30a4300c38b1e00618d258c018305134800c27604011c01e5cfb9118513417042144c68e28c2dc2193158c14a0542c0600c30908bac8c102050f1cf8c17214088168edf55129060c337342a303734c3250935f8d5cae0f19efaa8939ee77942114163d004d1631e44c2154810e3b3df1512bc784c9c7142421662b0842018b183236078f6658f1d40c30a1969a4a08d17458411d23fe81ffca0c7ccf3bb18ba063a029a326cf0d4ed05bd1f1c9c0ffb430213ff70706e7b4898e2df737fef591d8643fa1e12b40811f41ead4e7abec5bc1dbfab23bcf1d6efea086bccbc2b98d160f4f07c99c2999ee6f2ed4dc4b628f7d4a78204915946e59f3fcd254ff88a1cb0cf74998b97ad329724358d6dbeeea7e4eb7e4ece66224fab784bfa6e33fdc349ce87b905af3187d70de515859abb3e39e6fa444d886f1ca839a9551999325a25bd9dcbf09856e1f07616c3615a75e3edcc859fe81f94b7b314fda3c35bc8e1d1754c464d56e37c3a07ddf629790b9471cc1bd89a108e4ba8699a17d9d76809a878cd8f9e67f567e839ae7364d2b9f19c593be96ffcdd78a7fa86f2b01af703256eb4c6ad74a215a5b9ccbca40965cf4ddee3c426896874e3df7f6e6942a84eb5b326d544795f994bd5e93095e7bb91b6ba626a68155c7e9016d90c28e1a1558fbe1e5ab5a3d3ced33a647479472beab9753a03429931603ab03daf71576448f1d0d7a38b3dac6063df9b03d8b0b16fa7960092996862063c68806c1eb42a3e434b3e0863e46c07e6fc11739ad073e9300cf3a38fb3ba92df1e6233bae5ce2ff8167d4a300caeccbb34214751ec8e09727b6a89cbb793a1e59dfb4b976149cea793b2249d249ea49e1f8f8dedb17966609567065eb192e5d75f9a4e723fd81a6c4d52525212c6a694a574a5540563c38342599cd429eec1b2412ccf392b5b920afe606b9c4f7b0969db5028c7d6b89f67c6f9b4b3bba350db86adf97e67506c1e1b2fcdb7bf77a6559633c3b327cb56b71d76e7fb9448afbe73b055ff6766479f60ab0f5b03b7402eadaa0f6269557d59380cd4f2ccb4ca69e8e10a156478cd96559fb12245926343cb03b343fab168467c1e7ee9547ba75231c82604b5eae9540fcf101f0ba4bd5e3f29e7b332cc85c117c80eb65f774e0635264cc7d03feef0cb0fef41f16c3a10cb37c4d2c38e9ae17b63f85eaaf3a388bf73feb035d082eeb1a35b0f96ad422cefb95e86a612171d24b93d5553f3ed5bde2bf30db7c02c5fc68581cf4117f4daa7bd33486bca3d5a5156bb309d8affa85b61b1ede8dd54d0c66d7788cb8172d1b94db95d189caff323e2ff1e5d4d8de584ec21b617e4b6172f5ebc78f1e2c58b172f5ebc78f1e2c58b172f5ebc78f1e2c58b172f5ebc78f1e2c58b172fdbd2b785cd9a32c85c4185c3e2aea4412326cc13cd05894d9932be5c9185b1a871b240bc8ca961817849f52c102f0bb5903b967cd9ee90175fabdc6fe360638f2e3157ea51a4478f126b44b6276235fe446ce623962dcbd040c8ace452b3a009be53b63b44ba897969be12adac2181fe3c4e06fc6a47a0d7fe220cf8488918f0d1e5c6a576cf24a57f8af5f15a8b1ed98c60f9ce11cba19f2cc79adb7c6cf3d885c472e8719efe9a5bf96191d31f5dcc3b90db2af7dca3bc2948826f9f533a0a0cd03d7c54be8db4e545f17981c066ebb984999bd2fd2c7ead7a6d8598951a24a48f7437d51a122a0bdf799c533a4a51fc22d4336d22d7868d9146621ae5f2a268b991f7576b464aa01d814eccca4c6b458efe796c9573b4f6bbeebf5cae6bde6722727f51b7e83ee8ee06485fbcd80101c67befb9f379ce495b3dfdf3ed39e7825cd6655d63b6ea7f5ddb8f9ed4a683b22ccbb2823410640ca1216cba45d85ebff79ef313c256b77f5bab9e3fd7413d08e1176c5996108bd92aea2d47b5aa469e56b55bee3d29cbb3ad5517f3c51619f18aafe49775d1a1cbdbeb45779aaef3b9fcc518638c31c6886158a443413a8b86fbc556fd2174e83da9d7565b419e50842a2f8032c6208218226c79d9dbec4c61c82083b0b920b7e72d11266084adc6779b4369e095b1d5ed2174d4a613a96c4c66aba7efd30ee11d2410a82cb2cf45fa990e6163df204ee7dd3a5f1fd4a883dc9ed5588ced01f5f3171f308432dff3bb12421778ede88962db31f2201d82de5e21dd31d2140acbbd4e59cb3fd830986063e3e62862a7d672b91d66db159932be4632493dd87645842b8e0855e4b617dbaec86c793259fe79f684d0e59feb746b424bebf65b843deb716283bef4750ab2371372539b82d6155195274bfdfef8fd517378d793d2c134bd2703dae47125d944f1f020a70eaa87d2dc749c60338b59d1bb0753d077a1f3238ddf11d8655d97b56db660a209287050853782185a7305217a30051b2c610433da68675cf981196a1c0c4cd0b4df9510b4586bc8af2833ca90668cc1c640630c326448a3edf4bb1a238c5c4d48101b90db24ea755ad5286f662ccb9c19cb28d1f5d89374877dff316cf6a131ae18a3ca4bb73ccbb2cc8fde396cd6f85856922537312bebd4fa355df7e6419ca3990eaadd906a088e21656cd565051162cb76cc4b2dcaf93cdfd28c399b4b2be369f98e111d6f6f5a715cc78f1ea893d8f8187e576280797965570b38bc053f7aec6a8ef1baae0bf39e6ed61fb09979694a8f2dcced54aae43af3fde638b3649ad04fd3e492b39efed99e7babb66dfb6d73d9d9365987662bcf39075bdd32fef2e750dccfd39ef3709afbcee4ce694216dd3972b9e545ae9ef55179f66dd6f89b69def86a6c9a47cfb3a8ff86b6f36dd61fdef574ea6d3a6440090f3db4cae4d4819c56462c6d9d6ab3d5204038b46ace40631042430dd1a28fc77a7e7484e98e91cbd999d6cb8ffe55d9a2471a3be59ec32523f8bf6cc140d3e5db75d6073cdf4b04e10a9b344028f3a7dfd59832bf37ccccccee21d3d7aaf6799c85ba09617f1e6443bd5510b8fc73773f1bf48af0c4d7189ad872da1d23a6cb135590cc9401f3454b1636d4248d91a28b952a67ccacc06cd1b2860d32491fe4471a98859d93c648d1e5597955ce985981715b9c96356c9049a2428abed256d09c09b3e22d6cd66c19bcec4c647edd888d691bb1ed02493116b61ac3af3fad087f0c3ebf90993ef7dc73a6200b645db2b5ae2f68c24276aa8bd8d665b7dbf79e69a5429f73ceb450c8e8db53394297fea6f4386bcf478fadb22a6afb68f21a3f6a5efb9fefcac003c320828fbed133c77199e36dc49643e5cb62ab3c9ebc5d76115b74c9dcd1b9b763043e77ff68a5f2bb40e28a21c5b76b8743eb0f1fe3c532f4300cee8656d446ebf626dad3ce6536378fee27d5c332d0c03038af2817bff6bc33fa8df6b0409c934e394f61ee9c069661178692636ea215a5bdd49092d7769ecdfedec1f67c3bb5ad92b466ff4a330a7f5d34ce63d6a975273d3b47b6b77c7b8bbea31bb6c4580877cbc30221ec33f07a5a2ccb824f09f8b03c25207c5a9e16381b729153874ec95eb762ca9a916b275f61c8becbbbbd3b9b213f35727bc680b17265db2acb4dd49a3898b767cf1f8598a51d29fd835a9137753ad51bce44f9cd66c35f7e9a26d766dd32d9ac7cc572bef08aacb295e815232fc78b2a6333673a0d89fca67c719986d02d4d0862792f4fb233671e6c5527aaaa93ec7f409d56ad8ad98dada2dea17ad66c86e76b8f5c1e3dd2a16bd9fb794f489d64fffac90c3fc4de8e8956652f8bada6505d9a5bfbb0673aef617ca51e115d1f8ddebaa244bfe8320c97bfe757098a9203b9e7c2587d7c79b220caf5d54d793ae501329aa8220d2058818322822aeafb0b2f9668b3841630ba4822a8c3f8eee6c282cf31ad3d34b4aa9fbd061b6acff7d6d4b7996f7fa8fe8112be3df6ae1ea8817a7b1e305bfc5dfda08c1ed4f7d549f6cedb82f082b31e3dac46cf720c03749eed703e77f7e6bedb6e67860c21d1c56eb22f2ff54ead3bb183a41f88f1019887cf8bdcbbdcb22c0b5af072be1a7c8faeb3f2fddadbdfcf06b173de1ddff29e7ca51ebde544d75b563ba7febaf081144f80df55186c5e9ea484de13467ffd53f2e832cec5ac6d2445ff1ce3687969bef6b17c3524d549d1d77527593de236b09cded8f6d997913a3312061561701143e608f3d7f82847ed780e6fc1b7553a7cc7d0c9373fb9e6f23433d766b36f617e731d578879e23dcc3b478101e69df3f4bcd38c98bcb3cd4f1addc9a8119c1b7af253c5f17507ec784e769a37beda03f8774e7e437ba2d84eaef9cb2ced86cc373f4d4bbb41f3beb9a13b39bed1ba8304c76f7cbfa8eee4502338ed37bff97ed1b7e3b875e350ab817fc7b75937cf684f14db469d647fe38d64c76fe8d08ee7d0211dbe39c97ef39ef5449d64bf43b75328d774f8fa8e59dfb7e04e3bc2be796b4674d0d7291475e81bad39e876aa057f9d6ae186a6951fc70d3870cc6aa419d1266b47eae69a923fb9bfa1b66fee71d05a82972e916cf4442bf422f7b2ea501d87de9a917e1d975387ee6b55e61a9c9a6b9a63b388b5a2f7d28b602edfd8a2ef1ce1df9c7ff3a64319d39dd2671e469afff1bb0a63f5439966a4f49baf8624f39297a6dce689bd2426cb973c73b912663d6bd1e3788e6ffff0e4d09bd40dadf135cd791cc869d3e43dab93ec2d3fcd29fc9b3fcd48ffe6252fd19af926b779620d496fb3bf35221badfc9b9fbce78d6bb366afb9d38cb4dfd0ed94d6afcdaaf975f2cdc876cae42607ea131dca9cab469d649fd192af03b9ed63d1af3b4d0822bdd07392fd143682e375b44604c4f22e3ab34073098615f9b21e166cdeaa18e5b92c65ee62e89f38df6b138a9363275fbddb3ed20c5afede3f8cee600e6906358cc62944a78f6e7ad3259541e3d840baa2e5092ac088216326cd5b03abc8d3ac3285e64378d014cfd28e58fe68a5196b37b83055e7d2b62d4a917dcc8bf0bffea70999e82e0c557abbe6ad1d29c14bcd9d6bf46947ac2fd65891c808e92f97188dd2b3c9da1117a6531acde67ed450556cd5adfaa18bb1b4238fba30b44ee1bfc0d0f29db176c3e977814424254ac40e9b6e8c05e25c3e5ede074df3f935c974aa04ff1e75490bc45db155e792deb95bb930ad12d3aa8558b28e51f4808d2faafcae7a50250c1b5815b6ba2b20a7a106cb9f076995f4e7425a55f2c79abfd4868ae19f2c4d9306b5b9592cf5400cf3d6b65318b6e93c1f7ddc79cf492e08b2ca6fdfb78f1291db601c75e1620a195841069825daf82fa030c38c355060b3e68baf290684f1032b60f0408d36d604557ffe712424a42082b6566d0f9e61a045cb0db2f460082b6404f11292c028421a665411634dd00e4300c38409dc98021826088abf1a18473a40a38b199cd1258d2b84d9303d5830c106172768a1022582d6d703f299913dd3a8c72563019e1ca87be614d24fd29f66c3d14b67e97c722a70c8a1550b7832ef8a2f5f574d7d5d5e17d5021e3a14e84570d9ac4b08851d7c56aebc77b967e55d21da9ff84e2e27154fcc43bf22b63d5c636b32499dda242d3aec90fde1f591bed8b2915eb98a94f1243dc789a84387b243b2309756b5c7bdc206c443ea958b780879cbc7f06f5e9a10d1117fe9974b9e1825424ffe341b84e889f6742ae3ce9c691788c43239d740296263eb24b78635492d97d7e4bf6e3657e5618ee750b7c6b1795adeeba4d8499dd4499d74ea69723639fbe3d3c37a40b12c4d68bae4d3c3b6cbfb92fafababc2ef1bd2e27361be65c53667eb7fdc1e1e41c9f81fa39fb69be2db67dccdd9f26341d0796a1e4d023b0439e4397c0aa2e873d5ee30f00bc6e4330afa8c7e1bb3fd7fab0e3f06bbadd85811debf1ec00c8f1ec3da7677fed8fcd2abd74ca7176695dd107007c3850bf38874a1e851f8b179f4ea713ad27f7a1125d7a85adf413ddc5e578564ad4ca43f7317bd529e800981da67da0cb2b6ec1b868d1f2ba74795d5a45fda7c7a1bfd513f392de152fcc1bf3be3c300f29f39ff85f97d7e549f1a828d2ffa893ece453deb3139d9e298f23c971a65398c8a905a7d22a24ae02a586569d682df9c9a1d3d0aa1c872eb1a1ed14f522fe12ed31c106d4af8bfb716b28adf131293a051f150fbd66ffba381fe8acc6b6e33cdc0528ad7a6ca555585ae582c3a879e52c0f19e9215739798f09b6131d3a79117f8e0fbd2d4f8bfb716b544fcb4397a56c193ef422afbb66864e41682a399d7d45a7a0f7ccfee27c60974779edc956b8ca64a44e41776b2c87d79a1eb3f2f72851289d82ecee3b7cc7a114fdd02a77e854366eaf63f38a7a1dbeabc35713da71a09ef349f1a8e814f40725c67772faba740a3a0f77c1ebebf2d0a508d87f801a1293b35bda1193436995e6d08b7ed821fbd0a376c4e4ecab113d5a33970ee47acc7d1766cc3a059d6742d1e33b73c784ae634679a89963d6ac85091dc78c72e9cc22fe1c4a43a7a0e3e0200ebda175db6845b99f1e0aa9497b7543551446abd7d4d7f830c8b3479aea14fb33d3a35fb082e5526e06c5fde070cb335ff7a3e352078ec9ebe35ce7e69de7cc5d9f8abd736168e9c25a5ecb98b79cb7b46a011f060bc88009f396cb9556b6adda78b3750a3a8e9ffcb15bdea3c47651284592e7b55122ec975fce9f56c31239fae7a014b5eac62d6725eccfe67c2c47a5e15378eb0a6ff97310e763798cdbb6b14bde3fe16c7e13e6cc5fbebd6771cc7478def524bde5a5f83ab5a58cb15c14c21f38db76b3f90d9dc28f432bfb05b5bcf3a1edbd9706c2ebd4372ec88d7f39d12f5fbec82fa9775fb2e795642c587a28e2680df2d549cfef10f1b34f791fa79fa8b4ca9415ba2227a15308d1cc6812001a43140030401c120b870422a12c0b3f14800ca5bc52581f0ad4240852c818440c3186008111001000204d1203fbe86ac0f13f83bdb76028c32171b37034de7dded63de0933a6f7b4699fec7ffdb48e3a52ebd369aef8350a14f6b22c406ba36d43b607d46dba63b13ba134f1f031a29091b102ad1b71130f7a6dafeb00fc84a3c7dacd1966baca1c0b257c4fa20cd40891d6830ae8bd44de24464b370296e58bab75dc0b239d1c90464471aecb7e3318de12fb0299bd78a58c2fae20db46c2a94f8d2f831c8cd83372e85035db2ed73be10ecdeb619d0ede8b877f423eef8b5d61022ae51de3f3219579488fcbf0522fb3b295a61ba36e8a72db2dabcde34ccffb316f5404cd4412724185ce6eef5d91150c6503e13921b305488e3e3c3b0afe57d3f839716043cd001c1078debfbb2a92dd2800e6476e16fcffbdaa108a9e89f4bb9150e3d801f178578d914e24125807fe389ee6f58d7d11ae4ec0f131b0b3d28fed4b3b6a217c7f4b21ec786d1c3aa5e8b4f1014a862746c53c00c097b8cef440b6dfe9025421cadb5288a2d90ebdc302e2be879c50e5ad84f7f5481d214c98e02fb083d268dd4b443b69f8756c360b1e57682dd46c27a5fb584fbe3c6ae2324ca44e76dacc6bf161a5a3f387d575c1d2f62644d1931cb875a53d414ef973308cbd5905e9d75eeeae0f44392e6e7b432698eb6514e7754fb32fc62e512396bc3dac051e0f874a8881fe607f86af9babf97de1c9a9ade143b567aa81ffde317b5d2a0b12de8e228d6608e15197c0748443b2f1ded267e3aca5d4684f47ea8033d691e684d4302de1d842e94708d14bbf5502db55cc6894b8431aa1349d84bdc4fe7bd5f3d55f2dbf527592c074a8c1e5796c961d3e7c07691c363b1c8c0a84b688331526fd0a6867ac3042f983e99892f2b73708332abcc280ae73248a297b8d31cb290ec5a291e087626b914dfd6badd9639bb0c70c48cabc4819df0c894804c0c3e1bd4be006a8e6abf0f0772b2edda498f485979d93518791a61d593fc7db97e1f2684d281ad0050e95c6a5f40d3ad92bc03567dd01ff2749a48ef5c0d4b79b54f68d2e7a556280bdb6001845e0abd9e556360d8a2a65295378547f59abbdd8326697c920eadb7d4d342d59e8d73b6a56889765fb25a32cce1084b8d5fa144e8209349d25a358a341e838470a9ffe73610c091f437ad85cba6ae28d80046f8569b26e65798db1efbca8aebd320dfe2444d497f0e7483cc02f6be431f432c3c4e99661c2de394ee03c46a6f6b9d28d458c207f58a8c7750e381309221b8a737a6f272431f474702b02b270b9208310805cf43c76cce52fb8150a393527b3f55d4b052ff99a1c38dd0d5eb7b22c17d61dd3fe80f732e166070ce8e354e47137204b2812c1240260912435a2ba1890362a5613b89cbfb3ed0901ac358fec8580d9f5d91cdb02d0c7e827a9bda655adfbbec203c53bd19eb45a2c793e516662747c05ff3fe3062d1fbceccd481b97744ca95d27628d6f2c9bbb25a06574e0d4923c9cd53ff969fadf314aa3d8925f73dea15eece95323387d26b52c4c51e6ae18f4b6f8c97943d26ea7d740434f139402f120e00fb8a5fa8b3fdbb2bc4216574a6c24273c049d44e6a1483c0c6edcde0125c6db4c0050509b1ac94f8bd555c17f86fcb4a875178738c7c1a74cd2dd75bdd9344af8cb11f4af4b562c8c32b730fb99917e2d8317a48e5fa0e571fec9b73bd7a4e55cf3a5b480fd862b5bf250a89bdc19ad862b905a60fa75fa27021fba0f28fc7894939e314de12327295e4b6553f3b0fba867c8ae3cd1494d97781184230d4ff80af664562069926c331f6c685fcded09f2d1e5c81b9f300658d67f47b5397593ed0ecb20ac37abdf1a2d7b2308ba3e60b17ae25e1487ef866450192b0338cc4c4d8a5b4f3979be6e80639f6f08aaeb1ae76f303eff7f7a9ea24b516296cb112622cab99007bb66f98dd1aced055d0302fcd097c2508ae46de53049407c17e38749207e8a62de7b60330afbf83f2da4c69b9dfd8c2457ba19a8f5e31f59cd86ad68fc03b04b4c18b1b21ff31b607c02727489535761b81fc53a1554ef05d9f2397a7fcc5366ad61bf01bc29954938f8572a514257e0398f0cbaf3afa65b096ec8329f8402df4e7a2c14f547e49da1bc3ee8b9362280c60a3ddb88386cefe3bafdb62d86615724d6f0ca34e6f1d4961215ee5718bb7e3fa580e04d84dc25eb304e659cc7fb1c8f4c157d9834c285a80fb51114383d7b25b1423ee95257a42d81928fd1de46eb3ed7ccb7238c74c2ada5d3f133f0f3e4262ed95bd2372eba157dc13cad94be27ccf164347a80deab705fb2758191f0bac7f6d43aecb40201f5efb60b7f642b27506d4c17f7499f6f33967c08ea933c26403079007895de6704f1bf218f8b8c7b564eb9e7290dcd604f1c00f2ba9aec8a6e3e18d048056efb0b7d1bf2f08b39c254c52144b44f1bbb065178917b86e9e550f594ff5da07bf246c636776c56a477584a2f1cf1822ad465478a58830332938ef801d4ad6f846e4bd05ef962ee923f37b1fb91f9fc7a4155c61da34808f60171c5d6890e802d5c650957e1f5a480eeb302298ee917983e4c734d4f970d0d51ec302bb1ce4ccf262e59aacaf1851a2cd2cdf165d7d7dd1eded76f67c881291ab2b74aa85797dada3b9abb98689871dcf51cce57e017042409d597ff10739ea0857952b4eee03e33a7d3c042e3d8a20718c3bba4fafd6d544358bec95623a3ab13e859987bd526352d43f61856c86ed1ea0c4800e07a0b8d6458b1c714a9523106f986edfc7729f5bea62eee7967ab1fe734aae58fff1a547ec7e7ee9156b7bcf7ff892116b3fbff48b319f5be262edc7967e31ff694aae58df585782a6479249b795d6d67fc95afb8cb533bf569f275266affd3cb531eb3fd41ee184fd5a6e6d67d65e2c2674a40f6453995dff7a3ea1d8bda555a1ea63ad11215bb85f17da207876ea3c5a0c2a2971a723f0a8a4f184b080187a9dbc78f36929f60bf38e411103ee844e4cf5624c7b9113b7fdb1dd7835bd1478a9a9d59948c8c4f54130ec16504b13327a7ab5847a4dca531b0e71af4e817eee1d2eb8cbcb8fc80cbee0b36ea88abcefb32eefc81325d1f13595f859a7f78a2af9bc7500d8a9fc30fb0fc5daf0bbfd2d5ea0d1995f4d077c29a75e0eae00906d0b95002a69634806d276770ca2219037d123118a00594c4f0cd9ac90719712f4c6a372096a80890690c3d2569782087c180fcdf502244f58e134c829b6a14416495d52db0236c2fcf4a8eca15eae0a4c84071cfd9cc75199d9f409c61f9a11fb74ce9e2b175d1ee7892fcefb83eca37ca7b2c2535bdb06013cf82ae4db4b7a26ade9ddd95022ed652987b6e41ecaafa7ae793e06a1848333a7a1c3850f129cbd1775ef9e45f2df123b040fb8c471be843c306bd989c2272c5ce022620cc3e15eadc3eafed035ab34dba08bacb0bccf5cd535d901c2a2c2b1eccfbaf39d03d1213eaebe594e91a82b0ce591250313dca16d9f3d72b890d9fddf64985bf5220d77f3b32963865b5d7e892884729fc5806751bb7845dee03f877b7af0212afdfb64a76109dbb413ec1fb6967835f82c919123a4f7b7993f2e17497052e633062a9bd3921be810277b6e1343ee054f36c22aabc22bef93b0a2419d100c0514eebbf0e5f16ec6901bb225ebdaea642020763d89259d904d49100d822315ffb666f0045ef9e448851aae9483a8f7cf3a137170ab08ee948f9a66b14ae8ccdf7d8f19232b3f4fd921aa066aa0749cd5b31a4b936d39d450bf9fad859afc38ee2a9f609bf6963a0ec6c23d3cd4d703b0909b94281320fe523f8d710b595531c1416ca3d0b5b24261c7330ead89e68ec4988eb98ba73e2118139552ca40a3a2e75c3a18a66a48a89265a3eabfb5ea434a4a58c6693b8e38093a6964c623ab84cee04ca5cdf82c52cd2ab9d333b412e08bdae9a3cc070d137a717e6e52dd5f3048cc125d17a3529d48d770f91a98e96af209f6459943b110aa2c2401a5cc85637be544ac840cd406206243f7a64a16683d00f6f436dc58301ca9129845c16a2972acdaaeeaff777417921240cd0316b8b1f9e69c9ffce78cddf8d1ed53330a67038d92dd232cce471096ec10eea847e7cb06f0281b4ee303cf59318623610d1065ff4919d55b05a7381bd763b81fd48a904d19b89963c69dc4fa1e38acc13390c9290842969e38a438c6e8886df88d1af72f43e1794d15ca0abb6ee1c37657cf8906c01c6cb7642a4a2ae40388b0434711065f05e109af890303fca80ba7188b9089f97f9308b7d533b2c9a2da9a8ae590d1b5ee3886b1e0402ea879c58a1d1204b760f089fa10b3233e89b182fa54886afc1ef33e31be67c41e008622c9c00b7c2401c5515eb542372c9264a96a7bee20bea645476c1811ba8c4a4c0a126f138cfeb7adec9a3c07d189a6071768ca49509d0513402d430c385776bec730d5afc2e35ca6ed50813d304e4dc2eb22727c67ac5054bca41b9cf1c06e4f4fa420fe87a16ce20d5d5801fb322b5d5f61ad788c77784acf36c0826e29002567524958106b47971b8e8cb27fcc8b0431172d62be3c308c858f32c2f5c3a271ae43ff798d3e9e87ab33a6f330a722869d66dc80925ede1bc806f2031f58e63d1fb2844e9c211cf57dcce8180c8a536ed8593b37d5139479b3543356077d3f9cd09224ea0f07f669a0f6c5efe801ccef6bb7fbe410e4b7372a74ec89d58bed0b6ee90503032cbfbd3757ba9859aef77e8adf4507c1d08b578d78a6b8eb59228613256cee549e98e9569e28b69319c1af080f763334b0768d3d6a8fab8bdb80ef69c2fabab0b99c8a7ad7396cd0502e993d2777b5f768bb6612c2588ff9a4b35dd201b134d7402d938a11ccd55b6d0d63fa395d147faae39b25cdea455c71a50de6837ff421247c38605d4e5ca32df76fb31ce9d533942948b85d6e7941488e56d7a4b3e07111a294a33b48a0201f0bd9f3028e299330f558b3248d59d8737eedeb7ad1a639cf296879a663cfecba2367384afc147bef80d5061ebc1a09b9f867ea6c5bbece715e6a5a96946ebe90f2efd402b3e28d71ba109c7e884adfde5c919f81e3ecce9e70eeb0e28e90ed93a528f065d7f1c0b7bd9ad8ac47e3fdc77a27409b3db019c1e579d80274859a06a90728fa9c2b061659905166aba53b65ff192296db4b222c966a0503fc35fda73bea929e6bb152d3025620b4ba324c61061f345bd2b207c959588fa6c65c7d1403edc2c02914a1c275063666d19e3d59eadc7cc9f2348c24dc99188601570aa14cc41dce8efe259a10ae1926eb93ed67318c1f9dd4dec3106589468f887571c9f91924e891579d269d5f2e488cfc5b873a69bf920fcf81de2fdbecb2410b10430ca5ef370ecd9222dc198f5795dfabe187d17dcba75f0a85d4d180dfe902e0caaa2d0d2cd6c28552b2b9065ad92906a56db174fa45ccaa383b94577a8ac9a67ed510359c67a60a4b73fa9576f8027245db97806c0e51eddc2201521db092df3cab5e351120b64d0be4d467b9b5d0de114f97de9830c5ecaf8cacf67924df4dc07718d2274f202f05e41c326dfeb7c7de04e63600f2ebf6f142cd67f00e81d4cec08bfb9ece963346e5f72391aa19d5a2ec76534550765989cd2f296f5f66dfd61a0c0fd768070f0cf432d8467beb03967305261dcd15509e0ad891681b9ae4a8d1403d111471351cbd8abeaaf53850cd6006aea6f37ef785ddec13ed0eeaa17f96f286d89dfc74234b852dc4e6152c043ac6d4740b8d000bc70851df03e07281acfa318d60f80617239e9fad0f0d64af03e71441699f0539f3da6d9373d25e749adc6468b1fc5b9496cfde8ad9b43eeb56ccd2fa6cad9d7dcbb360e1acad9e8db5b3b43a8b56cfda9a5966d550b40db21234a622de60e20bfad84246d5d060d5a3bb490ec28701e4eaf3c07aa1f9e343ab67653fd142ab67ddcaacd07f5b6ae1ecad9f1d8bb368ff6f114b67b7769690f8d5eb932c167a1625195b5ac64889b4493b392f46cadd132e38da346ab408c7a62744c95803de5291d099ecb4580bc3008af3ede879a70488b131234a8852f31733acc363045403951689949c5beccc73d704e1be94e0ff68dec3747d1462d2d8dc74b423ffc12ed3f43b17608e5da061bfe10be513278e743801de721991183f7a3e8fe36a98ae1d1dcfff65b43d54c1dfbb12e0d5d4a09629e027cb41e6515063eb3c1d7a1f940666d571b4624bd2fd085b50f9012dc3b83ec0a8964d9901d198818259cce8cf53c62186281d00514200fe09f466ab4bfc0525baea92081fd1b6037de1263770542571b976fdd5951c9af4401bce5e4c8e116dff8cdc6f41a77863efcb0d596c4becf7f01ecce773c30112bbd2088f54a1dd99e4322386e833382ea291f5b4cfe96c71797ef4c94cc17c5536296e021b697bf5c23124e968ab84221a46cbaf0d766f164592ef1d9b31ca8840229fdfc8c27c04f6e64dfdf187ffd998476de78ecb7d39a05a5c44e3335a2b81e29747875e0b85b2cb8e3fca77f256a29c92cada0dc11069a28f5f70bc1977537c454fc9c79da21c27a9a08fc2c0536cd494fc17ff0450705e28efb9144a2e3b5e15540ae7c1d87f52c169e9476a62e54f871534fc9eb8abd19b79df9d039cfb02b9af89376d942100cf96c171e535f90fb3ec7a4e5fb808e999bbb859cae3e6b9d053352678bd34257fe87e8d823c853e751cc976d34f5626fa5ab7b26d0797e2b632ade7c06e8083e06f805202ea60bd3d51a88f519a4f1f0553ca6ae8cb2d2df8a90be1e42adbc452212959d0d785e884b6c4327463b8a3ed05dbb2df63e3c0d6b052f0103c267c2d2b067587e4e19c028988dfb4fce5b318128d9faf2ba6b2457f826a41f57ff2ee9b92a9be9166c03c873385b26ec47e3f3be637e8e971beac64e417cefea36b7a9eb0033ccc370117d8fc086d717cd9be3b6d27e596ea568d04c48d3736851bd072879ab4a5b1cca78f152da122fe035e3ed21d51943b071ae612451ee9c081daed5b805d8415e0296e81e8a289339dc7f59e3ba1a8e2a0558aadd00cda34210cb51ac7ceb74669e0f8852d72dcc4c7366c5f28773d124bdae08ba5a81aa1c02ab8b76256614796904e362a7c0ad80bd2d0c09b6b5c2df5a06dd075899444ee81fcac11d14e827c71668aad4a0283635dba91bca79ac185b38f4622dc4648bc5a849cdfdae50b3ef44bfae8baf9241fac46c70152fd52440b0c37eb7109fd5d58293872b81e3a236f49275b84c96dcd0ad837c9b8d1df84830cc11217a8ef59f1a536a139793dfc973fad0d2fe30e45a5bba632e0a33dbc8728d911b5bcd935218df53386932cdb69ccd04966ef6907b4d8cbfb2c65ffd8b2661dc30ce41ae5d5cb6c9b4b6c62e68279d8a59bc6f49057500a08a9c17e44912bb3cab86b117197449486aef572ea95a6e3d5bf4794ed8329e4e7d565055de5a942d860ba426602206ac1bae5095545e32ba7e0f615eab265b05121fa05d2e6a456a3d81d041a72e86e6289484621b3fe22b75522466fc554df04e9870428948222c6c96f54aae0847aeee51672ca9b9555f11d9063722cea13e4642ca7240bab974615f610518301cab6e4384438d625674fe989fcc4e2717ba5eb12393b665abf4a45afb075aae35e81dcff04e7e24efbf3160816f71823aa844e4fc368b0c28171f85e95e3c95250e9ab7dd65d547dc2e90c5d477ba55bc63472d3f21b5326ce0070966b4f2a94dfc36cfa4d4f455770e2d032b6a224a3544676426255a2542f1a60df95e37b7c703873aa98c727ec5d2adca6306387cd5b2b159b72b0f30b027fd812ca496fafb42bfee08ea25b4ba282e2c4223322464f8f3de5536ee3ed93489f3eb97e30afbf274542d5e93567067e439417cefc5754211171f4c0c484ae058f4248b55973faa281cf45207d5cdd1d24ac00d1bcf27715354d0557dad3bec024d69988ab02347c5785fc9fbe47028b13ea60409171930da57664ed7ed16ca199fa184b22e433851552889ca28da0a5de694392e89c37fcd51f10e28eabdbf06ca1cc66bc08c0e4b525bd43efd855460e0b3391daceaeeaf431227e0a70078ec623663afb34322f9f1f160bab12e0826ac48ce1b1ce3d3c004cd6a7eb63f3741197ec5c794400c758960591b1cc9ec71ac8c329ad700e7c3a551c827919c5e95bc90caed3a9d8ad968d898242d65d712e5514d6841e4426b65aad3df6ce728df237ce1b615d99e817170ee41f31fc812535228a0573b46f93afa875500175fea309aafa49a150f8b91412c2451a16da73cff290dfecd374124829c45ea0673dd486e3dc98b5013ac75a6e038b3804f75aa1f7b1330da4c676dd02713427ce0097a31d00baeafef407c7ef1493b876dc46499500a7f61b1ec2478dcf1535638c8576664635e9835f7fbfbe1dfd60c8edc0c1a4006c444a6f90a4e7735a06ac9ee52a48c89cc7a3871e93b4f25b820a21f6a98ca767edf036d7907c1105ff141b9333b236cf158c2df156a3d956d446cf2cf43ed3bd898260fe5eec63a98c717ace440bb45f5e359e663f32829e3c96684003487da3052db8beef989f652cfb5444fc520079988b16c1b31334f377621dd18140d826f58004e9bdb9a9048edf015d3820ef2e14599b3a3f64dfc64bb07d65bd09affe913b276f2099ecff1bf8052e38167ba128c02e35b6507c9761d820eec1113cac24f3ae04675cfb3670cdf327a992a3ce86bd5b16b6d1ae79c18e51a158c04be5790cbe7180a05ca2b7be27033f5707c6b0a92fd6a63064c1eaf97305ae54c29cb7252f471e888cf1a9d0e0500ca5d222711232aa7461499de5683a95dd53cb9917a55c2206f4501770e03bddd60e9db580a58e5a5b411cdf4237666ea3116498d10d9aa34ed64daf11b8ea2df3973b8edba80d2f05220887fb2047efade0bd2f38c20bf482a96635d438bf2b80dec55ca2158a95843b9518ffd81c8495356f70e0ce58f7c429cea68c4cca96fa70695a72dcc5dc045472969d4cce861cde5134c330f6f0ff656ff570ac2778038f84ea7bbb9877888c58759abed3598af6be5ad420cee2d0ab21d6fc1d00aaaabc249bde4dd94d173c756a67f3f6c61c866db264f36a2232814e03da81954e83e6384e1d48c711fa870d1f74bccabcb95073ef1ac71fffad6080efc86ebf1d9135520e8ad848493db75dec768db358e38e788ce23242ee43993e53f787c785da4fd8f672a8701842a7fffcaa14f82ad5d63d12f35256f23c5bfea55c1a1873a43cec83b285bc9fe71a982a2380d42ec432753beab099d125129653240662daa5179629a03c8342955747b6105a66189d623ef2b36ccea0dbc300bfbb250693b9e773ee8755f50141bc7ffb9b61a13361714d9434de61e91295bc1ad9041990a0a08ab7eace5229ced6f838530ecacd381b269ed6382c10c28661b47022148b16291817c32af29c54fe14236587093001a1a63e384484683fa6b6c3fe3c42a8aa714c56c8099181840918f33650473b962d6b4bede452c999a842baf3fcb47fe49aa4fd0c5cfb02b6a629ea12ad1bae4d750309a7aa57f369029cca092853960b53982a4aac5cc04696476e76a96027399271be57b9c63a898cbc68eef2886a23411bd6d252a5246722402743ce28d52f25788ae0b33451f3e093779db8b823abd076f182bc042b66f3737bed8d99e33fe0ce16116f9bd432d2530559118952217e48d782d87609005c872922f74967362f7968ddba82ddead4fbecab567874d522cab7559363526e8df0b01ec3254a49cced402ac73d942a5334d3acacfc2b14c0a6b2843ce8018535b723bcaca6e24559363b436d4f34908ea77558a5cc529d3c1d2d3bc18d539a3c057558258206270d3c0241af7164f2c95a2c625fc35fc39815d8841126ef8f520801a164db8acdda700fb8d6ab7b3aedb9535924830a94cf9c1d036f2d2b4eda3b1ce6cc9952f48f1a09e6a78e0f8b9d5b8f8c81ee599ba0148e676f60dcc9e0bf18d9f01de4246b9b30d6cb0190f1ce0520beb75067f2e3d7af8fe133eb667b593557e645f6226cfe8569904a3fb4d4a65a54c7798c2009cb30562176850c4286f4de63b194bc2b095d1de9eaf6a4f9b9eef02765b9728c3875a61125092b833545c014f2b4718d80ad7924888ae5032f957c249db91574d7ed7dfa5255754cc4aa6367cf32ecba45e5854f2b3b3c6bbeb9fe3470d8d5fb5f965b387c868cdac0f7ec4dc7cb603d3872cab833405ee37e3a956f01085603a54df5ff0616d9204bdb1bd400d9cf36b3298bac24689c4a76576eb3c285412440a5b42f5b6dee46a1c2f3993a8a5ebc8fb8d8d34f0bf8a73ee21c2f9b09ac8b3e891dd4d25f2206d36c033c75a3543b840b4c63b5dd5e850ac25a185fedf3e15681e4aa66492b24f1248db0e54470babb33d63edd4832bbc5150025cca52abbed93e1af9a45e9736e10dff2283339ffb95604246a2a4059f8dd289964e7cb4699b01d42014f1a859e743c643b428ff694a563e631415c922007ab0506478434bd59031e468464501d59d489db0c36cea026b352b3c952cc643f0792e649299fb820c0f7a8ca3f4a6cd7c9569e2e5a02f4ed0cd20e4b2baf99ce596ad730419bb2aca5a9d95c759c42f34109aa854057a7a502a0fb7bf739bc17a87255714e2506759a4978a2b873796c28a7b188aa7a228ac9c103e12c71d5340031d5950dafbc8b60a6677e59ec9ad82e00dc419928ebec970719810f168806397a0d006ee401571a1502328390747963375ca974049b66186946cb0b3475557d52721677133252dd306824415628c9dea66849819e00cd8a4ad4894959078b035fef1890b8e5d08bfb86484ed3c55c4be16e8da5350e1a0365cfe91d0c651422bb194dc4dd38c88aa35f73db0c797a193642917a62f0477861ed06b3d9a062174edfcad420ef56baaf9b1d9752d389dbcbe59583315ea3f836f737ac4bddc871a27138f83701dd48ff3cb722f77c9be39889afaa9ea8a22c47b7c03b19b28524daa261dfe0b273ea1988baf681300c60b5699526a1aae0c90c1d636399c8a552a2b62db7e6bee70315997f7e5bfd16153fb0475f82261aaddae4c09ea20948215c6bcda4fd159f278bf39bfe2cda0513adbd356eb74bf1b0e5a4cd0579373c8138d036eeba59fd168224c8198b10b2d7426819024618d570e620f4dd9eb89d8503cc09937fcea5b557137ced10ae6b680eea7bdf262264cf0a272a2e07730bb199b7adc6952b7705581c3ffc2dcdbea71283be98391b333bc0fb72cf47e0fd88312d66bf7807a4e5aca70196580c96d87054fc6fe001d837dc70284277a9246982850d6cd5e5c71021e9a53426e86bae674b6f294dfc31311606d35d93255befd1d646507d0fe980ff87c59b00b7290ae3e3ebc6e36b8695c2db5dfa6712e2d379ff43721d4c41fc539eae51e6e686e7f026a5fc3f45723a11abea6cc5d1321d0f29e8d63d7cc787377eb8b634caa02ec37683283c782f6531478a17ecd11178739b6f83bae6eb3cd3a08f33bb345c66fafda33687f1da63553d4c3570abd675b3e9a98b4a0142f5849e5234ea3da2c26710eacb3fe7075e6a03417e5c53a1f3e002d9ff0e9e40fa5903d887e18457c2e30dd267d764a1ecbad53ec9f265bbaebfd9b81ca54b915e7c94fe7fe38efb1e1f75da9f303a8dfe12a68d31b9ecbbd6030e4d19b3c5951c63f39d0839a206c3dd59e0e8c930bd7d23347551946c116b032a58aac65f2497840f0b16ff30f44965888bcb1e75024752f65bf921d03457564f1953c61db4467c139404f646d638c774eed67296531e8d991ba8366b839de7cd53129f62cdb8eef516f99db6ba5c8c306b15b12cb3c99aa1fb3ecb0b20836590950fd20cc3d31a547846b84a8c7b240e1ddf75453bfc7a6863052967a69ef2e5ff6a524937f2b52c079b8b8442e02fec13356b52f272237a9385798a166701d8ca27eb5b24ed7708567dea9f562c3329fb9889039cc6c2571d4db6636920970702955af42d95e3106d386e3dd05a790e834fbcd8680ddb5efc4fbccf64572d2c597b6817cc3f98b2c970456ab46423c53cf3a176f9d775b4602194efcc2463b59df0761d1784fa68cce2f72dc9c4a604812be54abc752966243988460c5d27afb9467375ef75711dc8936663fa3e7f44f65ed9187cbd7e2fa704c43242422f02ee5b05750fc5edb19ce0d81f2920299c15c5a84252d5b857ee855d947104b506c3ad781b4ce628023bc0f1931c03a64b507a4865b4700f8a24318405852e6cc8a3b7da2922c6b6f32c0ad2182f1632b02f509c97b9e7f3340c8c6284730d02b1149580878245a7c3e0340a547b34ca903df9f9854495a08cc0c8858c4862e6ecd9e7d771eccb46c93522cc8b0a8d6358e98666259d687cd0af7f1d5747049cbcde05034d8a4c0cd4ad7e33d26cf9343fe4c7b80de98ec215c818c47371928806e6d1ca5bd9cd9407e35fe43564ff137b82e50e593e3115a4406e40466b120973863b4dafbf71494628e288f5e30c5e5999198ba5dc6ca28a35b6208951b6e7272b7497655e3a7d048dca8506221f0cdd5438d94b2153c2711d7513a6b1599dd0ebf6cc4a23e21ddc698eaca402ab5a2bcfa811d4b44134a9205919a1c39641e042d92054c58c7876e0ce8ce70541e90b0d292c38de18b3d9c6f10b17252e9b424bc5aed82c8ff66fd8aa23e5b7910a9a4a72dab6ad3b7a2272839b8ecd5b8a324692c4914889002b9c7a98b8584d3dcd3b4b47d9c8f3ce8d10d6630c071b831278b9a5a2b70883d31484c834635d365c10ce11b4720499b8b48cc9a4461c2863b0a9899632f6a2378dd0a8510afb4966723dfff579cd6c2187c0f9531e33bd6f3ff42cc980fce7819fa44f1ecad15b538f677caf8709b548067417155b661187903a45298c83f0442d345a0fb2e7149839546a723d017881314fabf54b48e139e690cf121a8b486d65aef8046a2d514dad43938636a54906ea4a6a4146c4c4084b9017cc73ca206c71ac56b82059237951d23f83c8765fb08712c73571aea5eb999d54e0dd33381b30747ee4c251245d6a581da6ec4c4836f33ef9bebf99c54518a715881630160b2d063521fdcfa7b2580454d181043b22a02cb7c7cbbfd8ea8b83fecc18cb331f622a690093ded9a909f60a8cabe160b3c6a5860509440aba08106a63bcca1dc119def19198b36e01e01c912d27a1e7f56b1be9413ad7c81d504e6dfaf1ec1d7ca5473bd4e079a846c42627e3de0a7c2aef008128c3b395a86ea035664c5636c8d89c552a2f78c402d2dc14050e0e71c4988337166aa39d6ba337d54551ef65be3a9092e4770a9bda7c47362223b084ec51e905746308a2240d844c56b7c83bb6766afdddd5c5dcb9f9e66129eb717d010aad1efdeabf7e13aa47e0711b7139c125477e48a18889dd7cbdad1df36f1e81b7b873cac6081a2d532fa92ee7ec299e350eeb7334fed79f2a8e4105668c984de7234c72d5a43dc11c9790ab5a2863406c7a05ca84c758f0eeebce2cfffae384aa722002b687edf73b371dba94dc7582a5f288b99dd9ace6b0e3b78e905f8fbdea1708431ba9e003f81213278f77be07eed4490cd7da559887e6ddf025a358e77c6db72d9229a1eb8d25e65e9422ece481c9c4e88788a9163aca43f3e7e19f0ed1a974c9b0dacfe2d6611b2ca61441fd9cd5beac488bee87d19d4a17ca9d955fe7a84dc20faffc93bb36b1160ed447b7d1cb916140cec075c1719e2e1226199d5e87bea3c2d69dbd0871af62ab921c32aa29826182d16b0e326833eb4ea76846f4a577924c345dcdbe3bff860e08f702e0178c48b1125ac1ca46784ae59b4af28c87d20107953633463a8d3d13d696c2fb73be4c4443c89b49bca836bb890f1f5589f7ec3f8bc9e73645a2b0b4a55f4bbb6e0e79acc53a4692edfde96ec4ecb30433328c16d4296fb8af62fe4274dfa5656c9f1da2945c7456d3fdc49005bdfa850e949cdff244b09ed4c98b2f04df1a4e3fcd00e6fa422e3fa89ab5978cfae2eb3338958756026658bc04a6b6d0fdb52598f86045909de141fa000f4c80a6136cd050f401996c87b1a5467a58012379d1678c01e39d8dd738c51474084cd8b738bbf60435486142945aa21241e2e1413664500bf5b5c96398f322b7d06f018e7801dd41612ca435078168703ce210cf824006302e8a52888fa832d8203f10948331ebf21bfaaa1e87df545ee6116487609a0d99a187342e06733cb9dd5758d9c8aa4a5a36fad242e81e0acc03ed928065eb4ccae7ea895fad0c365b2b66b7c94934d86d668531c419a076d1a5277c9385dcaf303760aea65d87a82d1b911749080a7848a004404b17f02f9b54083e1143db418da340b66a343752d3d402b4e75cd7984ba6545c3b72a09b151cbab2de73c0b0ff2f27e15ffc923172c49504872fe88ea9ba034159aa30a4818487f29807baad99f686ea789735a092283379697cf5dda3344dbf77448b0e5dd8fdc4994529572e4a3f9e5723c21be49cdfe7bcab4d30d976aa5b6146ea1b0d56e7c20f04378b0e58f5ec7950eea751dafede31c71fb3438c1d7c14813b9e3301d348f38662a3ed018649072b913056a132b98b36ab83fce69044af1d904493c6fb3ec3ca42d0cda5c23215a9d920f171963cb17a5423c79f6a64aa7e63cf8e00f7ad5c997d930128a5c2cd9fcd3c2fde08b4c9376a6ce5eb5412edecf4442ccd10839ce3a9649c7b99d8a696cea7497b1cca0ebd84e39a8ba7df90905260c0fd577fbd0b0abae29f9e279390a038764527b9fcfbab30aba34a3ac10f9b5984334de0aac00cf622f4bd0bc047f57702b0390d54013eb63def1795f98feca0dad7be82a85753d27033ae806302bb693fc12081d38614b6c1831a0505355fe6f1753919638f4c013eff7b7f7352e924deca51f0ad88c14e4e81008f3a769c550025ea11f52bd8c3b05d13b0ae88ab2c354b8fee8e2d3a00370fab7fafd8b9357d219964288340ca94084b3fdb6c7d62a3d7c09282aa295193686c098cbfcb88a7f02d22afced1e48c8f0d21db48f0aa39179822d84892fa95e2c874fd619345e353e96464a77eb33949dc8b31f86ff8f915428e3cc0af0f375598a2d93b36c468ff99c103f59907bce1431e51ebdea8078f8ad39c14b6e4fdf37cfc3018546e868413539204c79358378d4ea3768f167266ed521afe26ffa42f3836c2580a8368401058a0c0640721f838ff2ce82b1a691c344602e80e3f813028e99253c36fd2b617ebd81ff3003eb5a75b7096c6a1ba8fb8f878f21ef690f949db2f3e60c09d3c9e998a95c4d2f88f3c20d12cc5f33d540484a96cc722cb660ff987ad07718e156c654f78a9c932235765249933378b9da73c1808d30b9d6a89158006455d3b17df0c1caeba34f785adeac1774c828748a2bb858e8f854e1e787531e9f80ecbfc93ad44fc29ba614492c59dd1037cd2a03aa35649d5c06f86d42907e8869b406e82276713061cfd97f33331481cdd201eadcb51879dd4655d55728696397bb6cef71652054c54bb238d41df4c43c2ef0bfd790ff29326e827f949109b862ea18ac2d4e1bbf68432bb66226b3c355b84408b091d78ad6b30b44578b48a9054626acb063fc0c2ae15896e1563756173dad41605f6183e3ce9bfafd8ab03e7fc72ce2647a5de772ee0e801f8be529682aaedd502d50de8b3dfd5a9d39bca87b348578dfb3e993590595a513b5719088abdee6921d156d008c9c671a2b38270a83a31c55eaa8659cd6ca9e0bf0ad6d1895df8da94d00622bc4d3ca89b73b1eed7e029f45bdd9fc1f6c5a30425567843365858995889e345a5bb7d232bca78111c576b91f57e680c535e675b7b9876b8c209d45337a0f34e6fe3734ddc2ee2ebc0af7158ab30a2566e17bc259d2c7a367f077261ccacf42e6c99c47167d02f50f39abfed47c83c3db0be1a8d29b58db6e1b034e2123492fbb865f2a932b0e79b71170e1756634150ec10a23c39bd261fb699d6a6b3a82385b23c89be45ab9c51cf5214f8ad1dfdc4c33599377191e7c9d42919f6e852ee67bc796768fccd736436fc599cfcea58491459899df8d82d45f12386093593976ed3aa73643285faa0b1ca4a5dd3ca93ce5ec10c3e40f5859631e9cb0620635f59d2d977fb6a4fa6e381cebff43d81b257558a8e28e65877a37a30bbabe559671afb8a881c58d075e4f8923ca6a76fbb35d1c7bd8b56db67a2a899323dc93eed6b4ec913b6050d0dd022612d0f61af7a8b3f11164e152d8e5811089a76bd171ea04397c51a382b56c84cc82418a681ac01d4d040cb3a65a38c7038400e28347a981bd5b588cda186b881e489321a2ba7ab475839fae7ee4c5baf2c7c6b4baeb00961261be349515cb8cec00acb29f00ace1050de1d173e8f4c06c2754acdb45850003b910accb1994a1a33bfa16e0eb2caab8f70c8dd822793786c47d388926fa155ce713444bed143289e6f0707061fab56924ecf75267023203c1e106a28d1eb78fd0b09ddb64f708040c359472d391620b8964b410627ec4db81aacc603d88a8354bb01c708d7a186f2917a7a48421186b0d685eaa8a93c9e952c5f6dbf9073f32a9aa33af6afee5fb323062bbb0c0d41f67f512a90b0b92b12157d62ead6c150771c4c9f016e233008cc41b9bda7e68fb0393594c9f05fbb1a51f0ffaccb5c997f1fab065115eb7859e66804fb12cabae7e1c2f130e49714246935762efc37e76e7843074130948d02e8d3513278d5bcffb1ef0ef4637c7aea68e311b44ca56a8f0ceac68abb7e54d0ff7b71f3a24bb4c21ca3a9e236da8295da44ada8fa26f3b3a7f11259453129592f4a7863ce387d5f5c497921bfd9e4a48b9623efcff34ab24df66668440ba2fd6e01cdb70ad45e13c2c6074f11a5d2c6542b6e946defe6ce09b087614d4253a95593695abfa411cf4a9a0978d6df9ed841613bb569d41b13ddd5f8bea066f030b8daefec07f9fe405742428f62c07de958230809ebdf219f9479ef3565a47a371fe523e0f571e61f928b3d86332ceaf1709fee5640d6102eac68f23e4832b62671bd99e81799318ec325bf4191bb822a53eccd1d72af7e26f06866a74ce133885de29b1c241a515707b5cfd900e83fbaefa6d0f765809e57c13f7557ee3d38d29036d9297ec71950e3ccca59a68cac2e417b4a0cad2d3b6d25f9215a901940e1f0fb5ebba8ce6e80f07e19c9601dc2ea37a1b1307a209c59acb02faa049a27159c1afa8fc3ca5c20b568ebb106909069bcdbf1cf02aa4674fe3bfa33bfbb75febd6da270c049ebdde32fabd41d71ec575f8825074ee52fedd165f4831623c0b072bf2f950b7fd6c22012b35f201a38fbaefb45bc107dff98be10b1f91629ecf6841f09a18ae46242be224afa2037c2ed24bfe5833712b36916769d558a1f677dcb0da58e263848f2aa509a3db0c6d7c501edfb6c02f484febb29f47b1d28c15796a75fe8b45a435f49bd5f5d18b7bf263d2e2a872574c8bbbb7354ff67df55f64990be9b2ec535405edd52e9b79b6142f602473672bd18ca8f185264a2e9f1222c7af24f200bcbe37de21e9f8d7ee7e719765dea2c29a3606c024b3324d1df60b04aa76f8fcebe8f130d274c1b44393459bd77fcd3c8f1b3d33e8174e50720f2855e47355c56c814a8e06c6900053c91f2e78287dfaa1603e0c4e7f1fdc4bd541498cb84e78212486f90f0b26cdac5fa6c94fb3f37c4244686488cf6f69e4db02920c357f6f997b4981cc79d0dc75158f085db2016c2fcf840eb51305fcba243cae7d6a2a20dfef72f1b885f3f8443df20ce01db80fe16654f5702afdb98ec320669081a255893f8076f293472a0898df45cdf8b1710486975470fe8fbc2e4eaf2b3819263f59c957de7c5a986ff8765c5ae31276b87132ecc28dacc02c35f0d09dc3981c1f96053aba2660fd1a7a3e5693da61d692ee0e5c9606b0b13c9eaed064db310c7a1657ed2d2ec0e7c77d5222c32271358648b4a73f3e3701576baacd80f2c26cf4f82a05c78636aad4a2ad6d36a002054be4d36ed15cac6b04b02e2619b61408bf5b6a1f93c71dcfb698d9b5aaacf60f1f5b7725ce79c5867995e5d0e00b557d8c84ce922a9567658179699bf71e46c04cfb1657efe98be9a79642f8f3bf9d882f7fc8b6e79c783a7673561a34412dd9ff8b46080d1db900d32f23ff4e0cebc400f1f6b1e10a62dd936246fe8e41ef3e9dacb2fb3b25958c29266bf6674be0f727a35dac0eb7fa0ec6fb5f48497d84d04ab026c902c60e6740549107b2b42fea02f2f52b2856ef44fa9b15ae8f153af724f441320c960610bb71abd0e86d256bb7ca42f60c6f042256c091c7d5d811bdaf714b52a2fa1e5b94a145fb271d659c99b79371bff662f0616cb0275b3ace0e3528a70e8e4906414390d83a7b3e625c2434e6911aceba4f2f0836c2fcebb049d55bca878db1048bb55a0a77176350bc7835a99610672e2b815b92f8e49c5b3545cc5a5109e8cf5445af99378b1d7adfb99ac23a8b28409ff525710224a7f307875284fdb94986db1330a4db62f4e5f2418060ab8b21275701270ccdcf8bffa18471a63a8b2697ef505ef3f55508ef8f1fc65ebfbf8f4fa44a27815b1a4f093abe5faa190f6b73b2056a1cc2aca8b188395c9cca10183f934cb9c084d400be77f0046aba34b604dbb25dc8137097266e9b9ffbc69bcd6096da65d90bd0eacc2391ab56462540d618b95abb096e95e8759b9c48ba5f0e723c6f465edf418348d6442a4cde890811f11cf7428273774bb9a272238aa32fd90ff1b8133aade1111821f66914719e7043a62f49875ebe906c94f072ecf36923b091b95c418a6d7fddc16dd20f533a300213126850b5cdac2a3c3683788e8a75e994e69230f472b5c94b2e2dff2ed1f5ee10af8031f089dc4a1592889548bc780a90945e8b471a104a10f8099062859353662952681a7b1a53822c035bbc3e0fa0eda6a44727a015829dbf40205b65a8fa7a610764f99e1b62eba3e19ef72747cf1ee598d2cde6563cf2d4b01ab04ac8e1b62d4b28bea44040e738dff495df84c58c48bc0e78dacbd5487eb0fb3288fd2a902e3025c527a08e6b16d2c27e00cd01f9cc833a1f1b5e8476095fd13755969a353f13eb8e75b3de066d2909a28918623639a433ed4e42415d02eb4e717a2946415bd3acf69622b6ba3764a1b2e6f1d840ca34f8d35a13d2244d1f4a24e9a86fadb3f2af08d57030eedb4ad7b7cee3f7a39c122f1a4043ed590e33e43f3f5d089c7355ba74b66e5481611e631702c7556a3f7cb1332f670c4765429c1c3ec9ab8c0f286c14953cf195d64281949a3543c39858ac2197a51f6231e478963689436496c24377293533113827e8d8d456f02e7daee4bbab92d32f225183729daa97071f43dae2afbe79f7b609a037ad668f8d89d84f91e3f0417ca307f830f54161e94506cebb510e74702f5573277a9ae8dac36a670b5f64a2ace57d060636b8aa9bdf097a4ecae5814727d6d8e00ff857ae33fde1fc86b494b4464d4c3d88111a4a6db822202d700aa9f25fb472a1e6fe85f835a1c4e455c84c9a2b2871126fe7ea1ef26c058c458ba9d093a08c9d9a86642888b3451ad6e80dce9ddabab98224fe5b4508cdf506b923b3b6a7cac87cbb428107fa800082b59521307b8351c90697a3b3b456a401736892a6bc9649c59026206d3d1194258db8a9c078ff0e1a32ad67a98e7e291232e9c54e2390316430aaea9f2397542060b26391264bf5097fee1ba6821155aa7e99a0631202c55cf99d958cf0c29832eca150b465dbf52a12e50d9c69e79c491d43a691170562057aec279823e49cc684c4fe91d029fe32a3da146b17e0a0ad0087b1f21ddf2483702a402810e1ad5b8280b44f2e00424b56a672741855e9c69394021c00158b9208b4926cbf863305f29b8e2174c18d1658c6d201175feaa48ca4b6741f8dd15ea12234fd11802971471ef98e7d6fd8638643c2ccd48958d5ec78b0de39df5e3c9920da198c60731ef0a0c03a696f313f54b14b19482e4b2448616da02640a0511c531a95dc2e7948cc56f2b4130e32190a0a03ccb5917359de47229d6a70355ec8c01159a9b53040d7060c38d1015b92ae046b73e94520b123b9cc577c200ec4bc98c96bef4e1ed51f6e0365f55532300f495327110b9749252d5c0ccd8e402575e56d2c4524a23b2c713ad7e2e362eed912d8051b44aa64483397c601f75ecd7b35de2d93b84367db4b52408ad1be11a06b14bb3621d635d12304b948f5f5e0580dc516fa785e345e2a1c58a0260ae947530360947480285fb0da4059acbf4f7b0fb68e8787088cf7e1af0d87828d27c695da636a35846ee1d0a020198d93b8e302d3eeb201e21a688f75c90a62702068df37c8c9de2600f23a1ea1bc47d8e0f98cb91c22cb887ce31b3b4c5ba02cd8e3f5258c46065cb8423c239bce011747b13e2573dbfbba12b781873fdb9ff98391ba2495e44bd493b79c347f9bc3bee2860ee90370e30590fc82f7f41c9c729d1f86c58d6ee84a200bd46021ca12e5e74d09a2b06c778025f1e046b79d597d11aaf2b1cd32d0515788e16a08c6e7e9b2c6cd8cc913b6d2fa6c488e81895a8f808cf441ccd8372f26f3d7f6c715e8b35d4e303a1bfc2a6f8dfbb62a44e24c1ad8ae25f836d87208e0db317d27531deb98c45edd4602cb72623eb2d6581b34651d6aa5bb3f1c75db8d3746578a1c27390b0f480b1e06196f0b3739f7cca074ef27fd09de216d8ad059e8b654b6f3215c582ae32e103a7b4d9fb9947c6dc0a291108c5facf9c5ca8a46238e0fbf4ae00ff54003740e2490ba87b6319097a1a78caf1d3525cf3479002aa5a4f876883b78d51d88a05ef9958ec324770160c0806bcdb9d8bb38148a4dcb8f42fa75521a0a1d978d04857d595972c088e6d08cebbfb6d7cb4db04359ee1315fc2a6fcb63ea156d463b69ba35ab7157cf9165221af6accee654cd07d3006f2cdeb00e50bf9a42eb3fd8fdc88857bfcc39f76aa7af21b6d665aa05c3d4d2fad2023a7e717cd3231beeedd426497e8811a2ef22beab9fee40b343b166c110050d1a5783576103282c0eb6440758e01f7408bf5a73e9c5e141025028335b1b0aea0fa4dc82eb0815976479dc7dae8c1e07473d1cb9cdc0c159e4bfd27d9bbfce1e63ee6af53c49c8ac597dd299a009aa224765101eb7362b096a2a1881c3d033c7adb6e0d4bdb1aa5c6fec31561282d9285fed04fc5c045d7365516f359f915e8d27c7a8412c75d1c0af45e8c63faf4d3b4bf476aa96fabb8c015a2b8a2318ebcd24bccaf1e5f0415bcec9177b13a637d8cc23d3d38c6bbf4fb6baca71ab72037ac549b9ab5b77b358b2e25e1efe1e76fb037f919939d601447fbf030ad71aff8365959dc43eee3dc42877120a7fe414fbe6cd47b0f3de86ee8fac67ddf86bc147b8d558e638dd50e6a5d5ebcfc20c866af082b7630975e948015fc91503f22e07a57374ba6129be5129a2c9ebabba1b980f1d92181e58811efe61019ec95175a310e7343141dbeb716633a91fdff792ac5302365b6ca1363fb63bc68cdaecaa6c49b4cd618b3d0d4e7f3180c8828dd2c566e27dcfbdc1bdb4a18ab29f3fd97cc3856260658913c5606cc31457f5612d8de765de8022c2dd4b02706a18fff0c7f78a0f1c117d1a22846396cb6de29824b11134e74720292b887a554d102020acc2a8fef70d5e261c88675485f6b21640cccf8b9c80057fca4dda7a9f77e9d2a9fcc06ed21228b236f18bbdf88c8ee8b24d853be49b53837e510a7cfb54dcb4ac71f8ea1e5e081dc1260f6439045b798ecf81b166e41b8b724affaa1658afc1944c3a680dd3e4a57ac5f08fda966445bb2b3f9f5e02a3a4b88a9f0e621c6f089eba83de701af6f4af6db374f2fffd45d915d598771c8da04fac593080c891f70f34a4957dea3752f8e09223bbca20c7689381a482466ed1f1f87c8d64c88d63c93882ed68075df24801c7e1b4290d7d081f303fc4378966a34d757ea5457072bbd29b3de6672225953e8b13800fc931bb79a6e7994e00bad7bf2daeb9e55ee1cfda172a6a61ceccb40fdd0f5ebead6f2aca6d1665b89785770177a285a99589c22851697593863f8db13fba17a54fc2c6fa147b0e619632df4c9c605537ff8ee2d31bd9a85a1d7dacac8285897e2b5a43537789ccb1852075a1bb6063e6150d7187f9d714d2e7566112ab411ead214b2bc64a79398a8f8c5f3a342a21e0d4132ffe3ed3913fc4fd49cc749cda10ee3d6dcb610a794957d8e63c2145d7f79527c1a7f363b5da0491eddf0e3a663e875940bc8fdf042b55924108ba60a00bfb408288d58a8a4ac10ca225b4d424e262c54696cfd9c82b0c174c4610edd5edd48979d664608f8fb8f4d41e1ca244ad2111942a77c032de7890436a60512223d80ca6399c3f21c44734f577c7fb9c14a49eadaed576271d856ce973906b39015cd807e6e71b824e8bc873b4698de48ee144ec6df9f7e960b40462c1b934b62dac9e623d360e5ecd4608c3321750abbce1d7f31c9e2c1cc2cf88cccbd9bcda1582beb094ec299876063ae0291cfdc696fb8e3e7b631c8f331e11f85a893acfe5d3ee16bd7deb5f3b16b791a0da0b89322e0c5966b0b22e8bd7adb2f74da33620aec503fc831eabfa713f5b93ea16755accc2754e34b0483b733049d10ed5a77479c5f3c67edaad813712d97f3a47d233efdc718628b6332913a6093692bbe9876428c922e3762c0d2762b5b71d7f9602b8e218555389a370029cd7240504cafe98079b2761a3ad20550582c4eb516cdb10ce6b37160987b358db77f480ec8f4996eae19b1c87771addbfccabf0df25afb5e1897681819a335c45e1756357569ff09f011b1daa87ce29d742dcc50a74073941e801563b066fe8406d266ef9c0c2400d6bc666a35f1c70029aa9803b618dd203992af582d3c6ac8719bdf795d6372dc325cfee07015aeaea26b469e307f44e07d6bdc30613a9fa1f1d12274d65da2fad6a7be0af18d0093fa8905d20d865fcfa54e2fda933b6f7f7ead08d69f608c4c59eee6ff944f9637746acc5db34f478d45e3f456d6baa0b8d37f92efdc1f8a21939105819432cc9f2442347cd2737ca4a150e4a64258fbe31f8cf968375db55be070c57a887881cd18fc6f037fbf40448c8f42669c1dcfced544c32422f1556989d88e923afe100ffe5504ae18e992ce58422edbee143356295674f19b0ddb89bff39f8acfe737b9d655457da0a0af9ceb5bec4770eb55ac401096f8317cd233d2cd18c0b994b652191e424af0bf036ff27373c4b20b76b5b6b97468e91fcf54d7eccb2fcc378697a0f017f1b55d3be403a4cef5593132bbbb153a77b04d408e4edfed5b498dda02343303cd467883d72534e75134b3e2086c7fcb5f8af0e1b46073b3ccd2c47e955d3869a674f350093c4b5522a7a6a53961f9afa5537f7991bc9f671df249871a409f4fe20c4f694bd1e35e5dc05f076581cba319446fa7a2eeac13739420e5880a77a83731fa04c7ff52f3df1122a209cb27263fc36de4127f8b8170745e2153d202402c3d224d7c907bd2670ef5e6a2d4571dd75007a87b015fa6a9f2009dce91ee00900296cbb894e71c99885fbe8ddd6c8c7214cd13f935a757e9efd1326ce5303306b25870128eee9ec3e18b486a7696e3f56a000c14e675f1eef425ac0427af76ae84aae33f3462702687969631b34f85a2555e33abad93c8ceded3dc5b3eb4e67dcab2a62badd465d1650b3922039a9c0a3de015a0671529c20cc4c03d158ca576a4cde7edfd5574a63388062fda3e05d737b06cc9c9a3e8c6e00b38675e22fd04d8e44012ff99c8f29d1bdd01e80fa7e6c32161c8ffedf5ee2c4a23a133fff38136477c83d555479f7a6852edf4fcc1dcaf848fc564dbd3cb54207a2d5a00025d12eb51597caf0311b1c49e7d192ffc60f750b1e2acf6a90836cdbfc5a0a4ad6ab6c10e3113a5a5954fc135462b7c9c964a1a486e85f9b18683b83da420e1c852224c00f40c2bb1c841c78cfeebf36bb4bbe76be7f317927f6798182464c312194760e2f9134fd68808e9252726576c301e087c2713c5c2632d3bcfc71f05694bc23a8f04ff10286ba31aa99a4aa757a26f177deb79238d7a497a918425f6c62bfc47a17d9c14e349c1e724066b509edd548f2d5cdde6bcb37280d0e295d624b40cc778937d0cacac064652bc26614512662eb98324db08be7b93d13e0a74086f3ae7665016a28a0416084618e69ff98e65964c4a8704388d12833ebb15abb00904bb3fc2592246a7eebec4b0820bec2cd54d4d8599d5a156b281bc09632706f4dbc088a110e4955c04aa3e053c84020e770f6a201edce75e1955b7ab8efdb3aa130ec072b38e69cd4fc38b7cca6633e1afb060047b39450372dad081dc8278ee0c7719a9e1bd593f24d2e15d3cc9c2834756a09f759653470817a7a87ec9a8e4fa6b1afc6d89381843c09ae0b2c3d6d93798d4aa97479f40b0520d9c661be65a594c017f4d7ffe2bd970b7971ef6a6210c9dfd470bdb152b607fc3190a81e78788d64b2434b632f19489e18c41927263b804529e6cb830682d0fecd3793fd6e1fc46d71ca5cf1d88c34edcb6897bdee705115283dc4b9e539e0b819be9787993bb183915952e2472525aacc290b98f08f0477584215ab5574f1bdda869a9a316e3f2fc8d4ec0cc58d6c7c182ce701f790dbee1e689180671c928bd818fee3590e5ac150c104ae9a062811913cebab4b92878eb3f71792d0eb1a3beca23fc2a2e5f511df51f9208eebd5fcd9e3d32233f668923686b345bf71c64432b9433a22511c29bef549300ae81ff0ab328464088f2d0a5c18eb2b0a1029760d29f2a5a0f23a0f14279cb607329514a0bb5d049056a9aa0171e5fd238728c1846b8eeeb4f64c36af866e88da4047d2ab585ca789406ae5f67be373016fa1664ab78d90b338c418e4632c59dba37378381583f7fc979b7fe7830f0051c5ea8a49a8f27f743639a3d2694284e4c32cf86a3cb9110f57c0e025d8135b760e37939e1fc0be158b93827d6e88b5b3fb7991418e90e6fa21fe060904bdc56f675d0ccde9435259797d35c2826b71c42e14660a997b9b249fd90bba863bfcbb4910205b873b80ae48a8e88a16946c0717e6f1c804f00bcc0dafd6cf77d37df8d9d3773f5eafefed9a83d3ac0b506c04e47b54d3cbb3a9e35ade3561a1d7eaba0c238bc3e82694764650e305da4fc45d20333a7be2b773de6658eba259e52b7f162a53ce53f92980946724af40de8bd49cd8f9b8f4ddb49f30d51e7e061c5cfdea19d3602f5b4c38b851f3dfa36924a1c9df6365fc0adfad05fe51dfebde1ffd15ce9618156dbb51536e310d87b74bb6dbc0f06b422f64a9a60cf8440b8616180012c8aeb01156b11f5c578d7f474080089a84f6502040a6daf26580f88c41b18f6df711376b7bb6ce8d1b69f26332ceb396393500c3f71963cf4011d033b5f2afaa659ccb1069d46b625a53b2e6f0a3c77003d3f229b33f8805aec9e66664e8acf3c9712fbcb5d2e297c5692b57a43743bcb136411eedff2561b6ef45b98cd919fb826d060f29e24398057309758b9ea0ce1c9ceb3183e68fd5609cc9417e4f20fbb202072c3d319c22849188443da43eb401630a4d631b8c87d6fd4470d6bb9b81e03e978308611431a855341f4fbf17137a03c45b348b01bbe9a17aac37ba418ed77512b29b0bd956114ef54d55d7bf5b6bf7ec0def8f987f59574b0e27205b7fa4c75d52a66da2857f201c94e74c1c46fbd609e94a57c707b8093b6fbb882059d57d879c654afa5867799f51565b6092f470d0d04215e297a3657480683870024b3a4d952d4176883874470b18f49fb25ba59000c82909d3d836999dfd01d326eaaa1c2f917949a20201f08515a0007a36a82af666bfc8ec9d5375e64cbdc00f0f4fe25feefca6ed7ccce732ceb27603f158f7e38468df821110976aa49d1ed0da58df18b5b799e7de3fae9d1db048294231b710662c5681caa90140f1ebcf38fd4870b75ea803a938a3e8df1ed93e267a200576598eed0791a1a0f2db4c770341ed6a536c69a92d5ee6009fedc9b7ad1d8f510539889ab50087041ba7c8b07febafb1bff02ba71a8e0a107ed17fc23dd102fd960e91d3d600e2e3c71b4fddd9c010e4f16799c36e2756b8807e819180c3be9a5fdaf50e5af3a2a616df33732d1efcd5448842b03dbf0f91f32ddffaa388b3d96953427c7da1840fb3d03fe204afc54760e669bcbbf8e1458509046b07cca4139ea2fdaae7e5df5322c44c3e17bf9dca500ed9e6b591a3a12c5bfaf97c0fbe68376bc3613f6e2a2d1212201fc77f71270939f93d689e1187405a8df5e2f81b7cd676f19cdb4dcc03c79da70a43d96f46524401f16eebda54d1579c1b40a8e04ca34a3b58864636d71c0433c33d24a7ea7de6e013f365d98838e002a10ba82fa00ed201f8fd4c6be5ee41b883c358cc457b883484f05990dcf823e1571f66ed60f80d3bd3ef8eb03666bf1d5b4b26de3302e93949c1adf02265df3dcaa969f23cf993179e9872afeff9cc68668bb2e4d695d7b05dbbd622aefed7c76129a59f596d0ff502aeed6bbb066d99003362b39204ffda2d692fa53b09271d6e3f6bdfab21993b0e79f31140bec3b1b71467602cbf3e28d642f696675f45196560cedffdc48409b1f566887c84168723b5022abf29c0255744a899ffa62497fff6807202858f82f142260da4402fd5392b5d30746132294e387ecf13c630fce579610bf6083f16e78264a9f9912820dc79030c81e47d300733b8838598786fb655f83911abcd15a9c54f03df4448563aa65b59c9737e65466fec4bc9d726ea61686b439b822d2ab3887da236d7b9e6dc4b2387cb7aaaf547a2a2e872b9384a65c83c2fd55c34ea70119e63c5dd6269cce021d42f700b58ec1173ddce9e86638a564a829e20844507d66eb95783a4d30a3742d4b1680935639ceb46c17e429df5a078b03d607c62815c206119381eb8d93a3c73ddb4fdb761c7649531d6b40aabd346c849f83d288dffd42c08966791e79fd84008fa44526a3ca1064c9dfea6c705d33d09815e9f8c329769c708ca177d2a35093e843a9740d3fd016be424031216869fe9bc1d7a8c9d9ee376310d439ab6ba229db1481531da8bb7cc5201227e8509437348925b453e9d039062d784dc9f2f3712ce78048776453f6439d60cc818060dee1123e41d45ca40b1db0c844d5fc20cc8bec306358823e15b28163006aa1d3954b00b94be120c40a141584a03e19f722e83a42d64f126c5e0baf5cc320898740d53fa8c49315efe58a6d78678883c34adc0ad3583064d803df998ebc93d07c6818342592e4f8a12e4ade98a48b9b239efb622d3b80c800d4a72239ce9bd98aee543b5061be9af1d4adf34315d1e4b3ae57d48a6dea166c4a21a48772f753469bcf0bd37a6932dae80382b33558e8e97af7ecb6eb5b82ae4405414dab1c9232da2fd2c9334377f11530059d687b964b9b865b1c4c89327d7d806b68c265ab3aaae7dd1aaa5f7ce6cc73784c73c5acec40c13527b908d5c601e2baa5e231156c201667a40c9612fe45971a68ebfad21b167c1dab7404f5ff58f64a1c7c933ca20011f78c1c96402c0e6c3a4731738572b60af27ac97ae52c7942b31d284573f0677abaa0661e39d001544b8b6b615277c29df9013396cbb1eba4cc952de3041d6704bc3fe414192e22e07cd67c63df14d7828a348d2c4db81ed19f3cf0c382d6cf4902623c7bf1707dd75115862937211edbf37963e9cb03e446e9e7c0722721845e9e304258de64cc7a4c5d142b954c2316c5e4c98cc4d91aef848dad9bb6baa470cbab2b678d31cdc921210b357676fbb5dd1112bc23caa82779f8c3834835f9f7df652463e72fc22fad048da92fc01e16f9453dec2e68510339b581bb7c6de5d617408e408b698eea83cb054884d6d2986bd5940bfa46f140fcc93b2bfafb49d4724f93f9994d75a33d905cb58fd45b48da9345caa96e4980ce0a2aaa3e8dc9a7345d7acf9999fffe7e3faccd94a35c7fd61402e5f3d7bb616231a749fcd2f849f0acb44d95033e7de51a07814ca07c16c41c9199130b3fd5f6a2285e9b46c005655c6a09a8c71c67ac00120417784769ee0ad425fa65682e21a645185ea44e144c90ebc95086bacb85510106a1275cc475bc32b799feb1d705b44f38e9b58503f87b6a908ffd67fee0f85d25d923c8e5a43fdfdd625ce362e6c17ec281554d00070b619551676c4f06a8a7e2b75000e48568c5afc304d485f8d9a65e51a2d669ce68c3005d7ef73661abd76c619881e16b616dc4dd1355c37bfcce43af81a952c9aeb4e92b459cfc7e87864eb917cb8617bf717a7930690b73f23c1ea8ab21e92e07f8f7c4f341d45d9800dce9bcaf7616228f0c9631e9d08d54bc9be6f52b400019419679dd527f75c59760a7eba8b445a46fc1227d33227776d08a5fa0d5357f1b185b39d61ee010e46dff3a4beb4467c71b5a4c798608be0bca754cd6b437bb0f093ce2a7a5c00a9143c88bc6a03b186df939cc58e3d102288c90f481426b38aefbaa415cacef16e25e5508471f8cebf3a7f0d4991768370bcdadd0a38335c8ca07fd0b6fec441044c7994ff9dffae4759b3c617d437da8795fa980781618cf4593f1787d5c1177b5039012ab5fa6aad42660bd24f883dc5be99e43601a9391d584bd6c404eea43639ae95ab3788230a3a00fb267a6b31b023283c116b5ff08ecbd3447bf7ae8f5441a9be2c131903a7ebd3c674c7969084131ba65a69a34440fee93493013ba7514be3fb3cb5a69a5266af55298d9c711448863558c272685bcdfc133c64edf036767e4e9e55a55a257372e43224e8dbeb9142cb1826808fb2f710f03f09d24cc2f90823e809ff68f25eed4eb9623d5dbf6166cf008509243430cb0a72ab85c821adc41d4bd62498e82d86357eead9b0062dc387a8737f1660178b9b98af6790d3cce92b1379e12b187e90acaaef295a02387e632c5df071161f8f524e17eff4304e02192fff4de80d6d428049e146e3a805ea2388b296f295fab95a01c3814025594309aa9c5da7647b1ce73b53da3621e7eac6266c89bc596fd72b462967b37450c7abcea78a47c6f2441e7a81f81b6893a26a32bace7e9dc89e2257d0b056adba4aab5102c3461eff2e8cbb49e116b64d4ebed1d932e683ac13a41ebd0e08ef89d0d444360364ecaa4fe47f5af91152b36370dbef086084e6bb5b72f2c57f5d5a5245932de6a6ff1bbba93c0563f009dc4b6ae96274041e7629435534c52bec03cf01e919a71178d2c66f6cc29a49bfdde609b85acf20ad3e6a8843692d52f48631e62f5d4237416f0187d8ed3199547f3d0d5bb10cd0dbdbcde8fdabd93c7c4ca1e1cef4bccfec16069e0aafd7ad7b20aac0b240cde1a13e476a8cb34c0f7533e6d043f631aa82b95a98ac8dd4f08fc9bb38312965d0793932100ca804188bfc296f8cb38534aaf5d2bd79662e831e97ac6de61e1820133a00ce48b45bdc4ae1161b668279eb089d1011221c0c4d0641a8631e970bef04a6c71acff1ecfa61c37c5f37f946c3cf7c5a140d92762bd3467482162801c985b497f0ca2fc24c4c55a09ec8960d193d0680848b1e31f87816caa0a42130a4db305a626e33135687ea91ce9a0392d6dd936935998e3d9e1b750e17a4834fec4e3d44fbe53263f319623e02aa1508601c52b5f0f8d1ae0f83800c3615a895102ac015b6d360280952050233055495d8b8046f825b24cb6ba0ce1a014a3b4f938d0218c99f542d79c2f09c6db2c8e80244e564c7932cc24ac0ac5894ba58a5e95fd1178dd058d40d9ff9c04e38c7004491b0f66e4ad4b18b8849587a3bd351c6d438cc7e37c6b7dcd1090fd9ac45a99306ffc15558d3207ae60f407686e49d00da5434566b81108f8a55e50f1f06c404791e53e9a7c22d553851e0f6a87d8e945672db633f2aa4d89158586a204fe15928146b402bdbbde10ee21a65ec953e6ae5c20107d5e5b5cc68709db0ce92f8cb4fecaa8308a56a1dd9b47b0b7b07d77ba07726fa19830042fcfb737947e87de3e750ddedc9d834ee68478361e27772a1b07bcf53d18feaf1714ec7a260f4677e5a7c0da9123648bf0cc09c537b139d2331144299c29e192d6a5e43a76515c97c705e99fb1d809d347698b56a2437b968bddae590b8513c4f38b0054a8e7e4d491ad3b7b05a01e00c06dc6435e4a4240e0b5fe122b2e17d64c9f258fb8192bae00248657b15cf26162595db9e9d1b9f2eed5166d1e2863b93ebb28c691acb4fe08d780a95d0c4dabdad30d1d9306c09a017661c22729f425f8d6bae81c9913b02eb02af94b3a0f644ad50f59c59586990a4fd44f923451bd98f06aa9b0bad287ea7deb7f240a490bfef7f8a113f47ec8afbff44911b82d2d95a421366047d6e343396ea50a6cf45f1c788f037c20d0834544a530b77cca69084eccc6c1d27537d2acf25b3187ab3fcabff25890351c238548b1ff2f422baabe011433961226b7474c4e25894222a8a8fd5aaedae52cc101e7a12d1cde14105f0ebd8209285f9680af804309c0420439bfe6f95a7495aca7dece39142472dda117cf8f415e95c3a05905ff67caff4fa3832d08928496b980f2e17f63f4e795e424641e6cdc9360d917df539ef401b64dcaeb760d2852e3267ccb34d8bbd688588ab9077304662354316ba96cec5fc7cd020be3ed8d7c6c7c9d3005e40604fc37a187bc8fe0df8b03aba4a752dad4ed76cdc991385b4a8ae5265e2671963ecf09021f27dc7687f6240bf2dfe8d4f84051e35c1cd886e87df832980ac9d3c23d1f87d9944cc92a928ad2fc4f8e2948e38bd32d8dab0106558fad05c07567c6e13b509aba37c71043f386357577212def0147eb4b402db2837b1fd1a8229bf99fb58d2da1385508167d7730dc84efa3062dc074123909ef0dcf447447a0a3ef40a8a7ebec9bc0b8a6e50c52887fee508e97e13c99b6c660cda87d68d1e2ce6ca4f1046cf33193e76151d216706ba57f5a3a6014b4d130744641aca460b03b26e0f8edd3e7ce5033d5c1bcd693d8c315ff1bb80a401bc637785243249bd746ccd5057e1b8200c704c2457052293c8e43ee34f534ccc75f310057e38929095a5a38a4e5d3196b3bf3703e6b8f99164b275d93ab830dc7af11708143c9c0ee01f68156885650c982059ec6995e17efae9d7937adeb2f91cfe9379f7f879418d50222a1c302f0376bc523ea32f088a39d03b0cee31f67533e1f9516d1d1137a8437a228f57b8a4358c75d7a945f1ab35746f2107d3d144d1109d463a6b38b05331e16672344f26e645ea012761f02186faf6b07809b1d7185de1c6ad390f0307cedb7455e1ea69ca78e9dc580c3a3613b61e2ff7f61011ed275e0cc98f56401bb520ec0115094a62219e34a4b9ab4661739d481374546e4c38f215a4952117a41478c36762025fd68b8de23044cadc0dc1f1de1afd71e984e68215a5788c46a36a0faff2ed6712e1484207f150b02db25e234527c9c3f39bc23558b608a88c28c99da604bfd47a58ea22a49ff445abef153bd69ae4597dc1bb8febd1e77e2bc8a6ff85998cb494e5a685bc6dd01d19a5efa3d9ab38d01e2512f5bedc391f04a0a50639cdf6842323ae9a8d0797ca68d790302f2e3c915498e422266629c8518f3a1ffef343c120602ccdbb24353f6214c906d609ec2455e913bba770663607d437250e8d759ddf57f73af5cbab5e5bd53a4864a40c65cffce21867bc4ab7086957dddfc44accb14aa8741095841998c81b43f37611f252ae545f08fdc3a994266ef2183b51db389116f9e9e134619be52b6ada03046912d3dfea5ee894d97033137f4c788c2a255ce4eefa7d194d8073f8a71501418605d6ba7f91aeddd6167c11274992d5e209170590309f4a0ec85ed6735efdcd74a853a33b1da380cc784d853749a12c2962fb743bc0cdb1f339df3e5be4f0e1212cff9275ad822b63463bc373e55fb200725ea5eeb480e648cd8eb1ecdd1dc7a5274c1a562c89b37032b6883f9bb4f25e42944d1a3838c1a91030570f1576c35d8ddc4dffd5db2f5bc128d331a7992453bd25965e00613f7428f5bd0d16dbe99d7228d8ea6590ea41ba9e11062de81712189763e8ddcbf7ff2ebba887d3ff886936b13e2fbf01beed621e8d8af27d95a77a15f07df90737dfd1cfaffbc35dbeaf84d05a8c76c62f1c2039776fc2dc4a5ff78d4941c9c02ca5664036e92e6cf254141b65402f597d8f90c744b24f0cad1acc7eae38721d59dcae680f95ea972269fb3b6dbd250c8e9500ac7f2f00f334001f93255f42cec2c75763776db8dc8e664efcebd21927a5e83971e68a16b9cd3d1912c50436cd814164364b9ea826f03d39db34d6e8149bc9b66ad4d9d2d5d42a1c5b436efb64f38fcbe591193543912c9cfd94cc3cc58be65a5ec2fd56a1d74f41520db0a2dfdc109593aa8c55997f3ff941b942b655eaf9534edba64ec8a907196c6a5011ae39fcb1a1a3e2e9e037fd65d0accf6e9bbfdb5eef49a7dfc8a4211928159aa01be99cc3a0d82233c46be80c21e1c9329dfbd5a9337661654b1bc59b66c4bf51f5c88015a3b994855409010b303ec52c481adeb565ba5a6250a927bcdcaf20ba88b0acede28f6e103f9b4a3d4f23ce08eeac2b2b58507a53f030e27f4075432ba262520bb6fb31bb7c1aa0cb994e4bd36756d3fd3b26ddb644a494a29656b047c047c0422dda4f80cbbd4e482b3f69c3c5aba97ffcf96ffffef0b8bf9437dd33e0af676efd9ff53b31c30acb3b7e65564840b66db42e625e3fd688f2fffff8d27d7b0d67fb7f7de77efbdf7becebdf7def37a68e2ca469ec02c2658d21c64ee7dd45894fb9ffb0bf448b5d9e2b668e47935bbc6e37beed6798f6b0bbc775be8ee7d0e21a20c4963c4790e0648462c575c226c26deb7bcf7b46fde6d204424acb2a98d50e3f513b6c729e04bc0c48c66dea170e73a7d3e92e2ca9a5f5ec7632f4cdef1da9bcc7bffe6bd773ba836d979fb8f45e53f97ff9cef353d7ba8d0568fecfa4cd7f3963ab49e65bf50b2a0e22f4992486b34c1331d235a185b62a4e5ffffffffff4b306150635951a7948d9699a7cf328b6dedba6df3c02b02105bd2b01814c64c39af4a7c403a6adea415a82ea0c5d9b6389f1e53d5f50a0209a9e74a9b085b0df7c86de61f00f93fcb0d208fa16155614626725ee3365dd7b58e049c435e820ea73d9050d7f55ce73a06d0b886ae43071dae2361fea0f3306bdc1f8f630f78d8c0fc61c63d48bbf13ccee3ee41e322c6e510356fceb9b70d02c5197784e696500863e2b6b756b330b3feb09d2d5f84b9ecc240720ef218aafdfaa79c938052dc346f33be90e248831031c24b07cf1017f83cff79166bca6731af0f23ccb3077b9ec548e4f32c7694cff33ccfffcf6220b4de10dab4a3ada35c949b747e49cabc6c573165b74ab76b2c083e718b1950d7f4ec8019d788e3387e819c3760c6356239063303665c23c6e318f7a0a161e3f6fca1023234a743e6b1b18c5a63a66bdcbee70f345ee3255098dd1aec5ed76c3359590a4660edf2c27c4de910c9c898ce70d5fb2b2ba9c1129c530a9ce29c7645805bc352668f4916b1de7604daa1e102dfe07d0172b737df9e07aa43443a48a1ab278fa6e9b19ca6e9b9cb05a1a5c56a0becf50222c2d19bf50656098bd14ab525b441d0dfd7075f19513ea6bb0444fcfc9808dae0c0cc6cddcc8c3abf1c1490af2c3397e5b1c5ae598f09d9e105882b58d6836c8f0671f5c9c0ad38c9643d892c008e89391d85319372a402d85e357092f323fe9039d90d106957cc4e9811dc1498cf02d8888bb0eb4610732d49a627ab035a6f4049480476832151bc1a8bcdebda9bd71ce4b536e36a7b00e431542ba3556989fa71affd08f307995a43598089a03b8c40d3344d63a1398d5da2f10f08584146bfdafdd7d3b57cc66b3beb955bc86368b64905ab7325c2735bfe3e03ff1d2e34e0b3d65de731343bcd2f7c36eaabed1a97638d8b7cbeb3501bff600e516b80e0f3189a0da24fdc384d6fd81ad90c30fb8093a9111c7ed15a428109a0c66e8ac09fe1136cfa71244b1b2275c23af566d8d45142a6c5c64e382e43a9d5106bebffff71fbe371fdf1d8c6de1f8f7f5f19526b9236ab411528fa984895911d49f0ecabbfaf779c6bdc366f26cac880b2ed8c167cb0820fe6a7ba6ec107392243b1976d9194d6d7468a0d167912541c63f2623c5641ecb3323264325c8317f09aedfa0b617b6b4d40aa800522c3c9f61472dc9d86c7356a5ca3e31a33aee17d5cd7354e63f41ecf732fff7ba9ef83c444336eb904146f51415272aa261dc196a2ffff07e920f75387c5a290e63fc6feff118077a0794a58c7be3b9344ada635ee8b723f19cc21f999901cb0c2049a582a579603245a42cfa703c79932723cd6ff4fb5e23a7ce29ee0607853971b9922efefc8cf7c6f63454e62ebbdf79e7e72ebae2d8d11db56a4ae55de710aafde853fab6c6aa6fc403e900b4841c90635e3de60a45a20ce7253c87befbd0bbb33461c22177e678c38d7b06f182333ef6876f707c38a8bbc66e33d339932758a7288a4803323d2a64dc5a20b5c1e55deee12ec88ad0643768a948286333fb73c8247d4c371a6bdcdb469bd90488a5a7d72ef8dac42769e55569eb04ae7fd6c9124728fd7de7bee2e1fea184b52fc08611f663656b5aa968d141d2731b02270484c57c757c8c4dab8548760d616eed8ae6d0f41663c513753403954422509e694ce94c7a256cf34a1d0643f679e35a1728fd7415bc4d99684ef95c80d695694f2342e722a0596904c0ddcd1ebb2e3c4934ffc75020d22a68af110f280f295156df89a48804eb008e34e3afcaf832174f7fffffffbad7f86ca424f64ee75b9f73e0524c16590fb325cc19774ba3e7e4ec49508390837dc3f5349a6518d1b3101c5922026937ab5348a5d3099a1dec30f52a0e1bc12ba5396ec96d9dac5f7e5e0b28586fb47de7bcf13124a8b8672ef814d3a5127d2ffdfe4ff2a25bb2a0a84524e1a89f2defb7c6b63875ac2a8e5cb1a16c7b5d3b97e3870202a29086986e493914bbaefbdf7de7befbd9f40c1e02819aba26a889897127b1435383e9dd43c9968af32f0039d989202d1465489f005bae9d911d9b9e1751ea3bc4777d82864129aa748e7e162ae0325418a8907ce10a78684c75731cc3d4e51042705d5db723e29e5111f97e83a93d142167dc2d237e776aae471062185f572c7822cf2935518d2ca7c0844619f97a6f091339a05b6162cc9926d517951a5cf2e09f4eb2419c4a05d1fa0d029a6032de026328f1354215f3b64211da48e9a49a8d68b09af0c152b1e1d671b952af80124a983e710cdade488b476f5d4509d087fa87c333efa03bc96a3c1ae40cdb480b5a929cdc2cc708c3a2e3e3095028ce581ecc3f00027d44acdca44545b0219f25145ba3d55b8d8f2dff590e51036afe31678efbd3bab34469cd7b234f78d2b2f3ad0246089129ec685509c96d156a66965ccac43e98e651825393783e486156e01033d2b6c4d944442df948f1861fea331c6091cf9c73f80f0eb98aa8899ee893db6d39aa7c58f7dd880ccc2697630918184b0b4bd89829e8811919afd70907bb9efffc72d30e4ffffff7322b6de731d2c6e1510c1704ee87699c5d3b8c8c93ebc5189ae6ceb6aaae24d4eb778712ed0c1e65c39a644d81e993406c88d2a22351a612387c21bc01ef38a15e618023f85aa92df9530d5b2882dff3f5ae4967f0bf987cbffffbd869ee0c553d5414d02e7dc646623ac4d352741192a8bb719a963801a76d2316ca2ee70a3923338515932ab19e471f8c13e99642ebda1544b08c5d41715b7b3a521a7114c7d94ffef36039b8f299b11543f5822d18ead69c95011ebedf02c6ebbb611ef6f50d434bd3906be28dc57fde0b3ce1871cfc845cc39fbffff7fefbdf7de7baf57e6ff83f1d9b3f7de7b47b34077ffbd7160eaffe169bcb04b41ecd75ec57aa7ac4530fa876553e9d57528de7bcf3b6e8f67f491c293fd9f8c52086fffe396937d0b83fe5043a0cea4604dba2e3ea11961c53dcb1f84d0ffff0b3d698cd856dbf538f55deed3fb74efbdf7defbb0e619212f925cbf53de3d6758e31593500f016444ac270c504813990904822c48d948396f8bdbef6c92fff13ff683b9a900d4559ab7a4a9a070f667cebe378e45feffff1f089d3162a0927d5bdccfd8c8d637865268ae5cb2905a4e8ca04abb66bc6249bd71d13890b8f0a010d11179e622d0fba28e8d3af96791f25a3a104ebbae1abac3d0002317700ae6add96235da2caf6445662ddba40dcf0e6edc350e13352e433025f8767dd0962f2794548ce9039006a585b2ff94d465023f6f86c019488babb19649df90dca1861f26faeb7c746c2228834d69790a82c659102af585e5c8f865fbfc8f5c5994b2c753fe3ee60e5a7a7c933243a42f4b21b8b20ca62836495f48cb2e28d785cac865a9cd4944b7bcd96a725eddca70d0ffff4fa9f614ebed6203d1da5fb4cba49eb9ca80216933e76f6721c6703813e09912110bd417b77509a16c9386a2235870869e3867001890c2f2012babf971a9010acf9992936b644ab579fa4ef94994a22a5068f8194292683e318d855829f9a8fec09adb2cacb19d243985a67733b35a4a625501f87b88c89ede255acfb729e48a29240ca684ac53d47bef4abdf7de7befbde31425badc7befbd4e9af77e7ef6ac34bd7ef1b93c4ba3a3e55f5477f698769736ab149cc08f02c24b9d32f114f7d09d006e6898d8192c27170e4d3fef930de71896766f0c9033c1a7e3faf8b2c4246b42b027b831134257a839c51bc72f33c858f0d11fffc32c16f9a5a05a75958901031386fc72d290a18502bcde7a534a2956c59bdefd20cb1d8fa3930ddcd4d5a4672b643a3cd115a33871cb36199ac2c8c256d326938ddf174a4b727a02151c8bb370b2216f5a31acc8bca3b32f454a56d0fdec5f304903d3792051068862b3e48302e742544d5a83b38d1f76cd8757ca213879fb48b331b38ac3ae659d000aa17265e6ffff538b3446fc3f89d5c8d78148f6de7bb797ebfe6e1d05898f40d83a36f345e2faa400b5c52cd81632fc59fdd0d04d614b1dece220f84869631a51e402b764f54c2c218ddf094bf9f7a1ded799ccda6134c9e744470baa017395d6f4be2c4bec9420ec8e0b26bb939e7b9de9a2687ae859c3012de758c26815ea3d47c513cd852e9cb42eecefe701dc38765c8d086aea49936e5d924a1c4040a9c613d66a7d59464c3826422d545bc6e551857266e6cea1a2bcd7cdb9d536deaa693b88605f5ecd1a49e44000a7aa89da5a18954fc68ebd3c5e4870bddfa52eb66edb5751c9ca1710141ea334bab29a1a8d823759c06f4813d1770508661ecb9ac7b640d0c04a2408b5338343b4519324a564a90e9346dafc9755408e19a13545619900138f3e3418136d34d697a1ffff87d218b15dc7c81ebf81b470db8bd509a4970d1ca451ac2dfc56063cd2f49bfccb2e4edd57fb9fa2e8079de5b701e90e4302bbf747d249a77f5441bc8dbfb957c713a03b98ba4e89aa632091ec51ac299e7a3a6e1f0a6721abf7246e67ffffff3514e5f0dfb5e1034f54cea5118a932b469b895913ca4c79a565ccaa0d4150efbdf75252f1cc6253896ec23497743058178162aeb6ae3f2a121fcd9fde14d26a918431546a43aa1c07a4a4d8934bcb6deb0133619a947059da1256788a4203be55a8b2ae1e90d9334c93cae2b1e1f8f97a205501dd5510fdf736f6de3b5bef1cbdf7deef110538da3a14ef62ade397e605690bb2024e06b126fb1805aa92b1125452b43319a881918cbc0da970961e44e5828abee6d680358458943432fbdae04861922c61556fdac2a41080924d7e75acfbffffe3ee7fefbdf7ffffffffffdf473f1214f2c208b6eebdf73e5cf3f4c1ee7befbdf7de7bef283d8ade3134b15971e4e824068f2f384c4749e58a40266d4aa567254e112f3c21d12fc56e1116da42ef75724d915783bced7b46fbc6a8105418586abb8268ef94beaac3903bca6e501a5b4391d1bcb5b875f636cb14e58a934243597bb9aabc75c12c3c685214d0ac1f38fdff7db4152bef941c368a30284b94a097660c0a64baca38a69b2647304353524741dc3644c788edc7ea8578845cae4e28589a7de240edbde7d1480bec72044b7063f119f159330a552d31ed941472eed67b9d0dd4f3bdf7de63cb71f4eede3b4ed17befbdf7faa5ae7288ab4ae16359508acbdb8e0cb6c8b364fdea2da52c96be083325efbf215410e56defbd770310bb0ec5f7a6d52393d149052921e112a541a985179451eac8aff92313272bf5a61ed48a2d8582099133b48b77aa163793eec5fc88c175f0d060016769de2fbc411d56635ced1aafcb4979ef3d642c0ae7b94cd17241e04522eaf9e11a9e1c91c7990d487e88c6e28edbd5c82c34ba2a689516edbb159203993ea243319344e73bc22f0ffd763dd88ada8bea0c5845540d4f3748703958ae43695f2a5915d30b31b9a356a9fed42d4d3183b31f4890a8cb6d6803b00b25b279dca875b18e3afc2087af2c1c23229c12d802c470b3d8d5f19ec08a715022a9835e1dc7edc2ffffffffb70057a29b10f6de2dd81e0021e945a75f2c94083e4840574b575a512952d98a541ad897c56804654a3592a2e696a8d64535eebcaeebbaaeebbaae3d00ef0a265038cc94ac1d8ed937e68125524315b5d594a1344e540e1685a49be2ab61b88b7664483fe11f8f2a88b7b1bb4039149df9eebdf7de7befbd378a8a1ee979872d862b46c33cc1d984b5020098b0605a4ce2da64bed6490bca26e44b7a0a80118df6ac63350b6cf99a8e9cbc409218a2dcb64c7c531730afc4ab2217fdffffff392e216dadfeff3f184963c4b6c5ede5c9955003d3d8e0a0e54cd7dcaec2f6ff9779b1894b0e368a9884827edca4355b6e4cb3ef511ccc12516bc2ef0039911fd193fffffff7de7b3f4b47f46cb5ffff6f51a23162a90bdbf7bd00ffff3feaf5e59a1cc26b481327535a462f37607a853f8e6c524e69d95486219aa4280ba3882ab9f71526fc54c93272ffacd7eb8578efbdf7e9cc18f1d386de4a33461c8f77a8140d9aea294400524d1000b318040000501487c24056ac0e1400052abea484a0403428160a45e250180c060301e100200000804181002814088581c3505e8db6065bf9b0ffe89bcad0dca9d9b4d5fd3e9bae7c96b2638e6800e00f7937d8d327083a421c949787f545b1719c3cf61a737ec8bf0083f225ac7f98ecfb0496aa4f202409fe1d5c2447a3e8897d127fd21b4e323a258aa5f0d1272ec5c0392423b5a955136362c4d828a20f98347e84f0cd9acecc31c1198606274a70c6877f552880c48014f0f522e364e78c54035fbeee735855956c05bb8c1bdd11ed4cf56b3768f3769019016e693835c9b7e172f5d11f71225e196feb9a762950b5821677b2b16f4571a26b857e6633a0757af3f81ab0305e493b37f1d87a2da2f1c251c7deb41536a25f9b11b20d0b8fe56c48025a980988a6f57af0b285c8e90fb7632c0114e93b3b9fea9a0c1e2b57c0ad85b0acc7340454503e8c29b882c87ad3fc1e18cced137d9ce80325e6d0a41da109636b5a31826332eda718bb5bb9998e3d706e170cc5125ea3fa4d87f60a134a3d3c56bb0ce7ce0f11e49bef2135795f2333417e3d42265782c2fd2ee41161a6f2f5f9b7280891f6b4446b0cc8efb5df0dd4c883e5da58fdda3406666a716f4a60dd8f30556b9e438e7114ba6bb0decdba3bc67111af796fcde2d101806ae3a64c009c210c7ab5bb522faa336ebf52e0af36c3d04c17f915cfdf333919eac78e69183f921642f55d13832e2ac7870755aefac5814f179f75ab088da9464746c8ee1ba6ed3b2546df269898903d6689328d5938dd2f7b3a70c62feb97ddb05b145efac09e13bdaf6f1d540150b1e410bbb6601c76cc9ad76018e76285b05b5c8e8bcc00ebe03ab52f564f14404d4a23084a48a6f883ca989e60c6d5e5a60e74a45ece72b920ded812c7bf2fad74d6caea704b777ca24093340c36e16f9f23cc027fe58a19ae4dd3bcdb0da98e98327411e15864bb82afc0c1efce335fc4b3e5cbb5880671ead2bd7db310ce0cccd1460814c0218e07e3debc6e5076512b051ac90697e014b96a9a287201565635607fe93c63fc9c6224b92a7fdd6654417b785d53f33e45b4010f29643211a391cb274b7280b5058bdb7dacae0e88840bb0b6c9eb8a187f53e0fcbff52742242fbef4667d08f8aaaf54bff0c595ef48b3be334ef67ec449dacae8dd6b6bbd5b47e3f043576a5f74aa8c38f63272b7e1604a5db621fcca9bc5d87dde47f144aea4133f2f04d6c1c0f3f22f48bf602a33f1cf944e364d040e7fe5aaf693d72df0be2d7764ea93928e991050d7002016b5d64ac9ac5d9cc250517eda6cac18967323d6c84bc1a09e8365bbf0a6551c203ce0b1e00e43820a4eb6c402dc09b00e65595d1794d5847f06372b81d6fe034279d1987026f3bf2de766a189799c85387410fb99c785f5cfa0725757692fe7cb45e1bae98e12e18f4384b23bccdeb02c94fc7dd9e7a7fd1c172d7431a5227a533bf4e075e855efb17a32181655385c04da142d50559824b17c2c670abb0d46fb18da5637cfa709c2aab53ebf66e7c4f2ddb7168e67e7cd8a4a917278b08582768008cae6f4ce7b06fde237f384f2cbcb7f5a53278be57113e3f26e229b0b7e96a509dab45a461b6ea6391965e8f3f6d62aa8db9f568eeaa74fddd0cc573b772cd91c74bb3be70f93973fb18867065d8e50db69a24c4fac2c4e6212b9e3b27981fca0235fb2a65212f0a3dcf3f471db02b946ef8cb26fa0dff377d436490ee35e1dcd0467c3214ae6b385f2673dc2e8d0332ab16e68d6ebd38948a2dac0ffcb571e673d17642fc7fa94ae85187218029598ff10e3f057e7301b87791a1f24543ffca07438ee88e00e096bad16ae01fad3c8c31aa26beb502d4273ec01b7d105f9bd16c9651f42abee2b4146b1c6d0aa51e8311b6f72ce2153230613d6720d3db5babb50a8c00345686a4a5a3d1dc3a5b2b48127b14aa48ecd80cd7c285099351c987488b095cab0c71238e739e57ed92f114a48b1e42eafc3499ffcf6d9982deecb59839ada3674d52008c013b0d7080418795440ad880e536d76870bb867d04a43b31018b902dd38b0fb2d1a0f70238874281ea66dd6669b8749a54620c1813defb5943e7a90ce22de9fdad89524a28ad7951829cf7eedb79df90723a87de9787ba8b30f3775299a6de98b5487d6bf3c5b98299962a4decf5882349948f876d877563cf1055289775a26ad6ecfd5408d71dcce0e8866041089767da1b8d5851bd479ac6c9a220d67e3f44fe2d5db7a85de4e131f3752b8c3fc6951bf22182870bbf99d423649290f38ed292f412e87d5471525b679e6d94b164bb52827633b591629238fd2d3c8ee17fb5b461c122cfecd3b01b1cefc9270747b50ab0224ffd5e7089d7b7d1cc93551ce8f84f11c0fe58009e947d1728b681420acc4ddb8937ac6b044aae015da2b00943818b601564b309d63e3ba4e200040f42a94663fba9d662e1dda5daac1b2309d7d4cad47d65a873d4f129c844fe75c3ad4f083d24ea3b929f08628f1e90fe0404373ecc10e0707c965f909ee712fea60fae14e6fa6eb2dcaf18e11be570c4b07f71881de8c77e32f4f86b8c05803c080a342c49b717a0af587a261fbc6b2ed3797d566fb682290f42d19deadc393765f94cd63484c4d8169447bfe232682334c13282f6fa0c1cb20ac8968f8a0e01ca4c435573490cf09fa9530cb850f6c881f7b27f3cc7a2e0fecdb149311be8bf10f92a77b3fcca0f89e915d3288d7ff9594c899626e370d835264e2162d9f831559b713d8d94167d54da650913abeb8bbbf68833729ae34b1ea731fc6c3b67ecd3243d6e465004c2f7d4619e2b056b31634c7a8ede940a271972e0928f4a072d389fdb6c213d2441ca0bf3a8631f3b5de909d7dc5cdc619dfbcd032a6b9880b751c9faeaaf3a3a010ba7711d4183313927d11be94ab619cc6f02ad11118d231d681a6a57fc2c006a604f7b31216ced4637575092d2327f2509e0ecb6f4d4c5ba61277a9403499a815504ca6447336c9edf03528a9e784c62a8316fb8338f349483a77a8805e7f4b4de6b0bd989476005587915b944408f03a69ad8f72d032a727fb5021d6cddfeec5bc8741816610bc660a43cb76eb879872ebb5d9652784414090a657ad566ec6836f7b2acb0c950ee836b8dbc91d6a273718cafb54f79fb9c14f477cb50bca8419167209260c6fe312a52bc4ce8a0940f3e130c80d595a298d82e8ce4c91713f23e7679678b61155684ebcaf0a89080b6b6d2c84942550604c45d58a64a48d019c63eb66c08a5c416b77fa2ec66032cd1bb127c764f1cc94a263263ba6bc5fb3818e42d24548e3c098e246d76e01a847d0e2f814050b633c79ded5e9003b36acfca0ae87cbe620e0ad0d654058831882a76dc9c948576817b4f1acb325bea6adfdb994e8343e538a428e1722bc3eba648b5c9fd89105a88970f280e27467f8dd8aea4b034fdbf1fe4fc7b639ecdc2916e7f9c4039d18a89bf8b76a75f1243373bdfdef58cb8c9835908200c8e7d7ece5b4c8c14efcf774829c44ba3cf0031997e013aa68c16dec7d9c725c1c7ca0cfe863a83e3c1fa0f4e62970362d61a641f16e9335994aacad38f032e0965fc835ebb56e1c4745e27a5e90a3dd600e396e70fb817c4de3705c62c6e3b874cc7aacdb9d4410cf518ea23868211bb1c6ea25e3543269c767c74560a154ad51e98f01577186e8c442b8604861e8512346894aececb0de40b47ddcbd85c71b53c00db78ab97737133dc4ccd5a36346001f1385d1b18694fcf2dc46a88c39aef7c8920f3037b618e00b40feaacb1f96eab14ef4eed92e8eb2d799ebed06364ef81f390e4c39dca0559de3e530e9904353707ad8a2d4462e00a57f01a7c59a20358004618dcd1942d3ce6a79e733ac1df2ddcafbd7a31f6b31ac7e084b4b86616afddddb03652bfa82defba6c78259b69700eda1f72e985958d1ea45b098744f14606c2f40515fe96c670157886f6fc608b53bfd5b6989da3f1d162262d7b275abf21096adc39330349ec6be320c0f9ac645b8d5496964cbd2509f85964acc92851a2861376e9c46cfd6f302c729b69fbfb35b96ded4674af37e7dcdf6931f7fa4845a4e6b322b24f6054cdf1b61ed56459961e1881fc29ca36f1a38ae785319e047267999c1f5de3b54f4e79b198993cc08760e9875f6dd734eb013381d8b022202f35f3a9565772d03d7fb10f77e9b850d30d746b6f59b84ea6bf1155022b1d77067f7c0a301faadb1653de3d0dcf4379e15f38f0d4250e98807c5ff7005dadec8dc49afdbf81173925dc7eb309eb7ebf976e9d964f01815884399572d37e2fa5a7425b2f3bad059afaab3faa27f1943efbe088de35c7ea2b8386d7145e07684ddff160feb8487c72dcb6b0bc9020f371e28883cf6f63a709ea83b3d720d5e7fafd066039bcc40e36ef457cb57af0a278301fc2dc4c556fbcbaf31b5f94bf76e94f3306dfb4c338450b37e45c94fa24ad9b9f292a18809d6df9daac5f6f3fc4d8cc9ed08283253f4555f704d8a190dba63de2771b8259c88661d1a36c26bcfa3196b87d8849ce104b3d8793a8ba27d16b1abf4d365518cf13d49e68dbc5557ca213f532d1fb9b5de0335f17172bd810d506ed44befcbd8489b26d75cd967f10934ceaf0a2def0974bbcfbb557c36941d1e15defed288f8e85fb47ff65c406b2528acaac218a0dc22729b23bafb19657a1b790b9af6ffe450b4f8b1c01c835259bfd9af9f4dfbe512b958e13bc5b6f152f4193432c79cdad1a0145eb7b452fb64e7061f95c052a7e37621e0fed27232658514620ba12ddafa3b11d8ff1551875d5bbcaa4ae558d68faf983864bc5b9dd9e46654a40344f5fa1df84ccdffa76cc0e474ce328d565671b6b289c04ae5cf9fecc0e353c3908379ae9296b82ea973575c61792d3dc2890cf51cc359be7f0f1082d8c1e50f5e7ff4f0594323f94328336bb9b6bb436e571b2bd59758212c2130bc9a2937caff760233029086f8a2bd32d44cf045810fd0fa6e5f9ac7eebe979b79c3381e29e48d0a84c05f55548376f8694b80172b00918b6fb568a5e2189953cdff1cd4b7164def428f6fa1a555ea342093c2a8406b346a7a320960495d9d1052d3139fd0f98d47912a3355efe1763ae5bd4b4cce4bc5b89d3bef01d95d6f54f878109e61e29777db62d615414244dd2234ba24b709efc951928cc71e4262c5b648dcaa59b21710ab01f3d8c068a0f08965baeaf904887877143ed2315d9306ca5428453a80039afc62c777eb8844b653cc09c6c23eed04236b6182ed31ab8e9a253211456a44822fbbcdd05928c3ae29b64b388a89ea5d7b9689857c76fa5531a3e1a204d8e948552d81e5b8a24110421996ef9913c6861660c80f6d12fae234d7ead94043a4cbac585e466ef4ed4082c0bd7ce8b909f1b1eed0fa536a26aedd63a5d1c8275348eb1fb30b610a35ac68ecbace7774f644bbad02eb0131aa4365fbbd892eff7006e65b7d144999465be79242c7987dd65eddb4f59127f5d48b137726f947150578378d20daa540051a81342df1979ad39739a7555f92f6d1e7ba165908c9e98d896e13c022f9870c5b347ebb39c4010913eef47208f39b9d1ab750f43a98bfb720cea4a4a75372b54110d860300889bec8b23292c3842fd8777e47371c10bd1c988b786584c820bd982c1c5a5fd94a03cf2aa052dcaf414508338c8b2f0855ed185399fd7bc3451d8af664c7472ac4ff3221acf2b5b2cfe6782023281bec65b5c2ceef085e833a9b5b3503269aced29d22957e4c952643e057d2f5e4e467054124b9b3aee82667032583e726635af492ecae81018529690ae627660765c025bf30664dc36f1ca1499b888afd35bcd1e0ee0653d2e54322a81c3594d9f315596aa80e7991bc75933adb81f029392e7a2bd55eb9dc062491016b0ff8ab7641a3f9a904746ff6224a0b053cf4e019c31849f5ad935abdd5abf5ca213ebf36ea142aac79fb523bea086ef52fae993bc935f959a09cb418e84bbc687d011bcbe6cf8274f2889b5b46b894a9b74059be219ea2fb80bf9607ca481304bf4c125627701b7d3154bd1dfa0594f2baf9f5ae7ce07646cd3e18335211b3a98d9c59d54942704bd7b8dcdc50293eeda48403200407a2b96a54bb56bbfc56bb3c614caaa827d1fbdd912a1df1524def4a93a49abd5ee7f2d6b34ca86615bf76ad3d56e384aa19ee6ea88a68ac7e9ba015233f6cf47c43a9cc6dca74f13a42d57696ddafa07d9461cb9d577958bf0385bb9a329eabca902b6bc0623d671a4e16222a895fec96ab322003cf2b843e0b3b04f9904ff63a57969cce9c282287c48ae3eddd9c9b6facecd14c76dd125fca7b6c60803f02a08febbf7f02c8a5fbe2bf38437ad3132735c93f0503f76f16e954ef68e0ecd840f77fbcc6cbe1afd765bf0b57b5f637b030933755a8906c93d5416a0053a58db730efa0528cb8f262274f09b3298f947b8c4a8173667f91100a66b2397caa2e2cef531deb66e742374248951e9613a2371ded8093c0f8830c22fda9d614f8a8dcfec87400ff4c4f807a71df50fe5ed5464f3a42484c408a56a66ccd8b3b6634eb7bb17b2421a575b4bad4b6731f33814b123d006f6dec6373a6dde29b81f18ca29d47994e70ea281643aaba1170da46f8e518e7285f7fcdd48573248bf50e8480b2a4c1da95273c84ca3e6bfc58676e43e135bec7cfbac982d0ea7ac02d43c8ed623f48a67f59f50197196ff5e14292535c2b445d568819bfdbdb6b5294d3564c01079cc1ed8f5e5c5f229862130eaf01de3370197d91550889debd7b8465cb3dd5a9ae7193273bb3f2993be4b752ddd20d28074b7bfd85c5e13d63cea9c8b03308c68436d72de4a30a41bb45d04fcacd0f82cd3134766286d98714f3216cb66cc01f9149436abc8914acd0f176f8914a44eac68476053337643893999bd5f485ae5e820457db0e2f9b770bd21f55edd001c1d3ed720ef8b31afe113c4187478cbd12948425ca61010103da81324c0bae8f4e282be8ae8a5a0c7862359d8f57ebba82fb9dba208cf8becb9cb62059c780a0ba68795c0e5e5cf8d86195abbe7ea762d6d273803d147a1b4821ef26254e5da36ae70e6f36342ecc814f67add6fda050d848ce73b6055d93d4e927fecbdade20d0638fc11e9a46768a95c7bf92401bf4c07a2a950258d9326b935e24a47537122e5ed86566908559bee53554297e7186f4c8b4648fd17390b52d181edbbc9c1e1c938e47b802c3609126431d518441f0c120f628e2d4e43998e9b49ce518722c857912aac9e2597bab9d5148178d34c6192d59fc577efecbee325651153024afac819a184d579dd04943b7f49a755e37549a138cd7153c6534a1fdf992368026c6c298143af31200848705e11e16186151e1a205149e232fad7f11b554318f039412cbd6c3d420464818023823f8ad3bd131e25e3918b9857a3187a03052b052b3377e57e15ca6a32b092101d8507f86939d428e2fb5723a3f230edac80cf78ca15fb6a740ed8a29ce4d2c6d646f3d7f655a45565b1be9151337f6e2c4324bc459a39ce28f78591cf10368b91b4e496a1a654c64ce939ca68518add597e0303e29ad266a6de40195e36e7c132f33e5b0f183556c5b69406c8b229d90649cde9c96bf66e4decf42f78f3ef1ff8569c6e833cbf9be5c91c6f75275f241c4a9b872c96dbd042ba1144325a0b5cac26acd5348c314ffdba5161c60d2107115498e7ece01027d24067add7e7ae08515c3ab1fb8705d70318437933ea9b5c5794311b2e83fb979b51b774b40f6d537837113302bfd63c9e11ca6071161413ad39b3358d1b427ba2d8f4fd78a34a390f1ee6ebd57a3fc33a2be18764cd3cd52fa3baaa9697924b412d3b6d2c8dcd5bed9a6e973b2f0f4473eab7795ecd5d1e2f2ec2843682d721a719a83e35c1e9c59fc0ce34fd55004ce4a420ed17c6e271c8a833b11b2253156d407e041b33efc293970b28c0e02530fe932f38a1732b61c78e6639e7988518b12d76516ed75f8eff1325539bdaefd61c8fa9524cfdf3f1bd7cbdd36ba94bb5acdfcd532ac6370e2ff23d790cab585f041c990d91afa87f64ab3d6c45cabe6c0742744eb820667b2dac651590f48cd0f80862cc07d7a9b8787f06a03f08e2ed44b09b50ccf02482e9de7be6178f5ff8c78abadb760e4fbc2b5274b426faaf05f5dc937271a6343a646d1ea6e73f27b4c410425b7a1a65bce2383b8a782ec5e33b21bc22d362906d2a1f344e036c075651717db6145f8cbd704cfd6612226221712a2337aea725a7580051e91a7357ed7e5897a978017aca8c64bd95caba2fccbef26d2bd1db59cfc1fbdc0db64dd9a07fb3f0e3975b0f827ae7960a441b18324f6d4bb6fdb08d996562d5069a0643a7b5b500034d327d175f848d35f95257917d768b0ca986180c4f85d80261abdd7b8d25a7f30fb5b64be05050641cccac1703dace3fbf5a4a18d8fb7f5e3e75f74e3a160feea960cdc8153600df888ad5566a072daf3f976f20f0b896bca3a8367872f6bbd7430c3a7b28cd4ceccea1c0eca6d97d2285f5a5c211a0612fc2e87efe278ea4a21535c165a5ef459d84fb20f2931c4652a5b27e0e18364ccea7b467f549004047f3546e91943d96f7ea8c03cd7d0abdd504a8166cbda7c27aa734e0192f0add858e1ca86940055652b559936286f346a33801acc819639c72d20c850469793ae74be1ab6e4194544177d54e7ce9794483a9b29688fc90bc64b293bfb0be0a05dd2c00f1721387f93e57639d88995f3827c8b78041f39134d828e0aa9e0682f014562cc1770863fe69dd760ef3dba5cd3ab25223efe1aef8f598a1c5888fa44d3fb0621150fb8234d4af628085adbf03d9252d449dd32ba6604678201ec01a5e45e59a894d575cf5e98e55bc302d48f93d1966eb680eb677681f9f3b14e5fff61eeeb69aa4966533a812c7713cf8c0133386a203ea14044de26d1955efb236ff5f3a9f923ff406083e10b98af920e8bfff180e7eb45e73eef36cfcadf0386cdfffd6b18f7632b1f80ab86d307e55eb03bd73b0416ea3c270d8709b1322ed3187e4839e4d86fc60aee155eab8b2751e71834e0292eb9a4204578cc6e1a12c00d4f3b8f9266c28ca36c7cf1e1a6f4b2123fdec1fd4fac894ffbe67ae0770a89d5242bf2119e42804d39456ef45dedb44b170b5468262ad62d14435ce0e578fe9d0955c873b48c9a5c9e0e1a76cb24160b2e0ed39152cfa8a07e99c9a69034c80a3aac29ad64dd7c318d28800bc38aef86e1da9b822f853dedbf52295c8ec4f8e43ce573bbf9c3758d49abfd0f6a09bde1e0382e4d8fdc6308d12caa2e48d3b408a3a9dd08f19efcc7e791789c855373af19875d00609fdf8c71e3279501f958678db5b36e8044ed1e92cb1f21a4a07cb4c45c3ad92b829b4db4d6d30548075331087a589080832452671a423c8cdc2b4525e5df5296392bdd0f21f68a04d44d106af15204e539cc98f45e082ae4d0dc3953641bc41ea8d00d295f0847dd879c6fb2839cf114c12202b7042ee14d87a5bbb42f4698915abdd2d1fc126f72f0d8967ab41df776ce306fea61a6a06ab89917fd2bd10e3b3d3c5e0911afd17ac5327323825decf1ec3df385814ef4254a9e934254737f1e57d9ee5721829e6acba7a78f0a0411e5f32fa00f010c334a5f798abddd7ca2fcd3e48c137bc8404d91c01af7b7c73f2f3676258c6240761117e1c762c1ff0a064c1904dea4879fed5f2745280a25da1f1eea832813def647fc0c003d76124a27aef9792583517573d0cc421d42f19f92cbf1eea7efe843ae56ee7ea751c1384aacb42a5baf48615ae1516f6b2845927268d872741dfc062768a3d11f0e2c71f2898952176695150846b28028ba9d3765279ff15ea6da9911d6d196a725e13709fb5c06e35c985cadfb9ee54f78421d6ebc575cfcdf633d857b46153573eefca0e69e00a92e93e91e60182f8493f208807ce9bbdf8491540bbbc4fcdc1786bba8bcf600f24485cba6a3c1412138441e4cadae56ec8200401df30184c2d9317f09193e198f62c6b0ccb149d12a73482eacba426ce9ffc05a70d199a589056e5031c1b768237b8c3af1e9e5c602a957932a21833d5e19ab021e5a541d1682e8669f1f89a4de194a689ae4bafd2cdc0aa57a4141eeb635d959a1bf5ff560e2f9bad874225cf23c50f39c5ee9f3cce6ed8c68d9edc7c968da7325390347bdba5dfac9f9442ea53e5779174d969e3d4ebfe0831abad39e272310f8b853c6bdbd4c7522a0d6f3cc9b21c1de80bf75a3699b0c443edd996b4c2dd88ecba3da64d56709e777dec6def48fe12b681a9ab3ecd098da939d8e0041ba9245f1305f9002b942697a0db2640e94d938a8cb385164faaf3b5840dd3a22d8d373180ce031d9ffb03556e436533cc43e320a58cad3ea9d90d702d070613b44a0badaaadff614f4b205741d61d71de98f38e9044940f5135634a738820c818630bb8886d73014d691b3fd4b31725324d57163b8774e5bdde7910323856dd68ecb9465f6b39c01803f1173c970cd3ce99554d81cb5b801efe7b02d55411dce0c4aa35dc8fad3f5ce795edf94e88474e460107ea19ebe6a83915696cb131992a3c4c3a2e15d2b61d880f86e2524e5fb2523fcfbb3492d612bab7e34e7f0756b50a125e161c6d6b0b21373f0fc4ffc306a151517707178754dbe155f7b2b4095ea9cd8e003f7ab98208c926827b6d74ec60a876474761db52aadd8b255ac5f342d2ca32abe998913a99b976f70929ad68de5c3e82881f1d05bbceb05a86dcf1364d96935ecbf48cd4e456a4b78fb24a5a7b6f48a6d7bc02e9a55bbf7748406d8a4ad04797711c8c80af1b2992138be43f8838a2a2414e57f22eabf8efc3f60a2d40a6f6216daba3b2217d7fe3e05c1865a8b7429b147d50986257836d1811b33fe10ed987327ad869f8d97547eeb6d0438858d2f0cacaeb14322730e0cba320f591ddfef8cec544eff449a1b0d59b0d93315d977c9e4511987a245688122fc8a2a2c4b345d8256e41ed4b5415df22395d70247f0414937b5340278fddd584da9346a793138672b68560aac9026f9a3855f5a0234ab01da51514a5b400cad9d0326c1b564419a21060a88cdfa5740c13851c0c949cf63e169afc032581e131353bc02a6d5b87c483c99136a5ff0c072ce7c02ada0693715ba084e64263c87f6ecac95f18d304fb04db5b3290991524a29534a29a594020105cd044104d8a68ab86cefbd830c8d417e9dec37cc6dc930f3139c939c732ff2a70ef3d531f2c3e31c9f9425194e2d418a114558246c05d3519090fcd97aefbdf7de7bef0df4b58dd038e77c886daaa8eb51b28e4c39d1c4c8050b9d14fd51dcca0630e8c94b10b22f4468b8d0e168dc0be66930744da6d4c61a60bec7d29650984021069415a87c6a56b2aafcd8ba9a0136a36ce482a5b28cad2e18c3223a848c88846078cc289b01b6426bcbde7beb4469edbd7b0ea2da4124c6c48e2510502226858c2a62baaad4f85c8bcdc00c2e20647c7181c268f7ab42e403f8e38be88306216681b4b768351ce2eb429060d36ac88f894d205c911f674e44c0f0c2a4e40acc0b158a113a821f2a38bbca1508f34185a5740308c8ea178c82520ac1a26b26cbbdca3b4bc8a4c4df7b9b61295223011d3da14872e484a7080c8d1441ce5a1871e984b8b15844a0341584b61c7111a4c7c391156808658cb5b0c185c2ecea36fd82ca134a80e408a1c5c4922b6a377a08d93206486ca68c73ce97c0f49259cf5503e79cf31c6eb58466e39c7373636d0dedbdb78c0b70494b801ae3e0163f45881528b5f7871aad2aac35a9c1c4454157846e9d51f54d6121539871228989504a54cf944f146109102fc2c2cac8aef618aba0a9144e3db64a005d81825ab1458c891886315b812454740c09f171e2490e30592a9a8c21b941864343701412057ba466d4f04a322a12c687969152972061591688e91c3f65cf38ae6e4c9de49c73ee45e80bdb5451d77939c3457912d523293b02014085095f4ec488284da1dd10e27225c50c1f89e095309d922a0d6417696aef316666d009952126ac5919d2c21315f5212bed0392232162252ab842e6bac913c1bdb9adec07d72cc22593d71b5ae60d07577dd91a55bfcda590385fc33248e37ee2215e2b4f41769651abc239e73e825a8f22d407cec73ce9a12d231a810911d1b1660253565d3361e3e749c4093a4858698100b33fbb864a4bb45abeaa4ace85ec24e14dd23382f54a4bc54f4d6dc82f859091e195941d2c7640c11adb62e5ca9223c8c2708575819294c3f28921db1ae37baa4245de5059618135e54a8c910324f940e132c249cb0990cc52f1174843b1b55564c51323b928474ac4a886c0a061c6b35f38b12a313834d3a1470b058c204e6239d46878a54595d0424588a5cc6ba66c1254c149e6491619193329a832648a8fea0b060e264836ba803b947af8a480f032a5c7a4c59ad092b223583cbf20464804630c63745581210589292302f7f4e81f2e4d382e42fede3b3fb5e03080c63b5555bf90b4d65a6b2ea72a407c7ca4282d19bb2afb11862425cb93a00a6c17d6fd7a914b9c2a103d3f2224402698615151126e593b732a9a59618f1119cb12d57cbe1586694e404acea07267463edf90624d4dcd27424b149d28fb725e2433a943ba5e55ee0e84313a3184448f0f9bb31480506cf9002618d4643a0b050b8e452d21c4659b35d2b4c83d7e53984c0741ca490dc933a431f763f493a4850ce1dfe69c73ce39e79c738e61852fcd4b13291c3e4a8800592912a680c3674b4616e0551672a0b2935795b8e7e81c07d1b22511ea0a7e7cd904b0c8c2f5c3c80a3118488449c0a04445fdb878ceb6b2251625e38b5a0a264c4c408eba14f95812c2b295336b3abf489ca39ab610ea476badb5d65a6bab65c80472a5f598b187aa87484f56cf939eae1eb01e33ce39e76418abca8a088e9149c8cd304cfd5050f2f2f1e1407ffcf4095a04ed3872b2a6024a83a92a261d41a282672aa0900636b8e9d70b52c079f8cdc049ce9ee797d5b2c05e1f8902fcdaf3747d3e0033c0e3caabd6c93bf3428c5eb5efa71ae967747b9ca7875ee08c864dbebb3a75a7876e8f48ff7413ca00fcf550bdb9de86d5abd70fc05ef75c460ed95fd63a5a9f371862f06d16da20b6e1dc041e74b5d79679b5de70adb3a379603fd54cfa67a78388aecdf549c3af8d84ff7a7c4ae0ea8c3cedc336d7e78c7af5a9f68d3bdcb5d65a6badb787dddfbaf6f4988ae06f5f7bdaef6c82bff5dfbee4d7566c13f5dee3eeeae41d09419ca37de2999e3fcdc17fab587bdbf3ddf6e11cb3da6c7f2dfced536de2dfed7dffeefe0ee16b0fbbaf7dc9455ead37db7f5ecde78ee6e5dbcbbcbaf1dd76ebbd77ddd96abdc9fe838b87441716e98b24d34191d1e4640580256a28cc871f343115c2b8a0c0358288d715029259a8dd781aaa91c41581a42c5c25521c31410c9a788244d3e5fa9ad1faa980e26b1da4978436728e6bc26aadb5d65a8b277e27904e2ce9ba0b204e6817c9664221fb62ac8592154ab860a160a38989932d412a595b4133284bf931817d2ce97c812f2b847c907e94785848a1c8162d42615a39a6805d20ce396f01a65b98e91668a8151911a714c971c6602054746508929f083523ae211e3850f8a169c1b82538e77c09db54315791fc804868ac48578915443c802a8c48b226a4e884059704ee9292a10013587aa465e141432805864c85519322544052548c528c66eecf905db2e46bc66a4997193e3a512285e40a9591890a7e2fb2481171593156a6c327ffb04d15452dc2dc1d71a5b04dedf27922a5c8912c674f502c761019547603449730b514306ecf3de1470cc130ca58141491aa30724892a91e221f4c2b30f92bc288d65a0735df27c6afbd495dd8d2b96269455377a241d43abfb047c1adb5d616c818c24b66a2d70f8788b5d65a856f54f133aa181a4791efbdf7c691af5a84f155512a1bfa708d19b22389131590ad2b4d218064aa2cc048c4122d4b42f808f1622b088a5697da168b0b22430f6089f3c941248ad591ae1b4a5363bca66871b271d655743f601e1b3f4a614a285a08655dd0e587d0942c165f4e48a16ccbf56dc03917bd1cb9f568c2be269288874f27e68b902b4dcb4751981620d49ea020313ca3b1968311e801a44909aa0a97700cd21e33c383a02959865401596119832b222a322a4a128db4744246bfce39c7d932c1a64cf4fb444822a46e8ab4c400b2f031a17a00d0510aac1f4a4f546057d46e16207bfaf929d93a21ac8ae101e4c7d90e275b98a2588da5d91e5719ab2a570ea44403d15aeb1a5aa34e0d60d75a6bad75502e05a0a8359620ce4993b82d7040908a1224a83c192125c6119016625826b85878a5201473c539e7bf6b539180963a6a1ae1644355c570e374515f5be8f31a7290893172e427988483233aa0acade928b2646c8917466bad47408da0ea5a63ad7d36ba238c283361048e311e42ea558c294f29464c617d68a29605cc051e7cc88b50b4a3869ad7189527a1114d635d5c7c48ebfab23a1bde20cb8123232a2a1f553e563c34be7e44095db8f0e2d38404da17adb5dea1a5b5d65a6badb55392cdc9e9ac91d1a9331b4f4134d65e3811436142161e505caa3891e26500339c984da00c41399af174c46b38a50a54906f680a972b1240574c6ed8c8507edc76a92286ac44548d986c464acbeb2cc9353e666b19b5f2690f03b6725bcaf3f71ed2edee44d153d1ee6696f454b43b72acefccb49e8a76978e3fadb7d74dfcd3127cfb33f8e569da9d4e494f7309baea9b697735503d15edce02989e8a167bf2e3f4c7616f77f8e3b0dddd5fe67af5b5ab84fcbde561f0907f6a79d6fc963782f9793ecf2f73caf365ccec21cd3cbfbc239824e43f029a35afa22de5f9bfaca5d5c9d41caedf6c67c5d7d2d084f0ef1595acd6116fed6dbbb74e89f58f9dfad567a971676dd561f2d371c7bfbea9826f796353bdb9de42b05b9f6adfad371805f7669c837586aa56f9abd7ddb1220004aba18eb5a7cf6aa3fdf520f00b5f6b9fea9f7f7f5ab576edddbb4bf0b107aeafce4f0f555c4ef6edad7d5bfb7815e76c9dea4b9df1d65adb9d6fc4b1e1f71a14f001509e9a338e3c211f11d82750752c10dbd48c61dbe96579e9f5b16bf6cb99985992a3983b41ef02f8f1cb999828f68ea2179c36e7e0a8b7b3300213d41cd15f9eedba32be75615558a0102598489af511ed5f9ff6afbf22d00fbc3d9b142ee2a04c28e7d948b7beccd7cc19d7815ea2908f5db35fec9915b39d66498e225a87a809541cd7be9c89a1582810c80408ac432f13cc6913c019caa5ccca288a62ef28aaf361bbd9d8b5de6e24cb921c45940c15020281bb0b744394e6799aa5f7bd5e1da23a2468c705c07ef1c0156a8e28f2502e65d60a398a681d5ab40e5110a817056eaf66474e2603b40b7ac102e743bf7db7807e7039b00e5740eb107d42452010e85573467ffd0850d1a7f6ec5bb111ad4311ad43f40cbd6001fbf6cda0c8867ff7d7de96e0636fb9dddd9fef06cedb1b0c985b6dc81090d6ce78da5b075ace39f3bef616031f7bcbfbd8d61b8d43c3cf77033e8f74eb4bfc4b9cf29c4872f4c55a29b32b6b3f3479d91b4c3fb1df810583b2b26290e2a67f7db9e1e7bb61736df317bf16adbd07f862cd217de9ab476bcecea3e40e07dbdc5edab3d5666f8fb51f37b6366b03609fe28c23e691a5799e66498e39187a17c01709f98862ef287a01aa7ac0c1afbde69c7cf4d573c03927cffe3870d8e1a46b83a2c33ee43c8cb4a3eb6e0f23fdebedd9bb74ebd38e73ea501ce2ecb1add756eb8dce998b38650e51c3e79d433afea535f5eefe12db7ab12de5f95beb5c3d20c0afbe1e59eba183c65191d0cda7d7e7d63b8a7adfebe1e070f8298733882c6fc8a322211fb3e4506f66ae4ad3ac43b247b73eb543f31c80d8d7d73787a74d0042a80aa010a2d83baa9bb2dd6c8e7a2e54008510c5de51d47b5bd9adf7ebd5c161c841cf66b8bb21c33c7d7a816c3ebd216ca789a2def77a3838ba231d67d6ea41006e51b520a6e68ce375f15500953ebd21caded11f870b2170390db8b4d6b4fe2fe1f66a74e46432b01a2ca0c9585beafc055fa4517ee9d65fadb59e316bf580f7ab57b53f31ff76fd7a7373a2a9316bf560f72bda71c35f87d5aed51cd25f6f7f3887e471c036d78f3ebd4239a44faf0f298abc1f875c966e7d5943534333a393c9d1e03a0d0dcdcd76d2d098340157fe0efb9a0bae37f5d69bbae5db7a53d1ccdbab5c3ebff2b795afb3fc8ccdfea5f26dbda956bfd61b992f5eaeb26290ee8dd5adbf37575cbda8ce45df3ff5db4a4fedd2f74bdff2ac17ebcdd5a9d8e6ee11e55ab9b6011b3c44d0d96bf033b8a09abc5fcf9dbba1e4a6073450abd7e74e063ef66908df62d85f7fac2bb5e6e9fdf81cca0a76ebcd30a699629f569fe67afffe1aebfbef86740811da2fe1fe9cd56d08229e42188a39b35cebd68b2063dea0b2107b5bfeccfbb5f3b4b25a60f518789f807df99b04d574918418638c31c6596f2e6651c4d78a9b8ba33892a5994d135f6b92a579dab2cd86afb555f3ac371cb3ee6c4936a65ffd6d29e957dfbb5977e985fad5e39a723997c3d7e62ed2ed553f444b1ba25d11d727bc22927545e4895695fd59226b647f96c826d9a10b66f6abc7c15fc1d0842274c021011d542238f69a62d63bef8dafddd65e8c73d67af3cc39be9667bd37e7a238929924f1b52417c79124cbd23cf379e26b4ff35ef39ed776ebb9777c6dbff776fbc5e1cc9b93c93232f85a999c5867ea2ecdb606cd288aaf452deeee52f1ee52f3ee66ee2ed5d9df6b724d0dbeb646b461f030feebedbfbcf4041ff32a9f116d183ca420f89677b56eaffa0e15fcdc546faa27005a8996e5edde5eab09e345afd69a79470cebb7567497e65f772959f5ab1767f46c4f9146afbc347fbb95f4cb2345be35498abc7ceb1dec17ebcd6d63f5cabb7947bcb6e2bd3178c026f89627d69bcab9288e234996a599d6e1affe2c0184d3b4997567d65d0701a7830d3a0e97cbc9ec741bccccd0d0d4d4a0a8050b172e987587e1ec70bf587532193264c87066304b3243860c193264b8d6029b78ee8c2349966507653dcfbea3eb70cd2d9e3ba5b9c106b66bb3da3ccfd3e6f256bd79ee24a0cc70ebd986c143fef8a73cffbcdd70e7ced2bf5e44ea56ef76564f4d6d35546fbbd1a8f5b43ea92a21fbaeab9e064c2f6b3f7770d7e2dbb973ebbc7484b297f562af771f48c1bfde7ec07e132706fbe5a5664e4677eedc66ce9d4e6379b7f5ae33bebddb2a53fecb4b43f896b7632a2f8fe75e1e5eca434207fc45abc1fa0e197cdded2dd95ff32e2bb617e3bbdb00cef9d5067b24c2261f63281fe3dd4f6b953d3fa8373086b757f7d18f0de70186f0f6aaff40147bbfd7f735af01bb0f6e0f637f4146f52894ee37919ef9de7b6f9f72af3d8609541dd29fa056e99060f424203d2efb7cd9d73f6210792090f58f18bcfef9d7d383f5f9ee1779a8fd7ab787f4cc4b717eb54de38d9aaa5e0dd92e77c3820b5100b04da12975cc5413770af519253752ac5b5fcd9f628c3136c59068946e3b588c311e7f8a4fd38645d461f10b3dbbc6495bf8924d9ff5f9f66c4db1afa988712963dea2accecc6999d155991cae635f7e8ccfb2120303ac2eef986feed7f3d7f25732c7d453f1428f9e8a1898faf6aadded705f7f12f42f418f188fe30d9072a8940c5aab49a890c30600a000331800001086e2481044519a2525f8011480093ea6a8aca07034180a840261300c0482c1a0401004401084410006621806e6384293b10180665af8eaebf5a82ad1f5fcbf2d4f432e3ce7b4fcbe09e85e9ced1bfb208652be674060f2d4d56f3227b614127a99ccd1191efeab4dab0ee406b404f4471bc031d9b655d2f9e93e489194eb68e0ae3c0cc149fff4dc241fec02f54af5819f8032945fbeb05713ae389ea5589e33891384cd36cffd507b970f32e48e196ec6e1141c0e528665e1bc46dba32e1a14dad044d3fb1120c71958dd9e64e0ac74dbd6608ac56a1c50890fd3c0969209cc0ba5bbde845c3dea6e9dc08ec6ba0d0899386663080b2e1cc1c3e342c8061f39e5f4406104651617095357c02471d283b3fd6a79586a888a30c7d748b4788cb98aacbe9ff5ed7519ae7e4a6564279c37bae3a01e2ddf4572d5bcf9d08811c1188d736aa3302cdddc49948364ece5dc9765cb78981de8203ba2622a5acbd162bfe308c4473bd2cff2046c37c14b2e19b27ff022c0ee777b23523da6b1281730a82d5cf0be22dda4cabf89b25cb5a53dd16a76d64d78f28a9e3f3ceaf48b767ba6324dbce30eb41579d4f75ba66662b5e766be60c26ab69b021f21970a3cfa9803d0bd8c4601a23223f6df1cde69e2f274bab4972fc960d2112b11a1cc6f494466c288d827bf6d43816538f904c935a7499f95ed636196d543be5674ce039bc7413c4ea3d7aa554a4c59b602386e80cc0e7297df2242c695716323acc5756c2c2202cfaa9e8a544c2e7720454f49386661bd67442c48ab8ceb89d0dc9ec5f8fe0877f835a39484af29066c4e5207a3cb2b892b42e30737542eca048e552b65c80c50ffcc5b9e73b1be8e245eef1b61c2ee31c201f372f93f4683f20456c06689af549cc31e42380d8e5cd2a265efcd7af4a7d5bd3b314db7571e41981a564b9020d840370b73382f590c75e8829fa8e001f22803fdefee161335169880e71af978c546f20a9c3eed11d96cee961f073f8f179317ab9115e5c5696b9f502f257dcb60cfd4c329a7ce94f4b8053225f8fb40af0a62ed1d8a680ccf4898b7f8096c8d055abd2666643c35c75c55138afd8cdc046a5166c12652ae61eaa016d82378a63ec750188b92fdb61e42e4db34bb8ed5722001614e5e70bc90a0b1d89f58ffd90a949d07af399ed959d01c91f3710650dfe77a3e6d1baf5ad1bacff57cd2365eb5a675e8c9b68197568c899459629602a87dedf8ee72c1eab82f60f4aac3c5eec73d54726588022767d76bd66884210023aa8b04525729be62224f61765c84ede949a55373a7ea1f8d7f118e53477fcaff112aaf571955ab72c313c046791b88fa190519e83d6ae01a7f899664353591ef598b081a48373acaf727b1d53c2e106e9e06f93e4b3ab110a021b89804f01f1ca848f5749433f11a593ea3ea8c7f5ca1afedf5ade00ec9617d888e226f94c1e8fdf74d0ce0fa57a5547849236c62708a019a4faa8173c6beaf87681f7d0e3c2420d3d7036041269b01aec212ac7a33d08fd900008b0d28d0557fdf9502503148600ff06b78d84dfbdf90056fd559b52f3fedd440f297a23510f97bd1cfd991d0f17e916840723f9a232c845a8a8723783b072df264512a77a94a923820c16fe073d5b13b34cf1301e6f93975f70cb0ec8ca0c3c08078c29e408ecb4ba659e352c89f644fbc619dee18732b2727337d26714489284d0d70601c0d2a3f2084499c4fa73e9cc087f84ffb885beeb871488b3c8f9905aca158c2db7165120d57105c89e32189909d6ff2e73a58388df45daede3c15b01ec91dbf0fc08ee743002071d9f63e35a4e94ff6ffafd454c797f06f6c90b72a2f115b06f60344f133b2fbca0554f198e1c294edb2662f3e5ffaeb8c82fb1a6205d78736d643258b31d456a6efe3ecc18afd00b505a20ccd710711fc46adaab7a65a9de9efcdef73af8392931ea2108488f0a3e38760e1bf37fca8aa81493006a18f61e6b557335a2e01b5221212beb1844b74f22629b760c94606e84593f57543dc22bdbac8b0bfcaa3e97005690d485ca3f6ad50a9e592a4148a981da6a1049090138b6f4a0122aadefbb51b177125bcdfd54d73b0d9b56720b5c28915f87def091ae54121cfe3094f122e444b9085c7adecf6642db47025cdea89ba473e9eabe8822779285512fc29594a1f9b61e25a2e217819596c54e56d516906f43ff4d4fc0a53ace6a17190621835f3f0627d1cf1261229c5950689d6a4200408a7c931fc09cb430819be0f1ff28913220a5dd96311156be7b2028d68660c6b45f617820835e91c090384b30716e6e7a7941718efba20d43415f06fad007d1208e018206f83b60b35a6bb4bd5a086c459013755903d13c39ce2c5ca497b9131b06e89246d106f1ba69f32895658fad974e0d01c4c39496046cbcdb2faac940fd0a7a5da97d3900279b6caadd781fc2deacc44895926b2cc269383b4c5368b4b13318ee4277c0838bd9b19fa098c549e4847816a223d5603b4d238477690afe54b22c80a014b2a73f7966e77599fed3af875f8b908a0d07d3b5f3d92e6d260952b1f1970216392af47ac141db42e5ae3cf40d99dbc844fb6833a49aefa047e6b1b436044f9fd00d76e81e753090b455714a79e6aae7895839f441448cb3c0afceb154013de4f632d77a8bba358aae517544e04afef0b2d762f24ec6b792d3861436b2649a97365877e8b3ffc684208e5f24857af672cd091991ed3e5deb747811014932e1810434d409cdc4b01d69bafc02cb3e87e09c72814e11790a070e6818076d3e982f23547132281f434f5fdd512549a84c38650fd7ce2520557c3337b7983098139585b4e64616e1410fd33b4c4ccb7fa6398bed46038a2caf78711e9a4df29bd710414b5c42bc8a2e1ef7ad0d02a25dad9e0725a431fe618127767ed6338dd3159209397ff7ed45ca7f22d74bf2a37561b055b340873820d0ef7567d5f86f47ec12cd7998fa4141d5782ecf080ddc5b1b38945930b0a7f191f0a572b66abbefdcf22b900230f66b6c6ff8935dd4f8cff2607e426349245c6cdf6051a6ea65e2bb913302bc6a5fa24643844b8013f58eb4fc71e82b8696a474d4b5a491ab174d4a300b273ffbf3075f907be845cbe2eeac9e596d1ad446c4ab73a11bc2bcf623a2a21e232a465fafc9a5685296d47206f068b1c926f006d35898c8fd04eda38204507465f9ad294c301dc92f854be058f04b906329f0aacc67dde7a365949717c151af53dfd152da7f82b78341b2a01243f95349a28877a7b6a7d551def8fb8a28b8b9fc6e12f0bed5d98879b98ad7b9ebe8e1ec42c7f529a20a89a6c541727e6ae022333ab5de80232f462de9f160c2deb240f14d425230898d6685d21d4ccc85819c521e69445c55d062a808062cd7076878108650797c49a2d14b0b72ca5ac196cc6c9e017ab4d4a5dc5af321b6c8bcc0e650906752d569fb85d3608c0d7afad6668f12707038d10a1d99887661bc1145448d680800e319f20a9d4cb2266132fd92fe454852ca5d10de327623a8e1496bb03ac9de44c95e65188dfd0def373b55b58fc72432a41b215747bf557fa617e73427500767d22d04688aff393694bd29988622ec02c70dc56cf674d4d6ecc4a2b8790501069fc4d843a86000fa10e6aa282ea1fbb992237a3a74f89a8634a26c1cf9a4ae41f62c5ecf7469fc7874be3b3bcd433d8ee35891cc876d66a875d948901e7325d51ce6e4071eb2ff607c4371ecfee11d7ab94c742d6ad879e39ccef69b360a28c766b28668b42f8edcc270059741f08cf8fec8d4bb6c2bbf63c265cb307925c586bb1647b4e1214ff2442f675183088ef0f60b4c22727ab3f75410e94cc5977129999500b2287871fe3fc17160c3006b62f990e830183edc6a357f7aa0cf40bc351d8c5e05653f211107b6f334f11162d741312e0f1bbee1c54f4e4b9fa1d542875374c80cfc223fee68e3e0ccf62feb3f28b76273bd3bae48f24e48bc3fd44f91e43ab868ed31f2c86b0a2006900b2a2ba215858faabbb6f764c7de1bfb877659487fe523b733dd113ddd01bd4cd5ff7c710e3087fabf70588860a7da55a32bb779235042c13996aae8d295df4e01cf3e273046754a10a20a32d2867aea0138f89fa9e669d67844b39a2d667f521d180e683be2a10fde7ff7c04e661430d9321ae8c4545ac1f03ec3dae8a89644be3d32d045befeaa3001dc0c0dcf5a8d40d834d1f388639ea03eb787460466cd752385c96367d366b5cc571d5cca7b7d9e2f831150b441370642ed4f6c125d3d34d259f70cb787538ebcda92d35be2cc59899dd3b0f07c3083b39a3c1beadcd3522664972564a970a8275cc87a9c27adb6cc0db81462eae0188e455a1c62b544b508268aff749d85153915533183eecb018624db717d1b90bc9b14a4cc4253651d50fcc3c8ea00b0a0200fa6eddd58974175905f0964e5080abf77c8272d8bde337c7f469ed5e9335c0fbf090ce0267073bf163a4c33378e451d88c313ba3a1fb36309e5ddbf3cca456a5abb7ca750da7b74964feaa23a8c7a96566549272328b58f61dafa1c3e287107a0e8549de0588b0dc06a4312862e21f46314d8f82b157c4be113f51dc0de3322c26c075e84a5db6c8c2d91d66bb3d1e54d34e86fd0576157fdf3ed61e8b6b14fd14882aae2cb66b7d618cf37a0a471d8f02d647da68def38849c5284f5b31e40cc72463d7fd3656d2b702afc5b7e8864771bb6fad125e5b969439e067f3b15cd74f3af6034e1c1a51d467e31537713899b49e02512a5fd6b9f99c9d950f0747cb5a84935c339dcc57e30ac80e4313ce99ffc434367d3807f72bb13e71dd08e3ca63c1d393ef28c58678c3be09e8ee61b0e388ed5d5cfee6b8df7fa8b9da2a1a66e993e1a6083b1f24141fe8fe47bbd0a7fc56554aeadf4d7b8370e58e0a7be435987aeaa93e49fc3ddca8240b4d0eadd8a249dc33c408a18779f51563b57a2c9cd7bc95d627fab3cc67bde41b42ae1457169f6db008310c63e1ef0d8ecef0c3bae1eaf1c553926462853eb1ac5a4414a4869e3a694cf2122011181bafd69c74822d9ffd94602406a1fdb2e355b96fe6964ede33923d75451b3c8f1158679aee5cb0658d103c92c187568540ea19fd62838b7a3c711bfe2d8940b65f1d3f68afbf23b8d5c7b1b682242207fc702964eacea7523da8c1168fbfe2e17b7fd9f9e748dcc7f112f7c1e3d44f22191d3a3c0c2e764c855c12225af15c741f8dce89b7b4b165e9dc3c146410fe4777c595838037b1f5fa1d80df6f2cfea8745e29ae943e5683117834866609a1be27d5fd18683a41abb0f6527882b5634531dc770c4b9812b50b71ecf2c13ff5ce5f1dd5c65ac35466582f9405b863d5959e14e1e821835648bbaf61d9eace9460ad65f24a6ea05d53d95b0854264a216b21f008a7578d0682b83bc3cc6740c48ef3882feed2779f347375228cc5e645cf2a61e117b747fabe8c9174a92ef4820c04d91a08f5f93aebe60e8d700d7d3571702f382934204b04083a6cedfea150588eb64ee81ae04b4d3362f8f0ee3d640bdd3610a643b7c7773b5421fb83fd075ef463171d1c9c986b2f636b05bc7b44f187333e8e5ac01414fea1d10cafd376529930b4d40a4b31d6f55b477ceeb4ebda48da42e7355caccffeb1cc27e6d72323ab4cea849390487ea4d3152fc9649e09ee05c75801eef2dad80788cef49d3ce3ccfbac622093ed53cd9c47e849a7a7d2dac4c0b196b7dde284cf19637b57972bf1461c3e1473ceb949f21dd45db5c2add65c7ba4e9b5444f37465f0660b8459ada6efa35eb1eba8aa28472128159e28850daf53925d6d34506ffd981fed8bee761bdcda2b8a787b9092375e886b79a8f155634d674acf95ed16be53db3b982f06a5e1bf202fb397a6cf9f0c9bea8edc0821ab6d0f7b75068bfb30fd1c9c31fac80283f8ce7d331bff398e0ea780ff96fd6aeafea0f2f22682df8b0cf521d51a3ec3f7a26b12ff4b2a07347380bb2ac74eeaccbca34686d35cf2c5288c566aa8adc2e9db36c452f7f28b0ee2f9008e4ce734d57346fa7699f088e43c3334367735d9226c01f36e837fda04fb529d5425fc14eda087097cbc88aef3d2981e6ab4f79bb1a287208a7fd3c9e705816ff1d813f61ad6e157e92c5d4528fd2737e1ad5feccbbb222c898a69ad4c347c9268bcfcb4a87af181e362b59a052cd49075adb9da04d970c3f9a7e6a7fca107da2e3ca295b095b5add54872499bb869b8f6e6683aad5f65cf2226b1d5b0091d8ad9033a6b329e8beaf8028709c391d52e710ac3f762b888dca856548d7638cb19e13a45a5a3c834424706b8512c48beb0164d2dc7ec8837d4d26b5adf969cedda8e07a2c74e51c648367fd3e40b967421915a7cd094142e41518506f78e97bf9dc31ca757dd116ab22da72e25eaa01142861d6aa8b8e630878bf0b8ed239606c36dce81aade5d07a33a995266c39c4556ad0c9c773a0d478826f96fed6bef169303783f95224b539dd4ff8c15ab07f74a3f37989de452ea80707ce51d297a99f599fea8a4a740d37c63c202b78d6bc2f6973f4be7de22934b2cdf9ec1c30de03714b918c8af33311380fc8e0fd2ee1a31699ee21d3a7d09737fca5ee43657d41797f2e181b4aeb3b1437848a99236237b50b1667e820137dc37b3603d15872773fe50c836e8d7b5a79ff148eaf08ea71eb932b7721cb5b2b58308854b4530d680fb13ede23c83e729a9e37c2f3495ee914e4a36763a2f87aa7e1053a8d3a5615775e9ebed86d4423f91535cce80a781af51f60497d15fc4222ce9a3d2037b31822703e133cf017eca0305a83ef38d22e57e07f18480839b10e985b07dd6a4b3c9f29a9705e84ce4b50e8cd8cc81c29d4cd80099fb04957e8182b3033271138ac7b195ebcc00101816a766a02d17870039f86d88a3d945fe655928599c1a80ad9d66244faa4a609ad2c23903de41ad4cfd22e1dc279eec803c2c23bf5155cd46d7391100d033fc50e7023d6b5e5364b583b86db39272362887e59877de4a21d4acc8737c0ebb7b8f1eabdce660d6e9b6deb573149c4d5ceeb2659945ccd2aadd6903d734b7b3832f6f9776bb85f467add87571263dc673c57e970565d11b1a51d3d3f23daa9f9930123115e0974a26ff1e813ec60ae2f39033c63d3621574b2109a89fb688d9276dbbdff6000572483637efeaf24e4655ce371ba8750ad3d74c70b9b39823ceb57800ff7f61afbecaf7135b9773f17cc783b37b95f478632411e5afa026a9503cb1b03ae61485013df5bac7b0d308bad9b74b58d553792a21441b2beff328b3f17920d4dfab509c815ddfc2ff51edb106205d031bfb9de25657aa4b4e2988e22a7dc9aa5e5c100dc9efeaad728cbf0de43474e63847b96998f61708e5c1e43c87e3305efcbcaa375973d38d6dc1dd76ad6b678bffc7c6059f9746fea28e028e3c09c5909132b2cbba87619029ae532b895e5b0362bb7cb71323a2285acf1b7b41d1ba0cc4670fdafc1272824ff420ae102f8e6422e356fe9c375e9e8545b6ed69c0ea7f22da2edc45ceb60e16ce50cb2d10e84c3ede3c98a5021a896f6e6556dff56d120d813fef9e11205edfc17c2f47b95b6e0c1ceb5a9a57d59e10ac681e6658da93c0c27711919adb823dd0e2748715e718cd5f639f147345e60dae1e8b0d06fd1f6a45ac466de8bd5cac443b28a1fa0b093ed1b28ded8b6a54f07dab61aad1efc1f141aa5116a902eeb89d8424aa3eeb6f0d3e2d1e721ba188880b5886ef7dd2632d822b9242a0d4d9e7dff3c0ca01aa7aea399cf28c1d2b623b04894fe528cb893e3ecc100aa7df4dcf08dfd6452cb92a21f9dc9d36c12f05976eb16b91af8908936dec7e66a81b1bcb04925f963a6cfffc33939211273b3039e392f8c7463d56734f4a983cf80e030743646f2cd484085b0442a756c79b74b6a81955fd5c0aa94e4d6387f79c0906f9d982a60d53bc0978356c0b24bd8b9e18967f11c48180fc265f3db9e7a0cb51b3a6905569e10e9ac2dab09473420d320f646692e1fc7bd7d1ac5aa57debaf941982d883e6e315392b93efcbf598ff808cabe1866121dd37eaa762a01eb001286eb0d43d6017957140b83e288bcfcb297b4508dce77e5dfc1f1c99cf854ff320b33098f46ef41cd7522e99562d5ceb15686ea4f0212d840b349f7be0c72cbf59a2c4a2b60bff253b49b3e8fec54bea554f6b0cc127bcc235b6a6e708ee14f209bc12e29576bf25ad53a7b2bc250a5cfcef92a00bdf66c5eac6b9f97cca7089f7f73bd2b20b5a65f06f77c2ddd04d444be73f7def1fb1127bff5a706a876200db017c1740db08f2ed0c0fc00f147269bea98be24fee46a13accc6c7c25a2847defba8c69f003566fdd04d9941a97c4ffbd8206414082fb3493c113d1e50db4b8cc32d22abf5b46e5eb538d08c612126e2ef90685ec8f1ce4dd3d92321d178283bd2752ad0870d16a0c325622df25ab530f85af4de9a216976369fb5036edef2809f0c41ed6163802afeb4f4b2d803385ebdd3afa48d77992cd4bd06be3411a8767f39acb2f758da6fda5d41837aa0372e1a31131e779336b31a86ee56305c3d6fdd79a563430b0d4650ce5cec6bf1203ea19079bf03afa10832f38bf102871279da0f1b10a684d7e5477219d4a6417a1e6840baa724c1813effda741aad09001e0664bc1c711682ed46ae48f93dbf67ba08b6ed0787893bf6ad113ea045a298eb387815fdca2fd6d51d25627d302b24120050958514ec086f0322237fea6a8a65b6ab1fb45ae0580304f4aec072311907dd9f950ca4c2ef4c9d13a09d06c2248cdddea044d802bd882008a882bf1b55802978af23017716621815073bb1b22ecf20e2aeac9107481d2905e6a01954bae3a64a7ec0e9e99276b4f634ae445cc55073c23adb485bac65d3477e3d8f0ce9436b496fe458f681ea8c689242cc24a32c6d275a6a7d1d19de5d0cf0ab8b4d1a3241fc99d25881e8845f805edb500b744a1555b904d02dc1dae6285bfd728f84700a69d25f42648793bdf4a2b6e73c4290c39c418381b53ff0b3e41f0c2c47ab9eef7799909df541d1083e791a75d7dffc3ed569f8ea1ed0aa95ef2079a0ee7a34057be4acae7e9dcada585dd7dd18b002c7e18523d86438c29ed185fa243ac46c698b446dc010fd37fa5e1680906998e4c993c1c6c27fb3e7ae91ed2897d2c83f89bd9154266fb02436898f25a0072b936486798570e86e6e032c159b971f6c8ac2bf456f3548482d0e1e269b6e7cfd3fc1949044d24dbc662915863a1275fc9fc12e4ac3f3b0a4f5d5e7de722d2b4153f85e880646e02a157d3f50a629c1f00191b53f8242c1ec0b413307d0735ec67c8d0152a796ce58dc118730a8bd8ffcdc784985a07313010884998c35f6ef2beccbdcc7f1efa668a4b7cac6d6bc5436918190c6a3506068db0685440af9230744357fa434fc2b7f740119f83c6f5252882ccbcdac7de22a100f1b14975e508dcf02702136680d24280e8fb0fd1aea0335edf5f6400a3e305a9e21e51a02eaa442cc998f2661d62e8d13de2575c0e74c8112327bf01f129fbadb0786701c625ab7088afa2bb0f26b575024e15d3ddba2e467f7f2d43d41f127fbd6dd5b32bb37514e42e8369bbfd1faf5393444e6f489aeaaad479ffffd085999c1bfd070f97c58d25e6b5d8ea0ba8dd036da9d37de0fa0e7e84ba6fb69653686aaea2459a0bc95a7282f83944803a0690d00ea3ed8f5960d7d1213eb6f1cea9a0003eb35a98133192a0f616c680aff552e8b46b38685a1b6655f90e7570809a2008486b4683e287c3922116c134b6f656621a2d8412dd070804317f184d1f964c1a58f0e55d0aaea69f3f86e63b2dd7b112d5fdcebe9dafdf2bb361d417d4506e89e5c300910bbaaef3d3cb4eb5eb0cc9b52adb7373c96a7114da9f2cebb0c021dc3bdd6523db96ec634c738d34890c3052135b51512635499715f303553c4ccd45b4e7e75de58e2688fe63702068c9dcdfb439eab45b7abac95bf5a53e7b70bcad419ac6568a3b09840b8938c97e00a5245ce7efcc1188e14a9bd64fb7c3ba12e0c0b458c4ab7dffe5128f4a437519d3ac00fea0e8a30277bdfc0dfe502e64811f1842cb53b8efbc1e52dcf384ca035076d6710914c081e9ce8da09f89021220325c67929bc2adfba8b673a01492ace567c0f6b7d904c56395500f026a242cffb7af55707f7673c1435646736726f0e10771f3051187ae0b4d5eaaefbd9af67abfc7867109d0faa50795b7f010316db92985604aaab0e44c64b8be673d1955ce4655b261c531281d3c9a5aec6a42b3b937253b23e7426854be4641c89a62bf6b146c468d83ac6c05b3aea5edd67b42df8c094185d556998874d25ba48e260f63ea2d4245d528100c0fa2052dd83d57257d270eb7feff10e8a649708b81ec18f3379ed2ed0afaa4aa82bef250055ee67ef7a457af3b1b1d48c8a549d6095d2e085eadbf59f9175f71db4063b7de8a09001fce8957fcaa595d590ab5b44ef06515027594bb5bd9b37369819bf6a2c2060583e8ef0e643d5cb6b978cf33bc3c01476b083c5d72d920f5b9f89c7a61a5587b7b90a21616eb5b2b668f6b72c5e2ba5e30854c237463bbc25138e7e2750257fb1653ad64e07fa45e13f05ad575f03476f5aca9e0413f1572a1e54675d7976db4dee211a596a2137c18e155c356a1d4f04652eedfcca654e8e571115b1e9035ff5a3ed3717db9c444fb73b9eed06316b1681b2513a3a3047452b2918c5ca0023faea3d7ea25c55bf594ebbe006b3a4e7acc5f008b443b87282390da4a586cacba3ab1cf7ab34e2968aa8321e7aa134b6bf82237f54b2b4ca1866e501604c3428a50c9834548ec78c42ba4fb4b51691d3ac424faf4f6a97846d32b81e9294973f3e397b4f8996f4ad67041de8718dd7ddda8e104a4fe66e01d5db4fdc3ee2105a2e97ee7ab06c3ba36665517989b8163212328c410d1f374b82f7b3bbdde9f6e662fb3ee61bdf08940494672a0898c92f5a87973086556e22d53ef4a327584d7940d630e78383d89360275d9c9345e22331c04e128bf8975976ff84e399b2ddf4428720f1d747df7fa2808fd79c4d162eb06589d9129451f7d348cdaca1e453a55ce05ff8f04fd4f4a13a035bb65e888c6a9b8283cfab8cf88abd7d4ff3a883b5c7a03972367fb5f90d315884ee994c323d2b4634279cd43ca4926b3f24b08c17f2539dd974313fa631dc5925d94a8ea6f854c50eea9aa875a0da7780d05238c824a598a808e9477bbdc65ba174493818df99ea050cf38e8ee114b3041dc641e153fa16c82c2209101dc45739e5580cf8b703db115b17284addbca44b908c2f4b82a482df386415a1bb3d14d3d1f09d84d9c86becd0629f90af8f911c8c39c9a7582d61fdfd5d307c6a5f9cb2b21b6e63d067f0f4a224c266767f4ea8adf2f5e7db8eb5a96a147c34e30ec402e88228200ff3f84a2637db52ff4a567a7377995abb45d9d6218a783b4d5281a4d40bf55f56d9991ba33776614d3580e4fa4e3e749bfe4f493939c662ffb09c1e4ee3fcc8d0970bcf4a184de1266279b9098708e4a18c3c798b861ccae6b899676ed6c47c823793f76ab0e010ae27fee1a1cbddfce1d593cdad1e26ce791bda9ef62b23837f1b3a5d8bf2bad0ba64f400be4437cd3a94b127e774e8d13bb8b130ae63f90e49e8023d5b6ff064d94f19ffff39b743d456eeb1e8e50fe2f47aa4739b89e1cbefe0701b44a66e6fffc9a91d92b82ce09493e5a417503bb7868ca0b948ef42ed5c945751a7f8aae6df21afe5f2a1725bb07f941b0e014ee13fce729f0e8bdd7167fcc11e473a438da481bf7089dbc161a5eff69c2da8a3810e5ebb7f0b78f307d2f4d1622d7c4c7c5114d1f80b75164bc77ecea23c96ea450792a0be7cf7f257a5f7b09dcf1d35489b2a5f5eba8a208602fcf33f1b18aa8d101e3e9e60136b50213286e5cd021e16504ffbafa1819c2be3405c7a36b2b7e60e96b465c1f335727de8ac4a378a5d8c1f90db15b8ad1cf137dc477a8dbf54573f6cb22d180f68f160638b1566bd3e9252ac8fb3890effe72c2d269f184cd97b98353952f4619ccea878f11dd3f9bff7c53da39083d6f25d4d2238b26a82b3417465cf94bffa82733c54f26d3834d03b831795809cfebbb7e232e0ab45af9d0b7247e13a5545d0869f7a5dd695a962a79b05f33b87e6c3f575c44c6a54eb4f18778efcc60b42c59f4c12ead8754a4da82d34b2fb9fcde52f1d7f32dcd68854defbf9a2b3f4f6efeb68f9d135b6a3a6f64f83c771af52f359beb7cf6b771520833ecd6132273d7aa3df8f2895bf876edfef7a0979e9a1244853bb457eb2f831af8dec0fac6b3e94b36a52844260de4ac59f04a7d9a33d13947b7b83d0884ab9e6e613344b130a418856df20cf32f90656b54c65b3432f6f9ff5d6081687eca68f15ce0791730a666912763ab220422a476ce8c7b927f027a2df3a4f81e5dc5d9c21591f2a562a5d2e9a618a40c142604ea9f93b75a305656a503323250e98ea87565d90e58c661adda847314ef6a245c70198fb29a0dc61bfb743988d5a25cecbced5a20340ac6cc7de92004309ef7a32b146763169ffbdd1afd9ff17d9978761e9d7c4236d972cbbda59452ca2465cf0bf40bb30a5d9061845320032f8ec0e067c81218607ff1a6003f2843288b11625c5105d7fc1be3a5943b475e7a2ae5c46754b641f3e4e3900d2bf858c30f1f1d06afa253b7d45ff08a02e0351618e13577c12b0d8557f8117d8905437cc95bf0aaa4c467190f9fa9329f39a16da8675e83a3c5673cb2cc3980b36c8805457efbfcc8f8cc5f863b9ff5645a067f3e1b7284cf1744a62832ea812a83c2061d7c3863061bd04095b7cc5f7e573e833a9f21bda6f909af342557203d11a2495016aabcf5bc741b6f821499a1072214c1056610bd4025c798e1a59bf04ae2278f7dc32bfc8128b23841228a8f151fe20ed8480f6610042b80500617aa23f87cf4125e453a24c487a7aee115c578950119e0afbf1ffe7a8657172bf298fb0ce63598e3b4cd7b8204228ff1784c07cc5f883756856112437acc6dbc9940953168c8820c1f2239a8aee470e5091dc048c26aa2cadb632d464cb4d8f919820e44c088a083941cb05821d4c40e307f577cf0983f22bc7479f14ada8cfaf8f1c9151d3e9af1c547c7f02ae215968457b35b938ae5a247e0274ef5c8e5d9f9c0f9e975b67a06d62ed583ed8b982f1e7a8ec9f21d33936292be63ae7c7b8c4e8ec93139262626a6c5fa1c8314936376be6372cccf774c8e11fa8e99929a92ca29a39451ca2875e5db533914a56cf89ccaa99c4aa55239b5f39d533fdf3925f4cd9a4bc0cc2560fc33cc64c178f19d61c8f876981c5a301926c39cf1190606060626c3ec7cc364989f6f980c23f40d43c4d3414496ef17a017a017a097971c92eee797fc925ff2cbcbcb4b7ed9f97ec92f3fdf2ff945e8fb65b6e0e9982dc8f2ed32795c5c268fcb956f7719a2e3925db24b76717171c92e3bdf2ed9e5e7db25bb087dbbb0ca4095814a7d465d415d415d41a16e40a15028140ad5923f68913f6881f9dc225b2d2db2d5d2c2d3d2d2d2d2d2d2f2c4d3f14496ef13d189e84474baf2ed279f533ee5533e9d4ea77cdaf93ee5d3cff7299f84be4f463c1d4664f9360599824c41a62bdf6efa317d366553366593c964caa69d6f5336fd7c9bb249e8db2479d8240f1beaf3267d36e9b3499fedcab76f48609f3721dbb66d2d39c3d32167c8f25dc222a469a0e792172f8594c8f8f612abd4337c2e35f1b9944ba552a955caa59def52299784be4b53b429daf65933d28c34234dd3b4a4244dcab76b445ad6b266c5672d6b3bdf5ad67ebeb5ac097d6b4b3c1d4b64f9c611471c311e52243fe38c332efa8c31c619ef7ce38c7fbe71c642df38f2f074441eb27c67d1278b3e59f4c9b22c8bd23771495c926546f47396b39ce52c673bdf59ce7ebeb39c097d67ac2fee17f77ebe4937e926dd7b6f94be8942a2907bab7cbe42f20dbaf9fe7c5fa0279e8e27b27c634418114684611846850a860d49c232d6377cc63296b19d6f0ccb98d037d6443c1d4d4496efab81ae06baae2b5f485e7cfbc5a4995c52befd1a72e5ca57bef295af9def2b5f3fdf57be84be2f349e0e34b27c67db3ab6756cebd8a36fb751faa67bbac74af976ab63b385437cb6d966bbf36db3fdf9b6d90a7ddb294fc7942cdfd5a81a55a35aebd1b7d7287d03bd805ed4ca538d3ed75c73ddf9aeb9fe7cd75c85beeb124fc71259be298b42168554e787027da699524a33ddf9a699fe7cd34c85be2992a7034996ef8905fecc9f2b3fa9cc3c91bcf8f619a56fe092a681be644af9f609643f4f1d7c9e79e639f3fcf99e13def074c01bb27c4b2cdf439aa6dba54ed0779659669925d1b7cb222992cab73cfaf697e5ceb7ccf2e75b6629f42d5926783acac8f21d638849df571eb6479d1c7d82628cb1c5fa1c91be3f472fbefde5b8f31d27d0687c5391e5bb5d68a4bef2adca4de5e8db3b4adf78a0df514bf9f62efafedc42befde5f6096aa26f7fb977be9b47014f07f40cd178053c845870220df40c91224e12d4697d7f8642ccc830e8db5f8644df0e8be28d55f563419e6f7f2f43a16f15bc1df8e980de38cbb7037929bc870d02e89d7148b9c1d1341ce8a116247db7a7da6bd0f876dbde383d93e2cd64c5a48731c6284fc7c722581f1d021e3f52168bf57825e14f16110cd276e2d96ad060cb3044d8b2bcf2d053506c59b61eba4665cb92e8a15f196c59063df41312b62c73487ae818872d47a387ee02053a06c492878e21d972f479e8580651c843c7405b560695879e91b1e5267ae8281c3079388164c9c8136524c9f1d1a95684ee79e81ad28682c28b878e7a62cbd0e8a1d7d0d932643d749823b6253f81e0cf437f09c29627d0439f54a068222900112888073f5da61cc7f4136aa6dbede70d32780244fb6cde14252f65c7106fa6d1153b854c2aa909459217fc740844a06da24fc740c3f052800fe9b39d4638d8dee769f4f0e8a7d16ce5f08e1e7a0d1cb69211db69085b967f12c2d635749e3a842d10ba0f47c63f1ffd2a0125b57514a254900bcdb06a88e213478ed86865131e22a2f984e542332c3a8507a9156f668de2c708876564a5b884f00e656155b0aeb4ee0e748484322a322054900d211c2c3ce45384837502110a451a51b6c342d910fa88a384832024bb4161b237b0ad8bb4f1dc93948c7545fa7c4b06a3b365586c994a81e44adb647ce4a3073d25fae8f848db64cc8379b0cffc89371bd00cfa887f62746e0394a082a54a00162e587707aa87810984014258aad905513db7b0a5155304bd7f38230949d5453f20c28f0cec687654ef88089c810e7c68a0921c0e2b543e344c41a2925cec6208546021a55dc02409ad1b2d96b05477e2407142482583dce107f59042bf6102c91595e49eea96523dd90c5bb62f62d87823a717215942a4bab0862647eca86e3b51c252dd4825c98feaca6c72f0c9910f90eace6c72108a0e5314a92e9d224887a25ac40d41aa6bb3c9c11b76c0b2a3ba17164f7654177b0234c58eea5e285d5c51dd2c9b1c9067050d578ca1920155a47aad808b5b3c3caaab6131140416d52d3d99620620d5ddace8c1063caa6bb2c1151fd53d3da1c11420d56d09c2053caa8bca26f78a8858a2a3ba2e2c181263e7850633ca4882c926d72c8002d45249ae86a5ba291bae2883477563b2c9412146a868a96e8d6c72af8a1decf0a8ae4c3639e982201b9610a924077f80c6505d1bd9e46a164920e10a964a723008258654f706163f0052dd12b2c9bd273de82048754d28e1860d991a3129981717548b09aed5908413402ac9d9d042754b170d1915e04b287c10c2a37a4f921065c70424eff1142d67d49062cb32c5430da228433c68a9ee14d5f30deee838d453f4308513e4181e763fe2cb9703baa481867f6e4d2d5b6cd976d77d2131554ee7a4734a29658c31760e38946c93e7a1c3343ae2881d3bf6e489744e3aa79452420861bc818f06fa658a41782a8a07270ffc1863ecee66c266dd1042d842ba06a9b55629f4ef61ff1c867833917834edee1389d644e2b52612ac773379bad4003e4f24b6a26727d1b78ded99be6fa63dc797d9f4ed93a652efddc8ead0af95de7ea767930b9eba4c8ad6b64a26456bb72d09be07217c532be2d280545d1d101954365f99e6610e7edef0d0274fbcb91e0d74e8dc43873966abb6e03e1cb9f4f3fd1ef4e7d316a02aead3e7ede82db10af5b79763be1cb33363cb98cf77c947237a29b85ce0a9a8cb9db9136f28be406b20aa6a07440615ed5ea4816e4b3fb2630ea51863f47faf7b4a297962b4433900b58451c96d066c2f274f8c5046d9d9211cae7c6fdd93474298657a9c91fa7420d2e9ec6450c9a418a3470762840668980e440668841be84047257d07aa66a702193a9d48a58b1e1d9574d94da348036751a4813148f7acd27a08f4cfa35842e85f144ab45eeb5f144ea67ce4792944d6cb011df6689921369f89371819689811454705bd26dec0a41874e28d06c5153ae0d98937cdd2e1893b907205141d1574f8136f5e914e50bc69349cf0e8f44fbc69a148131be8a1b74eeff0c49b53910f473a2ae8ed93146fbaa8e80a9251bce956abf5d061112bde7452273d840e8182a01008e24d148a34d0851e427721deeca0a2062c15f4176068a12dde449ea8d303aaa00ab65077420f238ffd1c75fe11cd96cce2d2cb0924464e1c39b244b0231f722842082d1ea0040571040e9288428bd68e1535f86a459303f0d824ec90274949affd1bba8188bfff9e887184195c159e10fef472bc23bce9e57845f8ede578250d277d765f8e8775f11710ded6179e7d9cf0976fa80e8712ec2ddc899326cee2154a9e73695e7105b22f39e4a1333878da651f27bc954fe08e92e6d85f904fb053bcc2124ac6c9cbc19e9ea1d0473e813a6af720cb062c218c1adb8b76f212063d293f25d0343fa093c7ba0c3b460c833a8976d2361dfd5e0ebb9b62578300892d149ba8c617132364c1980ab528e3b1cab4938731763f72342f398675d36ea29cd859370c6a21b8a3bd360bcb624ccdba9d7836b1e858a73cdb94630f8b3eba0c99b878b6730225e8dd450eeb3264f2b093a9e1d431f778d323d24cb7e12fa8538c416d83797b0b75adeda4dbc9638e712db95631ef91edc3f86b1819b7019d3ac6e150b265d106c62b44cfe9e88ec54ee2c5864c9765ed4589eb247af4ccf41a1c042210bb4ea285bea3e3e6a8c770d94b7139c330a867e874b7befda9cb2953d74940a8250177d02e79a69a6759292b655956ea3264d249d4549d2e8189b5a867d571d57c3a0c9d4427017550cf5aebf20fd965c8e4a9c3a04ea29df480008bd549a4608ae8e7fddf904fcf0fadaff937f443d0fb08f902fc1beae10a94cf3e7a673c4347860cbd40cad00b920c19c132f40226b7f52e955a6f2b66f9b1cb3eb0ce2076abdc56db607885c9f6692ef38b638cf107e672b4f652376ec78e6928acd4d8b5764169ee826feb31c73cdee8196210c62e073797b720409ae6ebc567ea5c4e4b8c618f0adc8179bc479f7f74868fdbb1e814635e6b976feba9d7dad55a71573d3b79863bb5fac33043ac61de18eb645abadb21e6970a16e36de5dbfaea591635d7ba9ae20f0af64bbb8b67d99e83f54bfc8937b331e82ea8eee7663c1a075bb83ed23f7da93ce615afd09e611cf51257bd47eceb272e676fe2eca659871b849a76abd860587668e6ed9ab78fecb32e07f3ea58f3cc2fd430ccddce6e151fd95bd7ba2c7f07f2e4f68937f656f1f1b03c74eca5eac347f6d833cff2ab86e5b38f8765de2a5a77ab401dd46b977d648f79d6656973abc01def5bedd347daa77d6e9518f432c585716206a60bae06123f1961420da112deb3799ea3cf1867b77cb9412e3043987091cdc58a12c6458667703334b0940fa2779766048baaa2d6a881c2dc60c66091a526b0fb84b4417ffeba1f0a62160400c60b19169effeb3a1c6ccf837ccec03fee74448d1c6ccfe7014c137b96fb8a77d89e5ffd5d0fac2b5f8e0cebe23991a5717deee1e77fc0ce3a668df43f5afbd79df0723cc8c95c4ff3f6efa35ad09bb00adae3a2086f8bbff2fb5f97472053c5f6fc9664e0cbc1f5bdfec97f1d1fd57290cef04f45d850b1e17371f91198bebb2c81d7885e8ee7d549cb0558f4839e233ea7a60431b5983d3d40473ed7b482b83236868b0d26293d1e7cfe47b7f717d11d101954104223b7c6101ed345aefe7aa6d62ab99d7fb23aed8a68b7504a294b5a195b498bb24197ef3d190c4855f4fe22620744065507913274c7295a2e407a590018318736fb63d2d1a2a3b53faab7923a3df3680e5270b1c5b75f6f9b291d87921bdb5be892f15eb32e5cf20d219005ba79be3911bc2bf271593e7588571736e562c477be9723c7f0edd907ea5f275d8ab0290efee3505df4ccbf63a8d82218f70a8470072830bf28ef36846d42f58c0c947f32b153218a265aff7cd0d2d1d199e184870e81a2dfa20881ad8ce385604946bc211d68f0b9e66191d6671e0fa12abf22168410c2b180c40b8e0524496de3a8b6e9193cf41bf10860960ff2af936941fef315e4bf8e0521767ae67d90efd1f6397c516b57217e53278838bac2c45462bb74a210b6ea136bb0997e660f36caba62ab445236593485366a34a14c27e810510879865c82fee0036a430db4e83452350c61c31652075bf599406ca61f4964a3ac18c65689b4d864911462a346516ca72a54499ce1081d5ac476f1441e36fb1391360b84c556839ec42d64910b2f64ff867a98f85cd302a3e83d5a8978adff867a74f0b9a628da7073fd9c720116b9a0c856eb03c747a0eb6164bb3eda9043d1181bf66f2887d64c63bbff867248a234d82e9db882adfacc176ca61fcac346594688680d9bfc3734a428166df4dfd010a30983214954865c9957e84c21dbc51397d8ec8f74b2592030b61a447b36cc9a47d8aea219c656fafc8ae8928d7e4e15c922175e18ead1e1734dabb2c0719c6553383844adb796e5b0f5d681debea4b7dd7af912e76d0d9db794056fc7347a3aa03f1f3c7c4f8b283a5c04cd200a2c583801032b4f8c9830f281c973f8038194e839421758ca28234aebdd7062842124b1620b25497835289284a5091a4720c1429561d163e04a1a4ce010032425a8a8323452f219b664f09de401fdf3f7520fe79fd7c4802124094f140188213c514520debc2ca298527404129e188103d54b829321788882c30b7840822a3fa44774831ef404818b2990b083ea3914f252d0699b10e07c4e75201d8308daa68bf817039b99e7dbf3d737f1474747c7c87388d4366404e9e8e8e4a08a627a361d95722e7efa9c39e1270a383f876e40f2d34e3c9f94e9306c9121bd172e9e1f19d3a18e193f5fe60eec813f5bfc344d20b804c63364321db2da6642283f8960949fa9391db680f0f3e86786485efcace11992f1f3ca4f6f1d277e7e6e21bd33a4e7c84fef9f347e7eee243f672ff9c9e4a7939fde2c22a03e379493e7268af273b6d1cf2c48d8bcc955c02bd389883fc9f8e964f213ce193ed4700692cf1866a84e3a300943880d8cd0b0e1057f62c067d49b08f0d9c69bd268c19b4ca63498bc298d30dee42bbc32b98c8c8c8c8c4300af641e8057271a963c7549a9e338a16d6c38f51a1ca4a72f74084a9d03f406a5945219a7b4044a29a52638a54e29a594524a57c0c4bbbbabf0caad092698608209fe78654209697c09de03af4ab03232323232ee00bc92f11b3428f137bc017875c36432994c2693c9647206e095e98ab7e183b7e13cf0ca8695494e3360f127df8157a714f08aea90018397ee384ee81ba94ae3e510ff42db9c5c3a07e4932e021ea4a9e74892970e818e78d922e11029e3d26114280552f92228b26055c143114684be60220426b05061a50a2654128c1e0cb1c1480b960e39482e6a400210115fcc6045477a86412f65805e46c6ad8c8c2f00af64a801dee4d63434830bdee43878653a9d4ea7d3e9743a9dfc06af4e91e699a73529ea1ec653b7d4084fdd06afa802f04afad768e26b380a78552326262626c66b6262bc061fa343c3d73cf50458297378e9566649c24b47005e493f005ec5e0a4c4a0f229afc1ab541845af699a7bdb9c5c731c9ad7688e23c56b9a109abfd03626d79c031ad534cd03700418fce0831447286309cd5fbcb1a1a2062baa68a10318461a2a0c2f9e0ae0297d224691a7ae03afe8f626139137b93585218437b901f0cae4a5131e0ad202f1d2b7d64b4ff9cc93308ebc04238b979e03af244e0282ca480208073b902184d3cf9f8cf0811148367001841151a84e604cf9939f8057272f005e693063103d8c1300af60509e42a15028af41b9456d8ff237460e1e65c353043c751abca2337825078057a8173492fc8b0b00af5e5a82f816771c2d2d5ed33790a7a58b279a684152931b248185aa252808a325a67841cb0845aabc7d0b1a3cdff2b2f88ce2c10928bc7c3bf8cce3258df4d77ae95222e18c9767f02009495e3e4982192fbd06a78797de030b115e7a00f04a12651c4ffd659ca70fcacde767f41d7822041c4801042aa4e842f5a8bf22209eba4b79ea3db078ea2354440e3d3882874a142a8a842a9e3a0ebca22d00e0558b0b0bdec53bbc7231e36344f2d11dc70935b18c9f8f5a3c12a3c3f08e44c0828f2db15f104f1e5b3cc32310e8081fa391e890a86da244cf50ca47a3172509273cb86207211ca107aaf8c40e4a94b1c373648a2a6f8f680348aae8805145911967a8f2bb82802cba688288152846285221f550c4104d8491040cd5911dcef8218b1514595285108f9af228e7f00a25fdbd9a9752ba237929a53b5e492bbea58c26dfe226e0558b25028a22d6939e2b8882a0cadb9f4e3ffcc96dbcc9b1850d4aa0c8624ad211aad3117ff212f0ea642aa38637f90dbc3255f119f5d4c65397d4b71e9e3e21e3688c243c751b78457350048f1123885183242554797b4df379cd6dbc2921cb10224ee01084103c506962bce6325e03af626bdbf9c16f1e83575b0d3a3cc69ec2186b8eb10dadc72db87dc0fe020770c4fef04e94c726dc3d60abc20e7d24c66e316ec1c10c58cce001121b10c1333c21061a54020fe32cc360e95e6f9c7597e1f4ee88332fb956ca2a9dae95b2522e81d6e50cf3acf3e897eb9eed32740d56244c525e2ad78b798f6eeb56b9552497b72040dea5523ac94b65f31e7dda4ab705774c732bf9c94ddca974b9e974ea4cdbf6e28dcb2cbb556e955be556b95574867e960cfde80c059134040495bfa55266fd79102032c4306b524ec69c3e4cca592d92f4eb357028c12ecfd9919d4066c56b3cb9dcb6dec95a5b3d71399a346d9b4b59fd24fd54b793f7685305b493ecb63ae42f59a22ee34e89336df2f23cb7d3e69bbfcd37376d5df691aaf2fa74ade2ecb2b46656a00e149d5d064bd01e893146ef56774b795d592b4b6aecba3a43ca8e9a72b6a4c5deb0cc369c655966f2eaafcbdba94b2d5e7254a94bdede722a7559eb7ca44c8db3f6cc4a66a5d4d712488a62bc310211e511f06f08089fcb46af15fe5563b5760559afebbaaaf788353a9733fd3dac57add5659497f499afeb72207690b4aecbfae525ec59c42be454ac54724d2b699ab679a9c5bb563765276f3999b692c6e1ee62dd75aba032535b24dc96eccc5e2af2de56758c27d2b45bec17dc8934edf6b39fccb32ef74ebc39795bdfb2df4ca62ecbdf3a2de332acde9deb5e1793d9ad72abdc2ab7ca4f5dc11128478e54a7d466479f2345c2fa04fc1b4232e4e1e3f2d699856ea35bcf5af6b2fe3ec211c49f472f3bb28ee507f06fe88814eb107335b06b3e91a6bab5995f8f5027d254b7d5bb83ba737beea0af25af26bfbabc5d27b750c7e4d64fdc6b1adb65fbd7e526cefac6594a737536f3768df3f1b07ced21b7f391fa8a395d2107c9c13ae997f7908fd2e3f4e89915b8c356a795ca2eb30275c40ed533cf7157276a43277048e9060142e7e5729a6a745e0d0e813868f776190e9157eb72eebb9c0677e0902c338803f65a69c5fefc5eadd61de8a37139d956abc6a355cd3313ca8482d4beaa79a675d61aed644ceea71d38e4e2ccb39616cff2ab774b778238380e8d9b718803c61087dbc1ab65f913976c9695e4972ec401eea03ead4b4d3ec401e20071701cee10879ad30e174628b1a7b56578c23e8a18af00e3d5e57ddf8a45624fdbdc55840261fcc59b1e35646c70790b02045eef56e4815eaff78897cbf1a7e1b310469fcf373c56dbe5d85804eea81e2d8c7118d3e57edbf3d1df6be93cc7d85af44b6ffcf94c6fbc41ae778c37f678d6620ff67a7197135db376db5e8c1d8e897e6f743576325a8f1a323662975988deadc8037744bf31c67cc3a9e7d8f3d561b80c1fc64b5d4ef4bef5f4e2b148bd37ba7ae3f569a393e96e977fcc1a1dc6114a2c12351b63911879fe428771ca45bf254f71f861b80c2676dd9a3f66f7f55804daeb315ed7ba9c0bafbddb85f58845e08eebd421874bd7ade61357a05e2f725deb6211a8a3158b601c7b7a40201669c5409821b05e9ac5f352c394d2e95c4ed34be9a413df2e07beea1377b9797e5e8c710b98abd9a5b979ba3b58c22d60dfd035bc42a921ed1d1e8c5710375772fbe2f70601d23b3d04f791cae598368c7b6748ed9e0c6f5d4ee6a6da44e00ebcb95493bb64cd033be9b033656eea164cb493317597714e2ddd3b6d839d7a0fa1f947e7e679ec258c577871d8e5bc7019627741419f8e9b5eda6588e10a64b2e909af6eb34c1c0fae47cf48478185fb3de4a95bbc427bc927079d72d3b7c6fccaac3ac618e20eca9e2971ef21865deff48c67ab75a9cfb14ead6b996bfe700b5a2773652e25ee9a08dc417da452ef1667389d6a22995fef9d26d23c94c3e919e917c7434ada3511a863b68041842191d63ca2401e475c5a3ffd66d5332fd154cac2da65d80296e1152eed160f233c8eb40d5ed1760caf60636fe14a27ec35b0227b6386395604bb6cbbcb1bc58a1ef37b6177f3f0691e4057bf538cddd4af8b9eba9cab85871154055a2ee771e4a977473d76d3eeeed8e55cae7947cc1b420c79007dc6cee574470cc35e9d870f8f9fcf18cbd1f105791c79ecb27aadb556eaed15abb5d6d8d66e98e7d4f4893498370f237d39ed64508ebd6e3b2e2f30943aa5de2d1e3e30f338f275c32b68d14bb8025c8615c330c76a743915d3e5ed458c3a3eca3f66e61aec32c40d4b1c75adf30d28364c97531ba48eb18c4714ca6d445b146e2bea19cc51d828c6c308d481290f9fa74eaf63aebd476ce14a270e5fee750be3a6d0f48937db8ef5294ddf76e2cdd6dd8e568f361e468e7ccc3ee691cb7a7b3e82d09a2c0f233563493f7d038aa9d4b6013d368f3cf47af4d8d62cbf96b8e7631e39e26104ee803c8cbcd92d1e46285e653c8e6c445b948d6823e261c4a5f5026f14f545e55a128beea5106a0eeb92afdd51885148a95f4bda06af68edad8b2e47619e71d52977a1a0b10a2240010e02845e422f46fb73015d41342b5d4a68567a79a110c212764ab7ade430d62040faea4be8f3055d86a7f22f8fed315f419f2fec1dfda20efd474f80622ef7b5e42f7fd52df05c7829a0bc762dd1c7b56d95fab639743ae1063b1917bfbc36ab2975ea1057e0e702823ba8378d4b2ecfd792af8e61edb4cba15e823506bd50bfbc5e304da7051e4d5f417da9c35cfed2c5a07b2f2a94eb2217aea518c1ee5202755cf4027a0abd4744719a636fe172f6270efbe919daac58df4d5393a5dcd69a372bde445614ef2646b1993899cfb60dc2ec52122fcf3e5e8b36beba1c7b610cad09dbabcb3649ed2e25254c25b26214ef06e6d14c9fb0552482ead447c9a9df92679e6d92bfae712ebc1cd82d5e015698f78c1ebb055eebabb77eba082e25d5b5ee52726b92b73fd72f25d7295edd6b09d645528a8a2e2545314bf4c09e0a8f6a60b0ab1eb544547489258fed399e4cbe4568a586c317a01578d453efade12f658300a92fc056854936cac4082d12ac32160056e6e8617e47558b30c618638cb146cf5b1020142675ecee9685481503c0333cb20d8f3eabb56bad75624c6badf547b4d58667fa373ccf144af0e8f9a5e01e1dbe14b8ce23b4f223cae0700f40abad8547161e7df51a35a00603e031510035663156010420cbba075a711c1c0ecccd38b4025b3500c065de7127e738933bb7b909dc8b97c095fc06e7e2363894cb702d35b85be385e9315daacbf6270c841d8cbd200cb45dcee50d03ad44ebd987ed72daab5b87160fc0218c57984e0673ead0b7e8567028b12f2ef3a1a3e8c31c2713b771fd72402f71f2e580d5736cd72e3f2ad00adc51db0ad441ad64193c6ace391c3d33dd3ab43200eee1985da77690928c924371c12e59d5a5945f74b95ab75dae5d869a75d93655fa0bf20994b659554ef60ccc1cc5c5d4b861a3046fac422cc11a59f3b5cb0390d2a3f492f452955e2acab92ec3cb872a9558d16b092553b334a102322648285fbd84ce46971d8d1b5d27657e544e2849d9e544bf2ebdd6ce7675d8d5a12cca912ec357085f805e9244563af4eeb284f2ed335c8ce97aebd07a74dbe554970e85381aa932b62fde524b3dbf1fbcf5f75290c93e4eb0d5a5b797b81a2e27703bf9a4cbf07f44191bde6e1df2dcf0cb5fd43618ce532c48af5efd85b6b10e5db2e08eeab02b95725bcfb22b6dcab92e0fc0bbec9b9bd0e55409dd8d4edee8649fba761387f10ad2734a9df54c56a72e9f94a0934faaa7aac354dfaa6bb5bb715dbcc2920c6883833dd0a7caaeacaf5ebd39e93da20c67427128afc19d3c866bf11407c36d9cc6bdd03335456dea8b8b43bc423451a7eed25d1e80c72e3bace95e3899eb99bf879ea10b84579783b9c827d01bc2cec7098f3187b8cbc1dc7a0996bce42f252eff88d2c54b1de62e2887810e6000eea9d446ad9ff0a5f6877c58847b5f67a14f6fea79fa9bd027f49cbe696ced59e7947b36d333f4d733167ab743a4a64d501d544b2db5934abf2cae98858a5796daae9d158308277828e2e7684a22d4689eede679067bf58d2b711af7a28f1a293097715bdcaac3cd6d8d8b92294a6a6690aba50b4a514c2ce8c6e116a2538f9805e9b4cbedd2ef9c330788d211208dd5bfce7cadc1a16f2dd1662dca67b6ad0807672dee42bc4175efd1546f49a54e9da99bfeae77bdeaf0aa30cc8bcb6e6989beece618d8b462ce9a15817141e18e7bf9f4eba580f9c8a6b8dc7b3aaebffeaba362b4d2bf689437cc1de40d9eb53807a0e162523c9cd8a44bbb6ddb0c6aca46f3a4953c96e8d1d9e2493bbf40320542082184b49f8053d2fa72880191164cd0224a6d5c3ca0990fe4b1998b0c36e93d62e6198597395e06e0e58d979bcbbb7101f552a01e03ce122ec410dd04135e918db43be1e5887e9be4c0392591a208ce4bc823c59873ba8da2abbf191a5f7cd95960fb9c41a5ba7bba1c01a44dbb6c7b294c14949a48533d53d364cb6aeccf4ebe1cf2cdc8f7fe06cf074800620a0b2d1a3344d8c924b2c3f0f466f8ba70d6e56eabb805d9819fd47b448c9397bdacbdececb6ced69c61a38d37974fdf5e0ad467977da4728071fd686832f6f3b4bdf43b31a478055f8e9781e215f55b617d51cb29f80729ad75dae8456b46e2b081e1cc5461af148e6f59ccc44419820d66a285128a7c1042385b4a38adadb4ce29e594924e990444cd8664ca2a65e5424e209b4929a5b49b6d21d93f2fdb0873d9459d665db165f1e6c578b551b46d146b1b45da19f17c4ee95820aab0ae81224d742c4baa836cb6352bfe106508cd9a4d565606d4d3eeb649eaf6ec8565b7a479f57e2960af7596388d832fc7749c71f2e5987eb197c35616ba6c63b070d21064f1083ead98b366313052c40d26f449a943d9fde8d80ea3c09268f0794e2be6ac1911414c38c144d04bec080bba1606db0d193485f8e85922f1d26510d5993c4c50cf538820aa53c2cf4eb24e676489c4e47919051156f0724a9e975810144a939e8c412f25fd9630d85c5ecefc8c4b629297f148ec89435e46212fbdb15ce9e29518e424b2ae386b647dbcf279bbf2f2b48b3b41c871480c6a1a3029128368121da25b10e827c31c40a028b0881c3c6541a09774884fd0cb2921d0cb6eb9a0081dc822cc29a594bdbd0b3e1494f74aa5cf33f329141095801fa20c01258bac89f531c689f4d067cf431e0b50959d486f9bd864cfc41967cb025455bb6b1469a2a776b041bff341aacad7e8a3cd362a65e76322fd84413dd0f093ce89f4d2c48a41cd0625fa60b3248b64cbd4091a544469409db0715131250d823f454034e873b62c090cebc2936d0c36e99db11d488c358435f1d433b6838fde58859a9fddf672442f89413912406931d6db62a8068bb15c786214eacf76edb2a494524a69376178ead39f562ba90c0b4e7b6676f0bda87972ce9e73cefe9ef33deb1655043901d910ca1f545baf87bd3bbb4c595bedd1dbf4db61ff2e18fca5f78893d6dafd982d98305fc2189dccd28352b64308a9379410ce8dcef9649b73fab30eedac73b230bbac934dc606679453fe90ef802c59b2fc94ff425c54cf443a1da6b26dce491dca546a4b4db1a152971152baf529abed9edf9955403a952ea563166497c99ec1f69661f1aa3de2166ccfa052b2b316de14255394f48c1432ce19512fbbecc352b1498f7626debc596d910d9240aeecec7ca45a20c0142553a40c0b2148fd194836c9671f59f6712db9965c4b2e20fb7329610961e463063d086390dc0e9f9e91bdc367f6bdd3a3e4a6532eefe879e93b782ecce68e1e6485dda489dc9705796edb669f05abc07159e4aec6adf05ef31b33cb65fe3005a474add35cbad6e5ebd0a7d6c944e0bde62bbcd73a19cc7334a78e753884d86458d09cba06318765d06f90bf381fa93a2517e4c23e83b533a4bbaddb62c11d16f52a97ca4b87b74a9010938f9e37d4adb2dd2a396ced4f5a560ff7e1c8f165cb18b2a39ea9d951cf54d9ad94ecd6c73a33f3116e339126baa4915df691a23e39a8a37d72b49310729915a843762da5a312bd46c5616bcfacc00440076205ea90310781386cf2d91655226807ee589906bc154e1ab60c813a280828082808a211d4369589901356db4c286d0389da6656a0a020a0254c20bc557c8efcf81cf979ac34e49cf768ce00e4c344c809eb078d0dc22593899013d6ad725b73020505012d6172abd40781aab5d13708146f321874ab04dd701f0ed8d336d22b5669ed5e0ad0d6eec92cefeb9d1572d90ab60c85e24d17459ae876c3b2e5589fb78b5a4a1bb54de6d19b4adb5c8f478dd43630eb7290e90fdf7ac1596d97598950761088834b381804d4367249d09335cb7b592bd2579d0c856050db44a7583628e4044adb58c78ada06cbac401df6a8cb41868c08c51e3212f4d1a11308e5a3439c59813ab2d64bdfa9dea37b6a1445cfacc49d1a57ed6c752824543b188b2e102d265198103181c284c5c40913219c4b3e3386422df46e8e39e570be526fa9f99a65d66bd6655df691dd6bea32c7b85ceab0dbe55c39eb72cd4badc3b02ecbf97d67d77e35116a2265ca86439fb3fad5bea124777995e1e9f503e34e203fe7baec50e899e8424d849a0835116a22d48449c5f9ace6b326500822e1f488123661d24408a98910932642484d9a401dd26b583528805123d444a8895013a126424d5aa536a5f133816492f8d347624f869d7acd99c7780a26859d4ad7dfbb89e91ecded741e4d7d34a72ea72a0c6ef217ee3d9a933f93d713eac76cb1f32faccb78c3eca9bb5c9e7c7698e7acc3badc47a52ee7e497536aea829cba1c1b8b40ec3dfa743af9c3f57492d05d502defa6877d30f5b693b148b75ab148ec69c522a76e459e6ec522b12716399dba758a456e5e3cbac79b970e864813fdc54f5d4ec138ecf2e629980ed5bd742dfe2fde401d945f2d27bf99d32ee3f807835da1e426df38f894bbb0120743f4d8c1aea5abf152873a544787621532a7beb9892b39d4d9e2e6da093528dc548431f6c4222d8d7a3293c89f78a47d7a5e364ff36497f478d22eb78e136f4edd6b1a4c04768b3054b7f1e60479befaedb27dacc39e9f5e979fe3db6d1d0c71ebf2eb7c64ff7cf392964bbe69a50e67d835cf996b1deeb26e3691db3c4d04e372b66516c78cc42a48a721487d8eeca2539c9e89ce83e1449a98e10e0f0bf2b800774c1c4e136922cdd3449aa7894877e172accb365b1c1c236c19e7a3b5339f6df334111dad4d335c08e78f3c127dba6747ee0c99ddfde809f1bb5e7d8e39eeb20fb7d765a9cbbfba9cfbfcb25d965d4efbe5736297779743693787cc0ee2e0a86ed6acbfbe1c01a43f5efae44290bdec72a0cb4e7692c60a3819e2e4c6238d7cef411c281d32e5c3814a29fde2bc67a2f7689cb445ef8e524eac3521da465a985f0b25edb4b6bab5d27855e10bf6d93a299592ca138772edfdddb8ca554efe187dccbfa11f277f6336af483262527b01bf5adbc1a39eb1191eb945792df9e5efdd9c3c3fb7d5b17784615dfc11a79fb8f768e6ece62ccd2e7e69851ce8f24b5d4e67579e2f6d0b76eb7210adcb81b083562ebea8b77eefcc4b697dbc14c1cb34b20dd4671f2fdf436e04a8975dce55e13ae67796b8225a5afc7619f5d64d5c8b574ef36abac0c9511ef14aeb6ccf58ef112fcd36aefae5304c6b718dabce597fd802274799b816df38cdefe5ac435cbb53d63417f3eb5a46fdbdae712d5cd63417c59dbc85136244a9c4156172cbad342e4bd9b8109abaad6980bc75c9753de2b3027548b71ca52388d2b53641c9621020a599b5682c618cb1129773358c312f95b412c6592c61d7344ca786335cc2d81bbbd6292b9995cc4a66850acd9fcc8200c1199793abcb59e7c4d371db4ae3856518638c31c639d703a67aa8844b57acab9c54a8462000000004a315002030140c0885a3d1380fb4a0f20314801381944c664c9947c46196c39432c618420c200400008000c09010300005551de8d8c65202dd14b1b3ab56966a079ff1b0b6583bc1ac02c4321317d1b41775e097afafcc3e4d82c74f04a7ad9f8f2008751674e7a2cd55ab3b100bbf023391752c2abcee271289aaed9ce5ed9c076f45b091afe9b1b0917227b55e24fbd82a30ee6e09ba1508c5cce4cc9aef1a71ee807093919a79939584d50b7ec0bde7c3b94d3c93f977555e543f805ad0e39ccba16bf566a5e16045b7f1609abb4c6a8e3345cbbae867433c1a529548bbabb48844d8c0d9946e05957cdc09b8ec2ed7f9815ce07ab2ca22a1ad06348e589e05731d6ff3d4ab061235e5ed54a6233a0162bb4a6fed00b2de4129a6e46bc2f2e2f8050a37879e2c0133b971c73cd109bfe105a1ccc7d449a9bd67e986965c1cde65cb4a78ca5bcc59790de734721c31fa4e7d912ec03c4adabaa150b89cfb1e09d4c22398ca5fdfde6a732baeef1a0c1b40f4d67cdb4222958e152586f69ce99193a55d3d88ef450d523bf70888458f91eccde709419c4e6e09c03b87cfaf02da51c293cea3e29cf39e9892671869aabfc6be69b42e277c66167d489b9fdfcceeafd5ac5cf1c194b2f210f40782625d5a54f393bb56762ec6702e9b49d08affbf01c8a272b53d5ea2d3e706b1ead5d9dabedc49fe49d156137efbcd54986121594397b6f4e03f4ba30c0da9a6840222bd48de162de117508834ff9b32baf3e2725dc51fab390743dc738556643af21136a8f07eb639ccffc93949721c337612535a125dfaafc3cba746cbf43239b1b593485516cb2907245e67efc11c05a7c31d1fbef52b8430f18e6fe5260a176647e45b473188909d84ad3cfcf567dbd0767897aa9449e852080f0e0308c1b35c48323437f2b8cd869449a2c82f0fc249ffcab076541b615ba9c6ce2d95001f208196942e64d1d01575c8519f3b0ac6cbf0b45c47b59bf2dcfc70bb25f98b19e4ebbefdcbd95fd9c62dafdeff5116f3f01f6857181a12248f34376117b34a8cfa0496926554d1eb0a62ca715a011d4c540cad877defea513d9f6af48665ca7538ebe6f3fb9f94549294919b29f6cf4ebede95d14d05310d7e22dee44d7d5a08ae6cacfd88035fffa6d57c76b5a9e5a569f53f31d53bf62cc6c4053a596f3811637bff61bb699b5d7610b5308565a3d98a9560347f5cb82d228f2b533864624b9bbfde4f67a58cf12c9d0f85f51c234ea2f7f76d9a160f5d23fea053bd2fa05eaf0165327454b5e8f1c9301bd9faf1027a381911bb3ab449184689ec5d3d01ea854336936984cd8f28125788be906eec8269d661b6b4f943f87cefb6cc7a5f061ff402ea3309f96895869eb6e8628a98e4a992db05ab62114ba087dc56159f7ee4db1fb6e30b04d0f1fac45940c80555d889d44a18ed62d1c89f08c9799c72cfeeca2f837e1630d1eccb349b626fe53dd9bc5e97d1405685762e043e576cc008f43a5b1c26ec3e59c673946b5bde4b38ea811dedd76555d09c5bec6046a3aa8148470da02a41a6da34e0e253205e61b786d480e323ee849dc823f9d1d56040504f82c792b03adcdf438b5deb57fd28a96b63561a16e292a549bba3e1ab3472797a7af118469509fa8b36714fb2de0d40dcfd744ea9ed8495b72e3626988cce9868e722432563226b51acb91524344bec49446481847ecaaa70301a60457766d481a150a1f7ab567778aa43a22bad977e84e2973f08cb7bff247714ee9623905b3dbdd619b2720064260ff26d9f237e62a3d80effea2064a5410962289703cd75b06fe06b760fb1baae08f6e4ddf6700fff9b7f77b370d4f6b5c9ca769eb74774d41959cb8b3b29acfd3108fe65ffa0ae5e678048af288ab850e42b404ccc27818b3bc507fc3c463e862dcab9105b7b7eab72de5e02eac6600963e281511f9b4a0a964135e748956c7f7d0016a57a69f493aff7bebade7c5fa50dda3bf1771bf45e8722f27be53b20cdf3f7b010314522070a0de21d553c628e12e8f25a139c5667b9eee6e039b7f47a38906d6bea8ea6a0b5c118cb993ea13c75524d15b34af314777e873a7380e5659aca70a335bb992e7d8c060057a74c0a8c46546837ec7098241819c1015d523643fccc03e2c0e2d67866656f909fdbe3643b982fad622bb4d9ef6b0f487ed12c376c110834dd061eb7ed7405309fa3fc05546f331f8def214c04ece148c1b8f88f4a3cfaf6e570a4001c4777e713295cd01d26bc7bc1d774042bbb13f7c7162fb5905e7fe0ec2eb54fb68aed7f0ae4a84f19226e100e3aab0e6b5e787f98294980c6fad0fc1a08ebbd126bd0e7773a24843bb4c00637e00d1cf43ee469c011a9529fb07dcb510edd08fa8e872535c571d47d61d772a2018de00f489ae982bdb05ddba9f72f2e8d93cb61cee578e5877c6b03baf641fa408d66eb77ae93736e96b554319a5fcd77594c17a07beb098f2a8c7e25ca4abaeba46e1ea5ba2578b2c5e8cfd438494904659eb5953a36d562a4378fc69b1476e82c9ec9a123c4e86c0189031fb458d2e7863ef6b84fa917ee43b21f240ec7ee50bab83ec23b2df7efac2236abe29f412284f15ae4d7cd8de819d87c76d823d0a43fb908591941ea663590b79aedae41a9d2a3f681805196de329ef813c0789e52417f07d68d3099d015dc4a65bf8e099ed57b63c7f64725d8a882cd9bba409084bd1182f8e244f0d8ad00cc41a37bfa6eae3f8943f28aa25a25bdd6d76d3fd6c0510dc46f746f924541864feac370b91a6289fdc35efb49f04474ed1f12ed986a377d5d113f741448a3cdb491804df5243a77a2bc9b1f943f21ff4b4ef63b374a5c1769bef2c2c3e1c3ea577fa41e7040ad8a376aba919dcbd353cebfffd88a36d207fa160ed85a9da2fa2f50e0f79f1f038c9aec10e1ecc0071ce854280974371d25642a495e7753e8af04c58a2ad3298c38ea4c3d923fa9fc32e9ba025d90ebabc7a323b5e9c0795f1494c3d6f03b0c21b5ecb16f72c31eee0c1295cba90bee3e17708b9ecafd49a91d7b6d9690cb8bbd91fb827966254067d263f7e742e3c678e8c3d3608c6aff888382cafaa13280e11b0a68ce7afbb5e0428b1ce95b7df038d2a19f31d377d4123b4ab18b887f10a046e5a7b448746cac6bcad6880ced3d57600b5b027ac747a541acceeb05e516fdaa4bf2d4e4e9a86446bb7dae6744df1b83c16b687a515cb61a64e8510ae1ed039bab30fe3dab57d151981521861bb98680f69fa3fdac5a7f706a2acc47d79d12a24cce8515cbf72f1b291babe84aaec276dfd5bbcb5da02432b549e862249b3009f6296d25ee3ca9df022b286d5fce7bdebecfcd2b3d259e0b85c24b9ec4e6ecdd2e1c661dfa611c5d2bcc87891ba7e9fca5b14dc11ec1ba70513dc188388b9ad19dbece10b3abf235cf622ce9671468278de642cd72bb91e92d3464da5f83e3b7d4c4216ae395ecdafb3f059893590b9fd1ef9bbec03d236f4be39fbd14ea0bfff61877632c43d4e0e92451e853bb7209bf4e2aedecde2d0f2e8a5b0a515033dd60b9f6c1104e40a1c45a8d12e3fcf5915658ab323c3062c8fa9a5f12f8057ce44a502f3f1ee42a06491d89e074d4db0963ac2acc49e1e98a7673b03804569877fe724b5e64b9fbc195e0daca5576920ca296770f4537e966bc21dd3e453a2414e35b38c070184196404e227a6d8f5378a62821e953cdff4b623ba497fd13a2571404fd5db0f3bc33e9f73dbc9156d778d69f32cafc5f3c3dcf8d0e0f39775b2b41ee8276ba8d185c9a690ec2ca7a949e3a7693b721949be9ab47b55c759589e626bfa55a3c4e57fc1f458d8447ffceb9b024367426bb43d51dc6b5a9b85527929522828c81e5d1db406bb491c2ca939060c249f526892fd0ca736c2ede9a30d271f236c3934138d20471a7d161dd0cb25f5ee4d9e4fe41b0f9e5c233b9bed49f073db358532acbbae745aeb4cc727577e1acc1f0b7edb1f6a7586e3c33ed7fbfe1eaace3d9210cc29034fdec32b85cb00cc0620ee98a252475d4a32e61526b950b66fa8c393bf6ec6ec42c5c111a6e19df4a096e0b475c3297d82baee887d3420d4957964bb7caaeeb3f86838f5340d8e86acb3ee0c510e9aa7530b7f88aefd98972d4da429d6d8682c4a2b3191cfc93bb444a451367303427b107563ea5ebcfb69b22e823b90a7fe4591cef97c63cf285c1c61c838d08db396c0bc6675d11dac8aa241c576e1e18fa4a817c659b2bb9458f5be9fb20122b8622700a957432dbefc8ab3cb9f85020ff09510e36631ee5db7e7915c88bf1257f51a1e65315a203347ecb100411d8c3f93a78eeeb6a3cda038bd6c243438974c56b5780bf6e9637a4655e5db7fda1c375f4893f7c6f29c4827c5b7fef261f00466190d11d9dfa833bc69d1a4bd35dd02a1f2aa18d8a513e084f74cc4c62bb41dbd2160f118bd9958682378c4cd778cca2ac1f728b52c7fd210aca939bc74389b630baf2d49543dec425c5e529c30485ccab5e6f4a84897032e88820223584ac5bc516a89d2dfc55a0a31e13467674bc77ec26887129542a95f7f22b1f7ff49a645c962c372d3da6f42ae73d46004aee450c55dc02762777a31c26f71fb037c04be2126d9eda9c6be39aba72c4c7581052d538035d6b6053cdcea9170cbf31742f7de862b5a63884ffb544ec8a5bff30de98ee00388794bac757a7544381b29d051fc62362abbbdb9288eccb29de0f272b374173338951a67724f65c16c89a1435dcaed6e688a08af8b3dc302e8a556b5965d13263b3472a0b3f1272c9beff059f48331ab6773a3b34c27df74959a58fe0f6a8677febef8e0e5b45f4f79914e2d8920d4526de45fc31fccadd2ef8209794c313a7ccb1ee74f3fdd3b04869c5c2a8ef747faca302ce2c61ea50af946dd08f5029fca630893a5ef254946d5683fe87effee7de8eb2af6155eff9060d0527024447d3f6841af59f9c5b3926947da5318ba71ca65a179ce875eaac2a6e61c6d90429921c4524ada572193a840fcc2061ae5db221bfb4cc72448b7e528161e7be9363be1449706ec7f8dc1d23448977628140a9b7792debbf0df95f1976fdab10e7b2a40f539bcbc1108bfa97c464106384d0622730d2357c22928aecf2007bfe2b4f42322d459baa820897a38d0a85816d56b754baadba967f851bb029b96721b4f799a34a37d125546764192ed60c4bf1755f5b65730eec94c9505f0f079cff90c27f1f3cae38611854a3b25cbae22076f4207478035c153e17741dec7eabd0091b2eaecb75ad9c1af156a2f6d1ed9bc1ab279770598a41ade39797353ba8d55487151022eb359961fe85e65e933acee45b6895d15553c97a5592c8be62e4ef4078606d57593691de484d70879e7f7d05ea2d5b467194b2330de36a94d3b321827f8880c5706b03745bba7e301abcbcbf8be1a46e4afa6c345fe735745c18b03a994b4a503ab5bdef56517a9e40f6297cf645f352a87481b0c43d6efa563ae1a11470b5eb0181daf0fb0e8bb5efb2ea12c549e6b59fd30e11803055cb7d442c04cf24a5e4712a9099fbb7a76ca83223888aaaf74bf338ed32579cd98e03ff61976b6f5554aac8eb9c448a016aeb6bf57ec500401dfd9e73fd2f560190179219e29f335e60cb356fb0e83f6ed5233a663eff4b7bdbad514a1ff1dc2cdbf9ccb97be31a63a282e01656b7b0777ab1f37d0e3c50e2ee77c0c1a90b2871958f0981b21fb323eb28a4eb3725a20e9210109dfd162a4b443ccaa17ec8cf26a8dd705e2b6a2bfcec3f9736f1be0dafe9530bc532fb490b38884d214e745fed879fd2d53b65dbe0785b1b37e8d47b57e993a0f15673a2a1595d650ef7646a2d9d2db7252a1b033a7a544ab1cfb3ca1de6eaba4cb33b7d88432c9e3576898b99c00c613c17c379ba53cd3d873ca8df93ea439937ba96d526453301fd58f67760ea52b3e3d70d383ce3c99909ba3d777950098e1ed07ebb4fd3151756d2f8f4ca58aba160feb76a756fa7e02914046e2338499f8a1220e7efd9277182064b2040402b16131dd368f76923a861b38a47ff78d8648ac2320c76b70f731454f2bcf66e22a9c5c0f6af62633427e852caacbffc40bbf5186941ae20f9f4cb727edd40bd7bd6480ea1f2626661fb85da2976023b1f774744231d686bbcda09e27028a9089647b828ef37fd4e5cbf70a193022962e2bbf5ba10471c4cad19451aeb22e39325842d5ec51a733095eb82cd0539c1a7a11dd77cfa7af74b804d5f4fe5bd910fa9985cfd98dddad63adcfdfcb9d22c775b56e45d13fb947f8e34757bab10cc64e6e9f5adbbffc327e7ec175335ace0582568ce54b64d648531dc83a5ab4b3987dec4e71de2145a18f9333d8087f1c60dace359590f8e216cd2706b6d112ce29a5e564c345e9c21a54856a62c489604cc040e33c756c678e1d999caf3d85795a9016de1f98b26c892854c0a312e542951820a99abfb9a211499863c722d0f596d05aab73055dfa4e82e9a0cd9b62d7b018b8559454bd15f12a98f3cd2b9c637f916dcd9b4ae1548c1b2834c16223b6223aea3977b8f4c8c26171770611e2949f317698867448314d284f01dd93f64d76aacd2d123eb73629563bcd071075bf1f91fe88296714814463bea0dfb54a8d9006536524114752203c879f8e44995671cd38ea64153203305b88e83fac8251cfe72f31ca90a16086a3a89e23a0ab24852d2d4d091aa2e7d0ffccfe74cbfdaed46c0a71ae5b4b6765a838ae5a6509e131f6f7cbd52b1613100e2be90134cf81f4c76a9be721dd9154631b846475f9fc075f0e249d9e5c5982119d4527b66fb2f2085b4c770cbaff03256a2101c954ef70d67a49d84413590c56da44deaf98325fcc4a4b9c4a41c374182e1764e417b049e2daae5df9f610fda54255e784a08903b9f2d39a4ce7ca8142d633eb98851f7312a030f1b9461a04041ed203eb1bf7c14dfc6da1b0ed7e406250af56d0377835ca55cd76b765c69aa4e535f2393863097563e82296236414dd36c3a295d532019a88a5228e4bc12a7c2615402d502f114e5a3380871edbcb0c4865da95ce4b294d57f751b74c730cbdd57afc0d175b3923415dc6983e0f2061b38495fc8a9575cef8480c84843f947a7e95a0b5ceb8ca2bcbae51df7378b575f2b2c4bc85c9db27ce85657aab445222bf15ac224a3591d8e889e545dd427c60520a1324dd6873506b6ff228c536822522582d8c1cb5a2157f63288d5c799c2ef3a2a4b59f8c8a727207c101122f037149ff84d48a1654cb771d73790048ff0f7eb874d7e451d226fe90b94ee620a98b032a9a3f480d7359977c010f4577de92538889af1fd2b0a99d31fabb51f8ca288a0806e52d469701d33916e05863351143d550629f36946638fcff0c53c41b80846507453e61fc47acaf6c213b0e7a94df3850e34240ca583d7db7dccddeb8256d2dd1c3f2284fee195800df2649e484ee887e4baacf8f57cb2c463ec98b64a6866ca03f02dd16b041345d51dd4b03655a60af37f5ac763a54162e203aad92151c82d51085d5a4d4227c76a6a0e933828264f894a66b6c8833cb4e3c8e4ea52e943330d5c7f23611e38871f4eb88cb66915ff00d5ac2ca0a07cdeb9a9dc95975fdaf229d1cd1d5361e4ea870937a7254caf1ebdf7e729875b03f0e01ecdb9ae38518a57d3de962957743e693e20a7bcc96f44695128927cb01cb9457f9ac1bc620b43ef16defbb0d1c0d21077af8d527a22efe03b97ee4ec8c9436eb764280895260a4e558438787cc973434f074d6ca24d89b998e4216cd00d80bcb2dc420764dc90982b00e43a3baa01021079d1b0f1647568391cb6f09d355fd225ae5bb95f896a0e8f998564fea787473c8198944c2156ca7123f0125a36618dd14975df8b4b391cd57489b4d8327602d4b0e744235d474b452ae76e7c1917551a279e23246809a5a5c57380053cb71f6375949386a29588a05188529bc675609398c9a52d2beb2cd1efc2365e65c5b96c305da8c1fa57c02dac139638f0366a1b20862ac5b1010000b80bbe4b6ca03d0bbe88f21d02c91c764d21362be162daecc9b678827037e5b19f54d56881d0facacd0311166a1dc99e48aaf4acc0102dd931860f0219ad9d51b8cae833b28cc98bd1596f54d8acd15294f22e76ee8bb236f8d97a3731cf179946d6e0c64cf87d17521073cc60c0cabe572f3eca74d1ddfaae9f02a177adf3220e9e02da47ab6ffe4c50e68eecaeacac156b9c5297f3f4264dae0cb466f973fcba540738fb64ac246a3671a204e001a9f55995798df0aa0e0c4b6ef8f9d0931f405f066a464a4dbb274d96ffc1a444e8decae24a12d8ef1721d887b4a72976c7cd25a18a40a6c83e1eecc37d97fff7834ba095cb94d3c182ac777960f24754ca6548d133b0a7eb76532b0c6315df6bb41622e8421972343ec5f32190f7eadad70aba5cd9f922ac227df17c5dbe84983f413e928b438a52e66ba56d5960e4671eac7750e9e955291870eb301c40a4eefddcd3b9fd552d591637f515f2d46e122b00864629001172e26e4e414f291bac84d95386c86ddc2d52f336c4b505b0a05626be0eb28648e6c586e0a3129123ac0fa34961b975708a2cb5fc2fac0aed6fe9a66f24b028c3b3f100a150247bb480df385657e657653d1f550fe7d5a63b94f0961134827f83afa13645ad4a252757ae4e1081c07024df8f674e11bcb0d65f7c24b81cf35f5d1db6381ce6506d396d94e35f33f4dec3e6ff42191865591451ae470d49aa3ac680e2552a4e7264e112663fb0070eb3fd858b9296e76baedaf1c0d19550c80507f7359cb1ca00631326ccd603f7d651b876a9d8c11f3a24d2f3cc608b57b2e231cb508d9fefff7926eb2cb3278d1cd6adfea98d22742bf3d791adb6037bcee1b06955b9095c270adea26a7e4323cb16fa4adce7c6b080ab44cef0f31dc660995cc1fdf50abd195b3e9b3c57e8e602ab8b62be98c79570e59862798adcd25b49dfe431ac7d5da9e4164a6be6c007d2a2bdceb6e5166b922c28161a173099122860349ce669758164586ec1dd528c48512e25fe90f2a45c206ce355563c86cc3d985c5b35bbb93132238b4e297a15de4a6ec0623c75b53b7dad6b10f1d6d793d315230044547a6b96f9c3eaab5f665110ed56557cc6f5770ae8fadce1148806ae22d47249360428721dd43acf27393a97f105d7df35d97f025e440561c9324721aa53ce20f1f653c0c59c2651a330de1b278063a007b42dc53a513faa332813351e6c8c5097286e97d97878ba653daa3482b081fd6973b717fb7a917e0106fcb986bff49d147376ff34e695fca7d83ebd3ba643cd21f2211600376474c2884d59936d2ba132a59a8ff22ca787a2aafcc9152aba0bf294912c7a86ad1ba6dd92ef97061b86ad55e152c57a8e2c9db30792b3865c2ce81858a747ede2fdd10ebdd1d3618890f3683270e11426f877339513d4551c63e9c3a639a7ba67a8a38b654d6370f414372daa983708445e45d16c4a48fe45e7de387ad2200f4fb036c56a3534aad42aba1ad433a3a75bd22c9cd1b3a0603c49373142ef2918aaf5d4d93803e189467592157ca21cc479d5e2c6dc51bfb2032270b69a41a24d77c61776eb53359d1c8ac78b4394211eabad09e97b878dcde4f82edbf66c262da352f6b543db74ff66b630c12322042337fbaeffbc2f5d13e67580797955245071fc5d18a82d3bad523a6ecf61892c78bc0108d8ec3e90f957ed6fda4f29bb9d8a7b62a0cbc588abcb577f46ca5ed919ccbf869d3258dbcd2c5bc04ec6776b3e9480fb6b13a5f96ff1766632b873c40b53ac61f6345d9f81982bd66843d03a9788a062b95776e632cf988221a70436887e588e8e504ec6bcc93799395b1b3d106207ccf38da73cd326f2a5d238139d9641b2d8dfb7cfd6be14dc0cfa3b0d05bb8f6e799764abcfe00c3f379728e680ef57836dce637fd2ff743046ef7e2788b252dc083acb19903a699427880c35a15bc8e90399f5fa839d423505a428271aa5a28c017dfc38516f99e19382db1a836a749df7c565e61e2ae010cd8051f27762587ad5087e25a31df7495eb9cfd5d955b59575bc088771ea436d91683abeb54d4c950ac3ef3ae7d1e7abdb6856d8f9544f5c23799ad6aafa2ad120cb0f41ec968b543ef6e048395815cf34b4d22e997b9abd04899de2fc3dec230540c1fca02d4536624d210e3b9f13c35374257486b7fb0c3c0ee73824a68cc0e46e6980b0b7b65e1861caea4095291841884603ef77eb713e8049bedb6a89e6be19c612184d9d9d26cd567be597ba0914bb63eba05ec891f34fe52a765c26eb56d57e9f4d023142fa62a7d5eeb5c7bdb07544478e6343fbd6a93c9f253050e58869455042ab43bc3803951b7dd01a988cbeb52801d7ecd29a566236ba812b302a11b767dd61d7ee87adeef4726b556a225a87d0ec3c549b05ad26bf97dc4cd70f3b9b84e527a34aa852d285ce66ce18de74def5f439cb7e14302a0533fb9af399b1de261fcc29edaef9b3bf2ea539552e5f810b439c1dfd6f783ff2bbc0d537260f5cbf44b857777f7c1d4e9c3a37f51d938134004b8d72e40b5af3eba8e59fe4c6958a1c8f2a72d5eb50a812240640712a0665d6ff7a1d03c3e3ddf1d0715b71f2eb369490306016411b2ac427dbdbc05dcbc9fb18a438da2fbbd96fa28bae7ede88d8339d1eada650fb6e9d1262af5ca336d94186aea2c0d9eab386d93a254754b25363bcf31605a55c31784841007454879777b098112697459791e487d5993358dbf052bdffa1eef6c053656da30978470259ef64babb868e02b73af5296004c2ec864f1e5a88a19ee943252aaa8be864c2800041dcc4b114c0fd3df47e35fe373f953a2680e1cec35dbab0adc1bbd511ec1743033345214cf30feb978aaf868fc2df8f450a002b15191d52e48794145a0001e45f6a43a749456df8fb5240ce014f21c65d691f35379123994ef3680708c4f9740257b6899a53c7f60624164acdb0490172a50eceaa1f6117208282e0edbb0648f65e3d99785007182a9b9e978bb122b54097b1246b9c257c5c62250fbc298d2ed2e76ed9bd26cfea2fed1f38dd608e0621098a06a618f00ebd64ad7a1af5c35a255a51f04ed1fb1806d5c22c67262d80a909c57ecf1f053584a8305e11f263d32fed5d4e6c3dd9c38e4dde6c42fa65687614b988f4003984447c50fb17c03d4e16aeafd70aced71f7a99e3dc5d7f2d814d7f3da3241f778b8292cbf2a7ba9a8984320d27274301679171067b2a2ad5ac85f31fc869213aa07d3224298b0cf45197d83388dbd2789a4724f96a2285e68ffce505a37593d0024f0edad1508d9ba953e2a612920babc2fb8d2610cf2778f5e1f76930666c02b253d1eb37faf4aded96d8dedb10a1bea2b98398468137a5576f12d5870aa6e606385e824376c05dbf404addabf5388ec68187b69cab596fd60a27ad4864383414d6e36b0059cba29bd3ec4c2937f3e9a4983d3182c7738a2634148636ea9e35834d43809796af294a66b049d727b2fefb1f9a403f7eb920d8124bd140b2b3d296431845a8664c7a8caf6042b2f3b224e27d9017bb151d3f802d735f98656db131a101a95eb42f0e0274db3502aea4ea1d5a0f94f2319699090839cba57dc9e9b4021920b9f1fdf4d11abdca02a661b874822b15639f0d3dbcc51ffdc0990bdd7520445399fa32bca54144298b0d79408a54098e55ce52f43ad6ba41d2c47d982b6cbfbb4eae076ce6be360b26e729385e38b432372c183752e3ffbcadb29d3495c0afb9ba03afb81b5d9b26f7386b6eb37218664eece7c5c633cdd99ad2991dfe6547e7f6c3cb395af0a3e0c5d9ede53705e750f6e211db5737d4ae1fcec58e9e3e40b0153e124d542eed7c6dd362e9893bb3c0ce4a67d2288ac73a54a8a763ab11f8a3402344bfe52c254fae73aabfdba1979189a57caa398a748ba67c274559dc3a4e99ea237aef0dbe2ea38ad299abe3b877e597321b326a8940cc1a376bcc2a3f880370a769e0828abfcd6dd8b758d7b09143b41b337554bf6bbb038daccfb99c6504af9256925464c600e27b06c4c36821203ce0ffb412a0a9a7361c1d2dba80c9d174e06d0bd5d880bc94d47d6ff223d28c63d0aedfcebf19c4fbf8dfa0f75816eb5226dcc695a9e9ee257c10138f4c89f40ead4a88179118d45f4a9fb81da854fbb8b8152ed5361d64695c1c725ac70f97dee92ef917281cb29bc61f5f849dc6ab822c36e31b9e9ef881059e7dfffaf54b5db6de5172aaba605575b19e2781ab76eacd51d7f05a6179bb82e4afe8c7485625fc1a6826d19c39dcd62658f040910760130ccd300e29faf783086ea323ba826e0c469663db27db8d106c0fd57fe657cbc184db5f72fd0f9e4f66f66e0c6f9eb74ece9ff14daa11d528e3fe6d3a56cd2394f3977a19db5b5ecc9b2efeb8d9991f2fa6e367e90488123ab3ad1a2433eac7c9b89425e6747da2f52df7bbd8d4a96136a969bb9809177d799ea0e486dadd841427f3b0763b4873af9d53ea0c667c16753169802b075591ce8fef017368c041ff6a0c5857e03ec2e5d655e45a23167f596c7e947cfe66a2fc42ed288b00dd4ea53240cc75adebf5698b223af456858ce4422e1ac06a4e7fa2a72b3b90af1e46a0b386b556c45ce852dbf7c2730e6c9324660fc87acc65f960f4378f620c68ce5c0a677d2d231838c8e046ad4d9cdecad373aa387ab9e0d33b46e18919048e771f460d802db57ee4600d0ccd432284a57993f468631da1be3dd6944eb6fcde78c48769c7158d0f135356d32b904d71e44d800a67cb13762d164b2a72487df588064908a8fb74eed753117a81ba91d84aaf1c9c520d1a3636cea86814946290790ce92aa4f38146259c01d21247c5a5b80d3d451a77680655a5c87d48485c8460202bc5363ad4525afd397d8f104699c29d3cd5fa3b713b9f08527e595ceabbadd028741de26c858e32485783ffa0fa2ade7f9913d9bce46275f3020d9c7b4c74a80cf1ea0412d588074bfd5c3d07fa4f2e0ad9c1b47c2382d8e8e19ef288bb53a7657307dce8a57eabf28b64c2c43ab16272804c6980032600f0a9d2ae55f89dc66294b0c24fcbf08076ad8c25872ec3664319a0c0144bc8520e49603b25abeef1dd8a6513d7646c84ca5ee55bd5afacd0e80a3bd1689fb992cbeec1aff8b189819a2f46a70733ac8112589979e36136c9bb50cfff15db34c000a6d713077919290b8bc18008c5743d936c811ab272821a4cb8b6f0791c65827fe5c2e0a4c1fef6ae21ebce56fc99e28efc645dc240f6108b792a3b1c8256118cca6090597bb10ffbca34e3fa05244dc495e136274268cb4299fede5a2ea749f6176dff36f686481739013d12a8d68aaa48928bc8b658d3ea6f88da89a7fb6169da80b9ee978a27faa083d304a4cba24abb523c3376c09f6380b100fcba8b72d2b35daffeed5a890763d7b0d8f5224b54d0361f6744df1f80aeef7f5f96a93603b3312e2d9bd1b6e08e04943f02c1595d43e3fb7d37f2d77f48a14479264fa670672972cafb9a508f91a648fe90bc65744fe40d01ada468b32936c8006ed618472304fb6c01306cc88b801a62d595e545ae03ce8042e36c4e8c50d90f8c6a27d716f9878e1ca66f4058c017f0254aed1f99e9041fa3a5155d12145d73330f23d4980744c6cbe8184e94b9757fe66642956252b3a6671d072765989ca6467d83a11d535808ec01fa134ddbb2a5acc3599ba610e1afbfd49ab73a539ca68e9da9c9279070ac5d3a5576dd4b4e03ed6d58c3cece2b6d19c5c957783c1d1a38f6d7ff141ce4e434337f39be5b2e1edeba35cb09294e62fcb2ec14d4454eb35656e961da84abe3e9a100340591f4fc3a0f4ed1f24e7c3c31b4605686c237539c79ccfa5fcb48960e9e78f853ab333a5c2f78a9a209a61af22d6c66678ce124fc99a9f13448661b1b2c047802c578b4a2f5cf1ef8babd4721b0ad750d1519dc1f9a005551243d4b486164c2d2b3847e36bed57997f5982977949c7b749852f62c6520c22cd6d5c0aec97eb2ec6469cad54af052283acfbb660e2d87c86eae80f49f4eb23545932844e5f30b3b8ee289d335f8bbc6c44d0a6c800c7fbfb5bdd6a3d9ad8e31be213ec7ba4ca0c0549b0eba9df081302b17e466bd39ccbebcb7a9f3d8dae0b94d389607d1c500fa76557c8454289267a743119948c6b31f029e3774c5bad8405e02fcd8d29f537b5da9bf196056574bb755995b35d97e3a6ae54c47e6b041e1613f413bacef7b701276f2928becaace6ce65d77e3348412470ec3d8682317f8973c344fac450148723ffe4eb47b6cb5a96ec61411bd6569acefe8161f3ce7784f4c5689c8d10785f3af76524c44e5ddaa78035b69a0aafc6b52e75450fd072331d3a1cf48eaf0904e3641c93c8b7cead4a0b7efc1b3c4af20528d7490780070daca4ce56d51d534377c90488e19e0f3ea73b1103fe7808980bfe4501d0129c41d9ec00f4b225f113152828aba27f03a6587013e818e6422c1d3f199581cdfb658c6bdfd56a01c39705c2abd7460a17fc471ddf7a259a712cfd105b3e1b174c1a6b9c56159b97aa6e1164bbcd1d4176001a65cb7e2cc3c840b92c82a166479cd147a81ace657b2c50742fa9be129a70a82960f74c502423095cbd4f5199d38becfb452c9434fa4d7e66999966085c9aeea55bcd867901fdd75b768c21e4d2bb9ab79f633779358133f7ec8d6d08c76c9fb90986a24b327630210ce9b0bfbdd0432f83ec2106624f236c5dfe0dc4ffb0eb1a6915d482e385055269752f0f7577c9016bd4372a7b6a538d7ff5d4404da24026aec52210bb5e9bb2f48ea7f91837db433278e06e3445855ec85b800c04468a80bda91248c435f97e25f6e46213d873a30fcf02492d8c984b3fce6e37e93a40ab7848ca02862ab6c0edff796580b39057b0a46fd788caa91648aea312374006d1691d53987600c0d3c5ec93199d16e9ed1ad1cc0ef20911c7e7a1ac60e584d4759065b1092d0945fcf6c4f038c3bea9a691bb02dac9c5adab701254f4826f323570d843c66f4c0d9c2e6c52a85ff584e1ef378697a4aec79dd36634398872452a0bab219642ad25886d5aef975518978962ecede56941b123026c297b686929fa64b060014a72f1e810562e84d86f64ddb425b6d7e90f9a0ca06ae85e49bbe09bd532ef692fd54d7b331d9290b1b6fa78a6aa70c8b304afdf9efced10175aa48f1623b2c4c01c6962f77e2840a1461bae58241614fe51f685b9444db6ec3ba19c1fe071bd2811a5d72a70f4fe4c461455a11dd4626375f48f09f04bb86c5be12893e5599728d4c5f6c2a492ec75c2f138de5eadb182cdead9317c977d1a7516cc7243c2a3f8fb68b100e6d9702b6b0bb6cab010b9f02668dae0b615b9854e9e1bc6fd54e0297abd964a0c674890a6ad7acbaab3a81c39a611c9446b15b60ee43176b88852b8908649baa9cf6acc02ae0096ccb2663d3e0a9b273757bcd8b47dc8c8d79cbf1d5417ce8e0332fbc8140f3a5a50f663b1caeb0512c0972ec203fcaf4b6565ea2fe09de03beeb6f055261a48582b13db842f35cfb4c18f51ee882623a4d45f1e0921fa5ed27cc9f910f462142801d6e80a5823d8ea8b56ff74bd08e7f7d5ed664c9be89fdd5c0ad8e3a2b13819f4159b239497758e428dd1843c5162c3285b11b514315292d8ee629fa250a2f1bab458b01db2297f954588b0f7f96f5cf57966550e6c4dc5f146a486d1f0562cafe3424a6c7e31f9f75abe545d324ede3d24c94902e6b500bccb8d5d426e26c7e26b4a4549414bf78e1888586af8bdd36c91e66e2be6d849a958889707d3fa05c07b28d804e8b1eada13fe7a907d3f99ac5b88d75dbf506e579671fd7e309172506e3f0a213efc3f4bc484dd745fbc78bfa224ca00cc2150b6500207079f245278aa25a7433c93ce05a2ad37bc1b498b3a5e59da8907988f991e76204684c108ce3130c9ca43f2d2ebd516a6b1b4788b034a6ec1a7c5a0b8462740e162eca85f535db3f04021a4b74ac30f280ebb74ec1725fc12a9d5db141523696a687403a8196d62aed4fd61f49e04be1e90a8ed70e49e448879ae2cb575e09e39be926d023043b0f3e72d53db720fe6114686cfa7a35bfef47d282eb61a175c72cf9f1a48c34803d1a220fe70b6b191c849635e3386873d22bc3bcd7f7f9351f1ca227b710a4b089dba0ea317d8285967a7ad44aa80f359f126881e548d180d619cd3dd333d5c167eda8bfa3b8aab7a18cf688c969cf38e002c3790a1f96c3d48acf19bd0b3d23f15fc6316d40afb429edfd519b49deedc5a57b694cb05f13a211df54666542237a70d15768fd9f0e3bc3965e3ab48bbc69eaf02eec0ad1c85015ccbc30e900f232852e2ea6781a73728af6ab6724ee9eca973e239af0687fc9bc561a4dbbf24f01ce229e6b5b11a6e5c3f072acb5146b38769753425a0dcf694bbcc40e953e211b5a3727d895b3832fcef353a9570a9304eff9368550b6cf2995d8dc8c4dbce235326cad8f0dc34b6df2225a015e9b155fb6f01d54c4f42089f75ad5f77681b5b24088c6254e2c7468b879c222acd75c5d29f09150fd17ca0e8049758c5b8ffbd9c7faf087a563bcfe81092b0985887ab69f2942bbe1f8ae67c0845075350a8205f736bd442afae30ea0a7b3d4f8d35756d5bac73e235a0ba4a0a00f20b432263a1ce86eda7c1dec72edfc2d06aac81a8128c8bdb051eee4333a66dfb329ce0358a61efe764c06e4537be1b195db9df48380c8da3bed6cb2f9fc7379a739add4c2ea430f1989dd4204022f1211a352f414b6b7b72b831609f48997d0c4dc3bd3527bc61f5675b268be5ce3922e44f3db41195de0717feb864987ef091fd0827d23a72e61357e44bdd374d220b5474e13431374c335c9d66ff1f585d035affa9d8ddb3100ddfb85f5f03310219864a232c0f11cd86634428e1c9689d178c8b87f330d3ff1540a41a66d32163f193c98fa5d5738ea7ae22791ca801aea6376c1bd8c1fb3259ed47ce4ccc1c18a003e13fb24b99b1e4d6622c53e78cec3280f6fe3e9eb4c3f407d68ba04c6b7ac122c007b6ee8c4e7a81e6fc5cfdf27c46d3246e89c2d4ef7fcdfa7d8c9a6740a385596b4653e33a193c9793adaf994ce0237cf4780ba8f6a1f5312bfa2f42140d6af1eb57c77bd83c7c332bdcb8b74ca1677138fec071b57811f53ab3d2b207b551914c2e470bc9cca6338d66e3e9227b34952eedadaf3a57c46f6ee5c363a7de94f3996ee140e893e5f92e59b975cd5f835f544bd1f9f8b10d894c1e38908d7c73c531588bd2ef5a06a58dfe9863a3034b5d1c61274c86ba0916463d5ef23a52c558d15827aa3ec69c39fbb6036e6b58b4b3f0770b4915770b5d589795e3e01626c5e56330a1fd648990a9f7f25f49e3094ae50882bdef3c123ffe5601e84bc329912db4dc1f87a911964d224d6865bf8f0fcc1a6beb89f1a687d120f054bb42c991b7752a95a77968b4f9c44f86752329ce0c4e88249bfd4ec54d2a4ad977ad713a567aff3295f557ae86c9c587317028b6cd0e222532d5b33da410aca0fb3e541d84ff9c71e8185831577d9ec5da4c5d997dc9c4d7697efb99dffafccbb227ddc19ffca9e3f391e86c6313441ed494cb509f717215d7b7746a1d59ee0805007cec228b3be3a654a05b254081fd5564d63cda39f44998252caf445edf67fa7730436354d3fd2ede029c96273840861e27e0776b92fb0b8bedc4b61218c6b0ce63f6bf0c8aaad11d47ba9bf516891adffd3b81738709b77070f10b8320fa2494a201dc5da7397d7859539f7c1657ac8a2ac436af7c315309a9668681a70d571a9485c3d09295942ea54705a2f9527f274edd27adbf4d0650ba02a4d243b9f6e42634753e15d63ac1666666c88b5ba837760f7aaed3ad91b3b0f567e9cc2cde9920ab002e13e02919715b92371026b055da213bb012104cf97618907b3eb86dccd583c30ada521b18a56ccad3aab628ec93c75b154ece00c16cdb03ae54120e602563255b51b934e0661f7c094a479825f28dd74ca421d57d39f9315f79dd0b785a1ec8845d85ff3b1b8394591c5f697b4c377e05f86518566e81206e68a2143215bd06e935ff03246d232bf1998d8c6ed130209acbb70e60461e0d4a2ea72dd5df52464cef319ac643af355953805d3400f312637e835dab4046fb8e8e43e21c4696029b5b34a0d09fea2c8e720a19f44d659ee8596e0add8b7c157a9453324624190d20617d244d8e987af87b8c152b02923520342a48395b7b4763b5a961605a9bc5137317e71bc87ea4f2762a830897ba2bd56894ef351965a01198c588cbbe90f34d949625144440b6ce200d13c554fd90d0441b42cefda8e42de1a9b6e058e7417f695400b1c1054009331d754f3d9b2fb9868e28a012eac9a92ae0ea62ede3d1a9c109268857803cfc312cae5671a1ab2a226705fd239bba5a3630edca5b65295f72b0c6701ccec38cf7b1750df221eea416492d1afeeef6d172c21276eccc186d35fa42fbe58496f189574dbef589c15bcaa9e02aefed29f459b57d256446c3ea0dcef267301b3b0808a3fb04343b6a3e0a1032a2ce26c7a4244a78f744062e7c37537d43be30fd9b74f5dc3eae86019cea174ac559ba1d1af562ce35973ec9b5fd9ddf89400ec92e368e2c5e8200f9b8ff2edb0103be85d869e597918ee1391421b811ffd38f5c6bceecc0ce31ec2df3acaaad46bc54102ed229d07dae25a41ee09008a4620c28cd232e0830034a8124aab872c2a7ae9350dae785ba71b49427e5620c2213319a1aa81da4b77c414b47479814af702a8498527b739e7053c7da9062beb7d76a8dac2c17ba8a62c544b627e8138540083a62da2a2342dfeb1dbc0d03dd82fa8a68ee0bbec1804499fd273f537d65e9a351b365c2e877c1eb8a78c9254104ba39b2692876a375ab282a05c6ba86531106326e735931b29d46bed6d2f4417067d610286bd311c3a32bc67987843575eef866ddb382a2d20ab29dc36f864c33e8699864218961eeb41d108d30750a2d279b15b0f0997fe8dfc78fcfcd91fc6027af1538ab2a822ca9e4d31411a3588c578530db7065a8ab3a2a415a4e170096b58c4edb29699a2cc50a744835cfd230635b2b29b8539c48023ed80fe1b559c07f4a9dc88e016c3db7edf919f985baa442309e0852987a629a117734a01f434037db24dc677d74723ab4c3ad32a8897594b44f20a2682993fa81a4f7a195d89a44854447ead875edb038b3e3385aac1dc7f26125d336159919d968702e10c43bb15a207491155c0088773d4c653982a7ebc824c8863879959268d2e26af5b7dd27f21cf72424cc5c47288c1cabaf84fb9114392b1230d4bd50b8ba5f2767c9d5039dff8ad52c03a3813503028c38e86e9a3739a7e474b1207ac059bdf6ec8aa72a1f1834286523f5e8873d13d1f69c3d45222c19e23e57d13d63213256611d1cc143e1f5c274dcd4f8ce044474fbd586c4bb244b6b2a64f92ee011a1186f3ee43fdd284acb56ce821350b3796ac6d7036071e6bdc1950c60ae884b2b9fc9a3fb3b92c872c4ebe2474351c95a34b42c80d472555b6f997d0a5dfb28d85790be79a662c3e12fdbdd604a57486eec30f2e414e38d6d9b91ddd2e19919d02ec00b090fae9281601ce9251a8d0ad19055791f95acd70acc5a0d64957d3ab9debee6937a53b9db2f8193d91d049593baf279e5118f2b2140a9a56f72c701e94d42332243bd044389db6fa835104f093ebc0dfd6ed43a25f44650fa68f094b8c3930e081c25868ff020ae01e59d307d59e546803594ebc5e6b343f0916c1a1fa1e5f52ef4a70aa7ece221542bd8e23e051613d1c1bb19f22ab79ce14490863d760b1e58adc44fbbe05d71f7cc121795bbdab9b68cfa650ef5e90bdb7fc121232dc235f8a9358d8ea74d905d964113841aeed2af41e7a90aec5eb2ec879cdbfdfb1bfc3a2dfb8579a7491983985282ada5788ac64f92f1dfb138d1c490bfbda62039b2b20990eb63f1d7c7ce8b3287c3d09ff44733ca778a0f445dc5f55378d6c2dbe2ed825007e2a52d04a4c2488775ebbad4e495339c3fe88ae5b7ead8f4689fbfbffe17df0b0e1cbc71c4ec1a5290b624bdc9fc56190ba3fefcad5f3428961040a2be6479cb83f72faedd3ca9fee6d0ea3d6662797dc9fab85aa8e82ba7f72191c545a9d2e71c88076c19569fcb78a087c0c2692ce491db006b51d60c222e04f1a25d5aede7796dedf2c14fde55ab13acc698df155f267f04edf6b1eb7a3a891e1d3fb335dfe26d1271223e3c11721b217b7026a74d19325547090a77e564fcf22847fefbe6f2d69870b8aede33b6691b2fb23c451ac6ac04c5c2f93629ffdc6281ec42fc0560e7456dd688b75449b0fe7258e2788cd99c165a939afc22e9bd907bf77dc6cae49b5cde3b581b799c40137b0034c38b7f17b11d8945eedd402991b033327fdbe8cfc65aebc92993096759783cb54f89bfc0407bd41471bb81fcdec3aff361f81981428551d738ca4dca408245c0472f15ac39a6edef49c03675cd91a798127387bd2cba4d3566aad8ccf1aa29d6ec35fc092dc75cfaad8e47c4b44d26dfd93b0bd705ccf39ac4b6ee390f8af450ae9ae7f411e58204297ea1f6376717ec589d3fc4b4eab80e58e6f4247200167cdd2ed52c250d421d9a484a17d1f467d1f90b79c5bdf5a7b81b39d9d12877394e40a341cf5951ce83fb68b5b9e08fd5cef3c042003bd08ae2e0260896c8cd3b9e39759541b52f64255b6eac122b1245a9a750c6d80c4a9d7ba0096e826dd7f09c3ec039260ada4a96aa9cffda793b536d5fe2367d0fde7fc8b6bfb9fc3b1615cffd131ffd51cfedfbcbf7acf24c89bf23f7e2841ad24dd0fdce4149305fe8cefe4a1b634be6e175c17ab1ad1492aca7a0424afa0e54c1e89cf6c6d77cf6c5632717d90c4b78bfe1df56d52a13dc617cb75dd2ef832fbb1dd8c74872fd3d732dd8da7208d19e23b3900ea9a0f4bee9ce5fd87d3359e5ff903e08d172022a3c68cdb55e30c9ff613c63fd1c44ba4ef64ba9b08a80e06d518d70b3e215047cd3431b70664771d315282adcb6b6f8ad47fcbc6f991a922758ef2b0999ee5650ec9733ef71b737c3a8e6191b2045ef960f4b4427eda4425b7b40d1dd46eed6ed01bd2b867fe2375a49c8f980af08da064b8b563800f38ee20d7009f2ed991a8946d60e3500df065baa06c415392cea19df94fda685737e4cffc47acbd471be97a5200db9a8fcfdccafd7c5324347013e09335b518157763af92e5a1ca15411ab45706dfdfcd924fa5c9243e46724d65ed65d1db07ebf85958ce5c543f8641f208994e8bccaae1cbb443273717f4f41cc9946ac8720a0621e61631e1bbe20ad795a4438c88fc00d964fbe7d6b6c417ad6bb264fb37c4980016d8eeb6f68f54e28208668902705bba4aaaaaa31658009c116a7635f1838b0210eddf68c872184f5f3d10689999ec54f52ff30e5b0da8c421bc85256d143575d1122aa42219f59442593ed26c058956650ed03fa4f70647a0f7d530696c9772244c5e437ddbeda7e1e389ac642ad45cc16f6996f9ce1872ae8f9ce1b884571b6ee411a9d26e7eb1486b3e534dab945cca17089512ce8d983a61a3dee4569e731adcdf4712bbc3c105c2abf58699b954a50be9dbd50cea7cc53959ccd15a349fe4246229c3092195f8c3f39d7de75b7aab50fa534622ac08ffa09c5e478129aa8e4d60aeb524be9ec894d0171a8acf6a22f3afbdf253194af5077de7e9d1d095a14f0cd5c47e210db98b30930b07fa5cdd44c693714c86272d932de6a83a5debe558cc1a586f5069c51b893e7a13c9f7117daca8effc97de95ab77831dc1fe06064cebac933e0ba46635a9cf6ad0118ab71c5a38174d4bbf343165eead6b394a5f1a843c068d25238310026b85b339f47a274b09044ef394547ea217df2f8b904b6435eba4cc3aa9b34efa2c90caac660450b917e25a1273a1457125514752c4c6ce7b1780630c16e232accd12a9b34cfaac939e65a4932c8ab897865c06d4559e1ca0e93e8c68c477c0c6ecd5f06f55770a6cb7ebfe7d1d4998b8ac1232d9e3591f1b35bbeeba686b399094f1bc8fbeff185a673dcdb3d4aefe466a151bbf3a04bbb1194f1b505940aa022ab157d71aa1d62a92a8e3f5b2be1f06f508bea49efe29b39b7bd390ce06359c205c51bb29d2571012c06f2566cac770481e51e203cbcdb9c7e366bd2b0edc871d6978274232a7c8d6b4ab6a610cba6607f490b021d1b815b7fb32905379cf78ef6ec40897564724724726c7a988c012397b92f804c9cd92fffc3697d96c27730c38d62a193118be7949c54edf6f8e62ad6925bd8e50f8b13e965af8678f414305d363d1a52081ccaf124e4ca7eeed633fae89257c2586433a6d594a3025a321dc99588e427de7453aa8551875038c4ba8cc25bdf6c273eb9d07bb01754a3057e293c12badc3e2a8afcf009ae29b8cc4fce90c23396ff592b59be0a66fbce1c85b1d29e3b0e29185dfb538136b4fdf57f6b39e9e7df3083498873869398fea80fa5de037392adf7265bc6d7110ea3f5f5162af88916e68059d3a3ce87bd8d91ed127131ad38241c476fca22d938b4a6a8dfbf1a66cf52c5e54dcac46ea018655c0da35271f15f03040ada1f9d33885018d4ea9d0a7261ac52a9492c6ed87ba25ec3a330e8dbee91ce0f14ea5e557166cc1680a4db0126961be6bed1cc6bcd1e0a20f40e1e172b5a26d5c71234e956dd8e4856dabc21e1aba343111073e72fd68da028e5c345fecd4ef38a03f114488ab20e7c1e9bebc9fb154d4e90a740d97d43c280895e9f5a45764acc32cd9f0c815a32e360c37648d2cba35a9890c380fc5451e2a6c3682f73d8eed7e80a30f2f419026939996842bb58231b6ab38dc4cc850365e47f0101c824cdc997a3082cddf0fac633b2e22a4af47ff169e02b4c9d031596838cb50b53446a4233bb786f17729c6bc4217b9d8850cd983d07d5d8e0df8a78eb64c41f81892db386aa80a245b4630267ac83ead6f7b041d3fec9c9f297dc25e891b48e4bfdc496ef83f576188aefaa73f466311c28c3cabe2a7add6902f2e87ce25153dcc72bf64d1aae2d0ea913fc69122701f90563490f719fe084cbc48b0d6403ac83124490a0e18934fd9af431a0ec397f32edd5ebef26f0d5d82f4ba1dfd5299ff443e4198145db211ded9e8e4603cd4d2f22c2e3e7468d42f5d0ba9205bb2a13caa7c8533fc0f0971c628efb2dbcb615621a1fe9283a93285c93385c999acbe4ca2512fba7c3eef7b3f803db5a71e7cab9b6b20aa3f3ce962a57428972b3b1aef643aea97d0db15734c3ac7e23ba9f0c450ed60bfcf91a5f44da43cd101e36988174e773bf8c48c2fcd3b655ceb3166427e6be47309551652e0eb77708fa78c09c26b36204a0baf8d311bf58a0c18ddfa22349f7c8414c69dfd43bfb7a17f2b1464720d48e11ae432d789b1403b799533e13809c70ff3fd3b452cb132128b8245d3917579b0d8c592eea469757425c2b2066643152c19341f58ff707ac8930b55b975bc05b852d012dd59066e8f604bd0e39e4c62e196f705fc96a539ad145666fc8f4bb97453163424bf74c3dc565daeab7b05bc06500df0434152472f3019aad1da468fb2e61d9c04c3b5473a8ce0c2f2a72e8dc6aa72e35eb21b755e80e1435baa6a63bd6484ab64c30c684dfc6a48530529994eae31105174ba0d490aa6daad2c4048796cb48dc88a2cd284b488ca1d38c0a646cdb1496e3f928b756bc61fadac7ed395c50862b2ceb9201a5cff29dff124bf93f8cf58f338f946f29a9e97eb29c4a597ce5ee3166fc523f8bfe2215e600a6d6811396fe4b5a2fe7f0af6bad5317e8a133e7ab755111a6ad8966a6c620379990fe118d906455d3f1cf51e57c78870b018e4487e892b0250e4882c36134ecec204c9ac3d0782d47bfd9507a246056b6ccb9f6efba4b0d7dab96a29d085308b5723dda535a2d963a5ae5c408ee48865f3e427a79d9729fa5cbdd22c6fb9f2bf5bc699a63cc7bb53e0a1356881e2a6831dff3e749736e7c47016cd491027da761b2758ba9b9a7b98c5b766ea081998cd33fa3b199cb7caf347326f68ac5690db67332c8f64e34191369fddc6450c688a8fcc9b0bb173a09e3c073ee55bd9e86389a79571f81f74e0c25d9fff52ddcdc75415b0de9551b54f31fc6a5d215f7cfcbee9561be8486616121fe5792aad1e2b30ed782699deb45ce7dc77603799a7cbcdb636fd3e4a829a529b25171af485606e5251eece0864ec1929b0e802f7816bb92ec43a14e4001d5512c8c8c0ddad445ca2509fc1e73864edf98943157d5e925089b97649b2d7f39f51ec2997d65ec660e0901e5a73189a96834f1bc66ae8f0d2c3208d3aa088b6e14eedac9b5383b508b82cb4da41bb25782605ec4480ac2fa1031420ea1fc3af9eb3ee4787834fcbf682513193345a33a5520976dc8f45c26dceeec2c5882ad2c2cda8a73d85d8765ea8d99f20479ced1e2cfa4ef95ce0fc0cd49139e82c4c9530b0b81146a5123b7ac6d7917c5be3376c7a50d292631e4d2b5315189e44dd86ecee8fbd9137864f8df20c03abb774c7eaca29795a926c9ad6119d19ac939d81bcae9f9f446cec415c3ced0af31915908609f464d67241527933a71f908da954d6e96ac93c0851e68717be2805c775cc96be4a00cafefd8435f41341750206bdac54c05d7e795c0dba73eb6a811fe2919e9763fc084b6fa359c171f2a4d0157eb02fb7855743de09a13605926e99d0d6e734cfa1df503bb03c6d3aaa73647049bbcaac4b338fbbd836e0a7eae002864a8811e144ef9d91224a46e0e175b3bfdc400404ac04164377eb139b5584f9e99779918a3ca7c901533a16a304962b5322d5b3b85731ac9ff2a8a8f67d1ea3e12f61c7ca655fba42612c3138d1e6b6a0de778beb186b66c745dbf7f91c26907ba8b45d1dbd69b62810cc55614b0d437cc4c492e9e48081fd6b7739f716766983d58bac8f3892fa7aead7e5d20e3c56130279a33e0c4510649ac42662b3f1a12431c209a5faa9f718d6206c74e472a13492f593916d7f12659c102e5eb47cb77825652c766c5e06e8338208d3882baac9cedec0105bd8f5a7af65aca9d0d020d22785f4faeef208ed0961bf762b677883ebf76126768b647e461050bff19c5abf6332c43fc9e190ee6da4329b57eeee30bbde4f31c69d8f68914298800c8eeddc551b21026b165210eb46632760418216288d240a0a5aa33b9d102222bcf92c9a9a04cb80dade7485db4b4883a48f1fb212c587ce7cb6f05510433dcd5b3e273b97bb72b2c915ddc5ef3fd9599cd8f5a4ce16076a10103d3d11c34d90fb911248434a09e38b3a9efa3719eea9ffdc217f3dbd8be3c9056b9c37d38c113c175ee413ecfa87acb81ca2afe3bce5fd52aa4ee931ffef6be43614338c620ab8dd375f0cd76be7198bbd24a3240e5360c225c239c81c0769a898378e32fa4f95b3d79115031013c7d8e226a5613bf8248ca5b4d65801c9aceac4199e7baa740207516803af88fde55da075e271f98256b4dfe0ef4980db140ac47fa7a5b077f33aa812236a33d8965f8dd977612c2d6912ff42565158a6d7953b68fbfa982f4e2fefc7bc475ead4280d54867a1117df1d4f65e3ff37682529036774b7678e6ab74b61a268cf2c87c5527ef64a47e72f6e9559bec377059e5815d834559fc5622182a74d71e6796b5d733b612cc25052a850f1abe52d8e83034664a63dfcbd1935397f2d542345d1401533ef3078adb626917625a707a43e5b83ea54c62084586d5c8f8de6d35c2c09278e6a8c41e14c1b5ff7e56775abe3a20877831e720aae0646a2fc61101f9222c6bd6afa0fd208dd187843e510150745b7749dd401b2929f0d3a1adeb64acddaacc615e3db6b639bf267af55387a2ab121708fcf5d20c11d442242aa3a8b85b2bc844e4441e13e52488201702c582002960eea53dd082a066e0ef35c39db050c61670ebc5e008aefac79e03a5ed3b4a96a927648fb71bae388b114e66bda3319ff4609c12887db7c1ebaadabd13c0641f68e18f508704d10987b47cf50efd4ceadab3ca894d93598908a913c9aed1ee41f8a7d95f42eefa56f1b31d8ef42082896b4afc9c636db19cffeb0e7cb4b599bcb313880762a5fdecd3be955c53df17bfead45ef82d912907eee53d78c8bb07f2360232c680bacf73d61f9999f2da6883cdb75f06917883f58a82b83108289da8dddceb7400b13418579ab50bc1082737b06d1a645fb54b2d1042659d01f5f8c24a86e10e6a16c040043633df9635f585684eff53ce41945580be4605c8eae44591d2f3d790f43bf341c689a59135b307a24e941118af41bd7da5a7d6fce741d187da1c638474a16517e6efe03af9bb4969a935ef8f7404ee8f86f28fac05350e4e0335d1026804c881ca1f7c1180d0604ee67c82be2caaaf7e6ebd101bb01d5860045bbd76a809750c258693a720ae9e15bdeabf72fe8b1349767047e260742a3bd211ad12042b003d8e6fa401cc03e7a1008bcfe537f1c3767881a6be5cb4f83a7fffdf1e6b99d9c39d5388e9f3d001c178e896d3d205bc14d2a95b0ab1ce996c911cee94e37effa92a0b1f45078dd8e5c8737cdf0046b8c5c619a43e63f4f9aeb8072dabb5b72207ecc5ba478b09e21ad1802b66e525c52cdc42903be0da63a2df5203a478974ca79204c57affd7c0bb12c3925368bc3f103dba18a78f0593a31aa201944398859a94dbc01a770b6ac13cb0710e144b7be38ab118b9579ff31a624a25217c50fd83a1542d2ae6614b4ac8ba3a9b33f337cedf89efe5ef90d39af1591122ab2a42aaf33f611969bc96228d0e77341cdb6929d9208d37eb58543ded70906693d39510fffb355e17539eafd8d307a19b289c2f0127bc6db683e78d2ff2feb33e9b19eb22e1f31c1e4eafcde8a633c8254a2cbf155b9d1d16fce21a9cb0e2dbfa608128500cf3153d4d6a2fe60a2ec5408f345ac1fe50ade4326a1e2e3428461bc0be8981839f0f6fdda82bb4c5f53c0e0243290e5f18809a01527bcec62964ffb3b73e4aaccf0d98bfd602de990f324e577f059b2503efcc26cf87de817b4633ecd9189183235828d972c3f8a185694c702be81cb8451dd1bc9696abfc41cb151d318e2576d6f27f9d15aae3ceadceff49db1af2478f897000cb035611d33fa2cb9e8e4c21e527522d30163f21476c5c6d8403546172fb18077a3cc6cd533bb93e1c44891a0e42841a3613286e934381e003894c7f5aadb033a63400bce5bf6802e3a7ad830d206ddf04b508b3d64ed6adac699183c3b4f826dd9237a33929bb68ae9cb017116545c630d9bf44dd3aadb11a7a6bee93e71c92602b26030c9717320f559229b4e5a1d77da4ec025c92e0791d2577f3ba4a540676468987849961e739650478d4918c0ba9a5a6621e5209bbacdbe1f2a601730aa9ca7e836d67e9cef677d57fb60f8755e854850e13b52a1efbc339d7303825114fe4f86225621236b1bab09915ccccce9e148cf89e0fed81485108116c145d60b778791305a54f7157fa142295fb1cde6595f176599a121f4187feba9aa0bf6a4ac488ec99cb423d3f4dd4c93c515c556e8e5d13d9e70e7be4d141d495ed0c064ade69d41c3be93e0bcf583bb60a5e587de1612b8f12d78409e6a31dc19f513fa19ea2e3d83bd1f14f904eddb57654ae891c2a6c99a0c449c24034e72435aa00a811ff913471a27af6cedcd48b72593333ee810fdfeda48871831cacdde2a30d078e38cda4663194a08a8370f2b784ed5e6b77762f6a8e747a73fe4eda0b929fc9d198b9aac9932dfad049b9a09303bfe7fc9ad511583487cf03056aec9c65c1be9e12230195c488aa7e136f9fc792e4f3a856d043b93bc4abb51d620615c76c54ed257b5315db7bb7ef0fcffaa22f4c6f12cddc52b22814eacd41a9356a1f06cea7933661661c028821508a086b881e959cd7f2718b4fc98d4b4bd1a84ca4b34f2602977f3b9c14a3fc628bc52645bf3030b6fdd21ab2373ac1a6f695a942e842ba81ff97f91bc7c2fe859b06f3fc6348058d1e7ed48949029a3af0a8d05a517808be7adbce116a646f03898c5aa0870dda2c8e74138a4627ab11cc1077c7a829dd55f49c9afc6c628d9bfc1444bcc64e40590a15ad36e337ad32bd2737c983fbf7bfd7f9ddcad5d86f4c57115589bc6a0d1304a7d2e5874a37fe2880fa5513b32528c2d6ec1e85e96f7d3b4976346b1eff5dce512167734bfa287816cae1ff84bb4cc57314737e91efa6b1a59e31005128a748d294a8d9681ed84abe7e16a6be4e1fb90937c229bc0a2a054909aaa0d07c510806dfa6209b0a249c0d4bf4b5dc27a8c598d23611678ddbe9f721c144613bbd489987b5d074325ab510050ae97ccf0f650fe989ac6450f297dac56e2fd504484eed48fca223830e6dd072b7ab5f8a6930f25564e4a1f76bf17faf0925db29e8a02c55ebb0571ede40bffe3b80fea811b66e5c336cb27df4a0814e504b1a4866b5d1903519d5bae970b5e644888b39111813184a29f10f731225c1db405656d666c41259e2a40e744b712b73b6bfffb2530298de16916385f00c2f2aa548ae0900444aee08d46813bdcc9b213287f355275820d281e0071d369613fcd76542182f8d9a64d3c8f6c1156c4ff3a54048bcf4cfb007682d9ee1a527107f9d61a279e394edc206a220fd77b81830bec1ee2b90d667050bbbda7fba163f907e46435cd7314262e60a3ed7ecff43e5c81b34e336cc56937174e92247a98dfa88b94c98c0c58a0b435cb29e2a1f53d27e31e0ddba32b468563456c88c8bf32f44d661c22a6c00fa418f4323bc44662fac894bbde7b0a84d0609dc78c2544253c827038256c386fe9445bed05a76e240f247155f0acfe26e0a5af2dcb934bd0639bcfea2906035d391ff63d50af8e8c23a4523017d3a6f7c3fcf228b0d23b0c20d4269841869a194c41052e976e9a030f243bf07af8ecd539a44a023623fbda981af0f2037af8d0c914203c9d9d3425961dfd8891a8763c6bebffb58a633043189e8c9055e7eccb1de45184c0e733f18c628cb8e473cb6b3968a423b0979de17721ea891c7b026e04f6ad5b838ae706ee263b0f875e31e89f63b70a21564aa3d9d7c29ed15b39a1651c864e75d5643bb9831949b9c1c0a0f4071d61a2d92c4dfad6955d961220895b7908772710cfde37a8e82998cb67c614e516a64440eb198a61351f795a264c5046283f325dc02b5d8cab289ae0ef9bfe958c19ec849e7bd87851a74fd982ec93a41dc30a45a030cc92724f890265e5a498ae09d2eda27b8a64f8a1f332887da94a2d0356edcd7b2cf4d83895dcca3b21b60595f31fb563335029b4e08b69a601859f3fa4fb56325fe15ad8d5a0634ec31c3b26eac4302551217f88b2362338e80fa104dfc95ad544f6b91047a2504f41433f1d3f54c462e9aa1fde681c1dae29700c24861bb9f7781f812d98c3a11cffafe7fe802a27fce4cbd646e399d4febed6dae121322ce66f287ecf910d56d1d48cb59392113492118d6437a10fa9f15938d59719e00ec9938939be00b900d72af7c56f60cd0142234caf050376492497d1fd5dd2b532a7ca2973cf1832a661e8d99cb791a3782fb70cbf9c417b8f5c323fc5e613d0dff012cfa7939771b059be2c844777129d765381413d47cb55267d33d87b7da53405b9920fcd88328effe54b791b07deb2b4ddb52266009e49f50b7b7b50ac7a730e169bca0235983194961bbfbee83160c09c41737e2a0cc3ddfeea51c2f934d47c603d6424263633724a4fdd04a3c803a6b03df310f15a2db1df4cac362398039bca89e46addd8e093194332e6fe10162d178af781badad63dcc8c42687f37536c532e54a9d85a3c690c562cd885fa22348754c0172c5a82703fdb451611134f9ce2bdda81cabb6e4f6e1eee33550024fb420aa5c2bca4e7e9670b70835a6d9659459afb63a3c8376f014e210d3b8bfd790d9588721c0cbd0a0cb6308bcbac83a1028789970f77dbb847a1b600d66e7bb82567185f18ac179e4fa354fc8cc121f782d214a0d573f00276ec05a981940e87afbb255fc2c2688056a6e59b5b8fb0b1c977d31f31c1eeb8274f91fc97d2279687520913c041fe3130144b0419cea5537871c94f747234036b26ec7cd72f61737ab000732005764533494496766976ab0167eb94aa4b5ae1121fdc9d21da84075c43608a94958e7c7183284469031152f368bf2a1aa8edac4006e2580af31153cf560c561c18b19e70fa4aaca581d21e47289d234f0f7d555c287fcaf4e464c3a78a99d5749c7199e2452543b8ac0c1c4378f9f5b97cffea69e134086fa90d07da252b1b7bc25145db806b39e0e34e2bc643ab54bd077c14bcb7c6477da22315e6ac0d1ed865ad72f185c8f5387fc55290d32a30fef6f6c16f7a540ec7f05be91f5ad952f5ae82b47a8bd8b4000f2d5c8b81d2430106ea3a8e8d0c90c061bd9595a12f213dfd67ffe5399e02ef29bd13a7c9f9d3f031e2cecd12ae438b10ce98425f7d0d8e92c3c9a084d7a03c371ab948bd4f20327eef2b4c3af5057a1a16d36aaf08c1f6327a87f47b7216fe8a7d78ec99e93642903b9d66283a09c9c0f9b361af881bf476b30223f084067b9f4040b6d549c26f082fe6da66f6ed57cc8c732b640f354eb36dec019db33b1158eff626ce5976589abba1d66d47163f7769d945d24dca04fd610da162129cf9be0146ad1d677bf24902ab9a14396e5a1a14db3f21ce86802604fd3bd0d75c427d85035404ad8fe0d98f934f270b7a7289e22d54638dcf76aaac45ee505557d726ad3b76c78bd7b399dceedb09462b7c916ea928bb4bb460e426d18227c1cc76aab63da9c1e5b549caef208844398991bd8d5edcfc52f41a1c8e70093a05b291ff1bc613b5b21ac077512d50f05745e746b5c8914160b5839ea06108c68aaf90648a25744f7ad6ca4f018989f093e89c01cba26dd247033223b07c2746de74e000a66538f3273826b6eeddd5176a5885d03706eb546fb1af9099359ea63adaab73e9b635dda1e175a1be4aeb990dfd0c2bf1033d52f4b1b56000afb8c45d35e8c7b39187ded2e7d5f4a24181649b52337f472c6f6bdc6970a094d28ce533f1aa5b6b8cf65dc726c83a13c76f6cacd5013f378f85e0ea59d4f9ae06a19489afdadd617f2911b365b8ea5d0b6895226f1adf6213cb409491e5e85718642e5165d3d1b750394fc026a174e6b5a20563a4a076570341fc5adc89bf44be0778609e0750e2f281d5d8b17fc4d1724e07c27ded67f51efdcdc452d6aa9d11b9aeb4c60029883b83618359a5e4a0e1babe2544886ce3fdf57bc1941e3417f218dec4da4dc52ca94920cfd063a0690064de8d07461133b28b97c7b0b44f1c83e9b5be4ce8fb3b3f9f1026e3cc08d3b377237d6b8b1867a6c14843cf169fd9f5b3fd57d3f2c96e7fd6bdda7ea20f4be13dcf99088d7280de4c60961f7cdcf663627e759373b9a4119bcfb58d953e84339ca417be1a7ae10f42c83f0a7fc0b9fe14b875f10166c242aa5acc27ef47e0c9a22887748bcb183356902eba107557bf06d15ee1ea3478fde3fd0283fedc1f27313cbdd1763a0d95ccbddee1c396e324e3827b7f3919113d791111424587bb9f039f85bebc2676a6a32c364a689a9a98d2c2561b18205966425690b17d88b7150c249d8888fb888b9bf74188f7d61928de3e7e79e80c37f7034b4c262ee6e778f314ad9dcedee314629e59c51ca3967966594d25a334a6bada7d349d3b46d3b69dab66d28148a8686269542d1d0a452296b6d4d4d8d0c193532f8cad89863cec66663ee8646a441c39b69f0f3e59e6183802b343e6a410968dd6d3b8a83e5c15a23dbdf5da5d994f5c44d5b363393f2e7cc324a6b3d9d34ad296883106593ba2c1c376c8d0c56d00c086d6c6e6e68d0c0c151a96ad4d8826cd0bb5aad56a8d5a69d56abd56ab5ca28adf574d2b46d43a12aaaa28234b883b71ba8469db46ddb34aa034d6a071d76b05407549431656952517a7ce78edca6baddddce353266d8dca452a954152da5a536ee0d06716c9aad3de8ce2e2d705b068d7b8051a28278364d9433a375ab39a49c5cf827d7857f3abaf0b50d052d0dc5e1c287ad0b1f2ab930155bd6dfa282a0aa86f6605596caa038b09f3cb2a1810ac2b9c1c1c1b199210307a7c6e2e0e0a470685038383803a03989d12c73f70d34df628fb923bbb0a39007e2804ec4daa28c52ca3969eb66998db551592f946e4739aa9c57c5aa2bb9f1e7369fd2e08db6877361179f32b1da4699586ddb68cbc2df20d267b7a7d928139a4a7937da4ba178585b532363930121845906339841efca3843c68c1a3b2345839a3163c68c59a30b325d17d29c301a64245590d0f65a5022c1ebba132f33414eafebdf3c447b08216400646b63763307d96606e5cfcf20b77dfc6f4ef953bed0fc62f6f4b58cb31cbd3efcce8dd2db90ef7c309afc2fc60825c7f7aef5b34c46096df7d46729bf0ce5637e7d8aea917ded3ea7a8201aa950d6a1c658feecf98b3efcb397a81e718e712d534a7ef890f2d3cf987f7ee48cb98bd13b7b8fef3fe38c33088e448c7ca56d1f7fe8fef3f933dac197eedfc37bfa0c9231ca1899c490349b179e1efaa5f1473d7c6e98437b48d341e7a694514a2d089689a036ed5469367bd0bb838e4e518c3ad4054a14062a0258f1c3152af9718864998585414ece908b266408727ae940bb59623dfbfe23d685d34ba887268f800ac153c4ecdba350c7eb9ed3f3e3e89eed194593a2a1a1416d9c9c517ecc58b3eed319a59f752bed7f50415af7838addcdcb42af3daef69eb4cfb22cabaf655d09e23d754295eea85d46e98e6d151f5ef71b97753e9d4ba3c0f9810b1f5a4a575ee8e10a115c7438c28b1bcee480041427c6103346104f68d9a19300608318438cd1c5891322b4108399243a38a2c58b254380a200342869c122a9284c182df8f4131d98a1034c9e5431820ad80c54923891c40d4eb84861032462e000480e992396b644d1c50f41585992c3931c92f0a0883053b4c04fb4f0820e5c804552183b407183268488520506627080a28b104094c8a86189982db27cd9610c26867c40428b1f30214d29824b0b464157620883031337bc00ab22041c6071c24b0c8eb428b5c0e5a0c5d21925ad1d68783540cc91264b2c59a204950e4031a8f8024511931443305181645a55c0e045932d526831a5cc0fc0301206062c4d536c6062092d4e9a92b2b80204055bb8929ab47841268b25c058d244073249b6fce0450b1040220a2e9cc0e0926284940fbc60a506219cf8a0488c0eb0f0c20e8040c6891210454a0431c316275a944c21e2490b5e1ce9128595285d903811e5740518392c915285144c5aa8c93203a6239a6e60c428091d1bceb400092f6268628aaa8a0c8c7690841653ac409a80124b6a90028a274028e940991e9264e8220a0c5a4040a2258510649460e2c9145a80c02f37484aa206300c3186cb11253065a14453104a1019296a81025ea8fc40872e488eb6b4114353766045932e3a2c31c3951e7a30e50820a68811a28a8602ab488144113c8481050928f0210738064e74113c2c20c2054692483a42067eb802214069c11353c47085064f500a026b690d945adb61e09f5a1350ea0381f887a294114ad9235ea1a1c82660860fef6a07e4e9cbd7760f3f84fcccde7547879c4d302507812607e18e09aebf4320c931104449807af30b620a42e87dfeddfd29b8ce42ded9231ea147f81142d8314819a58c2f85a4bb3f170f37cb4adfa3e56a0fde8f5f725b7b11d2f6a26d2fdaf662ce8d9f13adec3846f70f5d2dd50f21cfe7ffb1ec76c4ce96407bffdcfd01f39b73cedf228a11f7660a6c19a5b55685f3826db21f73b14798cb9d62f93f08f312c914b1b6a76e8b5cfa1ae51b3fbad7ac6624dcd3a9d6e8ddad3fe6504bb9c85afbae73e905ae9370b3ae651408a3f49dfb6cae77df901bb58fdde79f6161f97277ed9e063b5f87ffa5bef99c7c3408d3e99dfe13a7f29de6ee69b02cda5e038baabe2197ff2372b9c8e52d29244931bad0cc8549518eee0e6db26a95753e24919ccbfe799ee779de3d9d4ebff149caface411963fc7863b78a3f7463c6cd21f75bc98f1f447567b7929d0f79e5cb8e487bf16ddab32e2b7d30b96fbb93c8f522d7e75761f9524aa1e73142af3ef4bc7aedbe22373e47a73657687e84b17e76fa8c426fbbf4a1e7c36f46b34a339ac92e4623b2f9d16f8db351754d0f1cc436696fc2b0a70e95c5c6ec2927d41917e3fc38e7f7c73bb995bc957b0b0d1ec0d218c37e56e74666e6b9e21fba2c0f3a51d7b927ee53ddcf7a69da7db493ddec7ea67febf8c841028217d7bb958f95ffd0fdf6688c6119e78afdbcc88b58f09df6c2427bfd37526c2c4a823962b0abec876e4af32de3563db2a79ffdd0d528fdd3d73f752ed0a75dd5563bfa669f75f0f2803bfad2da377b1d4dbf721be4e1378a31695d1ef00a05c9be3efddab9903df5209a75d0c6f943e28502c9e5ebc413662ebcf0664259b7ea91fd7c2923336a83397a7a72df109f59010beeecd144777e3627ccd193bb3a7a661d853cb3837747772bf9fcf0ea68bf503554792e99e206a420c4286364ca01fb945c07e5c64b3c5c1933c56eede9605d61e1045447edc19413ee76774f12a394d34599d81714a4cdda39a794534e39bd9b6df17160e36b9a860a9272e19c4f7bb0539e90b68d374883e61bc2d1c0951f83503c5217429e0883b4e97336d468be13dc9a3bbb2f0257d2c02efc4a4563eeeee625cced30429efe7ed6b0b0fd9aa37850d48eeef36e843cae61613f9ddbd03b1dc94de33bfc7a07214fff0d1c3bd13f5eef42c0676e77ab1df4c28f451e100d6a9172b7fb26a377b70473f7fb3b336c0e018b7e95ae2b3fef56d50ccb2a9ace9b017b4c80deab3413e2d55eeb3ef9f3564ae74b97b34eed427849f9f16ba8d88f7f66fe7c7a49a72fe6c1964a3d5f77c97d36f4db982be757833d3a3fd8ed53cfaff1c65d4fb53598e3a4d1a0ecc9d2a0b453ea6b8efafd2798e3f4fd14e6407d7f8539b4efb741f3db6b1415b4a5523490c75fb2f497b3e9db5f72df0935ff1de0f2ce8cffb8cb7ce976d97e3697bb97d1a934cbf17dfbf66d673988e2368e3b711fc7a81db272feb2464719e5b3f4085ff1882abd339aff72aece8db146fb527ea693135fd3ea56514151aab29ffd598c1cfb3d6eed5baae0306473e20121b68a949801163e8c076cdcdd9ddf9ddbdddd9da3bbbb3bb76fd12fef975296e9e216cc87e952724da942c5a5e41d4d244a9e1c2905d9acf8c10a20b62eacc862056161e14ce419cdb460a678430d666026259b04dc80058c4d7777fb773b53a1ea9e2111be629013b4e8eeee76c622e6b2a105312559c4508031228b94626be1ae1e024a0dee52d2a1aea24274e9eeee6eaf619a1071614ce9e6072b80e01ba22bbeb821bae20be6a5ff1f2a3cb542e2ff0a2f10d21d9450d215584a38c90592fcf06efba95e67cec99a936f803bfd4f583eb07460b194409e7e4d0afbf16b895fce2f4d88a6e2a5dab409b76e64d83f0b072bf9bc4bdfeb14f8a31f84e5d669af53a83ffdd42dddb8cea1c062b90f65d1d7b1b959f7a972ae4e0a5272eba690645530896e8c437bfd42dce79794b4d7a82e36a7bd6e8611c1bbbb7b5eff6ee77a582222a2c682480524487beddd90672bb2cb9c7a75cd374739fb895371429e58f99f8a4848f74426626d4cf4d10ae91e4eea22b602212c9222e03b84ad0071558e11a0a67f4fde3db1eee9c7f39dfed3332ae844f49efbf015b8d3df2cf829c3028237bbefb9b89dc5ed8f1e6bb9fdcecdf43909f2f4ab8a603feea2244abbdfb96b92faeeeeb32e54572c1ad4f96eb8b4d7a5779e3a4dd38e58bea7efd7d19133c85747c358ebe975bf9ab739635d98ae2b04041f4585fd4e309823e7cee9e27180cbf4bf1a16dcfe6fbaaee4c1badcad5e90a75f47db2eecb77a5d0110dd3ec1204fff094657afdb9f755b476fb886d0317835b08001c513aae1be789f6ba6fcb90c69fe32d34c46f6291ad476ea3efa513b835cf93bd8c6b75de584e27f7c2648ee07936090e1ccb9fe367bf82af7a10fff75bc1b9ca5be4386f3381c3f27b447c2f58ec5834c23e32f34c31eceb91aa3b8e3bcf0d169d9adbd1514af71a9fb90a945587e9c8c468e9babd33bfded5120bc4d25c2f2d72796bfba2c7f1d02b555212c7f0dc26ed589e5af4058fe9ae3547db0fc30873fbcb17bb6f63ae76a41d06eb67a64f96b139cadf660f92b0f35b66a6463ab4c565bdd2167ab3ad811360873e45cf85ace083934b1493ba39d21b20b686a2243c681a00ad5c4fa4e339056c66e808696e27ef0e5c2104d2851820738088104f4fd402ec66871928405ad2c8450809fdbfdb09ff6abfa593d8319bafb555d7417f1a5a3e001062666d8a2061fc610037740e48486288ed0024999207cf1c5005d344562990aa11ff6d37e55f7171f9bdee987913bfbc4c69e01a798b07f3ff6a274f979c97d60133330e2092c3bb8e20a28403c64430eb8a0414c0cc4d8a009889fbd704ca97b988ff83feff24a85226de4ca0f4940b41b02a2616435ce1eae7eac2083fdf888db6ec0b07f59701f38052c08318088410c51bc30e4a40a1549f84085135caa00e2ffe13e2c28a1c116464000634b0f260063c30c605f24516406886d775dd8be471888be91181c0044ff0803d5b7ab1fb45bc13f3d0482578506aadd0a76ab0ab8520f6a380344bf02f54f9d0a8250817eed56f0eb43a00ad02245982409430444bb15ec7e0041201dad3939713f7c879f722b70375c2cbb3a3e6a0f5504cb47979f55dd6777e05fa07d2010c33097bf4c2f68d0810f7ce017467011c289255a7400038210428690216ca2ac290ca03bc75787df10613f7aa9cab3d1d96c8efcfa7e1cd9a368eeee376e7bb7e30d11d63ec777eb1e086337ab93542226c951eaf8c11c23f364e61939b299316034a8f3c119258d9765e9f811e185d72577c31f06fbdd781d28a4f03a2a1fecdc26076f44a5204f47ce0ec17e291c3ff486fa31ba6773ba4761ca3846617224ee366ea7ed8731a7e8e3f4f13bf638554e75a9908cdbcbedc667f131d0a04ee568264f2f1b42bbe5f4a7eed371620e058d9919b523858a427b2da7c6ad66e74312e962ccb995fbffffab8aa7dfdca1c3c845cebbcf05d515f28f41fe91fbf6a2733ad327c28e9f8e6f52d22c5218f5c1e416d84f25c49d994be4b2c2f6da26af90ec50e874b4d76d2ba05ebe4664a47b8e3092136a77820e226c244a1d456c2eaa85b4d7ffa9542a55ab7eeeb6bdb6c52dce8ebdead1ad7acc8fef7987d30221583eb894a3c91b2c1c3a3adc7337daeb386be7a96ea8a8e81757d933f6b3374b7869f6afffc495235ed43df089248c6ebf1fe91ef8c415a2dbef483cc9ed19e60f4a9e2853e61fda7384fcdc567e741b8ae3175b696f6e9cc69d3e6badb575d6efcce7bb9fb1fc47da6b5ac67ed00b0b1b0012a47b32d9f18043881459cd7e3fe23e3f372fb0ae763512d75050ab96d25ebf956ecbfd362f307eb115294bc0f0bafd538ca5cf03f1a9fbd07cec3e2197815cee3e7945f7e0578163a9d05e3f8ef66890b1a78711a515f5cb25edfba518cda56fa2d8535f1cb63feb9f6d7d7eb5eeb337c8a47be23e1c4dd69574f9b31919c31e9b3d9d1342e7563dfcfd872ed499b7e95a25ad79840619ebdfbea538dbf29d7e1aeee8f6afe03ed6e53bfdf6066871b8fd8da415c5626795409e28d6ffd38aa88e73662cf300c04ddd54b1fc9f56045f5bd7322a22d74feedd97d92dd6e614e19c73ce8c53dd6a6d287d65dddb60372d0859f61e6d60a22d2b5ca0bdfe913173f6f2a290427b7d427bfda96eab385220bec3dfea84f61a85f6fa53f8d15eaf1099b309f2a96258b25671fcfee2c66ee5c375563f2588578861fc698f21fcae04f1ce4e087e64e9b477c3c472cc690f064b1406cb46d573f7cd3fc51d36db6719cd227d7bb5394fdf6f134f0f4f42f5fd29a599472f76d6da59612787da913d8cf299f9bfc8a08c490a4c201d3e03cd33ad7b3efa91c78d0f963fc8cf75e1e70af1f67369fdb9fca78efe64148f8d73e1e77e295c21d4cf97dc87eabe1f8de76e34ffe1b89bcddd6eee36c2dd4ab89bf5b941bdff0d57c3317f8a9fc6da5cee3ed4cbef0770fb278af341848888a849f6b4bdf82efcdcd90949b62d6b48451d1acde9e90bec8afed0a5cfffc198365177ce574c87ffcd3811c46bb3da89806f7dae1c9ddf3d3fdea10b44d6803e417ac7d9c80176aef7cec75d7f95ca610dd451133b1cbc28f56c11af22bbd15e90ce4ff63166acebdd8df61a0bbbfd782f6f8106599665ed89e3af1dbbafda1d36edf5f671eb5e9b538b419ab3c62c6396fd4785e2cb971db536ef5f65605b6b3fa3418bf30273fbc4192cb32a9fbdfd9a16db21a451facc3a7ab679dcba669381337154279835cc546967fc75e1b723a1bea0da198610ce082184b01d4258a3cb91cdb6baa19183a39a996ada76f76cce99c9116ad8409555592f3636e7b4d5e672860c3f7ad5ab62391be4b41136e82ea306bee6af457ab3c8c92b74e34b9f2fa5b4307635ba30b7d5e8d26d1c0029a50e84b084cde58ddb377d5ee7744a8038345a00db00504103d8a2b7f9330e8cdc94d2dddda57497ce7d5fa38b85d507964d30e1c60d8d678328d87d456017a2beb0fc3188bb5041cdfe1c7956366aa87068dce4f400be803e5270a5907ccf62166b60e366939999ca983929aa877cff2c0a7ec8ce9eefe0e89dfe136ca0947836ae6fd427a7a50a021765caa84ecccc1d251085405fda8a3260ca20510366895694b27368a6e89503b344162630d2dddda56497714ecfc199a46f2d980d13181630b7bbbbc7183b7a6b28328171a24c19245c6ac6c4c41487608a65bc948994760ecd94cd8c4b16a62bdc9395852987325294c9c29485290b5318cc5c26c6cc03661e8001e38b2f5e74c185971de8809999b650eaa245165cb0b8c23d8ac1ec2e9f584ab90862c46ca9b1eca588fb8d70fbbf9a1c56a00fc37ab0dcbe022da5ec857d585aa2420b6c8a1c14200cc8d08b0ffd017021090d57338cf09ccbb47d70b056b47b4890de1c239325925172abbd36f26a548f6a2b6a4bdd1ea3748f52ced66c5aa7565134289a1a19336c6e68a86ad858e5e4ac460000091b751b0d4b4af2d25c9acbedd74860ee5723f94e9946fae754de50dad5ae2e00349c1c1de9dcc830b28dbad52d9d12aa5109f5e8f69750426dd5a48aa5266d4a0440ab8c89e118a872ada48b8a743490bbbb68dc54d217cbcf71a8a06d4b178000a082b62d3a0390515b4d4bbe536609004b5b4b635252faf265843e32420eaa4913355100bc9a30b1584eceaa841d2b635fbc785951a49d1d029860c20d02b012172e363c13646cabad0ed331c6c249d2a5948e75ac631deb98441ae22d35500cabad54cb041336180f0f2a68db22372e1bac00a9d68d0d46b75025fa45be644c755160b41b32c653ff888a8fb84591ba27067348699f9451eff42b297df922bb54cb9d9170504dd8c553800dca189198dbb5b5c1b4a5f6b858ad0006605546722449110eed29d158cc6ca43d266aef001b02641020b121428ab4474443400268dd60ee533b198bc554f801632107d56485d5b7821502b68ac5e29031193758986a9483454147aa9582a58cda4763aaad0d565b1bacb636586d6db0da5a694bab0ed34b1ddbfa37d8b6a57daa516d45a0b652c0b1e1400545a90019a9146a8562913119933119a3485c2cff2763d5a81eb527dd062ac84fb081fa51c0a60054d05480ec39d12ae33c69652a2763bec3249ba419d40e12aeece49214969fd6f07adae7c7c65a1ffe59c0467f6035ea056c396a4bc66ebf8c6d5b3658161b176089663b008aa626d5c9dd3dce8c81b226206f2e647099cd2c6b8ac9e85215c1d4788c3146f79e73c6e8b112b9648c1e933ea03226e631c618dda5cc6696491ee4188f5bcbc7c4e61329dda39431c618dd679cb1b5754cce2c6bf2e89e4594939ba46451b33163c6441967965d618d5135b13776bfa35d71d61a7988636636b3a032a60ca53f7435f798d5c88235df4ea63226e6a0a9074dcd54c6402a63ae307353127318e630503ce184952698a8f2a2328599c72c2145892849202171448efb93208da8fb787c1b177ee4a8efb4f5806a4b7b7de7e5ce614ded35255d47729f1712f7ab71e13b8c8126679b50c80de4ba5f4604bb5d9bbcb0fc5f4674fb4f2e2d2a6bed918221a50ccaafd7ebe55e61514a4d85dc1d6daba7ab97664b32b54f35325dde9a2e6f4d97b7a6cb5bd3e5ade9f256259aaeea924cc03cc618a37b6a875badee61a316ccdbb36850e7db5c50d85d0ec591dce5938893dc2f8706baea96dee1aec2a6a8b5a8be6a92f6d98c2a6cbe2a6cbe2a6cbe2a6cbe2aecf6d6aa30ebaa451b2c86c9d63a84eeee0e633bcd2774db4b7b56c67a2a9161da4732f54ebf34c364449a4162e4c29964229938cc24ae442eb58aeee72dd5954ba8305a310a0dea7cd39583c56ed7bacf24d34d7e047398699f69c45d9ebb3ccf5d9ee72e8edd247297e49ecc74390db528e76a5786fb55be7016115de9c58b8a4e50698e4a86eb2fe19def3eb36375cd7ac262efbaaeb062b13948ee97431f1eb99f1f4d2bbdc353d8ad65d33c8239e6f74b33ed539594be7c09138669bee6ebe876d6d5a209a53da4e9f223d7edf7a3ee71d23ed3ca7cb5e6cbdafaca81fb8dd21f16f597f67123bdd38f248c27610a733f96990b9ba9cd40d8e5ce89daebaf7185e5cf3efb69e3ee6292c3cc0c21079d5aa834cd78453964866a0002044100a3150000200c08080563c1609c27a2a23e14800d728e3e6c523a968843418ee328088218638821c410438031c6203354423600244a344c603f1a2b51c366e9c24a8487215b398ef45948304a2ffa14fd1a5b0403b655644f31e12ad8834f47351eb1833744cb616dbc7dd39b00fb592104f7571cf4a0a4e147f3c99a7b2fcd02d9c436efb8668b13e033d1f42677d19ab5bdb080daceb1eaf9ffa8a24752c74452b900a5db620e8ae1b330b679e16011627f3e863dc193d88970cfd57b6df3fa19ced8f94428a159dce836b837ee39170d44e147e4ca18be0f15e06546c879331a57a14aabab5e2bdddeedf7372d40f021fae9f2589506dff2a682d6264985a7da8f7ce69e2dee52344ffcc576c5bb9d3b65f9018e48c1bd19226be905d69c089d8f336a685483f9eea4e71a0123df1bed05132b0b3b4d0ce4405f0f91b5fa8c8f5489e1ed77bce0e1039a1160995c64658d0d7fcdf5d368a14b5b3699c13f25b54ba47a25c4fedac68f9b936bfba1e044c89d9482d00099b69748f43e88fc4bf568c0f29605ef612e8742a0156b1fd58ec7818e4398d7b425eebd6d033a47623d67f6365e1fb8818560c01519ba3882daddbfaaa06d157526f69c6c8c409c4b67977b76b6608810eb9ef5e059af4588f793aaee6539fe4c1ee18279e95edd8ab040e80b0c3eb9051f25f1873bede553fa1aabd3048ec2b274fbc59b4d3e931731444e4a3dae9a38d47ad95f6799d6f981e847ac3423daf7a0836da72948dda7675ea27c9bf8253dd01d0267fefcca0ea8cf7825079508ea13cc105f1dcc31eef2cd5b6db9ce27a0655cf2353fb9c5ade36e2e61373488be8ba607e812b44b00a6b6eee4d103403e508b70e18d616c99df1b59efe30b7a513ffab9a6aed0ff67b386b9f6f6126620954fee6bac8d37131e43c0dbbb1a5ca3c56a5aedd86b67e5cecab91384a7497ef0d9843b4bd9c95d01f27329e3d83fcaa6887893c9680643b99006bf9f946d56e7ae8b3719db811efe5ac007fc05aac2d60dfb7213f44ada1fb38066b19d5ce35a79ce8923c8c6e877bea814a13e468546492dbfe045db24c8417dd5dc3f08dc9ae2b2214f683dfd34e486d99f048cb7fb5ae532a7593f14303ffdae8c21c170d079218c0cde47aaeb9f041d9704d1960071fd30f3c600755cdbc1c90ac73d7387e23806958bd5fffadf0487dd79208b4de996fa6f9675cd0db456403b2b74216e385e59afe0c88278a890c08c8d56d984e8fec639d830e2493c9c8a739af8b4426629d446dce6d808d4e6d91ac03e78fe0124b50db62e0b351f6a33351227fedd68e386d353c446fc73a8b5d5fbc08d2d95dcf28e57890a1dc4627ca4bfe1b610eefa45af59e7c6efb49c5e62fa675ce6213ea2eabd68d51723c6b81b64d13dfaba63313c930835ab84b4ba9508b339a4f72a61f50417db3bc344280f7efbc2b48b14a7e29da6ccffcc3ee9f0421d247737fce4bc7ae14decc33eec1a50651d710e72b4d57338bd377c6e8540728067ec133c2e178670aab8d284f2ffe6fe33b644871788f0dce7cc4a2fa104ec942f46968f4a3a11e48391455773b8e6bafd2e04ed385756a5f194d5b540d59d74db8352cfb0c6122c794c4524e448d60605e8b485582e03f013892bf0fc5543a1c74fc439a7f4c89428f22c5e3ebabb5a06ba0446b107c5ded49380321799e6005af92294bfe7b6dd742834ff22e18f81a32873ace4cd67e3d789f92b54447b0b4b73ff40e8a6fca0f7e53f6b779a51a69958cb564562aadef7b1e7921a337d2f3311f7ae27ebd8b7f5a60c62425b58be650c2df4a63e3a58c4fa8b52ba4094d20514e4806d1b7ecc629a31c2687654d09bb9b84fdacbe0246801c825f6e21ca887318b5604023b5e60ccab5b8d8117b5fe20146aab82222bf43a19450c3f3c9218019f5765bd7d5673eb0f2326e0812d841d2a10d1aeb5f4e61227a377f21837dcc32e57c3e50d6ee384deb0f2f6c2c1bdc31e31d02bcc82a83f70d6c81634a43f322a4413a0b216c1b3c8a77d3a58186b5d2abf79c990bcdba6219083d9126282cfe807937f02dfb3c54f4d7a77a0f24a0764dc6d9abfb873e3e60c72735fa141211c72df38f4248f771c60fb6a3fbe9f3a000cf6d9879f3dc256c6d5e3d752f692e19027ed7e74ee4e483f4091017c7e550356f485f200b9a4d6081b0b69fd62b25ca75cc8b54e9fe1e94bc0c16c893d07525f28690162665362d4778339e7e0f68b14c1acbeb084bba2ba6381d8e441a08ba7716c85d66421a5d41950039301328af4cad21d291d24125f1e0d990825726387018f16235ffa7876b8d689893f672617830e67a6e32d767069435763b83483ab4b6920590622cba523d4231488de5b2d3f37f73ca2cb77ae9f4fe051666e2c10cdd86cecdd60f03b00c1641c4af0ee0ff352dbf9687aa98ad7bb5806cd7cd62e685ad7f8e3f9fb28946f99288ceb9281a6abb0a7a2f23fd6555b86bb706073face48987cd56cdd0ad41272b46919d61579233894241f56e3e5241aff2bac97e5aa0652643c4861d065340f070e8906d16b34a2fc4a198bc786d78827a8c1220fd28a05d3ff4d048b1f3585e7877ad57acaaf70c5d22ec5abfa6673f5cd6b4ed98b4a2407a1c8f7e7b4670a40f22b37956f377df2c2664c59aabb4f4ada5c3ea740f489964d0bc0e487b1f437dc196deea7ce4989bfaa0ec8b49570c118f4991ef55ca5f420dbc062d0999d8c31507752bebe04f35946b4e2b0ddcfafea5011b459eb0d4c90ae431348d6446bf3224c13a12d3e764bf11bc36ffbf3344f793801a116cf975418f9a0416a20cbf2bf6eaca0ecb44ede9f3e67f8c409ee1dfd912e278aed9dfa640b70cc47b1413fe8587ec06dacebbeb7916fc091a6b1eb6a918a8bde0c4c640e6bc5e3cea24ef48b020a837b700aee09eef32f41d860a77337bf762ab6189eac4796b205f9bcda73340c0fff403563fdec37cc6c15c75835b4eb0e99477ba8514160a2d5797f077f8cf81fb6d214b0df0bec1072407f93e6c735247ad567afa975feae9be3108077eb665697de30fb8ccbbf80007ddfce3f0942133dfb4709acbf7b4e50e72db69230cb5f3ea4dee09015511c35ae8b82010a10f8b54e2aa83552a33d01925e6a139e8fef6832b802873ae9cc8c9d010b183e6f7505c9e06e0ab57a80de9a94883b259b3d30ce0c5cf0f5fb881230703d56c082d14d9ecf399ad329fc7b4d6ef5ae6dd274497f052d8509d9c18424e98694ec4d4205625a5e0203f74f4444b2000ec88977258b6cdb17617d5c6cecfc75675d75873e209f8a4b209a9b012b7393f1ecafea1d1b1da0882a535e032caf677a192c1238ef2942178ef17fd8948149b2e26d0e3d3f5ec6966d3b2e827a4dde1505a14da09f3541750ed50d4c8598ba65090ce377d73d28be9de9d5f879d8b0435c325499709ce5ef3405352bd73ea0eebb0e152bb4a8a34113587d46431f617f891bdd0e71fa2e6037a48f9dbda0c7b70584410d0e4d63678586a4795fe4e695328bc76446a4d7ea276e2f1ce4af88cea98aaf4283b8998179d020d331caf512048f733e485821baa792b95102572a4b7d60847e9560772f1f41064b4b0856352c4261050582ca0d8ef3bb8dc50daab078330237188ff226fa36e469557932c6520ca47e6c9139fafe048e978908b8a85cbb4cb99b94c5aa84ad45f495578764d49f9985187e75db35a9931a8dde181086fcb315f92d07c54c6fbf85b1432c0bd4b61e7de74fc89eaa26f0013402cd5fafc8e1ff3c8c831675dd960c2c1121804bcec0c123e20864930f614a119d7459900764baf1239b2930dd8ee47de9c80f6f9fe11d366244b4a0d73aac936347e615391c8fbe52950f89e23d8e954ddffdb857bf77185f489420138578e5ac1dabd1decdb78ab5dd16aa1dc85724656599a281da2fb02fa2c63686ba7d6940e9ace39f3a029e0a1bf876c88f2668307cee1a34dd2c81a40b466bcd89edab82919a4e8206815b86200dbe3ddecf8f6ca71e817fed98ed556600a6c69d8b13bd61e5ddbb1d52454024404b76b5f0838173e679d1578f863cb729c6ba30e491c0f1ac0b7caece35b326e56cb72dce4d96fc6bea675dfdd9663c7b58d9a677672fd3f0a90582c9009ad949f0b88566fdaf96aa686be0adfcff99ff3c3d81f1051a60c1d30052190de651f34011149a41160dd1757e8cd900f50a64ada02f18bc95a555da8ec48ae9407830eea7b6bbe9f42201fca448293b547ead098a0cb8dcae15f43865ea5a3029a018cc433bf76019e6e0cfa5591f957de75ce255f0b59c47d03d0f2209bf8e4ef1a938e09da2e907442bbb2a8441509b0e56084dc0657438a671a1a80c625a619838d45ba5063f1fb3c42d9eaec028f641b71f7529003a2855216c2ba31ad2815d9a712c497a742cdf23c66da1f0d0bc40f850aa233686b5f2d6e6559846331846fdab7c24b7b24aa02eb8819b6e207b6c73145c6ea892dc988ba8ab806aa7126ae0859817a144ea070665a2931049fc57ee3266a39567fec5809053b8f448d31d1b095b838c0964da15c6a46fcb4e9c873e6ba9ef4182abf507f84f49c0bb92676252bfc27e5a8848a4568ce645dd10b45acef3ba2451cb16f44aa05c1e3b98c309fbca250d64dc0a9cf79c19fd4d144c9d53750e1c7dda8a5ece58c7bb0319e58c4a7a3b97f7697b1d9c142d20b9d45e9e83f538666937143096ce033395a6c70db536b2aafbb344fa4d0ecb5e5b21d24d0ae7be58143fada09fc8036c58dab23e0fdda04340f18c2fdc0c1b4b27ec6db374cb34097ab9069b8d28ae1de6a808f790875469fdd58cd016278071e2d0b7952c75d606e30adeb0c1035560c23c93262efdbce2ef198b9e4d18f875502daefc961a447cfac23abc9050a9ea4fce1468d7789fda4e27e16f34aaa5dd3ded5b62841f3033bcb0f716893a963b0a1b3be3d266b4965c3b29014c91e30468cf48145dcc40070f95a81a3e1bde5c81102d2c378f8553a46dc1ef464f8a0ca3693863173070df154f0f5e025fcfab8dc451a3ba476acc6f01a606c15ae645ce47c60bf2021cb9f7d0633bbee78bcce6c52cd8a02edb1dadac9c00aa84daea63cafff16dcf1280bdf0e4e501a050650101fadd971da127b0bd931676226f927c93dc5b08df04980e2d29805ff8cf98a76339616cc60e018c00f49af473ba347278b02481cd77dd521b1dce2e634ab7b19000b4304daab0dc58639a1316b2c61cbb90aecb6e3caca926abcf66aa1068dc7ded48dae471b3fd441e121baabc85020d1147c4342126cdf9b074bc872d697ec26c1cf5efc32a3f0cd121ba8523771ddcaaac89b99525374374542159c19ef0887e087832e898074ccfecb737dbd1e6913ec7811d61b759b00c2b5560eea6a0809c413fc1641274affa4d115f8c250e702a018251fb762cb699e9522bcd27e0648ec602cb6eaa08ce15318660cca2e856948f9fd27ac1a26099a19b141ef52f947f084f5b4c39f485be7f1835783b45b7ce2147ed7ee4d8e72968a8514d36fdb236b613e8188db1a4dfcab0619203155b523bd69aaee4f3b115e92a9380a23fde6f109063ee0db57ff0e432419679b9ab79019807acbf59ec8bb032221ea58f283898171fbb1880a38034cac990ae89272544dda3e6f09fc3f341d5dc2401ac5ee4695d590b21272886266ba87b2a5da595f2d8a1f47f68747ba220ba84e84ad493d1ec18111ba8238b7f35370e0245daf3438ae39260265a4adf16dde8f8489292cc4fbcd572404bbd1bb12de6ff492c129aa99f775bc0cb088ee93cfde972faaec010b301d7e786981f8cca8daff02318d7a891dcf61dbdabdfae3d4f4fc0bd77ed6bb9378e114a0ff0c3332dbc7ffd0f1818c4a5aa60ea0741282bc0cf8fa99a884681d8e485b7220ae9a5266b399db66702cece1f06c774973b7c9163a931e872ec2fb20f1bf15e098475f7a9aaf37fa54eadff7c7e6873e031636a4fd24437746e9117574bfb70f984c93ce44fb19a2749011850430b5d7635acdf74510160af2847fb641c68ed3ee4bbc4a5cbe34cdb83a6dc63586b9400d970ef97b2c7b0de1d6e2f820ca6973320092a1469eeb583a32744c13447bc46b508c321d06789d8642356e6620828965af5f69f4f6114763eac163c10802fe5e5a72a72560ccd0f3839f89c86aa25af2a59c65600481f314cbc36bb5fd94e04ba2ed367365bc76252261f9d0a54f85a3ffa6c0eeacb690474d1eb24aa95d96118f6f1ae8846936254d1b54f2dfe7dbff762e93cb3eb79ba77d6d2e679bae19865dd3e67ce5051f2074d4e9622417f19ba74f4a37ddd165fd1054ee8e31510b2a61e06db470acf767973de4cf1c83fcf80d0914278027fab50a0cbb96d252d6c1217d0cb91c79864f1994427f3079b939755c6672b94bd5b1f48f30acce83eacb66662b5572d2eadbd28638f2618b539642498d11864f1460329011d07bae7b115e5190ca16efc253dd4f288e852ebc17eec6ce3f276f65855ba0a02f2f6edb446026a80e73686e83337f4cb05caee99493e9a3a0fd4b9d2c4751c14f6aa4d692fb2b0a6dc86b4e69077d968fbde3657438a77f89295bb564303ce4023c2ba85a7248d8cb3814617b8618e6c296a5f3518ae69a4a6012e8121171128dab5c0737fdb22f7708bc24e1d2fc1d522882d36931057b396ab099fa93b51e05a2ee7968f2ca9a9cf2854be2fa73e290ad715d8dce6adfdd2aaebe15bfbc50b2b18b5ba4aeb2d368e8362ec0712de06a4b739b29f299b8d33cc7d4f042d7518a177ccc25dfd92a043053d17e73d40e2036ae00cce1f367eb7b046944f04ca04efdf50c090030800f76d748d8a660b13cd5a2e3efadf151768402e2bda6266e1d1b0b631e0dc1d3859b55a083e844016bfb0f0fd8078e9c42e8ee3ad58732c08ea87ba8d0b4d83781bc6d994845b1820aa8b9318e8c5a86c3e6f8dca8c8d417546828c5e3552431967b7048e1fbd823c5444660a96f929bee899b488013585ee5ac8662e01018dc77466719b5ed664923f2685e83eb0bff5ebab5ee42fee9a991250dac4240034fe229d77df86629e4e0f81974494501d5030d589efe990d40ffc7f52c20a362fdb786c765e0d3a46b9d940e39c2afae158f1c2e52ddce343757af8fa276977cb3bda95a3abbd664ff84c8c1ab0fc1c839d5a6aeb2ecbf47c165f05f6558e44907b8c3c558fc850f2377340e28f008933dead17da6a96d56f4bf59ab8e23448fb982f0e38f191e8d1d0f5926b9f5a31ad10b3e11e5e6181d67160dd775f547d625355e1d024a7b80346a01e0d50e662feada5f0defa2f2eebc65fa183bd9496439162f62747d6f0711b4ae418b19e703843386e66e9d872de8bf720d15941d545dcf8b306b7b4adfca9a12aee037caa00f64840e91f6d9e7622f98525b5403b95f9bc578da49772fb43927f42223f3dd31969bfe1d56572c5620fec4214613e171b0afb274532975fdc55f6792cde6a64c6c219be7d5e1c46a129da2ed0c5e1e21b12aa834ec65b89aa259b5ab9f16219ef1fdd3d4f91256f0f167e0e8ea3fe93f6fbf3f5a223057ebbb2a341b3fe92d0240e577f6cf3ea59a8bc7fde3eb75e37903f2744a75c5259579f8d991e0eeffd6a9ae87bea103328a645b142ddd4c3d425c8fa598274fdb259c5489357ebdf97e1bf2b91aaf2e8513c4b62c594cd4695264cd0842d905b2f7f404ae107afaa8e628812d893ea1802e9fb1c28a566db657d9cc456aa68acbb98bbff823a7da2a217fe8253a235e87178780d5ad0938f6a2eba6078b879e8f0b7b6265ae29ffc36301715e14ca24c6db29d5a8c461d0d5ae7a7bb0a9cd993237170297644c349da520fc42cd814bb1a6fa55d47007e82ee4335f84a3ba5cec8b9c74327b1177979ebfc5d2dcc1b083f8f1074f5f00a4b896e468cc56f29d5bbb46ae77cf23af6b683ec58a4cc5f272f0137185f7aa3a213d7a93b7d181442837aa6e5c6ee7a36ec3e992fcb5718790d000d8e75b2e80d3c8f3ef93f88496a29ac34d7b5405fa61364c7fc9c23b19ba7ffd80f280612e9e6813816a10c3eaefa236ec03e82ea61e48614e9eadd7c82253040d465784a7f3437791de9547af97d95a5b635ca260a3d827d140ddeca37b00d2e3ba9a4a912a8c0363821d5d677f887b1a2ea01791a6ef00bdc7161e9748a0170400f86613f38e56b452ce6d626d01a3ad51b59cd838cd49ed5c65b8ff24ce5487109bb0e94c0d55bf035a56f7dd8a6ab258ac4487816f1e79ad04080650484ce4026d2aa4a6bd37b1be4ee98f73c8de3b8398a125561efc5ab2670e3b49e5dc79b23138b5e070ea81b64264ea03eeecbb57473d7249b0cf9de9925c08e830f6741c9c02144369ab5a87e6aead3f301886f675e7a66a09f18ddfbeddb8aad9614b5cccf04ce873a09c13877e674dae744dd8f8913155b8c7a894aa2118c709d0b4c5ed4880401ac3b4f482988f47f9aaadb238b89e355346d90bdc687389fd514a1d8b9c236c87628784c947af49912b0b65048cf28c43dc12445174b1afa70295a546531b80dbaa5a01c67b2d6eb7c765378df3aeae566cb399380d066fadb79a4e92837a1b0a0ced18cfc9f2e39477c8f34ddc05e9a6d4f9b1387d1bed47fecbb97a62864e26554bb121e7161557a6a1ecf82addb0d5cb222e63d97a4c7f5c93dd6fb2dd77b22da0fd5ca7207d989dbccfd74c432ae87835397ec8f77e914648621dcc5839707b526b292aa7ef3ea5349b1402809472fbd86810a05f10e4c3ddc3ac0dc8c0427fb90974e403c3e83bac11f66ca7c2785b26798af3ef34d0d6216e351126a2fe8efcf19ba1f8319140f6ded7e1422aef7568c20a3dc69e369d789a8a32732bb1e7f27a857f33ab30bad90e802a5097618fd3ba55d0d17335583350e6f9e38dad8200e2d40a8254f54639b99197cd88706e862d899236113c63564ae96aee8e6c8fb3b15949e216b0c81caab55cd75debf39cca830b7198a67c8c7dfdd317a8d85bcfa6cdabc561f38496cc6f65eed1bcd08994402eeddecc25ed322466c0c0e811e290130beb50421105a31ee423863126204c7a403626d6fa0123e12be8588081562994a629db26fe8a3e4995f926d13d18b52f7ec1f26d4789ab8233d880364103da2621b11453b4bedafe109d6ca66acc972f17d63352700c7e24c0f0fc63202ef795f502f1ee39d99008ab11f26e7def0dc7722fc60b930ec04721e13eb4c2f50b47d4e8c8d66dbcd29e4cfb54b47acd48c9c9ab3bfef1aabed7a993f9de69a15ccfc553f44153bfe55577e784dd62db562e49f198d0f737866f7079f4c32bee1f9f8747b08e98c45bb8e245d9332356f6d6f309207c4c6555a20eddc9069efc024ef74a448410bf3e7f460fbf354491e77fce140da8884dd17da3025df66fdfe459255c8a97aa10fa3987f4dd84e2044bc328b608699a33ca06abeca006c672fdae2d45309c66f9313f6880411bce0b588bf5bf4e0df2560024a814b8d60ee3b2c0d0b6412cb0dcdb9ee5a34c5c880118a0fadb1b1b7066decd161236737c8daaf26e0803cf211a1d03b5eff0d43fbe5e7c7e919e6818c6e1f9517d6f3f580f5088b5b6374594bcadd067bde0eb7fc0f13f4536062373fd16ba1c85b64cf3b39b050da7f2b274d85e40e93de192337f3736951f92bcce2d8da4cd14410222175f4d8fa589df3fc354514b9a2f2e4b63c13499ca9a5bde699ef92d656eac0af2b7c782d4c0e0cd864474f93e7f35a3faf49d9b8139e25eacf2b8d573d43b4656b91f37d9c0c8c4be522b7478ab7cc5bb0f483d239aeddf4bd03499fa554ff0d624927842e55e7f8c7f6674e2d1ce4f5e62fc88e9c30e5bcdfbd5bcf038158f459933e0311217218ceb7cd01bf688b8dc3558db1ee7ac7dc6a953b8641ce97f4b9a565aec53e725ed0b20bd304af11957cde8c7f49387b016c539379d7d2464e9fbd1f46383cfeffde328ca075172fddb74642fdc729cacb5322d22f5f93ff426d88cf1a3fdc59fba2819cd17f9c030fb2787e434fdd002784806d6c26bf9688a4f9204ad71fd0448a0b9c17722934b8d19f6ebe1fec586344d026133fe78380088c4b7a9e82367f9cdc2cd8d92ea04a21cd64c33574b4a12c115a0e53d87527aea1c97e4a6ce807d847e5dacef0fc29692ad71e2c127daf60722ab668d1551556a69ba3ff9a608a96fab612345bc78f9bfd6d0cfd1ba4da265c9c3a920cd94a1f45c58093d87764e340470d5f09d8f1eb33e5190f1c6e38714796a23ce9645714f4c703173ddacbba92a87d59584467124fd1bd43eb8ca425bc2bb7023a6dc6bdbf6c08be550457d8a6460ffe0bedad4ca97faff5effc1ebe59a7e1918857630e2fc4d6e407075c49acaf1e9a046c228a7cf545d379f9c11ff2ff243b06c6e802770d3a9f6b4ee61c884c92bbad2976679559459d7ff011c508d4e187d14ddc033b8d301f15e352e45694eb27369446000d1b8441e50de63ac921ff927039d3daaa41f6a8400a9a1eeeb88e3d023a9faf720b342bfe2afc0bcbbc06aa31d70413e7df72f15d55ad9b5ab05a5960ea8fe00ed8f47b492c150789fa7db61fbf4f2d3badf0d5a90d12690117a1a3b27af51b0465c66218fa9d581d8a5921351eb36066c3b768abd5e0e8b8f0bba7ee062d3d302a1a76c19f5189e31a6fc2c86933cb479248384e4f3be2e697b4f10f45d288a2d8b8440c29ceccb4f852252c6b297ca7eb1499fbea3dec601da08f089cfdf2ec52f61e6c4dcf5044ddc0c73d0caa3cc3566f2d8c96bd5255ee55ac47e85e198688b8992a299bc3e9cb3a8ce82e50898f7c01d3da9af6bb818f5e412b07ee8f87f06e70c96e6f13ce9669fc954b838c08066eb33aaff98e0e93fc919ebfd34e6a4f8563bfaf94266ba86976cdb9328ddcefc1fd369e6fd2e76be3b614349943469f0832376f19efe526f16533bd5f8ab51d3446adf335e91365507bda5b5868899d1bf9704b91b83412c523b4429e2ae8f74d4e26dacee63ebd8a20e187911b001fd18adfe4072cdc1096a3be644c3a3fbff5fc1f093e4dc4680b862e52d15d658da267653fcf664db20759e198f089cab2e5adddb31ff84613b89a321bf81aee2a82723653ad0c77b2c7f1d060bfbada282942a8c40027df5dfa303fb6ab7c1b0bd710254dca9d4a1e053661507f38ceff2d89ebaabfa2aa676b016b6a24bcdc152da271f310a0f3870ed985936f827a1201a7c2f48d6a95d375b4352fef7314127f9a10c65e328ac30dac57d1c038de553abaa43b4792b53c3321818e36621c062bc55d3868c222c8de125d32c14e51ae811a5fc0422d4424d3cebb6aa8199241e38902096e5ca5d69386b49e5bd39442a61bc9d49a5f6d9c6526e9a6b9164e7e0d7e8dfca403d4aaeb7b763b6146b7a7fe0b8a23d1887ff857264b6c424407cd02600023e52c7d089ca2a8435e2cd460f3f1d9433ee1ec571b3f175e3b8bd0f757b1b27a5a3bcaf9e1e264e68067fa211d63714da25f8ee036fa4d8018bf7059a37b0d95cf0c7facb25f9c5c049ea7b967b11227d2d1ab1c6665cefd139d266eadcdb71b9635fff2abda6fb15978d81b40f23567e57d5e549c709c04034edb37207eca71210ad5df4e2e3331c560d87d3b9c00281f83271c15a530a75470b2f67a066dcc18d04b1591185fafef313cd9f74c083a5610b51ffb2fdf6f7189efc3c026a3ea21035f86984095879305b8a19a2a75b092291b48d84baac5f788924e52ee1349e80e2a1d2e9a46ba04b05d92a1a4c3baf4450b492b2a8c1f16eca4beb730b74fca7342643b526b75d886bde0281af25c32a21e4984906944d95f278c86010736c617dae9fddc288a903eeca4ade51af31063fcace53014a3d5525e405f8444ecab70326f04df7a758811bd7b4f790cdd151b5bc0edb27aebf954bb086211416eec4af52073bbc34b86984486f77c288bec0e4f72085c20e338332d0236c355286f30615dc70498c7fd8716de238fdf2c931e84151e38cc89a7a9f3c02af5c592f55b7c8ad94da10742d591aae7b32427ae39b75332fa8c0e0196b6d07faca37404ed9683b545c2a5bff8268ec4ce32bdfee84aff5fef53d4f959e913babb5b199a982e939b99bcc1ae1cf10a7a85c39eb64d1c7fd002cd4d97fb71808e08e99dc8ae0dbd6692bce22dc1bc2580744ba56bc9863b1deaaeab81e653ad8337ffcd5335bedc2e2f5d7f38905af3af94064aa6acd49351ef6b8f4143181d86ae4401763d055ff13aef1119e92e59573829b2958dd2e0d7eb498e64c8e216e8ba3035eae807c6600d2626ec2cab6e31321900f729e5baeeff58cc17fa32c3453d302e811e39863134925408594b5fbd9741d789c6b83078ef1a13aeb1a7b06acd4ae4e90134141ff2e736f30fbc359a7cc257c9feecc6479aba1bc713c631a40eed7108c37f2c519231858a69f3f0fceefabf511aab39bab9ba30173d16d1aad915d9bb327ed3bcdbc60a97505edbcca8cd8edcaacbe534a4b1b65daab69586d2202ed0ba54db428da3618ca037368019a5d76aa4083db182ee7652f5b31093629919651d684f4c38a0fde5bfc49515693303869e04b06e00e24ce50fac1b1f5330be1aca6a32b0301b5077b1f20377c05bcd0cb2bdf8bc722669ffa7cbdee61a7ed5ea751b8791839aa52a6b499b826259109d7e46d4d643dd88bd3dbc11d7867dcb4e9f0fa4f82af48be8ac1d19f4e6b4847c13a10d5a7404cd9b49f23f0ecfc892ad6b6f0b7e9d6c6d35043248b7104bc49a293225632f17cddda200b7ddeab14e80991875f8564fda7e381904dc61849a9681c21a0ef23f8d053610b6b142a0bda2a512c3af37c90e1e0f20f6dadb524ca8a129656577d465503ef847f3cc259b06f462b67b944a30c25514cbe7b4cb28d0075f756096c08847710826f8958db4ad66b88380921873900ce1bbc66b0bfd640cf202a241fea69a26da9a3db20624d14aa0db1d552951713e2f5d6a7ac90a5fc10cfab3fded39e8fab4e64ac0fc899ead119173c49b0d797b3a53abb00cc39e79bd749c3714c4d2b01205d281c88705fd4768d082ea6abb716396bd96b23f1107bd4580cd49977ddc38749b205abb43a181991abe41fb78c4d549cf54b571c86be481b4560f3408813419e2e03a9fe53106d092a58d8640962d85b0d867e2f2fe4dd9f1b442aecd7d8b2a445653ded80e1c62c00c94e5518816b42cea0cb9a86d3cf4d03481ee787e1e2cf88e16a886afa42de9088360c27d00065036dc5e3a96e24161c464af0ccd83898a19e89d89317886ca7c1c87e099b7fcc851d3b80616b8f371e5c12c128c79ac291ec267df145c020ba183906e5bc97e21004b6b4366b14bcf760d8e3e7d16948a9ba286e18e225aa432e7dc505cc6b13c1e75e48ec74083a63ab377bd254a06d42cf37b4216df46592e17f222792e7800266dbbf01191cc3251c871992488bc8ccadd0ce7cd856654043fbbd3020fcd42dd01b8272968e1bc89e69fa8c287a49b5af0f73b6639ae896591a47eebd690df4021ef1e798947ad7802615b0a69a799974fd394f63501a135502350377924d36d129f94a5bab67ec6b37355660ec4e0f563538daf8939e11bb52209d02a95dd8d28ad11719a957676a0accd105650f6af7cafeca4e2b668c90090e9572edbc9925d8b891c70d47ba452d45b1bdf2687c9b073f9b79eb536a4f4360928b8dbde341d2e9b7b45f0f35756a3eaf5e0607a9e21ea71362cd99f32e70a84288f35f7e9d0c1442ec6ff937d66dc80f3b9a769ade1ad4aff7909df2b4f927b65ff7410c9c8759b32c09667729e85ca383de1393c0f308f48c3c968cf55a3407d9aae57dc27803ca4a54066fc89781a412e72037b80795ba0de5734ce37396f9beb7e32c239771f8cc9314eb1985e009a3ec3970c7ca704caed06c66fc2046eb4f1598cfaddbd1a6dffd4832944a8470c5fe2930daed61599a94d36f0dfd0ae068d0f341b6d847cda5499b5e84b2f64a52c6e618138b587985bc56920b57ca504648816f992c71a5cdae83b49f2f41e3f88f0121731a65918c57676a910a99aebb4365574d6b622da95b2c194ce4169ecc2721689d6221732829451d3b4436e882968e17e1548791a62834754703db80f56f15e6ee36abf0de18b60b8b5121076a4cad78e826d3a69894b9601d55433c269f33f84064ab1a0e127433f7390f94d34f5bfb80c0caac488c274ebdee25fb3ca68f013eb486bd47a3842807b293259e87f8f1e81872f177fe780745aa12147800f4b716c1cadfb5b8ed8335446852acfd84e73b2bb827619d81761c1d7bd766e5d9a386c6c57004c2c94557124e8ea167b2f6cfb6dddbc26e5bb19518e79e989d2134ed12237383e009b797fd9048089c1f971bcf1972de2d864ea0b331b23eac210f53493440bc95f073a125b31db16487983464a9934c51b42e1bed0f3a12f6b9864e4806e225f0a2b36ca0d63bff9de46576d999c54fe78abd62795e4102950f64fcd6b0d8d4715ac43ba437f7247c6004e99d6916639af6482cd6d5a09e8cf9851027e1b088996a69caebb033354b92a9a5db0d3e76a2294d42c45cef98b8b7bdb45660932c814b4a6f1957e16d95eb5576e80f9e6a39cb75cd45735cb4bf1df50bf722b8d901110185dc83e9e915a5ede69855989cbd663b152f8ef0dec1c26b4c341e70c1111b9a32076021491dfd51678da99e448f2d18cfb798a17bce74bfb2150f5c165455e255ae1ed04e5172c542c42cde876a30574332fa6dc4695b25a05a243ea37bc5b2b658ce81c6eebc178bdcbc523e56961f3302565fee8414ef4cf503abb47f5df608c3628f4eb9318d58fea918b76f9eb8d2bd5bd979c72bb46102fd4137241d40c2009034e9a27df7b13c6d4439338fad687d46e09d2fc8d73a6b14302b40dd1ce9c567ba26c7f809a0056c5a29d26c45e1f1757b549f4cbc36fa0246eebf27c4754cfac899efe67d50490c2c9f6094dbf0d37303a3675bc948fb7d7bd3199bb0574d8013cf32340d57008931d30ef6133bcd16891588543fac88954e57b703d69324f7b5862d2c9497401b2f65a0818dbc06b24398003341d3f3a10e8e554b307c8665d85d9d492c0d85cafdb10856083c25e66205e49c797d0fe40c3833a312277761e991556f2cc656be7d615c1bc0e50383660bc73f65299392fd25e5be0ef2af8747760cab20c3cfb4ac87555a1ac26c6b689d50171f82dc99d1974c90fa43e4b9d0c38df1d5ea110581207ac6facf7b833aff391fd81b259fdab052b2bdaa72a226ab677fe013ecd550b191807ed9a4e7293d06050d03d2045db5bcbb4e53cad4a405cd3258a622483e0d99323ce70ff9f6cda880a30a6b7e7997740eb37505c05454627973ae821c13acfd6041b5997c914789dc83d3e23c662472924e2749a9505831a26340e5d517595d2dad73558ccd7ce73b43cbd77c0e05b80c62f1615818205ff9bfc165e2919879964ff81838f991b68bca0e6917242c2854a22722616f971583db20bb8ac4d035361b94984eac0247776d8a638b22b90ffd0cf9de4c4e9002974d864bb0025d301f5a6312c84990905da430747ad7ffa5819bdb040c20f33eb6a76189b192ea942bd7e027013fa2e1c0231f574b74ff4da47733d0f57b03bf6558148df1540f0f288b0d61529dac41291178abc9b6d10d24a599227c018a0b65167e959b4d65bd62893d1cd01e8f8fee33ce3a5ec42ca772dda4a423a96b575c59c5d30ac8b722057b2912e6fa0034965a827fa21dfaff2758cd1b8b95d5f8f1cc282e28707f1e11f1f38ecce9b216055f298cb4f49074df34c09cbc888e77f45b69aec01aacb223e90f1d535acc2e2093d3e5775397f03351c4eafcbe52384b0acbee0969619c8676d5c078b9156cfb87854ea75ffa4f85f0fa1250e5bedcdb6480ce564b386d6eed7a1a49f03817030f179a1edb48da17fdf3d1a8e83383c008248da4d5675828f2832fdd91169024b2b568e466dd56a3343866c36288818f146d6e65087a46341fc0c6893db1b32b443c47b82b6ac5892dd910fac2966d23474156729836f43d75896dd612c99f192348d56a10baf781215fc77f8294978f582cd7872becbd65c5fa55f738a74385b2a7701a548da17c89654eea2e99b1ca989aa58a1970f0832c2563e120bf449c5dfdb615a7267396b92938eaa2ec21a5ace68ba7065c4bc4a508198782f94a3a83d6f754adf212329600524f13727bb7864b39e76447b8455717a0c1cd1cca88083d85942cf7d0960e76eafd3b373387052f10e30a2ef8f6e9219fe4851e5001fde20b5b477926c02fddb4c3c784df961d24c00247cbc9d5c84aefc9c28995b3177a23f5e1f6e42c8007a6d28cc4a09640302205e6e5b70d1456795338224d9ae1233efef41e4b14ae8bd527f0cd66def2a74de5ac2d6e8584937f02de8432dedd2a8329038ab601d739a706075059da50ee3d630f2270425008d95b41730f007a716b3af3f7aac5188b37da9a0853be988e1cd04d7b4cd9a652649489384c7a74e92a7cf6f5c428bc09c7884a55685dd1030e0bfe58fc96f2c6098151297d53a4318ff24d888dcc36f8b365ac79a05caca76a26e2c71e6858b69e928ef1dae4b6fddd1a0744ce5c503f44ab20439989b61b0f0d60c87c2ffe176ae9338a033603b464a748ee4cb80ac31a0f55b8e0cdbaa0499a062a7d1a26438f463ef065d831a26e83155df1e4d4a360a1c72d510aad259b3f46b2e133e6786e0a3379952228809dc607ca8b8089fb88f6b10747985bb0112e53232bff95b1c44d01a545a291b41cacb8d32874409165b9c840304fe7dafb5a1c4dda4557c61022c85022dcf508a1ce995fade26b99711064d2ac5ab312e40eab02077793d7302e9a161829aca018d2ffb8b858888dd1650664245c798d97fab7ea876893364e8fbe915f8ca6b78a714118fe66a3d0b60d5acbe8e1d7724a5d3522dd5705158c9f2d223e5de8d10b45d297199e0cd0d94a1f3744a612dd6d8c52d4a94e69336de64b46e7c8ff59f13e353fcc09573a5714d893b137a6a7d4da0827dc38a29d6c28b2538f3c6c4e43f198111077db2510cbdf9d5e38e8e1b298fc0ebb9453b76e24aeff18d2c1a291678863c354a8d89e74e10843090da4a32070279ee88c4c7dab1b53859e6e428f61828270f6972a2c7581319a37444abb3b576a588f60c93f4dc35c3c994e0b7cd838c715680a40f214063e7c92e9db15b4e1967ef292836362d204855dff400c00d5d0d06637994487d6b38a5d0440b0ed401577e11caf1e04015a39fda4a6fc4607b0c8aa44dd6f90d04ebd39c1445f038337f7b552b4f61833dd32ca91e022fdcfc35d29b293d6ebc0600d7aca593b87273e8356f1c08bd419d9ab8cf9803040dd5ba6d26d38c9b64ad59d86b15588cb868ff86fa7a197b6e088fa3a6a8fa0206e47e25052f1557f5d4ac1074f914f44eaa4259d674f2062bce6f85b2b6ff564c2a6d29d34a4d22b5fc840a1d35e4eaf9a7f8ab7daaf5dab984e99c03f89adeda4d1fe008886b73fc1d0f35ff489110d2d2d9b079638d0d75aabc2d3aedfabe56e0f68345cf4a4f898aa3693706b78f82e16a432bab2c17b8e50ce4f002f7840fe10963469a6aae6e606a52b6552b9921ccfa5c68712947af4ef43c6d8344b692a421ad91b4b83029ee18d4179366a346e0360653215680fe13f802f9eb42c889b287d1c69bae74bb175d1b1ea0c00f7f5d5a15691644b82203f4147c3b381012f3b6302388badead03c318e5b92f1323d581766f5535a82528595de9badf7168c250aecdbf0b416c1c8b2c6e7c64e71a42b7e913340680f615751cf6960aa3a6ccb96d11ac96fd77e5cd98b4a8c6244601cda71324f9c508e979433e1f79f59cb84db02ae47d963ca88c0db1b3e003b54d31c665b2057e362f536ce759e195fe8bd18db053688cbfaca1eb73736e7c1e8e9a9c9f472b6f31c7374f5f76b49974603eec13442722861bf2c0c6e740d7c2b096ed6ae6101bd405ebe70a69cf33556392e8ab4030a3798ce0d42cf992c25f3ab1c9fb772c117bf446f9e26efdc827344780d9f9802ed45a7bc92e9a6c8de74ceaa45262fe7ef0cd2714f1f457b9a6673f702cc91116b463afefa06b8ac24d02a36c023c802e34d13b7cc3b1efd343707288f3f35b4d89c6cf0e7553e04c226b4669eba08815e46c8e66a464aa2decdca555c1e70cbf4a152f16db551706ce686a33ad0199cb2ddaf910e7688b00f13871d912c64084b90bb42eb7626670b52ba8a9e475986fd325e7cc2e4cd4be5cc4a1d65ba932179e7790a46bb9c287ea70119cea31889b07257a593d21a258a26e0b6ae714b5bce730a55019eab2b18aa0a348588e993abc3de08d02a3a4783084bee16656683ed54df64438909b2f695b48ff9bfb0af2da6c0471098b3170750d2838bd90d39acaf829c11d3540b026446e4212c3a7f4dba9f043953ed1e6c25dbbe48f907f6e84fca5c1809e7191df3e489c36a4af1e9a074827a79c038b71c7a4079bbf973bc3813dac60a29fa5a2b3f35bbdbe8b6d95f306257412747755c55eba8959b70b6b8aeea583a6a5b1e9418e169ab3bc3dbf43663cb1e3cad6f66b4c95304625688733f330e9d767ac7f69ccda3366a8709751541305ed9495190a1d04a9c1e6a52c1841a53c0ae71fb18ee07cdd593374bd20bb28f5e22fa1373fd7389b4a1a4b8f7ceb16df1b820196f3997428a08466b1b210004b273d8f45c69dc76bca8c1fe504e73884686faee1bd80b58d8a6694ce7b7a8331b8538e7ca0cdf422549c2ad03d627b1a431f420b52d7a91a2c848931a75600e82b7ca0fa54ecaaba47f9c735d73b3d153af394bbc6b11850b3e8d062b22443fbe6e9be3ab393b802ce06687021ef52a12c44010a2c365a5002928aec3e08f242500da7081831bad540ae09b0023c8ca126daebe5655daa4e837fa96c125b6da9726af8a67011a9545da67313b7b57c3d85baf98ef00d630a624ea5ccb40498f6de3387810c8ecf66ae80487909bab780b6475f82827926869ce0e32528a3340abfb5ceda97042c483df4977a30c8017503c7d2ea8a1f8b5547188f314636be9683fbb2f1cd01dde2f4e03151c0e61f2035b7d0bdf051395d90d6f81d954a08a65b3416df46810e61a4816513475b941d9ebcc4607fc94186f5d734ce8041cb7392e504e8e0e2e0c03ec3925df8f4f9c765efe440da00952b0caa24fe80a669a222736c2160716606d6c054db0de9c53a322a1dfd1f1583b10f493a6d232418d383dc3ddae6700ec19bb540d3c691d5f5cec00de289a6d6c2df651f1fdcc708bd36a74f3e3bd32b278e269e48efaa0ce7e0e80e48232653d4ed9af8ec141e08a80130381f39a1d944bab1246044156ef5e835b51d64e1e367df04ef35f5c31cbbad860d706166275f3988b1675535269e9d4878d9cb184fb6a5116facdc6f64bcc0e5944a39af4b1d11ff4dff2e29312b0ee698ad788eeb001403f84421c8ee01009a2d43454446fdc1e8d19a984799ccdf0d5d6b559a142871876837e32e2676a5e6e3677231ee106762a1d49a85b7f2049ffc549eb242f8694d49d741c5766fe71e4ef8808ce8aca47d399220eb3ddc81e4bc5a12ec9553223e796662544a7645e64280f64347680ac49c9e1935afd1dd9e05e253cd9e8a463888892495301d5409cae0bc6a0521d111c180a92da731689c5ed248ba0f9be4c08550769da7e8010f527924e50052f918771e8d603ea7da234730dc214768c43801dca936823c8f77e057c27381b5834742afbe1def8cfa18c09cfc069dddcf668d199a606947cac46cb07ac1cf96348b58ebe9024843775c0d7baf9d51d0df1dc44ab6d049fd1cc4479b91ba2ce6298a59dd274f942c1ed7bfff0072b371cc5d271a4235a574b99a2bd68275539f7fc66eab374da98a9ab0f902b71f6d49fbc268a97cd7f94621da1c47024036f17d8af9ead7b0878bd1dee18d2388f224ce60964a9e11e941136cb0bb20e49d873dc8b99c2e6d47b2b77abca3b838efa46c8e44e4b14070f1adb9abe344163bdedc969b65cda7f2b5a64272cbc5b79abd57d6e002562459185a79621f1cde4d5403643a4319b667170c50f7bd3e694e541672ce8e4e4de3057ec73390343988cdea30bcb11b738c7c9c5689552d2c1b14e3782c983204aea4ebd3fba146a434f8edd8cf1412490d37e370f820418480c06b0763d07ded316508ee3a15cbf3987cdf3f13f5a97def9d3287ee5df5d27b4c26ce63a78ac8bdfe343d08ef9db5f5f34cbe5b641375c47ef39c32c2ee8ffaea7b4d13c75ba72ac467a0bfb28078684b9c96e809d49226e3f315e26afb81208a5f6e71050fbf82023b94e1d6c97eee30e5bc8beabe4e34faeb6f13f86d4cff5ea75f6ce42774722c4aeb6d5dfd75a6ffeb6891bd0f16a41346757272d4b5a02104ba77ec32d3080cfa875cb51d7701749a574adc3aa300e09098e59b913296ed2df33d3bdcb23bc3d37bb290ce73c502988d7a3ae3bb036c3db8bbc024292ad29564f01be1a018ad3a4cbf2900812a427d73b035b5489c26a72d11b8fbb2b4111cbd7c10d08851e0e54f375597c75bb6fa17d27e8b361ae8ac2279e16951cecebf03993c5fb9a9e9e97a5faf1c3e7667d8eafad35b08df8e284acd345025afc1a904ad96840feb83fb3c038c52fd1d9f01efb19f5d2d349e8ec8a42baf044001f0ead06ff6dfc6da3b39cbdb1a686e52cbb58576feb3695bc7f053f0a7e0568f21fd1a83374eb07b25275f41c1d80101023b640c9bb51783347dea6802eac0a1270dfb5827a57425b27ee87ad0eb43ad0f4d96ef04a7ecede10fc43ea0bf4dcc72a86dc165773ad1250baf2048d6935eaf72677a3f48ad3a8be4a16cf53e4fc9ac1d8a5737a74ea0dadbc4e92618b48e73c6d5dd216fd47e1ad7d33765d2a9342fe2593b4a490325d6f9e0773275365fbbb3e1fb5c952875d02b1aacf27e50658b22c4513aaebab8ae99ea20e642e714838fe848299e2116972c049dc00e019490589fb3f11b1d5a5c8ca923bac2678ef3677086b055e23a084ba748b6b499f3b23be8a0a877bc163605aa9fd13a3d736865bb6b773af4509498b92cc14221586dc267480a52e5fa6bb6d3c46dfa41163d54344e769fa1ea070deb10e660b76606d078ee32603704f452a800edcf8a1bea3bbd98d095f155aee9eace49b0230051a11c90232d8cbc2cd1d053682a75f02ee8f47b1583c3261e1aeacebc07aac75d4ee467623c598cd9ca54e532120d116fcfe5f596b1126344b56a5d2e3cc541a2eadb5722478d11312ce195cc7237f1275ae4b0040cdb0f421242d8bb9c99f527e60ff8b72f2980d4d18bd9d6850717aaef18d22b056cc9e424c147d39e201a3ddb5d436a08a0287cfb973c98095eda20265548ab6476897b48f309cb6c57af254e099cb08b4be46e2de96e922a87633f5db96f30aa6254f89b9737f7f58dc100faaa0a5bb60acfa293a5c6ff67b2e2b33478dc67486f778001f9ec83fb867277d17d0951dd60a7076f21db088619e0301052d4175101b4dceaba634f62fbf4d063fd9310165bb890cb32b5ccc704de855e2cf1435194b300037a1880f7fea0aa771218541a04d3e1e5480757ce7e75a38c3829112cd996b2a769abe3339a7cb41845c4910254e3156835b3e1aa87321678bfb645234568099a0ec8248b604832f50ddbc61bd482654459f8525827078fe21b58ddd2d7b8eb2cc21a375634d5f3ba6859dffcf4885ec8369eb2b62a88148b4667cdb6d5f808c3f1c730ad27a2c2ab3c4cf1d81c97882c0f3bfe8452dfd454f37417765c706a3647e9daa5a9e5cdd7b4336ac14b5c45996f5285d66407404c00103070526482fc76d48ccea0579a74ba74ae3d68507c65694a21f669c998575f3cb407792d2b5a2a9970a9098f52a56ebaa8655927a3a848ee5a6e840ae9474d8e05b64571126dea2d333d913d5ca7bd1ba3b3cba76ff92880f2e9eec6ee393dc11598ddd89aff2fa5b1340908b47c534e80ce7a78ea34d90051810b7a685fd1e6190f83d9717c313bc4e4b5323ccfbd642f82e3b537602f089923f0551bf9fedcc81e259b2b89f29801189783b72b24406a0d3655b6879f4b478a3b4bdfea5d381256a0f603cc9a026c203395e58a2839ea7db41c0973b5bf3d195772ea987b6aba8a48587cab30c7232d4e5b6e00b4cc39a1398d0cf59be0304aa20eb830b2a5b3aa46de2f5c182b9787e87dfb2337eb0f8d1ff06dd5c010501081717db5645ea0322d725a422df1b402e28967bd2928b3e0d083f10190127a2b45194fc7168c0aec0cf8596f0e1fd90c776408bfa6edfd5c0dbe2bd286dcead9f6ab4e32657cabd9b7f80fe1d3c3562880bc0355023772a80b22fbfd6a1349b826140d225043159348f516e8c2dbdc6fd6b5aca09de5be86a1978543bd561bdeae74700a581fc71e468996e393b640d0c4ad4eafe3626e7460df4bd7cde594f9426711c4f515842bfa122d782bfd4f2c402e3dba7d46e9a9ff335a6d554b5db6345103e213f1b179462e2e25886abd95762e7d43aa997eba5a9cb66d0b495b34073ce3688ada2ef4729fccd9b4b562de75155ae7fa01e293e8b9814eb12ee221f1acdc12d016c19e51c9fd590761c13f7333776fa76843860604f783f7ae4dbe00b45f03553cd4de59cf8e1bbf47d1d112ac91a6626de8bf33b541527d68ffd643600f1a4e1eb8d4e00c9686086b49fda886a53f19778e30b7d05296475191278ed85b7e8c48dd9c55d2fd4e20b29c5c720de6ce0f9c5cf8bde32e1f78f1b306a105da56cae1d95a290dfc5e44c464e5cd6655125485bf69e0d66f739d89213df109340bc1412bdd1f39a644b6488f039d39e8b326060383a7e70624d0641191221bb308e6d1b9015da8aab49e6f56723212fe6762001b5951d0a6e4158785205c576672d098337ddfc6d6c1b23676aaadcfc1211c73c1157ce07011bb3b1cf4e969350f0734130bb59b7a48e645bbd4ad2b3310b1a4ea9a6e21d2a7792e5ec99be0ddd2eb762b603fc9d8e946b2b541d3de194377f83366c17f32bd35f655735f98ce3504790acc36665f076b1296fa53fdc287116c9884fc444b67a463e6266b71d8de402501b9cb221524491c1318a9447d30130e3ed4249bc1941b4025ab491d9b5f2d5d25902eee8d4903b09f86fd19f9dd561ab86d857ec46d74a5cd0e643703460f858523c87ff59a674b15e088656ab21bef82224892f256483fa9bb21003b18f3d457b0e4fc975cefe49db5d4627a052eb40de649ba32723fc1a1f5c94f764099519a2ab0b3d396cba374ccf24faee5dc578dd7cd1e5e3365876e6b181ad8758a26c0740f91275b41ae11f7acb23185b0a3bfe614a55a09e749f2d3219eadd6a2237392d05629939bd6c316bc9e9239d156704032a7e8e3aa1a22b054958f810b8ef28cacdcddb4a186a9382853d817b1c44e51c9135bcbc29b43fbc67d5a650b5173af08536a1c4c1f477ac02d9018341f976889a172ffada7b8fd843ee30d1be56310606201bca2409dc047c374d90c3397eb8bcbf13674eebaa4e3e060f895f22f154957f3cd90796c17da801d019232c45ba74ea21516cfcac743e1586d89a376ed9dadcb717eac5bab8153607b122c0ae83dcbcbea86c788b25b22a3a949fa1a735d956a88804d547fc1e881895bb28f68c3f8f63487d6275547f0a8619412830bf3444f79675d0e0f301a1f1c89bda9a4dacdeb7c6f781470bb0625ea86e74a0848b5975331f9e884ba32ed5b14fd49615817cca2a2f657b134f79868f353c5caa728caf79ecaa7cb564e97aab05892b7d642a459758162f41e352851b7cf53aef35daebb7ac0042825b3e34455928be5dedfba2b1436012572ec288faa322c2f0ba79b48bb51f52ba2eeeaa3c04ab0ee9447db124fd9d1ef927542250dc185310082a94435da141183150f54c86b8541e4061c74d19b54ece42b7300e54e37ef64970df42cc4788a253602473cf2e88f734764ea8eee9d622e374a6971dbf713e2c79b77f0519ae5cb9dfa9ebd6e1c849ee0f2c2f9556009cda8ccb20ae0525c5c5f69340b0d5844e52d3f6a528ce9a9924b2466169eefc3547bf9ee6c7505472a4d7230559cb3d86d8d9b9d0d145e76c25c1cf7554dda09907a01987ac0430679d1846886bd391de2356b0f16683167efaa3b87e3b9c550040b5392fb2dc693763c5491f8a06d9ee039a38183073d205611e0ec41bad68ddef663d8aa0b4220ff0b17c7196e1e47f04b70938dd5e6910fd9f779b1bdf9848a60dcc7c3f4d4e9cac310e623ea69d513ce018311291ee8499a8ac04105ad3a58ffbb1a55a5e5ea3991f3f4c4b27e29a197ab43c554eef210d47fb469f62af230b64696d9e6f3b3ddd28d68b4967aaadfa8fd111e28756ec79221f4c29627d07523518853e093424041a26cae9e8dfa4ddc6534ce3832f8f76264373cf04a3fe29ad5715d9d1ba94cfd2954711df3354fb4d138e0cb0333f283e2608f14fa3f939adff7afa66aeb69e488d5079e257f4d1c7c37c8f64b892e8221c3f5c172809b1541050c81599964f883c1fee4998d6db6d2bcd961f18a757d84554dd746e454fc5bed9f90d640bcf66a2e20322ac9d1b78f6a012d4d38e7544598f915d4b60e55d2808266124aee3ba77f5b35d1c301fdf31d970baed71b4ec551184502586618e1ca9e7839129ce6881dae3b3cd7b0e41afa9f826046cd1a1267fe01a3a343c046167b6eb676c23d10b7aadb359a12681bcc2c035a988a835d40125a4d07a73516fb1e881caa349953e40b27475aab5ebfbd2d62d5afd41ac5acd6ec938f074ca8453b57c498895276b2b01186cc05da130bf94177df753b116112982c6a7437756245661f2c60c68ccf27216defbdb7dc52ca94640a07086408f507b65531c62fa16352fed73fee4fc6186309884844ed5aa61009438923427032850a18bc85102a9c20220835f460c7ab092caa04b37f432b5db4b0cf414f54a15344112b511cbd6c8ad0c0053cf821f60510a6788541258a2b5a1415c109142f9b23428228e2441837e83c5102c25dfcfd4f4c401c535b05f32d7a12a02fbaf9b0f1c02a2d8a26c4aca993e3ab76b9d25dba6f3badea182768fad96ab0e1c643adb03c3d4d4c4c6e7f97ae20bafd347a24405f1b8fafa80d361e135015b13b5df268dd2825f10c03ee7c19a22236457f7b9bd77c1977a528f8948234da6f600dad9136aff9374a00622f029835df006ca37433b09502fb9d8a7e7eb5cbc98e933d23bba4a5eccb6ef49ff3477ded69ea6b608d92ec6be4bf3290a67e8d7f0553940b66cda758d0d28d29e63da1c8785b8a74a91ff4b34f758aa6fefcfa134cf9cf4fc5e79e2615c1d40fedb74f613e0706c97e663f411ebe921f64be269f5fa145417e9452ca98236794c22c19a5fc28a594df6544f4441c8d73238eec728b949dab2ccff8cdbea534846ac9d42f15b1a1bd596a7ef7fcca1ee5aed404533fb6e73e05ed3b30887c25a9999ad9cf99e5584ed1d0f8a72a7842df08458eaca51b1b53f365aa7e6a8234f2b7148d6bf37fc8df9e02f23730559f7dc52f0af86b60aa82b655d9a37c953dbf72740e966f7f0f0eddb3c3e666289caebc124cddf66e1b69d57c26f2617d35df65c8364fef7857523ffceba7d07c533ffabdc15ac1c669ef84beadc3acf9fccd1b63be9a13655be59264e377a91fdb734fb33d07d628915fe3bfd16c5fd3bf81fcf9654fc79c110a66cdbe3ce7f39cdde32d67a0cfc9cbf51be0d20f3dea5af18a7e383dd6605f71b3a5883ddd50da21d76574e9873616f98a7ee936a86216fd920ac2c7e99810a689744c18c3b861f04c5f9aeaf7b779d15483a91ff5e5d3d41a250dd26cef608df6dbd7705fdfe6459fd33eee9bdf36e436cee5b2aebf7ab9daf557875c4eeb7aaba523d557f4d55f76b58f5f1b0e7607a7b297a91ff2b54f65208d7c0df4af9fa2f10a56550e7607834f8559f4b36016fdbe699c86a9fe522aff613aa63fa707a954ea477d7f9afa0e065112411affed83d068cf8141fc379087afe867afd47cfa8a2ff622d037b4b92a308bf28b3d09cc97f5159d2f2317306c7fecf115fdfafd5cfad98b3d1d3e6ee4fb7c496196bfd8d391fa213f7b1af999cea54fe39fa3fb05054745ab681c6a15fd08c658ab687729516c37c2314c6822ba2c300b027f15de04130ecf30e066cfc33dcb3acb381a3b4a3707b3b22fa5c086ad9ba15e643a26db4860a38f9bf972befcec512fd235814c6855f6f3cb91636994def590ab71b2abf54e6f87cdd5dea9c7a203dbf5eb1bbfecb297fa319f7b15e477f1ab977a3be24dfde0be7b1aee3bb046c9f635f3391046c37d8d7c0e04c1176fc46156f6ecfd98af1cbeca36a3cd25c9fab75aa57db14aabb2efbe48e4abecb9afe866dfb108ccca9eab2e5858d5b72acbbe04836d71ed712086618774cc36e472e3701d42b35aba1b0e966f34116548841081b9f2a25eeedff9b463423ba78e08e3fed5564929e5cb7eaebf174ed051a31536be3c42ff887cce7482295e376937fa0e07fd29c8608a46bee6f73d32c11a11bc24c8be1281db74370d98204539924b6a682fb2f16da4ec818d4b388609e784f18c3f093cb071c26e5ca2dde9e119f911ece71e9e21e13209d7ee04f548b91cb444ca35c0e5a02528b83438bbc32cff117e603bfb2dc633de092e1786eb1f3f538c593e6130c198b58139d89618cfc8af39bcda9deb3fb798498aeb9f6db1eb305cf709e319fa374ca13061604f18b322184a26377e18650fb362cc65078ace046252895ac5a1b3ee25349420e550acf562862190ae13436c71730c71450d3372f03081c7d01034f8c19a2e070de14405873062042dd28721c218a2c80dd65e0e1aa20413063b038c2dac0784266e3063b0dde5202532b821034d1e943cb921aa044a7cfa4549125784757737f82db02c978394f4d0858d713948c910f7c28e00841ad8aa4583615ba6702dac0785c87a3f14062be372509222385897cb4149467043069a4992c06e88ba924ee91c520703c0125782c89122c4086cd03e474442a4c0c1c1082ca2f06c76b7cd1146559c200558d4c00b1e7a0128186244450e4ee830f4eae601090d8596d1291d758390f8205e0e4222744d978390dce0fae52024433776e4edeeee7206e92ea59432ca51cd644f7477778f4baa8441e4b2a59ca939e5a3dc2523e76b70b78c0931d1a558149f8ed2d359f794d1da1629543213ddc8e8ddb27a9412c631f3b794d265dffea65f51a54a952a55aac418ab4c5701e7488ee4488ee4488ee4ee48d38d4479a3d52a414626b63bcc7f8d56a954b2931d23e3d7f2d22a14ea68329d54f37a784c8bb533a7724ec94c9d99bbd2356accccdcf40447544a296994a392971363ac1265747797714995addb75a06d54768bdd2e87d4b9261191c9e5a02792dcbe212a9409ea99425bcaeda0283bb7ff05264630d5a36ffc1d7de3778fe0fc6b822f5d6bc774cc76f9b98ddba80421085a18190d91d2a5f478e8973b68cc39ddbb93524a29a594b2af04c30b48279639d260ee11246a0633a553461602aa018152f7aca5834507aa3a96af0cdddd5d76b099f1b0546e3b755c27e7ceb55ee7839267dddd5df29478dc25e5ae783eb0f1a7e7ee1d6c042bdc7d042b3866162d46f52ba1ec225064169d1102aa195119eeeececc9a33ba11acb0f13d474a2925aaeb605d7430a73142a76844ee450b1bdf75f073c72f0220322f87fe7997638f912353145cee37af4b7797eddcd7c1f002b7c1da2a18c73001fdf57e4559b6d129bdd5ba2153c2bc1c7404d00dff9bc264aa9c8f59b9da522b0e36861980b93260ab55f1460e764e21b25dec8ae5a05013f014218d787a26929d97837890fcc0d30310786610c29a86d045b0568bb98565a1e20bdb0234971c19a286233b14c9111de6104788d01258962f6eec6664c4765464152b89bc8aa5564c1f5b92226760633871622b931e2b9524b132081b6ce972500b502089604f97835a50c38459fbc534010bb8b861952db0dde520165c714306722416dce086f5151b40b50fa6571d912a638410aa548b72b91c148409aebc1c644417377c2d069cc98591bccb996616555cce9480cb9918cae56c96513aa7b51607ee2e7d46ac325abab83b7b8b94eeee524a29a5949287e69c73ce18b3b2d039e794524e79caacbbbbbbbf6477f76f41fa3469b2b4b1c771d7719edc4aacb973b5d9c9dda553960fbdbabbf419c3a594d25573ce2a5ba494ee02cea774cacc3927aa65d4ccdddd6b8662b0ba7b04594af912559a9d8027382eb6bbdc96eb2cd74fd2af9c9366dddd55ebeedee24ed401c2715cc7a0e779a5cee6826f73b9e6e68e6d4fa7130b0b4b8c1697eeee211fee325e43c60cd408dddd3468d048a5522f2f2f24744c020900e8e2e71fa7fc104c66f9cea08f2923c196af3885827f3100a0cde5fa73b95c9cf7bb9cf48e32aa6a88ed72c6763969bb9c3473c9ccb456cddd37aeab317ffaf439e7acdac6759e060332e7f4c1753de7f498b9148652d27965537b6289d1e28359fc3275ce694f2c315a5ce69ca78e61e6182d2e3266a0e69c2e3266741135828bcf3965668d39e7a43266a0e69c23702e314670ce4923f5c2cc2430730c31001dbbc4d03f94cfde7de12767a9fa9cf3c60d018800682781d9a7d770ce39e79c73ce2b93997976328c90a16a546666ae9a8ccd3b1924cdea6bdf6028c31ad6b81cd3e15aba399b59ec31260bf3b3b7e03ce79cd364ade95462f162742823ec15aeba48bad11a1c93a1cda8a86c84ae938132d39829f9e2ddc930e59cad395ddcc78fa0f595af5046d8f83ee79cff600e7c8e7c8e7c8e2475f9532ee1b4e311932f7c7c8e7c7c8e7c8ebef039b22ca7ac469be5c0c667397de1e3e3e373a40d954e507a9bcbcdac45ebb8f7de764cc93bc126ecab41807617e35111c7b9cfb87df7fcf2f13b95d7437b0e0ce3dd400bd6284751ec0beac8c7c7e7c8e7c8e7c8e7e80b1f9fa32f7c8ebef039fac2e7e80b9f234d4a392bb771db17b57ee660184ff039d22273fa726ecfab48809abdf6eef5d8c0adb5854aa78f27a14516547680c5d115443ac8010e8ea61cddc00a1b1c1d0dd5800655503183298e8e8e8ea4883d8c0032197e907e907e90aca5214a2925525462e5e707e9e707e907c9ca0f923db5c430e1f4dce914e329c6d3d797b3d6dad3c9be3dbdb527db12c3cacfcfcf0fd2a937206cdc6bdbb669afc95669203341628284e44d304162828464c5cfcf0fd20fd20fd20f92959f1f242b3f48567e90acfc2059f941ca666685a64e8897ce8cf6fd4122fa41a2210a28a4c4e00977478a22e4441350dc1de989bb230531b184bb23b93b12901249c00089238c7077247747727724774772f2436bf0010040cb8975c1abad36342acc8d12809e08d568974a75043583b9b4f14f4f07f7d3dbd1d7a4c988e1f2fc61dcb1393838ae8863840897df038c231a01410d109e313d0b3733b8fc3f1847bc8936faf9697cf0cc66020b8b3dc50099592c2ca7f82e5fcbf7c59e9804c748e318b9fdd254f258e8c0303e29e28a3cf2f0f4b42a496c1283682df6c424b1490ce24944e23692c803f32cbddde0de72b9f85b8f7863d7691f59ddb3a783eb3870eb8ed16d60da3cd3827ae9189556bb08a3aad255389dda3c55201b26441bfdb505068688070f1f2a558f273c847c3c800605a652617808499e4458af155b76adb756274ea736391f3c24242424d32e1efca18d56b118c70a357846fbac521e2bfc47cd850c00c140bcb9fd130cd9caed6fc159288a391367b3a259a9aa308cb2ad6adc06c6e7838554ad1e6dc568d2ce5e7b19d5a4267c1c181918a38f07b48ac684880305b6d14f85a7f460563fe151447b3ab46f6f475f195beee23ee6957c991f72979fe5f6b16a30d1c6d6aa011371acd8467f83b5840280614795131bfd662bc2c6e7ed0536fed664db88a0a907f010dab61e1b7f5bb20db129e95c4cc8b12529c528416643b209b10561bad16ac528d550a9b6edc8d6828d059b916d055b111b29ccffcb7c41a148902dd602a0639ef12a1b10df6d3bf6fb2f000020e1e56353c86aabadf1a2240e3f2fb931d668c59729c28d5f820a159831fa6871638c3a64f1078a1ba3509442452472a2848c1b462a71bb89f15bc78814dcd83edcf8fdd348b42be7d54f3a46e5c6a6e2c636ea98d2c7ef2ad161377eb531c61863d18d4637f6ce8db1898c48724d2f3b46e69abee4e930d503dcd27b9e8e92e7a48aeb7de7e9f06a177697e39cbce0723f4497fbcdd3c12de006e8b56daf793a36edd90bad1ee1620ad8ab7637ccbe5a71331f1aecec010e438a602f5a8412b5577023842780602ff9b21c0515487e5e70c50b4670fd1b95499c6b8a9e108e5bb6fa8d3c64ca694284dbb7abcd0e4318c21558c0a0e4a6c805208ac0d3f3430f48247985addb3c1861720417427028c2b2e48a1da004618103242f962d45ec06352144bbfd3c682c10fb63c7e699be32862bdf7d660aa6c1f5af5b5c0f6ac282eb2ed8e1a26464314501b73fead89620229cb8dd330b8e6122fd90639599c87e402d1955eb55a8f77182bd1c70e14a1ff3e78c7d452b2303709202ee9c4be0d419556ccc89ed4f64703976f3454a981b2d99d6cb4c9669dd68b56ec8b4645442b0f15bbceaafcdad562b4685b3b3b34cf421e32ba250a646abba8456c5775026c7bb2a6682e1df9eb50421f62f5be0c699e39371577cf5e7005b337290e155d7aa5d0e6a42c87590e5090515ecb48aafcc0d0291b8d328303dc0e126069cd7eb24bd2601af26f5cee11919777eebd031433ea7bb6c8f8c1b6cd8399dd342df49da35757c0e5130ecd87d62919871d6ac715a35bf820dfb9b56cd86ddcc9f9e8e2c1a7d31a9554677da4e08965ffe9de311088502433bb54fbea4e4957b773da340ad9aee452951441c1e45b431a1e099f873fe0bf1d2af73e6a4b375663cf5683fd00f592e7fb30be52bfa28308b3eca5d0e881107471b215b1157214f71e9972e0bcc82c0022bf0b040893eff3a0379a0c0864c14713a266c11a11fca586085a637282b5c85ceaed6ac3df2ccba7543260785c92736e7d65861aa941dcc00d8f58357f52bdbe0d60f59b7f28d0ea663685a555f752b97549fa66380cc17e40dffd2f04cf6f527c033d12551acf388e302cff8ad0fc4f4030277c9aff5cbe1abfabea37423e88307cb40404aa8e99890bb8055549df537c0337d6d5ea9e84fe3600d07d670ef5fb3bde4b68f7efceae568977559d4a47716b96accd197602a7330c5a568dc4b69e00ff9dc53403e0752c07f0341e0abea0295d964f8253f9629a163faebc7efc5ebd14998559f95308b46051f6c5473b422b19b11b9ab83682637fb9f2e6ee972cdc3acec391939d74a566c7c0f329ffbac7e10fadd7359d749da957dd63a4d6ef69cd69560605147d6ab3e6e66a0dffd0cb371b62e2c6f3cc3a54fc657d97b5fea07fdee69e85790663e07aa7cf54da45519cc4703e4b44f25c4c6d7b477d533a39ac757d96bcfd54ffbbe5559a669d73f7b55d639adca76b0614cba59f6bcca3efbd07e04431b931a869a539895e18059d927e91eb0795037cbb28ec9ae459a0118d52aff16cf6cd7ff86bffc5e501fb74a42d80ad331a10dbb1a6edd155f6e8a25419f8b35a043eee2fe71d7e9d26f23b688671870a97c4abfea52b6980446a32a55babf28f4f950c74ce1191c78eff04cf651c85dd1a89a4c378c420f04afe87710491bfd4ab7995df6d9654a717faaec4a7160ea47e9bde73890c6fb135823dffb9ad92f3d1d6dfa64ef08c106393dbf8298be3fec1d7e9dbe1a252998defab02f017e015dfa26b07fbee6f1157d993e7e953e7e791fbfb42f0586d17fe35a87aeeb7e037ba7fb9ac7bffbeeb7ce69550786cfdc7546bea2df8121f735cfd73b5f1b6915f5ef9d8ee99e7e1be998ed9fafc7ae77dc155ff49ba76378035ba7553374a0df3bbca25f2beda8501ffa7c7a3e8559d4e7be106f78ea1d6651c701b3e8574932ea9d4e9e80b2f680e0e83ba76d977fb614b1dd272fa7752523a629b1a2f883fa34b6d119462b97665ff56080b09fdfe875dfe95a9ee99ec618b3e873e73a78077a4eab4a94fbe9f538c0e5b8d7be72fde6bbd7e30077ceb9f1ad269e99bef304274dd17bfa49cad952c4962e3f97c9b0c1fee56ac75ff2b161c7806494600b82e51bfecb919d4f9f7a3a7cdcc857817aeea1c002b3e4bbd71d45c4216ff898c333f1e5371448dc17e27d21de30e6748c59528e8059f2b128c1605d902f937054be923f3f7fc98f9e04e46bbe4a7e0f75cc57f27568956c30e674ecca972b5f3aa665cefca1cfb514b1f5f227715b8a585a92a1a54ba9b551f53024b0e1bb62122f9a84fd5036c6dcc505cff8d38f3deee2177de62c2e8d433f422ef87097f614e4d9893a1127c2923ee4221af21057eb06764b039bce130a3bb056ab5a4470fd5cece1d843a37402db2436d1b1fc1c3790f82d4a2717bb6a37ac3a1685d37db1a7c3fdb58f37ada29fa3b7cf87ca57f4b58f5b85d32afa158c30ef0aac7455a51f6c8cafd82436695529c8c68f306056739f7c557feadcd7afbf318c37a706d6e8d617fc61b73ba9d9eb64b67f35ebec0a7168858e8954b4aa76feb1f830ab7ee53814b33a3cc3805bc1b0dec67117732c42edb4ceadcf0ec23cf8adaa33fe30ab7ec904368cb1f0a9e8981066a87ead55e6071d13469f5bbf7e34f20c0c63d2ad0dbb95d68f3e3cd3b77e7d16b49089e210b3ea4befc77c4d30c67c5523121128fe58b1e1df5a9f87bb94f4d7f7e1ae20f24b5ffa20f33bd3d7cfe12ecf3bc1e66a4f61b7bfecc62861b7bdb7af82e94f2bf08cf6f52fc033fdf5395974ebcfcfe8d66f2962e37d415eced4d93f3d8dfd1358a3c4bfc67b5bdf411afb35a6b760e3f8aa7e96ea2fa5fabb9f190b16e0d12aedf39b56d53f7d6de4abfab6936efdfe3890fa31bf7b0ac82ffd07eccd7eeb66211e1df3d2725707a6fa3d95bb4a60aac1d48feebda7e9de036b94f4d798befb06694aefbd07d6785f7a9b577dcefbaaafea9bbe3b2f473bedab97cbaaf4a691b35a4b474c7cb52fbb5eaa04a6b64f7120cd7c2f4523bfebd7bea6b6a7c07cef2920bf7bf638d0b01ff33d3016877c555f7a31d6aafa5b0e367b6122ccaaef236056fdb842ab2a0ba0055a55ebcbad15a663fcebbfbc35a236b24b3ab13aa3fcc4c0664c7c9240811149d0e04636c610680cf6944518d656e13dd6d4c42cb2dc1161d86e89bbc06a2dc842071f60108314c29e8240772ca78514ba812c52850c98f40085eda2d09b243ce7e708124a2612248e2881c4ce454287526d4a6f06ca61028f0718ddf05b506d4501b5b22d466da99d9551af6d69c15c991bad22c2c90d31865c88e8a181c5899c162280c0e1d4444e0c2276b04ec4585a95082234985a32ad1b324ffc3c0174b2b545840ca56a6b6785726cfd8206af8998898b117450864a59e0705172bc1bd4b041e1e9623668415c6dc120875a6ded6cd04eaf98a7573508b5e4860ca6b1a0062af453776698403c590f42e41230ca248721ae446cd616932144badadad92745b215eb151a624ba6756fc82cd1d37257eda9f230975ba5f10deb7db2e32bbe359e0237c8c8d8d8e00303185c1064c41426425004912540b04186239f275a175204d053f44bcd06d4f7774674f7cb2e84705bc66d3aa57759c74b828c085a22e889dbfc13b473ebe5a0209d2d685e5649af477f6195129c3166b02b763ec72377849045b2c6893832b079ba069e71b0856096ec5860bf6d5fa9e6de5cddfbebc70111dc789d03f17ac4f1427d202a9ee99b756f021b856368d116ac921f4a294de40f1212483e11e299eca9dcb179c9ef9f271dd30949e918cfc42fded2c7545edc31f5bb975d1035b4b74a275702c12bf9554727779825dfcb81e5564967f728e5adfcb200b364bcf4934f3ef9f3492089846cd29fa446ee923bbeda420a2dea18198555f2a5d1952f4129c42cf9a82a5043d66dcb57140b3b41db42591e1c77556bb312d842be92ef9fe481ed5c298db8d7eab57aadee5ea9cb9d56c9671e9629d6e54bbe94a9da2a29e58e7cf9235feec8973c198c0a8e25f39c3c27cfc93cbf504ab074840ded8dee04969f654ad581e56fae2f3b18c12b1556633d56a6b2f7f450add6e610f9aa634fec893d158a0d1ba88b228e098b36da5dd9770cdb94618b8823d38933069ec97ac876b8a1262443151272579d01afb61bd3b2d84213da81ad429a50b6c345e576b87dc5663a1147f522eb81672a184954d8b00a25ddfe2ae4ae5aad75a11bbe2adbb9fdcd04921b0376c526bc020ae2768263e42f011491b8629f238e7899891b462937f2302bfefc629256c51e07fbc51171c1314c8c15587e6ec7879e9f1d1e1f3a267691afe2d7188b54d188d2a7600d055334b526fb0adabcba48a668a8cd2bfb5234597d9b1777a7d4090c858926a9146a964a410b425f7b7e3190ee6fc1c1140a346e3f8ddb0fa48586c24493dbed1f435942cacd3e7e51175229d020dad3e757fd52290479b1a7824c8a069581442a68ad144dcdfb2a7e06dabc6c5e14ec215f4d614306b2b3a70f806e9b3e6cb7b02cc9572dc4ac2843436e4b71fb63f3942ecb15b6736a8eed9de7e91e9e61c2382810f1a33b2e60175d01affa5bad021440000248a562c460d40c6c48636196146300fb2ad3a91615e399d2edcf92dc4577689644b324d7a920d5a132b0319a031bcaa1d9e3f3c75ddbf7948161601c3660d7147239c433f39b22dd86fd0a506073b81d9b36a082607bc0f28adbcf7938b0a137d9015eef61d68b768dc39f692ce270b089a28d297826828d4516c69508cec0b13eb7aff6f8aaa790bb680606affaa7900cd5069bc3ed4781d1ed2c892255b0f27c5952e605dbe8474d61bd897466918efb2cf259e4b3c83dfc5ba90ed57198af3ae986a8c6c2861c9b565a35642b2c4b6a557b50d854dbcb5076aeb8fd91c67cd5f567ec1235515b221afbe1af0a3a6c061b6649445992857940760737dead7bdb7cdb7cdbdc7deb57b9ffdfb0e51f3986afbb4bc614433398410a2e908441c30545f470840f351c91437cdf711ed721d231618d5d6d0fd178df7d07d674608aa6fbd297c09ad2776ff3b26ff3f25234a71a0e4cd170a6b7799d409b9783a1ea863df4e3abf8a66f0a5bfae2c730626b3ccb14db5df653920ded8daee33ab4aa076bc3040a29a420e2c4111ebc78c5e7e12e109c80872c7ac00189939d57fc964c76f40aabfb70e3f38beb97fdede00b0384a537e51f44830b6e17a1901ddd9ed2445474f4908c222c4b0eecbbab1533c0c9c8f8edee6f09000f6084b0db6bdfad55ead7dfdf5dd27bb6e69070ec2283e5a0258c6ee845b7a80aecc66fb1a85ab34cd3344dd3b430032d37fbed73781671a8004d0152a2498c851ccbbe3f1bfa81e8b2100d446e0686addb760923464bf810ab04e1dcd08b868c889c4ac7b4140e0afa8157b9f17de877b02f00b1d78396601bf1c36a74c38853c42db2eb76cc2e7a3ae68c946a1e0c10567b6e556d95c6acd25e7b6f87063e115bc1b07f7e36b7970ed4310d461c27ea980d44b150e16e6cf72c3bb09c652d5d743ffdecd34003dd168200ddcc3bc1741d8859f139196c1861aec373fb7f68fcf097077e13f5b782a1ebdc08e4df7d25006915bf111348c496c844931b3fde44221d93793a38105fa8df817835f085ed4f10c0e59edbbe13e2d5c0cb6d3f3430ecf7b7b93d41075de82efb0fdc1561e0557c1a5024b891870ef557b503eb465ed4aaf8de0f6c685374638d56f1c76059c24e49841f23806a557f4b686fff8b6d8931ba8c207d621b07b63fde4820fa37d0cbdba1c4f624f54abdd982cc3225bcafa46d5c97d148bb74c4642a75dca6d1ead90d327fcf4166167524ae333038cea449f921059a94ed4a4bd5b46de3b8aef3bc52a9abc1c9809301d804c730e1949e8eece58f7e959ea3db151b79782649c768a58f60b3ef343b73340192cb1f83601c5187540fd982055b90ef1de399fafd42bc2f44ba848eaffa6bd5b11128ea1071b40f3adc7eaef499da8788a3a5441f62edd211fbeca5105f16ac11c1cb044a225fedb84b16f9aa1f27fc0e0c51bdd3f22626619f5bf12466f5b79488c3bd0083597dc329499de32e7f79007581a0eefcd2d72f0ee34e30933ee74ed7758858a6d57f8937c808933c998d92f0e2f6ed2b5d2801bb1da4040d2f4658d5e5a024a4b84ad02991a55d4e22368c4632c6cbef5eb2bccc8e94ddf392eac17d7f4bede57b129ec95ebe2bf121228efad18867e8cb979143aac7b63d5f1aa513d8fe928e6def3e477747f60647e6757a21f5e5cd17525f27d9bdf7dddc08f997f7425aafd29bdc3e8befb811e7f121a20df9eef58837033d09b3e4926bc440d18859ae845952fe784f348af1f54f4c62967c16f9a72f7ac12bd9c39c80b061b8f24b1fb301c21e722502c29ee14a19e6abfb7757e3f84a7e28233f6c85aadb81d1c857f24de091a3555246af36b5a9171cc384a79e3b7f069cc3a824acd9697a562a4533034000289315002028100c894442a1601245d9acf914800e7c9c345e4e188bc54110c32008a220c618620830c410420000ca3054633600f02fbffee3d042c86ee4367736aff499b8ff5ad82996e7e63cb4d7b9fd03737a446a2ad3fdc13ec61935b2aa671f806ad0c0eeff3961022d11eb4a1faa0975aceb724214a0957518f922cdda89ca671447c428f03ace6884abfb5009222323345c4f859d6c9ea0124ca2a1bb2607058d697b3cc0298a098aa14414f0bd2722d4c2130b3b978f880f2a71cdcc831ae28108b603a7ef1221a82ed99c169ac6a4f90726b1320346718df965d0a65124c0647d0f9d245b8dd378bcbe745b279fa51c81217dbbd82056efb5a89db1f1e9c9d576aac9ebd710b805f3673e81d52f35d90f6df9298e3db0ea7748bb388bf4c8f0a56667a1c310368cbdbc0db27a101b0f4821fc0da72f00543264ca03f1f541c1226cd7d41c099e6f14be410719b01786524661d748574cb1e51edc367e240cec41e39cf573fb9296a141736ff138944f13c0ad1635c763ab04c62fd45cdfff51664e98bcefb63ad1a95c8a28b2a7d0e802855c464b4a873b6a31922395bc844e5b0f1ca87d32f78a801578068d5bd7dd0eb0009c6153847b0ed66d1d68d418c20be9b1e756c355911b0845095c4e92b656098f6e94e858226143a360bbc511fbbb39d4a9d9a987c1091da18ccd3c7e283dfff11a266064b00f53f3d5cddf8748a41bf6546a1afa70076ea80634dddfbb6c86c45a58894a506da1e2d6a2fe0148fb30e659cbfdacb193c66be0248aa2281a985572faea68e1816acb202593dc8470e371c8f0be1ef8214a49786a0821b185b8444b934c6e62cfca6b4e128f07b9cc4328c4133198f7649747a04abcf0c42ea41904ffcb54bb4e4326e598751e09956d1d0c5995161138d3afc7a884ef5585ebfde644816d01d9bb79c83e18f9ea4ce218560c5d2866a2c83bbdc179b2a92077c504c3e1f4f0ffad7b75591a6c191262b1ca803bf628b283e2583ba643b6b22404c32e8441f0308e723ac2349751d92918a86c2a0578300d9cda91ecadc9bd05a27f5788e600e5ed6a498d9e4ca6e9a5019de6809c696555083a9375269461ae1ad795c320b9cd301cf368d7c39f431e1042fc4d942e63b80cc2635e4133902ee3e84697a15bc6a632c4c0b20d020b52df2207072b57fa0237022679bade538052966ebb64f8655d8219a7163438d0986ea55ccc2213f2710b9b5f00b8e896e9ff18e052b14ad7712fffa2b947c4da7310db25941a03b379e7f4d723ea4ffbb9046651636ddaee25163a86c4bc5579ffda9bc6307fa2ec4ac48511b10c116a07b64b111144034815e8434ad8a998a19fc7399c6619d267bf8d5ff2f145b73d87d1c0e109faf6a2d818c6f4e1eb050c9123d247ab5b58734e511134748cd4e1415cdb56dbe255db927fca2f2e6e041028278c265aa327fd72e0d5609be428dc1dc65ac68d2bd1959b6f4b3158350b38dafa6370085046ca78a9c6508a5fa5710158b140cca85e5b234d196fe395824dfecaa7a9d7eec4843a64825274e232973d8205a5f015caa3eb6cd3348d6d892e70fe81de09506acf23e354eeb6dce0dfffb26646d3c71c8f642185fac27ac0345e6b92be76cfd801f5ac6bd9efcf222ba21ba95b0246cbdb1c6ec59f0f1fda6707243b48d208c88c255612cb64b314500edef5729c601e0bbee686804685e9116aa141cb6a8fced583d6ca8a73cde595ee9fa1dbaf65310c0364d09404ea5ca6d7f2192a10a2767f468270cd7e797300a96f60901cb9b9e8b67b50cc769c49d59b80259d675d76875f1c426231b3c9f1a79a27979ed0f4ed1fabab4856a8be116240f9a494d721286f1e325545c44620334cf3587527638d11ab9f8a2039dd455ccd83ba5205004752cee3cbb302d989bf3aed21581181e852ddb26e3844074e30891bb852128fbf648447b3f83fd7af10399498621a12e3f8a40ed06f16578ef2a8e17936d2dcab16328a3a2a6f9ceb18e62a3d2c807334d5781070125b1dceccff0fc2878218a9921a3496942e0bf4d21d7b7c62e4d60e130d7a24608d6c22d7253a5c70713feae339280b7b1fb23b7430d2b19583e550e16d3f187ad0576f551405e78a9335ab3e550ab1ab76676e7dc4552470d56111c0ce7c930a7f2349b8e3414686e0b2f8d0dd8ad5279519f43be2491e168d2922a9159e44bab5843dbdecadc27137546c0e1b849d2d460a30da2618c259f57163b1ab92a73c0da92ae1db4233769003521c73bf0dba74e0e5a5e8e6d2de6ca388a5e05053a5e297bbd850489cbe3dcf437fc9db2480c59992989936502869a282d2cbfbbb80434ba62de6ca0bbce9ef83e595398b07f91653d35543d917f75e7ccd9068e75e89d1510bbd6a6b49dbbe03ae2237907d7a2866d28b8fcca5765d0d4526a03a059e4819c4b4ea11c11d625c70db71a592284a90d55983a8acb528cde22b1dbda742524dc922096b40c20e379bb96c78068746d16f9a342549448c332d9015286901621d340e92bb21aa90d91c584c36a52b1d7b18790971eeb6b1c5643761590a03fe5ad975ee314211358ea0223be2db56fad259736a5b0c2aaa696b4bb9273041b1ac585d237a211d747819bc5a1c90d12d491130518a8d14c9994683fa5f3ea6ff7e108c40e3c372f780bf5893619f4c377c89a9acd34846b60a35b13ee52ee7686b29386ad6ea17409aad4df299ed01a79844714818b6a79cc1c85560bc5da271d4d292f632b1a64fa4130f36fa745b53fc64fa2ae3726322aa6fe12c271cff7f0acbe775812d8a3db5da4870af201bcf46b7764c11101bae8e188c8bf1956e097cc8bb520de857dbba5043cc6cff8136a13717dfdf768f7ba170b60fb99e4ec3027d2b725b88d4a4ba6521aeb5a97c048e9852d90e3d8ad281a3f31fc005af438522695a95a419458e6545aeef6b121efaf21350f1af7b869c297f7144bebae6930573530ba3c200010d0e37b58aecc2634aeeee9cbfc72c46eef992ff8e98479943ecbf47eb5ba7e0b4ab764815080a1c580c4b4dd4790da4d4ccc49e7550c76e458b46b1268bd7dcd668372210476ade603bf51adbdc160882eaf6055a15ebf5d81358642ac4c59293d41a4a95e5b25f32257e7601c17a7af8c320702a36c6888555fad583b8310a07b65e1e230370d69aafe6d8ba941901e62a55655d9018c65608d19632bbd45306526b2748fa943d98c6e5058c900f63f56c31472c72458b0aae08d5b192384618074d41103bf4f411d2639765654378d791709438e54f3a0ee480e19bada2a1c1a16bbb2df30cd989c1289dcd298899ca4eb112203a8b250711f2bf5be5b57a88dc19f81c833d2bb65c661b835122c4a82b8ebc79415849464ddb6b7fce8c8152913a48d7e3fdd2bb1c6e24fd9bc8ae429925f7de62fd7017a22a69687ecea428b29835d311cc988d51d81820fea5fe64539af82cc613e5ae069e7f422faf813b4cc071de9424461e5b7b1d44b7becba86de6045d3c0bb65cdfd518bc62516c7929a69cce60bca38d5e19e181fbba431a296eeaf14b535ab1ef8ae5a9601a04aa02a2eb12e4e68e7d39c1d69a9b5d7c1cafcac8c930aaab3cac8cacbc8a2f77b8cc2b31abe306d0d2c7f3a82b9fabaab11c7bab8a9db5207a10ede9c5feb4c733e6a1f1660b161a58ec8cfdec379b4386890be2bd70dcf3b186ce55a31daaee1f14c470bdceea09683529e477d345b928c00f882ddd14db34f66516cdafc8697039d9201e1d95fac5d9fd5c16028e229c475654bb717201d0fbe32db5aa5d985c639ece1a1cfb40a5e973eb55f03a0eea2eb9576ff8981fc69d943bd8fb699c295949559d4b1e8bc5c6f5b872db913426e873ff6985818987e105dc85540650efc952d139fbd1f9b205b6476a1b57863bbb56e7410e719bc22dc3589dcaafa1470e08e6e8579c822909629ab11ec17d6025c4cf86426bf00ab5bd5bbf19271888a5e2545956898d910ad4437ec0b74805456806e1c32320d468204b637bc2803f8986de362a1a0ff1d148ba93cfee7972269869ef6038199cf95d896862e782ecc7d07a0fa5f8320197158831270e5fc1fbc77a5133e9b6709dda7ab655fa9baeb4045d656e23ca40fcd0df29d8a1a1f7a27f50b78b14c039edd14995a7dd88908de8c16b5a967634a2456fb6c2bcad0091a9cd644dd256cac41a6b05b28c83e192bd06554e3e7d21bb030afd9ebb31d888990062b9d3ce390af957b1c7303e00b746af934c453b644a4dac809365e9e621760012f1e263cf39bb4fd5b170b8f30b481e11bde24943ecc94a0c86c031d0a0f25aa3745224cb2ed1bc73c6732b95bdab09df7ab5cc6fe3a8a2fd2efbf275b71ebad80826e378986a26856318b211af28aae1274a5d6bbdf78470712f22c632b31fdcd1f319516df8897f97e22fdc21281d2dea0d2187d11e136521cbf50163e73257598798747a7bc14dc745dff7bdb6d2733d8e49df6710850dc0e9a20c59ef68a836a11a4126054207f05ba21e5dfc1d16a074bab2296a5f1b0e095396ca866cf71d83c2bc312eeaaddce7d77846db546f565ad92b6b87bb17ad460c17cd639387881a52a565e6591cbe104db450e3a123415da7317e7bbf7a13723d64d5cfe573f35ecc2409a99b098bc8fd2bdf7ffbeccceb261b7232fecfadbe4a7d35aa75b612a5385a4b6795e82ccc72f1efaa9c47d27b959b7afc745ee9f12d034cfe1e258de878608c33c918f6efd1ed5b654e0b7cfc39c2944a91fce6de7e6feb54954b6e4634f5fc56d41765b2f1f2d62553596329937a2e822eb0c6ce48258103ebec937b2b75713cb1ef93cd82decb8bbd8f7a7287b56c4178792d317cb41b6391645c3b661ff5ee21a1457a8b52b0481c1105155cd388083ea72b47c5967563b1453164ddbc7d591fb29aae96e8326d16d9ab5021fcf4dd507c9fe663df8756dcf23ab1d05f3aa05592b9acd847bd0ee31bce340ae446b5f66e0d135ee6fc9a1df0eee0ee98246133d24fe52a804a16b7277022ce57a5630f45a6c40946f9f5d678045f1378dd3ad9566047d16aebb82947f8b340b779d0cc587bace8892f2157538df4258728236a7ee06fac52805c414dba518577dafad5383b81fabb2dc0d311d85074c138375d8b5ac1550058d741f52988215e2082016b66b87ddf767aa37cc2142cc12f81cd0e6230aa02b507ae23c05c0070faf3efb4cb22ac94a3814ac78c35ca5896f738276a4f34247bd4762286b0a7479f62eebce1c308c8a67b072d97ab149f5ee57d3bb4faaec0f8b106dbb28ffafad146d50c5db1c380ba79658ad8e88d827f951afc0a7d4b72307e27fb9313a3c6ee8807d247da0c489e1665f84a541570b9be80cc1774017d54240047a9d14d9deda724cbc1c424d852cc5eaaf11e057ab9d65fe6686568616b74e4342559275e15d775c1240cc92b3d3e5c86e9b276775bd70c2353237b9ed1b3d7cbbe1e35f20c648c3b0922afd40cd33bc74a1a16dd42e00924a7727c2383612c3a82a160a3e721716404751a65b5e081972081ea6714ea5219e9b6025db81c293afe181964e24ed40100e2fdf1a25a53116195b72863841fede045edd4ec6f086e518ce4f85686f664ce524b841b264cebb850b651d5146214a57dca961f1d32552243dbf10d7a92b9422cd8d9d48fa88add83c2108f3404a339610dd538ba94b055b2488ca9405f4b1605e7321a3a38cc75a7a3d9d5358a1357e6b80be915a4186c3f912374a345a3697b1c4f71a850ef5d99b342dccef5f2650c36834e439fab84697a2c0b1057612376283e8be7825b5daef163adef6f7be842ba3d95117625a45cd865bd186334151f81a3eabfde9406bc8e3ee15a4af9b0b2ba6b53c0d986c18a9b13d082b46f8e0a2e4aaf2f584cf1b05cfd56f4ebcd64df634a48c63c77238dc9d5ba0a6ac95bab165af75daaa7ae85d9cb4671b5e6043973e223d2f8e37316dcae0d53a2ab217400dfa2e141af862ae812183480b5f7a9e184e01f9aaa8bb9ddf20a14aa64b31c55a73f59f1c260bdbcac7dbdb9841cf253b535c2c8dd10646a19dd00013fbfeef3e24b13541b94814012d8c321260bdf8d7894b65965f38e028e52c1b77014ab7308333f1d12abbeaa60ad011d837a9148be5404f2f605328a30d5698babed096f4dbf2170e10ed70486466e110cf95b76ac289fae5132e901e0d033647bb4819ad811d51cc90eabe8093b80a56ac97000c22c080245a0fa2887054180c5431045bc9bb0308fd0f6830592c2eb237f1170312e2780d80a5d2df4d8cde3f987a2900d30f27db9c5655c48a38ca5b14570ed83a00310b9341504493f70641bc025db4af9a392fcc4748037bd2f86f18f5a310c2aad4f59ba416ec10e1f81f737b4a3ec8c3a5df409af059d502e068ae0382ee158302b0e2c5182f198b0ac23ef6e5a64afba7e1f68a83999acb3fa785e1130a2b8959f44c736a987cb1a78f26b65821f83475ccede5aec2419db450332ba3774a779ab399e8c4ed2655f14dc4a2d3247d12d19f992e07f1b0923e4f6591c521b0dd2dcccbbc5333c31f213ce55e1dc33abab346378a34668968f6a1d8a25ce78ec9935523343da0aca1ac9a0919a5b5413dbf8e230cf0a2510a5fb039e8d250be283b05fe4f015c5724c5d9edaad0426c5a4e3b60830885b7522945c1821373d350029a82d17df0ae0d33732ce70bd47b0883655fc082eade02d68e191c00f622ab9840b87140e3849a6010dbfbd9fd3119a3c95e910b01d4402124170730a39ccfa5097a3ac281ece9b7c5db968b07d935660afac7286c36d8a215b71c02d1c02b729f31b94de2bc76e95dad22b54251662f0b6ef40ee1583c439e4f4dd3d994f23e89e18f36ccfed6ddb7902c170f31441f497c60a04b8a29e77ccef3acfd474f23977d9ff6dd71a9b12daaec841fd16711bdb4e97ebc6ae63fc6a2e9596a44fcd5598b1fd22699cfffbf2d54e6023aa8bec650ef2e383868a8e22225f01fd1d8d7ec472ab8f0c861a965fbca0b87894400c352c570c269bcb0aa866fe5e6c2d40e45a1823573ab15dec55c0217635a50758b6e1955c8c802b2686508c8e1d87f2745ca292338ed591cf9bd6ba85f02625af411a5c6b3415f4280ff9b9e4273a89a68653001be685fddade906a6026198a5c3e54a9acf6bc69bfb8a3d4ea295afd2505832ef837dccad5e9f3953c5a9039f5f4c53601b5f2f9a7734463f2c1f89dc0c8ef7527e99e373f787e71edbe7ca7f518bca07313a8a01897f70995363e7009baad0fad635becc4dba5447bef75d13687fe6a4e5b6e397cf63c03b99130496b9809dfc4d7051188679aa1852b24fe6a8207c6da37c788d025d09b18fc3373d98213d5be285b135ca42a5058640492d6cde5b32607fea1dc2cb5e6c3e03e982b52a9de61b4d9114615d96edf8ae0a70e7ea6c6978d41d3e3572f9584477208df9e42152c4644dd8a4212ee3c39027e471e0018b8819e710abf16ef768fb85654d2e608118dfdd91a2401bae4187ad681a7bde57745cce5aade2606f83d0961a9d99d05f5db74fd6ad581ac8e7841f00a48efdf2975166fd055e7207da86171c8a3937721e0329599c69fb7776d847e10d1bcde97cc2652bb08c2be80206e06c5344ff46a5c63ff1fc96a60f720b19168d0abafb0861f489b37ce15a5921d459c312552432a212f5ac9a7ae6f0321f557ec3fa75512b70d10fc1e8b478b7d8a50bfef263a8053d9eaaa5d9528f58934d43246a033fcd136a75f2b0d328f6ce5f7bed3ca4e0672ff781f92ed8ef124a0aa5ec2269bffa7297bb7959627ba166c43a3f70336a8210f5c1edb0eda668da5c97f50b00dcf55765e4e2d59e250e82cf7183d5d1df97cfc0e85e5349c32012b0ed23716f7306c8b1e4804e397d71c058ca017e0318faf8000a412428d5e01503a740f270295899d47e7078f6c5965fc4358a281d3b4bbc5aa3c4c9bd42ac70452971544957543a03802f62f4c925ed7335cc31fbf04871f0cd5c22c010af7266fb460a52634036973bafd663013d44aad9db46853c3b2a423f962914c447ea765072bc50741e7dbf347fa275a054c2a08f865ab97f9527f75e222edc9ca91e6092930e8d3456043b35fc520edd5d307dbfbc8628a13f625603fe9469dfbd17044556b90b6a087ec0eb9de21c3710292a1dc32f2ac581c891f2ff28f4a71244ce86b2f1644815758a8f274b2183378989eaa76b40bab2918980abcd3da41b9089dc92f1de328b5003f6a8883d60960cac1cd28a7de7b2d1d167a0430cca063a70490ed485a1dd25984126da1240dc090560f6ba2b6e8681a80c096f621a6548b815285059c94aed50ca15c73b7bd665f5461072f4aa17d265c2e6c094ed9e40a6a749bfd51c11c9798962b387426227a19a21d6787a0ce05380c20fb0fc14af76ce9574297ee7d963dd2592ae0143e17aa54e8607d22d04d41fb419fd61b96fa26632ee9f25900f808bafeeef09bd471cefd0d4c6ce70fb0d98de46a0742975dfc5503fb67fdab32681172a8009012df50410fc65472658fc5a0ee5ecb7cb4afad57b81c69966e0ef63fef46808bf680167ceac8241c5146cbafa6e97c0c2492a85be2a503dda0975330094bb423cec0573ebc9d4b4409f85deb71452f4d28caf4204896bb0c475db4113184bc46db779a360337dd863cf8ae14fa6055477cd91b814cb6a71d5d7b0d6dc3064611c110f7ba6951d3ebc12ae41801e79192e3e40ec339588a119058aaf0d36c23f83f1572480b062ef519a2feb152081734caa5725958e919a47e6308d31b0feb84a366d7915f4b74907f21ba91d1663617853fb326ef55348592d1a121f1e3b874e3001ee2454a556199251a50ce110c761d174faa900d2f7ea3d6ce092a9a958d11920be650a994929b82259a929b8e731c9b389ede79ec8dac84bc92ba575c081493262716b294be7569459875409c65dbcbc6845b0a213fdb6a83a299c9e9a48bbc86c773334d9b63de7d0a2fe14fc1366e4bc30632fe4bdef2ce7d49d8ae2475a9eaeadc7347da887637eecda61039861d8d50d5e5066d6aa58080d2bcd0c0196a041b8894856ada1e35b7f5bd908de769a18d44d8a15db1d374f0ddd873362f3eda2ae88e6319516f51f6252c674189d8042ccfaa92f68a8c67f9d25683d9cc32361fc6e0c62f130a1f222102d166a55ea22069fb4d0cc5199b24647199c1c235cbda2f49ccb52487a8b2bd4f353285f920d019b1929a053088ab5dca2e0a05361a01c01357be8352fe42e006ec8757d6e2e99bca10e5f728e130b0924c21c4891c120383a0ddc70d85e381076bac163ce855b1afe86f2a6b53d77b9d6bdd17cf62fb4bb5208381e5a61b3052a75c02eec4f8c2fda9a3878ce9541a19b49a8a52afec8c47e215f817b68b1d42d0810f3d9e361b25bdf34ee2b93eec75232eff96bf85cfecfa1e176e188ace4d44fc3070c73942890f9f79d5cc03cdf4706a4d9332970bef00788b66f116138b140c0f6fdd678872d7bd9e3cafa90bfd41747ec3e1a10456b6409c50b9468fa3d78311d95884a50e1f7411cd6f3d42fddbc3e8bba798a4dc85e23d9abca7fd678ffa614059b15794105c86605927f843dbe151c1391320bd7411cda486c69f3fa306511515047340dfb1b72d83dd218e823532c548b7e6e95ce846205a4be2e12469dc2b6902ec2f60523eda03b6b623002ca66f2e3af2da10667df435cf4adcc494dd3eb2551ac4396299f061c86300c0dd7c0f48f19ded50a4f7cdb64c37cd364616595645d1e07cf1e264a2c30e6588be0f040de7521239d6edf40f294045c3d02f3939d41f229e71317fe8926aa9a26fa2d5a3bb41121d78f9c78144578e8e55f54360d7344bb203d351c1eec05cbe6d043185298bdeabe314fe058ad3260aee52e0082c3715493d437ac135ef4da4a5dffdbdb783fc3ac0e80e078e6725199c999ed21fc6e40ead412dc702262da2e80a23e47a04c8fd3b7f7aa4100da281aee05f35527063fe134434089377f0708ec56925b8a5396f59bdf060e4c6c4b4f9ed901198dcf98c95e23dbe71f9a3a2043d8a499560438a03443d26114bd2d95854cd27763ef205e846d9bfca4b9b8f9b9779418160f5b50e72697187fdd302c50d3d2eea1ff4b7dc50cf32dbc23bd82d34e84db8c1881b438604d60ddd99d716049ebb68983bd1bdd2253a2f961dbd4297c002064481e5339ce172eb8ed4a8a25ecf361caa3026934da468ce7ec29612f15e0f150a8b0ae32b3ae37e54a03e1aedecc644ef5312a4810a4f0cb874e8955051e2fae97ede1b6427df0dd01c07695b0713b79c622ae7f64f42e22e85517fa0732aee7073297612c080d157f1c38399728aa50c864205c39ee41252892f842ed08bb085a32926301ed02ca5ca0fbb05a6c9b25d0aab879b797dcb68b94a98352cb54f3957538f2bf6058949b5d8025ddd329feb09026401096874ab6c73870138cab493ff37a7ef23e7b8e58ac03fd1d1fbb60f5d22e5a7cf6114909f0eba46f516cb4ca314e024120c60872f41e348ccb2c396a80904c668da6308f1a469ec0eac4478a294c00e781d156aab805e3925ca45cff7b5a3db06a32805e7f3486b28ef7cd6382d16720a87222e02c758f3353f2c842fa50cc1bf8298d0be863a6093ca4abe8696f7cb84798dfb87856b1c587008c4f40de4d87c669f593e3181c6e6ba5f751748821bc13751008c1a60c31848b88eb1c7a52054ddedd4bb834b319d1a5f2ad02bad89238908dac56a7397ea13644f457278bed5e08c19ba6ac7bcf66ff8b1163c329ce785ec18f9f028db72bb2d95b3bd1247059f7944f0949965e62e3a23cd04c638658c144099d684e34408ca18a78ca46c27d084e2133e7625c402fc5040f63596cb88a91f13aa8235312e8ce548bd0422fe7b8e0ebefa6c9b7ded0c5d13dae6e4e3a80eca1a4f8fa125e8d4f6f411552ea8cf2e9ee3fed1a777d636f384e276ab79b164652418678a6924d17a6dffa27bf0842830fa43a96ee65c1c75147a7819ed18732f3287480303b1c801ad23686ccd96519fcaa6c9858176e1ba210cbd40e5662ef9817065173c029732b98a4a84acea354017f23c9490a8d48bbf865ef46b798f839bc8027d7c4626deef270f34efc26fc535695470ba9e400278ff4c6a7521abdf2ac40832414755898af372fcafce0d5adc4f6f8a1f7a1d5b7fe378a43796d5158c75dbda4eabef68d4543b0aedd4c1d53c35e46150f373db6367d8bbaa11e01eb27e77bbc9932f7666851bc5543345b2edcc9bab7f7c0e17eb3551bea40176f1156ccc950b5ee22b86bf75611cc80ab8fe88cd0ec57431a64dde46b259ca604652c63cbee5ee803d3e4ff1bd526d6f954e78d272478c1fe848e49cc533d3c6c01047278a5b15ed12cd4e65141ca9e800328cd85c1515c85c2adcdb90705ead2e72101da173d893ffccdbc477604a116a07caf034f48cec577cbaa95847d27c5e4add014bd596da19396ae3e2aba518d4376bf086d11cb03838ac3691333995371525145c4704f1fde56af51bdb70c07ef6bcdb11d18d8a9690ae4eb5d523356f9c596251b2ed3487e1665eaff3980677abc6fbc6f146899ccfd624b1ceb7120180a231769ce6c66ac3d43804f0b59dbe69dc79d890ad413eafdf1c7aecf1f63e4c7ef08722b8ef195c6e0191add300f4d7181ee37b99379ad87c874d3c305b930df66bdb2e9a68d30742245e678bcd8b35882d0845dd50597d54c971f297f69bb0c04ca32dafc26b3ffd8b0007ccc452d8745414d0dac9ce1975b08aa62990a60bb329bc4a5dbca025cd08d90b8e4b34e786af788783f627338db0c369ef40661a6235dd72b78ad9ffe8d68b0de4804b3136bc8e3fdba48373cdff8fffa117c05c0dd85569ffaa1b6e613a0a1c4e3620083f95f12d45029d34db576d17f035de0105942e3e7ea0bf7e87731eeca63efe22c66c8f0d2171ad72a35f677f66d2381c50299fda29dd9d01c4de70a6fddf1c4006cc744c679d4fd6c41fe586f9823399a1885e4dec83aa807a5e858d4bde6d63e8980389a647622bf8cec031b2390ae19790bff0e0af7c6c9201f66b203897ba5ab51c1ca027356f15e480ed5d127853b11b250223ed6fdb4d5470d278e55c048a2ea673672e6066f5ac4ba874ae36ce58c505da0256911b75d86711739ae0005b807079ae38456b1f202103e7d107258e9e0cd255c6e6899eaa1a90010c29639b7eee26b7a0e6f9279f314e89fa404bffa1dafeb99765fb6e04241ad7febe023c87100fed3623bbf361cf87df2c4b7a7400110844ed5dd6f9ffb46fc84535a75033296843ce06c8161f8ce6754d90ab5a7b50b7c84101192c239ebc691aca463d9b144b3ed4a0bbdcf73eab72dacff1ee69d5fcfe57a2e00512e14410dc24b5fa1a92432249dfad746830e58e4142440e27ded031741712c983be8d49206ff2d4ce845981841fa37dfb4289db14bad967d88a35a9077024bd5b3c674642921c36d5ceb78701d4722f486f7ac03019919044a6d03ef2a110341c0effeca5dfee7552d0f899dc0893f290e8493c9d99f792e4f8496dc5d7de48fc2072804e4341d2705d58966f1f47e0ebf90b3ecfe33d7eac1015fbab6ba6c432a4f7883ccd3b672534704b7f85be5cf0fd7891018afa71fc5f5e1b678151c57c4724b358a20562f82bc9f192dbaf762fcfa452c04192912c1678784ca99976846625f4d19a10685b7b75c5b580572b6eafb9aae69d143e3b81972c2231c0d439612974a12ceaccbd9264fa4ab4d4da95c717a76da5e15c63594a958b760504995c14591b02330a378fefaa633fb24d69ca1e28f2b158f52034334dfa835f2f2f81ed204de8e6c0593091158ee4202482cec6ced7425cb3e51c4ce4ac3464c04eb1f1c42119f40dc146b0b836a99cbc279dd11797b8ccd390656c279c1c14db4d60a36ca46479841df1088dcfe870b499a04108f60981ae4fa0f8081649db30eb47c703a035a4671ca88e415cf54825e195c082399915c1d9b025db3cf1c5dc1b56a4962cec670449b5c10b2b3333460b332a082cc7957bc10cbe9fb429ff2ab9741979f70400dcdb6037de37ca85b219e04ddaa485136f31df650810d5eab8df0a75776473e13c6624d954067d676965e1b7f6fa98e14336a9b8dd0641d97533f0ad993a452137a1361a20b7c517ea3d253f1816569880dfca1d6480a2cc24e131b68e10881df3d1c555020192e1e00a6080996c0a09f34b9d4c0963fe0e9c06c12ff61d5e7cbe122c38977d792570070ea1aecca522f7a95f162bf0dc1093f1d87d1aa3f578553fb0be4e3068389b015c8a7d4bdcc17a7441dad09dbd812f4e04a63ba3ba43b7088e5bfb915973af778c981cbaa8f4f63e32909a2a179ac105db4ab798da6db15af9bc61291ed77e7435b4d34f920108b3f5f1eb1d2558f1314087044718cb7601f356d4f82479786c74203420847ea1d130866b67dd5bb58c942fc743651963913600a6030cb616ebd50ae722b70ebc244b7aca3ee355d23536f809582e6419542abdc5adab7b95ec5b1addb199aed3b02819fa8255c5c27b45fddaaf79ed0594f62324290ea886f2f7b81b27f8e72a89a014de80231877e53f9d2d20055b542b4bb5d7d092ae3d44ab7c680f6f6be7510426ae0ae72ff7500464844463eebd3e5e8267bfc96eee54bf97796972f17ced57ba66c985d6359afcd4675d39877ada8431b288639b037b30f3c092f12debb1cb004f1437f629656654cf2e3ddc66005f551a8985dde4c108046252f1f62ca3ed4e41d65c36bd2ea6fe67052dba87c7170735885a685450d446202f5230ee30684771aed7aaeb22865442df44b4b0459ba620c12e42025dee089d46f6bf8a030c5658150b6c8ebe58da27c9193ef6797ad1d8f12c2ac0c9328486c68e0b035b856f8e0f748ef84901e97235cbd6acff50756429ecabe101b286254c124f8bfb6212dd580b4d35b6481b2649c2420f6ec5341090cc286e199e52c17b3178033fe85b1c075d970922e867771826fa87289282ac2e08a1399c95ff9999408d368e27bdd3525f61542810c4da80287810009d4ed44b8534a3202e9dec6ce78606ee8d1e5e955fd6eda69a92e1f30643cdfda6166c38820298ce48ae054a7939c8211c1bfb96240e2c4f70e484d164d784228310a2dfc36f7dcda9aa47699a7ca265542571c8d7b625a6ad5c7bc6881be311d0ef59775dd155c8e1d400494961c6b45aaa8bce9067e6edfbad80ea2137d04088859f8df408d8e4b604663669711107af4faa30a336873bdd50107dce1294a84bfe31febc518f0dbea9b3bac0aed7d7e1831d40478b0d2b57f32cfa2f6b4804d0a7310e69a8ff641a7d199fca23d0e03d4dfdb3a4ec431a2bd43795ea1f073d0a7ab9a7e840484a6749147729cdfe0820a850dfb921827c40ac7d29b010acf334ccf3b113734bf01f58fc5f4db20e4f6be1764f10cc80ff061786aaf55069cac0ff58b1777e41046b03fae4cf809c07130c4007438e33bac7ac23c0651a1cbc1e6f8e8ed5aebbef628407781ee6f3222969251a2b88b2bd466581a1f1c1bedbe00fa686b2b91f92cce2b33846a4589bd355dad5b06e111b160f0c480dc5f87d349b4dcee00a6748ca22c13bd3672e7e26c10c0905667083868b11132358623c433fabbe45ec55e0ac4df65568864d264fc06af0fe5d7583ba05199af618df98586a72765bc066b70536bb5100dffa6769f98735c8bbcde84624a79b7f7c99fcdd166b0472faf9076b5966c638eb2185f1ef074b05aa43aaa0e7e743188e41e985652a12cc97fefd5751824d4215bcbfb14d0794a9ccf16f342c6e06909d5d0a433e4bed000324aa77406f1107330105c44630dc98627acd10d6a1847ecc8668568a6fb3652c94e05aab00b715616a107ad7aab74352fa63facffc550c10c7bdc37398b9507f28a9e8126c9dea6f1096f0a81ebf942b5b0c3b476dac68c75f4cd579673864cc4c5e01cb6409271ce8667db80d021ebd3921789baafa280579c7976c979a4ee9b8c4d76d5a7e7df7e69cdfb46c13648559935d57e222269135fedfcc33c628e55e2c48c62f822232373267066f860a217d0236bb2db0c90d2b683ccd1ae520015d671a5eb04945c3ac9b306e034c9bfb88b84d8d93ad960fa06a14c417848172877a6b2626d3f61ebe92d8d558417f5a6aff1ce911e4d535a11721899b96fea8473553e60a0b7ad2cb14197bcae988c199e87b7c382a6df3aba5c823582f7e27fe16f7f7e8f7ae17e073a50b60a68df97c7662dd52fc07f3e5bd6dc9a082f1958b20dd074e357a081f2b6f0db4638739fa6853cddd99da5c160904d3f5900b8a13c965a88bc1337b3fcdcc367195f75e7f7231662cb3e7026868983838b1f67aef5ed9bb667d7389f8833538dd5a60d3ed029b6e2f90affeb994fcc19ae42e73f411c9d3993fbe447e63171b913cfdf9e3cb1ef8af73c9ac72f1becaf69c7b63185f26821113e070d7bbf8b0960013fa550fac72974de7a1471d01de925e4a494b7cd4479422870991a682dc65d62c16b4d081232a7aec83fff9b86b8c12565a7809bb1ed7bae62eab1d464445300c162126ce3934aa1d2615540b3563eccc042fe4d9535499b3a76825274f224a4e9e452da785cde23e1a79c9a6d327a23e513534aa56286e6f6e77a539d1142cc43a0d6e03504f8461223ed19b52dcf78d9a13bfed266af3db5c9cd3f1b1891c38fede3ec3846f271f6f2c022142438952c02b8c3d53cf156a2f641631a45b8aa32ce621fb57a63b2f637edb0497ad18bea506171b04d2f4def6556ce3a442d5b28b8b099fb1ece41a3f0408d853726fafde76e1ceedd4ab9d771406f6cee15cf38e442b72ddb1582bae99c3263e14172d7703b0910e3924f632bb658811e2007fce2db9434fdcaa80ac05169ecad2e2a3721bbcee6dbfe40f3d9ca03ea9e436db0c9e53da09b6cd1770c14c42922d0a93c8c3270be9d84f5460019522803f04967864acc919d6be4cec3b1c736510302621e52b0fa00426afb19e2c82e3f8cd044ab46b0a907dbca9387c030b79dac0339f18016c4ce95eb3db3276d0cfd4af7bae2dee38dc2ce29e995e629ea832c9947d329e282b02fc7b27509ed5a85fec1a1602c23e6f3e5f8452886f9ba17df4a088063cac650627334e657d5d5441904afafa80a78955123d07e9a7fcc9a2b5518f89a1b1154d0686436b7106215fa5c58e26e53a93a40533f5c1f3169a77fe6c225328ba965a46a47b42c9f7700298b6d4c4760c4b96a65b063aa3ea11644536a0d683bb88e70d1cb86a142c431ec90b65ae18704b01616f9d3b904d70fb2d6e431dad2229cd87a8f598a1a5664c27daf8145728ed99b476d83d93b35c2ece5a2bac8a938f082b0bb44573d8620fb1d15036b03e8407ca404fb4c9bfecccabb5472cf4aed9ef094d87adc82c1b0563b29e337e961278c69c6fc64e1ef9b6c773feb6cf83db7db0593dff45b93fdec0938d301d532b86fe71618d5b241bd1cad5381eec919fc6dc4594dc32cde97d9532e8ece5cb52b4bec7020f21297e607345c8d122a2aa1d9c1e3f6a0732360d77214f7f6f03dce8dc3b82db9806bd2244f0ef8a911e354db87dfa1e24ae280f72f2b346858a1c55997596b37b0d83529de5dfa1c8731b7f6f33b2431ff34c6db9805b6a83bdfe2be2623ce7be2b05181a2ec3e548060974e81b41a1b2d4960b5ff5f5e75668d81612ecd137e5daf85ef4bb7389c907d39814d721db49fc8aded84a2975cd7ee4085dd7d3f6b87ee04fe3925013fb0ce2313fc6e23078128c73610ab03b562662194022018095d21f646ace1c4149800278307e792ca4734d0bad82669275946cec3cf1d5e87363838347a85b8a72f71520f2755d0534040a51843325a06af1114402adb0a9ea1a6c176e5e7eb9731f0c343aa87c80e22f92bc6c1291a782b9c1ed99159111f103494867cb3845908601bf5700badbec9b8b80a1b781d3c3d6a1366e0572135907db48253c4f8cce0d03f7ddb207720afd14f0324a03eb7259236688a4a93ea97cddbed23164a06894140353faab6268e865146ad14c266fda23f54ebbe0da2c657d1fadc5f1abdea81f49dad504423905d37459afe25adead8f955c2d2195b239704d81482ea41d7d2cd4b0f490e103c49386f1a4570860ab6915c8266420a6b5026f2a78034f4354a7842e83b32e233430a3b5cc1c157d1a9564b1f442d86611cda8dacfa593ec522c060fbeecd3721239cd643da4d0146c7febf4e63fbcdbb88cb4b352df55eca3180837c30379a8c3c24e02b664ffd73265e204faad29c640a739122cf0e4345472d8321ded38f4ac88e29fd89ddb5efe900b5a0c916ea4b44fc3e4341806e690d69b06d3b7d702549a227e0917bc56db8731b90db481d5ab8b5eba10534f92011c743f39602cf92148a14facbd629d937a41a21dde036dcda30dd6c5dce424b79606afa9aada30f098b425176a0014be6b067102003c8ddac253e0e555c7792375909d05b45a53838ea9cafe8963514d10f81f81ebac1d48b45817a17c999d6db42c05cdae14e5657c6f7b9e1fee57737e924af0015339bebe4a42668963740520ff451fa2bc0c4c4e7e6891083c1a4a6651466cfcfc4f8181d43c3caf1547cba993953564a0b4978b04cb5c6fc5cb67a4c631a530e23d6c002053ebaefaa4248bd503ccb77d956c4f1c8ced335f2e0b9192c869b74ef43e22332671fef8180dc23bd9855a1cb078f541521af75b82f12d498c06e828cb3023435529108cccd0a864618994ba1853cb6f4dca4ab590740d70c135c5260778b66dee04c3c762d2b8f18c45990671481c6bb18f8bdf2610ea507e1373a42ee804f55836d8972b5737bfd072612badc76ccf85fb999d0b7d2f6f788daf5cd0558b8d48d77e6c60fdd9efbda3037233c41da93734b490a92b11bc2194d16f81d197d8f1614326ffc2946cacd17df5505882da89d89ec829c611becd19533be64707df64b40f9bd7f468f9721a0771ec722c6b291c26bb2ebeb9180864867416755b57786e7af713880850a7c90d4cdb4e1f81f5f0bc2e1a657cc4df0427ac662669a9956e00766d24c0be09c26dc9051242c80422f18da2a2c68ce07894c01220e6995132210f5935dac1cbf639a843f36759ae0dfcfddb732fd03f1c143dc172ad241304f23014108686af324eb4ecb79433e2ccf6e5d7ba23c6a9e31fc794901eb99747f8e7d13f8780290c2cb444d7371920c0d424fbd7849465be546203ed0ac04968714ca9662785a1ab824858a028276071ed43313650f3130a25201df3489eecd8a6b16492f34c98dd34a8713ea261c7616ace3c9b77403e54d1df739cb8a9faa980fc8ca8f4f39e9b79672d80db26a3e6062a74f94f02ed1939401ba29553dafe552af3d25d5183e1bf72a93684a278ff730659bab63a0c88341f2477f40f5a77fa9d5f047a2772f14ae00e0a49ca28b37d8c84f0bd9a0852158942fa08acd45e08627d3b8fc61a30e4ab67e7e94a54d38822b677f7db1d35a3a09a858de7a68604d4c6f7c08fa46993ab9447a8f6b449910ac9ba44f805d052a307df58507c725a78af5b178e88a86053a95e8ca76e2d6ed29bdbefb751fdd7e7f85eaf5f6409be2841b755bda86345ce1a6f2a0292cfcf0d87a717745815613b6de3b9108949b8826811c1eb654a6de40b50d992fb54b8e77a98887fcdb8b3f18798bf67c74480a4d92c9e4114bdc4c03c6ae0cf1b245047571b940dea752161e80a4e699545a6dbc6afe0d44ef2c68a2d37cba3711a3315ef51e29d369a68ae8742df4183e5f57d006684fce3cbb6b98324e9797ad1d263bfcfca33600a24a3f051e670e3ecf1a5152fdd2596cc4a909423e3c9974a08645847f0330ccf2e8bb99ef890cf8f4e49028e3b7ac9a38fd9d74d7aee0b051d8f94e44a19fa68518cde4a56829a27f1017fbc09f222218ad0e34c78b67a9229d9a3673845025701c0821fdf8cb9175d80b4ee7de1bcafe7cba4e2beb817b48be6e0c71d0fd0f1c6d5ff1d18522eb0a8dc370ce4c7efdc1e43a70204591e094884723c2ad057725c020fae4bac020d99c4d486bb392f113791585d35721dde5205f59222c24eab14b964a74c30a89f635a82249c3435efb820bc9679e7335b02822541b481a6c25b53a253648bbbdfb7e8c272defbd90da49ca744efe2326ee349c7071c8ecd17b183cc08c1ed14548098e056c77e4e3aa096e31a3a45651f7ea8b1df31e2fbb3407f09f4ae70e5cc74d0718b1f0352dd862dcad1d7878dc2c732d2f7b19f9be395cd90b2ae76fc8bd165a82c0517c148e4a043598a0567cbbc5757002b788c95a37d0a9c0a18de998a47b538010e9e8b39616f0c5cdae243a797fb80f86f70074948ce70446c18808d5c5f37a83f3cfb780f9a1b9ba4e2cd665f96ee46647a53c9182dacef213939adc9c2e9441d746cbeb28f6d659e7e53c557b10153222fbdea8d8c57b1011f236b2f09437adb8818cb69d9929043fc19417fa1b3e53530b0fcec4189a04d57e001c4079199f55869ae1f7abfde341796a165bd65d64c24b27a9fcf9eb7695e3943e22669781432a84634ad9360c3d05bf3352c2d681c0b05a9af1b95ce444582e6a79497197988d7b83a8b5cee72fa5a522f7f02c4a8311323f32e1e6e150f882b719d98d3848636eacacc95781a47b6df80706a2c1d9f5b414fa067f44c415a2a1a4064b25252dc115558df1ddb01bf8186172ecfcddc930486df9378ef8ee76f4e112c7e90ddcc1d488d03677dbcdd156aa904fcdf7faea8b986c30986bf33d973eccc4202393c6e8b83fa144aa31365b93d9baf8e1848b68e3cea410234d2c04479caf58c6c06aae40f680a0ea74e898e66359894217e58751a03bb0237755d38bf3456460bfd4507ee1c69edb0ede7f5f76bdee11ddf2c3188489d7aa03a87382755346920661acaa0005883cda4d9a417a4a8a465df7ab809009e7fb4fc0c1a8c2bb1441eb6f6779ae86f14c3067b49aa6f0fc1b113738b7dc0a44aa416bae395e26bd4ac4a967c572a0eaffe9aa5445964731a745afab79404273d3aede89f0d47ac17c8cb1a45b3ebb8cae79ac8c7cb05b7a72d8f6260024606881390f1cc72ba375f2a858af967ccfc726ca0f757ad20e1e1c9c9d38e1858c9170586721f449c7c46bb3da47e0179457bbca11009bed96ff1e6b802d783f75f6f4217e291167c2fce079fdfece7a225b22249a17a7425dd0de17c1471a2d3801b35292bc5df263fcdaffd63d35a63cc992188691c205be69511752d6c4ec994292787de1ef7b8ad2a34e7b0ffda0621891a889723b1066836b5c09a5a240fe29c6014107025317d1c282d20d2be0167af95e169bf9993c21fac900a316e3868803bebf38ec24b12caa84884f5d73a65e34fc6ad38401a1f3ef365a80e1ff9ea9dc6aa6e89120ebe6ab856ebe17afdb1c429b8c37757344e42a560c45e54cbc21feecf09503e1ac5f0483b0b179da4c6620f577d008b61824419a2abcc40d061b46767f28375e00d98b49d0233d3f4e149b58818320d607a43b071dc04eca64e89979844f8debd38da82eb08d28306725bb2f6dbc4ac6e4e03aa011b58dc4f31594e072fb9c06584a2258cc662703df87ebdc23f44a878e94932489bf2d03a1e577d986f14b90219efc2ed286cfd52ee1a0f5fab7748d6558bcf0d3fdb5860682749922a790860e6e82f4f0a6e37cf46678eb28f71f02c657d4b249f0aa1c1179fa0128836308488fc790ad0d0f1551ab303be8fdef21e24584e9a6352147b0e8245b59722e9d69c30f7eadf1781e720c4f6c55b84f904f2fb7a6226023a9f7629f9eaf530c80f1f3e72b05ea03bd4d8d068fa17b3a2a6916f804f1d6aad7e0d9161f73e330d4a7fb74f278742478c15ae7572fec16afce112050273a64bb47d01e7c710cd6e9e5f68c5304f334d1a4d51b9ac6a0f92e9690b0b5fa58e62a41cc2bfee722907e9f745b43dbcfd05f86a37b6c9e39982f1b13d59c72b94113b5876237f0abf7b1a05b25871833de7d75388c666fc24202d0c14f9d270a2e8e4a0fb68623c1ed1c0a2c5aa75c98c032745c3236c9f98d66ee70c6b4e5164f1afe26491842d180d81c6112bd07fc59c8f0cfe56a3b478715e63e527b1d57081c2c2204888346e32002e147b6d957d31cf230b5717a0f303fcd6bf9d9b0db677e2561f5771f30de81fe2af2e0aa90f9ea8133a6385fd3b36ba9dcbf6b1bc484c36ad20617ef93883261393bc1c3e8172c58de363f1e64585b1d4b6898e0146a76a6cc6fd0a62c09711a03ce2af10e71fe84f9907b5c25908732780a1fd59f860e1cf4f7bd45d13fc288f21bf878b94d90008839464d4fedbbed991628f213c31c3944571b4b72520f46422002c325680a0dc1041f8e94c3e1b36203517c5ae77d4a8e1cfa5adc6a52f2380340f9bcb1a3455c1324420d951761d6b6ad62b8d4a5cae2f23bfefa6dd84fd165865ff34ef533b3c910208bfea23b62c51d26b85633d00526382bcaf7a4ba358f4d04e064e06b2a2d032f1d05a844ef1f56a60d31e004a14681b8b694a2daf3a1304c72c407863135f2e27f8fe0ea595766f07b8ba75767ac94fc2e412ebc298932609ff49403afc026b1484c5e857a0ba66018a963a2aee479638f3de2bbb9cce2b59d07a2794b74370f10981591e04b4cc9a20a02d168e220788c1f1568b8712dd89d26627aed407de347bb2710ebdebbb3632d34327cfd24fa6f925dc128f74b617b2cac166c3bc226ca6d41d246308e29e330c7f60a1b73db7f55af61f41f22cf9d2dcc3cd8b6aae7453b526405d636ccfcaa9f22f4d46f5a9d98ac80fce9014a04584909d6672b2e166a5490231e45ecc022366672eb52b440b76ea4d5c2d123b6c05701aff18021b995c48ed6158bd786faf449b5837c138489493ed555736f912864426d4099e0e21599bc15fbf53363218fe54263616b0df6bd0f4b8d8b6ffb89e25a4380a889d7e358c59e8263716591cc7cb1e203e261fdd6c796e521cca21de4a9912fc59b759a5ac2a0ef2622dc476f86f6a0e9a39a534174b5e0236132c28df8e959132f072a7964ef01b56aa5276ff5f6d78ae520cfce41edc7540c2ae945eec52142ed5a3cba4213e6b6b5b7603391789a58563cd911ba68612159ed22e96982685b3c87838874c887b9fc27e185424c4fe94056afd3c501563f3fc93d44aede01189556daca1656e4f2e1a926c2b7d9ec435a0958f2b0530701de9adc082650edff953f92b9f7dabbf8c48222c76287ddd6c00da96107977e36ecf4e1c88f49ba5068592eb6ec8e7cfe36cda09e100fac8056e95208a54f6b45a160ce1b5f9706d16843e80a3fd80a31e73e2a08362a6aeb68544fb788248292984cff0049e11c560ffb204f053998e4016f3fc5ecfbcbef813d20a290d48a9d43fe01f0ca40120f41587b8741bc47a745c37a51c64644a818c96153b2bc0f317ec2baf81d0e6876d917713a4831286e38f9a55bf11335f9732ac902e75d8e54ef5a2a87870c111a235ac56e09453907f38d248d1ac896dfab40502361504ad0116a0748af1d51214a65a2b5b6b011a7d913f51af53a431b64a24fb2ed2b8809cb0ab3ac562ce15e81b5d81a7952b588d9c2b783ca20b52233b2f60eabd2bd0c2e922ddc01ea382cc1ac4cbc14f1ed81922208341eca120293fec07926c7ac755f02d65071c4e1ed425e257132a85d68808990d6a3a15fedd4fe1cc7fa98721a5126c3e9188f7ff71901c376e86089ba1dc05c62d08204a7b1c3fd83178e4d295fb4dc8b4cb2731c0ac93863a52067aab6226f1d4486b7e825277f920056de285a7251deece49541863f21d7badc7a719ffcc9dfde3130d34b3506b0e8cd28a7287e3034e0390d518183816ef7b79c747c1600e57c88e25b1beff721344b23854b2eb83f18ba1cbfdebcb91c81944a9fcae03f99680cc15ca1a30a43a95b8d2befe782b0730a4cef6ff4f0d040b39983b859d111824466bc70c6f102d9f4c8d1d44dfb818b7a7e7c4eb159a924a0a97c905823a0c22cb51c9d02e84b6bdef7fbe3bfcf4da4a8adf90b0a7cd6fa4f693c5a5b8f7646306cab686838dcb87fbb871b9ebffe12ede781748df9537594dd436b93310921406632e344b594a921bb2ef7731dad9973af2d010d80aa9bc1b114e9de04fe1b4d9e06adda6d59e618100c4b94c16c8c26deaa12132507a6c8e0de243ea23fe011943d4e3e26e3b04101f6e98e8dacf26f45380a0b932c3472c2be03714ce3b2b54537532deff608c8e9048f87d8d89d192eec4fdf6fa1cd96f63447d0c584e62fc5607e149fe4f6b6f29d8a18fdfb69660e03747f8535f410264cf009c1b7f99f762ed0589ba17ee72f48f88d7c3f8b8a158d67c707f13c764e7371a7bd5893fbf54f1d73f21ce91e0ab70286bcfe711e8894afa0adbc8ae8b272c2d90331d3780b50f5f3fc99e340027011d8f3d3f18782788db293f80b49c8ac2bf878b147b0f92e243cf18294f9e9281c9a259a8be498f1c2c30f01f0a01a9ec91fc7a1bd66834de90ce02de21eb81d61a00be9805e80c39cb8783dcc1a66b15528b3536b89af6205e3daa739f8870ba4bec29fa2af8d2cdf2d3bbb2a12615d380ad7b5891a983e30b337a088246c99dfeff2ac96567de1fe0f4daef47c74c7023ab90a8ad083e3afddcb8cfe0f422e57878e622ef22964467298de74fcc5394e91731fbd78c62e4eef1eddffce6ff55f465b0984cd51f93456fa2f8ab741c0c92badef8e4d006004a113f5c8a1266ce6927bc0c222ceb518a8c7e0118dd8148ed2d1749625ad3491b9e77e5e78b15e0c06f902008d2ee62b244baa328c442d3da6d143267dab0780cdcc1902f866e8298d2f89ee5e7b1f1da102f14ffebf5f494bfe91a29deab10afc5662daedb5b65751a44fe2ecc8822e214ede32d04e7731f432b7cef4809610f310a0f835e8b89954f7ab20a021f5abc58b430a384238ca11bfcae647efb8febb0641bbe1f5b6cc1a31f05bdd0e0074a9c0f6168bf10cf5668e046a61d4c4f50d8fd56045cc380b88968d3900268f27a1e0ec2f0a02b1e444f2ccc2bdbc9efe20747fec3c80c6a5883a93a00191b7afc36a15d701bf9e92ca938d53930171db636bcd59071ff2ea44df82477e0fac73d414254a862fb13595dd8034b6dfee12820328c76bc89281322b286838c5628aad07639054b1867d46e959b4c0d242111e66ad4c07d8cda150ea2250ebdc4c6844a2f2536ebf8463737e5fe068dc8f85c480d312d382e20cbb49d1f869e5407b76fc0fcd2ed38a7208ce0a3f9a2e67bcc2076a266b5dc8e47166dab4ce53208aac40ae2e114ad15d93d263341c7fcdf8f8ece49fa034e5fb2b7500ac82c8efc7a5bf16150f1eee1bca3dca707618e6ec1b5b26e4afeb0b3f4bea1c71fb6fcd4c7c51f4034967de979affa7f89dcc1d5b27796b7942ed884a2aed6693f544ab1f3a849a395a49debc4f0db57138ee715ac77747c62f029f2440807bf58c032c476aab31d509d6aa837c9df4da7b8eb0a045b7692cdc3c4650f895a8b3da4d2c54a8d281af764519b7b65bb81e8c775372ef1c9229842baa9b3e12b5f5276b215da4fd8681b42a54e7f9403939dcf0e513a0f87501551c74b2953eed6b053a505040b2a20ea4729ef399ad87cfd7685e1ceae7750773a85548b23d2a25fa27118749de67b193655010c0bc376317ac56a2b24c2a5e6d1bac4a4a732a537536f51031425038a34a6715c3092324e071a0326b87fd2608c43bc02d82b485f213c3e934209801475d577802a4e50bbe5efd655e0f57b57eea637eac3fbe6cf631ec5209f600476622fc5eef3dd2e07e02d072456b50fc188490b384808912df7965b4a99924c010307c9061007bcc3b7e7cd4bcd1965cf5833c829796509240c9212e166c545281c19718288063680028d32caf85e2252651d55a6841a0280c0d606bb43e80c7d0e313262a31fe22894b5cedd8d18e8328f5132d50615fbdde8704dbf0d98fdd8288ddbafc33b983925a1cb3983d669c01c71e504cf499e0645930c8c49dda3cf2c83e9e2852e6ee00922052f0b70b1e243134500d1c00a2a282306d055e8b41074861848303c21844590163c59e460b485062732f4684d85d02b891ea2dcb0c21434785392a0b4404acb061858fdbc05cc0e4a5c6c86a0d87942cba54bf0a0b2fde20726f7a3d2890f63f8183e7411840f4f68f14128cae0830f48f860430eaec1a0320286d2e5a12782b28c99276c29a5740863746777972d25949266ee948ba14e29a1bb3b33333394f2f37777776f86eeeeee524a296f467b327777ff0b89bc5f4ec1b294ee4364f00f359b734a29e3f41b4f377e1e804c134f57f68d32cb90f812c33065907b5ed40903dd7bf4cbd512100f9c6cd637d62d3b314ddbd06fefe17f39ee0359ee29a575e3c9a508674219e3850dc0e5a12776187a4206229ed8f118acfd02032d475a68a9410d5a8270d05205c7041f0da030a05fa945aa810e91e4349c454b942c474029ca02c40c405954404316284f6258d278b1888061418ac28a011296296260c5602a05dcf0e82e0ffd60cb4051abeab97cad3fc3273e34519ab608014ef8c0892cb75fbaf720c4f5d37577f718d906f79311c0ed7e9b8326b4dc4699a43401743bcac5c27f1d323538e23a1577a80929b6888b249ad08112537e5caccfaa20051731c0ae0cc18331582e84880fb7b1288fe1fa9bd0abd27577771417f6534359d0b87d457b0105cccc3c7491b9fc3e843033733c00962ab73b8a85df5142c8a28c26621c65f142055838f004152e1cf1a003211f56c36a70bb8d50445ddc26c085b93c44644506e1cc84ed873d3caf76dd2ef5883e33c5422e249b40a89fdbfbdd2bd25f5bcd5df7d83ea53eaf62a7a0b34d146ab55a3e2c7eb8d33f69bc119650b25e4495dd5c72772d76c3a0c52b5fd3becacea3d7d1ed3fcb3246963fe3b49721e7149229aaba991d7d9c9652cac951efe3f9f3c28f5c629c99c17ef47ecb8eeb1484d0b35c8c7176476ae98e95d263668f2debd469586ab26bea3471ce8f3376a5db5e7c1e9ddfddb039980018e3cfd92894b5ee5e775b6a6f4b8fa7bc71a397445ef77e628c312cb050cae831ca186762a7b853436431fbcca33caedf6412de1cbd62f6a28ca7b8a261fd3f1ed71d0633e3cf38c6089feb14b59d821fa5a82ca30719c2f64a8811b2f081b0b0e3aadf9d9bcb94d2078ffd28cc6636a787245ee919b9899c653fe79c1ed7294f222b1adedd748a9f9979ce0fe171da5fd33ccb75ca338fe3e9f947af739df23bafb337f30349bcf2e371a59744dee8652d59e090d9ffa317bb65cc0c6c0061bb63bc917e03744ee82bbd1c17fac787eecdfcf8de3d23dc855c238bed978f030cdbef1d7fcedbef1376f27e46b8533357025d4f05d6bd9e529919d529a6eed6698c7822bc83efc75d62056ce00288167ed8811060b03ed48d2d78c1183790420637641112df87dbc4296e4b71e3e340b9f14de8958d1bcbc0c20491103cf8b8cc604523baa0828919b4e0046310b1628cb10275aa372bb7bf765a165b745b00377a9a11d7bc603f7b8d7887006e37b9fe7d717a134288ea5f9fb8e0c224021e399d55d84f1edd23b79134904a204927bcc82992909c006f3f100d04376e11c9f4a48b6b625ce3f445b3178e168f0f501091cfd19517cc4a4c88e8a8571ffdb22d8eb2d9923178b9fef5932e5c7e6eef93313cb9fc938bb12b5d97a31144c0ee87eaf690402cea85966b5c886be4ab33c58e11c6bc9840923c3cbdfa6c8f141e2f4e54d6f1c9085dff0a9bf3a243c5e38acbd6952eac1724a0dc2f7565cbfd1470fd8685fc236c09ebd567925528048eec670292ceaf0ac5f67f2620e841008bcfca009560906e08252104830483c4b30a6b7af9a350d69a5ed75d91e87a0c164b5c07c104048b39e21a87b90d8c174ce3af0320981e5c77d30a421706498607fbc1205dffdf86e01a7f09731bd92381825a12c92dbde2212c52ae6fb12ed793e0e27edc3d52e2c9fda4501245f793596eb83cbafe326eb15e7d2620a15e7ddb105b50af3a8aeb5bb6d8f58bd3b0eb97018a39e21d3780aeff3604ef6819a15212ae45cae521a02d8a2e0f15317155e85536a1503f24ea87403006abb84dea4e25098179d39b3c254a96c01cba0481c4fa91bf04d2208a1b5aac9f22f4e5c370d285ad026c6dd9467f7baa6d94a2509ef7c1afdcf6d06be71bdcb69b1bedc5a51e5441c90b2c0e34a2baf26195db4f04e3ba3394767f238718a3ca6d784b4f100bf48a87aebc6e7fd2162feeee94a8fc703f26aae17ebca5bbd155681925ab86e27e1c4ebf8f7e55ff8d7b858199d901ccee8e7a772fc68fb38bd1a3472098a2e0e6a6bb8df0e282767968488ab90473db15590df065dec8ca95796bea520fd3f7d76a9fa30bdd93576d27f3313f386e43041ed5f8cf88ccb5cf4f24c603025fe663e9478daff15cea51e3b3532763aad88f85fc716c07af099ca5fb4bbbbfdb4765feb327530ffbf4ca789fbd26d333dbe0384da98789fe961b43812b17fa5c981f32a2e1c2bc69c868e7d6f87edbf135655bad9cfd2ee5c0cff4a71a9fc9789f912bf327db7d32f7084ce3d6f8a72514624e1d5f7e99ae88f58cc85cd3974c8fd3272076c6e49d00f3965ad4a75437bb29d26f7aaefbfab91217f363b32f079681c0bce92b0cf747d8ec8bf4d7f8af3fe6fd24633ffb988e4b3ffa6b7832dd5f3ff9c94fa78fa51e27dbfdb52f732aa130dfca97b11d47ed73f74b58fb6e7a2f4538f3c3f435def435be5ae61a99b7dd07af7d993f759ffd98aff137a6abd1cdfc383dcc9f6ce9e9c33c8e9b3a18afc41ded3a6044e642f8190c2cf5f0738cf6db5b19140ede11ff71d86255818daf2345c33be4474a23c7add6ba69349bb2ad68be49b11cc9a89203c00d91f28eeca576bffa9cc7558ee3ea96cd4ed3217b506db09046c8032d3bf947de219ffefc4ffbcddbb46ddb34cf8bb449778e0ef6eeeee68e5905400fb6a9279f6694d2cc9bd1ad105d715dffcdb5cffedbbe7af4eb77e9c7f6dea3c2cdd39e728dbfec341d91498da273db9409c97e7a4b66240059f3216b7a2e8e95bd2bb276e63ba12ce611bef89295794e989858f39b85d3386daac1df3f9e600a323de6113ed93d62ef90c97053b8ec35994d4087c5659ca779329daa15870d767e7d9c5ed5afffbdcae154adb5de5c1eb74ef1ea15d451bd225cd45d5cb992c4124820a104d1952b492cb17d4569dfe97e38acd36ccf5f19a76b8c6da29ea67d7730afc12e9dda1ea7618c7704f54af3b6af6e3b26f64f31dae793fd6eebd98f5d7cdbcd292d7cdbc90e3ed97c4ba1535b924e6d1ae8d4b6814e6ddce340c27eaabbd5520c03b21296fb47a1a474094f88b73d88c435dbe320b2da6f4f3bd5f5bd43024d1d92283ba42e77fbacfb6a697b6e7b140f10297610a883b04e6d4fcbb0db43a48d5ad4f6aa5ee5f00d8fed614fafe86f3e777bdd8de76e1b7cb23d0eef80777b0db44d646dcffc3197bbb196bb6d1b8771b72f773be36e519cb16d6f4bde4769dd9e756c5e91ee995dca0112481029a1e3835e2efdea11a945a62ce122d6cff7a78ec9e96b04b9ae02175d129c9e6f54a2c33a7dd67d414edee9bd83de479da604ad1b4ff34f1d139d9650cfcbb5c3c20a2d56131d16b440a7a80532af87c43141019da237f406767b1c572c8dbd824139dcbb57eb143683d77ed6c13cdb367dd695de04ab748a662ef8a457260f06c125ecf7fc78331c4958fba6d829d92181301d92783fe8a2f767870456f992d44e49a7e86f1d8a07fbc1980691bc83ad4e854ed1d79c5818f3a7d45a14ea53394fe9e42f57c040baf4ad02da26b2e8071982a2b9b4bb94d2eff4f1b8f4caa5548a2c50eb92097e8f100400428e9900e04001e0860d99981a276b82297175d36836b9a69b6bb8a67b8a3f4ebb77db0a58ca696f2fe578f49c2863cc91534a394b3973ce393353e562bf0874213f3de297172fb007f67c5cd4a372a12507641a4398ce89de6c52fb6be42d676308f884d0fdfbddff01374ec35fa3cb29b3d843870e56e67e37a59cced972322e2b3504202d757f8d1d638c113285e9528efc96de6d8f728de904c835f061909d264da8d330cce9b8067ec73554cb319dc06591967252df299672382be558fb809cecc6af26086ca51c588a5f39c814263e4e47af6e2c67463718f9d3636f83377a1f08ae7b1a16a24ba115188340f271ba79dc46f6b84d16731aff9e1e180c08e8a3b26743c37efde4155d5ce38e824b2f03dad2b05f17f55cffe60bb3238f026e71d9e309d41a805eb9073d07b85744bebff48af4c322ee713466a1175f474228c3cc3229e78c31c639e7cca667d3fb06308cdacc9ea51905c27ea88c77f055a2720895bb76ad37bed81b64d88f5ee61b68585665182593dda92f175ec865e74e074c8fca21a32d6073c3e4f02466ed8483e1e54ed14e653ff303bace85c27ef4da28ec673b55a36589f08e79fd4d30dec1475cff0cb0cd3b8d7fca0b950e7a90037389708dff8d1e1b4403f1e5249244f2d10c90596446ba0d2edc1fa6054b84fabb536aadf7a150ffd6899a81ef74ec47ef132991d4450411a8108715f480031f1c48b94c848327f793978970d0e4962e13899174250075d8610a8c6189a561888b8f096c5f1eda7245852f2e04018090632600385000b8614326a6c6c99a604a5cdd349a4d19bd2194a9458539f464e072acfc4d2c131115dded321191109789882e1311fd70e76522a2d78540843cf87c8004216e77bce2ca8f0d0ce1f2d016a18bba3cb40506cbc1350cbf29e472045808ddfe49c394725bbedf4fe74aef935b2e943cb5c87483b43d70a80507c70c1f6129e5c1b60bcf927e44bcc17e2c64f4b24bafe2cb1b2e741c1c21215a7402fbc92379b4457f72c204c0975e4e66ec9c62d005db8b972d3396420f2ca98968204e1467dd3dfef42390089c724404c9517e424110368a2990289c47a19640c1ee075f13168bc5b2d8a9065b94c562b12c16731bc80363b1570cbe660c02cd58e6c1578d2eec4763d4e7c267da29f84733565096da32ec375b41bdf20f0a72f73ec9032d55594ad1b052e8b291dbf81c55b9505ab9b065501290b75a71b65868032db7f1315bb375345bd1c3b15e589e5e4df71208713d8053ce22c850a9542a2264582b5710a3d41025669cf67cc436419ca61f45a4ba9161ab621b15c75a972405262c07e1a25902228160e0b290bf7c15a52aaaca1e032f3dda2814f4d8ea8152233237524899a2e8c360a311992bbb258c1bd56846638c71d3322e8a284b29dd2c4a759bd26fbafd67354a2be56ef78970e38cd188cc95f2c616e179a8b4570dbb213bec865b6b4ebff96384df5eec396516a96bbd41ce397677531d544eb885269575700b3f510c1da270fd44d181cb932f2d6429e28b0d43ace0c25110a81575b787e342d62f0f6591743f2ef2a42cca8853c62e0a2264880520952ffd1f6471703fd59174c1948068c08690b020d8543e000492194d8080810927180d1c9e68b9c107d68315b0226e1f2179006db2200336952cbedc7eea05105e60b91fea7ea820eacc41f7837903cf0c266a60e9ccf0e833cb5e56b060028b614a152b5040c315237ad0f2eac2882f3e9865c44c5f6c56cc2de60f5600455d81125cd4424a02b4d861e6f290162bdc7979280b33a2a89c13cbcfd9a948da00ad340ac70ca554d84f16d5272db771f5ca813e76e10b5d6f22c240da3490e6a988987194167dfd9e536ee3c38bdcca22942c92de3b4d9730907ae593da1c6835f8f29b975e4509bbf065d7c3822390a01a811340c21336cf82ddf77f9a81fd64d186e436f22bcca773250fd7c0afaf1b49aa9920b46e1b7d1765d5ea6d4f3bed717cbb2990a0d11f81a67977b6fc51ed581e3a32ba1fea88e87e1495e37568cf5748b758dbdb8c763b4e6e589a97bd8bb2366fcad73ad70d8bfed6ed38a12cfaae1b96f6d97cda654754b84748f7513974c0120ad9fd8089bb23d98d5e11b7974b40b88bcb5e367f04d967de9d1cdbb198d2ffa1704109d6929318ac9fe87de10a5003d6ec944033bcb0c084b5048422583f7d29b44e037f7a3312989ffdf494402cc0080306d6120050c19a9f794ae096a0242dac25397a50a2c2c29a1eed12e0ebb0a0cf0c4860b06467bfb09c4e4f498c105524b19694b860cdd761c96e46888c89b1a46767169676aa04a8449aa1850b2fd69286818514b0e6cb4e8937f1c35a620282353d1d5d029411f2e428a648e182253b0490c1f20ede21fefd3f66667666668fd3fba08bb2b48c9f4b27f0c7e8cc1f7339b65a38ed5ea4a2da60c1f2d015ad212bae154942bac592fdfe5714dd8f52d1337405914cf48633717633d13b014acf75d32a4fc567c9cfd88562cdf9ecb22cf93104aeddce4559f29dbd29239050be1fd14a1ca561c452a2fdb070c45ac24344c09003259915ac25323fb0dce32ee1e32e44020a0e30164bf1fae161b196d814402c9802217c5cacee54565875c27c3a53dca00917abbb1c2eb096348454b454d6f1239f2fe752724a96405e24f5e5d7e90f7f68d75f725576de9c330f283df7434a5cd5bc0fb29847c89e2eb9fe51968090e02518cd0b415748e79cee3d39fa5acb2cf672cdd53ab9d821e13efbca750d39ae2b79cc341ee82130de10d6c1027b849318e9eab07458bdc37da9db29bd0e983dc2493789d7ea19b338122ed7fd781ab1fba122501144781d04984d4bdd8f6aebac0533d49f2cfb1ff16e5fb3aea18c401c8808aed47ed09af1d5b975725ad5defbe0f6b5dba9d9338f60af945f2be7cfd2e82c39c0d348c36356bb9f1a33adbb37ca0d6984914e54769b9f9ff9b143f223ca7e286f0b81ad56aba5799069643fbc3dc4f573e4e61649e2977eeaeab0b4af47601a577a3bda3bf939727393f895cf3cc2f4d2093af75bf245203137636e0943bd10f4cd4a3f62ab95c54cb6d4ba9f0e76e4f1157a08938cf2e30ff9fe45e4ade1d771d851aa9c53cecfe09437be9c35e364087a0c1b7b9571d2015ca98e61bb6f4bde419fbee4a4379def3027baffa4526e338023158fcb435db2dc467571a02a8652405558713f16aa22e87e9cc5abb072fb73908182f07de811a5f43e23323575a5912b53b8f2c8929bbdecbe1c97669e691e7c9203eb7c330fc7bbe95484acf8f0a535b11f13c11d23bd4aa5d02b5592b669567c25ed63c8061a10448805886820a51241d5a9484d97feff8eed3ff9a84ebd9618a9c73e7bccef54d4a426af4ad5a998a465a74ac52cdf2f951241d52ba79da4af4c0395e3bb34a5fc2470b28d1758170fac5ef8e42525faf46a7a1c5f1b4fd88fde18b3c88c88e405078b549be370b012e976442a21b144622f13a9c22a5085443837dea85449d84f2249a414124dfce2ba3b6771603f89d4d32e7d9aa6a30d7defef97529aa6254f85c50af382548160929048228ccb48c8e00b1232d8028c205974e79c1115a1ce97e2b808e164ca453b7b3aa5b38315e58cd23f051930fd3dfa7f06b8fedcef2db05f4a0af5eafb07430a2ca1be5c1efa02763f4934f4450a6e185ba8524362ec5c1e02a38a0f79f183a8ba0e534de31042081dcaa2564f0fecc95e592c833d19504ff63a39617b2824428409fb652f0ed6ab0ff654e9d50773b839f00effec45444f0ad9ebc818990c48446e009b31a1ec7574941d65adcc95bddc660347d951d6ca5e4456b05ff63af2723fd893bd6e7fb6d336423a8cb6e1d134dde5c9bdf2e5f6cfa419f32a93c8ca2c0a32f22b47d748cae5586a7167c06688b0283569874a13c0c20d1a0c14f6236141c80408e198e0a301b593743871f2e24105400405c1fa520a60c10e5d604963488a16d6a7f24206d20b219f1dc048b5aa699a47298adf0474d904bbfc53070d6147f7e81c6be07ac122b5a0cbe5922e97cbe572b95ca82cec375da8d874c9a4564b712858e4942e976bbaa66bbaa66bba94b0df74f5b8a694445c19d062be70db284810aea11c14b687da1a4958c09310bd03fb711112b53c71484a2963104f2d645252e61f580f1224c5fc73233ff39f9dec34984fe74a1ecbc4143d3e383e78b4a6c784888a601053db6ab55a44fdf1962b8477b8751f9eda135ffa4c23d86a250dd9c17eb355a5f4aa639422e7a7f864858f911b55980e4035765d2044c4375b443c8b6c3ca968788c150dee18638c2814a5504a29df618ccfc12cfc18638c316e27f076382fc7cbf71bc0ed2f6224e0a858f82db9bd865e25522d8b316a5fb42f91ba7bf48fb3ce18679c710ee002445071c59cb8daaf34c18c1e8410eef0457b012866948d803cf16bbc9e9223948ec0ab52c9992d806b8ec06c0a4a3b1da5afb18377d3c2469cb8a6370eda78b32996d8b48070678fdb5418a5b00aebc9b0b05c9680f5b867326a6271704dff117851d9140d798b30d193de9be4a2cfec81f55c58ab54581236c2e20e38206d06d277cc18eb029054a1e728a1e09cb333efe0e68219ef94543617cc3ae79c2622a8b8668c6bfab71d0b3fca861c238c7b2ca5c7b9d32d61bfeaba6d539f54570fb6ba64aef4d7845a9177e3c78711b2e0cf827738beb0f07b05971ca3b5a6a64c4333879ce2871c132be5c78f314626567a1c638c31421c60482861978d2ebf16849bb2ad6a5b85ae0ae596322c6075394d6759b49c2696b2a3daea5429bbc2fae0e99b606053ae04e43d9352ce4d7b9a79a1d1d2093a324a9f5aadaf7d6f55db2a8452bd16e4da821ec38fdf30d25829e4b25a6b3dc33d78eba6f58c31b66617f1db372db068b41171fbbfc8e5f2746d31a7e9d546d4a95e6d5862cc6db622a721ead576d4292cbcdab4e0547f6759a947901d2e67d6774259dc6f456eb3211df56a4bd282579b19d0eb600b4cd35f3b08854750394d52af606b3383579009a7e886c49004272a58c3ed87af2ea1a3304d436193abe6a0d5d687a2aead4607aebfbdb4e5361d02e760ab57cd29f9cd3d84c236dcf7c3167896a6a03e543661320f7af4729d8bb2aac74eb375b434855b4544ec40b8b0d56ab5bcb6a2676af512dada125eee8dd5293036b1588804f61184306e2f2bf0105bc10ee4828b22b8003a83b301f2f0f0489e1b2238373c373c4693e7e6e4b2dfe4a940bdea6f9890cf1099482b46d291fc724483d17cd24573a789ceb853cae7e9067003ca4a1b834da5546e335b16191d05655c2bc68c92fd029e7a68fbc581f832bf1dd613898851be30b364160cdaa33dd956502aed945cbdfabaf4a4579f4f18ef903f6313e8c269057e151f1f295268809fea56cb03ee46a56aa99ebc22ef902f6f28593260a870d50b773de372ad8f7399a2e83277e60be953257daad972d92ba726355888414206c8860d6241475e64184db445972e5bb664c972e1a7ba374e2f0080d501aa0a8e210290c38c0c8ca4e43032329ad3486534c4c86d6e54466ea4729a2d40c0b93c74a35219d96f1a1909c09ae1529c77c410e69c46938af9b2df34e268e8d517795446b79f46551111914af5a9bef49ac013730787b661d8a0031517b8e579643f2e420ae30b0a493c8470ae6441ede04310173ebb80594a8f9c3308cd01f809d434c27ebcea8f070fde1159b24f1539a7096693200bda9e62287310b651fea1dc8e11af904fcc28299a033c0ac5c5be4c2e158624790982634217b64808c7e1e987b6674819a34c923e3855613f99f4ea55101b7428a272e482a2a4a4a4a42455924c4a924932d84f26d122e945d69e12933aa794f33565982ab0df7c210511f94fe9e38383b2401d88828492f82144dc262b3a013240be84d887f751a780045f482fd70684ec375f35d6ab8f8d842aac4a2681acdc7e1f9001fe923c7348ec8abf5eaff97abde66bbe5ef3e483fde6cb8acffd18e985345b5b78b9dfe4e9d55789eeab573c149d74a874cd97353575884804008020002315000020100c07c562915028cf3551f60114000c7288446e56341788635190a330888118a2883104000300208020a31011690170b5cac32063e1b6f9bf994ba9f5963a973457dffc2b8795b899ae049f2580cb5e7c1ab2687dc6ac25466ee41b8a8c55fc0205dcc62dcf88ec83644ae8b9f512a543b7644f4caceee7e8b29beddee1bcfb9a508d8058ab435e7cc7e2557c8677e87b31ced131b5a2134a53b66056c72d5fac4d480d0395cb90ef31fe29b38462cadc789ebea217db878003bc85bec2a06fe477beee3377ddb17a85fadb4b7402b48645f4ca72f0b81617c10c3fe9acf8e16d4040e8dea47f1f0642be1ed73eded96fe1404065e688fe8b591c53c76d4065a089496aaac30d5a6a62fcb755cb233e1aef89bacc43570ae9721d2a96d4d8a6da582f05540f3e4c1241260ae9c737614f7ab49cce4c0ef378d494ac770793678e5cdd56e29ad8cca6db548188c4122ea2fed3eecbb4c91564222a270436d628f39ab2a966ebaae8fcb0f8b1042e9274cc21c162030e8d8c03c0b642c13423f5664ddcc37c161ad14a5a6006694e5e7ca2417498e4b60bc001f19ed9a27f6726fabfe045c3c6f3753e50fb20b6378d659fd89f6d3a3830aa2f799898e4eef07b2388a98f51afa1a676e3790bd3ee2e16530a93faeab3e41a3e839e8e68b253a2e6e61988dd584b4b9cf277aa973bc927e96a86edad2dc626cd1bc7b3511a7bc584fa963973736544f0695d8ba3d5868a9cae70bf8d75ac384af05b9012de2445aa6890eb3f18c8e5034a434cc5a9832de0ce9e05691b8a0bb067883732f9ad5333063641d08dfe43847398806bf6ce178304217555c9c15b1eefa5e2777a3c41a49aef2471e4f8d5ee39ba82441bf7f8bf1e10b56b34215b0caf1e022a006db441bd3cbb8c7177f5a5dd91f68c8e870b3906e4ea056ce843adf8a3a4102b223291a6ed7bd24d5319f5cef5a9572e52ef64401d940734669d21d85e7cb8c95b644895cc6392856ca3dd02b2e2193e42cd3569d8e6dc38dc6cd81b986146b287d5942c90a5a0070cd72cf8a8d320e4756e880df161be9b95dba0a4c77a46327dab13046795842d9a7ca2d0b03f6652e4026ef4947aa70bdff5a33c8c55601706dff6a872944042f75de312e1f01e89d107ec35aff838f2f1f64747c31134a6761950fbd75f78d590e3aa23b0fea7683d8065acce420ba25d27513a24964038fb5defe910593373e012f535fa7a30de0cf4a5759bfc522a9af467f082315e349141e9bd4efb7f3eec039c36492548d8f8f63401ef872d5d770e84d5c515a195307f467679701baffcea552a8a09aca327777c994828e928ff4fbc264d3fe22341aca123bcf89d84be7a534386d155406343aeb84408daed35177c351a4d3c22f8968ea04185ee4dc882ef8cce76a86cc1a0e9140de5c56a0e9ba26cae285924154a35c715f720d7240af898eb7e2e018b65da213c9113632804740dd8ff179ff54b42b057c4f1ba531eb7838741f9602e28d36db47d4b310ebdee36f5d7e703c7dfb433b6450f594dedb9e8e50d8583754465b810931e954f163b8a776a9bb0ed02175bb0be46dab235ac051e31d3f656315698c40695a0cb47a56751b1fc546be9374a49d1e23a6804443f2cfc5fae657a817b3b8f9cd89fb6b75ee5d796cd8e6b1aaeaac308987f78bbd3dd5dc2119c37be59ebd06a538940a8d6da037b05e1bdc08861638605ebb8f2c6fd76dfb149b00372f86e9a262cef37f41a1c0e16465d43d1b326e533bde1224fad85d1859772fc70a23363e5e048c69708f350300d0540ea8aca850c82ce15237da518cb5eafa934ee359238aae44379443e8a965a67b2b8d408a8f40907552846af25de6770a93b4903a487e207fd89b71adf3c05ce68260f33c2066695b5a267e3fc63db04fd99f092bd01eb008f18a3ce3ebac2a70138bcd215d9fd7150c49a61182fb814988a4738fbeb5fa72dec55ca64033b9e0f6897357022f00f6f7a541c37c2313b672e8770f0abc694397e912223b26d9a6d541fbce7521cca6492b7b73f075f2109bd1cc73c62801dc1e084766d6664e014e373ab8cf839fec183cbb348056dad764859385df258827b26ab8e5ca3cba35200691122455ee6c6075d2981d8d90109376c33b75dbb7a98c4aeb06ef6829e69b1c36b0fb9f2a6197417b08aa76e53f656e82b5cb7cce74ff32eeceac95dd12bf892ac3ae8c58073b05fa4b7dc72c64010c05a36f36b42b5c96f158a0d283e56e6a8ab3f8709c96580f19270a2d53178cd0d215a49848693a1eb4f69a15a0698743b6f9e61e5f2f002afa1e6242b7e94073573e37c5e3cbf7e9c17c5ebfa7db4e18352d3e9ec925d98c10d88199d2ed6af787f31d39a4066f6590747069c0751a9a4442a9052913edb78b2a452a6f8e87b073c6ad734a795d9688aaaf9d54d1e3111865e84adbd5899c3d2052f6f8dc8d78c356a427829fdbfc93ed22278845b3dcaa97f9e5e051680e24fc5244b8d415e6cf3f86aba09d66df5591922403370aad272d308efccd421cbb3cc2ca464f483952d325637bcc4686a08596641dc12c66d5bc3a4b23b6a97291c395bcbdb2bec413eca20561de5342d488063086c86e2c967858fc37fd57a66673fbed50054f8ff04446beeefd47aea038e61d4a180fb4aec285bd45cf48eaead37fc7751f2d20b5990c735e3c72787994a9ec687b00d2bcce5778e8632fa847d43e7206cfb118b2040a3f207e0c01a98ce9208c49401a497a43f634239240b05e085591f4651a8704c7219fef249e7a5e2eb60ace911bed9899f54cb4d28a265d80a92b1db9589c3c9213e34c5a2389fe2c1d1328738f06605f481cd876b6934e504e75bb894ce25cc1d0f16259c309dff4f91a521a68b98130d3e8683c84e122c6061919441683bf5286a91c974b158f8f694d41f4b10b6897400edc1eaa6e8fc22b348fb1855f9da390afabbc9015399025e3ad99bc7294ceaa40bd7d6fc74745d1194120bf55ffcd9bfc68a1df990fd2403c0ab08dae4e4e6137bd4e9aa4c328ae436049fdf0fa3951057b9ca0a460a84f1ce35ea1554e7cb83741ecbd0dbb5e2d84df0b9034ae7d5d7a25bc9c352a332f3ff90759866f6b2a54b21855515682fb118ff90022867e25fa159a13e2702799e9167db60828e8ce4e5e9875a439cceca791057298b832c9869352d8a5606f72cf35a6ff94fd5884a29bfd278fec9670eee3164931efabd51c1b381c8504168d4e4377a7e87d03c93da5c4a1810c7364524e5dc3a6ffd8cb86f87a5afaf5d01e05be10d6bd20e36a241cbfed925885ff86528367746f0286ef916f2940c01aa5d570dbf6e46296cd0c0de11fa76254f04d7773758d1ec6af719a2fa00d57cffe80df62b7096665d50148a4513c6afa6b05d8141ef534c3f4d8c9574682f4acba4ec8903479c902f33c595bba7b875351429aa729c5e779da19b0289292b754dfb4f89ff0623d2e31011d6cc5b10839fb4b653e190e1c55a52f108f002b60e037c3e04739fa8ac0ef71848fc124958e0cc730db62376a9af2835aae3018b3116ff079386a5f0c0c6d15548c31acbdef103492546f448e3bc10cfb091f5f5df9749cb4741e6314d1c1e75428c6926b1fd1de931960ff934b1bd84c932364471794d830b4a3be49e0f366a0afd1e6395846e77a399036f1dbaac805837fae5fed4057f3a18008375107304531ed92bee850729516ade698a466ccb6fe305915dd9c2169f12cfa0f2218f07c1b7bbe655fe485b5f5f117f7b59c557c5fb42d8b32fae016b08827fc0166bcd908a19e76e5868aef51e8023dffd4f7d9fc1b6485d2e548da4349c47bfac7b27279e5ba4fe0ba1925025b1fa24e3adf305767631c772c5125a44b66d5f84ed3000d828418654637838fcce00383b051e23750209980c715e4adcc8ee54eab298c64806b414a72f089abbc4425ef21b68a651ba0a44444e8ce807921444e014081280c95f284be32d340f0b882cd760bd1ad3a85585db0534bda1dd81d652ff4bf3f1aba8c9fc61143382bdf99a02cdc31dfc7eb80cd9b6e9054446cb067671af318cc99358e2fef0a636bdfe37505f86b5e1f0fd1a3ab68271edc24c38bf2a225b1c50e5429456c9420c6298ca52a3da34164842692c1dc764305c248b9bcc39b1e210ab68707674630a02a6e046f78fcce764c2369dfcb85b82fd92f0aab4c69ec7a0c6dfab3fdf85a55e60ca8aa10139600d0c8d1f45c0ee9b0ec34e410ff2c1c4776a718decc7cf1399f41c0374c57abe4dabcd0aef06740ff557b0a06bbcc7db573a79d65a354f9dd8f6fbc32be096cedd70b2c1487329c8a9719a206844fb2361cd453a771cc07375d5a117cb5ee14abf125a15762e5704ca8308f6bd092a0c8d78a75b56795497b00a3e5b28dcefc0b12a82fb5a18f5efa21183a7e68e953972382434c221994391b3377d7488c29995703a9148d76fd628ed7911282a177031f838b9f2e1f514efdaffd5e25fbb27c149de9193a25fd49a97fc4f7fc92d0c2050b424ba803b71c9ff31cdb5c3ed5d3145be9bbb4c858e3c06e18386145b977ba23a4bbcd58f967c1e12968d8fb2a32cd4da941f490e9afb0c09e21afa3e39da4aac2d902ef6d2d476b27d32dbe2762a2c3e547780306f640622d61e31431150f0ab1ed1a9030ca040b2da4bc5f0be1b7db2dea3d4ac7e04624a578f67c4f9ee88038f7b6adf7ff360fc98e72c51db3bd7e7d442edf56152793757ece43fb82ffab29541cdab56b9e146550c3ef1ff502476df0fad4be578ad964cea06d322b973019cb3c3128e70b7a07ff24553d895bf2bfa1b21d36c8de31fc9bf8ff711a44de03bf6f2973c62adf7ce61cdce91b4eb6affc855888538577f5f0519d82912c0c9a2cd420a80fbfb1821e767ead46046753c719a7f9b47247a81c35d126c7df80b4dbb4f4831969c252fe5e7fb00edb7e618e5ad339627f4f427a532671696887f10aea07f432c6610ce336ed52b3957c5590115dd11e53b36181ff942fd8d518b9727b22cbfac11ad602dd7ff205372eef00cd273ecbf7b6bb292a73c5a57dbdba5d7286161b0e91815b294370e6c9a7ec47090744d9f5f52b82052c01ea5c74a4211067102bdef9b30c09dd80b0a8e34e1d88364bc831223ee6171952880b922b2581b71cf0287418644e8894c762e084fe8cacbaee180a2ceb03cc404cf0202f15655703a297abc072c9fd68a7f945426db127ba868be9490bb1faa12c0f57af936d6dd202ff13c5459895995136567a7cd556d3a2fea333012651e1ffbd37acba892e555c4b948d884be47ad726ec5c139e9bb064397275b10125ffb4e8deb9a872ee26eaf8f4d203ad9c6f3d02aab47ba34b209e0ada0c404d4358ea6e80bb899097afc49d5045954334f3ccf6d4bdd54d7253b893b10877cb107a0e1bad5c24436e424a71484c5166234988ef68f82c2c16babf44c8cc5babde688bf8da50f6568e7e9bd88c8ba03594ba2ca45874d2af520bef256b5043c29d12c7eb27a0a6b6e780506486c0692183d5843d1e1a5aa55c0bdd9cd471f6ba62d47b2a29dcfdcbc6dbb82fa8235bd54da94185316ad56850d756053a92e685dd87bef1bc8ab53a811160bbbad0945c0b9b4eb67431033ae0a0180c40017ca5d2a5010012e8b23438c3566ac651034ba74d5bdf2df26aa9002e7f332cb55acd6cc58824a2e284e5d7d7badd004bd72bf81bc26582756ac045127cce971f17b2c9b97c1c4ff040a045590a7430153617050d58f31880d972f882946e303083d17ac327146e4d174539ab88a6ae1c1cd1683572a48668b8c557f74b33ffe1335278e6908e86a9aea39b6c1ba0f2e0368a6c76273b427f0dac7c704dc8306ed67634bdc8de3a4478b1d1017fae126a34b16fe15e3568544671b5a4dc9523e2b599c63d8695bc0525fb2e704cf373aa743abd512fb6c34bba4c93d95410625eda4e810165964d9753455bad939dbd7d7a335ddf610343f6f6940d25b0d0a886d6d88fa3db340ffa31bd079702a76e1b3e843342d9a9f977f7bdec2e9d1330cb9eb9ce49cc660704c434f78f87e131e53896b2e60799cf80d71cb7d84cc4df5d4374a6c8249dc90537775779855e38669a1c0f8b3297ad41b737176e40c3c8ed060b50be8fade4f807aaac086c58820f175103a459073c4b21bc8432b461397c6b37290d09b882da87d5adc1b2ec2394b3d747622e604cdf7a62237b08e7964bd32a9028f9ddae90514c930e741341d76594595dea22574ad5027a396bb3eeb34e85944d754f4f3b775807e03c54f1190332d316d3cf820fa06ba283147678a4a6a57074e3284a471953c44fbb1f7bf512e439856cdf5a7c6b95e883bd5449141514da9e5350ca35eaabb580e09eb4b3d6a878c558b7648d318089a8fb132ee060b01b2db19be207df5461d696380b2d23b48ba9b7db6eae38d34cba7d34151aab915398faab212f94029220c36051efcb10af230bfc32faeaf7af50f6c3b0b1666787e10ed4f623a7cfd55b577d503ff01913c75842bc519d6ffbcc957a931b95726add1015524b9ff97bf5f678728fc3f9f6b2226e12256f3541bea589920f61e3f786b541d4073e882d899446f90ebdb22ca2ec42cf61cbe8ae4fd5bee2fa8145ff915a9430d6634359075db64f1d36b78185207bb7a74c28d3c681c9c16394e1ed39c3757ae34c8fec9a0fc9106fe244aa7575462bb445590471e9665e4fbf45a9605f21d706f8c7b7c4f1a8182a6a0d456a1f2f3b9744132070aff7ab7452901dfa614f4b66445916c80270a1da882cf615cd385b49bd9b3159ad495853b9a94a5b354dfa1f048dec7e5f9aa907794bb32a391746d1ecd81a3d819261380607d082ba1805a888544390b98de5031eb50c64b8e2fa2467d65d415e0026700c1928f6bfd58a6396b1d2a640615949974fc175d25bfd6ca1449658bd7887df4063a229bd015d9f4e8f981a116ea057482c025ccca7a578492d2c5922e2acaaafa0ded7c4db813ca2554f6100d5acf0714f99ad5ee0b977a64c95a925823587e463ccd9bf7ef17d1531377465b8134c5c8612cbbc66f48786219682484ffc460a4d02761e27bc71836a0aa17e753cd8a3ac53c3feccc9285913990ae6298a86f0f75924f96d911a6ff006d9d017e54e727066144867823a98b0f21736df809954938ef2cee023befa8a6e81fd148349f5f7c1aa477ae854b547a87a4686d6b523446186d89ebb08d22fe452e6c5f681d9c96a0def6cfaca3eb799e9c905663b6808e6148bd8ea80da788ccde90639f935eaa90ae82b60f24e30651cd3f747e322c7a20463e4bfe7b20236852067a7048365896409576d4f29d08b44243c783b3b86e05f048a2c47b124b0c22354cb159829c09563871ba482c9d2d9011ad972135929819db5cba54b5ecb4dc8e75611372271d5e326119e679a7571f7d0c7b1aaca019ada5dc3202b27b3371f89bda27590f57ed794fc8bf462ec5bac93b6004811d98e3a109e28244accafa1ed7f18ac8557be59de34b10e7828e45c6aecbf3ce2fa102a7e45f016938350c3141dd8a26b40d1d8ad7970c8fe931624150c5e22c559fd71103bb5aa25c8a4d0fc7bc8ab85df4d7d145c5514c9799483ca2653c8b6925d81af8752ca68b11657cd64fee1e3a7ea24327f33ef487cb2fc17fe8d2a0c76f27e1e1f67fdd311a4597079a986189c0993435c7bd653189adb93f585fe472a98f8385cea5e41b47a16b841d9fe223826abd43bc52837393910d1c4cde34f57c3d43782eca74935e6da3469ed161c7a955ff6da0e84f39690f2f1b3e9f29b0a9690b017d8c9be1397b3ff06b253731f236e4aa0a39f668f4cc003b747869c71531237494d74566a42bea43517b92f236847002ff52659e337bce2f660500c32cec4bcc62ee9136e1cd2ec1f462ce7d2fd180548b0d7412997cf4006a3b4aa50bcee2dd26d59f2d9fde43fcba6bc0192976fa33cb2679cd6349c9addb8f4b4512068117f54d13ef972945860d27a635bb6b30de2b5fdb5f389e4014b0a505763e9a4a91c739bad2ace4981ab015f50ce2c36cce6bfe602f00e16c84958dcc5c77ea60ea0a8c95800994f4e1e3dc77a1a8fb72e1fd0e7d49a2608ea48b3c08b5031347b09f88965751947a38b8ff3900128dedd326d4f8dace84deee87dacf6f6e84b76bd91df49b24ee07b7c83b5f857776ead9ebd92eb2359c247b3accf5ddbb77243189be72cbd9edb071914f69cd578ab3070a57788861cda8b4b5e69ffa17e8d7cf89f319f30b8e7cb51c6fbbef13b49dfff3db36cfa14ba2f5856e14e23f30c10c898d9cadf3e66682a1dad517713bbec73c58532a74b179edf1f421d726a3b3e4b0a4708682ab1bdc932b68047d73e3eaadc42ff997f62d135072cdd838a165e9e76abddb820c247a42bdb76a48bb220a4d83fce08913c5c1b517ec05207fdb1062cd90260a95c5de5962d9267a40dcfbf683e29ff3dba39a6fe041c7fad9d1656c3061c3d1abe8270de3dcaf9ac5231668e5c70ddd62f08b9c20c9d235c61f6b5ade4565016635176b4ade4848520ee61862aabac5aa3b2abb8301ab79ed985d7a4ced1373fa3f948c6a95c6afdaca3f33724b5a0754f1845a8687edeb4e545416ea5365b666d1aa3c7b336190fa4dc4a06a801c94ef2ed910c525882a887026f678a8b178b88cad66ff2bf26e42fe538b5a8353bcd54e7ae650828203fe162a1a5f81868841c23a45ee3b57a481a734f27b88d3159a08603409ee770e18053a923646754359b6245faeedf4facb76ad9336fb196513e1b3b0efd59dc044a2d07a52376cad59ac3830db1ee86b225c9c9f1c98c551ecc8f15443e621231e9c7df9e4cadc01f08512b2eaf58922ba96ca0e878e503a7f07c0a011f3c7b9101aed696b970ac9a3406b799c216144930cc0151f51117b1dbaa3daa2f4aae5832e0beb9f4a997d3023b9c64f73ed9d7e1658a72005055b95fcd8c2097391c39960d6adfca038da6246f67d177199e0007ae9be7bdefc3054db059328fd6252c07c07abf029b0c17904e26133bab003452cea5f63f207c2229a4390098aa90b51e8addda2264476f844b7d85f4009a7d7f7c423f1681c18820145059077786576779b267bc60ad7f9291b62a9b574385ba4d91cd065541113dde48c900c7bf906575b25ab9ff5fcbf9c4e9f02dec05dbc5cb186658a6e8ef6768c1ce0b0d2b8c6067cfbfa34b1c0e9e6969c5401e926021c1de16b1289c65e3c9c21f505a1f3f8deaebb344a818c3d05724ef18869ab74a2bc968fab9db4be4243ed74742d5f826cb7a9751b2fecc7a0ccb588d4af724b25d0a0876772b6d2314cf73187b8a836943f3efdcc15478c8141dbe2d1d7fdbbe89031c6b8e202970dfcd5f325e9b51f32afac6382a97e7772c8e2cd789913b093b8e86ccc2f821ca64f3accbb7a83b8cbc0e40fe79c678dcad2e67242fe154eee96abf14aac5a1c3d3c33435425f61042a8650c19008886e80d49635f2dbf6163be1a8668a6747fb9f1e1ba80cc20d017a2809541ea55a6366a3a56165d5af31160865df57c300dcb4d88debdc0e641a6a6296c8bcf0a8c0e3060801367610800f2c765eb18a7d6177f875f873a689cde52b91c93309273b98d0857a05628c82e8ee07502f61d2b6c66a4547192730c07a02140180280a106002a3bdfa4d3cdfd9a14431036f7f20e0e75857c3e4cc338d957e3349ad00dabc87ad48148661bb9d2f24fe9f1a9ad291c6f3150aeb1121e43af441616a387bb1a217cd1fd5e35f51d0dc1b76129c0afa38d79d1fb34b5b1e8457de164fc332e5402ae134243e1ecf7b1b62157592308fdec09368254a44e9f18b00df9c7689db51449c8139d62a3485c7bab7efa9287326ebf707279883b9a49873d39424bd1a267885c76a3ad804754c57a2358b45c648b0d1a6c2195801c461e994d233364c0e220d2ea78a90a8f62c9eab6a4244e724f0b7cc26ade03b97f45b4245c164cd8721f6bb5b5675ac26c2ba4a5e3802590adb958856020c4c658d9c5daccc69ed792d1e1b0657f43745bf0c66ea2e4e756191331f9bc79a257a5f0290e87f4b94565575ba501ca6457b0d549866e810cef2344af4d7f19d3c76ca7458b64a1226c6bc4456e084bba6913f454002a55f7541f1e149c035c3cfe9e3289cda60c7b929575f86892f0282ba9b5fc507c53725be4659b9f580f39627ada6da0f4bb8fe4d3595ff04108c9a9da1c3bbf12f4a54238abfb70a274bd03ef72c3c0fed127e808c8caf896eed1456bff81341e14a7944ad5d3d24989599b881f4d566e3d1dd215bdfef37c101c8f4f80cbdda92e49d9193917f0e9695dab0ed1d12f92cd1fc8e64c04fcfd14b0eb13f058f1299049258662f96e8da13a1c75648d31e7a336dc13cb1f265760319d50c044a027bee2e553573308b4664a50600a4d527e8a77abb65af1f4c1c10c567c595f058c9dda7e51ad108670202ad6374c618694a024c5ec5e6e917283d14f09aa9be386343eb98da72cc6dc26b3af3ca5ab591a5f0c037f9c6a25794d61289a968f279fe94cdc891f4443e0c16a118a90621c1c3c7459235fdf5246493c2e6b33f1fdaf36840ae1900690c471b96a8860b9a20e61517a5d18e7e76db7123b115b8e6f1374f13119f7c1c71aa0985588a4fdfe64a91649860520e74a5d43bdb3fffe0b55e012438c127b8181d12ce5a06fbc2380f776cc445138f546436a3d547c172106a8942e82b8301d0e832f263e56083cdea8c48c5a9b9bc073a97508e11210c80b17961f92fe6c6b850f9c94a724db3cc7ab34034b483d81353dae3447c404e3b6fb567c16c82d75df574ddd022d768d7c96d6d68a798d8404bdf9101970522fa0aa04fb23c9b69382187bb1b1eaa4acac39de6fb12d29766a84086d87361ab47dd4baf719d66a23fa4fcb14dc28c6d81677a326007e4e237a32ff30384e6a4620d4024f6dc1bb789b83d146d7c21803005bffbbd3fbc1e2951797728703055d7d7800e3894b9351d3503ee0c471b19f7523478a3d633b35b30307d70a126ea5dc704eb9a047b0cf60c70d10db4383edbc010bbe258d3c48bd4d835edb4722f92c3741e31ad0e81931d22f0cdbf41badccc2966c345631f0cec46a60500f5b5db73b299a250bc225f5cdb038b7ba0b1d8f0b10af95dfccb64b36db271afc5cd5f29690c2a679767ea24067d946d9a58a6f60da982ad04e22878263bc331f368c7f9deed66b56084402b6a154fe9d874500378b08ea82bed720d84789870bac1b26a80232e39c8f73b31d230403dc00257a9c25c74ed674c17e3a83fb6a1eed0ea30bb2943ead13bac14e52181721b90d2bacde2530c31812cde547701eadef5ef76c693dca202e7bb678cf93850295f34a51c09f79fa897a54ccd51846d7c7093298447b67621875db6118a9ffbee8187135a065cb660858dbb889aecd46aa598ed8a292d87231c0e0d7735b380bee686a240ee32025b0b6e49c5bd60e8047c644dc74810d236a2ceb569b6868a9ca1fff7958468cc21ceb3ab28ae743342d32526b8a76ab20dd70dfbf2bd1b5dc533375ed7156d83a1489a1e52b4afe22fad20b312b0b4d76ae00a449f7a844f513f69fc9f6ba2b0f599be559169224bcb5f77c56242a2ac20dc44bfff3a43cb3cfb14d5432a2aaac9fcbbd89ef5f1a2f72c79e620cdcfee3dcfcb3ad28650db22d7d4c3a40b6daa2094c169666e80d92600430805442d23da1a269931928562d91789ce022c0333b5843652468960d41360ea3f26f3068125f8b0e55ac4dafea9e1b3f75f1a9d10b5abac48716e237e048cb3cd4b7ec11a0f6ac62fdef6d8c2172e6bd1b45968a600d389e626edae5141f9cab48d1f00312d84e9a700c1c2b4161d4da168c19743ee0352462bfea431db02308c9e1a3243b530316748314d46ef158e13195ef20f36ac9fedd2ceb2dac15b0077e9d4293696e98bd7610c2ac91856e73b2bb58568ffaa9d7803a1998c70288bd1cbd86ef1f3c506cb6818b9884242c101f831067448c202d64f7edb1263272af27c10a2a4523d6d657ac5e496677e820334d47351a3ce71fb5eb8550da67a5de15329a35e424207e8b7fa6a38c206d720989a5ccbf2c8b703125b9a4179f28be417d635ad211218e9db27453f0473d3ab4d59213a95408e7b66ca42a285fb205a07d0cd10fb91243a9303f990ae9eefa7874380f6dd1b8a285a403146912b4eab7b9c513c232a06630d9c151ba480813adb835974d80c5b870fbf7754765a43f74d38f35b5634fd06274dd95796ba49c235b25a0cfea783afb050b90ec06a4f373ddd1af1b66df0c2e34cec4400421a062ea84ceb402b29bc7f00655f66ed8c84c529e6d20507751f7c7a60eca0b7f4ad3a2171ec85aeb1f1b378a1b99f7956569f6ce5d2ec674d44101b6dac4479454d0e8e6bbb6a10228708e464c0d597019823e431014e54cfa12368bc8717f91520b3b1c2b158b6686db63e8168d898268a9f8f25305ba720ee3bcd2702f062e0e88204327a67afc49464d74f69716ae520a99370fcaea58c3209111669c7ff3be14b0944608e8d21e3517be79de551da5e670be9f729ed327c0c867a94417dc591f17141dda091dd608dab317aaac1bb6c494f465c793cee4489b9e7e2fc1f2e776fad6dd18e18a11c26090ec372ae61317f54aa40a364cdff08050c248a5ee3c0597bf37c3692f4afa462bbe6994ae66ed78ac335d1ef66b0cc5066f05112f3f825f63c2725eea9ea6326bcb785a54b872408e69d69ad009a752c09a0eaf3afb3ca46659040b4a6be9edbbfffc32d8589cf29979efc4c2faf6b75ca8941e164f185b6dc4028322850cdf30cc311617a3f57c5873ee7bec2c3049e80665ce2ebf18a99914d37c0e1c82e7692b91896adb2204c0ae524547c1611048d476eecc29dcf22c7a8ea4c55d81032accdc62549b56b3429e4233e02c0ef0a74cd449be3a891ccbe2b276160d0cdd6feeac0bce8dab23a10ba445729c967a683b7da8ae18aad211009f1fc60ebf87e95a974688395956ecd6af474ac42137f0e1a30f33a658b2c96899f2ea58ac5010beec416f7ae6ca1afd1284579fef410bdf5e9c0df4413f28695a55e67a4c6015ca458c365eb10d05f5c03dac8a05dd5c1e72c13e2cb94a5d5975b73d4d49cdfa45b6ad2b7b1b683a8f914330e979bc47620818599c8df33b1e41ae13b6ae73995f4c02b636a2c424af6eaea772f8fbed769d57b4415c9ac87b067d8c66bdc6c1f399f41715cc2732e694f481378554629a7aa034d95760a8e5df9e1233746992468c5893dcc55c2c571eb79267dde221717ea94c916e2167a6c4917867b2cdf1aebb40c48befa6c4b4a9bce9e79b0fde5f989e9f5231d2d2d436a881d61039fd37bf3f72e07bd32d48b667eb6bb423fb08e88e32aea6b79671883737dacb94c563bdac27016496c470f6b862321eaaf07f706ffbf79e29b867a6cb2bb260dbf3b01e497099ed94d5fe8abf3ffb88c4a454d060a7c7cd3c74afad7348648805020d6af5eb080b982110293f296c399875dd91a9bfc7a0618b50603af2e2e2c93c4caa67a546c0702e5b1a0389c8b746bf919cc43db8d2fc0705f6459513e1e7f4e60b5234b37c34e1e424dbe86762c8518968f16cb24d9ba71073989c983d9dc5d5b684a3cc695f9217fac0fee9c789acfe97ccd5b81b845a7167f829515aecca826b76789fbaa1c2edd50a287c8e42ac560c5d971a6b49483df8285c86e6a660ad32666350bfd4faeb8866e08f4d753b41a06e2bfeaaf03841fabf806e313da7711c2ef43b9c1f9f3a640315ba1f100f150f903cd2db029a9fb147350a42b0c178c7e69ef8ad463222629e231ac3035a650c2a4210063873b70240a63b36f518c3d2418ef6fc72cf11f5ee1d2da6365d5196e6454fae6247fbe84b87e5f55a70952b7d10ee7c02e6c5ba95b516515f75c54f63328184f9d8ae2c886b7bf39ec28ff0b9a16fb7c45b03b4c9a5f1bc8eab20fa4b6f142935ee0a8e670a92d1f1071c3c278cd71236d01c2ef6e33c68dfa30758a499aeb6e050b3645883d5e0a82b8450357b4db96f1d328018177e2a09846830ccf05ddb6b0288c5d0f98b15d8f9d28cf012819aabca9407cb7a6ad5922c4bf750cda0db06197412256ad8f641304d2ed1f37fca7c8dc95907eb0c8a9cd1904308cb83925201d0151f3210153f2233c27d4b1ac99b94b0d0b0abdae9930449c411e113ccfb4009da7e11da1f892503c4414a16b559369f60a9474c4117dc8329dd18eaccc33abe6070351b6303a9622586b0d5c19ed49c7dcaa91db6684bf012d4bf0adf1caf26dff33365d6456814e7d685a8a7e30809af04a77a10c096228e75ba8cee3a0063cf23e4754adc4c94b74e2368ec8872bf1d2369d2f96fe3eafde34fa9b36ab9508b393ae9c1c935410f15ff5e62e11ad8e0ae5fa93225d5873bf219ec4056d7420ffbc90e8ee17f868c0786d14a77e7be93ecf2ce89fa4309ac7e3a485a98f23e15a0ab464e3056c86eb3aaf74c0aaed7800b85c6c430c22d1a28f03d98f647cb3d478e6bdd6a4cf205b53ac85f026ace6719d8f390d9f5e4ccaa77ee7a7ea16ccdd0d67a0a10a7cd1c552db0b4c616203a86328e4a6527b8593754edfeb7957dd5044333f919a14e31aa9c8d1fcf98e31129895a124416f8665c91295a86747d1d3092ef5ef9fa3d311c69ce63fbc8b3fb4345f0b961eb892c1814d2524a9c35999cd986577fb5b7d28ecf3b3c38bd2be687f10ada47ac9d2f58d21b43cc9230ac419f29c9dfb31fb06c6575fefa1d1e766f8b323230948294818af535995b4183ea8ff76aa091df445a69562c5c5bf045b70457dc7bda670004786b1bd028344815abcdf03a20542258603e154ce9fbb240a7a38250fdfedabad5898d83f0aa0a1b3794a948c23afaf9343c70e57bd9e0bc07f661efa9d6008cf9f35b82aa863ae32ca3e5bac5daacdf0e9227236e554ff6bddf212febac77cf45e0162f50cfa2083802233acb17a9eaddb8cbbb8b061afda56c71fcbc9c3006b163f68afdb2d22c3c98b9e2dcb943105513ea99a07af2f51fa2024b7afa890293d3357ceb128624aefdf0017194746fc9e2c0beeb96268ca4290e30152d1ea7edd08928d54f1d63b17d9d29f7241c86ede2a9a7524b611fa66c2f2bc586d9061bcea2408942c1e1aba69b5da2042d53ed0d96f7709e39c3149b77ecb1869286fceaed82f9ce7243b5e0e996065ffe9679660ed79aa308b362828e983392dad8feca04970c171a605aef567186eb706758678a6b2ef95edacfd255196eee7e5f199b21a2a773523d69ff0fc9d501e07a18375bafb00748ab700ab8a0ea78eb87b1a594ddb8a98df44957a0c025fa4a2ed26c9c184aa1fc1a4124c5a9b8f2e1b0a30df8c011d983b7d22c97af9bc26209840c23114668b413db151624b1f179897fa3650af8157c9330b75eabb9998760213a409474e2c1ddf96c4832588403cf7bf5995d70a7007a204d48db59477eeb5ebf110b147cc75f304bea95a5c810eac06595a87eab810f841253af279053292bb6e61fdb896b11a6e17add20eb15b14e8cdd3df92277132949b4927bf3457617594ecc4ae5d04b438a7e258e16fecc1b864ed2bbc2268d60d63e26dea0d7bbcf6a311a23f8396972be2991c2e7e238df281bb84bdbc23d3220006d3b5bd9d7fc9ab67f4d6a3951f8f40f90076858959f03af0c990ab2c32e9d7cc0cfbd56061ac2ef6c7eb29e0dabf606c3aa862dfc4c0440103f078054de66bc2447d694365a3ba442332ea49eec52f4abe356ba888a55d6f3eadf306d527c533e3d108fe4ec897fa03daa183f8020bf339b62e2fad1b39d110a7ce67b30263cceadb954960c6d37e9c78c4df61fc29595ac9538840128b76a773a41f6079c38ac2053132fc33ab129eb2cd41ba10da15dcde824229d4ff0128ff7ecd61ff289372c2ba7558d6c2ba63d4462d8bf199fd1324d06daa75143a844f5c6ad283723fb27b4351384ca6ec6a2dddbbaa590cba73efba00d90b33ec2354d7fe2c063dc1f636cc782150ec668029fe1571604137b4cd56613adcddf04c5c3d68fde069a8472b57acc6a351d926cc8aa635ae2c85680f8abb803d8af7cf5589f0774df4dbab56f01f9ff013532b0368540b34cd7262c776b2b7fce7926ad67609c79fff60cfb754e57e2ddbd87d0e3e1e6dfdcbc25208df99a3b02a9aa375d313a305348e1b6ca46e651a374e2bc0fa11e777a055193c60eb3aa343f2867aec7db8b8b9fb874a930741e5cc15dd4f8e8d51ad0752a2aa71325193d9840c04e05a14f4cded6e51986d42412ace65d73978c43bc905d62b32384c44f8f9d3575527eca25883b2b47f9f08041325ea68c105f5ae2915b32c5decb810b1343b8b9e5f06a9985f815af1c31d99fb56b4e7c9e15860704d6a766bc73df3db9170c818b412b8db3aa5bbf6b2b7accb39d34996a3783c8feb2cbe37c05996a82f5b542af2a88f8f65994753001adc94188c2060aa752848734d76db760e5ddc4daddd49d0deef40e70120c2fd511ecba08871d3bf9dcd4dc559ac9525978a6f87103be235e4cbfcbfdbb3143f67eec148ea6559a53d36ddad2e4bb540a1f9bca191621d8c9faadca43304bb9fdd66c7343b7fdda75362b6165e934a64918f7f5695e0e1ab3a6ee35da5e21b7548bd9efd4c0f69d2309159ef177322fb91940148fbbf57d279c094b5c60bf3b9716a4ad25dfdf9ad4ec561c2f3e05b3b2356ca66600c18a036bd37eabd7524a65b11e436d8939bab4e31d18bac238a1868ae898a433acfd0bf18e271111950d80d04440d8827589fa8d1e64cda6ae2213ed4f4cf61391afb5d9858e93dc620f56427cc8354029ccf724b6a82da39ca4c73216ef7f1ba4381cb44593cf06f0d01c4dfe710c83a7ccdbc40c0ec5af17ee87b241b2532c9f45c1616262bad1ccf04f6faf57a2c22875000a2ad42103d01503d7a146e76365d84c55ed005ed6899920a26693416eddc25a94e5ca41d5848dd410666fbb9165aab829edcd73c7b607927ea5e622e30df80747fa84db3cde4ad99f734778c64c8492057ede6a15a9a980072c39f2ee8cc283098273df8d58ef4ede9a53d8f87fcdcd926df3a1a61084c0654ff6f2537d2dac2fe6476da0da18826eb117cef25644c7bee0c9af73a628b9d832d3a19ad668130eaae3435a0def4eefc23c91e3a57c843bfd5fdaf0e4fb316e0b7d937aba028d8204a3b8fa69ef07d2c7493c7df90362246a7de3ff34f151b0eb3da7ab8c0ca235e18fb0b7a33595d046ed7c6df6eb4db60410b07d15a5049f6490c61f1281313ec85487c36ab57baf5a3071c49441764547fc0ef584fd34295959ef3936cf76e23069f6dc7d0cd965dc7f6964694b43ab146bea8338ca1dc54beb50e9dfc9db88e4f69e55edfdd00014f9c001d3e4450d3948a0eaf48e76f071078b0caaed982ee5a5de8123a6a4ab37bbb18a4cefb53bd8565f78b278f8a96cab0a5fd951cfcfbaef184211c537b94707df5acc5496718f64b6c3d3ca79ece764cc5a1cad8a9024521a1ced9d663817c8b4d19b56fc0a6ad073969de0cc04d988162f196b5f32af6c33fc45d2f2a9342e476791f4a32b008f6c222949b812c67593a0409f43b79813e8114479b4db6ddb5336b18e1a17c119efc9308d918f166cd63a266e07128a0fe93b104c5fb5d63316ea30c5aa9d1ef59d8ab9712e800399d3f7d6516473d2dd1480a2622136b05702c34e09d917969432b2f9cb973148ec9d8bc85c925738b8874eda78fb79b1b2b792c5f67a7b22eeb5f131ca009b40c4da14959b86f56d8c6eab1a09e03ebedc504b98eb04ecd543f75ae8a2ef8c28f530093bd87113101fde91041f868b4de47fca2eee9fffe72be575eafc7f44a75805ba547476cc8c19b7e544f434b114e9717e0160f23b4dc0e863c555441431c624c5423f6883df882c69b4475a078918bd44aa38dea828b2ff72f260b935266393150d3d3c9974e9e802d0511e1ddcfe92c1f1021c922c04a1aa2583db8a7c7a6ad02bec021349c1134ef0fbb5394f1bfbe9118b61691ccb30ec2155f8effaebf6b48c4e9000762370314b345ca8a9436ce316a54f812a3f91650d02dd653a29fadd808d95e4de5cc9e69458bb039b5e1a94b34b8a9d259bb1dbd2a3927d197683d8bf757dc1e7688f5c5b1fc558a7659706d7a24d77cbd574da91cecce64c746869f69d9a66d5fdf2b15e855cd7a7bae91d1141450942dd95755b117ed2429f803a0d1df74c4db7195a281f8af494df54d870c0e4eb292683db199a3d91fd63ec991d3091293318d00b0ef32f05a642a54f5caeaf285f7fad9d26140c0ea93bf04724f25b6be1a6c523251955a171b2e23174715ec13560456fe9b7cb1d2f2f3b7ec5446a44c94bb77d352061bb6070a0dc665bee2834820d3f16019f8f5077fa1500f728d3a7ee3d83acf72dea2cd514fdb83fc172854f9a698f7e7e9e60181376c1e347dc462e5384907eb91ba6d87bb000e66d70bf620133d6f16ba5470ccfbc781c81da545abbb6c6320236aec8b80be2f505593aedcd1d9247143fb8db77b60cac656619c0a71e049f763c3ccd6da158c2df003142bd8ef9bb98ef578b44a4951797f0f393093af0dd7a57a7dca720d57ed64a39b1a28cb6fea251c702bfafb7ea9920d70004e59cb35c39c99993dc72e428c71c72cd35979c72c82db7b972993b871ce5ca5daeb98cdce3a46e2b04f239f95e1c8ba4b286737b881fa18b0c6b3508dbf59419f9a055c52b136f57f0416e6feb3d7eba6886a0b797c477a08a32d5a3612cdb25371d54701922c9178681e09a9e71f3f04fd777f17fd03ea2e445950abe090c7d34b364cf36fee1212e8f3f53562cffa888ece9324ffc23c2dda4448ac88688e4f1f8af1931c6bf8f5141785a285e1b1f67f20d11dca579f58df4533a26776c6e8d8eb34e99d8e915e49b651dc160b451996dfc7c1360a6d11c97b899a1b0c8f024e4786d7637f203c1335e4f60dbf54eae3a4a6536589b41de7715a8d235d8e67006b968ce6eb1e95eff5bca6c2b70abebf0a4cb3b8807b54a194db1b795770058086de1217a719d0876cc524278fb9ead93380e306c24aa833035ff28b6e7a5917e18e71a836719cd85e2f8324a3c72343c228677b14c02f797a86b1c245d1c1f46c0318c3bec989a631a6658c0a00eb558d2be0ed6451104e53677f6cdb84a335a315e811013086409f6c3e253121d939da827f0b5349638da28cf5f7bd7a30748ba982d85eac5245ce0aead2b9790bc442a62d5aeba854526177db1057ec8e39fedfa653dc15fa99af96679d2c53a025a8f1b21b998dbdc54b0824e69f79de5baca33c7dcb1254cfae608d8b7e7ad02c3d3537cf4ffaf2e0c8a7f0e6ee6519ed64c437bd828b6f6a9629b17924c2367e87cd02fca5dd5c70a56e473bee0cdfd3dc1aa37497c194922c33e2d0592067ee3ceba1d566892a3da0f803d108d714196916904fe1c0415ee0fea3046ae440909b964ce087073b770240dcf9fc88d91e75bfbc11950081087847c8d7db8d00e24fb69d42fe7f404823e524ec2c0d4eed31b6b11f368d9fa18db72d726409fcbc1346446ff8cd2d6b391703613a76fba2d3003f7999ade612b93662320a37f03e91b3efbda887999db4f987feec8c91456148fd494a14bcbae3a9f5eb0ba8c170063a46a451b91243d50bcca94052e8538d68ada0076f34bb9d1716cbb21adb138141cdf1d78e5ad3a768cfcaf3cc93d7fa9214f3f711c2b8ee29e961431e6ae56f011f37141a26e9384220673cb7b7022e18959c306d95d388d5c550591dcb2c0da0f6475802beac75bfae9ce4fb546e79d5e1a3880effa60da401569913c1d0793953e89d110793a3719f46365852d7483d9130417c04214790d20b7adb8cb1f54334c78162ec1ff57558484cc660ce87648248258bf316c4c29567cc5f01fd7a67595be48a4731b0907a70265a7b1b497597ca6356dcf3fde97c7ee133dc399f7ca2b28a89b149f0c9c9176349de25e7b703cd613fb433c2b3f97db0be812e8cbcc6cc5818ba64a8107280369f00090562e9d2bfd27061ab119cd7fe071e742d14c195188506cc7a6a81126d558959339d80860920094bdc0b10e987a1e23024868b7664b7d88c6f4391e4379ffa049772220eac58944f074caaf541352d0132da42afed1243f9387b6a48658340a129ed94ce89c6dea733d091ec39f920166ba2659c3e21875c55066d290123e890995d97e1495dc0b45f09a4212940fd9e92e6812d5a2d9c6441e643a040d6aec295dff5b5befecaef87f9b5b6707f1ff279ea942f22b85329e85ce519ac2a1fe8e43f014ede8311ff414111e64fe4e57c4b89b619f86a3d29883c381979103e18ab019acf4953128040f8f21a709f0fa99249285b43f772726a042c20e1952a7cbe5d1c856eac21af52c6f7574de52056c34b0b10e9e05cf23715a1852453e9304c7a91064f7740b8db67f7c5ad92df3cbb456f0e916d3d0e8eae0bff55091ddc3f91da9438dd1ef210f22390dc645b61f7d440ef272c0e45fc05e08e733ba28e903087b1f327d564b1cf9433ecba3ee9a50c52a3f8623731cbdce27696268b8d292b6becfb137752dba74cd8c4ea56c4e23960c8465d6db44cc2e0ecb265c477eceea8fae4262bc747ee9da6da30b0e6502d06ca34c3206d7363d1af788e577bca66d641c9100759183c09387d7f5c22fb59f9bbd1e519295b35d8ea594d12e1dba705402301acbbadc70598feb671cc1101c49cc389ee3725c31e35886e28724af055061958684f33d24b289f413df1ef1f0a09c4076cae197007f202bc89f62891f8f44bb1863a7a12acf7b77387b9d2d056b26ebe8426bd6bf4f44b5c3cec60d33e04cea96bd171e7ad74777665d6d668c7d599ba2bd81abae0ff9442c3d6218a85b8af7c4d0748d19ea6caa046362e8dc7eaff204bd1abfef09593abe189dfb20f541fcf7d0de5ca580a787a2cd22c5914f20b500073cd9e11719a93a67542cadec78440698faf45395bcb29db55c4e249523eda41c064fc2bddb6757c110d21b07d741f815d594cd518519e96809a6d7bc91f705127cb8c2b28030a33b885bee53c7ca392afc8355101c06719bd9cb8d2c9651d6a8ae17f805ba2f237a0fe949cf6c607475ace98f6ec8d3b7ae2f62c0e7facf58e98c04fdc26e628bb173461b3fe076aa8045fa399469e58a58c64068fede83f78ec8fb0c74b273142bf7a76bde0e7814fe27314f462ec10652bbc7933c32b6999f7d2a33fbe4304927782ea5bb24d07e2ec8f3b9abf859467965780646770d0ec9ace85ea99fa1ddb24c041b5f4883f2139da64725d1c6f8ae7c51f02e88c3f1759939238a522dcae027dca24ba93d37252b9903d6a00d2027dc79fd2f88abc122889cabe5977c216a46fc8e25865a0100f6b1f2602c276820adb1cb308add9b5757fb81d947b10133bd9cb6e6b226e89057a313fea0a127749de0d656d03c8020881c63fbe32a246e219ec33d54ff079de1047aaf3955caab63aa0c6585b41c635e3c56305784854e8bac5099ac8d3ed6daa72e524c3c866697d660edb599dd14aaef953579b89c2690ef1eca4ebcc13c1ae0adf53d841d62411fd99e22af4772e7b62ab52a5d076b07af56f4c448863a718011b03512e39b0a45409af4910be6d58dbe2c35e5790211a009d01fdd337b875ab8f53ae04bc0041cf1b14ad63447020abe0e821e2cc196f0f0fa1c6696cf45369465470170d51bfe6321a408e4536f67bdfbb01625da693113c60b653d05d4fa153557cff8f6dcea67ac3a3cf02ff971a7a7e4a701dafc2912e6ee5b2d5bf5a1a78ae003747f7cd46849fd63196e3e10adbfec0fc1178f46e248eb05d236af837dff050ccfea0c2d7b01b2a3d3601f45b829a3f03862859fe832c0903d588cf2bebcf42414611c798e4e0a139986a12529df4d94bd780babf0bdeba3848848375c00f1e6f9d4d860eb9fe463208c89c0fdb3000118afee5403ccd040825818c82b318ad93d8ebf95f7a50a9345f94486fbbfde9e9ca8e5bea5176ea7f65012542e97dc6744b4e3b6b489736d8bc735796abb51b28ba05517d56c3f0544242448512b8c1c79ee5d0ad778c4b6a25504dc9c8da262774087b011f79d5b5ee6a5210fb5a98a8bc4ef30a8563473ead4d6ea8e05dd7ac864ea7502b93891bf49053fe62e7f6a03ea216df31019c4cb749ede0ce948a6947ca1f99d4f1243a435baa66d5473e82732a8233d571254f76930be8813bc7af59e6c3df7855779ed9929fd89b97ea8f23a7c06ed622cf9c1f1874754c35e4ec05e1461cb59e63c8e019338c8084efa0cf8465223f5aed8b9b8035e6141a6c105f28bcbe5008c0f8045d6c44095f0530e0817f39d174b11c789a4dd920423211a014cec385720ad8cac16f41274d1582a6c7adbce705461a80e9bd50e6a8677b96789e623d380a74b31189ea882dbd856208c247c6936242b9daa06705b60e5bd432958752dc95dff3ae6850f8d8a2f47b32783d379c203733cbbf2a2f50f18569e440f9d7f7fdab5b61e26ef38e30bb746d1f040742f1d338ce97773361412a8824741c846090b598f63fff6cbf2ba17f9cec412b16aaeb4cd69cb0af75c1df0771655af763046c5f0fd685cbb1d61885d1cf1618fb23e12f6fca8bbd869602c85dddd5754537001ae68e357e9016869212c957b2c0b3dfdc1323caf7ef12b249bebcbc4c782d6a926e79f25016dabbeba0d2d58f15b2fd9b8c6133050fca32d7849d3a182e232aa8c3cbc4608ed5adc964c5b1a8d658b61c3a7f793e212b288951ccdd6e1e8f97b8d9570c9d67f90701d6e412fe11bd74b48e638058f0ad50da5a110f52b7748ee53814fa3837d07ed1084b9d632fcacafd45ad918726acc1f5714f453e43ca31516e6f8b2620091296782c99ea640517d258c223107897322ea8deb08816da020b28226a9f0d0e43cf53be3024cb49e8913e40ca9ca6221b42fcbab1c92da2156db2aaed0ff8e1cca8dd01b43bf730fca901b385140b0ae349b44ee211ddd9a70a406f5bebc6cc3c423cdd660ec57943f4d5a0150b10d64ea20daae37996c9328805558388e55ad9e2cd35134e1af4cacd7f0794300452a0ff8f44d3c577cde4077ea1b882422e87404c531a92c76e339b7c5abe08d9360c3ea9eed506977b741058a2b14879ac378419a1eb5408091809593538a24aa05efe1214b76c05765269a230121945ca32482e039b470e85c7fbcb7df34e9fb35f69b616eca33345c828a7d34a028a873d6fa7530b43f4aa79a3533cb90e77aab16250eae0738ebe34cae8fd100a42de94ab1739829ed9a46d023d9d0bd4165d4f33c6474a09b7520e99082245f21d1f710b38f04244315f2bab8a4e15cb6210ac06ec602914a0d6d5e0ba2f8edc38cbf9997287e54decc0cd0604a1e093ddbdfd26c62e4ec8795dc7f60d1ad0f7e9ffa5ea41faba2729a14005e28841b9739791ac209e4ec71566dd1f07fb0be2d316f73bde686ae0fd92e7bcf24d58cab6a709627429d543c8c6aff84228084ec31bf08e0223ec32f9377f11e7b7b167f2a56765fbe8fd6347baea281303e1009942fc2dc09e7206d8bd237044ee59914aacd336cc82c74ac9ec02626c42466219c449fe4cbeed38600a684e2e6775b15e6167202ceb9c0cd5a2c883b787d66f6a6737f490c241e28de96d0c0b9ab8c13af86d43016cc184da85d83d2426a5ef2b1b3ea8edd5d1c5dbd2bb93a879f144f43bf0d5fc111bc6bdf94bd9e184e78171b408ee44c14e0523c65a97c517e1416f3781cacf5d4708e842120bc17a26104fca71ab3b24d291648384fed758c515d171c77cc3e82a2b1db0a51149b6e75f20134549df564cb3e7d416ee5ca29feecc931f125b88e674862094767430f8d5666368dcc56a0c0b7cc4ef0ed1be2c825757501f64677ebbaec3c05f6a20a597f1ccb6369eb8dfa91a4ffe2b5253ce338448d37a7db26b22da46ee05db8b60014464d57ddb9fd9ee9b5a224f58a5e949b2c9e7738e5a980d4c12bc2338d28659c0c538862e2b5887cbddf92ba6a2d3d12c8b81850ff688b3a1801a8d5a078252d900a1621e53d10d8018199ff2085cc628a5b8e939dc4c8f273039ffe185b0c2b17fdebd84f665a065250f50f3b557393f6b6c4ae4291b52c4f6467442406004c9bc0873f8d791dfa8595ab28b3a3818eb72dab043c19518c5926f7bc292d5a7f9996eb85e6101d9d0e2816301b241d507e9675ac6d79c3c840740db14cd765a0ce49234cecb7d8c2130702cdb32cdd66a84a132a158e010e2e5a8cd988e8a492d83fe07b338cbc98d09798a426a0227c2e26f64b8bf4b6313e6c55d8151098b3e027665a47c52a9016df778ed77388b48130abbb6aca9752f65c785374adbd498cf54ff0d7df0ee92c78e59f2a9c92234553aca7f5ae779f3fc70d2669b0fae6089d5579b02ab8258f6de46f3028e4f6ea51b3ac10a3503d3f6a02ea8364f74133feb8da20a5faa2e6601ef328bf8992e38299899a4ffc280d23b7ab49e4682473a3224bb96a4998b3bda69c191c19d771768f9b8e287003fdee3d1231724e429a32b7c2447f3648eb047d3c43cdf90b24db32a40be7df674d1768bff452a7361388d11f36dfed673c014b81b94940b60f6725e170bd87d363c4cd9e01ef4452c81a0f823d7b4488abd4f2b75d8ec8b202eb213388a1c0980a532762817b362e5a8205ba995e5bafa5aa9a1b492a3a99202886a49c6e6274b891f48254d261f3ab5ceea8c3906181c9dc3650f2a35ff2259e11c5e69464c084eb7530b01d2d53758145d22c88d797363ae41328d1661d567553b816c6bd3134cfd8e3985733a277122ef4d89f6edfc9dfd7abdddca955167e95aaf7e4f5d9b9a0fadb4aee3dc26d193a45c918f6cc494a99dd0b26f456de1cfdc2173f368bb6f9c58d214684ea965442d4f1e9341b57f1e4b6130cafddf3ab475ef505bd98bb16040236659817df4024788012b874f8ddcb7d0608fe420f704444efaaf947b4783dc11d16a8f4c2a478e3e4422aaf9ef4955f9ba14ea5caf6da3fdd0171e5b13c7d526db1202fad27df472e721dda82cbac2c31a8d2df7def2357212e16b4454096c995cc824e07b6090f8471d8586f51644e4520b704bcf5a24ed501dd1f0a9295c0085ec3e0a853d514d4cba526e0e86dd694e8718d7ef7110241e417b65ec0b1ab548075580bfaa00e0251bc2d02b6132c8f2ed624834cd9b3bd9c6202ed4227f7a8645a4ca8a2421be3794fbef6c9dea434725c062c4636c34dc2a07436548d492890b581a1e0024f8283271302a61c4914c8f6f40fd505db10f2255bc28f9ed346e6f3c41192171d2f4eb746c70a2555866f7c042588f5e4e56223eb9e455b750d4d0b0e0085e16ebc725067a075d8dacff99baf2ee03be2ac4fafdfc22103bae28cd996af8cf993725ce158868a0415998609bd5940bfb274d0a1f018c9e704d7f2e7257e6b8f93a1db21b838ce473763c3893dcccf03f0d074ae5a3c11d457bb1827851c960321cb1e56ed97f3c61cc86d8ea77aef898349a3cd7b38e7caff9a1dc079e3c7742161fb21c6b58f05724511a660196ec1303614ca73ef70536779671d43567b4cc7ff311e06199ef6d3035aaed34ad3fb546e944047060054866f4358edd42d83015fc3c11c0649e58fa699cc2b34209dd388c60bea1d9af1e7b864c520df8c8fdad6d5b774c3ee12e62bbf4ec938e106f8efa123643e50d9cde3947f7072402f879eb0ba6a09530c07f45cce849a92307df82268ba394725f035b285987c513af0d06ed320593d9a661b36c56ec4de7a37a709d04ffb09d8bb9fcef32f9835ecf5905d6372c42c427d23b4589f28f5fa9efab39f372e57b2f785a6c14626fea84551b783e43faa6dec034cd5d2c5ef3948cb6b191b726e42ffc8a66691f579c30eedd7c8ee7791963aeaba0293e8fa18d2ed90429f2c6bec9695909029f2f4772075f49204042d032a6c1a7b5c40d0aa4a07ba2cc969e07fbd42e86023ba3c1a017f1d1ecce3dd34fa3e51f48b258675d819735b064ccbb31f469c5aba11633c9629dc03d25f56060d7c2743535fa1a954224c50b7b997dc65563cde4ebe2464efbdb7dc52ca94920c8607a807b007b10905204daacfb22c7bff18cadfeae79d404fc099af53b11b40b01b9d827f1e057580384bbe6cad7ab59236085b41e839e8edd836ed29c8435fa3af3d0fe6e960eff1d8b833818418566ef9dcdc3da0d3a9cf553eebfc6cfed867cf83529eec31fbd52f8658953f60946a4324f6b2c57190d37834cb344dd39ee763483fd5977d37d8ebc0be857d0df6f2abf95a2dce0a3b1f939fbdcb5ff3e867de8e4cbea6b9475fe33e7b1edb6b208ff6db6720cf904b033dfa5efd6e7b1e8fbef6a7e7917d07f2749ffd09e41972759f3dcfe935ee6358b1d3f6619f7dd86b4ba72f865f0cb32fb69c85b1110e6a0975d32bb638232357fdb1e7e18f8118c833c483bd6b9f69607456a7639d256bafa41482bdbf90fa0e7ab341ecfd5dd8fc1dd05577faebf7488fbe0db1cfa3f2a3fff0d12bb9149b8ca0df7448955fa55a58fbaad50aab6d1f430c7465bfd37d067a953b4f47fb785ddd73e7edc85e7b57f65af618e8d2be0377fc35aa8519a594ca18c619eaed38d8e24c0ec76cbcf6fe3c3657ffd664bbe73a4ee79d8571611de4199acf03f2f46fcffedabb1cf4e477137435e8c9eff77674efef51d0e59e8bfb7e0eacce5ab29897fdeba89c857d74560a407a857d9786651f0f22da6427d4ed51505d0cf5a88f6bd6fcedcba207f3b16f8b38e66f92b92bac7d395116f4ea9fbe27ec615f82a777a1fe04ee0cd5df918ffa0abaacbffd9e70e33abb6918b6d9ac0495d77dbd1dc67d1af03a0ccac7886353fdb815fb1bc7beeeb5cf04ccab5fbdfaf16e5e8df7c7f702c55a0dac5307f5d9875dd4a340afbef576a0de3e0fd45b9067c8757afb3c2c8f7a1ef6539f02794e6f4f9f67c203f8d6272186a78fe1e9abdf7c962fa2defe4d63f6f3ea5bd4e75550a73a6bfe8b12d6a5c1b129eb3ac4fc193b04989f163e940ff421cccf346b7e9cbfea10fc2733a012d96c9b2a2d5a3e99e5e79c31ffb29d8efbd814260877c2fce4994a812d674d1dce9a0ff3d5386b3ecba7e3acf9f24b45615f71a9d5f2f37f388dcbcf07e234fe73befca4e06b754fde8ed4cb77a5e8efb0bc833bfe2cbf551b6d44889782af125417fb6cd62144e06eba63e82c2f3f9e21fa3cf2532f53ef929f7a0abafc599e3b4ffbeeb9b79d8303dbc703f3f2fde3f157bd675906be4af8f1621262f8d39f3d7f1cd8f8c6dbe9fcb068f6fc458cc7ebfee5c73ccc37e4f20e7471a04b057a1ab8437ecc7b14e4213fc6e3e10ff3fe301f633efa30947eb6fd4b451f40f94a09aa8b81b657934eb750ec0f1fb4e5fbe1acf92edf4c7dd159f60b3a7d2f5f0c5dbe18b67c314c7d3164f962d8e3133b1c1d1f2f4ab6a65773fe2b2ef5c799b9f564cd39b1d5675165f18235e2b8c2f20c69cf231ff53cfea76f6f877cd4bb24e84dd46ba0cb416fbebfb703f5f2bd0aba502f3dd7e9fdf41beafb7163c4513f2caccf3df795a0bada639f977dbd199df132f0ef2ade1728d6f68afe4906db7a41d395a17f2e4d3686d873a783819ece7ccfe550bca8e18a087c97604f77a47cec0f9d686324da80402359461577643f2da91f3b1e1d5670d5fa6e9c25bfd413fb8a492e1d192e0ceb2f5f3eaa89dba744ec637d1ecc5f419e21174f54bdca8b5fbf27f4ffe1345e04bd1d0cee0c45d0c55fc19decb9fe0e7f835efc18f6f784f18bdf4b18f66f4412da811969a4a08aa02a42ff1e4ed3e3b3830e3668c10f462431257421327431841244484e20117ab082262b9081143ed0c048e8c54781af37df55fff20cc9e7e9afcf33444117f6fc3cf5fbb3cf8ba037c11dfdf55dfd1574f163cf83812d67294d24454546391015e5404454545464e4dc422c2db43da3a666e51ea5d8574d52e7905fa3a4a454635453b3f492821f7e60c2618a29b42a9b0f17bd6091585a96a83116b1afa94252b934f29a476ebf56250949ab928484b4f99ca83042465252914c52a54a122bc1590505289873feccf933e79c736ede08f34e971d4e279bb88977681b381b8ecb492986d57a822c3b81d6044763b26d1cd771cc6c238e933c55c9ccdd0f1fa978ce544b9d621d7ccd1f5c8a5e3a9c2d360c0cc3cc9397432d70371797970ad3e130c730730de61a4c315858d68c7a9523c49463caa864646462605e64645c5a64646452322c5646468600a718717004b42b5f3df357777e2fbe7204ed6204b84d4df3ebe6a4df3747a8a957f1323533317d41a58a947352c911b2e25c8e5095dad434f18b2f9898a6f42ae6087dd1ab78997a156f4c0c34242d8909cb8486a42169481a9296c484030e68cc394f30e709e69c734e25a5251f94947c50525252528a4b4c45454647888a8e1011151515193161424424c4844848880913264468cc2a3e52aa7c73973d9cc6dd2bcb13fb8a4a4d543a870ea7a9effe37fed9579de5ac59a547951ecd721f0e0b25a525a12425a1a4242525a52534a4949205d3c8565b2b1a2fa072c4112e20230631401ac3082358888afe2f002a6b8958d9a9e0625560e5f3fbe7083db95e3421b99e58834b412f878239424f72849e7801257247e9ec4bc11ca12739424d748e17771781cf116ae2e60841e955bcee39424abd8a374768a957f14a2e4708ca93a6b1374728e9e6083571bbcb116a22b2e40821d91ca1a41ca1267a15a93c262465c4b039e724c2f6c789611856b139a7ac11f349a577b608896d6a44916ca548b6d65d77f29b9a9a9ada71f23b8a6a0eea780483016e8b1519c0300061a055ff0c826106c9a0fe4a81004db09b1808d5e1d4477522f4f5b7f15594ffc22e0701610fba624140f8e8769011cc2d4667766a2922d3541d82f6b35677f7ffe1967bdbc077967ff6ad6e3e1d4f4de12fc3856199dbd390d246a336129362183f3775d94a0bd583286ea422c4640749d258e1324ff1c02822c52a3e442f66bacc4d3be8e16e4a57cac00a94dae154e9c44a0c75763854d25cd9391a70e75728ee4483866be5bba442e9be6c50715f33d7efebc6f51c20dc1708b7da2a3e5c7f951942aeff9b91c5f55f9de182ebdff233a828638beb6d8ddc8d3334ac516daa233002bcf26b91329278573ef682192c4984d3c10a07b84e744084232d0c9669dcc7c7c7c748c8b95c3973e3ca0f408847b18924ee2b3eb9f286e41f2ef2f1c54aaee4264bdc17ff702517d194c4952fbf5ad5af5a4b5cf935373a74c6a8e2caefe163c895ff438c19aefc14c438814f0e8e00255df93cc614573ac9c11054467065744285e94a325a70e54b23252f588b44130bb7bfab94928731aeecae94524a690780832c3817227da00feb83a05e7e10a82e73525e19b424c125f5d4b3b1079a9d820f263f7c82dc5dd6e8d079857dc5250df858b23e73089e4f03a37f74d6ac18f651c37c6a12a5946a585757b2f2f9a73efd9fec31edd3e9215f94acaabd7b4611bab45bf397756916fdef10b2a7afa2bf6df6b32ffbad338f877c0dd4fc79b44fc22b30d34b9f558836f3919c267b1511b6053db84003e37029b87202441c34cb404f07c571dac74e47033d9d4d6bd0dba16919f71907c6e7893e46c77d5a72faee7870780299ab424c6ca793b111f641b2bf727a3a813519cbf7c359f4ed77d3034887a29faac2d21f025cfa917e3f67a0b723dbb6f7df400ffba7a05733d0c34ed8778f71ff18652067d13f6dda47d9c759f4a6c6a78600d1660a653ddeda119452fa4f31ad6e1ba594525a29109068138b52a094e3688d8e0f8aa568601985ce419f3e9048ff55e94b4ae9c7449bf9f461a28d7c3242f09fb9d246b3e4af3a847e295f35414f8766d9c77e20d10628a3fd8e494d035bced2917d3a3e9c251fa392498a169026cb2d93b60af484f27d769c2ef333835cb4c1e54f6161b5e7f7e1409c663e7fe52a0cb4056069873f620c94e3b5e2770047a355e5130e367a3ada7b3cb2973919d91893967a6800c84e1197573f979ba45c715f11cae5a42c94b8afc8848326ee2b52f18eabcef1e26e748e3ee372f7ed17a16f77dddfb4eb38ab574e7fd6c77e62478118ca1b1a57eaacd9e3a3e32c6e81abf8afd565adc73bfb62ce674a250666b5e7e45823f89a327af4e8fea0dd625cc917c005ae3fd769ad956e9f7dae04fd6e54a294cdde12225d40ba2f950e6020715f31492503308a48d271f5c0009b715f354c2449c20b2f6a60811760843d26780106411ce182234ba0808a12305e70fb2b18395cec46276014a91f675c4a8f5fbc148ae59f37fce4c89123f89a48e2bf5897dddbbd3b4636c19472caaff386c86a96ccd288d3545bb95f7f75d83666e91307f7c5bafc2fd66d28f6358ddc1be234126de6ab58c04386e47676dd049652ca2985d86c8caf8af1e3dd6ca4e1400c4fe490032dac40894188011c78c1a40b1d9a489112ca7881031a6ec0c211263108ed4fd1124a402c7812c216b7c865df0b85699b524a654b4b29a554db368dfa96bd5a2110495608430c25294c9c71c4862f8894e1040f2e6c4fecdf578b8601618ca0873274e0e20a1161152888c24042050e49440925d20a946051c31838a0b182507e8dd3dc90a10411529004a50086507ee5fa74847da9aeacd5dad8ef5f4dab57523e4c12abf2c1be569a7c1b0ebee66fef5cfd9edaac3f59d328f6d9c7dbf3bd6e6ec1c8c7c74785305e1d0c14e9a0a39f18dc17c7356db1748f7e9adcdb3ebf1c1334e590ff35ae7c1b2b9e734eee2250e3722a1bdf2b89c29c9fd7a008d5ffe74badbbb65098d708fc56945102f1ce2089dd14215e7e1426f679fc51f53e2722f690288dcf200f7fe4894f63d840405260ec237d1ef1697d7e0af20cb97862aba6d56a6e89979cc6932d416f4794a08b9f823bf599fe0e7f043dd913ca4ff52f611871527b9f3c197ff20cb9e263cf333441177d7e1eece3d7cf93a0e7e00eece3f3c0401ef4993e0f057538abe30b398d0991d51fcda82a14014955b1afd8e463490f1513963fd6274b971af5b801e1d2d7e134fe9c16169394bea450ac5cc144669d6efcc8342a66d19b8af9186ea08bfb1d18968f61c70ec7d3493d0cf71be84a3d0cb8e39faa57fb188bd1c1b5b6e6b0cf0eb9dc793b4e2757f75e4dbd8bfb94850177509ffa9eee704c1801e6b1af87dcd8e1c0fc4d6b3058d574380ee419aacf239f4b81379d4a69a0b723e653cf23e65320cf902bf530cfd3f231cf03e65ffe05e4493d8c36e46ea9cf3bc1041262f8f227e068aff3f29e4e4bcb7b3c529ffaece5bb7116cd621ec6c3dee563d8f27918e8ed68f997e7917a1790c7e553ff02f20cb95c3ef53c2fdff2318489717949b584305f0cbf621f76593e1d1f8a76df8db3e8aba211c78531acceaa57877e0ffa37f475d08fdd0e14d743bbe341fe166303803e7410805aa1ffab254708feafeec625bda94ce02bcf1b1b59529f7e3f806ae89f7d3f2dd4840e02d5b0823d9c25fb6f1a0848510a4e533968c532cbc0d54d4b87b6b2c2be0253bc60c587702708770483d07f27888d1d42f9411a6887f0e53d17ccbbbc0bb80303ee3c10fe020ed997eff23de1bb7c2d5f2f09b12f8bea5850a7d99225d2b46599fd1f69fc634b89342cfa143c7229cdc1f55cfe2ddf02eef412b8c34b4da408853b41381ae810bafc4e90982b66c045d8f23da1fc3c97dc692667d197e0cecf20dc09b20a5dc06eea05d0df091291085bc021fbfe3d6127c4beb8e86dd077a966e1507301f4798858146de6d32ce8a640ca818d834b3da81ba2c2eeebef0e1b1d518652b81344bb8245e81fa4a39812ca1d000c717088253864e3a3664f14ea347bc338dee127867cf142b81384038389b0e583f49122a1bffc76009043b81364266c018760926c907844e8e090ed74e03fbda20ee43e423cc8697ac959f4ab07cd10fdfa0d97f6120b886ad0c7fa91f6202fe2465894a0c0976df2c304ba6ff0857aaf3fded37b0d9af01cc88117ea5952df5fea9b41d2cf7d2f1f97e5b9c3610139ecb9af979cc667882cfa373021b9943a0f552e0d8a38e88b14db4df4bb0afd5e6a26af72bda2d4e93b7da7efdd7b23580e9cde7eec1ef56dbf66ea15b51e44dfe93b7da78ffa4e9f2bf1269f13f58abe33e915fdedf32211077dedf323bd12f212441cf49d04d1038af5945ed166eaa55e753ab0fcaf5e4a1175ad5a9af5e96f91c6fa6b5258e7a68b14b63e08bd9aa827bd9a5f514ca8a5d69d1f4a0995346702980446000a294423d51248d85cc151ee8c37b8f327eaabde45407b07eddbb0e1b1fb6dfb6c749fcbf671fb9b46a92acb1759a8cfa557139c3fbb08d0afa08d5e6d1f79669891cd320e477efde607f8f45bec2af8f271ebfbf77ac6e94edbd6f9b85bad8f6959e6ffbd9af2562eda7c1071cc9fdf459a0544d67c1b36ba7a5feeab5e0c6cf58aa2a67861514ca8a55ef5bf504b4d9b17be753f3663addd8549e7c09e877cef78f833d2471bfef95fb4e91dee097d5f8c74e79fd0f7f53c8388633e23451cf3a9bc4cb15d85c16e62a4f918c8d58c2547c888ca9e84b88f07d9eec7bae422b1069f3c43f460be8b1436932e5258cd450adb1c7d553ed2d126de89528a36d1a88856fda0a41e3537d1ae1ebd9a3a7a05019f19c83eef7f6a817d4524ff80a4d055e9b6ec7f740e2f1259ba2f27b274a50ea7e170bece7c1f9d0303b19faf81f927a21358c155f67cb58fcbbe5aeb84a288242e64e1830e4ca284b3870562e8d0441733acc08924e17c9ecf53820c83c4be56403e44ec8b7de64a1ae1a01517390a9a989498f47fef783c9dc2be541cc4469c821cc4416cb5e6843c7fd4dbef3e7ed5f1fc4f8f7acfc11d1d9eb88749b22fee74e0f3063c0959f2e84b2c9fca59f3ed87faaab37ea28d94776a5f85cc11dca944913b7f93df471c5f64cd9f2d257674c864d6d48070d3cde73e6672d67c1ac5ca672ede328936d128dab41977822fcb62dcf9aa6c83eb83f54cb26d282b843d8109b8185542d81d960861bb1f17ee46174417c4d3e0dff765b3dbdd8fe5af2e5258edbe2c1208ad0f56377e4665c3ba7850916ecdd58d9f51d9787510176d7eb04ad1a68188343fbc678834d6cbb81f4423ea0d16496c1eae4ec4b1232e9571ba140aba857db56ee4eb5fd31f905ef9047fbc5821e4df4cfc3bc8bf8df8cbaebf8406f283887d751053add6ba7791231bd44566f7a44e2c8fea2c1ed1e914d61ffb3aa88d4419a15f821df4847d75d00dea1c918528a3c1162f60e3d10a4d2e8e1b8f5400ba472b50b9afd50a5fdcfe1b1fbcb460e3110b42371eb160e4f6df687d4046935168ef3b8d043d1262e813b3580a6b164e5030e40b317808fb004d610cc196ce0aa6087bc482d18d472c105d00dc78e46383bb8a367efb59d1267eef88219d2c7038e4bf49174f50c61babbfd1a88829ce44458114ea421666d84a83290485f4c2663220c25223206c2daa622bd192cd96481b2c4542c4d21c7c892228b0f5c6231f18a6158bdd78e42364ce605339b0017501174a57aa48011430b8a2c40f578cae14dd38400704ae04ddd74ba9dc520c99942a5b184f60280a230919a6108541c40b4c61a4a0044cc2b06104378a120d42608851c39582040614125c2e80c07822863b65e90a50eb831a10e68d4ed258baaf4f394173b02c373a89c2446e11c588076151373a89422489e5764089b8b88133614f373ae1020a09b8404a43a9268da0db31373a9172451a30dcd72711b1e560743797ee6e49b1745b77f793bb77dcd6dd9a2aebee8ab9bbbbed06dd75382b2681b467774ba718055f3552ca6654adddddedd2927a3915c08c0d8579adb39c3add1f3495fe2190ee77e5acc86cb9cab05529658c3edda594324a29a5f4397baa88f00db3f2729c767a9d27376d8c314eacce29ff35a5fc40ceb982619752ce17cddcfab3d4ae98ee11a3dc73b293d3b5ac6254cbcef05931aa4921ba132acb88c6a0534e4967864500fbfaa86e040f5c9b63270d12c2da0e67be65613a5f8e7d75c726e5585858527e535353a3492158583a1cfa2cb5454ed7328c562d3b836218d5aa103e319a49215a5a3a1cff16e922a76b59c5a8969de1b362349342b8b86b990b942aabac12a3d38aac189d454ec8d8b68d9b51568ccea2cad265658cd9fdb9b22caab24a8c4e2bb2627416d1895549276665523ab12259e92caab24a8c4e2bb2627416c9961cb44b5a6b86f9e84163f48199445641a4d1be351008bb0088ab69db366e66196719c7719d648e73d41772561ce3364b2965115d9ced275396e273b73b33373373333333733333337333333733333377333333f3c6715d773aa198999b9999999b4a152a56daa7e908e9a809a4a3271cc4cc3e98b9b99999b99999999999999999999999999999999b99b9b9f93f703df8d9a44b29254729b618156e94b8372be9557c21121fe68c86a181ba6fffc05ce976a1ee2332beb8605f5cc48d1fb3827dd5ab5ab9f00f37fe8d4c34c3b308298adced462429802e3f57b3c55782348510234d11745f758a21178c1dd8003389602c610b6251372ac1850f5154b937224541e546a428a6dcbe11290a2eae76235214555c7e8e04e696ed8f31ced960174a3675e3d10c4edcd68d03744000bcd1490d7c2a12202eb394ee24feca6fef3645033e88a8db447cf2725f71ca7dc52f1010ad5cff79e255dc1717e1232777e1e8051caebf55e970fdff852ad77f050310d7bf0574fd6b6e94aebf8e2eae1f8da08cebdfc3070ed7ff870fd78f62c8c1f54f618aebcf3e404aae1fc950e5fa511014d78f665872fd9b9da7127bb548d5d8838b27321c91b2032415a488c4808414156480c6921d3001e3d4972ab1c28f1862a4e18212eeb5290618b43022881f42b7a2c3194d23c34ae351b61a6bc2eee33ff76a452722722f721acf757aed4fa0f65a17ddfae2a55b3febacfaf493c26e967e4fe8493facfa3dae24a30cf984311ce2b791858d61f73aceaaff3b432e7fee778676865cdb6bdfe0ce90abbf03776e9c55bf5ddc37b8d372567d0e747047abbf8146ff6addfa334bc2aefe316cd0a3a08f5ed5ef9a86a820e205413e3ee10f67bd606194e44a5edf8dbcbe23797dff527841625f0c04d4afd50c7ccda5eb46b7ce265a646bd22ba736f2e393d06107559ddfe909b7fa79fd597ff63de18ed7a0b7637e7dd7acf5b3ba33c19eb047d52db112648938fc6318bffa17c625774229a5ad5ef9c4c017a59456972b2b25a518c6d1c724a56005b7a09a2669dd3e5b791c618ae06a4fad639ff504b49fd86b5f633f3f53653660cfdd04308c7ed33a8654d22d5a29b5def457f4e394180b9a68337155bffb550f1b696c4ec76d18b8b37e943b2a171fa8548e5d86ac05ce5540430d1530cd182d2a10c23d6c81440f37b8dd33aa9ad60b688e88e8e0f6d72d6ecc8d4744906ef6646b31b2fc2f976bb9dad3dc5158ce06cb2e405cdda58b70aaa82b9fbb9cc6e4095782ae829dd3d62ba594729393b3418236b87e997fd5af15fba8fc59bb62b673cc96b58340cff572b23b412f67ce3967ba9c3681af387fec5611c7114943b69f21d02bfeeed6e1805edd24859e748b907135f373ce69434e2955a0832f41d92058a90c2e5d5ef1699400f8c27a68489f52762b6db573d450c5c0d48abdb8b4a4582cead4719b96558c4ee9cd31d650c99cba245bed1c328e798dabba3114e6be5cec9b9125bb0fdc2ea75eeaeeeeeeee8e7d317477ffa8bbfb14c16ddfb9fddcb35d0bace772a5d964ed1c32377e353ed58db9f553d16e8985b92fb7d66e49ccc2f2cbcfe5b6a4eea671f263b9dbc6c9cfde8de3e487badbe974b71327bfee6e284e7edcdd2c27bfed6e2c9cfcb4bbb57035bb5bcbe6c2c90fbbdb0b273f7a37184e7ef36e31aaadc666a386277392a067dd0812a35f3499104162893dfd20ad68f285dd907819376861e78d47448a4c2888c050438c6944b744026d896b55276a0022a20621233d043149029414444390101642244866b8102661ba810c4456cc10a640e92789482854d4faa006841a62b810a1228a0d8a44a1828928520031014494a3a02843d410a3c996f1912217857ec029e24015e06e28d6dda6f49ef3035b75a7d305c8f2cb186d628c9362dd189d52ba7bcfdadd3d65c4badd7538e0230e50a5aa95bbbb62b49beba60c7365eb9ecd93a73373532796eb55f4a64e2cc8606bca29b5f0e6aaf9f7e2baacaa2aa572d5aaf98ca5060760a65711bc5a4ddd183bb2308bd1caf94b77c942e913969fb31d8e7ceb32875b9db1406ba66d9b96d18fd22865c43077777777772c933337babb3b9686e5c95f39c794d25b8aa0746213c33014e69db3b58a948b22d3b8eed471543a6ecb41eb5aadec63665966a87c1a8b7b8a73b156f32c258d522ed9ac5b86b9a4989d6f6daddfad19b8f3794a4fc2a57b628b331bf7c69d585c5e9a98a4f61fb45a3a5a3a1c9d1b13d854575363512c2f3073840c7c1fa36aaae2f383513f989864c79dba9cbf1c50d5e06ca8549cb6d5e87eac7c1969add43a9c09fe388249ca70bfd9c0963ea5d95d378208e40f67f5d76aedabc507fba37a18a5391d7472c2e7f6dc9a73ce454e2ceb5af4e3abfe46af56dc86a35373c47ed06ae5fc9ddc92c69492b91d697a38cbdd6b8fa8a4a484596be7d464e770a9f297d95212ec917538ce6484da2bd92293d26edce94883655c53c12dcb32ef72be4b4ff57df48a82b25718e855f77042b7168a4dda3e28a05a73ab8c7fa33543f3cde26f34580e70fbabe5076ac1f5195c7fae4856740acb5dc34d1809f31776c06146c9560cb1e2f6631d4ebb641b942c81f1f3968605a173f0d7748e483b1c3f1af2c2ed27aced018deb9c956d460e4de0a833d8575ddd68e10605546b7b82e8c18b2cba4863080c96f4e460c60e2b2041a38521b250a9d0e8018bac5a5675615fab90bf7524848c19a32d4574e96f51f5d909dba3506ffd9bde24cb1d09ee709d48a804cd78443d2ad1d00c000000007315003020100c8844029140240c147df60114800c76923c6c542c1989434992c33086410611040c318600030821c614d5cc2100e1c84352265e9b8f83073a081456819c86f74bcabf7fdfbaada86b393fccbccf565f19fd6a098323d92e0d8fd917b6485400c7ac3732bbb8e59c39e025ebb0b0f1207d00e22da7ee618b184eadeba8ed260cb854ad29f4f9ccacc31660949cf04b8fffd0f356171a4a29b0d99400d3c26ace569c81d7d1446db16644288a5fdab8aacb166b21925134fa109ee7cd8c688af11b1a1eab952a90eeba379da53f2dc79fbbd4f6433ac2536633a08ddde5a3cb0bab027a160219e8dea8b5ef4dfdc3156530e83441db98197114e31776beea6443ab3c8854818ae2871a2ec664ea52e3f0f3aa71293967d7efc084d3e82268266ba36c3cb73624afadfb743dc2757a5ace812ab17148958d53bfd0c6eff7ad8dcf6f6ee34c1637fee086b038a784ac7ddc72601f7e49174f1956abd7d49c03b73326a123aa8f09ea82bcecfd68a1b07bc642c331b6ce9c60cf4653611698f8675609438fb6426859c6e07191623d5d10226668296a39d9a282e96fe6aa6289c1c64816090c3f16b2ec27582010d8a004c7e0038d074a18df340c804915e8e8c318941754054a9898821f63749e82189b64c090080b3376421419637ae5a924939b32b47b25e476fd3c1d5c624c3eb1521baeac94408b5c9f6c5e99068c8fd4023df9756446266af3f036cbcffafdad02fafb5cf133bf70af7ce7e5026c7df84821e2f9ccc6bbbe7058e08519267421596ad1c67e043d7ca7a6a90ebcb3bcc26d8eb278972619e2ce2324615ef87f0ab9eb27017fc0bad85d287e8c26f9d9432e00744c8e3bd04d66ddda3015033099ddd6d10014118e8ef3aeaef36835b0c5526444495b45cd4498a32a9f1ae7bd01d8ea65c85c187cc3f22153fd21955fdf9f46dd5723c9f472b5561e011a51a2c42f1ea95ecde61317a3540b552f59f24fdc9a0c17505b3709df4d93c9a89e43f39cf96326b3c2da8678b28f456e3dd6d904ad0b43e1460f44b274b020ad9eaa4e621dc7fa998c4bc47b1d27fc3e75c15c317a4dd606c27a3b715180d5aff1ecbed6bcfa1930898013b60a1147c47f6f30a68fba87d3efe5f64dc21b13b5394af625c6af8c121c01f14f08fd98535c148631ea93c4bcb94ff8e8f70087f018a8bcba9a5d6cea1c26d3d41e5c2291e729b2f23a7a4bd585bf2df884958355dd2dd2956ee185c02cb35964a70f496970bc5578fb2747f6d2cb18b38bda0b9bbdc59c5ded08f64e93827c423704156a79b6b340a1d11ffe9c6434407f42bc4a3f759122eebcb878d4d722f5c31009cce2a82f801c6054882883f935986bfc2826a824fa589c82cc37f807064606d38ce08f0022e4d572735201959368c90fbf05490044f7154dda322a7271b7520eeabe0a2a90985619e4bda5532400776dfa646acb15773cc9590070095501afc4f9cc342b830450d0c59809411bc56cfdd71b7efbc5562f12243edcde694dbb70cc7bff815acbb4e24d74d5cddd22703dafb06dcd258f3a9fb9a9ebca5a771352c1cbcdd0520995094052bc2700034bea1f353667377c628dc02563f2fa33af95cc7e936fb93abb224eef0a6de1499f3899923429dfc8c201b800e01a04afcdbe7940f3f9f2d9650d50279424b663848601a06c9788b86a102d37092ee9e7b32e809e03c767c4ae2bf9ac0f5542eb4454501ae9c52ffe521a0b241e506a2a7bc974a723feb9ccad65dc7adb847d35a82832f42863e8750ccfc2c837127d48edc98917da32fa8ed58aaa0c14774263f6a3b3d05b8bf50b9d2d2456bb0bc97e6db056adbbebf4f485d43f307431c9bd54de8689a61c5c25a504eb25673470d563a8cab105678becaaed529fefedc600b0ee6e9664306b4aa21591c81b44a88a48b73d45a4834511e94782618c9b03370b42be41d352ba1481ce41e190a85a7836c2888f8cb956238be2c7653df2b9c0b00159a85e23435c3f0ea77ecc6d64c5f89821c04c7968cc689a01a7473b9d582974437d046d558c7e978607950a9ce81fd13fe20dccc034e54b33ffd86e14267d960f7728a6df06de816d80a80ecdd7d62f72dcb5298a3d560053384e5d4ca061f8eb01a4a2c3e529ced536011e03e6c782571e08f1a6c4e0f49ca75a7f00f5e587e7a15a1d3187d80f3fe80f01d858a6eaeb743e34c23868f7914521fad5f9bbd60e4c058426c08e489d32f0f20af0a8068a193f4cd8529fb48fbacf72d0c03a4de3aa1f912c5228122ffd248223d500d53661c42592755d83371bba5b5064c59623d2fa0466454e50162ef9cbf08539655ccce58decfbb9377b180696d5f472b6e5f99846533a474d975d80bcd002debe30e4492df00c0026785fa53c3ffd9e11bf20297c581c4df7dd0f8c6a7907628d3b7c78610c6260f88fae18c004b1a424012010c2f0ae2d8181ba55c31a343dac1ab0bc2bed5057632abdaf8bf8f97d8d27bc76d1d29559911ad09f4410f3c82c7177ff3e4781da01f64f8cb552558ca7a57f758c45a331fc34981b483b945efd590df48f4265a25260bb2d1154afd01a45026ec189810a4bd0c76e2456c8b5f7ea32a19a6bf4cc00d110627863ebf09b1ddba30815eb87743186c1d51cfe9011da3f1377edad2eceb4fe563323d8c368d2b5163d417f3b226d851e16ac49c41b8cd1cab83746acd57918c0ffb2320235b7ad3a5452f6dc5c23baa615706f326038a3b60efddb23f4d535770aa6f39ea9393f2ba4148344f6146594d1dba710f7b985b65ff62cc2e31f482c5651e5b943a745d7aac12c38fbc45e42b2e88ad841879cdd3471a3a7ce7185a396f231b1aa69128937aee480d8b3619d6da440a5799bb011e3b8e93c63bfb03c132ff37017da3c7342c8c3cd8a4ce8e987b1cf509da81b7f3760cbfc9958fc8425f5f97ac53b1fa862461cf2c90c6035dc9e7e609e6e6258f85804573ec819e0a359f290e437cd427e92829f8ab82b30e1e15aecd00e019c9205540a207c016e1c4a3728e5da5e830955256178f9b6bd726d2f50755caeea3adfc6d1413ff87f2ecd568257b17d97ffa3e5a0a05a4289553ec2d1988b2eab7d509feedabc689755cde2dce95cddb21ac3f5ef99ecb7c153e15b34de9f35e201dde09f29490d6c08a6c1ff67cab01e42ae4ef1f94821924e6c9cb826781964b757fafc9c4ed38ed079ac9424e3181f131d905aa1bc991f0b8badf2e00df47f909a1be8b96016bf08c68eb7e7347594dfcabdfceb80d0ef85c760120668c41a7f4736bf2784fb950e41829c9cdb5540f24c9b18978f4e6417fc7099deef275a5a40e53e657de03c05138ccdbe7cbacf7b1ab47030640b6bd14f39b9639fad4458c02b702d4df29237a8a1cda22c0e5defcf7b5a23fd44252efb0e9477345fb6f88e4595a1fd0df0ad6870be7f534b47bf0be6de27068e75bc81eb554a60aaa45c5ad1eb321aa09b6935df356d47ae290ce624050ed4f75374b2c00eed1105aafcde5d85c4335253dc6a329f8739d7481811cc327b0fc0da4dd327933e727b0187de740400cc5464d91144cf9e81de7f9c3d7e193925777049f8c26e3e55772b6e55607b2cd4cae48fcffe179b6fc594822284b746bf5123ee5ed067ea8ce6b3b39ab5ff00036ebc300e1500af9e4d42559aa961aa318cd55d7c4e20170f450de4fc58cf085c2159730f177ddafa2edad12f675b1f2edb00408baa8083db30b50c4d0ee027fc98dacdb47cd6353f2b39737d2bb152221107043ded8f027dca0eea9905997b684503426f91feb9af51b8aa01fa86677f44ccfa235337a4b92ee5f2dbfd62b03f5bdb4e2530269ec0d82b1ca91dcd1ee9bcf010d6f511e5ae121baff02fb0c1fed4029877b120a9cd494b02c08f3cef0f240b8ca5ef7e83be57e5c95b6d93ef07633d5d903793c6c63ab479920050b23f0decc9cdb6c97170c746d8e7443a7ae742d325b89207941e41588311c5342da7e218ef4f03c0320ec0161f5668fce99c1ac6f913ce5bf6272b426f1f4cb90c7ec142d2d4ba68c3722c9e01bab570e97c297d6f6aac0ac13e6b97a92931c3334ca7889788124857e32506e3ea835b859775796607113645552201f92f95c3a295f2d30c361394b08b38020e06d42208ca07a84ad624b6fd6b9d3be3e6155af717eaa52f792007eaa01cea0339a80ee4a03ed44375401eeaa1382087faa01ca803c90798d951965e562cbb3c4a83e0b496f26321a1cc1253bf72a71c157a164e548f5c839aadf4ddb2634f673a4ba62b73aa073b8d26f0881197f0fd84b462c2648ffce0b2004e62d707677e3a30867dc71202c491539a7510057a64f625b02870c9e8bd6fcb9723e442fdcee11022cc5ee4071df74dad80e49fcac65beb94b57d1fb56fa2fd97c8be79b31692b7d47b995859bb45f441d25f4efbcc6d112a301555b2a76c0d968f275ce2172095e3584e1ad92334589ec2423c0962cf11a52056072801d036a8696810602b047a2a698965107ef30de7d7278a5a76fbfb52477dbc2e4d6c24b70eec3d2ee8f7df5ed20308ed441bcfc0ba18c6598cb2cffb99ef06ee81e35d5b7c9ed8f702cbd4bcb1c9dff441e173ec6b5978ed5981da52db2bc15f32b3b87294f670ac518399e1135f14e9524541a33d660ea6d169971cb7952612f80d15e07aee7264cc57829a6581e470faa9beff900ed8c2c2edc1e0beb0b37970e158d01122acd7f4f0e1e132744f067d6dbf9f0ebe354b29355aebe7d3d965e89e0cfada9e9f1c5c86ee64d0afedfbe9e064e84e061d6b83f29a89a1911abf9f79d0b9365aebe7c3d9d7b8a104ddabcfa73e94cf9cd3dad2aae93e6c697c93eb2f5ec4e5eb83699bc4a071bd3cce95df34196c18e0189271b211f2cbd1baaeec91c168adabe6110f7fec50e82c2836a1070734a080bb3c9537bebabf3889d54171d4e2ce6f1aebd1007b694a553709219ba1928ecbeab0cc4a12114d02a136864f7d16558af18cc9216b0c9762786fa09f127f6f6d33fed0f7c452c26403f4f5c31acd664cd642e621a9090fc5aa7938b05e75e35d423e660f7a2542d563ce159545e59c050ff0bec1e435fc12b9780aef0c4cff66879dcc3506c1af89f7ff95d4ee0cb65b5b1721bc1cf51ffef0450d1b5a44108d0d05a47d11c8fa3a03882e8aa10d50ab90a29dddb6d2c25469704d8f18e7f2c2206488b2c98a0bbf9e619daea5eb744b355b7cc440f855c668f657e06979568b06bfa08e12fcc3e2fc7f473d01010bdabfac28cd85e065e8f4c63dbafb0178d8912e9d9db53ccfcbb655f8ffd367377cea1b9919002d41e98d9d477bf44cd3ca9aca1f2a1ebdd9dcaaca1a0d593a45ed277b8e758a11202ab430b6fd25786bacc2a5da97b085940f630a290a2420cafa36b960250095727105093afa0238444b936b942591890b91f8f82958d24d2461cc7f76a4b03a1838d232e00fd9a0b4e14234a23630dd1eeaa2188f1f6b1e65a708a96a34d109544a0d482240d598a704495dc3c72984504538f67a82f85186b3e83305693f597e2207ef0af02794b3735164a70caf58a0903822fbc7182eedba93ef8b7d1d371f91c41775596306d3c3760f753252ab4e8bcf1aa4d451c58a66ce028bca1a93cf992183d909f843940a995bc461278ec18351f83199fa2e6ae3cd9c0eae922909e6692fd44f8ea7478539b6ce8048503ede3b150882a2b39fb9ed4ef81cd354e37a960d3d21b967f058b69a1236b1c5537bb6bac4aead2f0e87121f93f313ec825f752cbc19bbce2a3162333590e0bc254812fe15de4c660994080f1985bdabe75d0288c8c4702490cc89f1f117398426bda5be5d0b17a6e006775291305191d10839c79bb2fe6b8cdebf40054f97b224b00855527f041512dce5b1515fa8596b9dcc44367e9b48e2fd7d2e7438892f22f96778b62421677cbdba4f3629b9659849e53499a50ff5147f3e2e2b621f4d399634562197e300493fbe4fe3ae7ef0f5121f0a0d9eae17cd5ff00284601fe7dde221bf0719e3e86b184a87ac47b855a2310a23f1bbf171cfc9ba77be3630f1fde499f9519705965e7ee8c7f07d5e5a06f4bc9e29afc6fcf01978bb196dfa245711073a9dffcd7e8a4dc2dbc86b892776d4c6b995da9f9ce87958b870818b9447eba00f1be6ff10d4af200f8088e93ab9817f31182625253f4ceb90f84dd54d40357f81c75909a783c91181867f7fabab09f39a58e28c311d8260385bfbed2dbe593164142b3719f7e77a346a5a22c67573ea5b3159bad994eb7cd43a925ddc91bf53896b388ee39d1f38cd4885d0c1172e1f897172fe2a07184b5e81f9e2341998136a69148bbf11ca4fce6c1b063407ee59c3ec418ce9eeb30dc0330c0e0d5305a4780cc493db7c7510b34316522aa4a187565b021b4d83367f1506e9dcdf9d49534cdd345ad5f86a0bbeb9387af6586303eb78e08630125e0e040b660890102e03e5f0a011eff3fc68fbeb463f9fe3b68fe78936e0c92fcfc1da4902775ef952deecd9e71d65f699630f55686e6bba6fda94fa10f99e7b08b7797ea6fecd431e1290bd19e6ab601ace49f6d8ce3f44b9eb9a3b67ede7b771e92517d7dbceda4e2952cd6bb66d8684240425b54d14c372db6c57be1fe0cbe9dd6f19474badfa4531cdd4eee83b5512dc72c41444c9e2909bb55a1a01bcf021ab5d66473b66b7cbf72d200fc033f667046cfcd8d256966449bbc9f2273ed543b3ec8b9168017c799718f974ca80a21fc4d7c522f0b1c9befd5a4ac1c97ce40012158d4be70c48049e97f04e22d02f37051e51baf20e7f04c3e68547ccaf50ade0ff28bd141623050658b784dadae4337331e96ad1f56be66410bc96876a089e190a500859d1692476b7b161eb859d63fbd61f13318df93ee1f3c76cdd7d0da1ca76e9fb451b77a4732a69ff822ddca02748cd77b3c6306595cc090ea71c19f82880640784e9c2634dc30ea72f5c7e23dfebcb632f5151a12758de073408eadc058412399398e343adee45ce59e82eb4c88f1ef9a0a50b1301ea5a1dd165da6dda982b2096aff36216ac367e3069264d542149abbc5d9d4aa5a4f32b9dc0e59e08f56d7a4a0b6d522a83d61ff0fd9e428fb877a2eefb52ca3be74553f5195c51abf9864680e098189c0eed79af97505f20b0205b792d3aa71e1a254a51285f07a17d3cb1200918afc46ffccbf2842948a0d827efed0422a63144a148850671bbcc8a621b4571bd910e7d2089ca7fd39cdf50a98d9c5c7b45c3cc687f01cb635649e05d6498cb2d8f94beea27df55587aaba39125ab5c813c20903b39d321758006e13918d31e9a83c04a955f0cb67322910610c01ecc3c483252df8d00d816d1abeec3e1e9c03483cb20c533e5ec9cdbbf498f0f6b110f0f0b6a1fcdd3978deac23ffe227c3be352a8954047371e5546f697524af0c727c01c5323798f9c7af057f671487f8ab121ad784aebef995080e7961741bdf46c9426757d33d385df787446e756aeb3efc23ad49db96c3494599298d1a5f7f8fac7ae61b4dfc50c533c3ae5643dc8746b208eaea5f2bf36fe382e76b1855806d23ed4fb8ef792827277282d3ca11023eb02e8ed8b2a84b01b71c3922c438c5613c8761cf20ec2182f0b88f1bf23e93246ae10d82d51e1297328bf54bc5507489f6637c5e8f9c49dc975163d5ebdee542e3393d7bccacf4d513dee3407156bf35e99eb13439ff3e40d013e3f98d266337197914868e1e02b19fd223f3dc753ec7618e0d4d12547ab9d705de1ce9b0337bded19c6ed57e7fbdcddbce3e6cd93f02c2d7a20393213c89e0c8fd69394c76e2ccdd06cf23a83435881e98a9462694c8b25787bab7afa3007c9895ed89367ec267b799ca979a1dc0fe29ef232e7f6c72b7fd2f29126036480d12e78a7d10c1cf2fe07ebe430198bf01d802a2979817927b244b8b709902c840df7af1ea966bbb17960c83cf4cfaeda1f6fb8cc35298a31fd9ab9009ef06c43172b3a753d048468b858798e63c9d1010fbf77c3e20327673ac011533afb5792e7063f6284fe171cf68c8a97185ddc8abd6451ff7860a9d261d2b57520e699de2ca55553c1c012bab816431bf1a403a08665266811de0c4c8a0c5c1daa7460849179980f71409bf08a1c81e117da997be2a86e8858fab0c38233ac432cf989e2792a49f4ed15c78ffca12b14452eedfd754adfbe5a90ba0a88352732299c09e484412c27f67d58a0fe3358c585022e37b3481572ba6a4692a833227012928d5383fa8d587ba08f99a174c2d4296acda39dd18d77f589bac7c62a9ce97b71a0263b1a289c2ba209caae4424f29100f5fe941fe633c529823287b89831dcea4229a57129049df4b147464e5717c8a5ace3a82fd942a232609a9b68ab684f67c5a2784bfa6fe7b72b36353d6eb4e0197e4b4b5125dc797dd88651a56b5bfa39133bb1473705bf620e086fb547defb010350fa551d735ce572a3a2971aded0fcdac7ff76050922343b7bb60e6ef0df8abd79125fd51bfa9de341fb640756474cf44611056e326ae143ed0ec480e38afe07b06e63dd1768909f7cb6240b00052de80557a2cd0b73ba23ac3242a768f89a015e429d79b764166f0b4a03a06e1f68b099f1b43e1dd5896c9a5826abcecf2078e08952db3877fd0814c66df743340df55462cf0cec2a3493176419383a1ee953c64897faff87a86e6532a7fea41f4aee0450e87d80f57572ea5f74b8d7cdc4514349e46a336942172e250b167bfb12e198a1a34312dc3a2c4c9b84792260fbf994146c65f17a86d91710154abbc9fcda4d02b0b81118184eb8c4bc7a14ee9ba37bde944e7ee1b492cbd45176e86df887efe1d2b6f89b00862f50cf50221b301f2e751010dee13d631f00d30b7a5c3319ac353db864954adb1fc359df810fe2d917074c700e50765eac72dc8af8487f1a9de5a44438e718111a4ceaabdce991a159cb1f52d6eaf81d31cc511dbd3bba7f5517da5a2d70f7d28d89fd1600572175e55c4c6d42b683ec16062b3c590b00899ca34aa28b976a9b4d5a11642499b3d65690fe14c68a34037a3b87e77841de8ce14b3994d4d64e9cc40a539915b74f20b2d968dff7fbb8757d8cf4ec39c617dde147e31af7f80d01adaeabf67ba8a2baba6f17482e798671199e677e31434ac493874b0964a9b5f3c4b8a38e7fafd8d58d5b8ed7e0c860ce51563605ba35d23edde7b0fd9787ddf5fba221a537cedf7b88a379d20dcada6521ce9faca1706741b1c8c68cada3ddac59d1e0e52089559f89aed88dba54f917335d4dc6be952893ab4967c56fd32cf30366f2ddbf967711824268581c208ecb7f43a055ef833e56b3df684cb44bcddd3a921630974bc6e05c3d3f3c4c03c016e7ba277efdec6d0b1dd55c136b5a9f0b984ec9530de3701b15faf606822fc1c145da2fc19306bd63477c86b976f6feb80c9db023a12cab8ae2e09f48ea3d31129e191fe29371e2e6667aacb10c5e99784e95d4bacca5aa96c9bf5603a06148b1fcc70a24a12b9038694bef79985352b2ee44cafea1588558d66c4a5707201cfb24067eec32d4b75a37ac7ae113ebaa80fd73e09147cdfe6690a0c2a8f91bda71760257cefcc48656632b6da1a6f6e893d37348bc5efc70f99c40039ab9c45d1d90e3448ae8662214869f23e67a76baa50367f8a2379eede2b276c62588e34f3e5a88b15cc3e4086164236b3d70dcc1eae853c98fe9a68a3d94d108cca947241617e90db28043b983902c6237f03f25128eda11e398273a9804ed70a4e9132c0bcf4402c968a5339a790640911523a0f43fcd549d74ece0864828c363200067e9e3241f717eb0dc32869e398b2276a22a81ca0fe5f9c8de760c167c0a99be5c2205dd624ca92936e9cdb5db77073250f4a20cb8eb74bd41b561c3e4d9cea8efd213db361720371f6ee38ef5e584d660067ed38f57e0d6bb270257fde3eac6499ebca347842173e90460c934b2d62669afd2390427ee7890d3c563abdfbfd30cbea26f65eff726e47cbb12f5dd338aff449c2cb64607723331039434ddb4bffdd7906778cc1afa1bbe027cc8db1bad8071f8ed0835716dc85f83c3c8c96418d0363af64ba519d474eeecd437dfcf82e71b4707a7a8762f4d335afb8da6cf205e681838f80974423d2a83a8cb2dee40ba7ff415cd09df09e5542a6281f18a645c126a8250713386e9b5b92a5609859bd5f15dea6bab28ea0a1311279893285b45d5549a930d4b4e294525a7b698fd939c3664323cc54c0b40e40e3e51ec68f6daef9c83da91508553c9477b40dee1e34e14ce87be2ab3256d673f2f3b0992c84614430dbd7165912e8729ea28313740c939a45ae12292b0c6242ed3da5d93e095e1e9b9537aafcf15277a187f2f44ee93b32d8d74c445b770374ef549cac9450caf5231fa828f7b39b07041645a149f0d73e0000bbcb84991a30f9fd39000561d7f7f42e6fa55c46cda5fc423f067913775cc8f84817eb785413f9457419746862d56a675b749aa7acf74c5c7f953a054676b675e9eaae49dfd6857c61b89dfe52371902c7387324e6d41a25f82a9e4f5a159cc6a9fb25525ef9e02ba8cffd8abb194c8ff04239957ed1f6ee0c958c8c950d8bcc227c27d0784ee46e707fc5391978c4950389dd83ec08c4796e867509081318ccf10691aef2ecbce62568acb1817ef578711d400fd0c57bdf1ac13c3b84dfc8a39cfe56eb7b99bb058d459ddadcf5b2e8418356704fabc399169cf2e7b54d5ba48815ab7cf89fe9834c56137f2930db9a5c5e05a7c01f6dec3406bdabc2084f810309f0e8c300d5a0fb9be2674284844fa925921609c31d2b877388a2038413dadd08de2a657612e5cbc724dba52590e04e95a5989e82faf46984ec4644edc41bb044bba4342582b7d6d0b15a69de5dfda0abd0bd9ee348a6c28b93cb6c4c82586267269258e49734bdfd2004b8b2f345ba67a075d52ce1af5efce26f7d2f85734c10a7029aa4308f0ad817cb8a3ec9c644a852e34c17987dad3d2d256ec4372f48dad203e0d288a15054ac91b37328b747357e1c32b4613fcc6b8c67716e8dbf21bbbb42bec632816b8d2d79ad7a5d5642acd12592c67a0b9b6ca06cde4fc88b23670bb9591e27a3aaa799a54e17eed579e72fd0be27b2514aa027018e00d36026d322836f3772cea474ccb95face3f239557080c631cac74504623de7254e257e14d0221e4077dab855e81dc4e0d0581d8bd8877773c55f80c9f0fdf63e1d6697509bddd49c88cceb6684bad298f8cee81e954fb58657d08457b55053ba9cdb402455d9d26303eb68fa8c7287d5beabcf0f1502f5e21c6502b84f2a30a1144748078d5950e8493f438c709365ec9e59c2f7e5caa9f5fa518183a78650ebacdb909f9a98af5b5b8169c3f9b5168938a167a6397a5f31fb52e14476621336cd3732237bbd85ffbf0842047942aba7f5687f37d5f0cdb09e4cd187fbaf15f8009df68aa6b9e068c86da492a9b0dac8b4c1f04372a83c5e036762db0b9d1b04c1fff3a17d4902c1fa2490f3618797382c566c439cedfc93c588003840bf49cd60028df56fb5482644e1da157880beedc4e7ac735b002df13e9700dbf8d40b3f00e7957443b0969e57a5b18dc409d6ecb6dcd0bed06dbe6324f65f36f8711bfc36aef321a6c74f2ea464e1f91b0042a6d5490a35c1aa5247292272812a6eb2b20c1fad0a49e15099f90bc2d1337e4a6a3ccfe37cc43692ac9ad0a343d9482c4b0e3d362dca136d61dc8f203beb2a1e8ac586c8e5c62081d74e343420f7ea0b390072dc2a1e2531cd0a90e1deb40b5efc4a1c581b14c5d0f09a3280774f98eb2feeb7d22ad45a522652a6490412a6da270e9836cd84e0c20f0928a85f303a1559e603bd307f9bb8fbd4bcd92b20228afb32fb7c9ffbec67e0df7641f9f386896847b32efc6dad5707ff6e293833e4e28544ee92c21a8e4c3c90729e75c3b9deeb37f5a4ea67def597eb1b11de77ae8be6d94076fa19223d31bc26158297888ff9ea7c57a57d8fec2c6619815e26d42c628db0fdd97f5560519893e3453a9ea47301217ff41e1006bd7aa568917765456adda2ab63d80c7247c23f8c2b4dcb1a5e1e36b8979f1ff747f1f1b1252aa62f6d1880f3c162ce4299e1f786249380e25047908622da7cdb1c4cd2dedd5ff6e7f4f9726181741ffd2aae5f9462a8c944224e7f717fae9590623616a515e572965b0f916b8873c3e5ec1c0489719bb2e8fcec58c1ffabffd90fb18292138b5748ed87fd2d5cf165f47732cfabd21408344c4ed4182faeaace025cdb8f6daf3e5b1766e8cc0ed58b6201020ae7f710b831f74ed2c9bd9865f62516bc2ccce0a5383e22f7e8e11c93d4a13131d908afefb02c2a153a358b5b39c1c7c36deeded56fa12508516b2a07b907ac27a9d42d34575d6de54697b38d35f13804fe1fb294a8c09729fb6f010f37c110c935a957a9cc49470bec11bfc6f6c5433e0d08766720aa10337bf254463e57c758287e4c4103ca3fc4476fafbebb0ae3c7209d6f1931f4e067de123b949ac5056d20951b542104ef34a5c50d98587a9aec58d73b45b7b93f8f76ca30a69b2819edb944a9f862a9e0dfeff24d4fa953630227e50565aca645176899b95cd8e12f682bd6f425c410887b6aa7584b11ba4d4c71d132604e1ad1049f79a8532c0ee247f18ba4b53b5e4245918f2c75984ddfb5d1153e301620e0e115e4f583eb1bc56b064886e383953b76688efe6cdf497fb0bfded2ed8fef992804ce72f73061e5d2875f44fd4410147b49621b1eb930cc2619eb1ab056469cde080428c53d6af92d0d4d14c4e85b5718a3301e7553408b4989e9fa068b81d80560ec76d3c77edb4e2a3e888c5769a3049b654afa12440e71e00d881c7d33c7b15ea541d10f4a5a9f8c7c6166b79f18fe1dc33aedacdb3257a80091bf99d58e3da82cb645c0e683280230d421526f247d1a44e1ef4df14c5e9ff8dbd6bf72ef358d71aba51aee1e3ec61624227a3bb375a673aaa9c00823f8534187a4524e232616743ee15f0f6d0aae019b752a1ef81ab89a4e1fa5998843a7956498ac037b9d50373912a70349602d19e5d5ad98b91eaaf13067b968b4471f3937f05cf30926256e9f41cd6dfe0f21f0df5fe16361a9a55cd1a39e7cdf8ce28119e73b1b6b37d8e33e493b4abdaa305edcb371bf740fb48aa5dae0d3086e025e88fa85441114bd2e46406d353992bebf9fb67ad64a415c9b8aad79700eede773f0bf139482580d49147090123b58ec8270c69a644d51e24c2d524442a3cb369821df161f557ec45f01ed21d8a5ca0c09bf595955f3e76954154ac2035e52681e881f288dc080afe235fff59b290490db0daebba02900655829afa327bac107b658516f89d7723da3c391a738aaf6dd21b34def60f2de72131ab202265400b10bf3e8d42637aaaabeb536036dcd7a0a0e6287ea7b62c15c0a6e60bc22bed98828345a3829e9ea9eafd50d5f932847ed56019a492b2445015d7fefbed3898337813077e721255c8433e7c656d6c4b98a73aa148e2271707074ead2e7baf3d16f9538d72087cf42f9a0f8bda923d47aa9ad1043e4f8104a77a196321076c379e960f7e70811f8b6b4fbcba3fb1a1e1462940143591f058e5d44012756f55f1065b8c723efd93d620e51512efe183fa3bb5e43c274dd9122532c3478dcbccf0c148fbca9e06a0e1fbdda2f63cfc136db04b4a12efe782b277b6e7c4391b2761202af165f903a22238b09c646a58ec4d7bbc1235cf8d717bb98bac553b3a50e15d8055f84f8efdb58ba0c2236078f5815aa76195fdafcffdcf52d74a748513c58c03cbc6da1625209ca67c420ef0e80a50905e4c3ec15fd083e2297d95a038ea9b1e2af33392e9b5f234bc83aafdbfb6bbfabe56aa3f67ed01dd45997c8a96ba5ffddfe8e03759fa81c044e94b068b3cfd5ccea541db46ae0339e09e45114e892902f5aa024f23b79dfe7ded55980e32e70e3c3110c2db3913935f95e8c6c9b79a48a2a09e069a39e152c38d422a8255221753d363dea13c8f066fd10de9e57ae6e93a439476b402db78b5a555715bb9a7b4e5428f53919762e8620a261ee6b872a20e01eb5e8cd6011f82174911bcec227297f6df0cde43f147d540a808a1a04d87008aa2ecbb9c0a23b0b83bbdfa0b0539118a594357eb36646de13af0ad17a4521c3a24eb7907f26640945b8b071bf1c3400cbb70a0165d60d332ad5d8ad92d65f3d85917839abced463ed908c059307f5d87ef0a5a4291a84a7a3ad74b787db1ef0b4b609433b040929f1e2d053e362ad74e11a2ca0aec93e7b2da4f92b849ad1778ce2f3c227378289ee4aed2dc5745552dc47f6128ad860fbe28c3a9e1f9053477afc0f4b202e8818a5eb50ce37003f51210cdbe779da10d6e70879e506acc743d7099b6e386a9dcd82df2b1bfb5bb61babe345ae9506377ba66991e55e537ce4d449a93dc3a0141b84ddb2e1d30e86eadff0d643b0566bad7e10c11ca30cb0434388e49eaa47da04eb67a91b7816f22d91a583233d314c2c1bd60ae7c644d8cfc6e7c5c11ad11253636405f73d4b20211d731412a1850315daef1188964e0b53e60ff34698bb0fb4eb6284bc964577a66fc0879f0cee1d355dc3118ca22988687b888cb72613763420d66cb21377887697c9c8d75626f912258443f0e5af7c534b088db429144e60065790a16c1f77ff819f93722bd68078bc04f36560cc05b857eb40f9339bf088bb07d5b8aba07fedb136aa8c2229e0042a715316329bee6f2a6eb01de091ae0896ebaa21801f104e6e3b358fb2ff3d55aa0509523c0f86fb3e8e79217cecc118ce6c7aa80d2fbc745d3d368c6d411e2660a0788691084dbbc359c2cf362aa462dceb397445c6a0b12580435cc64483017417ba4034aa006222c23f85552f74fd36e38ed45e54a163fd48000f40bf466a529659bc3ce5443c267e1833e8d7822aaad736ad3e7462c5e8c070c9bef46b43a2b8794a0bb3642a8847640043dd79bb511523a9a34fbb788ff0bff4f66f63b35864ec14292869a9a91876fbf5360f446dc0f943a25f92094e8166248039e4ba1d5e9e1c822115d773329e10bfc4c8e50db306210b6af060eeee3fe0877c5f66a0ac1e581d8fa62a75303857894e077205e0161c33cf97668965549dfe467850d848e4e5737d0caf432eeb4fd8e1422ec43d3d965e7ae27d7d49ae53b045d48ff06557752a709f86398f64ea56c93fc8d1c926150d5b60308829700265e1698dea59413030136349aacba2172d2b603470c986265ba75370b179590dc54113e032168199596edbae970a34c13281e470539667fb09e9907834c9159c5d80e8539baeb5034fb25eda35362c69ad03e6c67497f844d120847a42f6c16d2897638c4fbe9d4613a61ab52b81f380949e964ed546c4fdd9a9acfb2358d1b3a948a3ce7a84e3bad8a4cee8fff6ee01882340959df1443636a16add686acb12c22bb999ad68a0694d03d5c9be0acc67ed17d14a344a369059cc357f64fc58fa1cbca13bf4eeb1797ad219d0c4b41eb934e36f53051428d0b9c27e05ded9559450a21c0ec4121b8b63acd516c2424d738410aa69d854ff140be10256cc5ae2a145c308ffbe84d8f48593c5a924d7ab2b4133066f5f84fe64852c8a0e617db11987032a027d0e973b8f153571fa910d961e72e5f9a4100b7993664dc50465d9434002f5623e8374f298c93833355e7795c534a387d95994dc2e102ad2d96f214d6814bfcd2bc388c126a4e6b4a298baa5c2cbd4fc3fe2dce71505f8609ec8ae37d4d91c9e1a39e81b1b05c9edb4c2a4a639fe4bba9a2e9d60c27dbd2cc8c214385e91690ccc7dceafdb6bf2f927139f5122c6d7510b677472f5f8b1b8a2a78bf30ce12ecbdb601bfadf1f6ef9c40ec3eb7d57514cb2af9da0b9c34406f05b9e0703c2b96407aa278bd5284b84bb88009e3f235bdb3270c7960ca8632ba3a7c4cfc035e98330cfabbf0eb5fcaa7ff408432c563b4d830c4aa49ddc25feaf6792b4c647ec59472d1018043aacbebae4ec292e4d06d52a86f8513305100df9383f49257ebfc0da12317619dc27caef7f48925a5cff8bc29b39f266d58dee3b8acfd87ef513a4c4176f6de554e4096cde934bbf02cbd80f58823fb474facb352dc4d8d3ce8f43a58bb49f2da33241eafae6798744f9f2acee78fd32628067d222e78b8b9d8b1f96482db8a6834874802445cc6b5aeb71768bc6fcf14b37a85c673898a0bf077223ac1bb081d0cb033bf757ceeae309e6dac5312aac0f17dd8d7efd7673925570fb550f94154de8c4f546658a36e803efb11d812b54783d99a42d171cae24b1af21a398f0b025c1d4273e321a25a809ddad363e23af124d99f958514d46c0aad2a4947a2b84bf9995237dc9feb7127f2d4d81b84bc812a682e3d681ee3cc402f522d58b17b11f4200c30c18b8f140a67404a169498c900838f580b4e71a73d95091d08dd1df2e4058a968987e30b405ea03ac221b9e7abc5338231bf8fd52b444b91f9043f89b96d567ed25700466e55cbb44342b263600abf0c63900961005584d224be7713cb0df3f8ab07ee1983b9bdf3284b270d81ac036e47025d4229fcc2865ea88468faa39f8655523eac7b38f230c406a89492425ffa43ef02f7282b41b2fde10edf8796a43b8cc9beb5de1ccfab3184cd408f3005ee03828578a9c4f000c7064cd4f3e0eb1d68d451170eb9c3c2e1114752e56423b31ce7c0383cd58f9d8ebb9a3445260aa0865aa47922fb51df3e0ab600487dfb022ccdc32983d15fb9c1386ed04226ac9a7a7793154b8534f2f1a4338c58421d12067d86897b5873ef1c64890ec03cd75a333b6e53fd2f4f023152f374fbcb57d8a2f6403b944a84c1073a124a6fe5666f076e744db6b92fcf506ff01196c5e9b315341ebe18aeba095f5f25540ff05e22744039fc721f8c2af4cc006de3f662f6d12db70c578ecafc2871639ac589a8a7ce11ba4bce11eef082ce42c328865a1a88cc9309f627866f747b498112d2bc0f54ca7b4a5aae5c0ffaa6cd11129329fe237e1d30db716433bda49d7d2e12848c0812d5e161f115f40d986c3f54fa25778fbdb0e5555fa701eb1af8eb66ce426115c2c1006ed5836a120228c36b7d68a6da76f5cff799e9a6c1be0a320d3ca1e67dafb155b35220d11775fd32b645e3abdaedaa4e25e44ffa2ad3d92e9b6e4d6981bf15553cc4bf67a71796641fae88cfb2e7ed0a8916a6770e96169592580419e2cfa6c1f7a5a7788196dbf3133300e149a947be25d0a7482b7b52cac9aa593a65fc5b5d3a0a064403be28d7b704b7d990d2ffade793015b44d4dad706b9c012ded3eb20195ca04ee2b9b0f4a271ab2012a4b75976327cd0331e9d6b322991768bf47a0edf25194d95b2c7f1afcf493c352cc8519a08a0fba7d264c13ecbbadd7d1bef7335989d009350ba9fe7a2e9830b341eef5ca8b4510eac7a3180982d65333b406c49c2e48abc6753f7da08572990f2166b09228551b4a06eb91fbbed9d8007f474b5c64d8320eea40dd9ac29acb4be739e17f65b293a36716a0fbf4688f69bc4517c139307da564a0e06197c49cf06b1c113de7b0155777bbc3938622480f7155a022e60a55b28ba71b243d7ff430b802c1536db940ef12a0bf42103e1533eec3ff5c73f6090a0c0409727d03747675e71389f187539462a3ae363d79839d78215b7166bcf6758cf156cd9f1ec109eabe0632ee9ffcfc5a9c857f3d8b81010eaa19dc79e39bbb5ad64dbda9b778b06b5d5c207a99f96eada8753fc958ae3a1bce500396e052e5c4167ebd45120bbfd636c00f653759d7d0216652de24917702202471895a2fdcfdc982ed96673a30c53591b7cff3ce5e8dfb2048d218a38b998de1a336ca750e2f10c5eecf676f379bc7176407c88510f15e165ed6fbd1d2ba1ff7efb74b99ca07e5b86ecd3b50cad766d87ac00a1958c44d7e4ceb8111f337c9b95ad905eb8d99015592368691ccde59245997d021b985c4046e3e590f36b799e5227cf0427cb898b2723266ec910416dc2f5265675c43e56f67d24e83edb3ccbbd6995f2ba291af370f949bcc753a860ab6e49da9f3f1cce84986d9cd0d5cfecdccc8406ad05d216d3053492b2d171d196416b9c2d85a1980a3b668259c4bcd931637002390f7a6b71424c1d4b0e882ee276d44126a0af637d6d87182bed4ba6ea39e21b380f22d62b931dfff0ef6b6c132da1e709e990965914f6669f1db7e3816c2c1e29715bf032326fec0b232704ad4ca20857d553a16c554b41140b1248124e1feb2335fd9e947d030882298d5a3518989d0a87a033d667f51b5a95dc64dedf10d38be78325162a5d059be4fa0d4c94ae8c3c4a157aedcfd2a82a10bbb7deb9133a367e75bdf7ddfa68554f9ab1e56a81819334dc7bb3f6399e5542ebbaafe8886e085a8b101a2c967ac2938c5e0657394ad84f7af788236573b111cedefb2bde8a0c2a2ddc9b7b4b219f1107e00379c2cabbea82bf8ee804c1080a4abc38946ae3313a720e49bd29f77409e3e0013d697e32ea55f9a024e819f4df06125c7874a8bad377bb00bda2197f63238e1feda7d23a94ab84aaee4744c566e4d4d77f47aab482ba95e924a5f24563e3ff6b353c4dc4c1dd53af94f90800ba54c70da134b4fb56c5626be66636892ef6bedeabbdda4821177bb53dff8d3013346e998c3bbba732f2d1b7301f711ab4f76a7fd4229530f814068227221092c865f65c185b53debd2141f3f292631e81639d252f73d58687a2e9a830fd5bae235eae4ba7f6b902bb58563396587f757a67e878928c809c06910d540bbb3d1c848f44ed6f7d6e41a83da0db796ce7d644b0951fb15851a85c492c6660894f96584c728464171df2d57d0991dee6d9891b6045b5ea30bc01d82912eca56d7d9c5514d0807705728cf84542a0e9c79641cc07d9762b0a0208bd3695ef4ec7f2b31bcc67d2626f9067a733c7242b7e6e8a86941584613677363dd1eddd7f6274c34e5e1a03195f4012c14bc3cfab141c500811317e87dc098f15fcf0d6731ea27820a78b4f78013102d106d3384c89d928b88bd5b0919a9b4319249b72b35510981e7149751e30ed2b75e17111346d991536d3e9bd3a233063bc129b772777207acafc63c6fa868fe89b74f4e85da077a0255be3d6d6d003fa4fc4805ce1774408436bb8582832bac7f2df0af14358f52e5c9a45ac29bd871d112a515f22cd2fee76ddc5f9b3b61332514460bbf3d1149ec25c3664f1f4afa2d7a7798acb807e283f6a3aa198d2f90c6cb1d6415703262201c369f2fd94450af55e2cfc53f42f1011e12f1aa534e59afb9dc2698653c9405af416417ca642d746ddfb35b5b0c56c253103af845ec7058362d2e22c034e1e8283db19b8a41ef67713adcce447bf460c54f15c31be06f4e196b570815986f56fa3656dd376c7b657ee1aee3e1e3a745c8e6aba279a11bc6020bee7324d052d8e2555e8c37780ce5092a1615afe1004c0872b50493f4ceba435730dd6cd94d7b48472b7bbc74c3a11d01f56c5b97515cb408b54edfbd41df15f8dba1a740d9529ea953d70b39a5427fcc06bff01fbe83b4745bf194f180a6b9190de7ee4158345d0622ff9ea0d6be40613db3c6ad4def2b932866732397782b4540e59c0fce067361d51fe3a0728a9123b242dde18a4de5f6470e605665d45e28429f9d19353a607af01970ac98e0022000dfdccdcdaaae726a1ef8114b85b8f1cdc54dde1261770a484e26f40491d36c56f3ebed43140985ea5d579500271477714b316558827c4447006673f289578da9ced295d494438b859125f4cae4d14b6db3c76be9d370d973e293058adb88b9b34298756783f6503c32158115e3efeda93ba878170f554b8e303c47b961848b6ef6a8896194ad8f4a33d2a330848e9458595eb3bfe6719c2c2cb5d6190ae2b0ce2c560c3e3498058e9e3aaa73f1a43478ea35a91856060cbf21dedb2da5d2939491580dfd6413e464b1ada2cb09ca75dd7ad58f09a799151544e7002c1bdaea831d990929d291289b4541548db179bfb833d3a26073becc1fc2aa6f6a5aede82050a200d7e21317466cb5d6014cd1325dedc6007cad89d35805318ef746198df1f702debd9dab5a901a8560780624781ebf2b654cad88e36d1205755d26583fe7aae4cd1b181a10ee509665df16e7e1065900a096af900174eeab85ae19dd8c64c09da7927d71a862d54455a5d81daccab06f713017909386ef28226700418b7f494dbaf15c28630eeacf86e047cf7a50b2253f491a3dad180e8cb4a656c205675b94350303a2245fa4456d0c8bcf80ad8c1c11f6d3bcc964eb26de714507787d9dfdc612ab065f4b77453ef29b3ab312d029c4bada386a8a66d80f708a47e7d3613340df380418dd2a729e186ebccdcd01b0bd2a985de60ccde420fd9ca6ff5bc48a5115a322fc85c682135b0b68b534abbd8c9171f35d8362fa15b8135b88b74d3014aaa793cb39dc411d8d9260897eb56e95a6cc379c3d76872785d43c8baf6ef5daaf6d121c6093983bd29062b3808050dc268357a06e4f6095914108e0f15f31cf4954ebeaec4ac2f2e44fd660425f68c61651d5946f96ec68090a91ab46fbe640a8bb6c73f5f70506f7f3902673e4b34582fe9a5673ec58569efda340f95c1df9ff5d80ac108db92b596f9b093d8c8465a6b3f73bd642e2364c8a0695bd8f03dd7b0edadd2236cb761600d942f7f9bf16cc008d9e0c47fad074341a17f270199caa1dc3b09ccde4ceb292af255898cf9957997290c424f28668dd2a57a1de6ca7f640ffca7cc94da504fea06d6005addaa164025168f9f356d12e6a85c5cdace3bd2a31b5716e2347c572805e83aadb4e5c2cd7ad6c638492f7f0b6b111723c7ab3deb02d1e424cf0e22d544d3deed41dad0301fc929e06b8f044221406a2f880d0a6b33f903a924d6123be7067a924604458969f7012115f64e69d9e8c3bee3d69a0c441888c0b113112b3789dfc4fd5ca8db7d2e4d900e5d00090db9fd740a7cdd90a7e80f1a818929ce50fefc42f0f760263fa0f7d419a002970cfe96d65953b16f6a6d48e571f7dc14123c8c833ba66d923b4777addbd79473b79c66090c8e116059842076bb57f3e674a955b55207dbe125a868451080cb0ead76ebef61eee08c50ee10f92c0df232f6951198fb5f19c9c5e7f9e3055c059d81b4e2057e8a2c9e5bf974b74ee2205553e917bcee7273d7eac82094e3b7a493a1a13c2d63bdb836e8fbbb31940dfec6e3a11897334531f15a02db1a13a92978c937402ac3434e00f2019d39499c77f8010b5ac078d05d4b730893bdcbdb0e62418c001059f0bba8aeadba96106712d5a69936b7fd9f845ccd20a2794ff557400d81d7d39fcbcf744093062e30097f1e87f8c58c25c7d140c2f2fd0d6172365aa14cdaab1897dfb44cfbccb764a432b1b2b4b1aca492b46963658d1cd8d43f21a5e55c318245e476d2f9a79d6f0aebddca9e6ba70410732b637714aa58b5f83ace147de698687eaf0f4c2775c076dfa2147e29344dce4a3e3e60a8ce3cce8d9e0def7f7040de09c39ce999d6fbb8e0d0aa78cb02880f9280603011064e38028c93dbd44a7fb673f6af3f5ea4b0fd98fb90bd611e462c30e78128884ade09c054689cad427a12c212c29132ff0fad72f5c7ad29afa6b6ae837f60f8062d7ac87b9d40d76d865d5f37655762bae000ae0a4fffbf6d1576d002ea36693abd9d0820bdba7600b8374bf13320f3d784e2931652e77c735fd071f6277679982d68ff1d0c1b743e7ab3eebcf90aa7072ee3c865d3d5cf0f43669c32c4031e8a0fbce828723c0e7afd67a3d213e73ffa16a42074d5a5d49cb7b0f893f40ef488708ba2c3a9f4ae05fa06ba067a5283d0a9d226076dc0816cead7ac9200a9c4424082a95498f5d831a43d3b3ce4690d1e46eb417df1256b7a50f57196c73606a271783daf4d05bede8132e7a629f0d2b641d39fe0e5f6c37c4a15293706b2229b76f9558e3d0be8ada1a2fb670154b7a8789f242ca48379f8694e646d68714b1be8e49a849e82deb8b313e57bc6cbd16a7a620d2d007f908a698aaeb802172627bd3fe4b30ad9fbe5e55a494744d54fe50662c74b7c158edbfbed35339c159705e7890277a10dfdac623e247906edb54d10e7e09265a92140e65e1fa575f04e9caa5d482b8df4b6ec03da42c30409f6cc706f70c58b2f7f2b81a48b4ad8fabf0c6541ae20ee7a18f490e99dcfc7c12e5f007343c2f7161c75e6935e6881cbbb71fedae3810b670efc5becab318643633f3c66c87203a6e7402d9088f4c9b893243ecb22770d970254332d5681e4afde32304481794b0538238d777fc9ec4c5557128b598a12da0de0ca7cb936a93f25682ee09e3182f05004201d9981c297fafb723b78622c306eda5dcd8c69cd24a6a2ef8a913d3cf704dd5261a73f102a759f1056cbf3e700b5e17fbdcd47d968a1f941c9ec3e078f6ff8268f332f495cb235f3f153e12b9652df00260281cb28bd47cf9f01b6034ad5b61d4175f75dd3b6b31ae4ada2ce3af978166d97575fa5376c842606dc9b9c0535d2f8b06760360277729a2129debafe29e0d9aee7b8548f40020b24a7c24217b7c5043668cbbf1503cb7e5ac09611f87e02fe866f8f96fb784265d3716cd2f91b64c25cfa242ef62ae3b2b4087ccfe9ce6cf2628eb41a60f1151a0f7d3d668cfaf90c261c5ce318308cb1bf65a45c0d244f145761900ac4812bb36265e25377e15c26cedcfbb681b6782feffde7cd504791b4412f9d3b6a1a9d713405118470be2203b8b1e226e66bc098893e1c9be2991783ef57137896582e4c0fd6afd157f20bc7465eed338d08f4a6a553e32ce8eac7df8591edb3ddfb8b13e74f972349bc4a963b41faac6a7f642a456f64dddd1088e7de7f5d5d4e1e9571d5d940bc08e21cea821208d701eb1b2891db23e9f0f41fd0705549762a739c002fca41e816d958ff4facb8eb4a1e3d2e6accc1ed11ee243615f8b732f99b210270a5398442303c4cb7d18cb40af153231508ff64fa2a471940ce6f342f59106c4c30f412039a13aa5aed2594acb116fc124741ed849cc3048059496f91c8c1fea010f6c0498bb8ab1753ccf7bf0690e714bb2901c804b8034dd6a31741bb5451d19cc4161fa7f0113d0475f727e62267136a2d70ae34fc537463bc861cc9f5d0d4017bc52bf2131f91a0274c1f6a3960dc76df67a937bbd4ebd16d33fa0104bf662cf973ff3989a549afe1ac9318ea4d750bf4bf2a8d2520aa7ccee5baaa06340460978b502f543a40c74a7f5d9338b9911b1407689146a3f8117b78e5c5fd8f4f3c3b8c452bf5e69bed9b54036a7d7c979926f3b2a263e1b41b7e8531646fdc9bd75b7c1fabf61a942d596f464e34ddc3aeebddea1e9f44dad156a84f00a673053638c2c2d5e7475d6b4396ece02a791664fceb09706e6530e2ab79c33915b6bf622673c582d9bc405fc970fb5923d8fd463ea5cbe5aa83de155da957c92a89cbc87b15094100c95db7ec92c53ab40b658367201810b6f8122db7a1c0b4bec01a14b37578abcfe3ad8d8ba4ffb172852ceabf262b0d512ca76a7254adc8e4381c35e5b9d3d1e0d75e6edddf320168ca7f29efa6f263c02996e6731ceadc47d3f4e15ac807da938ea059fd9800ecfe6f5b2c1c3bb5c0ea8e9eda17bf3cd771e1de774977e16a04057cf9868383fbf844f7a915a292b6ab35470bceb33c30a4eb7b5888c518d69f6002c4acb4a031abe25c4a06558567c3a5c1b4e01cde32dcef6735054e0b5ac84d9cdc71a15ff2fa7f404eab893f83d2826b15e40ec9587848a3ab86c13fc5b7aa2c43f95fec781a546ee7155e8c67c377efa7617641387707a7000e5fc2fd0782900999bedfc70444c8027ab4afb5c21a1f10a2305f261857fc9403ee041d113dd8478dc6edff7ce2aa62f80109415e5a92a7be85b8638716e6d5d50efe7c420ddcc79fa78760c04db0985722c86ae8e65cde4b2043c3b4815e68390d161ab2d1e87a0331a7e43302c7bd0192c21c38d291b04ee99f1e563d1c97859e4e5167df60187858ef1848c101e739e88c1b185875949c8489db166fc0bd6468ae29ed981a069311ec30ad021e5c842674fadc4d15704ab70b2c772559e64f1da25c12268c16ec0ba60b68d8b6c13ca919a1eecc91e0299d640e60eaba000c28ebf87833fd09d80b384ab4d1d0c46300b44451af49b4bbc5e94bce5e92c7a0d50befecd012d25ee1c2ad3c6b6cc806ce95b77f26ad9c6f32919f95a077cdceea39c6b7694e583de61758306c7cfbac24d87523bf94bf1a31fbc9cd9cb0b29491fbb3b640f7dc5cfa0c7eb5e1d04ad5eab8b77c0e99e60268514ec2f76823fdefc4c52e2b718c01df325533dc002fce49e832d2a8ff99a8d89d2bf0ee8094358223fb72cb4d2f4f0eee21af5cf0c3e7a710084da3aea96003dcf609ef6fdfc11052319f5651d67f01b852da664ac0fc713a6c380c3cc45fc8a767e34d4dc6ee9f7124361c8e3ccec5b59bfe083370d211e7944b2ae41bb7ffef5625e77070cb5568d50e3869b4cc416e8ca37388b2143ef12b9085fda08805786e6699caafccd39dfed1ddd2b114a8b022e080da6a47701def91e592b9ccf1c654faceb68c6c9a720774710e02b7c8c67a6f42055db99203861e5944819e3563bd43f6c60f318faf6d9d72784ed3b6f2c70936c4194262c2a7a1de001cf9b7c1b782af6658d419c62ae0e27dacde3b2cb5a4d71f7bb1baf740d982f576f2ed5e6d5fabf70e4a2c592f27624dbd32bc81139144c7cc929b4ae3ea88740bd348a6a9bb8d26b1efa2fa46a3f6430351ef20d5e3e9b46b1bc700e720dff97d5f88c96ea41c20ee7ed1c6002a32fe8abf748a4b68489f14183ba0b24d4c8cc3cfa4b7518b5fb337f50b88330e5fa67cf18ed89c6ecbeb85bc86445b88eb772ef0d199e902105d9a067dd449cc52bf12453eff028f07cd4b02fad07dd4d3a57db5b0af7f1a86dd231f8210b54473481b53824b5865bfcba0c90188decc368df519ea9e83b5034b73647d67d976d3ff07f682d852d31227cacd1e10506f85689edf70268045eee6234eef99acdf01efa1d6d2d524b17f99166c5fb4ac96e11c629a478a168d8a758ab77827c580335f3a223a4c1a3c0a35a83fdc286a684a2b028fc84adefa473fa7005af4f24c78ce90289fdd9c983b442cfd518d39b1d8feaadf483446828a5cd8805182e38d8adf79e56a6e64017d16700de33719a02ed2337d12db6a41d3275a7f9262d6d81a2e3e2541f903257e14b25c42f9dc12f6f7abb0f6b681128fe028706ca0292a2a48e02e14dd05010357679292de48af041ba96edbab370d30c1bbfe78e5ed1ba9e85b36aab8fc7ecc46d9d8e54fbb0a1119fa2cde6f7403838471395f060d4f63824c1e8f6015df022f808b3bb290537de714c25d24753b6faeededcb58ae02377a2b62c80e00b94aa7dce427a91e5e02c4cb030ad0568f5b3054aa9a0e19bebbf3cdb4d080cc83853a7e136d514d1ba449c59ef468b4c8c6a2249abddff67c76ce44ad02c2c6ae457f3028d0b846db60669483270b405a0b3428402641197ee2db776d9c7190048ad8b677b72df79632a59402de08f008a7084514a104289ea8c286a69fea386bdee4e8f4a4e8946e7a8c274198643a4190d44cc7591a11cd486d2c62c0a422a02e16428a30d588cd28bde259ba29e194728c3a282810e68d4e6a6b38b57fa8c126434c24b404e83583e8d476a1b523329d067ba7c1ce88d4fe53111a6a2e978ff6b2c93457116898e9849aeb0c5ad2a9b2e4ead5ea388b66ae30eb913a2d4f509e164e0d0f4e0d8f8d377f28ff2ae1b1a9dbbd50c37313623a7527101241754d2b2095a7d560588340128491dabf19d990041d2d50113e958d5820239ed415d770eb01d2d1a92f758154501484e5094188e0a80b4484171568053e758182d814a02e90123e55e5e88993007410a81172d4ab157254c353c363d3e0d61a1e9c06b7aa1cd57eae86e7a6b59ecad36a96e612124548142147eb09391202a5c1fdae464894067bb09d5e856e54bd1a21472e66617bb5d5594b23e4ac1d222aead5965a2bc3bd3a2341dd21398ac231a91c51ed8e48ed7a6a7fcd109f5e7990ba15875733c407098eae660892213fbd7223ead6945733e467489254573324894fafbc88baf58657c3e383e44657c383e4d52b27a26eb5e1d5f0bc806c74353c403abdf29cba15e5d5f0e8eca0ba1a9e1d57af3c05756b0daf86c745a44657c34344a8578e82bab5c5abe11162d2d2d5f030c9e9950f51b79ebc1a9e9c20a7ae86274850af1ca76e3579353c414b4c5d0dcf929f5eb910752b8b57c3f39384a5abe149c2d3d32b0fa26e5df16a787a788cac74353c46861cf5ca81a85b55bc9a214743a2a8743543a2b87ae537752bf56a5c2e22b4ab7111f9e9959fa06e4df16a5c3f4952ba1a5712574eaffc87bab5e4d5b8725c414a5d8d2b0851afdc87bab5f36a861039e9ba9a214e8618f5ca6dea56ceab196234040ad7d50c81e2eae995f750b76e5e8dabc76564eb6a5c468614f5ca79a85b495ecd90a2214f485dcd9027ad5eb909ea56cdab71b56cb4aec66573d32b6fd5add3ab71dde0ccaec685e3d3ab4ea36ecdbc1a970f92acab7121d997ad352e9d5e7514ea56ccab71e9ec54acab71ed6044ecd470eb619f1f7f055d21854d0d3922b59fb359d2425182a068af2728271b93894383d4e6766a63bb8bbd7b21d8a1ae1702aedb450d761379edc43543d46b2058430d26d44e38341a751234f41e67a1e87e21aaba0eafcabf1b7f548fd1867ed56d30f422270adba86e501afcdca8414e05346423377a42e42c1eda222323d7d1660839cdb5f5b01168e8463ea691b376bf0de5ac6d498c135493daa8ad676e316ed42008ba111aba911bf50a4aaf8e7ae5517ad53adadfedf8575adf3c964041deec479f189fa8fbd91083eef36edfc8966446e3d53d312a66da87ed56a240f95707d5415356d2a0fc9d0ee66611a4f8af8b4f1cd0fd6df689c1b62613a56f323d353d3d3d3d3d3da1283d51154a29355193899a28a594527a3ab5b4983e33994c3475a2a67fd39c7465da78530bad51837e0bfd13fdd3e929fdd3d7a861a3c54bb5504f045c6b7c31b4d0a7d4e34a4d94d2df38da42e9a4267aa2f4378e636131f99bbc6d70593cd46f4749a69349db3e6c233dbc2d2585d2d9f2db667a4ae99c949a4c4f4d2da63f99e8ef534ae9f37aa7837647b9969369b6c9f4a71ab125622f39aec687652da6af06faa63f7d21fdd3bfe9377a327da7a3f426affb9357fa9367f2529eeb15fd42aea63cfdfd19d7b15ec98b73236933c364acc1a73094685597ba404934a9492c590eb8b08f8f228286a8fa98b3100a8786a8eace62a0450d416bc0812be7423769d0c5071acec85194113444856045f58a2b0a47b3b87e9217da005649cab4cd0b414ad5e463f237a991a6f444c095f4a11cd58f7935c8c7812b46faac06d263ff2baccc7cff05ac8c56491846f2e26b13e36e4cf2ca52aadf26d21ce98f5eaa85b2152c075c4a8ad0a932759510d1a46e91db9758b6d962f1332c3a1631e98202dadff2dd0b414a955e0781f8fe4a7272aa7f8c3f6ba2fc183d1170955fc6e5c8b13237c40f53eba9fd60f8402528c7e7548c9f8a1f0c60c53eb0c6ba398a1adc0f63f3ba264b181939b55b45ce4860f1cb555dc429b47fdca4417e05f1ab8859602fcaa2b6bbbbbf74b815cb8a9c0e6affb7d8771057ccc4317e2de526b91f55e2700afedc178ea0ca0f73a8b2480957cd6a8a9c45b953b888817048df7d38d5199428d6d2c822f9dbe424cc187c4675eee3d7bef8a394d0908bbea2e617bfa67b9306f9536afcb8c8bf29af7b29dc2185b529b65d39ad9c56b849351155d347fad36f5135bdc9f45d493be054d30e39d5440ac10e95e54d5ee842f5c4f22b2c7f62f11d404924a9a66761617993122370eaca9ba26c1887e5703a98abfa87386a7ce8e26138db763a3a1cd095280d16b1bca36c54934a35692696974dba08983ee9e493452e38b4061cb8e2d01a581e07aea68f38f1a6411782865fbd5d96622b8c2d174c9fe90b8154d3fb87028262ad4f1e35e82ba793ff64f98c8585e54fa79fe995138b975ae9a8a02696273dcb9ca4470141559ee5c3d96a4d9b79b3322defbfb5785c27107f8280e9571eeb6a4cbfa2a4882775e54dcf5d044cbff22dded6166974f252a77f4f045c5bbe1852a70f06b09adef4ed68303ecaf450aa0d0ca59a4c575093a97bd1f05b2cde5613cb279f34f8260f0302bbe9704081923052b7c65e991eaca6df666137aef237fdb67136aa49a59ab46a7ad3f3b296c6f4dde93071d1eb4a5f3e31b1f4ab50afc6474fe5b733fd4cd3702cef1f6d7ab5f2fe2c4528cb6f8fddac4c33a9dd876da4faaf783d1af4af6182b9797f4cc7594b3357be1064f9c2af2c2e2aa02cbff2616cc556af5ade83eafcac556ab9cabfd4f261370dfacf96f6a7af55fd513d5096af06d3b3fcca179a7ee59fc57381ebeecb8a8965e50bb91a6f889dc7c59686dd984c586c55df41e38f9a273e15f901d2e9a90cd6edc016a34f83316e3fd34535be56863f6e542cab8bbc83b05bd4d84ada5563f49e1ae3b77d1991abfcfdc659599114f241f508dd74110ab545d5bfce864669d05b0d3a76b42f1e81af52be668e1422b942f98af2d52b2052182e9f19c3300cc3b029db49f570c8a141e792a0211331113b61a332566e38e79cef1b499b2f2537777f7e727ed887f3e53727373f9c757eb4418fb4e597aaa9320854182439fb49fdc2cb89e2bc73c17f62f2b3efcc7bc9227d3143f56a16d15e6a5f6c15ca93b02d6b9ba4cc9319d79f69dedc0bdeb2b726f5e671cd45361c484f4d9aa6c92769ee1be76dbf3a3266711f7f3fe6a9fc71d0185bf53830186825aeeb2679fdd3935f620175a17bb2e86ff3e3536fbe4bafe4c794f4737ad4336d49736101cd9ef4fdddbdb00df66a1b941fe7d6a0f65c26378ce10cb990baf48afb587e7c92e7af31384b2d833629e5338de455213ee6318dfca689cdc96f5785f833cdcd3b38106ffe01b2228ca02392541b75838e70552152ab6e0badaafda730e88e99069f51f409f5af48aa87fc90fec05e071e64f658f61d591aeca31d0ff9adabe8831435c6b62e218dd1f39b18570894e37b6b5f564a6ea9fec33b23f86e8c35aacb24b077777777777777f76e9718334bd964b81c42e496ea59e6ee2e34f60931cbb2a9cda94ded9b73ce315c38d5f96d47368840e2ed92bb90b5540782752e4c8d44226d2419391ffe66d24d9c3c81f2e26f832aa594f2a7535b67c75dc79f340b73b92a7e8fcfcf0b0bc284b01d4c071b7296d6a3f5f4446955bf4d0f8e4f10ecc7c876d484f2875a4fb7546ea15ed5a8fbd3c39a0c854143ad67a832cb775c470bd769a15ea1389fc9457b94e1943fd3d2a50d21c89e950b49af72a54a8e87f833cdf1c02f64a177d103a691368d94846dce907e1aa8f2791e39e903598cf2b318b36ddbb627601f778d1cdd6300c587248907cced1db3a965930ccdd330ca3ccb32e9463e570502d9d5d02addc8bf99494dd3b428f193519b995c8ffe041afe6942bded00f3c93580c47560d030e6d447bd6a99daff3069481fd21ba1da2bac8b05fbc3880561434c58551aab423f16e4d850afdca8c12e76e5672c18e44c3841d6c3b23022cc08231282680c1a6de20f0be8f7a3ce54b069a4a0f67736e4957dd1ceca6e5c054646143937ea55d66ab0cbbca01ce93d0d67026966250943f5c73eab246d8632c3dea5c4709ae52fbf090a22b4e3444690b8d1a9ba91b3b296ab3a6badd060ffcb591a9356f537097222f464a8b606a57694ac153f4d280899c42486356f4ec49f4458c0a42e1675815880533ba5761f724b6a162afaab6dc0ae4ebf3fb3abd4eff3d815eaf77becaac6effbd855cbefb7b02c94cab2401699955fc61e7bf668e3868d1b35cc8f580441e51943aeda8851d0708578ccd0d203f53550351e156bea4d2eccf767d6de84692f5733bd9c5ce7a7bc1ae6cf97af7dc86ffa19df1a824d0387583d753202fd159e28e184287cf8a1092da00122c5126c8e7aa030c41196d0f4f3f0c1e3c6a76c643f9d85e2e12cd053df8def0b27751014404579bce3b10be7e4f18dc7365e8f7de95ff128b02ffd2a5e05f6a59f7a16d8977e2905a1f67742a8fd5c174d32b03a1b250b342a1945a8fd3c7240c329b78dd949f3cc819b75be57ec633038057fe9cd78f4e20d4ee1e1559d79bde2f08c35512e220d7a13b47fc67bd8d5a0ff4289f11ad02d341843abfcbd09fd769c5c346417bbba1b6543a56a3447ed2fc69bb28b5d93ca75a91c818631d5c3192346651a9fa5ae156200a1fa736bca2f4728df06d2ab88aa5f7aa95f7ec99e44d0f6b90c3acba0590d63fda25e6055fea12cd5fe7cec8bffca10a8736b2ba3c2be304b01acf2771b2b2b359cd5499554c3193f9816233484a968c0748db579b73b22d0b9dd1cb126e038d1832e8c000127071740918119410c4531044d9134fc8a996132a296b8413d08c4029baaaa0bd4022f6aa92e90ab854ac2b6bde2ed43973a318d657c1aeeb785a1da738dd3db34f737f5eae3d7a850b55f1d98c635eb0e06981aff06e9b962dadff8ec499d8e4ccb6a5421c46a9c58c4661a0435729f93d891cbb2ef488cd1a37377a391659c34b5ca8998619f651d044ecefb9b5a15e31781b9f557204448e909cacff10f10b6756996cdfc1f9e667e47e4bb3841e5bb7799ecc865610a7bf936a06af6a530f95cfc661394292b6107a7888d72a750ac328e140c4726b119339389884eae07078e221407066dcee7e4523ad37360d090d64de97480fc852e2fe0a85485eb2ef1bb80a3f2b72cdd165bcac64527d4096d5c6c5c608f755b500cc3300cfb4e0786615986611886b17c274459c6d8a9b4b9e3f4530e96fdcc9ed61f5041458489e915d6dededed80a31581b4143189818262b0c358009931ebde2efea025d7103b32fd8bcb82d77a30a1ace6a73e406ae21f028b4aadc9fdefc4297ba61b75cf02fe48ac1407768551c66f55f2fb4c165863a775f72b61da3a832d0939eca1f0e5e5785a29dead5b5e20847561ca1a80ea0ae1546180a6dd0a90b84c4cd0fea021df144cd7404f048fcd40542a2478bba40419c54cd45442b0aea297aad5833f2fdba842baddaff930487f8d4f4f3d28cc828df7735231a122da8c106c2c1460cc59d39c6b8bf4936e2a30689241339c4849b2c097ac924b5836044ec4b0b14ea47b5dd284883d185240912a01d1c9ffa1b6fe3514f844990254978b66edd5ae35bfef4a667f9955779fa29bf75ebd6ad5bb76eddbab5f4dd73bf3de9b59f9f7df594949d067fa635a15ea502f05b01f0fd1a935ea50490d2e32a0da857f4a741239acbfb7e9aa455fda116146a3ea186a47a5feabf4ca7412240487a78d0c40e947001e408101047b208c288881002f0668393bd58c22609911551ba68010b2b627005183e2061444acfa6f4c0c02dcdc5ca745a8ed0007814009e290728d4e03585175a8801840ce8a009298e768040a404ee60f8329797da8fa9fd329d6c470994062e882cb193a407449848e0a8e887254d280327e72406fd0aa4064144e1094f18c9208a2096880653fc600c1fa888428a2d882d9ac08328a038b982658b2ab4a0410d6e88a2a0e9a7464c404939cea23a2e9d949eda3a421ce4d75025a855fb9f38a90ca88b0519ad2a46905ad4ab500548c5a85721edd17a7a15aa14a93ce915dbd47e8d881fa15254bb0702fbd4a741ad873fcda51294d2a302d4abfd8a7c4fe4f37838b2ffb534f179bbaa593bfeed5c58acd39192e2d360bf4acb59348a55f55371a324670b9dda21fd717dd123864f193fb59fa7111a6aae90fed49f95f9f9a9ddd487fe9c8a4043cdf5e32cce074d083d61810d0e1168fab51f6701e007308220c40912a2f040a372c2128470c50f143092d0f46b3dce0a804d34fc84e43993cc73a2143f8de6791317f217cde64257ec7331f6c53ffbd8a8c85f2147b9c17f1a047d93ec8b774b8a95998259c0de6fe01a76ab1a8153e022ec8b3f477914885a2192ad18c36d312b5312eae14367651850fd4d55d06ce628551e3d388efb7cf0d07ef2e8d5e6a35741b8182a68d730c639afebb61dc76dbf35672309b4676db95e0a82791041007b6e23f1e8a17d30e00a655f087e838e6a700854c621aac859ef2123a395e1a0fc2c9395e99494dd0900d13d2709dbba842944d539078c4b0b3b66727ca56961057065500cc0d1608e66718ffa09be4b0e188a62c0bef85cea9f42e44ac056cbaa7d610edc17eee8329452468a611d4d357efe754c81e7e8e1eddc2a314143909bd6caa4547f36c1330f4133ac8cfc765f566810ec1dcec2d1aa26bdff06629cb5bd4b0d632a0daef20673e0788f864a830796c526686d510bfbb8b52ffedc19747b1db427bd0ef3b747b53833a80e477a6c3f5f87ede7a31adcbe02f3b7ef07e97380cd8b66698e848dc5d0c3f32137b05e92df06f6c53f7e4e5d43d187ab7cec4bf4416b7c1c527e3833e87ceddb667bd2cfdf620b3bc05521bee691bc9b181aed532da046d60242156a9480fcbe6b02ed254c41c443420db63793e61c6761dfbfdfdc920d5daf85d836daeefd625832333333c7ecf3cfecce6cb3f30c34f48a0336f8606e66e6a29fdb6585fdfe60785fca6fe92c9da5b36ce695cffdccb263732f3b33af30d4001eccdcccdcac854f779fd2c03c933f601f9c9939be77777777f74e8b56ac76777777d7fee858f83012666f6ef14c6119931fc42134262c753d06dec3cccc2d2d1a7a0fc334d85896833d90490f84c67ff935edc7ba0a885c557702405ca245c48e70a97677a34ccfd26dbfae6552a574aaf135be906f4e5fc83b2c1fe7b88a7e21b7eac65dcac73add17d2b97d21ea517bb4a38b02b77414220a0909f9f418e9e9cc5de03ddec34cec8b3f75a17df1d85b2c8bc52812f2521a34e4a21e37d22bba9a5f7b8f7b8eb352d99332ae02da93b4e75efb3847cbbaa2a2eaf9cfa558633e1bc73d1fbbc25977f8a41485fa0fc23a59cb1692c343061a7058e2559979a34829a50c83547e8cdff96786a228faa80d7a5e1a47396b69986376b88abf3fbadf0cca7ad82215aa8de4877d1aec7628d38440d80bb78899e3112d269270e427d8676562ed4f395a991566145428a9d2db99a5b2ccb908235ea0265ab55f5c34e75a228c1a72d01241356426b5437692b9e4ed520caa3d03071a5c3a44fd9bfb2d15ca86f88ffb3812f7711f4772645f7c6b0182cac79ed43208cbe2323436f288f9290ac57004659f059574288e06bba4029a7df6bca457da6bbca441ff66e76db99d8e1e3df8c755fecc463cd09049a8069b64249246dabe02dc6fdbebb0aee22ab03df7dca743e9a35f8cfc381d67a5e4b671dc973e1d8ef4e8bee9afc347a37d21bb78acabe4e7436ce4eefdfdfbd2924b26f0d7ecf98398659fd1ec3c8a32e7fce411ea0b2a3fcaa35e45e99504321a8dbda8edcde6484150d6483736c8a24af2e4516334dbc1c0399ffab692d13d61cb09422bfefcfcf0107f2cc444a8fa379376212b9313c61e61573dec8af4fe7d825d6defdf4bec8a7bff2eb2abeefddb8aed2cd6799805fafebeb3325f2c0b44de7256eadd756efceb605933ae7a310b32bc605933b8cabf8fbc8d8a5e43ed83daa40aa28662897e5cccc20f4e41886516788753186359ec8ad22dd8e1c17506d1cfbeb811141b8476ec4be770d997ee9f5af2509fe2d9f8ce6b79ceabf199c7f298b7f29b677a92772a5577939307ecf8cb80b5967da8fd61b74aa88dad92da1ca4c17e151d6f5dc52a2afd850460aeb6d79c42ff266da06cb08182126bb4ecd897f6fcf41b2f779b72d4fee1fe156f36a822645ffc553cdf711e4ec13fe579cb55fe37bc75558eabba75a0438ddc07afa1575bb1a07fc9eb2c16f4efbc2eb24b2ce82f03b3d02f4ec1bf5fb03f988576710afe5534d99f0e0aa2166c943ec1f6b03c3dfe6253f0cf3c0e63f9080bfa0bb1aa1d66a15b9c823f8fb12aff36a27aebf0b0447ec60c99a846afa420ca18638c31c618638c31c668139f99c4887d3446159791d8dccfcca616702c7590b35ae8f1ce7748a85f214ceb54ef560ece6ac125a6dfbfaf01216a05cf41e4dc179a70a4b0dd0e8bf504069511b3c1d68e6149f6651563fc6970e31791b86f7b8c8bb114fbb2ed1173c59f5fe8ee9ea3531dc3b8b9e5aafd6c5f12d5dd97638e39b6bbefd308dbba842a2ee6868efc3d86d2a0b351b78ca0348ba7a0f129ea4c4bb12ffee2a17df1df98bd699366f150afdaa64127d58756a654fd575ab46fbab532b2fab70d0d5a990790be55db31f94954d72dae0ccaf5c7911ea5e7fe47f73e3fb82f7ddc23b5263521b91aa4e1ca794bd32e387d4199e8e3a106ddbf4b83665fe83254fdfd0b637729f97599c9bef877e51f9cc0a0f1a3d346c595e9483370a2b7777373eceeeeee1676ccec88813182865cedeee6ee9e41e597c3c4c064589665d23399494c4a175a41a847881f0686e805d918421b0f0ccc11181821e7620899ce153cb002c7e533aef2ee990677f463df3b7c4ebac39b69e107fa75fb675ad8e13ce33bbcbf981b4cd09955b9035de144dd57cb072f9b05bae288215c573021b32ccbb29719966599cc64263129877c388b940433fa21922e301e03e3de5f88c1ac00131f6685188789110a617cc81073628c31020135d104a2e8313133dd63c59398186984ac0b048485154208c1c0c000150166889c1ac210bdc00a26682d36ca81618fc560cf2b4c6218c68e31c692f9830117ec6d526d6892d3847f818074603403525d20201fb8c6e79fad56abf5a2d98fdebbbb4f0e51efbfaa06bae255fdc309aae1d768a3521708880910888f03d7a1187773d4c4ffc1d6bf2edb4a0cfb6463edc50a9a4812cbc26e0afb855adde995ab5711db2f94462a3fa9618eba38708d6f8357f9589661d2f32e36ba2c165ae0430cae28c20d5a30647370c40f556c5146165f9021a407165811851344d4e08c1aa0701405248660e20845d0ecef0ccd33e9dbcb7e4b2912abea0fc891011182e021081743408e0c2d41a80b220c29e2a2f1079754218ea4943a1d919f8041edefa6c344f707d100021ac2945ca743c6dfd8004f9ca0e7ecdffe1da8760110b5bf85eeeee6818d1abad417f21952dd2709d563e053fd2788f3440a318a7ed881114ad084b40930be20a2051948c8a1711df820c6d49083810b6a7fff84c151edc7681d9aebc5125374ccaa1a72403068c9a0f6474a5bb0038e571e03702448edef224a485e8da02180dabf93b21c81088d3a94ff47839d43831dc3aa96b5638554a8cd80f5c28611ec0b0958d5df44781144e521877de9f8818086064b37b4bb9b8a8d99c82e3333739432c618638cd2f3d16005bf7afc6ee0eaa0f4e16588710a83f20d9782a0e106ede8957f0c75061fa51b9a4384b90de70196a57d367c0aa8be32d589501902ae1ee84a42a0e106cd492b96ca7e78d0e02a4752e7caec6bac12ceaa25d9d659de7f4447aaa64af9d100e11dbc8178f6733ef6fd002706b4cfbe1f8f2a0181ba6703e9457b5583ff3a81c03aa931468f46d209752798504317a01714d1404e3ce9adb9a3b3e7a0f68fd86af5c05efb7e60f1495ef69a87f5207dd6437becfb411b08b43f6eaf6af8e6d26cde16b9e3aa944212bc8b7f357c4bb16d33dbb22cfb8842513abf88b187b46218e6dbced8caccb8c35fcacf3029a3ec7d2072876e0c882d5553d759d8d6450a1f46926465a45819edf9b9c5ce4a796695e7d60c458f1a5aa130467add3e2694df3d8e6241f9525469c50ca2c8a23a3fb1609c810eaa57ed639f7d914ff040c56317edf1114af138a7a4e322e296ccd9615b4b54a5eb9b89ec5f2435a605b734245a48243d907c03a09e2d94c88191214724c0880b2554b898e8c1072430243b077025ae248898f0e9411744f82062c28a2878900518437a8021e1a2f3202cb20c27c606b304748375b2472bb4456b644691a3da3f03f7e4c9ab9a53a9b057ad4c4f1cefd2a9e8aff65af6b2dafc98bb4ffe17b708f74dfd1530491e08a82721129a590c75a2c2094c68e2a48a219c008292239ba325a4486206143dc0a018f22ca000d2362437338c6e091b14251c232c892cd342f208a10981cdecb0c1ab859914c848d3313698da8e188816688736dca0159a31838823123261a1a11e87d6dddd1bc61458472aa070015ff19a6961470cdd15320809a2074149b430028a0b46454c10c433468e12cc2815f141112c844847d874f7ee19a9821bbcd8480abc870f338ab080870a82e07e1e3e6e20d48387509114dcb8dc20f6f021831613823f2975818ab48894581474d69d0951f2019baf991676c450629c319a30a3b6898b3a7960c4b61bdf53b07ed9bd71af7ba93faf40247712444175bb8db8a76158a2a0fc2bc4b5b0cc5dd5d343510a7e0c8cb763c6070f3ee2990217171dd8b44cd2c415958adaade87283388568e2478b41111988c10968c2c6323803a3420666240093d151fc09a821aace1a75819ad069e2a69211638c7132dd171aec7651d821c48e0dfbe5ef855d4984aedc1455253f36d4db953bd92fc5e89c40f7dd075f1870fb1878f4f021c30c2290b506edb95f4f04b2a2b457f1b4ecb54c7b945783ca6f9c177ee5dec687f3c687b47229ef8667c3dbb68361dff42d5e0dfba6df6aa4d152a3e54bedd8daf22f6c6df96a7ce1be08b8b67cca03a926aff45b7a152ffcaa42bf056cf9c259554c1fcb17d215cedb5ec5db9e7a295ef7db95beb96d31685e0f1f0df60c5b741a83463faad1138d6dbfdddb14272945fba510f5fba4be2f7ab4d2a275660525bb451052fc402a7f37eccbf7e41145f977c7d0cc7da518c9305ecb9c7dc83e34dc29df393ad8cbf80cfa98dd47b96f1da57dffdafb70a221a2a2a30de53dedc3bb17c0af7931ae7a4d2058cb1a6c9b01ba5930c148166844a99d05136e6a3f079ed496ffa578cc99aac0b7ae0281ab7a86f9d91fe981fd38d2437ef6fd904b233f9cb27b6952f13b7541fdf3d1600b89d16c22825213ff4daf522e74dd4fc15023cecaf0922156663fd6c251c02cf00e7ef84f60d01c6fa37e10382bfb52f181d064ef9f83b3b02f153f1e3620c8bc98233f8ef4c07e7ef63f4057f96b3fbf1f4750df8f2f9ca9f84b13847d29f9a4cfbe94fc5218c85efb1ed893be1f47be1e5949091247a0f00491568b86667ea9f8f170d5a90bca1f0d1d1a9eb79bb1723fdcdd151a6cf9c1c4c02c26310c5bc776777da50c78d8567bf5d388c305478352b2e4147777c1d1bd8063f246234a516012932b4850d38a0a4a42b0172660ae9164db140fec1750654dc56c27815e402df5c045e0ddddf5f6bb2754b12da3687309367289888e48a2fbbf8c1c3dda28d49cfe8e83acdd1d2be6e14061f14bd5c4ef06aee220ab03914f6c5b4a77d3dd65e698690746e909139723658a9429b6f404e52897a296774b40d07d1ee37406ddd7b0f81eb675e9d9bd44bcc5ee2ecdfe3cb10dc7dfa493eedc19e8e4e6e4e8a4dce29cca41747ab533638c31cee0ac398926d19cecc26aa0124dad6e4dee6917111711ee56ab5d2bb355ff26d2abac8d14adcc038c889c740448f3b7df56a42f457a2095f4913833681fb9cabbe52d1eed72550e757d2e17512721ad8066df6c57131ec2bef8a3e8d357cfe6fc6216fbb0ca37776f6f6f8f31360a8c627b8991fc743b54861918f376de807d2659462184dcdd8944a9eeeeee3232333333509d5f88ca3c1966680e34e8ecd106658c8213e28b73f8b88ffb7410f6f5ab813ae60524198d7d81f1296ad07ba74157bb8ffc097411a8f1dbb60a7f8afe66810327bd0add55fd3d453f17bad2aebe5ff84f9266d9782b0b9b2ec7055e547f177226afea59f5f726bd5aa09e56f5f72267358d3fc5d85d37d5df89f4aa97b8e0a73a16d59f99b9050514f57ee3fdd7597e5d25a4361efbf5a71fcecee7eb5eb4ebbe195d2925f61ff77982fb141545570a060e8154fef849836174458fbcb25404f533cd99416dfc8d0fddc759ced8afcb22a99fe9d4f763071a94cb534adf2f67b9cfeb85721f97abfc493f2ba96be8fc0dcf6d785dd4f285d43793b756be907eec2e67b98fabfce72c4557175d3715558b62d82f09481ad4e74228a0f3bb21d6b075769ac5472824d4bf45090a655ffca5b752b76334f6c55fc698008caf53a7d4605b97708528e2282a2ae2228e3bc5dbe9f0d7ca74d5df81566ea29841539dea8ffbedd3e9d1fdd67d4002a265a8b40d5675450bd5d00824000000c314002028100a8603229168301e53755d1f14000d869c4674509909b424c8519442460182082000000080008c8ccc8c8300448f44af525c8221a0d932d084750374e480a204d736f41ffa175aeebf73b4e3206ed60e7ef2f7a6c4ee76b23c92a64677fa1f0d17f8dffa86a852d8eb0dcdf98cbcf04b76bf09177bbe69bc49e1fe70127c3e34a02e8a674fdd21bc0d6c022712eb67bcb6a64d218e1aa8169ac9d225908d702d4fdb68999e2f1b140f43fa1804893be9e77cc2d50502ea7d89e12658976b87d3156a636f75bae9be3e187dd4f527c26372aa34f7f9fed8f8aa53767a1cf3a0ddc37462244dd8e551dafc7b60300ca7a9df07afa6347563b9cea0118d1d26c652f8aa87597ec330fe4b1e56a56ac1bb110b302608a21d15fecf84ce455b481c771c7d7016d77327b7fb9dd03a2fb90a3074f0c78439415ef35aab8d6fb92bb01be6267aa8754555161e1cc509ac1c054e6e775d6aa237ef1a73537ff85d51d851953ba3efc9851e624e57a7cfa1aa3eb7ad945154ba245b21139a883ed51f391e45f34d442d0af8e9f8343a8afc04b7157022c29ab5cf0f52150ec23a8b370db26e5ab40f92ad13562b24bd106b1557da788f2d79846ead9cf08f98268daa7ce9c188b8cd17416e34b717131f3ae4b34c1a414e2ca14b4ff3e5602ff625ac962cad4a794fcbf619ddbe14b9a17a71ac5dc7fa847f4c7779ef075c1aec2a11c8b871ebc3fa9f15ef8f264020d8c1296231503f0e1da6a3aca0c2ce64ab9a8995be244458305bbcd7df94d5cd491bbf9b3937b6f1e5741560012c74b85fba379d2952ce03fffc07a80198da86093a6de6c66794b402a2a3f6ed21fd50bc695ed2bec038e4228476b81ed7b71d2bc686b86b3dae1c2bc4c746fc368e06cbb806366c94b8eaf786d8f170dcd0606fb96806e4ea1782ff9b69ab8fc36c934385787100e53b4a1cd3972d4c7bdd66338d0aa2a8726b962dd1e17bae0f7afc0caf89b5d77b184dd9cf17b060a8e3809cc8ffd83665bf5a0ff383f6e85e0e371c6a968f704ec6007bcad393cb4e7ad6e44e0bd729bd70a91655220190267d386b01adc4820413dc67dd0ea5b969753fef8892cdc82fe0ab828fad7d9d9b6e68c5b3e8080951ff1cd1fadf2ca6c1136b119b76831fd4514734030b101cf2483f96689c84b9a3338de63379ddddd205fd522a858cfdc21bed1d0cab5371898ae65f1473e267f82f1b1ab70ee6745f3d19ed0920fb7fb927a117602ee46616aa46d715c6da69063f7605b8c4f556ce1c8f5142a9a1738bad9fac8df8c65ca8571904ada97da8cf246540bcd3b3c4812d9e0299770159d12086ec491b3e9d6261d33162460c374405ea9b02c93022fbd4a6cc1bc5ae69bae4f02ebec50613dc79210817668977173621f703fdf7503cea7729681e20b961c5231bcb975129ce249b659d195cfb0bccd7be88de1c6ee29f63f70355d27ec8fe7f83df034146c58290997bc90ab5f7650f65d538bcd5def3d0069e5a0c7e4e2e5e260ed3cb8d2178ba47d6c903a0b386e78bdf457d31cb545b039349338f6d537f346a6db35919662a33c25edeee32ac248bacb8ea592d8008435f967ee2eca4d5095230e22b7abdb4e45dcb2c026a319ca46c93918e00eb5e40938fb0d01d217c4eb1604d4df4cf282abf0bad5ee321f2ed68099d4af675b2c65a751bc9eff78bf5085c3cfad63290d886ae879cf5f65783c823ed0fe507307bcb06a0ef00c88483107c739db9db877115709ab33b55894085db91ee8814c333af5c27f9d5c9a88460144b9314423e6d690b2f7ef84f7b80c64e4cc3e621642e60d018c1a38266770bf674c47027d5d5fde1175e47c4e4a0b9ee84f41308fd72cd7f05b40f1ac744a83d644476d907d14882f927dcb285d840d012865004c08aeb379de3628b9a449c09ae201a70860c9fc77eaa557c9d0abb3807cc046958a528902ac8296151c01ba5ca006187fc4eb7cbe721bae2dd98ec1378fdf37ebeac34e80638d597c207ab19cd807408c598a7c070286740fd427e45008a7dc8c125f8c991575817dee09f8e5af93d40e5bd50078d96d51a0b7393ae923fab4575301a72cddf65e9a33e441453418920fbd6fce029171438e3eb66114a05c37714eb29d8835b10b1f003888028d638053dca29785666dac1a805699963f4c16fa62a9eb5b28f31cbc2d6428345ce3c6d5a78d21413e2c93115017913f41914ca3cdf63c30bfc61b4511e3bc4acadb4ec48e86ac8447b65c97d8b533d16e5f3bae5446bb18f0bc2827572a699010dbaf7b18cf118999c80808a332e85baf5901046a6142168cd92aae870ef80af9337e802f6875bb5635b2c0cf4ed00b2bca78732992b22cef88012305d9a17cb9d5db797041a36a3736b96ea34db421a4caa8fc4b8a503856c995bd45a9425018aa47a45b8d5e8a7c87b2493cc5c620f03be2be3d15b7486c4a5fda07b95cd59d5e44ce1203e8a3f032509f917e3075d58d1817ad7af0388ac18716b528852d50e587f2d60130b30983539f2d88442836bf0c65847320fbeda9a9cd3163919644d10f57f8bb6a26145c7b119493a18bb55f37e104fa8e66cf580e93d5df822d80358660e05d63ae933407acd562e28c3b1f10cddf30688fd66e58f6285f359d9a5b4795f32ff2dfd807c3e1e00299b56b6bcc8d074e251a3e03e7bb4205495ad1cbaf9962f7c20df7864893d813433b6b30a0410acbff6a102242425c470bbb6804967792d78e4212195534b666598238d2f6b382351f2a6014802b3961fbf744096bca756ec825bfd167f86c491658ba3af7acf853db8199f410b08df8945fab3dcbb11bc6667105d752019f5592770e3f1f9ac04f52be202a279a5c5c02704ece0fe88a5927cf88e8f02bde0a0a673b3025cefc65b9e9069f46d42a22f5010afcdb8c0750e689be2767922a2607c625fea43acd4cec5dbadff383ecc84b64b8a456fef3a06e4222fb1f19f71430cbcc6594b38b94a1a0411be08589bab0a19073253979be23c11dd83a24873c3839cc0fa695ffde7a59c1703a11e67f1e0d429fa1d7c342b90c17fb149a824eacc5c57531ae39b164194a6aaa4f4abcfaa053e26ca05a220fad5dba8a3aab63d4c038e49e770afca7ba79bbc196a325c50888e5acf06be7ef4818b02cab93841b77e0534feb9f476ebe4f52c559fce3a0e586de095c287ef83b536c07d2556ca5451dbad8eee92cd137caa3f10c4bd9bcfe59d6cdca502bcb83777bdddb16ad5bcdb6ecb28a52898ad60a2015e4ea27d074801efd1508a183ace2772d67b3698794f33341b8bbcd82a3d76f43a84dcede267bc30fbd5145c108b45f01b241437b15861f4e3492834278f1dbe2802ac9a3c3191963f315f1ff665f8d716d9f095285994268079bf733eba59d422df25f3b855c9e398a37727f585c6c4fbc97829c6a20f5a8170530bf72428a2fb168e4056393be16077da1487f7cb10778ff74adac34fae8d459681f17093d7c5ddc2b414a1c52a093f247b8342ec309efa64310b614874e4ce23c5c98dc83f18f471beb4cd4aa6b0c563061694dc7753790b24cae3e9165d8ad3fddc64529c74c091df5a8e5cc2464a664cf3c8cfe23a7bda39a3f6066c4a37caf0468efc4ab828368430c9e1b58625acb33e7ff62f8b362b81f558c538e618cec9f100670dccc6198e438684992541f1812ce0519ce7024699dcebded4aabac8ac9611c0cf130e26e75d30ab30da3bb747c416a424cc3c40cdc16073925d8126ee328cf2359b1ea0136ca3dd824c072ee420410906cc22995498d638ac01a6da1e55f0143a405b527ffbf41df496178c3564865e846665cb230a05e8461e4b9e561732b88e09429a88ec466daa859a46a87d1f0e073cc2f671dcc3f4bd1c9baf7a481b919f0cb7a10179aafd5110290ea9e474843166cc1d986489fc5e6c909d946b6297122296595e8e0933c4ad297dc9eed116c14b821de1bce5a81afbf3eaf507f3d9d9d564416a83aa7ea4e0903563a2456ebba23480b97246dd81d80bc7b81dff3d7eab93b5e9353edec45d23f897153d2919e3a7b6db359a27d7f01ff3f219f15bcac9eac4ae40a131d3f66875f48c7efda4e8cb39eed1ad23b617ea532a70ffdb9b285dd6e5194e192f22f4b74c216120af4f3d11ec7639f2e99a05bf49350a4421ab4474b38ce967990bb75d331c1286d6d957b228a9ca2b73f3c3a42d4d5784f35b202f77d98e75e7bdee526590b931fbcc8bdc1638d4d4434f9631dec00831a19c75452add9d172a8dff32ee609cc4feb62bc4a15928fda3ed9deb2227cff0f62b9b9ef0d7ed0bacc18d533d479e9c417b1b84d9c73dc5883c9c50a88ef124223d06684487e01125d10e96f5b9c683c69e75804b29f9bcea0df213bca30ce6b0301e13b9ca9bc85db65df86be2dddaf7fe01560acf9b5c4dc515cd2ac81a27ca4a3dbad23b785eec94ac85581f98ef16ea78cd15e29388839dd7b5b54dc1155e71f904cdc9f8e6f4d150efaf768fd40a88f5a72f2ef86e24283852c3190cd95eccb2c42c1f0d139d22fd9fe77e1ab18a8f33a1be35b9d62a8f5d402039bfcb0c820a6bf2b5a85b0dc03ca94ce96ad07f951dd914e29bf5c5d61dee407da9cabc11b0de4db8ddf898b3be0605ac4601b26ca9d7d13c2480b55511346270c8ce22d6c46282d67aa07a0630e7b408f1bcf07c11a7942b57687e6ba863bb500b7a31dbaa0b81d9445d9ca76e8830776f09123eba486c16416a3b35caa3b718e439b209106485d6f77bc998b4274e8b909c54473072d4ed3be8f0b7e3d0567ab9ba1ee17b50af64c53887e65a34e415f011e770b73bc614584933900daaa9acbdcfeeead0519d7d3a21dbbad22c4da4fdbce258074c1004e3cf870e10df52a6b7bfc0a21d65f544542447dee6dd2524fc67b4b24fab7f5bf9523701674d7005deebd8d1b51bda03bc39eb83b6ff3572bbd1a328a59b6043a9a0914a0746dffb321416ad814e975176b446cfea8bbd4dd452bff026e0a7349dce5f283d8a11456890f71d2a2300432264c0c96f319f6a9bb803c52e3805fd9530381f02ac6cea5d1206418a3d2c4679a5287ea9278b58cb8857f1cc8b1aef1624f51aa964121fbcfe23447d2d1844084597c48c216f387b626095ad551ac1f8a070cf28ee4270617c56e5b066ee236c8b0be2153d86880320108e0c386f10927a780adc2f6d66daba5473a04c6600928f7a903679d338758f07e334218f802c6491e3fca36efc6fbcab8d65bf620841db304ccf2a0e5534625178098f9ba8fce84baf34586901f8c61b1f9617d34bf4ee9459f5c8729ac7126562b966378615775f5c898288b0e3e4e1eab027f316c6b03f80cfeda6d2c4237e7bf29951523191a73c08b827e62d14386e469614b81e384851627873d14043e264d489fc3abac3ce8d945c325bf6f92d8bf2e0c76131c2cba4edbe8c41a06ec951b50bf63123ef48f27c5ed10e40f3746dbeef71248cc12a1216d2caf9705dfe4d2fb2a42a8f919c633dcf99bdd3bcaf9a45f25bcf5513f26e64e6def8b387a3f8d821c2b792e3a662737b0f1b7609c24975137b3441692f86058dbd88f927d9af81d57c4c420e615c872472a24966ba8e78c56f61ffa7a52fa91ccd59e9c802243f7301c381694ac4a09a58714d54147045f63364f1df2ac2cb0eb87f39b6c4f1c3b1e01edd8e802b81d0c80514fe060748a1440e583ae9e3cb4ebf57ed43dc118224a7ea4da4b6c8a2cbac26d41eb13ecc62c4d90751b2f0120a4ee1d94596315788bac9045ddf01054b49e437551429a36e7c400d7bd0806e8a06a10bfe2070a194a91c9d31ec467c8b3fb7dfc6145ffb21f0f7179ff8623d43858378297ce316e40b007e2cb548b4d53a18937619289234caaabc2844ec93946fab2575fee23e47b409d76e553a43f49e27717a09035ca1e26ddd2344a7503c46dc77b709d05f81cc64a1af6c1d14daf849f0f5f61eac713aa3d20869274b74acecb4eb30cdd5341bb5e9cf5c7bc33489b31ef97853ecdd447afc4fc35a722dec81e42a12115047f183a31b760372e4f329beac4d62692ae078ff090bda4c194bfdf084c0b663d1e99cdc293807ff0343418552bae700140183d6e6f0720cd035bef0afdffafe18e9b1cd5b1f3cf8a3c2dadde4eddcaf329aace24324b929b0c4b6c84f60de014878922bcc0e7222fd4519ce49a1b076e46482aa403b42d25632254d6087d4abf442f267ef6cc229a130acb193dd5a42d1d69e6671da949eb9be17bc5d01cb84a160dac1348914de51789dab5dd68ad93a698610019365637ee8e7c3a08dd50bdb7f0b0f6a4743fa09965f3a4686412de948a9a4317328ee7fe51146b456dcc39883a6c5293f9961bde80c8fc2c0a5eb6e645da285574029dbac5c22538e2211647ce06555770c2a9cf4c87a5aa78a0060fd080079661f17343cdca5a8ca989bf7c3279f730be96c4e8acdc7d850fba4deba06d20f25120f57239964477cd81b70c9db16e30acfedfbfc05fd0e6fbc4d09fa543ca13c76ff5baa71cd148765422bf8c27493163d100271c66d28061a0380abdc8e630ad0cfaae51f450713c9e1c1a3d72e886839ea1f8467bd6b63ec4344ac449bee59b683e5004bf8f5e854be6f870ec91d8dd72a3dd62c0b335b79acc6618acb38b8b57f5786bf5bca39455eb790c987b4b0ed392040f30228235e091c7752b13ca45f8a88cd4a165e3c9eb892c78733c119437d0d4782eddbe15a9040a476ddae17d6a23108cb25d15177e0d39c87b4e9a16dfa9b489aae90cda6b63aa1c93f302272018f8c5d32067b38f2dc548c1e976de4c0ceb44d40ee761f0b6cae2a95a90fbd83e4f1dd54058d2446a0d0c07505a868b6314a7216d95d80a86c4dbe7010dc9e6a2015b3e51ee1615aa5cfce96cccfa352bf8d628eabd0ad740f5ce22375ec25a3a2b4469fc874efc51e847e21289cb23be68c3901efaa8407084a92f5f14190b75897a805950cb1c9013193d35652b03d59b81adf7c171b03a687994447de98e33583e518a76e83535dbfc930d14b687cf0257967cb081a42a8b5e8e175b9e043c9faee74f12589590604021ae0553943a8fb5a5a516f3a12897d145c212f62abed49576c2ad1671cbe5c34f91ffe25110aab525e1d05d6d8bce5c62d576364a01f1c620e4706a3c94eb7eae16b3134e95c190c8a524c5ae18ae268229648323367029c36899660e64f815ffaa688181b30afb7149648e0b02666a19e93abd34bdd539842c3564fce12b1e78f8ebbe815cad2d67d8ce38f0018ef56e048e46f3f27da5359e8e364af9f9daa5a061f5c99d6378117e0b81dc56f0538a1c8f664b8983451c7809206b6fb9abdac266013ef89cbc149a1f3c1a0c3a47b1ec0a75b6b4257a0e7a523d83b7d00f7ea61704d286ffa7d02f82e36ae3d01f4f59ce19f6aef6594a028fc832f23b72596a6ae68c672add67e13f0bb8fcbce58360e5c9ba0cfeec7bde31739c86fc1a98725741ff9d004e2f06bc5a5243de909a7d35f90700f8dca72c59ce4f5dd9315b3f46a146cd8a761df8a11c325d8b4da9d33e28f84bc8abdec4eb1a2442b94163a939132e47cc7e8179ab0f5344e19667e28d77c2a10ba4477c48558ef24b6e542ea85ac7b8b5f5af48b5bd0bf9e4c7b4f04a4e8e25cf5d3e969d44ac071340049011fc02eea25dee63e53d929e2654cb4145666d8af1e92971e2560b40ea7e8c858224614941d531021afb300ac4e8bf7967cf510d5f54e00258f57d5996e8f777a04bb09e2a40eef36c426d1ace2df98394b4d585cce5d1352d63eef02a3cb8e7cba827a3bdf3bf903bc245e95b5b6a7053a1f5198fd1508fb94ab05e45b62205f32ed04b62abd10201179709bdc3cf144867dbb8fb28dc1d7061efdd43497f163fcd410ce04d6e0149d9607aa9cf23f75103b8a75d7513a33fd24ca2ce40f28d85fc3de2a6285eeda71c122d95f96839c5bd520180b97c4215b892c66f8f7eccb5873d820c74e4097e40010d8504ddd7fb8688b48a16a63a2db492df2a74d6dd8fa15b4bfe924921024f781d1b1f968761c57499660483b84af130116b722e8daa7e680cbf6387459ca8ed9bfd40a259195f2516400a53387d67def8312f07c71357c9d5adce5fa5889faa493bd58fb5086e8ed698bb80c3b11710a5b9db02cf1cd464a494fbbc0767a6b07890ba56619ef2d7654e0a57c0cb55346042767aa680c7b6025affe97c06b1fc8790eede3fe5d0a047d2e606d2a793cfe9390823eb000acdeacd281f84a1844a6af62a0d515f5204e73cb538ae55e315fb1b1471c5422161a5440b2f03e492b48e50a65573c8072034d5461a8c5fcf76f4c64f596e833b98c63752096ae21fc1b15051e3653a80005c4d7a6c7dd3b323ac16d0231bb0dd2588a477a74252eb37a0ea197e996183a3584770a4a6988e87ad7b411aa133ecf5318002adaa601061500f1c266246a41b51268d683a6a79462c461275b4370c11e93d1a726841ac66a64dba1254ecbcb661c7cc173c7e968b039609bec35f3c6d29e31e90a80c403d698e9aa60eabc697887bb54b80481c71a4a44fe3118684b1186b129843014b34c96b50b47eb2f414d64ef4a4f696d90530a8227084cdeac2b067dffdfb99e55a1a4d4872d76bdedce8e51a2c828a76086d4ccc8fd3071ac8f749c86a4551816128429cdeea527bfcca5a95072a01a5172a7de86a195681b173b3a0573cbaac263b1133437486fcd90a9526f815f01bec9407595c677bde82fcf90cf39ac8ac2087379d3cae4c9fe4459619773722c6c02ee11885529ba8e3c31a9457f739b0aaff6820a6c4e3f54902c5ac0a5730c41d62359ad2788ad547561ec130ae333c6b8f9af558a4b00de3442340d1695b20b3f911bcbfff821aac4bb0acb12a452393a1ea9004eb3e143a412ba2f5d59dc5b6421faa78daefc6ed07024ee3805c73f5aa8ae2359d39eddcf24044adc28f9791e0516017c29f7795f2dda37a880707898e042ef7f6338a2e15c7cd2549a0eea31d2ff69c0e3492fabf0bedac82f86f91774c9ac8238aab35f24dadc0e822e98d840968fa1693720c60dcc7e402059104df90ecefc3c93b4cc4679d26f647280e5b637ee5176eefd814b10660d5aacaf12067cd598569f36b78a3ffbef4a31416678cfd3712bab145edf1d7fc9abdda21625ab03484b60a6e582c5b2d118a387b8db0f7b7c49aa6ccb484134ecd4fab0acf9ee85903f5a24cf8c5cbb2d02d17543d805d901938ed18ae4445e1c75103104848ec22bccaa7e80f50bfb7fd4b795fd42b532d3e2ae4edfce7935582e78b1534d30d5388023f746060f864d76d2f63c20f4b0e4f20db658c030bcc190fa09c3b76a0942e6eee5a6e5b8324a073354a98eba93b7e806e4f06b5efc0c481996cf777265d3166ea40155bd95fd29c6975b7415ae75ce4e174f9a681844702d4745388603b34adb7d7425276ecd7b0dc88268aba6f5abd067d731cf60953ab16ed0bf8a640498fcafc5631cfe4c1e06784d5ec7a2535c1605a4ef2ca8390d9e803e987ff28538847755e26f12d2485ffdfc15d7953a90ef3137c4aa574558a4b5ae110656407e6d847b9f162987f773f564891f9dafa19b629ba65f3ee93ca624c7ebad721b844feb54ee1753aeaed56d22ac0006336782d82c4828bfd547be151e27e3dd333f0e6fcf3e6d5e699351aed6e20821d537b44c2146e7255d1076c485230087901c024587988c039261e2ef3a267e7b212f824c08c9ff40148269d4ef76c58bc5ba49c6f8c3a2ed64e183b036409df68005a4f23e1cec651b5cc5834e4128bc608f34aab4ecae4254711c83eacd8a8643c9b360c9f391bc1f83fa35e365bae32998f08023b6abe38e033f4d9b310d6e9b27031f7132b68a0f76a80939b6b8f72a6a3983f59e50a69553bb4fa4a0b3a740679347b9c835a26156470a48cd6c359216ad24fd85b50e2757fb8d922e061dba0d3a41f203c5905115128128e744ba10c4e5645b6131514bead01355c79168cc3a0ef07714071259e9bc850cb33d7456ea125aa979b6e837c15c24cda42e6c4fb80d907a0a8514c99305cb26fa14954e2bf15a4d410d4a209c3be92d872fa847d717d6605ccfeeb54d548afbb98683c4a6be899540d6bbd32cf48f5c420a3b96880ab5895bbd5d58c26cdc32833b95aad42dacacd482c86bf8573863a2c87c5415b9bdd7fc430a64330a2c0441e4f530de763ac648b457926922838c90d5a000524d64fc4e836c9f78cf38dda47e61b44f2cf8b5efb65351156e277c7c5cff7bccdee7f7e9696b00f2f66397c3734c2bf56dce6c7049e6ec6734e2287ae353a52d4c3484fe3565b9340ba31b2bc5ac6da184f5d02ee0e9b56ff98ce6d22f6b977b032e8ad2e35fdd0360214b7bcf48f74527de45344505f0038fc34199899cb6248d193c4c5f5b7e4aeb46bfa1d716f7f459ee9e4c15b46a0e01160a2b88015d0815ac1ef543f6ae7ed136bf028e69a6dc1b1c950a789aa67e1c2b95ac30d44812b01413c2a11702f6482dfce673aeaf6b3e865107af60c5521d193969ddbc9fe8de4aa105d43196dd87448953d4df0048311735d4932f6c5665e4638de439fc11baec13cb7da895faef6951eecaaa041d06c4321b6969e47d9d177109bacca48eb042174622fe5c119f9bd27a0f2cdb5de10b2019239bbbe040853c2bd29b395396df681059bde67b21c22e2556b5d4ceefc09aa3d44afe3ec24a474754c037ce9c9360e3ee35c568855565673dd01840c4b4e0aed3d72b4715e73821df25cc044f93032e7c53304cd626bcdc8b49f85cc466720a25768eac888bd99bd7aa092f7420f3aa91d2d2bc415f26e291cd9861c03ade0e38cb3156439a86fffb82b4394e0734a5b114eadee63e45098af7de8eef088679711ee24c92dece78e3785668186c4bf407a9b979858659c3c4ce9048c951e88549a8972037558db36c40ec6014199b8951e31c1a6f2b4cc00774f5f0461293c2b2c0339f201b123209dfdf549411e0d73762535b9ab3d0b83fe4b3aa0c754d246899c68d560408493f834598fd15beee6c65947817ec18c8ee4902e2c848655004d97d6b6abe1ea9323e8672a84ec10b7687e570f5dad964f254c595c68e9b13107e68eb824d6856c289967b1348a645fb0b6e35deb453ad8914d63549c0c5480810e5efe3f5611c98b1491cbc110e74f2996b2467931543ba22b174c27a162e7668c17d3a33b5a4ab73dbbb4ed8cf10af6296bcde0a88464bdb6c79d5255575bbcf261077e41a4f27e51ea3665a1c1074b07e198dd2fc75825db6604013c542a4045f208dcaed3f12fe79d2d495a56edd06f1de86efb611bff84193aae33032c03b39a446a2e165d9d51ae93ab45a13b1c01e410877fc438d94a944495b3387236e79387be3d520af6e18ff188b7481e79a1e13b1763247884975a0ab07541f2407cb97662ff5828b34ca57547dc8688413d3eb320a98019e1ceacf3a8bd15d45e1285ad43bc962bd17829be778658b32a46f7816b7cc619e9722562084279fb72d7371a2112004408028d6dccf8d236075e9f530d824879c5efcd40e06ac4b209063672a14c724911c5e4dc68f7a41460e6b265b69911a2a3e59c4a52850b763941c3f696921da98d08bec293040a5bf41b4d99288f5502a650f48f056214698b274a16b2882aa018552f50bf13b061c9c6360f9db0094dfaeb405d87b48b78087ab0d47824d1ea4629fd7c03494da815b2076fa4d8a744d5f4969a90b7b8cad806d9b609bc7bafc102e31c29f58cc7432c5c986d078f47073815d4b9fd7372cae2ffdeb1289f236364233d8ae645361c95dce4b65c66af2714c1de3aa9b4ad77d93c2cf2e7bceb2e1edfe2da023c55d3d35d3d0001922730bf336a0309032223e3f24a5fb6c927c88f98bdcc77ee7791ead60a681f87115c1eb88d26c6916a5fec30ed504dc2040cfeb13f4f76323a19932dab490d010fa0e9dc535b6d9bd1025cdda2b55862384107aa03bdb4d97558f2c955c9b08f0538000f08600253014f55c625359018495cc4b4ded078fbf6c9c483a1c99e759d380f6fd952259fc04d6b13003867109d3c02db57945b1595374674fa0ab210cd3e7fbacc94ab54073342ef5c67d6316e1aec5c39d3df4c36a2ee090f0b66fa5d0fa97cad4e4eacb578232db9d1a51d8062fbecff8f35f22eb814416fac60504708c801ff5ca04cf7801c69f03e788e131135a645bd9a27b5c91d9fe3233851c6aa51ad75f8555d88c9ceea4509201aa210f2a39656ca7d42d340e12cbbc6693fccf403108585382d894c60006df421b324c83e50f7f92d59e52f004ce7fde45919a7da77041a4937cc95c9e97eb71c65c6341dcf07935560f0bda2f8b81c88390ad762e2c04a1f51f28fa3a8697d210427e8530b3d4472f62d06c35b5c793dc9c620b75b7774650106c897d90b2e0e705ca61b5c3e05880d24f8d6e7f23ab6ab0aadb4296a5ccb1c109547a6185b57bb48132e7baf59a59fb5129ad97e4bc275d5d294ec00c74d267f19877388a5488efc830f991c7c6eee43bc6dc2228919c17716e43a833bb0d5aae61d3f5e466c56f99d718757440aae550a3ba2c845e91799f53145718172bf67c336ac82129b51cf56f6f728ecf07c75c183f1d944c597184fd8c10d99aee38e3d3b18c7d416594e333416d1e916b9613431a0590ec5dc9a818fa1c0c45159f69e9b13383f19d97cb245303f5e77464af5a22160aa992e54c0c27d3295d9c54f3c4315eccb28ea6123b8971902a80ce6da290416833583470f92852b5e7720ab847c492d1c7305559458704221829d978aa00e1c84f162b79be9f2b09e9ff2a249075fa28df270796d40b0aac636d225a21088c645cad8a3b984a880323b53778e38b1deca3c024fdd2828baa3341d634a1329df53cb4c76f62b169ecf9fb328a08b36e5d138413ec452e4b8c9a61c37ddf3e02470d7e6660a0313a1ab520cc7038bc0ab88bcd997be4a5e6b792cef706a0d99d82125e50694c2e180428647c870efebc26b8d10bb4f15f4a0744ac32e540fbc22df2a545198bd237fe38b026b37ce512809469c41c5ed18b50c059ae5e9595090a6d77b5e93c017747b3addd87c7f6d7297066467e7bd5251e1fa822a57810daaf0e95a0c41d4b4a25a0e12379d03ad6c955bca4c1a8b8cf2340aa4b6b2d3397119c539c6eef4470821ae8908040b459010aecaf5b89e5eb4de453d4cd551533d6952057556df9d91e3caeaea05f130643700bb1c4cd3f2f584b3ed3ae92830c06822900049fb686a8181e5f27bc0899c5c2b3ad9345b16ed55d5828b317d1b3585dcf0a091e58f2ced932cbd6503cbd54283de4efead4717e81426d6284592c0b5accbd0d115c3d744e88cd3e4945eb302629e6275435847ffda2cfd94e0ccda97405e1a9606097f4fd98da44e45aa41391c42e1078e006a02c3289fe17ff348ad56fd5abab50c19897a3816bc9d0ab820d49450a72a45259ee121fa31e00460faf04061b1626fca44a55d348abd9c2522c333371b62ad4f69ac4260c5f58c204dde078a543480e22ed186e9d0b53ea1cae552e692fc91c74d4f10af16f57d2761d3410ecc765ffe6d10897f3834b6a9cfd66634e07a2b12b90d729d2361f85332c2ea93e334c43b617faaba6a51911f57444c741c9ee15f3487a82957ed0bba26dfd39f655ea4e8c91825e4022d1e1e5085c47171f5135f5b1a284e8ad9667627087793e9190944261175bff48075ae1ae9c2e8a083aa31f1890ac31a1762ab1a36653d9a3ddda90cd5a54a79c214a0ba23c47ae336740dccb55c6740a9b552a5f8059f308478945a46f2bd33591e800fe0bc740a663bd2a8b198af7ce09510f5eb7c7d79256ab5bb42a362b5c25838a74ebdb5f75e8f6427d130beb20db1051969b5920850291a6c923425aa24335d64a5b87c89c420a4470c780270fa40b124d62995572bdb841396dd7fcb80833ddbefe575654adcbd3a1c1d6020304a5b9b192c9cd0ab3eda6c3ad42450a10fcabf5a778b491f739051ceaed11c6b7a141182d2d4432b450b64f001540f9119fe1a7482a4676bf8ae7d0e1dc7e82a319fe4520d7d10f2ab8db08716bb28669c9f12af97b156c68e442c406a8d27244f064661ad82781e852a23fbddf9dc6a10e05cc2fbfc02b35133c14ddf51278e81462e9c856236bfd69c3bf78b0cbe939298079057b0f78db6a1db2b4984b8ae9261957945014dbcd5faf4f37bedadeb6a414b40a1e1c49283c32b00c933418169b98032dc27685ebc96ea257e24822f57f814253cb2b4a1fa2b3485a1f4d9ce0182cb70b1a101460cafcfbc3f14aefcbacd23695fe8c1385022ad1fe03a405a81da2128a9cb353d83b590c2babcca064abba3489b66686d3687930753221a364b4c32b5da2e28818623b74f3ab1d06a0eb950c327656e9e682cda2ba6621cabd274430ea6701f58b3c0fcdcfeaae6f10d6e1d55eec12d46d09ebf148e98400d699ba1572b6d6e90467a66b70a00098730906585e03b2967d079ce6afeff4708451ffd4c9e78f5d0678ca4e15e68d9cd33472eb94c4619909f5896a37a2acae38978192267f8ad565b4d0d7c43b77284677c386f0f8cd2fcfaa37d188050726056fc42594938196eaa84346f68425441c906bcff7c0f3d2386c4966245a3b8e1105033309ce47cde98e4d35fd745b4b9c96e84e378e6eb4b8d23a3b525e017e6d0f792c4e58744bb2ac6aaf07400ad9443980c472de3df17f32918332b06b0680031b18b6e90443d3ea4f690511994d1ab7d20992933b8ad6d35c1403488da0efeb2a389c07771bbcce4e111eda02184743fb563887f1f7e2be43670b92bc318a0c94ad05be90f00b62baad209754d0c5cf72f2e272093fa3db97e072cc97c6b76db9dccb2af417b62d5a7589e64402c934af0ba7fcc37d2263bb3016be806cec26d3a8534a74ddb8ad62da2b81890f02e5f8a0e1e94fba8c66a608a519c002af4cf8d9eab5c169ed7c53c24b3cd4609dff55c84bb9dfa45fd89316fd3d5cf4043eb5542d7e9a9246d99ceb56eb927e9e924d6124e134e8125269a07adf2248b2333427a934637d24cb3649612fdcf174e2efaa1cb408f630e35d074612fee1f2cd79792062e0aad011657266c64b2dcba8fe0160a0c806f589e8490a940df11e0ac1f1a99733baca9b3e1318da06540d094fc3e070c8182aa4dd200d24096094671126b1ad2f2d07cc29b4c625a85833b456e035f03d4ea516573f25d151b3ac5a87a6116656338dbce9ff254c56c7a9b70a80b6de0dd57965f0de495391b1250084583c8434e7f23d8b4936a6af0602600258b4898a273b7f7dbf8844e7411fca64b590855258f03358f7e5289883e384d58cd7804ea2acbeccf7ea10ac08edc31adaed26432ae47ef662ad266f26e357c8025dd9ffd0f063e1d29458a12d158a54d7cc002b2c6fd617d5187a4c4079efd526c1b3b67925f9ff3a066830fdd2e605aceb50282157ba86f85980a7efb214176448ffcd9a86f8ee207421d0ba142a522738ae2c07342dca723e74e97a9236c40cfd2c0ba5a54ae563999379adad00a297e5d294120126f946e91ccfc42c4f991c1dbeda36ab6b1afa2c851057dc22781422d376acf5f9009094f668e772a8fa96b203f6af608cdd88945aedb3296d2b1ba11a89612596fa946761c64b04052dfd53f348338c93005adc8900c89e1471dcaa0f047ce01dac140e3ec9d4f77948d3d2da51562c1699a071fb4feaa34b7ef621eac0a7aac8b75e31e2ad70f8255a013582f3936babe83cadc2eda30e2dc0e97cc8f0f4c49373d7276047185093e86390e9095c88eee90b0353263e597a691cffb3f4dfd0ac098631c68657a6d1be9d65e04396395276ca16f6fe1adc7e5b8df2dc932b66ade3b4d85bad41cd13711a6d5aaa6b70a89cb686493890a521409cc641db83cba57ea432c12e44d49939a57ab51028cd7583343b7b88fdd273dacd621be60bdd5384921e543433f3979f0a1c0a3271c4648193cc7d2b3dc011f1f30c80ad865040046ff3274a33e8fb6c21946ce07a4012506d00733db79265cac19c0446d5a4d725397ab909ee09d0eb2d7acf5d0d49850ecdc189a5d9aaf550bb13e845c7c9f06a860da7d3592e4976cd111973fc2ff98706b40b672664468c73b6780fad1eb17d96cd84c7e5df8a30f8c15f57d19bc6b9a7492d2fdb3e89f971fe85d176dd907c84325d7170917c9668a7b6a15b7df3e897e550099f088c2143d3ca9598908347ba10852efc26e1d731c16af74d477b7cdd3b6400cdb5059fbaa9af2ba769c7a4640ba90fa9d81b2cdb349d2ebd045e0b081ffea762ba38a5e79ec691959a90357e556d932d4f3deaef3d2397413282a180bfd451efb7d26bdcbd0bd0787aec0157c25504189b98a01526a9fce3ee91e42349621a26e3d12e0583a92ba3f7ef2548add2d1327679a9eb7278672de30003473617eb0900a5598be35ff18a1e54b5384326ad9e85404175277083bd0eea5729f2d70bdfefe54e7b67cc655b473bdb9c860c745c7b37b11c66a6e614998f88f1f911c80c596107ea11315ccf165bd5bae0bcc6c4fa1c4fcf91303d62e8b047c403991706b3c43190ebd4abcf5165cafcfd3e29f61f3ab37f7e94c863e7b4a9c3a21fd03901939134ed82b4bcb71204df79c7844d740cee0fd0abc5d57ba1354f10b40431b68c0c83b5d32d4fbf14d4f50736cb9bd9952ce23cab29d8cebe28b15407fc34babdf39b42f8265b469206f91fba2245f38632c914d16df4738a8e187fa551a9691844199c3368480744495ef3fbe9c43557cad723c90bd150720f52486894d0306e2ad2e69f6c381bb5c488c16f18d794007f54e022133c40d815ac0efe8528ac4097ac862106a1d78b3b4e9b4cf128a4b44ea35bd37ba6fd0dfe5b436c21b615595c5fd11047fc6bb71408e715cc8e99819f54136610ebe6599887e2fe37c1ccef13a02ff893742202c17ff4c157f485702d529eac5a295494ee504af17325c8ecae5c5e679f4206f1cc29f314d9a6008bc5e8989709d6afa7990eea4758bdb289fb7416b76dc5a0f504e1874c4cbf54ea298ad2dfe5040d7e8744dc3a05db3df408e98de8017ab817e723f9e985f2839d9c031257f278840ab913515e1ac7b1b6eb806211f86fd0391985e8956b4ae71b858971016cd03e4fb0fe335155ea9a4dcd6ed5b866bbe4f74b5c6f537081c1286bf934cbd994ed6c2c6de409855cdd5a7d3c77a072ccd53d8c6f35c19485d967751b6d89e3243b96e6934103e79dbc023ad9ae0690e3ec5d333affa1261fba3f02c44d722231026c155941d43059b00143718d844d00dce1bb641214e032134e719ace54eba1324e4e9e15d42b5d99c749bb18668e0d34a96413106790d3a9dff9cef64176d741f53950d538080b24b40332da19a4309c99c8ebfa0b1316221b2fabbe00b64c17bf4cf5f424b43522765570258eaa4f499a3c03b2c9d39d58563c80916772c94cadb22402f344070f865f4052111e7701ab1244b66a3731917ba213b5f18ada9c4d330f6b0469a20651f17928c923a88b248c5482292133dbc23711f8243f691cdcf640658290863ee8db1a5c32f3720151f13aedec3351f622064a0ef75106eefafa154122016acc4b3746a6b859f40fb779fc4753c17287bc97bebea0253ecd0bd1c11e30091f2b1655b97af9dd31cbb0c67d4c4e69c54145e12b3a8b2fa88f43f2344940e78cec2eb2b88c53ab46028c9a3d70672d01d8afa0b2ac5d64a5f3aecc14af848342e1c737faae93ca6e39874dc4c01b7a1e482a40c994482c8324fdcf7b4847abf100e783001325b03a88816f8adfa8c506b8884eb1729e6986c2fb83db9a94ffc6c3c68f2f8976a00594023af777e54cfbc2732afc69392bdd77048e109bfb8a01da81b2c4629a6750cc7a0977de38f1bd35f8a4d22dea3ae08e0641ebb54ea71c529a5dc5a037df80a256a92796a82a3e101f03eea211de2b992e25614b84a1c635d5956242b6b044202939a68832e34ca0371d81e429084c22ed200260a3b459a31dc8c2ecf8bf029efa6794f2831a8d0b2a98f20120cc7b929201a0f3ed69b79201571a84ba5937a5d3560994425e91cf0d6c8166f05062cec3d4db1615c5cc46052f7ba99dd47984a395ef518015fe86048b221e7c502348190dbadf226a51c3006c1e32242e92ff86b60c31bd976f7bd53d8d09e34eecc9e6129d861f86b6ac7075a72e1c16a752057023c2007420bf95993940d46e68babc52a37654dc0aee02018e90eba7618f549cd06272a4a99761336070c2332d6bd88bd9230fde3472eb599831a37192594eb08af3210417f04938a80cef2b00728585604c5548c57238b6903f1ec7a6245ac5d5e2ba411264272e13f8c940207c4ebd04a8728a9de1788410a186d7626de24bc9143f1cb044b36b0193288105e65d5b3170c41470391c995924431a0c41bf9c9fc6d526c52fa088a8d8849ca1f385507b22b2544ef9d36b841cea98c31c399077fb35e0478da2fb8447eac4888d2fc614ce9f01143b4c8952ba6b022b62080da2cfd701efb8bffced14c99afd0f0550c32152715185c104a1ecb234679698b666a1cbff9dac6d1ba951debf495260841619a352c13774919e325f1b00a16c255edf9040048a90f1585ccd760b003d681a117e11bf22abea948f0d921aec42573eae09b726bd8ed1eea11d1683cab5bbfedc17b5b80e3a09f046253cdcd91fdb5dfdc24a6692e7981306dd3933885a44dc2beec975acfb6c3ad5dbeebc0f8f4d62b4f180acde26069e388074fdc15cac542ac89b99dcc513c2057dae7784713ed3a01579ecbbdea53829950444749d6e0b9b65a70779d16a1d472e792027021b67a007ce1eae08200a84acdc49927c70a396897bd0a4c6aae4a9a1b4107b4893a87b56ba21db180659d1a0a1ff1add74e00bc65168ed70109f510f50caa24ef9b5f4467dde5ed4fbade2b3c2bc78559c6ff826c3437f6419f978dfd1c22753ecbeea847e5121e373b7b1116289d34a94572a2063ce496f89648427274095909ad85c8eb96596f3f4b7baab5964a5e2708e773f9fc8dc59a02afcbe47215858803332b4233586ab0943a2f7fd01e881c05032125ec5f30def969a71ad2984ddc3b2fac253651b780ce02ec6057fd773faa2e94f6f023169713777dc47e49023f8498f4f2f3e151ffc00985d22ef1fa04b8f613aa223ed223c05ef47c3e22faab1baa889bfadead430052ad5f5e66cf9e29f7a16019871728b98fe97db17b71f8c659d056943c152a634f5ff374fcaae8372b7a69e59cc4071c283b16f6e4afd33c9b03a53ddfe12440dda1d10db62eb0c217322376e4e9a6057f5af16fc50e03c8afdd7f1954b75fe476dc9f51bd47c524b8a3f5ca103e2662cb79123922ef65e10b2c1402e6d692dcdd42c039be3745d7a160ab32bcc4277e6b58029891bb018c57792922691eec8d84043b9293fdd0f4cbfc1d39e624298ce255115f19696ccac7969618083270cd43ea2e3e67b1219befa4972412b4a0a6090e129498c15d9b4a44110f0321d46c3cac24290c8c6308eb8da879af07c1c6d9bf72f9c228409d385a7842aad6f5a8d12c43d6645f6d7d3d1528b8618c341e659e0cc9bb196570926bd8a2a9c8481f99eb1de9c0636318776878cbd0c76acb1ef80b05ec8b32df310b47788d00b79a817a47d7bf1cfec12d312cd06ad90e316ba4ca3133c27d0b737326f650bb454efed2fcc0c17e53284342617e85a3d3e5a64aa09057dd9f8605577834e2e83e1a3ee576c8e2b811d327d3aa338cca5dfafb2a125284148c4ee83ead2ad088edffb74fac48896e372836112494d0003e3bd4d01dbbb0b7760a6bb0d7934b8f3d1401c6986f12b5f027a2763d5206f6c6df1f98d80ef5ce5e467f2b9a26ae8149df7922ccadc9d06bc6987c4c5901338674fa7979d702ab7bc9d9caa728d1f428c56ef8f8c25e37f4bbd49ab8a828cd5eed6840653741712102e119f532d73f504686e9fa4103ad010798f688beac5395a716475d72d019d41925f69cdca74a2c91004f47b5e1ce44de6624750af45b67816e98e7bedf814b96104f2b446b724b1f546b97618037bd11cb63ea0e27aae3653d9ec5d217f9fe70730e9012403abce640e2adc51d32926547756bb23e623371bea493fb4126dd26e6c51bc3fe16e430c4be02aa5f303124ba29925cb6ecbd18b3f0dee8686cc260958d8e40c11a3638a334bd2c811d189e8b0168c65dacb646eb4a03dbcd8516169db1ee0c6a4719f105756664153d824a8d42c076ba05d16fbf96300875b471ec448f2287de289e7131bbe059f6cf7f4053d28f05cafd45bd06bba95de1f37e965dca0180a1cc705bdea24d035fe57bad8caa93361ae8d4018d3f72952ab281f3f462fa8e50316cea00a58e495759b114c5fefafc33b76319ef97ca799494c03e3c40b1a88055a4c590faa17bd50b4a6637168328de08e7cbeea667586463537d5e33107191b32bc79b5d891e6aafedd0eebd4753f906324cdb3809295eaa7c147d7dfdffc59b54e4b6220a59859d82da1a8c00b3633038572f449921b0113c5867ba9d3063e9116a0a597c2a14f7122021a80519948631ac61f62b41f73d43c80be14db700d2ba0789ef7a5a881e4339f3c2d4de1d64a8a83eee6563f1a6f310b869a11f3681fe352f7c8479420bef50aa704861948113ec35e02075ee9094ec920b7bcc09b64271d4b5e56d212565f2e4af234b7c621697e8511709f030ade4a74475008812f36200425f8250722dccde05443f8b2d0ff37a82ed3b167a9b6f230881be5e8703e23c1197e8b1f52f190ac95cb32942981f2033ae167a2e63e1d79a29a918e0e9f4b668a410cfaf7a760a504284c5a9747766aa7a78128f7a05711d2d253d777eb724f680310d3d63c1d42ed5e6172015275b9f596e3783b1d90b95d34d8137f713f461a1ca2400fc1d02979d41e00d1173724004833a37e1d0953637ce28e7be083dcf968b1ffe9443e4067cd53490221826e9d980c8888a0c064256dd8a563120209ff20a7266dde834958ef6d8ae0ef85d073d6894f46932dd4ec3901a5a1460525df8a00996b26f26187e633de76946b8b79002cc3eef1519f3a7792b333abe1dbc981db4b200b8568f3b0c4560b9467a0a0079af49716146037902b90b6feeeb6e17c6c45f5330ade6e00d69463192482d00caa59ba1c46c7eb7375936d83659db23a734de0f75a3b8977bede7f6b564c249eb0616604da6f14697ad865f8fc9fd9d9ae5ae9875f45c899addb2b672ec07206465610dc0ca7ad70c4a979fb3e654676d8a576bac78bec488be683c803ff513b6a34d6c3933c7e682a8aa6998ec2e8a1a2d1314ed071e1a7b318fbfc634b2468442e89c9e3e20f784fe16665f4bb67787075ec54b175e894f58d6044d794f5ec5bfff4cc60ca7ae6bfeae0dc273463829fa9340008e13b27358e2716e7e33aeae38964804f07ccebabff45363d8aa4481301d03842e84919f445accb6e7d5c210c42270be4707504ccea8258c98a112892275235b65f19778deba999228a058e884079ef0aa8179814e0e0231cf3b5d5d9f167c58502cd383c0a0ea7ba029fce31dd5312d0402b93a727a7a59780b26154b1570551e9af6162ae8f1a8006091bf3a7b9c08c9aec89c192e20bc61cc9fefe9cc75a8a6e27900b543fe56339d350fd9ac40536546d4b33f98fa54eea6faed5a2eda3b640c034d7dff10b979f2ebf2829fbe1a4224294562f0d56a3c09ba022ded8422df39213a7f5387bb91041ae4b250743828e081901377c3f290213648780fe0fe4fe4c3bb911f43dc92b325292348c65f23f684457b66e472a3fc10d52a276fd5d862800cec3bd73ea66f5e3dd062ec63f78e2ed216ef5d56cd00f40bcae03243bdec810a6659517918a10995c31839e5e39a83550bc2ba0221704a0338d92677fd83d9b2ea2a5096b5545bb989ef86d83f2511b7639caf8c606ea18b34028886cf30438424489cb9ce5b03b5e245ab3a2e8ea134a9f689edbc973a797e5608937c601024d37b09467414b62bb972ec2cde7b5f33314a725f3c00aa8088c296c5050c7e8405fa66570620440fc1aad3a096c901f948df7fe041448b4472f3bd4cd94d0ae652be98cb734cc48244083014483d753edaba5687fcd3ca36a53435909af06c2affffdd08c6e190e40632a41b927e8e32c59834f2e113743892faa5148ed4c9ddeb321498fad015d908f151e88e26cca336d4f34e1addf99be09ce9a57ba7ed5aac2491185e9eb1b8218c0e0946bb57988932009390dadacf223ae40b5dd2398b239dee9c0e619ba03e500cab18694ae35f7244c3195fea18318e3649a36b54d0b57a8d3e0a3e314008eeb668c0374d448443936f1361cb709a77d3b2eea0c7f0f4781310c2190562edb1cfe7ffaa087ea3bdbfd72cfba08dfb3f5812fd20d7b042e240a151704793c57680399b0071ee987a2d5a503dee53c2bb8192324dd3fe007bc254c652af4a5db2cbdca532bbb875b46f2202d54779003414e19614f59bce69719823ec4888068ae01660d9d6276276fe29859226ae642dd51bc4236183d043c2f74ee932b0295cb74182a1db4b5a6f8f687d1a7bc081bff7ac52de1903d7611028a26e057b7d2151221fefa9f8f7f7f1feb8053ff38abbc1dba4e6d792304dd16291ccea7466a1bb842f7da126a29d13c0f9289bc0ac260cf9f1936e6cb760763bec6b0abe563128a07ffc1a902e186ec07d9e62e08f8ebd76a38181e86ef8e5803db90b2180ddc81c653d750b84ba4aa8b04d85d22db06271bd70d863eece9fd5ffb05607f1f7fdd945d065a2f42aae700ec6c8821cfd3e9edefd19c16093db066a054806a9019d204ab078d40d515a45ab5e258f531b47db5c00069d175c26b49d08f79d4481ddef63f72edb43f5d89be75435c697d845ef01764f82e4ed16738d2a9959ee79c13bc145e71e3a029fbeac6a611963e475383aacfbab6418cfa7b58a545f3eff24f6b609de0139b660903af0d3979e8b666e06164260100c919bad1b8c5a5241cf1bd0bf46dca161e645f3be035bd4cf7fea50d747a0d41abf481d69b10f424f6a943570399d27f61c8ad812f5d9794d7fe676538e5b42bfb85ae8345630b64f3faac2eecdcc696eb366c018ae89bd91200178519dae1bf099006adbc9c50cab7c697c9a9cc3ad6f7f89904ed33ae388e6dddf1557c395e0690c179ac7659485eed82f40dfdf7f7cfdf058cdf78eef4cefb069858bfff1f6a6ba90d98ca17e02d99c33c60da265024470eb00b2cb429745464eae3aff50dc91eb4e300ea0f6ce811d72bb497222800cf6d7f58a629ab9eb8f437c678a94e4e122bc611fd0d2e911918c6103d9df4266eb5779c000a2f1b3e03caad43257fe31c65f4e6928b10e1ae8fc0cfa77278df70d9f8e330435a17e62d5510bdfa4006deb23f7b18b5cf93494c9c4350662050f2813c6777c39a84d8e7ba7b6129d0fb7c59ef3e16037a375ff5eec7aa40eff5a9aebd580dec7dbed45bf7a5ac083dc1153278d5a2efa9c7f4adbe3d2c06ec7dbeeadd176b81dee953ddf6b11ad87bf9aa772f96027aaf6ff5c93e09eba561044632ab92186ca1a48dd7ca663682a247e0287ea924ceb07ac9ad8ab23ef6a56c75e451f61f3fc6597c40aba46e56632f1f09a3c6e600aa1e96c4b581a61c1d20f7aac7e7d8ce6c9f0190ce0f973b434391a156faeae73ac786026d90b3cb6800746cc1613c584d3e13cae6ab659df13ec70e7f7b1711db43fbffbafde6d86862f28a3b28d442a2c45e49aa5cfb4de9acc46938df60990b9c63df7eda4bc38c36f00a745c3ecab434c5ac80f2bb82f9d2989235c7a96763006107146e3236fc70e67676acc4050812aaa9318e83834c5c39b8c5981888fb4d4b976cf6c17a390f2717de9bb30e525da67e38b84b2b85b7ac507ec2921e99b19b6f8a38f7af1a27bea53b5caef7d0e6a6ea501a833f95182de3ba896cafeb49d364d44c52086df9d720baeed707f714e55af683dede98f1f8da77078cbd961f9240afe2817bffbc470fafd73fabc45f89149424e03fa95562d891ad672fdea41ce960fb67f4ce6ae5bc7414f4d4828b63ae907c8e00725f21e9a6d3a851b1ddb62b7804aca96e0d32b83c11db98be81f08ae65e8bbedc69442b5a16ac830cd2a8e0dc62d9c16397f97c470576704bf290bb274cb24e2d54535e729058b47040a8ad213a2d67ccf35b2461bc4f8fedcea1eb502129b82575a3bf2207761310eb8264ce9f982946f6339da5d60127883962039be4ffe7540511f4f982cc48e50dc52569dd863d026703a8d4abb55c87041ef504ab00414fa7c9b57d122fbb2281171a6203ac79965b465081e77e01e4da8d0a63db6dc7ba909c6d9848678711d9eb143e6158b09e5f5a74206fc7d3002e54b6c527cca265082131cb87466eb1085c9dd2d206b4039cc5b2ebb2b138d699bb82655d8609716ea008b2797113b13166f4e85611bda9cf5a7c13a4963398cfd3380ce8d87e117c6fe322de63c426d248bfe40c2e25d89de5b20f66903ed3709c73ead413f80c74ad45341e7dd4e0b474a2ed14084aeace5c35d6d5d2b00c73684413f07c736bda19def6690c25747e2e0a4849377d292061f4ec8894dd01c4f1155f45d0f7dffe7ad2952fb12bbb2dbed8efd1f7780fbbc09d89dc8e4e5bb7ec6e0f4e1c912708ff20efb613ab2b68546388fe3eba287536168a672761f1e8ddac242b8c88d7de5165b8a44c0e3bc5953cb3ea81a11e8a93c68f1af6e21916ef46efb61c644455cf0c96ae318123640282f5e8173a27a8df2742949a6a637349bbd82de17c2154274f0375c42583cada5d65a5575676afbb9a88de2a431f8bbe2a667e829adb3bad374344a567cc814b531995af1289db558fbfa7184189496d5aef34dd87205323e658516f82d9b53c367ab13ef499638416497753a6fbbf9f3254ff05fa8263fd8cb25d5a0c7fac5113f32afb50a8eff02a7f6777d18a2c1383e7b7d2037b157f20b02a05c426271602ebd9b6634ecbf0b9417476290da4e61c44bfc3b943c5012d3bbcb90c870409350cbbb7aafe424e201572eaa15eb17b20b9d6af50d63d7733d96cce372aa554e4ccd5701ac924d88d485ec9a80eafcb1e2d2c9deb1bf29f32a616d74acc44654d40ff961be639bcf74740b90b5ee4d42fb3952604c849805f8035af3dd0fbb01cc2a48b57bc3c1c959926ba228e225cb855ece9bce3f26faa5cf4cbbc493d79a6a76dd78497ea76b241514e3c73588482584943b299a481574ebd06905728ccd39b1da770b98bc42a19d3c3becf55fb2faba12f07f5d77cb9df6b40ec132b0633f2c2971bc5becc1d3483b8ec68cd598640701fdc0c3224557373e5ebe8cc890ce8d7018428aa8271726086ce43c9c5c3299754a3a5c8a86319468450a5551daf3de140ea625540961b2532022bf45cb467baccc39d8bd3f876bf998cc23d2124812844f08e4d8930163967f4b5f2a1d85584f06cb4b2b9b5b7c87c4bd12081113ddfbfeb8ad4f1e61b07f40b1a98f79f25f92e3ac75057119d34a3f9af8485f312da9be17aabd5b50fb87a7a04c9af1192390edce5f3b193ebf0b0725a027939ce79234adc2fe186ac5a04a8cb65aaac1997db8bc9f619d3552b100a66b6a1cca6dbd6af7c63892960de1ded2fed64ec25eb091a13f91fac27745e81f735c87fa20d580da5cb330734877c8dfa8e5974b959e168ca30d31099ed3bc5f46b4ff98d856e2bedd0dc169abdda8370623b0480f07bd843915366b1431142733f08599ebee45d28512b84b63885c3e29999530cd23c63de6637bc5f85a0a4768a97261d86772b0dfb5a3fa39a21336ccd2dc955ac554241c5222f89ff35c0b7c036e8303f100c46b2b579f66756a2e997bccd3bb0e5b4be51791280775e7a53c69617033e4977e1cb985e729df9c52c76c6ea97b775748a6729b7399b6ae6a10d43f46c822dc8d2300feec836d2650a1a38ede30d54ee40f86a2eb0edcc51d6cd7ba1f4f78c18b96f0409e819894a599c8ca3fadc49f2c14eee645a7d3813d17ed884b41fc50495473011dae14d64e33013c23a9a09d41f69224ddc6446276e99ce787413561e6d221bb8ca6ce60326ac8bb74cb4e42db39ab8cb6c8643269cf1e826a8b587407e1fe23912bc550e30f3d8ec4f8bed51eb0b33014abb6c90a67e7ee8a4f4fe583378cc003b1a5d7c66072c0f5de474b00984bd1eaff31db72e2cd83e6a98340442b9da3309b59441c20b7565b39be3632dfb018488cc855d81ac0e2ad49c356bda06f8b40dbe753fe09771ad9687fb7d564bf2ce0d4d0f8654ed9b3a63cdbb1b70f24cb0f7c305368c63fe11f6c8249b70865476fcdaae838244682519b89d3182461eabbae2e078c45e20eb0f5890f74d80fb0ba90c1abf31b344bccbbc35afff342ab0fe3cceb9420b8d4d1054f618c01b3406024ef3b8403fa6da5ebc49c44416eb9c83fcd9c210ac99f45b6f5a406e7e4759806f91617187630b5a7eb4f0db29df4a9dc7be503891ecce191b216e2ee0e216b399a4ed242bc440a93a609bbf6d541ae48213a6925ae8ed9ea32574b993d16070137957dcfa136f80592232cb6566bdea1fce7f17f9766347acb6e73578719c8a23f6927c487c0afcb8b50a5aa9439e179a8a952e06ae5cc0b035fd65cb2c3da4bb6131d0daf7cea9d6a01056c023db9a57a89465e50ad41d21faa6eaf746fcff54f4c72e6b94e5183c73c9d9578fb1208626921d890ca3bfc09dd6ec8ec423c4dcc0cc83ce80ee11f807f06f1e61f5eecaf0afb14eb098ffeba824ae529b816a3ae03e4c47fc84b2efc09d62bfeece13981acf2eedc490b1e788119234e431eceb787125434f0ea51c00e519a1a7af50ba906e2b9767036b0b27fa3e01622a9de3dfd41cf84801aefb7712a527595c43a762817833f4cc32017ed99984e77dd7a6218c689f4a31c2ffea075b2d1d686fa7c75407fb91376bb9d8585c98e96c9a9fea516cb9efecfa9b072aaee5442db5acdb56244990a20b45f9fb234a1e1d2a565eea051025674ba894254a6756beccaa14380fa5fbe07c1a9fe8715fba4a332cc9dc344ecea922a313c21e8077734c6a89cbca74ae8366cf98d9406835610b04bb3db163adc552b5e0117a8b4c912b2554f44cad09980cb1f0a81fffd9850450d792389f59d6934ee1cdf9dbfc60be9a1a674a04edd744630adcbbcb6fdabf2822f81090982e50807b8d8c5fc9da385a919391388dd718f40834c1985cdceaa7eb327f80ce2227d786aee2b08a77b070c29c93567f92cd71934ebea3e26fd501474f692060a44036083b45cd0584a624a42663d2e9188ec98f48458338e01dd5b5f6df3107d4b8de231490dc82068eda52e2c566c66cc301556e60872ff77205bad53fb5feab40569ef54a0e0cedd4916c00d4401418c839378a478b9805d71354aadcbc225746b10d1802570c25c029049ee89cbfe0ec49b20e81a3255db7c84c15cdbe73db0b08cb0ee6f0c44e7903f2cce68b1de55b7c81185598d868795766e51dfcec8a29aafebaa8f111677ec6efe080620338a88577d89f155886c4a4c8d2e7467e49c6294e12142cfcd97a16fe4f2c4365e05030e85192b0f975c4b367ae13264c97d52c1d36a7a4005bae782975743836a30b3726e5c376b38d76d7ef1b4c6d869f65c52c0c5763a2086cb93de3edc79d18cf7cd93ca4254a1decef2b3e5252a87983c8905eb80276e84e09415042d22e34f746cd125ab098f720f72536659928c22c9f053c6bd9bf916fb042c6249dea2e7273c5373e01e6b29774d7dd5a0774783fb1583e01080af1da184ba17f54f6145f7e3fcbc76171eb670e60d8bcdee85784e8ea5ca2ac6ba8cfdcfaff9b0178321e8600a99bbbc728b574a2a9b02a8475a22723f3c845b0770876db4d0c3897e8a79b1a9714fdf448ae32f062fd45e5b0249e41b8fc0b43477823376f4f6f49600296a6e3791de4a67fc67e77243c037e6d4c294ad4de7aee7bf3ce5137bdc5a0fc75b8a62938a7221c0c9b1e97650d3888ef67453b60f456a777dd8eda8b29e8cebcaca0911814e96893684e0444ca957f1770fe9a4c5543bd926209895775b150919a2775dd1063165b0cc6c8c9b49c72b1961b957f92bcb888627e833b6702a25d27009fdc2bd70205bb9addb525054612b3713877e030cee03b8b8c654b40b434eacfd3fd758548abe21b9f2e358e94de888716ee6a49f8e18bf30ec3b385e43da7e4101018b3577222283deb03ead257ee8f48acf6b3963446ec579a285d3da7e491d148c03b959534d00bea9eb7f7e12011de64c6fb634d833e6dba6465531b8a7d080d85a095008a7cc61e6a631171a5a865e2cb385dfdfe6e9a83323ed984cd0cfeb7a696dd952daf44e99ebb639c8d06f114e32c675946764aeed7219024ee7f0afbfae0e0da6104722c50ba289f94a71e9b19f00ae53539b84ebb81112873fa5e631e4055e20fbf3d393362c9a63e1ae2dd535471b41c2177c4dfb430a3222c63b1b2a40531b608e0b7e60163ddecf327f58743462641035177d13fe7491fb9a00a8c0ec1c652ad598e9967707b4e4e1c2efb96f0724ba302c0c4bbbb58d7db245addc914439e916556d62824f991fc98f55e9caf7571c1ec49887572cd159fc13b3e1ee8370c27d03878b6562aadf69f15274e81d2a5696086b68c1c3052a0c6c516e8174e97e9d747628523e44324c97f8d22ccedcf45f30cf366bcb03ad1fbccd9f077d0de11516b5e894c0008912471cff537dcd6abfa01f3ca6087605cccf4fa0f18570165a1e57ccf386c559b55125a59248b49c62ca9c5732f3dd5e847b7fc61ca26ad3534f2d6d3b78274cb94f64bed100f9c44b9b14800bd9c87d85a1409839dbeb9ebf5920367a298256b7dab1508ce492244686b28a07f601ec5420cf82aa71ecffc0d23a1d0b33e19e1e388a09579969ee0e8b951722baf49a619c1ebc5322521eb73ab18dec24c5730408db06cedcb875607c025dec05645221ff445e38091ce65553e7bc8add8b3d48ae5100e7636d21524e2370d20ee3a0bb69a821ecdc51d0b1c8b0b8ae1407ca770513a0e42154313f5157ccf06bc53cab4bd35bbcfd10ec0441f6fbf6cf01063a39f87be80f897f3ccef73e504aeef4077a80b0d449fa5d86b7d839b354a39107f92a166566961b78404fafd71050b1d1ddfa9d0c72d5530504caddae88d681d7fed04605bdd33bba784b03e1e02963d7e7636de31fa7502b373ce9328a76879744ff2b54d6e4c01aa247040fb6f0eb7c649a0c9740b3ee745a40527e0fef398323cb1e1959233dcc2b18b16dc61694727abd6e835873cc291a150bcd0a8b392d4af203c3a46b47877eea3fd3e35a4c614aa6b1f7baf18c8f73d746b109550000fbc86b7dee39041c4a3117d36acfd91424d0004022a2ea092a2dde9a516c5cc0de5767c2c5e2071490411ea47871f6337341a19d1e207b53800867024647830f74554d2dbb9d2305be806c553e76059f4c6c19f1adb2a364f782658542228a5b1ac15637343bf55e2d8798a44af93abe8cd20f6e20a14239ab9d3a084008b729fd1a439b2d1e909e64f84d7dbef2cb55cf8baeda70e21e2873aabb707df47fb953ed788f33782b6000392dd316515f720284db956157357b96e1d5ea1b0ef9d39af50daa600f82247aeb288e08acb922488b7810a02d94b5f95534bc3b751efe49d9c032e5ac0f34bb5da5e40bd484c68fdf059f139abde542e35bdf640666782ccac08130d18a044dfbbb10084910b5748176f04381bad6db296c8e4b9e44c93717466f7710f630f8855fc1bc45a3a0e625be95e264eee9a8138ef60d199d933fde02faf7ef162d015c70f0831daa983335c0e58ffb8ce8c9c66446698a3ca692c747af0de32ba2e85c04ecc2a76fd3efc7acabb0aa6f6efe3546877f6f29fc099ef17a23d87693a042f7c64fdf45ec657fbadabd5d9c075424bc42aa2e17b9e287a4e27441dd7cfb878d4ea2ca84887acb0406cc09fb6bf9a45ac58e137a9ee6d02f0f622a8ebd93b882d394858e1a79bbd8451698d8921945549765e19a7aa805dee96a0097d2f0980e5c4184d6702b824c19bc9d21a6e850d4c067235027c515b96e014003f26b584d821026f245bddc059810bd4b0282955fb107469b941f2e3404d4b2ca4bef715a8588ddf3bbfb2dac609d3b52159967af8ee9d2fe12ada9ae5b8a92947abe602f48235f616043e2595ac6e6c2ff2bbc80c056a840884ed1d4474c82c6ef44cb3e703897d8c86832ebc529e44e4ec68021586304b91cb299e3b23ddafa2185e923c7a701b0681a126e7dddf998b08f061a47d930f4dcc38b2371eb16c6197d3226e562a702240a67bc4e822ebdc1384de7da61386a9a621ef8b20deb0ae2dab085643cd2a53d36e5cea18366728ee4e3299c2580860fb92fd3911746c14601ed4670372f05d6c3d9ce82d37183fba29f60c2ceda416a87a6a778fc5684608af80c378acf8bdb18d3647cbd679069f8c69f01acaf3e35fbd66a0174a64a50354020da8e14ab994dc49e2d35c290ccb4d1a954f4617503416279bb5c4310d5f9f8f44d48ed9fbf95bed0b7ed5805bc3b9a79103bcfb26cf90f17e14808b46e626d3528b253ece9bf758b05ac3a19f62be61bf387c4712c8aeeaf3b075f4af8f2039d5f7b033833b3b60fe0a12ca3045d6f7c79b15d742b70327fdd5775fbfba3321f73183b9dd5e261a07b3161c5850bb2d7d76d135200e27654650dbae3c81f5f24dcc29f9b577f63b8dd76d679fd6f28e561bd6f172c626840752befd8d1d20644c032a4b867c5920cc61351d853d06261bb801ce7141e6b068e5fe7c46b91f0e8b90b0c97869810e2bd34c5af020f96503b3f9270c2ff19825f805ddc0f9da3d638b02147cbd917c772269b412d926ac81b56e4835e946f6de7bef2d654a52068c07fa07970757bcf0a481e36fc0e8bc127680e891450910708254ca83d629550b182ca37d9b982f16b0ec487244182825263c5d3faabc51a2460c7537150c182863b6442c1922490b5555c45429755173a5c89b1f3ac870cd700eecd9a949d2d869e1ab4c153447280a6f0306866b041232555e4250f9b0a5c53ca57da59c0199e1ce553045e8f9c1eda6fe08d1a407c9962f72aeb061f239290324899d3154b6cac08a24f911c565d1a5a5a525ab9ee2c5863739205351bec8aca1921185860d902662e4f468254a387a20e9c1082541921c91e5c317874fd4932e265d5d96b2601d2e466915a5f004550567c90e51403574bc1b39c44ca1b2a38ac99c9ba4eabc97a0196355e8891f5e9c2d33695828b383e98a0faac30d6052102a3e6c6959312189c1f07505cd2752f3b1b70bc349cb0d4b4d50a0b8809e0355d5adf2f1838c9d3a3f00c1f1a1c1d9e6186e34024f438c48595589e2754bb345544252078a0f0e2270aaac00b180cff2f60f796aa093648d1dad24ee68b0d0304ec4f08842f5e58b9752eb6ded2f2a261fa5377a4471ed4e15f451e1cd942a757ab0819ea13a022a29c923872a87e4041a5478300a3eff892c68c4d63e4241c5241a59efcadeee05a09e403dd182218a0ee866bab2b58fad531cad18d898a9c2521e814dd886da3694ccdeb2073d44b65536db77d146f66dd65a6b5574f70dd5beb58fd44647d95a2b82a2289a6788414c71d6dbf618c50ffc330441f0b4e5300ceb78eff53cec3e8ee3389ad4bb8dedcb466a9b35ba6d53dc4bfd41ef1c705637ee6e7aa2ba35cfd0d62ce81504790d28571219c875b04d7f907a63db5646b08d287db07a1ea64af64677bb60ad1d1f74a71efe29fe79c7300c6da228be17d19a43cffbbe0f7bd168ad25499234291ec252fa95a2804fec6d64c9b2761b81e7909bdd55644bb3d98aeeea55142bbaabad28aa0aea1ed213e77def5e909ee83823904790a43b7d118cf441f0fb1e34a9a594be7532885a6344603acbb32cc44889bcec5feef7c7e0837f82fed04e003c813f68e21320f909c0afefb5ae510f4a82853c08a95f0f402ffa2c921f591095d4c1076d74f37d10acf2bd93efbdd44dbe9f676db736ba97bc75c9cb650f6ca359a64fd363ed586be1db0bdef7de06ad08196dd446150c410861461bd52fc1461b55db57f34c136dab61eda43a25dcb5fd1ef877bf7b30be8f26a6987a6063349570f56d1f99e822ef6717e0805d785b4f460852d9f3cca02478048540f07b197e34b4e47d08545f9a82648fcc1ef85d8cd4461e56f6fed646653c32b7fdbddc5783e7799ee779597a1eb5436db3d6de19dfdfc599686230188c752f72bdbd7b9bbe712ff153c5d03d837f43135ceb5ddf41e70309c9880f71c1c80eab42acbad06de41a794231eabc6811f5ec4a4bc48b0cf92cef162f53b2e5e18589f5ae6d0f3eb0801718723fe825c86d7775e842eb65c77743baa540ca2de59a72392fa7f8647511dd6d7511cd272eb5702c53aaa93bf9bc8163a6dee413741e189629d514563e6f4bb0974fd0324d59e5f3460416a9295d38e5342424a287076290c43f9ac0db0df4e1f6d87d58dae4beb09c41210b0b189c8f282c5d74e078386191da81eb113595bba54062516ec18e70333828532a242854c1323e4f30509d1fde581d98cc94ea88191f47b2e05107fec0574bb9253552aae2f328bdeedeeeeeddeeeef66eb7bb777777d7eeeeef06733728ae308e9f77efbdf71b046957d07a57d0cd087e7ebbbdbf5ebfad65043fea791ed206ef1def06633072fcc8510c6df9985e2f5318fdfea000b23f6def85070303b5ecd7d2f0f3c018a5275ed8b7de11ba5babb56272ad46c48a900832e538c821e917d20a46a2a4a284586953d44295305e36bcb1d23a33cbe3908a7c12e5f14de491ca8634797c3b3ec885491e1f73f9ca631732797c5b1bfdad298f54ba35d48872e9b2f83484b5106f68269fb31c7e183ee6a2da1243f9cdf2f7f6fb1e8fa1d2a242e9557b6f0d50f255734b9b65b39c90c3a86cc5395fbfc752a6b4add9100d6570902a22b527f73768ad932324f53a231293fb417c26f7973310314313056d0da3472de113531534c7b24ca56cbfdfd68ffbcba8adfe1bc5a2d56f7eb4805c77f79531b9bb97b038c12ab2ebaf1b67bdec3157bcb03c915e95dddd2bd3f74837124e495bc4006b8a8a034dea26d22d6888f326c3ba4d637f1e2b8925ece2a6225f2c24d8ed0daef9448102e600a1179472e932359532e8e5201e92fc5df8dffc9192dcdf85fbdfdc1fc9cbc634268cd5f6475ba3cda2488d117ca52c23d33f2b5112fa29657a4f60e5b47219ddd6a894f20dbfc36fb184fc99f83eeba54695c05ab5dada2a07edb41ff07973f79b7d08d8dc36badb4329f9f5c71f4d3c3ab56dcce9c1f77ed2bd29f2258ff079cdb3b5728c24c9c735592d56ab3593efb016248b22f9fba4bebbab7577f9fe586300ceb7e65a6340dbc04c1ec5fe0e354e81d446b88dbcbfa00863253f1645fe7bb0d615f625d0ca23ac7692642d7c51298fb596ca628dc50b15c567db367a473e297750e092c2830e2752d6f47892e245089b2f2933f0c86cacb66e29905858d18d3ada603153aa23557e38f2840156c006312d532a2467b2cd94aa0a176869a8e7bd7fdfd2bed3471f0992754634d426381bca276e5c4d195d493a9dee5a0fbc96ab0ab4611c273815e186c8d296932c3f3ba8e694c9ee7f01e884a9849c3d3a98b0168e9b7ea041932215ac10c72bbb3f28e786ec5f7b92a5f6e49a385270b27f00602dbc9920a1000018013b26d9df0226678286602ddab211eaee01c548777757006bd119c0a192fd4bc05a78c96605151c1db9bbfbcb324a0c300a6c3bec90fd69b0165e2e3922684501b2fb0e4ab23f1522fbcf602dbcd4e10d92fe2c7c82e510391b6a234402dcc490fbcb373b723f89afe5a83c3119024f53d403b8f8f8d1a348105bb4bc8e921b7e68c5e5db689b26b91f6ba06b0813aab2caf4c0a304040f0d43f0e9e2c386291c751e606842f3416236446422059b2d6bdab490fb71f9b69b0cd6a291da904d94413e4d6459d92077d69c355c72ffdbd800c9fdb19b771b28ba18392b8f723f88cb574344ee276d148853c7089e1c7ae4789d348b890d3d8ef420a5021a2538a70345a77477771563cd126a53e633c59b1cb2e47eac0390dc5fea2025b79aa6dc6ae6e47e9ac64dee1791bac99d12d69a1e267b9a1af0642fbbbb1bca8899fd8a84464b06b3ba5d2b3711b9bbbb7bc814426167a8a43833074d0ca5532876b20f35016088084b073566a698b9e18ccd7d64af8a3224bbbbbb7fe04765d65608436ec36e37a789dc4d66979b4c0f65a4b082904921f7f76d0350659abae89844b9f001317a4e708109ea8d175cd30f7c0e0c3664a1dc343cc1a7ad04ea81cf329f24513e6763a6702082030f9906079fe011ddd5ac59ee2122ea74468c9d1bbcdc90c3182bb9b956b43052a2efa377c2ac71539bdae8ac456aae6b938bcaa3c36471e5fe115c4e466a5bb3685bffd841dbfa59a4c894ba49643f180c180c0c10b90bf73f180c13b40b3a032901d81f867d2b827d13ac45dac89ad885f4c8694a47fa7545ebc87d80dc5f57a847316851ff0b182ab7d7e637bee87967e7f13d6ffc5eacd5b891c39a431a9ad87751d7eacfe39fe281ec63421188fdcf7b10fb9f98e941ecb1692366bed75cec63669d43c50e931770d0585ac2dda6902066ffaf455d614d80c180fd488e3f83cc2209355bd23c6d261fe6fd583bcff31c43c8de7b9fe4b05a0d1b397caf76bebf076be17910b09ec30f612d42b336e568db67d6a56f0df627d282da814b870d5929e0faab133f528a72e3040f1590226deae0fa6bae3a793510d6c27358074a35d3ad4cdbd6258aec71879acb3018b66ddf7f5eab368436ea9a238605acb4723b97d59d8ee99e7cb4d59d0e40b7fd1ce6002767e5107882375837cf192c32f8de535b13c1fffbd1ad29c4417d6bb278123e4ac630dab8b102072b3adc14fffbd8d2bae0feb20401882e749a0491034c9a3a40e010e48b0b150c4f6839e0f1d6402b37402ce1fa7149c19a87304959c2b9195407f7f797fd14f4908c9428e8090edff440511493daf344f163ff899fd4b337f8694a9a64797247cd1299396f9a803873a729cd9c5ddb68e7a0f04977fde447f44dd6094cbcacbc116202ae0e40cb169517f2c89002165cfdceb5938c8a7159fed72cafaf48991dd5b6fa630b54555986185143660e0e1b26c80084940b38bee080a04782cd61b032d5654a15c647b60a922995558e6c664a156697658010c20c12b53b0df0b26782d0b62a45220d55e1e9fc68f6408fb170fd59edab350b38eb0589ffccbaa56db57effe2fef7f73f5388c4d38caf6ddbd3a8f5bb0755e17dad4ebc668d5f8d83cedf7b664d434fd4efec7d959292aaf5abd51764069f356864d014e1637f5627356a9fdc5e19c324be8f44ad0625213e0993041a349f34f2678e60b3ece7474c669144cd66d13cbdfc533bb1193343889932601540c1422fc4f7bea759fc4c10cf1421d0647109e192038233448a805a218a911f5e0d09d3d2e03345ae7f9a7882c5a795c167cdaa0f825944177e04f4f51b073e67b0c823b46d86599d6a20d0685b147cd21d085d54ff8e57ae45541ef6294c06ad0bcecaf56b168d5a65d068c05da385c1195829b2b404cb0f7abaecd89932a244c897206d68f8d106a248a9b261890f9225b8fa25f8111523e58e1c3a2f7035b580ab2fa37e08ad0bfa41f54353a67fe74ea6e60823253283a33a1e4c4eb831a9ae68153a012cb9f040c60c364b6c5e595a5b5c5f0440b2f598383616b5d64a00aaa2aba2e80ee00cc382bc90c305f180637c90e442b6dbb194fba7d65f7e068fb21262307e19f9b0ef2fb93f275115b1c79fd423128c7f7c1a7e44bdeca9c10d0f2e7c21b20b95ec901ac3c74a9b16441109e966b3a0f8e303d548d47e6a942295371bf8f8c51acdb6767e6d042f638cbd8cbf6130647dfaf4c918df1610854fba801a630154050734d70edad62e62acc127dd11d56c6d1b79e0b3615e7d10ae48b3c67d0e3a8f4340024c0d79727584882c4d7ee5ab8620ea6c6901a2d646f0f257cf11bc1cbe679ed66b4b595f585c565bb552acb7ddaad287356c9823dcfce50fd36a4175949a2061a3e605188c4812240343a878ed8240034409995cf7120fab203b294ef249efe88c80c927fd72ca67cd5173d5c985ef4e30864d9a2813e2dce9c2718006215b48a2a6f61481a3573dd491b2b485440532b8fe10fc48e9094b17952398f268f5a1116bca2464fd13c6cbd278c10e4f4ee863a5f301cb08987010e1322605394f405c3c7064d0e10142034f832a284042c019b0a877411aa03adf18f0e351a5021ef0ca957ea019f2064d152270e878e0434b8625ad1956c0338504e6654a8a05be0358e25aa65460ec80d9951929d158dbad189eb7138945266b372ff2a29088add622860d7c8735292f69dbab36aceeb65b197117fcb0f695a06903b7883143d45d136c5bc56a14657e2edd01ca9718020f83bd3bf69f1f2b492286fbe49f1f41cf9e778b4f92e65945f3ace6097e0ca61495c1311cbf860d4d124ae4f03daf86fd1088003e7e11c0f7d18ef6bd1fc11f41b346783ba01b5ca07bef4d72fc74c44be689cd968df7c71f2b797ffc7b2383ef5e0e7a441fdcec71347d382625dc6cfc2477f76ad4ec7140738d2fdfa7fe62cd6b0db02f9222f83394a2b2835f23fcb3844c42891c1b1d74b346f8a7377b307cef419f79668d98d90485d933dd6052faa0a0a0a0d28b6a528f3864ffd92c68369bcd66b3d96c369bcd6826a51b9c33137b51fda0265c674141414141414141b4a0a0a0a0a0a0a0209a8969913f93f937669416f96c369bcd66b399293ecdb0fa14e682664a4d9ce29330b28d425084f0677c9904cf4a444b70f8b54f3ec117451804be3e7dfaecc99e679ea179824d66dfb0264d8f9b993728166e8a10986deee224d707a9720dc3654bae6f49e8c0a9943ff065ef9572c35ec4b243a05f8030079050f3670abd00b3fd195ff64c123c5ff3ec0ad4a60fe37df24fa5a85cbff635e88bf03d68d6a07d7213127f9ab22b4c9fc26abe6735bdc8ebc0c459cd1a03fcfadead60a699668df1c1c7caa768c6d05171403168260edadb50c2d17eb4e4cf5bd88ba20cfb5bab79bc1f3e85594a4fc85e08fff9b6fb42b1f7ff31bf6d42582866c2b065d8c34ca2b6dd1ae09fe493e0b94909683168260e1b37fa748113841e228ce883a33d93128e6632053d9069d600fffead8d6613da8bb58f5254f6826a372a0e07ed8323613695c0d14c1468cf748349e9818080804a938643ae5f63ba71a20b9d275e8230039585037aa5266a4ee01385081413cee068341a6d8a35c70435e17e37fd08050a704c3650a000c7748306040404040404041404040404040404f43a907040269309aeb808d122e7072351b8a09f3dd30da6116c4d4911c24815932170407f83663291f81c39723421e168df64c3d13e475389a37d1388a37d8e1c3a401c0ed9d7d25289c3f115b1b484a37d0e1d361c0e3f6209477b1d48389ac904f4403ce480d91199e2810ad71f54c3b4a80ae182c6879c2c6b50c035b82407991c50638a988385c3fda3158a2309a34365498eb19e613c8a32ebf95597e7b7d6f48418da115f75fd8ce227840e95a5d7338cfdd6cf7a9f57ed6cffbedb5aa978d5196bd3a1b2f47a86f147c13f9ba88b9a04e9097a829eb0ef59aff2b4efa5d69b525a436bbd1d3a30a5f221abcc9829950f549952f9708552f920a55e603c6dd07efa495e2b5801d21261df91dc53b8830e7ae780a90fd1239f3b3d14c9344da6545b569902dab33867cc32f83031fcaf76daf26767e48f46fec01a373209236bd44cd2a060a9bf6fa37db95f9d506d49e5a24ca9b678e49fafe6c922d71a58842f88a5aeac8230b8deea799e379b79b59e33583ce845f72b888285bea7fe9931aa9417ddaf3a2fbab187fdfd203bf8fd88e6906586344b6230820c1fdcadb243885793324cdec8c1ddc7f7cb1b7ba0f76a405f41e7c124be8230585613fa79d9d76c6b423f6f1fff887ffcd9df1f1ac79fd55a7c71b65616cfefc7a0f7113a0799be4245317e92cf6e399af59cfdd440f0029b2d64b097d5689e31ab4ea2684f706984444a0a4dc027b572f1410833dac803103a88610119df678a35115a1c45530886f8e173208ee6f93d09358b4ad95fac755883b5f882aee0f36fd7b4b392c846773f2d8bfaf2d745b86823dac2ba0b1a55861f61f79def7c77c50f4bf8eefda7e635cbdb860a182e465ef0c2028404517ad8414961cbc9080a5cc042f7c3a7584b4b38a16bc6185f7cbfb66dfd35171e23c80e3ee96ecd129f3eba1a72f81144027198d2e8d97365cc139cbf8c10ec1f802683832dd4b952478a8c12f5d7dc61be2859aa387239e8703433f8288608d5fc8056737ee3412b9f35c7831b2f12c48429559d3bf9acb93a5ad99d6a913ea2387f0789928c34b8fc88e228570931fc08632c4ce98dde1c88fb1377b7cad113fed9033158d19201090e4c29e0fc6b931f755066881bbe5cc8d3a405e74fa384d10b9f948bc6086d24f4e266936c9b83379f14abe662f857ffea5f73fed5c99bdc264d8fbbfe16042dac5983704073cdd5c9758f4c6349d446e2db84c214367fa4392609c1badb07b5145dd4b60f4230c68dea627c90e4624a8c0f925c5c2ce34c08ec1faba0ed6b63738a21f0a5aae9c797304a72b8023061c2044a0d3f86d041ab017b8bb7e152060768064a29a5957ab7249770bdedeed65a6bad93eeeeeeeeee510a86a1b5faed36480afed2d8f79007ae0f8301576badb5bb91b6f96511358c7fdf0782575d60287e200c86bf52fecc6cfde2effb407104c15aafba469208f2f3deb8fbbdee55f2b850036af61ab54fad6eadb5f7ba57c9c3a7483f519bc9d1cb4be45a8d9eb018d72e0514e813a242699b7ce20a74522eab528c67af7dba693e316cb06f370d0f43a8f0b0944faa1b4367ab0bffa809e96c21d263a4dc092e9129151d25998e0a4e38e8be4ff4aef52406b8e8800d0882a22886c777d5145e01a9caba0a8247982ff0ea8c116b85e55d49bde037a45b0a24315617bcb2a2a3afb8aebeba88e613c45747828491ba5281851b9c6463bc22504f74f04fa654503fdc0b2e33a54aa2272a89160132a582928a6331066df96f43b2a0edc6d56327a3fd844dd9644476ad30d99fa8dcf194648627ae3b5d385cec904235dab6fa3fb5cf75727b3d0cc29ba327e897a0030a59e0eed401408e7d70edfba7b5d67a0178d2da9a6ddb93b32c5cff610db0e5b6f6820b889e101191032861875e0c30c840043a5c46d46540db2844424f5c29f209494ec1b535b01515912830c82003d28489135503720314370160a7029025ec9053703500d929c812760e6074847484446680014500a942c58a0cecf85d4196b073599025ece0049094568ce544010a58c05d4052092ef9e4265132e9d618acb1a16da8f444ad59bcecbd263c0fcd0d5b6bad505e972a19bdde7a8bbb5fc1ee79ac0977bf791e341a64faf5569625177c6bfb093ac5ad0931b443d976085e0f833c5496296e5537b08d8a32d84628c4908d4e67afe7512931b6fd43dd20e6eacc996bbd0f046f493ac7b6ff3361aa3018ef034351e7efd7d66ce8328c5ead3028b2b5c3f043c41aba4f0f83da8218b9685bc7c0c2ca4deaf0f970e06061dda587418d2ea0b6fe2eb137a1318ab2a500ec453882ec0ed222fb17c4b04f6df76dcdddbb5231e6ed96685d703f4e94cde2e545c58b8a979758db0b45f0bbe29e700fb8874b77ada8780d71eb968a975bf7d2337adfb59f7767686e36f7516bf53e124fb0db1664da4646a0bca0bcf6ecd95366c962af77db539630e056a1ddfbae9562c20faeb5da107c5074d236282f2960744e5296d45adb0ba5780a7bf6ecd972cfb2e5e5e5e5e5e5e56eefad5f963ec47ed76bddb715665987f27ae3d6ad77b7ac7528afde42ca700c368ae2566841c67b647b623032e41eb16f0b505e505e505ef80bf662ade779b4e679de94ae0b171bb668a9218b140d3360b922c31e2b55a2a8c430454a14284f9c34c14cbc300c78095682a17012fc8491e023f7bf28efab49d944a9dce1ceb195aab55aefba0783229bb5d75a6fd2e54c0f70e65cd0d575d575d5e51614c7f07ae397f8157e855cba6be579f7aaebea7ab592d67639a9b57ea077c1cfbb6a6eb6ecdd45f6747fdc5ca803400692e1a9aaabaaebebebaba4056dc1d6fb40f0ebfb8af9b5d69b68b1f6033d8f02f6d7d75f5e7f85bba8ec557eb028babb37860f82352b3a8101bef816d64234cf1a9a186c5b555714d773f33ecf9ef17af83e2f4a1a107477fbe93cffbe285bfc033d0b7e7d5fde97f760db4e0f5d5d5d5d5d5df65aeffbfccbf2ca7ad7730bda33574eb78730cbabba7a5cb76e41ef4fef7a5ed57567fcc431041f698b9e90e1eb0b89016deb2046d298efcbe63f74adeaa2555db808267233d1b404b5368f1e895fc043b01316825dc02de0209805bc02068273f807f6817b601eb5d62fac024e01a3809bf00eac0333e11c18073e019b8097fad45abb8e30a20822f8ecf9d2e39ec200df165a5019aa827e4f937449b55a6f92c70b4fce8fc4273f1a3140b1db204ed46e2a4e2c17a58be52a6eac622d290e28e759601a54872501b9ac0ef60472c1b83028b2016179480059c8951bb4b22790cbea422ecbc462ed6ea2958a01643ab3caf91175faa2951fb9b012ad5ab8685b197c8a6e44376d748a6d721b6a6565bfca1297ef626725eeac0902c821c68a9221079770c1ed760bff92d60bc159db70080e95de8da8dafacee8b6e6b6a42aeed3291bf6223d5f96379b2d14824e5d5dcd855cb72a7db57ba9ae8e852e23e9fc48fddbf956a94bb736736b163106201379f4e8a325f5a27af322164d65cb6e22cd74b8d932160b5cb9ff0680fc8162dba9904412185725f1e4bdbb05a693e082b260a86f138abd766da1a4e96e4199d2f677b39c955cf0c962c50aaa82e61a054bf9d1fd2e0df92cbab7cf2b7177377ef9ee98e0aacb91b851f40414716acc2dfdd498d3f183bf9b9555230fbc3c72cf565c1e15458335d189b8a426f5273ee5da28481fdd9bf3be08e81484475d7181b0e023474ff4e71c8f8c5210ac319913af9ef8e47b2a7ee125459eae0b4432fd3b84aeb8412a8a769239f1a37b9dae936c8b6c4b1b9d322d322da1f824b7f8f599a195d35df27483d41577c825725db84ed749a6b34f80962a8c039bfdad541355e1d190cf5a6131ac1bc4a98dee875c58c8f42f10ba22dc5251740e26440c2b378c4bf77ddecd91cf708c5468d536aa2d7545384551f4875f422eb99f925074404b3faa7d4abd921e5d8ff3e9f1f4dc8f13659b8bec76c55c4ecc85ba127570cd9120bc7d79f2e4e1badd6e27ca34f4a8eeb6dcec76de975c4762bbc6a22a3c7b259fb3abb03c0a77bbb6f59365f019625d3d5985586d74866572991890dc1dee62b9302b4c136285bbdc1fee42ad3e0ab5c25db88bed5cceeda6a32a6a8eaa703353995a2c2fdbd69e5b77cf3335d616d75acfbaf560f8e997d789dfa87be54add2d57e747b127aa82b466327d8b45558cbf34867136b8517534c35d54a527c4a7e27f1664d17cabf45303bda8bf7aa3ee96b6e9da4675ad1a8022bb8971c0f56162d4d8f785aef49f8809b67585970981ebdf645cb8fe0913b95e32835ca98a5a6badb22070256540e04aca7ec0f56577707d990fb8becc0eae4f94653dc8b66475643cc8e8c8b4707dd91c991c5c9f0ac9e25020dbc9e0c876b08094bdc1f5656e646d646c646b707d5916ae2f534344ca74100029cb6100042065696cb73ce62922656830206567707d991913a40ceb04292ba3012923838294e170236563f00624a52a6e99fe78db008506274c648041918d00031000d10566ed0300000b86842ab87d47a4b5dea2eb8d12dd277f1401079ecfa8448d7825b564666c00008000c3150020180c0a0644229148284e255db10714000c648a3a7a5c3498c8a3510cc32808822088318610638801c61883104365e400af44052547af6ee6707fa28895c133a190fbefd20be8dcf309137ab68127b121b5b15324b7cb672000de37a2ffcf40e0f1ce32bef8660d084e407bfd0e2eae2c2e0d8a015ee7a90a0ae28615a506f1b557d36082920e25659bbdcf5b87ac493af41c69fe88015c3bed059607f401e90ac81e14bcb03204bbef877175b88fc36e52ed93a044e9bae0079260c1ba574bd1904b71c010854ef101d1d4ba101ca0536263ceb4c58b0988d431946e3b9de99dd01480c1e131234036a09a54ea572f5050c6a2f501304137fe3eaeb383094206af1ac86489caee54b24d5b2902511f5c2ae89ad131d3ffa347313ec40f2b197c94a08b36b0f42b9038dcc721823df8abe5f93bfe608af3b65ec0d062086bbc7b85c369c820120cf208cac83febbe52be5d5aaf82be2c903fe3d969ba84eb27b4d7106941a84b21f410c528d9130f245762bbe9543eee0891bf395711104bd86a4f5cff7424ab37c45f5611d1bce536d9e740b2b8ea9532b3e98ad4a47ee0aa61248e75b8547d479d66463a9a91010e1295cae40a5ad0e600e7978b8ced147333b08a0df99d80b6bed5c71ac8182d2f24ad6200ec2d787fee640af10d4e3f74f8ed3facf1462e6796e0e6363eb9d13926a0c54e11b64621d9f82a52ecec40cfe8e69f4afe0209f5aeaf4a86f43a0f299f24e20b916ecbdde311ce55931a445b5282a06f9eaed2673bd47612160292bc2da8fc78cef54a2cf4a03e9faa09cb9e0504b443df467dbfc464a6026f85a2f60a1dc65ccd67ae51baf0e2f1eefbee2cc381bb7316d80a75466462103799381f5f93fa50da7c3dac9876966f9403a648315b13b93f9d1ad45841c58a00557f9896aa129375dabeec28b01c66fe9054aa95cf4a2ef447fe0bbcb83a427282c83152c883ae110cfbb45aae0d59b55f8a04e0ff431eafca10a4edfee796272bde78a9d834c1e707ef496918b5555dc052a468f0c4a08cb1cb8bb401290b3e71a310e4be69be8fafe27376b9154ee6b1d489adff6cdf02271e1f6a647922199fb2348196ef6c400eca755c195efed1bfa4b81a42fbcf142f9e9f2c1f2ddea9e021015f0004c2f8873889f7f8d088b99853132704102833ef700925bce250a5301e4b5418ccfdaaa7dc08807e2ce0a70127dd7c93198900dfc3f3426530ac9f9f62d97b0dab263f4548a50e5e5ccc6ee401871b653d325869bffd85db3d3cbd7a1d19ec6e7a0836d2367cac2a5cfd327a929df78684d9db9f76f3aeee9f4627670818291656977f54b8c87e3028ba0f059ae974645a8d3ec58db292b5bbb3ec6ae14733f2e2eaba6250923cfb20641fdbcb63efd98ce9742a7459324d1f0ee9e368bff7d4e853e1ee85ea07409fbb6f973dd367692a1020c73d045c00cf41fbf3c5b731310a7bfd5f3cc5a2dc379f264cb44a60b03bcfb6405cffe61bb8d19241eec59f0cc76d417510084bf52d23a19be437ecd4349c2a36129a423bb7299959afe59c0a91ec5dc89cc19b57a5fd1b88d4308607ec171db5e35419d26867b19a52b78f44fb7d1350736977e8268269fb8869d8bba1f52e29483c8e10c8b5526e55c68a8fc7f922837645f73e1c51d4ddeb59aab7d96fd6aa4e7502568575a9c26e0c7255e75add06fcaa0080fdbbc3abe8ac4904d96e9d3fc0a382320d05630269d755b5cf111c9bbeaa46cb2e43b12208abf6af0094a142d90295d1643ae14e98f079c8ba3648baf6494a109e652d865b07e0d56055e9a8a0ea420b5978a7ea346461ebf3f76cd0a8819991311eb0de14c4186d114992fb218118de2d52d1e4366b85e83bedeefad21342ee5eb607a0a80aa77809770608118b4cc1ae792befe25f3e83974bf3c6e4ffcd1e9f989b68a7fdacd7a301983ca9c43ba76e8488f6d6de901c4a53c31f9758d206c69622905d01d7cb15c1625885d515d69d7d0cc8af8d93d8bc07515d2d0604207e99e697a7a2ab8380cd14dedd32bdab965be5969d0889d0c008ae41890028e4575eea29a7ab9095bb9993233f63ced4935ffaf64bb54845947deb5355fc0048e8ef86a6995c6dae757358d1dc609c5ec1ac8251982dd18545b63d89f95545849ec9d9d1347dc348d0bdc54a26de6c471232f754cde1617583ddd3da8a0dd7dddc404893fa00e974edd5f4bedd0003955b1c2c2b5ee63e9456c2958754fcc94088257ad5dc53e886079e5360d3a897f0edd02ef1565e3d466be4ed2ce3b1fc46b836458001fd90ca4fda6ee9be1ee4c08d764b03a4c19c08b7d8a2d253020706688b5a58d24dc15e550a710a3d4b3f10c3e7bd287568e572edea6211f401e45dac7a61acf2701e98e39d4a1012cde3aaa5f86978a13e3025593d924f53e12b431349a0565c58c77474cf31d73f6c4a32e8986d2231c92fe5e3dab730cfce3953c605d63938365d620d1efeb4bf148557da4a5b0f20e7c2142f43e4e6b16ae113d2660ba7b260ab8a2526e99d846f59da866149d013c8e61d8a27e759121c06bf035745988b8a7b3d99e3a8b896257063079b2d455aa4c96020c172605e66d7f4445027db086202c7f583cc8005d2679d520b2a79735db66ccd6f9dcbe2dbe177dbb12d9537c182d5fc5a8b006b84fb8b3b87b57cf3aef8106a9f8b15c3cdb9929f5920efd8040d589bb781f483678ee1ecfa4783a8c4683acff955febd7ad6bf70dfd16ac54b4bf45a16bcb5b43649a4a36c851a12655701927de8033838aa65c9c6d0f329d33a269be003765ad9ca1c70bd2ee6c555ea3657ca560b8a624cfa8ecf41dff893fad0979ddd440188855dd13e79a004a32801b57a09a5d351fee66062c41e21e4f64bea1d727c01ed06b787673f6eea93211b25720c74041f63c8a061110f010ffe5ee032edf5e5f74e79d639add01c0127219175c4d0d052b4f9778ad593cc8fb46537c4622ed4b47cf9971a43c4cd666d79acd126b6a7de3d47ef97683f3b861744ff36773b638b41e379e7de5e0e236ff96f0e1b479e8bb71685681c1f811cec251b50c4b6d22d18235d5fa38dded4732a36de4194ee4500b5c84a2a319cada6e982b84d96586f87692eeb9c150776320fbfb31cb5ea4e3d9617b378c6ca89d3c72ea9c930364f6a181a792cb36921271391265c01935185b9141fe5189d3d9842ed44cc9174fe36d202fe2b92af097f34c8d6730d358631526f90b856731f76be00436860e00c676870d610dc28849ae74338b27dc1c20b651131827c20f370a2699e43231a2f0a2fedb12e036b236a94aac36a395c5f5da250cf2d2416b12f5ba36b89fd441a00971753719f550e63d33b22fb80a53f594de608f66d01087495a5c131ae0e670034700f60370082b8df3358eee077ee239b16dbd51325c073d783121d1b6d86e76c57720ea009f8891b2d26818d3f82149d2dd0c6f657c6706cdb012861b6fc5937fa4b219a6029496649f83c777086510806b7b8c1cea2f7820e366af935fb1c0d929e4d8a5c312b0cefb205f4f8dafdb1e73a651be2f66cdae15f15fba4153837f2cd4fe0e1ae936d1e6fb7e7133adaf2abd46e8c07fd97cee117752a027c845c12812018259c06f88a0205a0f842d72d4ef4e8b04d0394778649134a319d0023db3b4e900903778da0c3b9bcd042d1544498975334ea2ed1ae2f2d732941f6f4e46b51a88ef5d439c5c18db7a8d1b37cf7e29a132f5acd131047f49a53a6649255f4571b2953f91166ebd9ae98a9bf19f01f05cd32093541b9592982782bc46cfafe92e207696d053130395be8ba058a15d2983a095bb83b9be6dbe0d9836e27143d6a05b43a202e78fb2496b9b5d11ba2d068cec81acf3bbd62cfd8fe7a41ed0944b6b8f52516d76822242b43bf84ce7f2bc728a92efa9d385d81bc5e2765697d70392ad0cc906a49be84a3a5c706d3ea2762d1c0b56ef9e5a86e78d61fb0523b6ac1c5bcf9a3f6e6807dc811991a28037f747d8c2ca2ccfdcf6d6d07b3bb237af1f2760aceb3acb86d5edb6607fbb71905a97508236f39d7d3db415db006f7633383d746cc764845a1fc7b2739bc70116fbe1f00a10e248ec02bd86de645de293a618ea3cb88fa15d164978de2e09ae2c4664912cf78642917fe3f7f61229f6bb7ac2f66d47dbe59b58657e81efb2373324e63eb8ab3f992cb9e0390df486996029e2584780bec83dfb64494116b579998994cbf948a979274480a39df970f972b105f525a92ef616fad49da41e91779cf24e2c722a7ef422a91bcfa72c4a25ed51478f16d3990a69f199437a6d2039227c93c60e94f569329b8b9077a08d5a553b9362445993526b619abb0f2386cae30ba38485661865cdf32a328888f3c57b05c95d2ed6aeccf5546dbb4eb044358fa4e2dea7275e103ef1cb169470981632ace63752045d507cfc50784320a7ca940aee6157067720483b75d698215fba4d3cbc89bf4d85fe85febb7050815a08cd2a1d666ec8c427112c658bbb6c4a8ab22557ca2eb815961857f56d1c5b0ac5729cdf3b8283f0cdd218ad0bc6956d1fc884bec25d17a413388a76644e0b481379eda00a0235f8de84db683aa5d55e4274ba356af99951e26a5b58476fcb14c21c31dd30b49c0f64f0a899b42f007569602ceebb78d9eb64e6ed726f63a927f304df83a0c659cd3d68000ba52d771da59065734023ed8d591e63968b4c214766c595f0ab343889f3ff2dc07b07b8d1d51f11e39bdf778403a5e1e88742143e228b8dad95a7c36e06300dfd894edcf2ba4d1a0e349dd2355ac1960b49c0dfc323836cd406b18b58dd74e2a6d7eebf103ea2decc0eed9fd34bc9fd9f65e82dc90f8e4573a2560faf11f8d770efb0647fccc1fed292b93a11095dc6712bb537e8b6c154e58b721bd2bc99f19074d6cdbad3c55809ac48742b6d134c1dcc707f6d04c0d7d08e851cc40516265e1b8b5700c23f51bb13f95466eddd310961db5ef2e33cdca765b4604cc25ccc5c7577d7a7198afd477e9c63ed6a0d771447b841e9a2619299547cd96144856a1ce94dc9a7bcf4513da5972b6806e24b4d65837228bd759f716010e638d20047711e84a88ff7829c11f1e1791d4a447b07e56b6b67c64931d1792e89ccd3315ff97f0633b132a78cce6208bf779863b83c7e76417709eddab5a7d70d098834f00836ba4bf23bf0f8275cc405ccff4a350d044e4ffbfb165b00bf471d60960c14d00bd947c20bb93ac8cd7012872ac08c0241f92f8dabec9d04d07b89484a1685a4433bc0815c43494c6dd642698503d181152f4d6a339921058c57e83c0149017119771bfbec0859fc50de32b2a2705477611123d805916428893f81c69ea4d9c7d8476722a139cfb248c10d023fc73e177aa19d7f7f4d84a350e513de5dba64e4ab82275a215b62ad62322413a3d7631f17ec031edc019da4f53343e957dbe766bdf59a7e16aa18f5b68a4b4388c0e88099192e3b92cc89f0003c02502f35cacac890d956613b897a76711d613724030bd7fd5867abe25964a666dc50121b38570f02271ca1c13b7e59b6d74a5ed2327cd1f33b3bcea8d902135bcd529e301ab8688d23b4c0e8145051bf641f3e43130c6d68fac54fb0c6336cd058026d938554d3d2eede7e5314dcc4246fc90b5500f45025072be7222d6639775914f18e1ce34493c8f8a8d573aefe649f6fed561b2710039ee42a901b18d6db81ea9d5cab6d839a25db76d17b7fe8ee3b2f2a9d20de5449e47e70d933795a6ecd6c7422b7bc9d098de0528903980c806521327ac474e4c2606550abd4d00f765ae94f93ea5251d7388cfc6d790efb4191328a55953dfd8287920595f885a10318ce468f91264531ac0ec0162838fb51d1f263b69cffea0ec3554fd878da043645a7e68ddfe99728db8dbc5a8b311696f9306eca9f007c74af0067c064ae10c89b704ed7996b4748824d0bbbe61e80104aad4ba95090bc87c4415b158c4299b70b3c8f2f20e8ff403e680db113a90208422a2bacc16e00dd5c7ffdd74c13d57ce4f1fcb0f5b96b813304936a9e0c10537d96a488e8fedb02f1de280d1905e8078f0636685ba1e28b2cc85f3a26f4ed807182de95994d49fc4f195414c84b8d820436d786fe499bf7b2faf3a516fbce4fd2f30dfa04bac4bb79dd8e86e0191495b224326e2712b8d712edbff37e324482e501300d8690ea65753c60c3a0f018892bdf8e664fbe69d265b78b5d01c2765733abd9315ac585f84592ceb8472ced5f62b7b98bc098b9b32cb9229dbbd7598ab2398c63235217d904a7432406cefa5646e22e743d12dfe1a98e799fbcacc33de2157223f680c55e04bc107e818cbe9babce7555f05c651c1e268d686e6e1524a5628360b5ca9ec830328a4f393fbac208e0fc8fc5af4b2b058695387b834b38ca804861cf46fab03db8affbe667a95b44a0dc712d312227303b93a75bb4de18458dc48ffe5b62671bc8959657eede3bc5bcbd79a2c050694fa3031044caa95a32e9595341f035060ae018f924de08da1b6e9eaf794065d2ea850e60426c4535588afda582d6ce3d3b9726d33f2fd58fd6b91674a12e760f53947f3604b559ead782158e1c0410cb6261dac3a508ed9dd00cb8ac10b13c90bfad03fc1b32a4d2083a4751a46005c3ef82f4d263abd1dc68c28c50265d59586f5cd154f57a2b1a94e21de49ec497b7895b282b52eaa2d32a53f17fa7e9452bc51dbe8db767c5099897b5046e828f9531bb54ece71343577e5a411f20b281675983a190941946a034b04be25c2781c0c9680b064e95206271461c25a7b44fcce0cee8df0611706508a3e4966702782a0c33980315d0bb2b0b2310c192f82c1c5836867c56e7f48ed6835975118ae69e5be8e7fe6121a679de7555f0ee1fb569d0c14335e1ba4928532758863d078a19ee879aecdc5ba97aa4c8b348f2893e08ad6b1b13fee8c21c63276e88cec6720dfc5e2688f5cc0f186883dbd8405826836a53116c14293a8170e62eb750598c5b3cbbfce5d0bcec95b4f6cd495e4a1573a18fedca5b84b1b64e744401f4e503e90bfc2de5cddead9ccf6fd3735010ae7fc582c1f36fda8208e2cf4c399bb4ec99d426ff9fba468a1dd21d8fb9f1f69a3a24def7bdf3da53f1520a87b7055cb90e0c65fea88329e7572ea476dc5c424d1d4bc78a079fed04864621b0a61b7911bec2f697eaa86e3697acb08cd3c238f684c88f7af41a51d6a4c4949f001fb3f000bc67b44daf484a247483304591fd336b025d342f1eeeea0ef8548a9d87a945c12f5b94d0e271dbccc2968bc07899a05fee0f1e7bdfb7ec059e9a745c924dda3dde540a3edba7de33a4f7781d099963b45c8b14ec38269ee856a3990f7c38f8128414201591ae959414156787bb47e3535920c936e809a941f030993406e8b6947f7006d8c9cc866f648d1bfd601b3310e285e44311b5e216994b24c4689f2ea73c0ee1c2fae266e2015a1cdc2b2094047bf0ec25748d9930663e2660b9573b6ed51ab220bb87331011f8fa856de24ce0dfdcb5404474ccf3b53d171482dddcf76020e9da1ba7d3a2912e45f6a980b8d10319ddb2d370a83badbb7c146752c2fa13f7ae4ec2ca880c6608e33b3ac9b99f70c3ac6dda25a865604ced999c9973cab90d177c1d140e74b111aaebb4254360006147f1dac4af8dbdcfd4ce1bcf454a6523a1d5849ed77d6bb0350202328072b187fa48cd96331ec1678364f4d09b2429df7847659230d4ba1f06da5a8ec1f04c0e52c7c9707861801e83b6ddd16e4fc81eddd044d8791e6e631755fb4efab4e770bac2c8a5b2478b4429b47186de6dbfdc9f24cb047733bb01020b5570a3493636c63e41acfef660b754083bd84acf7fa15a9fc6a206a82433eae59a4cae4f3ff2868fb36ffccdbe3446ddacd6a70b61dc892da592d5683abfb870a3c8a96defd4fc6fea2c4ee19940fb30c4d33d0f2421796995cd324150fbbd48ce52e20f9871aa0943dffce050b296423b92279921602b2d97951c021a5dfdd610040d5d582ffa7b42ddd72b6700dccccc3489b1d6498ab3e7023c314f20da39c44bd1c4700c43e735a442e873c6dc47779a73bd369c39acc529669be7d30e456e437730c48e076cd7e3f9dd2967ac6be0fa6e67269895e3731645106b18915e3286812a6ecf4e49880c668075047699dd1e36986424075b7b1daa03672ce57755751f5ba48914d231b8038281d1cf8c146fc81fe8ceb9da88152c0961b1ed0054679ff186e99c10c2ac026c655d545d3b861ab86e02b863581682fd2cd9252fea0746adf40285d0c5c30924e6d4de48d9dd54f8f97505b533684577cf3a644083ce920d4f8a1bf6c1d41dd77121a595dd7238966bf8e38516bb3fccea61c7409d32264be35e09a8b8cef38be197d0387924b2a9f8d64890d62cc21456f16e5b2fc51cab5d0f48e6076e49d0a319f6cf520c689c13a8eeabc0a98fb7e5d1dc1bb00ef0f138fb818d73d722ee92a194c906e5d6ff90b2ad469bd50350f69b4bdb891b456f56d3dee4c2efba5c16b2dfc9bc8c32a7cef832113878feced0b7ebfd0c23db5239b7efcb7f8764abf42b2aca15d72be288a7f882d8650cb118720143c50ea62fa1406826fc07e520b2eddf7588ef0e144f9c60b84ac0404c55d8e649930a266ad72749d07ea166c5bee69d0e85876c33f94b7d98bc0d468effe80776b024f53342859faf123f347550dcf143bc38c3cefa5336ab635c82af73ae1c59992d1974b1456932300baeb49c31dfaa10a2441a4f6711724df8bfdc1e18b0d26c8777870daaaf73139a235b326977fe006d5fad870c570e1c45d0e5740f6c5c8cbcb6b6bbe91a5cfd3881b7899a6986497a8807cc43d9ca0706bb2f4c250dcd21a31a2b0ffa498a37a7c0cf383c3689ee4bb97d1a062e81bf24477e03e84f4d3003769bff05fe805d627dc5774d8ac8b4068e944c85389162c53f30872c7e046b1a6ca2ff84d37d8b156dd23eaca062c4e7e72748b360ce5c4220dedc282d32c4d730c4c8e18a651ddd50c674f6e3f07cbce6e5f9beb075d1a4e5419c1c559f958ed61247cc3dbc69f45231e343f1e40fe9d91c94e893448e85a84242f1c2b6d6f6c13ce6d104bbf83afdeecb6409c3dc3cd70ca6c44b45131da68949266201ae20ac33a10f6aebc0a2868546c60a95744c75a2a69d0e707888d80a0d477e5ebf7d0c1520b67dc777f35ef5de1c8e505e17d7f4f96a16138ca1744a4626f4331bc289c153a956e5161a1b9f2be412493f1ce9eb2694c66e9fb6fbf120a5fa2011e69fbbe58f77d28244e72c9b020097b865fd5842c859003a8e1582a2209e95815422569ca9cfb3f9c15fefbc19192526f0a15aadb218e6dbab491c9f48f5c7c1fc09614b64a4dc093985f12e2369b71039e3f61c209d3cee988cc538542535b2ce4ec90ea1b46b7976e5d504b566dc7afd00c75adc3e034b55992ad3397d7caf9e651a155cfbbb63e20c04daf71e75e94c04d09098d06151957c9d78b7a851b1249afc8c8823c6ea5e4154529ac577ccfc46393ea385c596b643c10d74c101a97f1ab70593702ee6613be91328b0cf3710d77fb9b5b0f5da8bfa5db4680229ee4ea9b006c9c3cf77462a176bf7259293e72986f9693941069e392960fedcf0d34af9bff762bf4212732101f30aee595f14e8c216e5df20b8c19cebdbb32f568220b53875b8c3146d4ead8b85279fa51c652cf55d6bbcae88530e611823050522fb2e11f35225d8f8d35af2f005e2a8d6bfc04023cd5362863fdafe5496d04f4b54e00d427cbfeffba7303c0231203a2b5f3cea1f8ac9a5afb0d1869d967e34c5b6424b53307b613b8618543ce0055d18f1fec46b224b8229505c1543d27dea5cf3b754ea600203c6117df30c9a41a5d8863989e1dad30e15f7a44f5d709e5470b80ce7b606b732e563f9459add6ef7e92b272e4a2f0b945a502168b1882da6f9dc03b5f47e3262642e52833bc6786220ecba43ad4ed9aa8bb9c3e6ab7b98b2b55db1280fb1f71d4fe1c4ef98bbee7b1f0ef003977cbff5aff31e3cf31b79a0371e8f1afb95dc284d1a1f11619547c3d7ebd3207f6446e327556fc1f02fbf49d3c92515341a6e316d01aad858c36270f80c424d54f134980284fb308ebc8aa4308c7600dfc699ff114111edd1f29ab6884938337a98c66a495c6184d2266cb3840f02b7b104080d8ec4efe88777ff8f0fbda04946e1422f00987825447e6b6c9a8e8e0bf0402a947ea528bcd4ee18ff3d44732bc474557a30bb99f4057b187585a1ffc61b4557058279992a997d102ef1af933bdd7d753a504119dffe32b5f819cd7f0388b137cae28ce4d530065d63a2b658e7194240814007e01161789386ff1d758c3b0f2d90d8706733ff372c1492195e59c49b32c31118e7cfcf6fc3824fca9e8e82a1de05c386e96a70e71bbebad4c8bdfa5e9726ca29e7db1a997b810a7d302be984d5672736e4f5aad8134d7e353ee1d671d62be920c75ad962f762911ce6676fa02f81fe6c05cbc96e83f3cf96e4280efc599d375b4cb1b14dff02a249a469c4c5ea77ac195f50d069650bcea2142586c8feb9640e4d10570c8bf3c7289c37383a1f23b41d47ae07a0d6c39705ed37aa2371e0ee512de206a493f3b421c0754607f77be782cca8e4710307c43a614778f68a51bf8f8d84caf9bfc203e4970d129f5615644fc620dfbdfbae861cdb6b9344a971a9c0fa6f1af40d33b11eceb0784188141f4aae79cb4c393fbe3b6a8b11dd8d0591389452bc72b2517c3cfeab70d97c86c361d9bfa4a0d9fc915b5adcb54d873dd690d2d0df6f23d7f4fc5bd58cb8e09c7584c1eccfe66a7cf89a1f975e5b5681c9f2f8efda1a3c74978dac5b0e7c99c547738e3ef4838ba726d755a223aa34aabad6a6f31adb9c149256eec1385aec1c6bda64f3ae048ad03666492e7dba9ff6d3bc937fedbefee98f61e0db9970167f02b2b24e156bb550b4881180624e953a8db07c49e46b7c4098dad5ce37e9227e3be5a082b387516b7de47c5f2fd8925c330e0b0453343d414a7f034865878b0a721b0944e960b68df789530bf713a8d11c961c53fbb09162812bb4138e26da9c4f4439cec96593b2825f40ed35c54cf5f92bda53cd17e93ae723e6dd70f5ded0c027fe345ab0003e5fb1cf1be6888ab046f10fd78c5dd937ac4ee93a6d2a3d0bdcacb517285a8a3560b52343b6cd733847bc862be9d39f9718db693bbb81d94c3dd8f3d5ce3da1c04b1d4ef01efe02dac3781a0550cd6bad035bfddb2a87bded039883bab10f6ec22a5b57a6cb803478085db3b6ec3204c2ab10b010b7cbc09e8748eed47c661ce73e72756a3a6d462cf5e0a3660f8a186862ef54373a54873d12579796c9d232a820f3f688849c67530de77e3ecd4df2a75c5c6ea3f570f614d024b2ac59f7f8c383ddf7fdacc431d1bddf02bff39b817ff31bd15e7aa864a34776973b2b110781730e58638c0b93af8ba79b58dd81c12c60dea3310a357947b1b885326e28cca2d0186496f8b53d6b29db2bec0520b62bde001ba0451f340c2bdd3c5068bb4630f1fa04242d8801071bfe2ef48b9ac06be2e9f3084ba690666e293bf0de70219b1cea9cb01d28c235b81b44692b4a9ad0a35100bd16d815ee1816a923728f7053afe89de68f2a13ecd8c528cf00c35816555b9d387cb2872bc0e83c132a36f413f55484cf7d3feb625307e8367edfd6990c568182da7ec5a60404b913cd4eb9678414a4b7b26835b7bfd5d21577d939c8cec0401c4ca2626ae861729c7e58eb0925c61626d4b44abfeaef64c9d3063ae23134b0f8c1aba327024237877d6df37dd86b72489407f756838a6cf9f5ec10dd2885883804505f1858dc462734fd16f52d5fa54077a88c622f24a8e0fbbeeaca69f44c48558ed9b065ccba7f72c4049caec29240ebcd17845de60e27961cc57e727bf0723a535e342cf847276f3d8b4c41de042d356e22160451d4cda3162f282faf8af9acd00d235a4a5d1e8b283db7af84483a7e13bd2937d3ecd80c2f832490c69f016dd67e94d2b80a156d698116c653c1645f016314f08366e61406073556676989e5ca17eff2750eec1f48cf582fc4561e9e1142a50a54463e1e1e54bd7e1d1a43c812bb8608289b098629054dc1dfedd0b95b5378611cda488fe486dedef6a3d5bafbae6d9dbc6abeb16bdf931e7d9a5073db5cdeb8c90a8694d610f3b66f716b22dc7f9c55780b7fdde612e15778ec3892a926e2f5ef3925ef49f6c7974345358b42d15f7186df8cf0ffc7af864393b9b7111a6f17096800aab2cf404bb3c1063b110604c7fed330ba212bf59343fb68756a0b6250225fa9b94e86b1f9657cfed061233abeb76df5141b4d001ff5be964623a98c1096c45de5221bab8211002cadbf76902dffe2f0a912092fd7ad2240fc9a5af7d9d39cd0bb16e8a47691100be06a50236f7351b88cf579c78307b7a8998936aea55b226a50bbe6fba2e621a33d333a4ecd83da936fcd8bcf9915bc89aa6df75c9c6ebdb13292a645f13664b3592df9f2d69a97c4136c4a57123a2245e47e00ceb05af03bbfac4cd0454f0a08a70c496173c740e039bedefb80f3e52b66c3055c056dda54c09e3cfd76e185f6a01f0ed19d6bfa80412fc79b27d8b54cc64bbd29a5a9dba8def5f3ca18e23e4ab8d13645dda2006ec1c106141c239f52b364e0a8b3164b9ae53402d5ecc5c9cd40fa6d823af8a0a136dbc470c9a30b24c034516742e0a290fdbb7e89fe659d86e45bf5d0270c24489735fbbd7b9109810dd578a911362af89c529fc57137bf93364be8bdae7075d95f33265772c271a01f83b4a7f67ce82b4eed169dbf16ba0cb200a55d5ac7cff2a5505d9ded85f04edd9b3d5944c27554d97ebc8189993ec50e3b21087e3b2680ae71e19b7e0a957838d584617400e98cd6085b997dc969f05fd59948caad4317aa44b52e813afaca17cb2b22b9436c1afd0c132c8978647acd82683368989fe456f6525ea3ee3230ec0400398bf7b200d0d95675e538e04fd7fe7f32b834704a71116496c52ced838d5a4411a5c291316a41077268b2b1b7a56563430229b88c2367b0726b3859ac8f651b350627c05331317f916906595c54d8ff82c6bb2e47445291e2c421915b535b6172b24b7840d2d3725d408017316ce19843c6683a1dda1584b3bc596caa1a7ac30dcefae20c8c38e9e883f27d3a18ace24ea34b4bc9e2cfe5e81a77840eb0070e71e0385ed77da1622d46e90ddd20b2e06594a502eed1c2b6a3c6c0ef2c3dfec396a477cf80fc0bb802c210804df6f4fc48f7a61061ee092800c9c440bff7bb8c81187b86aa0109a6a73ce88ee6048d83b500c4eba9e8147f933ae6e7049a460e29e3890621d9f940972148653955b07af85938508b8040128f39c242589c439460cc7240cb0716bb28850a5897f647bec49b6a86d10497b7eb2ebe5030e2ae52c8a0e0126cb9597293dccc08332bf929ef48907c1e392f025f663ca9cf92d04a9aea47b504c1160f53f90da0ce5c8d9386f6d930a9fb8373cb7ce08583226d719b0de490590e6ae2236e961aedabb5d2e94739553bdb3fe8b5efad50ec4cb09405984b6d99508f95b692d2faba6603a00cd284d63b0b6badb9ab7200cffedb137ae113c8399ea484a7764c78064b0732419097600467842718516c45ad2a4636f3257a4d21ac12e20313a3487e06cf5456f6ad70dc915156e4d4b2373607fbb2ee8eb83ad96992b8d1d4231d563ffe95172cdb942901bc3cd581b7632cf58f93ee3563cbd281ec7cf2222fa241379aaacb60db184f5a2a2a14c71f4c688fd75964dc46ca644c9f13d693bd59f760e911c7d426f6872811b00f56bdc331ba43510d5abe4aba7ef7bc17ca4173d904db391821945eb424e066a2f00851062dfb810f7d435710a7b09e53cc64179f3ff9104d5f90a998eb79fd3544393535db04b5fe23e970da906a98b8e2c6b8746a9bda36363908045e0774c66a62054808c77c5bc743a7b3de7a0504342a833cb5aed090c2da35df7ddb6cdc38bd0584d151348dd3aa4803e0fe40a47d245deb3deee60b186b44c1fca5f1c0567f5cab0528d0b49abdc12a7d2492886c50407db7c13023e255e07f7534f4c6c0e713969fd5b51ac35ec0547ca74533325dd472d995d67515fb1242ffb25358196a7de27a5a4967e7a91c0106e713e29b57170348645cae6e6589f3ef0972449741cada3e0115e4b12145047132c34647e71c9ff2141936ba1398b18f91925e95ce8acaa15ba965e39e7b0072e1a9d2a81911a2513f05d902ad782391498bc1645ce4356b400ccb60e79a3ec0a1b319414719a6f8f9eb4fc0fcfbb689002ec58cc1f5a35acbaca3a6fedc718423b2d21c7beea5c7fb68ee3a251feff12018a32ff7638a0ad525450a83b1634300b336d87c81b06a8ff477fdc5a03d5229df6a0763bd0a549acf56933c59383887f5cc7fc56478a8a8830c4bfbba03526659542b9b6d1ec5062cb8a13cb775bd121751801f0d23eb34c8084a343efe1dcf74e8ba8255149794ab4f9e749d03b10a2797acfe24e4fb8d418b7c3f0b20984b893058fee4d514bb34aa04528aee66aa37e331c3a28a7356d76d1a1701f4e6f08bd1afaf37b371a2ad8e78af5978458431df73e00e1444a2a648d8fda48afe81c7e75fbd2b591c085061c6acb47162c1399b72939beb2c4adce344a9bfc8c836a9f657494d334116e8f8bb3a8112b16de4feae1e33ce0241ae80dcd1283d27c6f0c451d585d7400e9198e0ecdf9b30d9e059ae0102386fd519712d4c01343b3b5d7b0376840a9133c9dc237c8d1bd2b837bb44747e3c452a2f6d3bbda4bab9b68d40c1ca9c97f7208c2e888c8a1cfbe083ae48e860d4425728a2cb4c7d26257d5950ce784c05569c8282f5d81534c5e61c0938e7928c366a4e5b3c96ca1946c918a058c66b4b8fbec47d8d10f6cd0fa5711742242dc56137143b7da84b3e13e35d864e56078594782d15c191a0dd7f15a6575a35b63e4d98d77e362b070a62d3de86c5a31cc3067680b2445b350b8d452c55134d565f8c3f99d569ac0661dc99e7a4de761647e241f1009e24631a4f1e179cd0c04eb6ee928fec94c1c33fce0afa8dad6bdd4b75dd6466a41f495a29dac86bbe509d5ddc6cac38ace2964b7d8827822dd470b59d80fc5142b030d7a4bc3efc161f4bf5491786f641ce76d65a009d158c3f215ce296ec661b9fd11fcdd40a32522f359e946d73a2189c44171f2fa982b686ba5802a08fdd0c84b952ed7c945685cbb51428bd6427c51a9427a2d563c0f9dc24a02544f920d00628999cfc6c70ebfe860c923827170446f33e42615d5a1b1deacdd69fe0f24f01158dc4d63a2c1aeb85b8bdcb4237ffaaae7c12701e68c8b83beef188c401b0cefcabd0872795148210de2917c0f2d7d44bba78842132575ffc725252bf77377d21e837bb6d283ccf4987a894e2654e81043d5b7c61c296308ac8f30e41dd0ff78eff72f3fe87b840daedd76916a7ccdc9daef0db21e32a5265f01fdff449a4200a7b4158096c24227e22eded8456cdf3aaf3fdb13c935b6f63fc4a1122d85df426bd367e4aeec3bde6bbfb74626a2563ffdc2be582d59588eca8911b64fa2f4a990edd94881fb92e6d4c36f2fbe077ed09a119efe5832fc8cf44ddd491f28f1817fe00824cf27ff9404fc6029538d99d09f5cd613f8b7e808e894706a4f4ee26d3fda4b1df127a3192a622afccac603245cfbdb123cac87aac7587890a82947305475adbc50b2d3a572e277083834c8e5a2ef4c560dae71b0dbf2f33095cf8fca00279f9642a88ab221748f87e327eb0952798d23f2195eecb02bf626ab64dbb828ce1e8c70b6ca4b039946a50b99711c6960785c6012e6047e14c3119d6df112c4ccec0125e1c431e9d5959ea1b4d3f19d36cd950eba783e155318c6b4a32066b1e5824b054e96fac0e4473399862d348f4eb4171ca8d5ab4b512e2bbb87f16b326a9a57876c151ca18e4e197e59f68bb91bba0935b6f3ddaa4e2ef376cf4f6a0b865d49bb66ffae5326b24518e05eb3dc864a73ae7f327cf61c43c249e7dff56b7df508ac2472ea9b32efe63976ed3d4a1c8f3c02f351c84c5242f00c2e998d8272e97577dcae50abd006252fc363d3869828770e3114dd39d92b57c86fe34b3266cf69c9984df2725bb2226d52336f11629224c4f4639d0141d20677f2c5e649e4e555eb4062c21424c6bbae3a18a8f735c0bb39312281c0765929b45febfa293549f6051bffecdf78d61742fd02dc105fcff007ad28448cc7d4c4bba5a333da0892bcce07c912cbe4abc77b04688be1eff4c919755f5052848cbc2e6f10ef9daa13b15914506944ef8358614a38e90d29cb836bc7da80e5791ae3434ba0bf4b4f06cc0eb6d094909e6b39eb2505139049102f9b5090db1765d97b8cd1417975c4b25ed6a5ae716bc7c96a68788bd864c76c596329343d0d45ce8119404cf7d422d939fe68ec23e740b468e468b9ca660facf693bed64d96ff7cc70614910d40a05bde41690a770442e81f970a1dbdcc8616615d05d46dcd268ed664717682cc4e0937a6d6dbf28cc4e37198575c3bebd708184154893dd15fe92337c94085ba5ca8bc6fd7102f8824dafdb3f177dbbd0bbd7b68154bd1cd788dca8a826c6650eec0182274b884993ca5ba6835896622862dc8e1a4ea901b1acb43077ebd30fe978b9db39cdc16f089b92d07a479161f8e65ad75ab67994df2d35994ed4a2a62b7fb436f8662ed96c212fb0d39d12cce460b2a775a6d23d0ac3857458facd22156dd3923bce12747744a9e0beeefbe3359ca53ee704e493fcccccb49791167f78ac7a2c3f67812b5ac6a0da21935549310949a16087eec93d0a4c8e6c7d99d76c53e11c0735cad1d5092cbf22048d522a2b8cb4bfb625121ba0e95a31ecb21b78ddf0b17fec37305ecf79808b9613e7cd3b70bc2221cf70601641b4abf274ebf70089645299077b04128b0ef782d8b713c288928fa5af29bccaa162d43ae41c1d41f53d2f54c94bb678ab778d042cce251dc13bec41e1807588c0f7af9c54dff306a1ffbfe9a9034da778d9d9464e0bcbd84f4677d431322cb1808867faf53b72267a88887e20cb8e22da6a1209180d46c238bd5d8c17a4276a20e6b0e605aeb7ce73fdf19ae047724e5acd5c6e8435dd4dd644286dad48070c1b05c636752942610106744a89819058a3891a9e591fe879df2ec6b09ab911147298583297e000b10cad87d2fd09c36674032c993e9bb1f56ed2c69a023f806e31e962b5283b0a3aef4c7a898079fd6f7289a46f458040103101c7c4ef10c15898b7ed9b67bbeb2ad98d3faa8358edb0a1dbf7e2b16e7718a3c3ac383622a5497b974c2b97287efb033780ce6cabdcc77c816c22f73e51e269e83d6c6022c98117e1dd85f0b0340a3beea0ae3640ba4ad06d9a3ca796a1850ff33a2c92efe16929edae27b4879403fe1b124ba435bef5185dff2ede1dc324cef5f99f14d8b1a9b981f7836f6947cab7b2685f9e11faef9ad2e02320d2ef40fe48ab921a28fff5f20086e8c68eb813ec44447edbb8383e502614d4c28a4512772b71a18d1ecdfb0056c3812a388f6d03484c89533a9b21490b093fcf0e9f40f022ef6dfc5376b95e509970b754cf348fb184db7e9533139327672c602bd065ff380ee5f8a870c75d61aa4290400042537c679df8532bea553a98da7aab1a6a5366ef6104d1914bb58f843c7d2cb2143463ce26934938a0b7dbbf4ffc317c70267a63e04984fc646d67f5c442032e0a7219291217716b8d77f6439a3d3a9ff34712f568cb36e5c17cd1c10efd9a53a921cb6adc898a38a2ea3932e4c96a064c8fdd51b183e6fb58b82ebc2fe8ae187f52ed0edc6e8e95f297a12c27e7405f70c2a9086a8081226252539e04b6e82ce41538bc92aae8d619bfd5caaa8da588a10fd1cabfa185c5acea1c6a386e01e20c92a61b1bb18636c4fffa4bb326eb8406cd04c39e663221f52e5e2b47a97a3929f91d89f7c9e59c0971bb93edb01fcd4dccee39531d87904ad8f9e4f3242ddc14eb8660a9fb6dd9f43dd76d8fc54571939c8d35255216f9d50be5313900dc6b8c368e643cc49f753594aa58aebf3d0f9a5dcac7939e508b42596f12eefaeb81c7b86791d80afc73f7f0e0ca0052c1c7b1b9f28f8cd660b45ef00773c60134d45d1978662c746e4e8f18e15cbbc5ca9f73ddc8a3f55a1ed84b5ac5b4d6d558135941107e0548647932a96ae1f15c04dbb34964ae5d129b37d060ca039c622ebf43e9b6bd3c8cbb87659f436d2d4e3dc00b6be7e2b4f60488eeaeef524cdd07a8d479f6e02742175c77b7cdb12853d2ff99c9547321d3d4887c33a2c9dddee41aad90d1482ce678cba21185119f00a1a1b2df7706d8b44775a30d2507c2a85ad52e6373b6c91d0471cbe5497aada55171e97c696def02faa5c5438f00afc03a2b69ffeaffb2c57e535df6267ac98323aa02ae793d7870e48e4a6f08a9fdb591a9ab5d6b239fb9c9b83e88154f5f5b802fbb57443a03beb6afb6040a3a26fca09b9c45dd57ac30a151dda0cf87ed6a8b7a7fb720138724138cc53b60acfeac25c9e44b3c5b4c3032b51e9c94981d8c13ba37207a4bcf7cef099e744dbd4ebcbe59a63c4b4c99c99d110c18aefa1536fdd793e746fb80976a2cd4aae394ad28cfe44556dfbc24a3de2d866cc35c0fd67149de42804efba12978ef6d311753b4ede3cffa98d820386abf8e674c08b5f1aa87c30ff2e57d0a0969c1b25761ed728ca27fe31a4314b50d45a9096bb069d337d1a223d19426e26aabdf92ad9d46beed97ca7f2886ff7e326f58d01c03098404c4a52d1dbdde4904a5635310a8eaa43439d13ae89dd024ecfafe0e026b92f7647d3b3329c14dfba13503dfb0287c9f95f18e9e0c9df648629387b438cf33fbec6b10db94d151d4fb3815ec3bb7d316c797d6ea53d3bdcc7a36e6797ae5fc9f7d4547bac1dc0ee0c419d1e1331cb4d78512818a365b2bdb3c4b1022f08be70d69bc9c49457c90a2f3e250830830cb2afa308a21fb35c6800fc9fe397039580d82e4b4f3eb8f8146f967ea27288fa954136b782f3ba84db5aaaa4e7e50ad202b8c33802a8a810f2e0823b0e898e1414c1570d156fde2bd0c584f282b88b33ae5b15e8e9440bd09a0d76b5f175fa882b56c285f79c200985ec2b57d53971675a27b965a74a40bbc9fb060ac7c919b0f623a1b40ca93208ea54eab7bc7cdae49235f7e07e09c453fa472d37937cbf811a94349afc61d2538765bc4982a8e5df0cbf468f7f905cdc2525848abee9bb1333d36f30fb040246dbd606b60befb4276aedf00f1eb1bc9d7c91c68ce37e3b7a9d753a0b1402d46227212824abf9c19947c220189d101006e1f6897c71829a2298ea1559da0d19c2410a1ba19558e3a4f94d983416c1909e98f982947aab885c289e30495573425a4a7f4ea490d8f85b50376b12726add0c661d374463ad864a62fac73c5f608ca4631953c632450a5e6e842cce479655296911a5927753cd3f6fb921d740acc1c03a198018183fd124c1e3797afc4bfe5a86cd132ac3b062d6252daa752963c09d681905cf81fcaa60005a6466ce4597649eed3bc93cb093753372fc2c81b4869a85eb3af25f11cea370a645e029828f33dfddd72880428b109201c806cb21c28a80c66c9b04799dc495c991c20f0cbb37dd1eb4ea654d45d8a66bd23432332b80fc86c0ad6c3ab3e0b28542177cf39fb7cc7603db96fe34135091571dc3018ab343f3dd69fdbe796724c79cd877cde6f888b4c071acb5ffa96db4a4490eaf9b652afe02a361528e6e9d90ed606efc35ddae48598a66bc934adcefcc7d0a4c10ba76d1851c4afb211f96695662942eb0e5268d7b7b7908dbdb8a0a4236c3c13adabce647b3288eae0f093dc67260545138737545fa8eb6d31e4ff7c3c16656740df16dcb7643dff1ce5d3cc01ec76e7047da73a60fbb394900304f1932fcc76be414987161f2be7713a853ad658de34e3c212ff6287de5003e6bdeb59fd489fc3af47a7cb2a2255937dc23ac11f4783b6cf0a581f43b1ab6afa18c1e37014a808197198ab17dd6605bc9f2cad98543f3d2b2c06fbe7da43ddeb9aa8fe6694fde72fd950a607ac45f7560e0773cf13ca11cf255dcfaf9a887d53c88eae0753e877bed1c807d778ea827d29e5e4d8fa89293c191dfd33b2ce9758bf478baedc90a076b96ebd4af0d61242625339096c7a0dd4f46804d255460a2924dd9b038144636c43013fc89ee8c68628beeba49a98f32832f874972f3b38455032f5502f978726536f2549867923c998191141c0c539009c452ebc61c18bf2b51885a9ded3b01209b24319106ca12e266524f6721cfac8c3c0e097111c33e8480b55e92ba31af17b1657eeae2a552dc3322384c00999060247510000922bd38b4f3345b7f3f8cc59714389077e1ea1a278e7d451d83e98a22c93e9e31864f1e899a3543826a339f881663b2d2061d1b20114ecfc9c1c3877134ce8e10b4d4988dd49060ca2901a311976089b7c7c43790eb1ae010c8b97f55a4d739ca0727931b3daa84279a83cf8f0172229314ac774e30778270b8329d3859088b1361800670c3a38aa6bee6d22eb77436f74c437411d659b5329217016639e0cf50a385f7e81c174d9f2ae90d82c62a918cee8abe29a50c35f31948eaf9cb48a88146f264566a1826689d3e29dea6f8c627a0976be78949c3513716c533ef597ebdc65868b194d61c8db0912c3049d97a872b5b4b67762e4376a1ad0d6351f81d20ad1b8501ca2ce0af7722b8ef2ac79ca6933e08ae01431857ab243f1a7fda3c16b797fd508b1fd639b5667b6b9e2b62fb7a913f532976be8ab54645333d408ef2996dc82baefe9ecafa82a412b411152329cac23a98b8763e40d144960e08964ae7dc48301d8afa0309d48a023de81a060e2320588e361aeb185704cb818db204c62167513d5cf8672e869c2ef992e26a9bfc4362ec28531ecf8c37ff4f3c0bed415002cc796d5e2a0ff66992f4ef754cab5b1b4c91893dda94062dc36a93a0693ad6c53eff68f662ca465ad2bc7b91d466bc57e2c5337e142922523393bced9417135736c0810b025edcb8ddc5d1be45b508ca0c0c8db637fd132f163981ce9322794ea869272670fbe0b38d7c28a7c110fd03f05811cb7b720a1cf32ac25512c695db359e440a0f09de1b92924a308bdd00880780615fa3efe61639ff42dd3e0cca85d3d76e315ad4b0209c6f112d8b1cff257443a46bde3051c8bad72f9fa82a393bfd9eab08cf5c6d946c40249d45ad7a9a5c4eeb26da38b701e499a3fbf9c21bf9f150b1baceaf344d8cac72a65948aab3b22c20a02a80c0ae298e270e49008de2e62839011b0b164b1ac0f49ab00297707b12c3a7e14dc2af46995df1d0e4240b2089e4b92c247a5cd8e44c49f4dd38e7e5480ebdab1deb9a16afb488b6892836df342e8bc398b78d7d6c87914ccbe4ffda587117cfdc237289c35b503a6b7aee64a5233c1331390a3065c5bc50cdf5e982a0ec57fe7209ba49da0e583dd780d6a47057836e71d02aa2e79d5c3e96e154194dfdb3ca0343bcddd4257f731dd8c0ed1f3285aa320287a9c4a512a5fd583da246efe23ca3a6248429c7bd3a4480bfd39cff5762237cb80b754d29de80990488d3cd41452bfa1b420ad771cac69dfa6f65657c57eba48afdd04fe59d169d74d0d7d39751873c9572d358c49f1d8d7fbb017b71b7a46d5a0e61ae70e2ae60cd6047108fcf4d61cc850c7573552bf97d177c4d220a224cc812b49c395ba2ea1b3e65550590af5729eb50725312f27d36e903116f5357a906a6ab3d1c05eced55fd4948170aa79391f732229f8eaa0c64fdd2c128f8b8690d82c6dbfa07c14dad37215995ef72deee3dd9f73bb3cef176ad6403d15048becb5a8b2b3ccce8e787e324606bf577e6f24c9d448983203d83cd49950f9fbe5abf1211108430fa8eed05d5e1e32069ee0758465f99769ba5842777c06f1fbac6593d74399e22b7260e2f673fa5f05cc5db71bc34791a88468eaf37296a2cd9aecc84685377d92ec1ca749dc8cf6e3708192de6788b527b9e3c3ab80939f0b44a9954172db893e90e177056a7fc7b11c07e470445334a7d8cd08c82f7da2dc6894d8b55a89313da765f1fd2858f5ef561339adc96f9886b2c36a704a1eb409818c78cb054736177f07b7d027129bce1acf018bc69a175b9b3d316efdc22484fa09d65ba37a5f559bb9ea80761492d7f42044b55ebbdd5018ff36fc66da4e6cc15fbd0f755ffca1c34c52950d32a68292eebfc9dac14492339dc538a5627d302ae1bb8d9470d041c982b7421236e16351adcfcf850b4169e661cd2f62faf3dbb2277a47c0baa89c02c8fbd00db0b5da9bd745ac17be0fa77a364b10778a4eca97e0d1f840cacd99fb350b70f09da47c6a0c1f280d409b956f8bc0e8edcd08285069292b331b987fde21d68d007282b889fdb430ca4b6c81ecffe119a531a48bedb03a04ff7d3c48866ea6832917a9c99c7cfacd2c6e721448138101f4c368ffcabaefb7fa8592d636ef7ba5ef78e453adf2c12ad7b0469b2159b6a9aae9624bf4e41dd11af6987a1cf4b08a11e3b274f18962eb24abe3dc2db018c2e0cfd034d6aa9f12574fff540f9509b5d3694a2d724ad85cd742d5716fb778b351844d94609e24bcebc2b45407db29f87b20d4bf13cd28e7e65a8dcee01aaeecddca29ddb5263218909227dd2a2c661ed7b6ec8f2054d6d9748eaa40af795eb14a1ca50f5173a07e7c673c09ad003fbb5fba00ee6eea30043c891715d5d019daaf902099eae7f30d3ebdaaa01f0e25637bc1840a5860292fb09831898828cfda5b78c9f28013ca55f9af70027d632eea996db317d47f9d4cae67aa4253281d35cc8c34a50e31af8c9a4be8496de7ea98325d3d1fa7e092fa50a6faf8553fb30854855a51327b370df41f5f13e5d599ff982cbec6ba2102f0f51875c2d8e003d1d5842d9cccfbd7008423f554cf4587cad40c0280f09799c0171688d8f2e28cbe46a8a63a09199e57ed7f2107b290b239376a9d1301e61d5e3faf1df8e0a88ba69d5570c7367e88a1accc4eb977c7c11d268baa1a7c01d1fff1d957ba261b1f1448fb35fcdb77b52b7ffaf511dffa8e7342f823a8e0083c7ef6eff653e7c2204181d9fa9950edbdbd1a7c5ed1ee0f479661e44f522757f4f384cc0fbf7a6f280754b2b505dd88ae3236cfe6dbba6bc17249ce690f3be66af94ddd14222993b2769e3e462ca0d9eafa3d90d270b320d8694a8eafdfeaa0a18993aa57d29f90d07a3a921d52ba6ba68601b25e533d8151f97004993a13fb4f23c4752ff9f427b0c15411533d381d16a910fb013d54417da9e4617e78d60325f726cd28c4f52417bffcd32da1328518dbf81710d1278ff0e8c7c068d610a4de6f79a805931af89b38526f8032d3154232e65f628c1e9519775c54c505c74a9ea1638c4d387e0508a129935d8fae152de7b0d0944850944abf51a6e15b27afa414a37b266d20ae967b42606e676aa01c2860096160ca6d3422d1e4a89f8d4ab00114f2da78b34e898f6518c2205200c2a78c4b949625c5febfd19c163b0e495d0ec31fe39c6f8c01a3cdbee0f463c48f109c9b0cd40543777a46422a421ded0edfb1f095642bb4a6a50f84af01c126e61b61fc8916cf36a42859b85167e954e214d8bc5d3888e222cb8931d96a2623dd34c6dfa0170ef0f423991194e1cc623e8843505041af693487cd703b193b2efc49318ff5030dddfdfe5107a2f260f805f96009a68e08b6aa8d3b83320df8bb9bdf39d1dc85e9baf317e58dc50bd3dfa707905c9b770857ec1769b43c6a1fa645cb97133f25eb81390c4129a409d1ac6e787b276def10cff46415b5016cc878e107ab0bfe6c29c5a523ad23363b3ba03d50807ee093b94c78cf478dfe9ae40b77b9669866bf344fdaf289f182915add962b2bca7806d0d3d378a5518b8c436a599d828819ec73515b7cb38f5b338d0e3028e8a76ce93c85933abeb5f50c1131b7e4a590048b65325a61b9f05eb8672dad5de3ff63dcb356dd59a67bba1b6d755004f3c7c2945d8aecd37b2612fe0c1cd079fc8c135bae1fc9d9c542e53ea7aa1cf65a3f5d926822cba4b24980a5559706c13c4c1044ae08e9c4c4de4044624d42446a47617d0552bf70793afa18726ebaeb77a67c280d181366bd255db959fea3c9460c65a05c27464ae561c2c087c4b150d168200fca87808f1166e2f14f02e8cb07cc2bb8e0ce1e994b7f341b37b6c7c43eaa48269583a273a6b502152a753c79cc180648900a96ddf32bea4ce50fb9552e15c0f3fb12f02f0bb4034efa658f03471fe2001388b38da41941ae5dfd660333a88a44e2af9d2327da44e1c001208a44ef8c4a2027d1d56c926a00de6696a50bd1a89d439adc56b36c9e8c0ff1952e73bd1c0f39013ef0461eef0e7dbe3e27b85c57527bd0cbe8a0bb6c2d95c6c42e74bf0a7eb6a4c3529628d1afd80528012b87737788204c514dfd5ccab75b2c46e2d3bad3d2df7f05b15d24e2a14e79cb9250bb1deab074f80f10a7237c85b114b4a73165655f78d6e4d192d62be6a3e3c20a52ce8a8939ed15f1e3027bdb68fd9c6ce03c8a1f2866c7dacc224a33e86bf376bc4aff6af84fe9f70be816906456754202578629118501ba2412e5b9658ebd4ae8541b0397e34dcf953e7d63b0fdab053ac158b5d8ed32628359c7dd49403c8c7194c115dd3d65536c40962d47cd08b38f8139faaa8c04eea15c773e393f69e4dd46e9c610229be3e4f1508b3b0ab63e63ce2adbdef6e68646284ccb25df9530e2943d9668147162c3562084f1bc9c950ca3b5a8d20c5e928f61b965f52f1a447350ad7740985965d4b0eeca3ff02cbe3ab57ace8afb597a6432ecb544c2df4ca6717b01f17e2783d31e758d98ce58451481e681f67f50c222f02eb6f856798a5818b5090528ee0244f18b97c9d638e94240a464c5a255ddb7dcdf1c216d4cd82d85a7cc293783b1e20f1d45ba69fad2b7e918ce0324b69f25a7f63cdcb64c954a27b447f24437a57d84e1f912996c91671933c886b1281817d8cbdd3ce51268d84aaa905edb6c573dc2242e087d67a2d7011dcf262d6a07b47e1fb5ec588d8617dd4990dcc8c8954197a62331fa128db739f1ce749d889b2286773ab254f72bd694473ca27a022b50b0d76d0ac0b61e66bb40b2e0b854089f1b4b1bc7226626b7f8ad2c057259a74d81275cef23568cbf939fa2767860ed25346e37b4c80a84e1e68c8d64b63e7f96501c62003e5f982691d85ab5ac08a027e2ad2110e4047e90d8f8679b6d378705d9390bf5ee276425d0db75881468705e244475bfbaa7cf556af7f2193d570664c9896945263e5579a771ebcd50f083ff821df6949fb8344501e4c113316be5b3a3283196da2927ab15eed1509caf3507af8d7b3587edacc3781ae219f8f83df4df73229fbc10b3c6319466f91ba65643c0339584bb849f4c24c63b2c2148bb4b50241ccda175d618f76498e0fa0a2926a3aa9988a07e3365a8fc772376cdd93ba2eeae503953ac7fa3456f31f29d110e88b018f228d31539bc6d703323e56389cbc9633625b572b3934b14db53c77f55da221fb05089d11bf28f1764146c395fd4e115ecea478ed6f469a2143ee315d6e8152aed08ec0ca6f5d334be5e35f7d0fb68debccc057f07f4800b6d26703786ff4591a38ef9f8665122cfcfb9f140243036a1a05497364c109aea3459df41bdac5f779cd0ddfa4aaf6d1727a3b9b125ffad098548d5a647c4c2a3e500d69a441c914e1c4c5e443eccf0184bd8d59483f1434a8a9b2241f5e5e610ac5e2f3e69d535ac2e007a4325a65259d2451443d56527493d218162c5f2d90b66c2a4a344ce952412ebff21e269d6132ac7eb807e275d20fd64299d7ebd8513855153c56832487a0c946a51353cbcf995a9a519f72af106e658bdf0820f7ca41be68f51f30e8f2e621e4016b6a3fcb36f342f1a78c2a9216fbc43dc798ce7306569961714067df85dd0cb848cf77591d59f078017f25dc51d58ccc4f8e5999b98c4357ebf5805eea9f1b3d81491db7a8d2dacdbc2f297566bd3e7bed77cfa37af2f125b4cd82bea89f36eaa3802a94969d800a6783989b1a1c359ca65d6c41b33281aef632817e19e357de40a5d4791d554e8f1f27c5478f37a7f210dda399d9bd4045acc14a8dd60394d3afa0778dcd61190d95fbd8c9cb44e78ba2b5baa7f3e6e20fd0c39f978d1d3b6ea9d32dda78ac4433353b8b2b964f67b98fd359809c18eac6c369cd353bebcd09b70845f48656c538ce5d1b958c5897012a46652062a93cca346c4a97f3fa7114542538166c9dd44b250c1d8382959e3eacd47d31d3239656efe85a82fadd731083a4e2d985812c4473ef5e5f3b6f13391749f4fbfbb49722fe23100b0df393fecc9b3cfed55f9d0b7c933244cb239b161b2ec0b7f4181cf802deca3acc2df4699551276ed108a190963a4952245e8f55f2458350401aeee1d2d99bad830d7fb8b5d532cbc40296ae8df438577aa0ccb1da2512c18b15d236fa6bf24368122ec08caa4b0c1c3ecf633c2a7ac59e475ecc465c48744d4e6147e9a5c1159ce13f6968e7df4a4a0f895b18d55b4a1cbe635a9b89e4db70a5fc593904a139b589eb56f462c3b7d615fb629ceca278118a1d26862d8776c5b246e3fd0842497cf384e6194d12fa86e312acf5e3da737aa9cf0bd1f6939367cbd36a79023b8c6ed41b037a495e795c3052b25507a9f068a56a4cc1caebb19a3ad19571014ce8296d5586b3ac190657ba5d423b7ce0c481187b9d7edef9a76bf31f00c64ccc3d86404aa28852831147b77c8e4f141bcd3958fd5e160da975e036b26ceddefe726f29659232d5076a075007db67c09037b085229dd0e7eac6caa8ed3a5bdd6c87a2595866cc20491fe4cf905b00f819645a233c8d199c99d80c10e08c6c468b19dd0c6fe68bd0b2d45067a6b7b2e1eef669ee93550300c9728212c07f049205051d803f0d9285849e70735367534e0e20d49bc19901622606cee0ccc866b498d1cd7c31c30b676433329619d98c6c4636239be9ad6c285736689b2ae16a652c2c1e1df8593c29dcdd62c9906aa63a4245530941c52bc155820c2753c965cc25bc6660a0ea08d54c45530941c52b4186125c59452be13503036760a2d128b4238c401389447f7b258f235540be4818c9c3cbc9547219c9d80845327d257f7b1ca902f245f240c25e1e777a9ce971a5c7b9e0f6f83832364291118a904860d882a2dd3186a2a16e503964a1493177046d187208fe4ce67c48ba70ff85bc5d78416f960fa1622820a89c50ef23840f0f25045584f926aa48fd984b3ce5e6cdcd27cc5b79b3d568a858adb14182ca398202e234364a2441c5b6bb78a1de4708a8225042c0502f0cf56ca8070af542bd502f095521a136fc31aac80755e4de409f27d70dea66fb893492486628642ec9d19f1d9239333e9339341e247350a48f212d3f436ec90016a10845680d71e105bdc3b7334837a41f2418a90a5225e9484fa859bf9eaaa996aa4b1d6b25ed767dd315b096391ae4c78aa7f2c6e5c7bcdd6c683f8eec1ba7b151829a6ee3da916076651303a98a1e09675738a8909e4821e99c064794998d7d92602612ac4482b990602389042b9176db7fc60dd7c474a5d6b0a8a862fb83a62ba312c787d70bf53ebcdc3e59bded37d2922c24bc9dce490eb7846573b3a564993912764e635759cb6e3ebced2defe25101f52e9e14eefe3c3b9339333e247368cca0619ab75a7b2e1a33eefd8e880cf1a8ca3f3cdc3e6b5cac29a80dff9264f57836b58342b2742c24ab090b45b26e2c1b93ed6fde6a0d0b4912f3f695ac1a89037d867aa497d3dcb7b00f2ff7c6d28666537ea5dc5e2c27d68b219b395d4be2bf266d5e54d5a32ad4dbd0405d1b47181407156a65d37288c4826cbfbd1f6e7e9fac1a2a26e784aa583da036583ff081c88667c3137974e4fcc9a323e7ff94c99c7ff03f44e6c490af6fc1fc95526b3a57aa8dcb739ad0e5f70b4a13ca40cd2b65fbdf9e5d852f9b045d8550d0b0665335a709716ee22494266462c3fc92bebd33cc759cd49a8f1427db1fa60cf5dcb4813e593556cdae3e3c9b721469d342da14b121913632aaf2ef5ca9353644a80d196c846c97d3d804a1a6db1cb13b577088481c2fbbc24185a6a0a0bb5db32b1c57d014131c4e704e83c30a9bd8694307b33c9f86ed36316cff50f8c211c6f6ffbc6e36ab9663d5583629b586e504b5e1cf82e223459738785455c2409f21568d841c5599b92743573ce5755798513fd1254fa70cf5509a446d1b9239a8274956cda6fc41246b09c99241b27236e50f43bebe85fa9107051bfb53b24a261a45ea1832ebecaac31365c09032ca11b5c36dc96f8c21b54d559194e994666e8411456e110031e475b95a963ced4ce6a03e449530a40e009913f3604c99636250fac329972dc6c4a0be8cf2e8309ddcab73d33f07938bf86a8cb6a8ea949051246dd93bb6b49837f366de7876f5e1fd8749a11ec9a3237465e4d1f1e1857a1fdec5f7fbf0f48745221616969036731e1da6133743e54b9f2c33b7fd5938a73943bded351bebc65ae23467efd213c00fb35cebe295c27c50246dc184bb09dec92d10bbf75e4a6de2bdf886816f18d75bef5e67df077e3df0eb7d5fc522eb960e9156a79e3a03fcc230b02f153a390930f6497145b6a8a2ab41f5fdd03987bdd0e20dae11b52b558c10a34a4e15557ac03fa8b202cba48a09a84cf941e3067ac40316e8518a986d093d9a5d2482c8818a0e5e50c1e1099513805fa8b003b7c20e2c6cbc27381bef075574b8a98d47054f490d2eb7095e0d088f080fc80d23bb030f4684978220b4ded436458cbb8576d9d43605ca18da53c56dc114db0e6c5368fba4b82bb34d1982c3d9a6c4f649712ae06c535a609b22c3142de285a14d55602d749622077ab4a9cd8b256c4420f1e2074bd32d9bdabc48c1ad41174158427b36b57511c5e25458614705441fe8424258b162a5082b4558b10206186010018308186078a520fd12cced54c939e27f5f0953ca095fac5232c1533232fb9634dcac524587f14fcf8b79ac63f57c3eeff9949d712cab287e287e60ce0fe6ba3fdb822b60ac360b7a6dce221194a054a0000534c0c195c3175248f18411235c10c31056f4a6d080040f7c40118426626003106a008517476ebb580f5a4108a1c57a61eb6207d7d605ad0b25db6e6aebe256e23569b203264cdcc4c129ad74c43beceb2acc4dbf5ea7d6527c4763b576671e44239d1eaa0d6b696595b0afb5945a6b6b586bad25615b2b808f524aed4b96ca3720a594da97cccc37591680b0335ed315ba3e0600be3165318248e93843248248046bad05474a4f6badb5a3ebe34266eb67b1b5d6fa2e7d11fa518444d7b73244312216d4480463eda874d2a3cb6429a594de52c985d293a9e5658a13c9da97d1a674ecf400d35526caf80341167c65c4845e86a6f48e44e892f4e8a06fadb5f7e663472274fdebc1dac485ae8f471aa3898b110010003375a3af9908800b7c3109a3890b7cefbdb7c6283232ba4697ce81aefffde802adb5d682b25d82ca6d942023b341656a7e88a2f54b41767453e7747d0c32b73f26011e8360ec160951bc5fed07e68e38ea50153b3edc9beba4935a5cc61ce4a614449b5844363c2bf4f9bdbe975d615aae7d388b7118777670dfbddfa5954ab34f079afb54d2051f2be9c267bf20628c3b9d5b222007169aee92846762d7f79f11004a03decebf95a45e33787d1c2d4869c217b9188e8f3d3a3cf77a6e896124c6a9d9fe75f90724d7a8678500dad97aeffdeefd6e7873339c22b402f7d916b40381c25b88a32a993e41bb7007da81784ee3c20b196405d4739acfe2999be12e87ed0fbae22b50f6e138fb5ae31a152f140cdae1b1435a9d4138bb02ed403b100e7471128c64fb8376d6dfad006337e16d4be29a2d71cd96b886696789366ea14f4cdb37a7a97f827650b60b2f64bc04db1cdfc2de761968b7fd69b5b55a5b5bd486692a64d26a70ec90de0a77768569344cf3d819364e7217c0896dc2f61626f1b5f6f39e3bef3ba753f280a195cb526c974a24d7e7a41b58662cb2977dd5b06dd7f77bddbeecaaf4faec125551308fe3f867692c95587094856366575ebae91a6dd6c211fa5b70d317607ba45e36b5833e1d87731a3f5db79b384d0b6e62b1e409a509b5a03422177425a3ab350c28893c143b9fc38df023a827417d095a6b58c0cd6626ba7222b392cfc6f162fbb93ea32af79cb5d68d35c3ec0d55b97f90de76f7cfe770bb02bbfabcbfbdc9301ca7c13688fdc1eaa0c53e53443ea47dd9945f31bebfeb28ebfb52189aca3e3dca76f26be15af1e7abc78550953b11b5e63e516d5096e7fd7d08658def4f79f64555fe63799da02a1fa1ecc6d275f625a505ac73b3621bae558dabc1127c84aaea6712c76cb624bec94105166a0dd601c7837dd917cb6cf49192102e74739996d955ce366714c018689b29ab43571e4446592edbdf85380d8fb2706c7f9ff96797ddb6bb2c067dfa6bbbd7e03fa8bf6a79621d760aa80a280d7eb79f31905d71ae358bd7afb51ff02d59f7f7791650b7fb086d172a060255b92561a1fdc65f6e7e62d008f07f6bdfbefd8e0d730ea92a63188971dcac47dcac2e735908174a09e94239eb349ad39ce634eb349d85be2bd0e7537a4b6bdf7eb57e22769a5dd14a25d3ace5f94ef32394e5a22c26a813db87255b04544553fef5e5c38ecffe9ee8d3694ef449733b68fc70633b128fa2de3cd1ef342da48acb08133c1c26548c2a4618e1c1c86cc808743bc8a18a996d0727ad1e38522c91042fca14af202dff1b376cc9c1ef03f3979de6b49048c5e9e6f4ca7ba729cbc39d5d6529daf7a931eee8105d85513a94f5d91e4631cd288b3691a9d030b618c3f6a765b86bc1d1b53cf1ae0178bf50375f6a8f4d62a22b994954e833ef981d9670a03ddc85bbd30d2ec2cb0dfaa45f88ba59738e2216dbd9ae4aff34d7f22cd1287ce8ed6c57de7a196b9afbcc96e605d8213fa628c2ef1cf0a96702ba740da90fc310fcd8c4d3f5ef786de9a9f46b4d67972e4059befdadb536c7c8080d7a1a903d29d4fd7d9fc36f480cfb420a88d1dca4bb1261dbf2c5a5459b427104939dc39fe827fa89ce6234d608590959b95ec8804179c6187d028d4431dafbb08460dfc96f02c597d3e9249e4e2c38dc09773a956613f1f422d28686a22225ca2cc80f3aac8005873be14419323c638c5e72abe1727c9c624c323effcf20d3327d4c1436244a3e2ca137c5dc4e289818d247cc8cf2c9d06a9078677a334a72f4a06064c4e04e2351c812b21a24de0fee4123954c35846aa69aa2daa97a2a315c5a48602797e0520da192a966aa29aa9d4a0c55cf45356b51cd48aa19a89a7554b3ac9a95e0aad96a355b0d3462c18174cce841c1c818cd6ab51968f4b54ff2371205a48bbc217f945c5a48608784e148f1937ced6f240a4817f983bc29fdcde56f2d7f23fdedf637d8f6ff9aad56b3d54023165c06e998d1838291319ad56ab317d0440ec1df21735028d08f383120644384d6a3af89336d6269d66aa79108078818cef6ffb084869085d6a341236854b3d540a39aadd62173c8cf640ee963c8c8f42e2d24b003c39162ad26fa845c5a4860473f0b4e060cca33c668d008a7abd570a35387ccf90fc91c329b485cedc342be1812c9804179c6187d1ad56a2311e89451d78bedcf12fae0502fa70fcb9b503f9450a797908812511d3207f51944e6bc98acc7b5837cf4eb35cc994e2391650979f4785fb00f0e871271e209b55f4e1fe341c1bce9349e5e604819334a8f589a381ae36984f144d2d64b87cc397d7832bd00603cbda05030b853931e723898223818188f0eb3490f39dc4b11dca9c678123bf92492f724e6f1e544d25687cc79f9fc5267fb347159e89355db299e5dd5ec66a9de76d60b996daa56abe13e2c12b1b0984d42381bc2994d342e831f3e91b465727109241145fd44d317417eadb5d6da5a8536c1bb52beb061d3c734509acb73d36fbe2a6bbe92b1fa0ff9f431104ac3b2f29103a569213d7dfc03adb91a089c13068cca4d14ecda564c4157b7b7c249d094d3bf48e80a2739b2e95f25288dfe91e86906cf006c1f43c29fe15b304f7f045ad371323efd98a7ff34445aabfbbdf76e6ce6e887f7b1f2e191be16d349ce417d269136b42f763631f4a84889320b022bbd68286d2aaa187d28b113fa883fb914ed90cc291f933639aab29162b3b3d1d93871d397dc6a389be303f533e416f9d78607dbdfc60a6ac3cbd28c9f41a605f3641436244a0216e3910ca178a80b9dd49ad08a900763adb8e6a82a893ec55b78863c9c98b32b71665337a0355250d68db2ec8b349baa35602906416d8851501af107f1b65dcca12a1771b6bf8b312afa1479b1afc434d1f2a0b8e31abe51167e17c7d82ef6783655f329e1b5f0928d6b76350402b425fea99b80f98aedd949a5d6efe79e34b67f378e671d213c1ecf6b389127e5869bf84a8c8d600c8a939c63353126f2b63fc678246bcb00351a26d46adcc4b7dabd25c6ec0ad76a62ac26c640fd62aad118c00d6adc3059c2ad0f0697255c966e398e62a9675a6b4dd2892e5a6bed28baef0fe3774f0abeb1fd80d65a8b133b0222a1bd525a45dffff9516bad45f0914bd42bfd599f5e99cd6c6a1343cab63abd3b6425e9aa0034e59fdaf4262279987ef42c248fd28bde9d47cbb3bc88e4e1f2a2772b3852acdd75783aeb4eac37b18e73202eb3416c67f9d18b481ea227bdd72252dc74cbb350485a22f312ba026e5a9dbb90256d447f3a2d369d75c7cedeffd4a259fa8116e1ec4a034cc2b8411748709041cb5f94b32b93082564e0e18624376421bae5ecaae5c731fb409f56475e984dd99e783fdfe9886e20588a6c6e7aa714d576e8e1a3890f2e080207468e90a10b244b9e70c10d0e804011d95c74f318d12faa896a4e93b3d6372653adee46cd429f7646594428cb88ba1259234d581becd3e6c0fe6977b06b276c6a1323897d6394f56dfffb0365dd7751cdae6cd6565413d5b6b94fab135d20541504555d216aca1f07af27ae8b063d242e11dbdf61fab4333bb3451cc7eb5b2da56cfb03b9b6dd8244d7b7fff9ebd1f1794b7ecebaad7ddfdf67f621afe0c46881d56dabab51f45965a2ef318a8c21c43d3a725a9ec54559405876947542cb7f1e6f6a13e3668b2da485e229ffba5b3ea5d5e9b8b37b4928d0d42686cb16b163b6bafdd86e6c8badf3fa6334d9d47625b6cf2a0b43c9ae32bbba403ce57f85d88810b37d01c5460458cd0ada3e6f4c66a3b5dc915daf90ed798bc8daea90be5948da2201713ffc5911ace257f20330eccfe7f3391cbc429c267732d8210121650705b7ebe7a39fa71f8997d4f4796333a7b19d2be488d3d80a4456a443710e86433b1d9a3d297c5070cafa7c902354e50f7a50f07d634ae8f3164159b5b4575095a7e0d956b7d32d36d07807244062d8fe160a65d11c6cff9310fabcb198bd35d0d7f2cc5a8362e62ba1ef95d994c704faacb2d88d5dabfbfc79f377feb4ba6d754ee355a6652d44b47b1af0e26f2d59013771623bec8b1f7e56a0381c2e766797766f0abe354b08040a8140205008040a81584a0dfa90b8899b75092ee7a6131d143777526eecc6462eed3572107148874af162f764ff3cca441c3773fec6cfa343083d7e286382e84e6f3560dcf4b2e46689ccff791630b373fe5047cdf9c50edd35839e05cc8cd67ade9f9e3c630c880c0b99b95984e6662dd5b20eb6d25a69bd2206827bd0a0c80db45b10b4279eb4ec97ec0a012b9881911b84e084b8a1d5630927581003e3060b1f9eb4ec67bbda61850e90708561a50927ad9ac3ed15baa6693737f526e7acf57feb9391c91d5bed8bd43e4869ee9f98d2e0b7b6ded864ad4bf546275a6bbf0fdfcf34a959c15a41f1f3fdf5d0f8e102feeefe3754e701115c80851cd6d66ab903821d10277673f38961662df9d93867d77fcaaa2df800858ef7c58f2fb620a10a258e10e1092e60d9d6725605c3b6fd6cd318bafef55d3d3ac62db4751af320449cfbffb08aa65485b1918a97c035a03420bef782e0db55f6ecd9fe6358ec48cda68b4108f63edeab6b944591ecfa750cda739a5a77bd42597776825aaf4862d728b5d66caad65afd5af354d1d67bbd500c0acc4d8c7bb5d215f8b4ac3aabd381b6ce42dba72a27a76cdf3dc05b5527ba07e30fe30f3f88c16b753a9718a41a89f6c1fe3fd848f7cdec0af36c2a6657f869af5b2d615fcca630768f8e0fd603fdbd60fbf702caaa98f4ef86e734b91e7dd13ed8dd1facf62501de80af52a9540282868bb819845a5375506d7c6094a8aaac547c5740d7d7c3458a94300c06def07416ba96f8889bd56fe8411f0f4d9719547e4a9a58fa8dd39c56292001fa51d919d7efe69cc1c7f8c68d1b47741dffa8c05a5a27d75d0c767707040deba95042bb66516bac102665016147551e0455f9572bc4ceacacee6850cfb0baab3b5bfbc070ed6238045df74973365749d6016e80341f0dbea1c45a107ccaa276f5dfe79c3ffb01716247723bb2102090e94e83aacd5ae326d82cd3dc54b43561a6798db0945a4a2bedb32b12fddb861a4e8e30f283490cbc90220147ae64f1c315455e6083d3da0dda32d3fe6127df9b77056b053b65ede341ac2fcf9fe31e9f76de92a2587308f2ee942db8796fce76243de061618af6e4a03675bf92007e5ef7683d1dd277a7d68e68dd5efbc94f9ddab0d3113b1db1f3393cecc0a80a2776a4466b394207a93ca5b656cf1752800f3d37bdf532d095e690027ce0ed5a96e0d76c3db7d66b6bbdb5de9af1682413c54aa9b5d6da180e86dd8b772f287cb67dea2bf0bffc2c38dc0ac4cd7a63b01b376ef03016dfec93893ed26a292d2da596de5a2fa582c3b81e143ebb96389ec37338264f1859a8c31848a88bb9392acd6a3527b455c89b1dc1ae264b60353dca26cc606acc68d0808cb20933981a331ab459c81b65516806936282066d540a79768567b39037caa2d00c26c5040d9a1e699d6539e7590da2be69adb5d65adff44df3a827d0c110570b860e0fb916a8f50dc4ab419cb2be121217917d82bf14ed2c5096ef045c8005216ed6d420d4066d08aaf2afca62faac3935c7c79c5d2e970b0465325c68c4c350f73e9e4fa9732322baee530321a241223a6f4d592f786ad582a7bc66035444591ca02ac744f4ad61ada1188ea14747fe5a81cc682a46592b5f79a4d8fe252a3aca15dbdf71bce6288b65fbd72bbe4a80177117e240b20f6dc3f6d4fd7a04a54bd09a64b7dc689cfa3afbf3a470dd6441dc35e63494557354e59e831534e5366a939149a5c87dd25dcdd15d8eeefcc6873eebacce70f45973f40926c6d81ebe7f85526bc0f7307409a2cf9acbe572b95ac42bcd7a1c40a1ec2f571b9d376b35ab594d310cc7301cc34e063f9ccb890e1242a4327a66d72d528f6bec5501e2c63f51e39f32c09b4d3915ffbe4882fe43d6d62573c41f29e8673ec19bd74ea704bd87acad71fccf7fc82f067ac28baafc3bc1f61f51f0d94057df0d0d1ed25b20f265050f0e1c82a06b79be474bf490186753399b7af99418f752dff39f17c9971540d8b56bf9006f8d3f967887797ffb62f6ab429fe0ed8614e003acbe0b75c6ae2cbbbe0cadc15fff85ae30ed45d485d28035f775a0299a020d3fd014dddf4cc6bbddaef3c562b15a667bbf987f316bde7b9aa06bc87c31bb026fe0ed036f5f0d1252db1fbc39488501409c59c334c11b7873816ea0de28d61d31ca32c08d52027abc54f15700bdf8b59625781e25185282f1c50781be476bcc429f3487e4f325107f2c81e73fff527f85cf4b2d4b1d814fe9296fd894df9bc2b8abc08e20e8f346fdf155109fee15c6522c5bfea7d28c172a83d28024b8bbb59f0e16c37bc3f0de50cce0b743bb3a1ece9ce6060bfe3f7ffe9cbdd442d7bf540b7dfebb5a6ca07d53db173e36a5fe81207d1fa21ba0f3268ae3955b9da76fb63a7fa2646cfa99f49b4dc9dceb76cc7635005aaba54c12fa7cf0c391dfbf732f18731d1333e0ed46f1858cc287b4b55c4185fce28f3f53235309b09249b2c54a565b479da63b972fd4adb59691e15df1dd7caf552abf405520f0e132c6f6b718db0fd4ed820efbf53fe0f14015fd829f3e0f0749570ab83dbdfd3699f6f9a622e893f26ed7a6a807be1b2246d1efd52f678105bbca3b165af8415f4067948583871b0f00e162489db6e8e937d57b7017ef566bf4fb5759add125a536acae32f9b3da607b59529afafc5997d8a192d2545965a0448a2286a8fe2c78629ff2cc3c6c2f7f6c2f4fd7a186b22cbfaa02188c31feec6a0356051f96ccdb7ac0b7e4b7411266873fec9ba6fca330a7a0566ccf415551f449773038b11d0b37e30b72d6ba54fa979191b1396b5d2afd9b66474666ef6464b40c8f4ac4e5d2b560186be0b5f2ef789ae6afaafb644cf0135cacfb7cca024d70b3d2406b06406df81380aadcfab7f4a0cfca3b6becac35f6953c5ed525af3e6de95cbed4327b917b0431810b764576d8820655e0267a4cf0b28812c50d967743a6f26aadd628abc6a80a095dd51f68cabf540a856aec85310b76455bdf3eebebfb72589e9b5e7b95f7f2349ce72ebbcac094285840d901083e80a2e5ef2fbbfa401732a89283284d6a80d3f2295bf43083112c88d8d082967fedd9550f1f38ccc08a121a34e9ada065d6d035763f8c3f8c793c2d03a5221d5b287da57dc79c3fb0de5a6f49a9984c3684598c73386e11e234f54dff67761ca53ff5ce59eb52c9f4ef629aa55226f3c835dccca0c5a3e561709c197c680dc14ffad43a9a127e253b50659b03f6c3172d04bc557a93cbbb943c5c4c2e26d39f4afb7ab96ffad3bfbccbbf94f6e6fee99aa4b839e7bff7de6b73780e617695b3d6a5d27f080b61e2288831c7b4bd2984df29595cbac2284b4759341b932de4cb0a2d2edff23d5a24f26505d297be54f2283de97bb44417d2beac0bf9b282e95dde54da97e94be4cb0aa72ffda9b437e54b7e536967349b7ac9e503bc55fa52695d4a2bfb9ee8338481644e931fbbc298d3b8f042dea1f70f613604e234a2f70f75676753ae6334ca25d26af712e9ad4ea713027d87dab08f5dd6e3195d749748dc72f9101982bcf577767615baceceaeb3dba216916338e6d2a5cb4c55a5924bd57d58e8b37a72ce3e0bb0fdacb20ef820f214b73d43d859639f21cc8514e8be0f016fb5bc87746124c191043e6ea1ca367e70e3ff1cee41c1cb0f93981c0201da2291b62553956d79df392d250f185aa4925a18cc541339ea09187a023b304029402d4069bee722670d7e59835fee743ad95a6b6b3bf21135dadb554642d73f33106af3a79645340db306109910c743883d7ca3b4a3ea5d3d07dba1e4778fd911393881122b9268a1050e3224582481410c40a2b49c87032c78f0e3044e48d11aa1881dd0a0850c881ea878d3a4dfbd9ff5a0f081e0679a205c14d7da6b6dbde3d35bebad6e5f462f70adf75e24a8b5beeb7f81a3753ab79d65bbbbd6b566ac3646bf39df9c49118838138588b26d6d290661039d41a8b42cb826390911cd00000000a315000020100a074482d1701e6861a8d90314000b6b7e546256409588835192e43008a218640c0306004000020410a221a201004e601b2dea578c7ff8e0e2cb720181b4965465a876487882ce756f1630666bbf1f351498de0dc30b4f3e095c64dad3a1db194d1e4c8573f33ac92ccb1874bc16e045b89c3b49c5ce3de0f9cbf0653ed496533a8dce1c1b33a0b678fa4662fd9adffdea7bea00817bb6266f853b2f5ae6df184cb4a843c6c67c6888167d314f390844e644ce9e6f3243c400fb071024ba2b216251639744c61a1f1e635a9c12f964164336cf8b21797f79da3759ea4cd33e0036219849585a2666a4804b025e0b14dac15178efe99c6696b66be4904394346a4d697f8984055d653c2357c5c5b39150e905b3b38eb4bc146593bbb4cee00b84ed99e2f42ef72c3d60255e8b3710dd35c1c5fd61ce3638df664483761ea88efea81abeaaa261ed42883e50c828448ab3417e304f3ac16a3183decf53ea0dbbb8fbebd43ca5f218e25dac5c0853bf8bfef5a1c6dd815e85ca21022e3d134c38977c7b5dbe535b9c19802541c5d4d35e62982867cf28a3b4c6443da60139a0fc7e4fc4165a4475dc817974cc172924c4c3d6550aac4657a8deda618875691b66213946d89e7ff2d2af210b961f7ddd3699ed2195b59fe613b99a8bc21c28bc2f60605fae7bd15260515ebd3274f662a984196e4f6fa11baafd01066042a06f85afc035356e6b02d515f428c0eb80dbb6c79f9162103999edeebd7ff89148067d2d08eba53499138bda9cdc74e3108f8096e074ca281973de5f45be3ae6ce46284c3087757e72d69d24fb1ee1d192d43a6abe347b2fb12b58a80000814f2aa28919212b136281d78605d26eca87a3c39187f828a20c596235c9e6087d7691193406a064e7d136883114883037875ddf2f76bd5d2e9e7cc040b1c22084930e88f8a13898f77683fa8ad8513436080c3977e5abc479ca5fb9b957928246436f09a47d895508c6324fabb49bca82278f44a45362055b4bad659fa32c38c5a9777dcf5c10929c8fcc86bc9c1534cf739056eab1e8202efcef43cc73ff26f8dcbf19b03bb0815b954cbc46caa1e2604e79eae7200987a4506decfc15e641867a5f335dc8d354744981e1a9fa8f400208d6a5647bd657f897176862dde6a23b343910b0163978b02a1d0482794fd90511f4314eb62545ff427d281e937aafe9f2cce5f8756a97c8a66147e317c466e80439961bac268cf284b71722e74d42bce0f519563f5d8e91e9ace4539651db3fce2201544e13fa3e35079281b6075a6e466eb0d1a545ed1cd5767a1da3bda8647024d5d1f5f8b24ad842b65ceefa14e3c88dfbe28e2a27b836776f42e477ebfa8c7e103d72585b3ae5ba7ccd8ed299a9cb352eb0923a7b0a09066b10f57e0aa35d0ea83c33baa0991b9f60a73ff7dec400cf553384db490edb00890e5c000cfed12b3eefe285f4a65b43a7385565646d3c4242d6c1efe841ae8fbe2d040da76e821524d2bb5da77a50d538683884ed1e16765413114256a4bf1d51c8c25577e934a19660a502f245cbbeebb43c11111d43cb63276fed1a22fbe9953fee11d090fcef247161d9cb85863c03812ef3de3dbda987304315b890ceb798849440a3f7f0a5a041d0607f3764f95eb23d9fd35688c5415d3d852bbcf94631a35ef2ae466f878b92755f8afcf896b917aaf3ecf18e2cb2ec12b3da9cc789db54c517c5035e5473037b77526cceca794845c35325345b7e24ea9490c4961eddc08acd30b87b3e873a82ecc679c69cf3da82c066de7fddc8a7b490bee8a41931e5a1d674a9f69c3f824d0bac56e6d2ad3dcab8e380ca929874deb7318cd1063223a73de44e28873833bd4c8f05d8fa3db58a0559b309a58955a38977459fd7726885f8c4d6492afb40e76a70a5251864cb1248b11b352e32ccc68744c78041245d0b2043d90db84dc5dcdd78d799631cda4d233f31c89b5593bd3182cc72d80e065ba84eb7fe88d2b6a9e1c6775e6e227e943f015143e1458a9e619698a691804a602bb095094001e5008648a08bce271b36a9d60f0e7e88c7c44e992ffd83eb6865b33923788912b426c92a6de6b15593d9e88f2dc976e2806362e056a4049c2ff2b947b5fc447f7c2aae40ab3f14f7b4560dc15920205cef8acd917b2024934c1864204089d2b060f6e37d1347a05812c9d91984bfa16ce9e1d001dfe08dc78513a80f16077c4e8237228d9cde61bd8a35f0921c7fd0db5268967491f560b4400ef30a05b94bf2c21d201a4815930ebd4ed581761c42ed74e3bd2d59948192ccfa9730672b578ee97d40f789d808d2a8ca3bc26b994ed35c732a27da269993fe5f83a24dd87057cbe03cdf59be831989460db5b7b043cf365c49afe99a1c663b817ad94701b772b45b3c45c62d646fb8eb6ea4fe6ddaa5589a8d2fc7a640d399c07342662726d0fd0897ae68fef0b61d15a0172fd05d8a8752a8523e6145171bd7bc06a6b74167c17a29ec9ea5b3ecbd6ea649e6e7dd3c46f783636fc90a215e5f47c1501268fa308bff3726b49981a66592f4ea0d8a6beeb9bfc3d83a4ac1db42c2b748a78b4fc99b98679eec5900d28516a93e64c105c6e4a46748c64491570a26be1e0ee2102ca1e07147296082e956aca39c2fb5f694c9894e546927d7db98788491693e6f910073f10a959b6b2675fb5e6c36b4b4c2094d580b3e509388d8f4689842c97d68146a7609fac5d4919343e5a5e1fdab755fee90e9286b6e799c7d0d3bbb105b75a68bee2d594db9f0d531d473100228d91191d534c840411a71185695b84b8207057662637529df12930b198b7a04a80a2f31a904640f1603e9565720ae095d9829be430d3618eac6e8beecebf7872499ac84c810e6dc45dbdad9f96c67205d5dc8c8e0e00e0691ca5e05453a1102e6d531c7aff18d1b3773b65d9c281958484e3d39156979ec0fbffd7db2a34736d1fb00ac46796fb5ff3d552a340ef7b4af14a7814ad5f4928057bfb731f4603ecb9bafecab2c61631abdfaafa57335050e35f409e1b8cd1cdd6054ee4de5326edf9f1750046f1d4af6b9841a2ac468400a2d8d4752d8746c9f0b9bb61541c184159002afaf33604d70986446db64ac999c85f4792b605615527cee746a122097712a39ca8b47c3de5b28c4e00a3682de02a775b976b2c52c994c088b95668405731adad410cd38af0c323d72bfcd5c93b321ce80d371f62aeacd911e859cb6ad1098935f44c0e05c562231adaeac4d0ee82b248e88e0e840ed238e334f6cdc6621c759b31036b39c6ef0b83e272c01659c9252860707a859bba6a25e7f95e54fb40598af2cb227aba89cd24940b7b03508dafa88c224e50925b34fb6982bd6c9156ae7c4e8a72fb3c70a0427533f6998e3b8f0d065ed9e2423f8e062c9a68e0c4ef86202600f26e26b94718826ef67386cc043d3799c6135a18d12dd98827a25b66d8f916412ab1017c5a05e845d5afa769d4e1c4aa353037be5b41e27dad770da06c32efaec8a7519462fa9d9a04530f47384b801f7e0e92740928c300b454db032b2a557ba19d10ad7efdb363778debfea9218f61c40425bc16de646750957b6acd5ffd2a2ca40c9538ceed56f720086fa72376dfad4e1d15b5efb2281a17ffeec5bb5f669f5bcd2e30d8f6794c01a43df3b482df5db5b75f8406056cd4864c800d94935a7759142bc908cc72f60183ae2cdb71a528d851de69eed4a3063749db37a955189e2be6df20894111e1fc6b66361ee360dcc9fb453afae6a705f373793bdf2283857145836acafab1254a38b3dc30abe81780f0e1d6e437fc851797ad1824460f5dc5905270e0b7569be3af39da45e238e36021920199fc7d6820008585b5ea7f2ceeba90b68340407efde525f57f3add4ce41f39e0b69874c587761dd084612d7ee40adc8764f3922c3818f562bf115b6960888001dce9a39bb882b7eaa248a40b3f8878687a581d914806356bc9efdab268aa58a1921571a6b0ff2caba65217eaf35ff6d2066d63ecf044bed601eaac5774c5ccccbeed6ae427f96dd207030a7c987ebde050378422080efc5b900b0c09fbce7878564366df89bc4d085286d2a9f662af9db45131dbd1b9ce10eebebb6f1e3a7c1d8999279b6e37cf869237d91b1760f700ee4c6b5bf042658764d3fc436b8a0757bb16a8c6b0d2a14448b8983d602ecbca3eb3556aea887e60848457abd2d1bac353270093061d1660192dd855bb9b4b48e8326a05157d3fcfe757123aaff521f13c33cb7360361bfbe2804b786a7faf9bcb5f94ace8edd3cb7f6011814ca070509897dcc8f0dfc65210917a2d53516170488dba3fbeeda97bda0f2af6ff8afab5d9c0e8c44afed3776818ac2a89815073b71597f6460c8c665d4075ba85bd4d217646612198dceedd2fc5c22a5987ac19225f8338e9786d6b220d4997e6ac9128568d2fc0329aa6710d706a35cb17a9d6deeb55258c3e7f7a1f18ccd68814516ce7ccc534da48ceebdea7d8374b5a3fa8507028685290675b64bcb34bf4fdbe74692c904c7017788ee11e5748676da9846d36db37ba36ef8ab956d2bdc9c7799076d49a60540591c9e2f96589b1c72269583407e03e835212e3b737ae5bd2590c21b32e0e443ffcb9e8598e6a8e57d97b849dca380e308144c80dd8b5609f40bc9c3528da82082ec99b4ca8430e9703be28200b98891441848cc477d15f439b8f06128400afef65fb65cb01b34c10771dc0113802d1b64e260e90313d47f913973d5745b05424cdee155720970837f5fbfb1ab9298153eb710e387bcb14f8bcc1999a7897b5f02373300ea2f68004e47c158b005767b6f34a565f5b6febc54b61b73ee8fd93b10c9f6a5d4522f147e335675442d99ec6b362dadb26f3fc9d32065347debb04861d7d8ffdc0e70e244359566a6b220ffbd6f757440b894356e6fac3451d8893cb51eb6ebe507269fe6c1e9b0e1275d0d5ca854490d8e0bd764aafa3e28b6386805655cb2c80ad342ad0687fc3df0ee70a79f647aeca47fac39d4e1310e6f291a59ab47ef2879114bfaf8bf0f6c8393bddbc7d3dcf9d5840718381ccafed197e8b3464c1c6213fb1d298cccb981372d559b1389b3ef1f3485487c6252ecb844d356606b6daf7bfeb6b980defe198651b44b0cc2d6c70219d66c05c9219c0dfc49130ded76cc2f4ff12c6a609fc90414b625d8fd0c2f563f561cf73c493402aab923cedb749a5cba7a161dbc146c8d6741d2fda078437a7239c617cb79feff3d3361d621f71f811d756a0ad4b7234c5e50379ba07644d2ec2a0094f1b8cf658e26ec0d4d64823e886a1c78c8cb3d8879ebf62bc642ce54836355195330c7807a3b8aa0d5862e4dbc1ae3d839e30d8973e8fe411a2007be08e594ca71d56c18a5b2f84a1ff3f61db59817cf60b0d358ed131a72d9277c96c8c6ef020588e2f128a4224e4cce32ff9f5730199ae8ba49aef9d2d8a7be282f89b52f2a70ed947d97752d2eb536172b089d8bf695e942f921d1092674c6b4a7910619a91a5d9a7c0592ff7c19a212f7a9d64626c7e3385f3d1f7158ea5dbb83139a9c1ae0cd760373eadc404bfa9865e610b19f604fb251e01d83c7d03882aea11924689bb23121133dcb203a8921bff3be0f4a22e517c09bff4d58b02b12fb7eb777aebf4fa8094ed50e23af0cc39a2771504f77f59778ce02cb27470c1cd3d0548db44451c49f0aa8c9b229fd3542e9b17f39899e9a1af581ab71facda265f745680ba53a23a7261094f0972901064519b5336773bf9c9c8bb2d85b8cc26eab56f950fa41ed6d44a6577b8d4736699582b487921d24e7b3736fb9f47cdd25b4055848fef829d4cb5f7d23295631e17ce4259a5512d570059e48e6becf072c0093a3def7a1c905176874f0e832ba1ce5511cd442aefbc2d5a25a27bffc01b0eafa7b6293c67571d4119c892067354882a2e8483f2d2448eabefefc5c0a29a75856390c4c827ecd6b8b1c92bb3c2e46073ce700a75b9946bcde078a997f1a723d7af46ef51dd7b9058b9c1e1f2124101ac7b5714a982cee731e434f9707c876954b0d3bbf0893cc8c0c4827a15855946afe19e07da6a37398763a059a871b6dcc5ab416394ac979a57141f94b45fe4b96a17b99c0ec02d98db4ce0cf17e4592b7157dd590f3c3cbab8f35d0590cc0f22385b9c01f087761fcbd32097b18d635d000cc75fd8c6939166482f8b35a75a8c1f6b6845f4c927b5831178bba08467d4e763212d08e974714578eb47b697509d9e3ea7a99e8852258708c732ca521b2deb3efc8810fc66d70f2cfed059ec48f8762f88d0f5923bc251f4681dce3cf0bed8fdb1ff4c8378fa8f56d81eb4f2994f492db7fecad1fbf26cf88b58aaacfabf781fc378ad9af9b187d32c809e5c10c4d869e87c006540d7637b64368d40f3d6ebc8fe70585d7e861b9c357b49afd84e2b3000395687fffe98f347725afdc527386e281b5c9badf5a3138e1aad8b3815dbd0f5a3956bf78aff0a89d128639d9dde826d82ab6bff0bfd9384cb43e215929bf85c653ed05e9143b23be4888a458728109787f1a99cc9f27c021cdc00efd5f0068011d7fe60114d60cf82cb3610dbaaa271ee391dfefbb3e05ab300b27f82e86ab9c5bfa563da2f340f60ee24c3d9c31ebc23db4bbbd5c81c20362891c5de17f42d3116ce971d64d7e72c6f0a3959b8f4a1e33f2d0c2ec936abc249711441c0a593f56b2144c8b45562c12f83c85e1a3af5cb338a9eb95b391ef0aa6f6dcace8016eae99c7ad0bce1fa14058f59414a0180a64cd68ae01d25cf2356c39ef4b9b4edc93e64995e4825f8474afa204cc27f9422ac37cd984cd6d0207b07ae7e2c121b2a9e1a8a3e2f889bc6ea94aead3ea46ad27028ad4316708725e76ea39d0e60376bcb3d94d068b10ed2cc61d652aa76baf0f56ab56ee9254b9dc4a2e3f5b7a861028a91989216d98a062a37a785c768a62898621e9c82b453bb795896693ca23b53c36ff16320bbc8ed46092cb26e609098199cad7d696dbf981ca3ffd0639aca36b50089ad2790ebcab52f0fa4a3df7bfe62f3cf1a2361002862ca1b77db671f1778985919a36236d280221ab2802ba399b4d7ab96b9315977799f6abdeffa2b25562fce3abc2377951797837fd2fa8ada7b4a8a80ff277f3403d5bb65007ce28f8125c1d48b0da1005270f25e582bfb67afeb4d385169e9fb6b91380b12fb0b5cff4566ddb7b904e1b358578877c88aec8d7ad1a51f544046e953ab25413e8768f9717646469b98b307606c124180372603a0b8e5d620019320bf2cdcbd8b497ecdb61e8022becd0fa0a2ffff6449ebe6ac53e11203549f5272baa72773625eece38c3acfdc8c4790230b8392b5804f9021173834f9882be53b88ee8fe3ba0c41815899441468e9fbaa038ec6682e0ee217d4e07096b98e1096c9da0e19a7fba01f20bfc5ae4f5ff127039c6aad019d17c2a76a37a814f12b83e1ec8c44d8f69fc6b2536d6ec9083bb4d548ff1f08198ff4a9345e4a05257f8d4c8afdc1498f7ce79072eefa2f0a4ee617fc9a4b8fa5d9c97da2f1ddda5a96255d63cd4aa1d3304bf834fe3ac26e858a43ab328c089908b66f1166b1d4e6862beb7ac33d1a65829647d079f701da09883c38dfefb34ecee0e8bb721bd54b732ec46cbe4e69034ffac117ae0f2fd187baa247436fd0b7dc1dbe0583120daeb9058d732256ca595f9918dc679770ff6b8a98b97be4cb05376925681105cb1145708cd305ab710bffecd185b2b0830e82eaf059a87107046d73c73aea4adc4e8a541447edcc69436703031be5f4d347828b6e19a8a6afe8bd6f147399b0a174299d67b73a4d96341990fd667e840b696eba86bc84b0cb73a43a0ee0eab8207f0f2abac8c77e43f8697b0032fb9c344131c7a3e46dad6bb8f0a14061b5796958ccdfa6acf2aff80a8c4922e1aca216ed874a3349fed0f64427eca37f6877a3220f28970cfc2d9b0f96baad18ba1a78c9ea376095823788283269e9776e29b54a3e8bff05374ed58bf3134706bf82e495837367a543129489c10abd92c71f525c2c53d78dfa884b98498f27e11d6704e41d41674ba3e4e51f95d93581f2777a37c001ff694f523d080cfe89cdb2acbbb5765932459d2d338b9ca80410c2e6ce9f19ebe686b21537ed77cf260225face9e9ebe07e4cdd4daa171fe8287eb18925714d48bcb5c1e69bfc417370feded06fbc6a0ee2c5c07446687c705d75775029079d53d0bceed314562e0aa44ad661389a0caee4cfaab8b810eaba440b1115189e8e5c67603035782db9c4b9dc015ac0f4f1cf61085f7b9976a544f956eb686394de6af693a409b92758d9ecea4c002e10fe6428363495235fe88425a7bd3925ad76087a3b6c86159713942c3c373b5600e27f092bc47fd54eaad9c611637b2aa273a27e81d86db8ecb02d9ab4a34003b86f02f421ff1e019809f97f777a060c575d4363bc1eae78851c668657a79e58ce97b2ca13e58e9fc94a7d3cea4aa2a643f70a34e9d9a635531d3d000700386e9f2eb38d2061a6febfc9a35583cbf474045f26352b3a5c7a43e8a545a96309ade9ed3d3f3aa3ef186da16d3789f04b334dc17af9d99ba066d9ee50949008b023327b6c455443fa24ad25e9c0c73992e3cc84b0c7b707955a6ce9bfd1347cc0dacaf887acc547c7bebde2912a77ff1d210ef2166e4056fc988819b9a0962e004c8af901e65ed0895158fdbd202412db206d0c7c9fb8c033eb13ac20f97ce195712674c99d880a5df8720aa2e81224fcd9cdeab3d852965882212f75c2c620aa8cbaa38c7d1e3e94fa37b137e08ea657d56834e6987f62e9f6c8c1d3ca0da44d01016c00088822f805dc08a7d15eeff84619f62caad61ffb8e76c12cfa5e00a5d699a5412a619bfe6127167bef8f66632f712be6b050466443c120274f8503cae0f69a6c95ec3be1469c1c4939b1582265fb7b95c4f2895e9c4cc7aa2f48b9a27045157a201c8a4b05c2e0dd7791fd4071697eb205178e515caacba2d2d5ce5ec172cd1fb3dc3483f2bb0a7bf045d32d95fc22c0fe3708c929bdb33ed65095d25c003c47204e046bac6dd64b7d3d2d50ea966d46e996895b86c2317ebd5ce5d88a2cb23a01cf7409d1c95f2c0143727a2f56f2282482c0d8c7e4b5615a7943f1daa06d8625ed21263b1e3e7f08182655a9493309eb270d9657123006a42893050eab3c4e72d4a6ebc8f451c971cd941c08f45b6a482f788b2342a5209a6471ce586a46ec0915434d29b068751a87c73f671fbb3185736720dd5cc126340b1be82e4d7e2d58e8bce1e84194843079484f4d05702a5c328d9401cf02e026355f9594dc9803ad42cff5b9d26d03cb51d6798feeb821fd9d6ef9d2f66d3da24c991cb6e9abca3042259b9623a37349ea573e9945ad806afb3f034e1aef1b19390bfcc6a1be08514b69758920c146aebc8d4df100a9f7565b628ab33224f1efc810439472ffd8858ae12e2857422d5d7b3466d37326255a8b2b6bdfc157f966fd213f722a87971758930d1d0e455e39248162a6c176576acee5d5c4aa1610691a3d88263c2a69d7280bd5a9668d3e5d8757b5d34ba15dd536ec8b16fecce120dd1889b716ce0069be69f7e54c97cca956eca417a77c284d77d06ae028080d6b4c02873e994f42347a0469475d7d2ad4ee036ee9922ed0e6c4b64a8dff3e4d77ef7f7ac7bd1e3f341b1298307b3fb33f643809b292f89cd2a1e5024578800a51eb61092a027a8947b1dd0f8e03346ad110703115d61b2593f14488aa584c455f6865791175445977b7aa10ecebca45cc9dfd7ef26ff24f061f4561657768324d3ee327048ece7af8850b172d7815783c96f0144f49f7cf7e9d50ea5aa485a96b3a362e449d52ff5801f0d55ee7cdd88f365ca2a084d99ed52b924bf3045fd8fb66903724a9295ee392dc83c81742a79ee72d05fcd9418d005e23c384b25e7325b2342e25385b20fd840f4ac6ccfa68420d16b62184829f715c0eac1018ea2e3a4b9e3277e6fb68cbdfa9978a4bd986cee453312bc9357203332655e6bcb02862b0042dae3b858f745f9bd4cc8203c73d4cd2ab97f6c43739f4a4cd4e21ba5c803ca2f91d02701927b106fb9a31ec118d83f8743b6875ecefad40199b1f113ddd38926b0cd4334d8d70c06f58129f2f9a1750c5730fdd3636a5c92510f2c5e075984fd3893b43e385aa0e9c3654522d4c968da9472fbc907a35e1d02594869eabe6d04572a17b5bbf88190358817b55c00458d82160f96bc07a6ded136331595fcde18dcba8d622ead32d94b4207d315d25bca5ff28975d25c1f53dfc57a9bc6fd90a779af74b996a08eaa79960d188d1cebc01c5bc95927f75774fc71c666dcdae597c3c3bdcb7b819c8bebb7223e759878d088506520d8811c0a84a5b080c5032bfd1305c33fec208049e259b990fc94a89e2a47edd8befefb55c8c7d2bfdd4ecd213b2c366c791df7cf27b31e448066ebb24e613c70c0f4ff5abc60c3f427e1e32e533b4308351b17dfcda621886872691b3f77d6da4db164d1206312f461643f678788880c5aaf44b0296ba2ec6f5bca19a20706c68ac6d051200dd9f0c16a5bc268ad9332d5cae5f863096d14c870e5786d7339720475b755afd2cf48c82f1d2bc26a61624b9ffcf2ab7f4beec8cc030382dc0bab70d94f5412472695986c39f040cfc99d581ec156368430318f83b1806c2ac01a78ea0df4f33836da6a8a6f234b12751cc200af816a686defdcbaf6a3a2af0c95fe9baa8db88e45484cec09c421e5ed7a1335ce776adad22c024b4ee9523ade4eb1203c1814a47dcae0a438c5f1e5b6721066a5d36063da68580f6eb55d84d725731d7ad90ba46272b04e2c78ba3ff25044a03cb3857e196fb1c15728a3a8296a1e394b4234af982a00dd765b9cd52f2f2b8a119b125c55b4131b267ec5d5dba1a4d35c2dec88bcddea76dec77512aea38d05c2028769b8c63e070ecc061a2a75597be3612dc65add690bd9c9102a724c7ccfea960ec8340c2c870d14281f924830baf613e81a3db0f25ee2d05cc70e958f2a9eda37a546a79430a8e367ff3f4fc99b8730d86742f91c92936c08f907ca06ec9f436201aa9361d36bfdb1ca06c55d306424de55dff1af89c1ac1b9c8fd39c57f3aa052c122f3f0a9d760d49d779b66aac086edeebc0f74067a9093ffa501e212d1409a46a733bf72065133fb295474e8cc7589d97b02b48c0365f594a12673fcfba781264ba37954f51d5bd243cb7656b3951a067be36efef928e3b68c4ac9a1b05798452829199bc1a6c4b1d17c546f283d6e827f76fa5c3f527530c50bf647b62d0fabc76fd48a7a2b4ed1991b7ff691bef00141257ffd404300f206e86b7735b0ed2e1f65c898b06c3c878906c7816cd2b646fa0232756f60d5d22d8e3a83dcfa99c428bf29e505d74feabb79ce6e056bb7649b68890f4d818214b87d5f19059dfb3a0a4b0f264dac18f87d64e7f45f4364d46139bbc768c8f339d4fab86268e9209cba12c8fe7b53720116082be6f011a0ee3607677090190f18b4cebe9111c8aec367ca44adc6110512354fc539f465e977124051b7ee095a19039504fa6607ff2da378d5fdfd8652c63d22036c1010d007087f9ff5637a511cb317936cf267fad40ad89ca8e450eb181d3aa78f60f04a8724291664459834e775f152660c32bb9964147dfa00427706eed6201b76e79496bef6fd3dc5c66227fdf312199011382934facf415f3e87fe5cef4fe1cd1ae84faa727c4f891fa5b36cfabf72e0db47e28ac2dc749963d277bb57e5c65a35c063e91b5b47954b42b0fd1a7c29479a1e89bb2ee6157e65ef96ddbcf227d308ab2c3f236fe695b3c57773a1f1fadd70b03c0da57f6888a3d1cb38e3c1833cbf739c07dbca9b5a327148b2ceb7823a9c499e15aeecd0d839dd59f1a453e70a6ad40b36a75b18b44af72b236ed3d1683d16880b288b6864b2aa3bc0e60763e46102bd57a33113a60d05159355a1ee89a0cc677c0ed015b38e6b59b4ecb8195d264969312100a3e0a893cc3f2c25ca413289d12a8cf3eee4e3118238efaef630314ee539a9667530fb3fad6953e9f7a9a6a9ff1b261ba55edebd9ea0f203ac79b789c2be4f00ee3884d2f6ffd9ecb8f75891dee0bcdb619952de801c865e2e58ea1902de58b0b7c912c2995c537ecbf1bb595ab9caf8ac11ed4d64dda1218f1f45d31e3568e01c8eb5a71e49c454973e9124d9a1aa1cfc43eec2dba9a457215d1fba4618a19b03431455cb80d0f48b8520c07b3473e7683666f8abbd86c2559ff1e90dfed490c363e00573587b2e7d1c2543093f9e93b41c4db85a18356628fa779f88d558f7416fc2043f815bd683056f07674b50945d9b2feb27eeb0579905069ead94330c93a371e5eb5b0a475e27feb1b7cdf032d8b3af9e0f6dacc374cf43a587322f97079a77209f21d4c907439d700344861cb0b885d8d8c55a4ceeb9375a62b6400ea5b022763ba59ce1d7742c61529149bc2812ca470f6a5ad0b5765f4507a4715ea314e6af6c85555c09d23677e9bcd063203a369038d168d576814cc32faba8a4ffc83c00493816ebd6a086e842717ab4dc8f03147359acacc0951ab3986e71f4bb5dbdcf30f041d058a750e3ee57842a4bd509439f2d383e9ca1c5a1a2833b9989e7292439c312ec292da92df483374cca08c5670600efc872c7ba539761986c74981f54ccf1e5997b6870e34205dc677188b963fd3752ff4998ad412bd0594c46d39a0f73e7a914221b82d0a9756f5191a6dc2596cd38c1395f377727a6e65298fb69a1b3436a3defd6c72fc752e4251bd323d13093d7875242e1cf7317b2201577ec8d62e30d189e59c514bca038819e937528f60617af1fe3f6b71bcd8266ab4a6ef6471c98aad4644daebaeb1f4f05d9bc09f1409840d35aa1e5ec223320a2db1cee5ec3c0fa6b3c65e7057bd855673de338f94612aaf1f10af2c8bc7d0439e7cb1721424d83da110e403783258618a0789ecb201363283d58b82a699ce7d8e0d54d8d089b048b5aea5618121c709433e8446202412eb804b84ec8d56e7744b8e95c88569b3e07b154d590d7431ded9d9b17255ce543752d90d184d5e2bcc5be40bd349cabb06a3aea4fb383838baef80ff5af89e43ec2de6d495a250f5f2d4b2edcaa4c1099cf971c5cc76d8b898cbc0075d6784ea56f64547a570aecafb3516e782aaddb1506638adf2ec1646807a1b103d35e094b583f950ec03eb25d01d6baaec98542cb7c3053414fe5a78c8747c7573d436d06693ac99fc8672872b62cd1bdba8ff0f899edea592a72949b4a83411afe91f761a0b9e5ae9ba451be6ee73b2406598c776f9366b3d25be7a38ecd4599994bf54832da35378db48a1e2046768d16d57029cf822123629b67ad045509f25bdca7ea7860101adb100e56c0d43e33870bafc16f8dff4e17c273083cc79fcaf3dc3cdc6dc3a5523d0a60dd0d850812202a98043321da6e3cd9aec1c044fad591c5a92fcb0db474f0c5bdc96467037715281b0069801373febc135d0635e7021f5590cf33ea3a0d4b214c315720543c47acf47d604768b45500bc2f676e80f9508ea101533ef4acd720d8ed67b7b4a8a3fc54ddef16c2b3517a1cb0e72932e884a741324aef58c8816c757eade6340d47df0e2da64f1eeb0e37fe42b9c031a6f4b42af7214769c1ed2019975dc623851040030449080720b1fdac193afca37aa038862c00d1397213eb88c6aa0dd3e2de4fab96f36e803a2fe35069d47231cc5df75639815ab666de531aef72a87150de9ccdeebcc1bd1a67327ca47c543784ac33257855feeb329d70f42703ea6cefa94989ab66ecac37d53e20cc96d1ad5df3cb4a327e33423e58c40fc5cfc831caa68f38842f2590177ce57044ad469d49982bc1519e51f251e101325604f111a02da974b8dc842cd74781ec586a13566e64d3eb2b5bd9d7a105ce697e26d61ce7104bef17d4a4288193f6ce4811bbb467ed78e680f694ca49c418cd5f498a8bc9682f4b61d0a93d497e89a46f5e7a25b5abcac12fbf8f59da04aa53ee8f2d90369665cfde902a735c91dd93f7cfadf9047d1112338e72a2d19799fa1427c1520e7303e834d84a51c086e9204be3a9d8a4e5cdd8ac7891e7c51c350b9a3c77000c49216488085720c928c58353e515d035d0559ec97945a0633261c496a42ca23962cc519717f9f4089b35115d66f3c365365d8c059024c477b333734280f12d444df43a8eb3af5a4b4415f272d2c50ba9342fea8bb6e6b8115c09504d622b1885ae2e6d40cc66bd8d24931761399105c0e8af25ba495563ec6924b08a32add0e118bb4bda546088492d0056d7a3f133c1342b5122e9f8340534775777933bfb89a044079ac0859cc52341a43002c292941d4e9f3c5fcadda81f85e50db2bb55b4e9b8f74000c9b756f901600e03a62714e03e010a11c0f0109975ad0829fa3e52dc95836540d73d0f21a7337039f8eff3a7642714e686c69290808bc7206258334114fb302abfc4863b8962df2762b79175e560290ec8772e8c487c04d2c19db8a51c05ede4345878a494defca4b714dedb91a6b20331f988924cab59b7645e9249e2138a981bb5f126a7d45b06e1f99913180e19e25157942ce4248ca2559e534f61e39ea209a36fb472dfcb8615fa1dee3b3071eb8a899c49a435985344e40c9c5b8cb3e15111878c3a7e5cc0381e39db9171e9dcc565de5040e0c4f1b280b1ea27da282a604a10d16407a40ee63e73ca14ad47f574462ca52b01261ca0cd7f90aa0695e7cac19fd2914d6b615e6cba0eb186455525e1e7c6ab94703b937ea5f4bad8e7662d2b7144570394d05066cbab407a6aefa1a4168ed1e89c224c2d7d35cc3c02949af0a221205840c6746db3bd9e83d334136fb2596ce4171c18d2c5d07933e662a95f8efffb62e4e58b7e3bc0514bb07d44e9474a53b97023714895df516d2213df6f4b91d1f5ce4ff33e1f1c3ed53bc90ad17c2760ec612041fd88b88198607a83b68c4c9f9375c2c51536717f3134c7edef97b34f5bf8b5360a5c71603ba7170542dcc8be2d30302dfecf53b397b9064a91166f92705d07ffc3c2a746bc386d1ea3bfb86cc96618e57ac8717e342db3281c72d278ba81fa3715ad8c0a09ae58fb6022f7c0e5fbfdae4a29e13b1a8fda62336b505c7d52a6ef1ffadcfde26555955d32277f1b04e789a4ba1f89345947864a383207932beac2957ae73db638df52255cd830396f47e7d1fb244b18b24efc9442f86abe64d2f804c6c7b4f20528954d1b943565cdf35de9e4f71d4f3bd296cfb4e910400304ff4928276ea768714887715cd2fbd6f3033d1e45a2e106f05ce18bfbf2f9a7af60dddff001601b19d956cc00b68178717fca5ddb04b07356024e76bdd5afaebf912487f7383549e53623f3ac062ccf23aacd9d20b9baa56d6ed7fb3b604df4d4ee1022b8e692f1025aabebfced3696f37e258d6b5f2a8994a7e325b3af66bf4b33622448a4e624bacfa90c9b3d4cad727d280c21bed091fbc2b811f8a38a5ece13373995fe5281a8e30f599baee2491118380001320b8cf33812f7b1571f2b5279f193c1e17de38c4bf234f244d5766c37b87da61a48e570be3b4406c8cc9624404841913a75eeecbe06d1162fd26359e39050cac18575d474bc25b53a7a65125a943a5ed03dab71212adb1a13f904699ce6f90d115e303b1d0b86c675fc02b077d28d34b53ec14581b64ba84bc9ed25bd84e958de8dbc0dc62a1103fdd243e236405dff0eb860711b91390ff2cd8e2cd81227352c123b779554e73bf31867db929d398f870ffdbb56e228fbfa283340149871d5a59db2e398e3901dc5d5a9245c22b5834b176d7c11ef185b98f8af6d0890daff057492b15f094464e3f6f39655bd5a904fce00d451a3425cf5ffc14608e5f285edf05f67a49d82b597d469c5efe2c38e3c23407945aec5469e67bd4bdc8dace3237269a2ed945de1d7b12570fec36b2d911574acec6dc6bf9c6ee80298ff22dbab4852b0376e0d1afb33d8197dc5adcade9f5df4391bb65c93a8485500336abdcb24d1ab50f9c6b2edba587922618fc4f5ff3912bfa6891775211ddb4c1cd9afe381dcc262e27f211e532c13b14687146fe1a3661d31ac4b3b84ababa716e39a7bbd865235f4ad744384e5b8cbe43f144da7abd7ce58c3c788c0061bac25e35cc3bb126e9151316d98f56a50a8984bdf015a7cb5b4debbe7a718b00a69e0a1ac90ec31ec4a2108a51ad4ab523212626a138b71aed8614182679e17ca73966ae10281c66333467d681e0867b9980ea1690d5ed02d1993562534cfd6931e3c18ac010d00a4ef44714b97b1de99a807f82212ce77a4fd9637a094794121d219caf79eb128a61f5ba8078e32f8a528e23fc8c842903f2793e23086f5d027f2c69af73b74e22ce67283bf218deeb1926c9709a150acfe22d6962f602615d8e5467492b84f6125768a41bb4a2231e840b0a80af5f7758328e0c0390798400f07c36edc2270c3eca2f6ff2f8238401224bca2d8d8729659343b3732a8c6857073bdb1b052ea552a05082366a79468f1048ada0615b3d4879452d6c8ec5148b44f36e401c2077cd38b534ad562af1f13d0c6563c1469432b1b12ed42bc523d0402b46ac26787e6977f04819333a8b2b7605048201fe68ae813819895a622728403b8e69d1d8e85c54f967b10dcfd7c55226fcbc44c91c3cfbef26e50174adec779ab96a411df88a208e0f3e5c819f3e2924ab28b12d3d5b7886eca7c7fb105985cc93c97c74963826270f04b3ee223a0b862d005d2ed4a6d7f4919c5a6d492100a3716419cfb03110607efdd586555b9c0af48fa4c409ef6735b51125104d53ce6bcc4c28924e5c5377be67b9154e26b0bd4c64e50d064f55784d32ee569a8070d63d0d9b19a86116bfa1c1d7f7b144b1f85cb2d33286add43a7b0607b58f1c07ff9fa21aa06921dd125c19d21b75a7bfaef953772f388b98c92b140f4d61101e2bae399c26660cf36338ad092ed40e28abfb6cacda4a2f8360955f609bad436beee356a390416fdc4a7e562602209be0c4503b7c3b6b2aac8e50ee5f32cab5f8b16c2dc4ef0e84581e93dd4a25a22729c2c583b1724267958b00951c294029002e8df72ff36aa81cb535982b94f22e624942a59cb4d9d117c91b4b4b481f9315bc5fdfef119914ff1a7de3804bc48d3ef302732dac86d0070a55526d4f599abd6b51c4758a2c8fa7f15050e6e69f6106af5f0546114d3f7a6a97833a482a5d6d008beb30e055fb836d96be29f912d91f42f74bc75294bb4e13247be51f2e20b75d6d34da5cdf30ed7e04daf8c03cb7652c1e443f61d51c5abe53cdce11d78df953414efc6da5e7a2f529dc7ba82dc089c43e8d9af7dd62b21a4a75dbdd7fec60f4ae6e0a22bf42cb4200024607d5f611daaa48fa00aabd29dc2f7e9134bde3ec0d8978e584adccc38f4acde3f295a04db3c0456ea5d1a53049696eaa82a45ed3f05e3966217db472166e542add4e70e540ae81f080cfa1402be7a5251e2fcbc892a155a1ea5889f119ce05d1547a392ffb457136919072827e866a7946f393a42615558040d06166c0ede122c2c60c11bea03c5ab7ca170fb56c9bbb028c6a5f66da0b0c02c127452595a72453513bf0bbe1333dff52bd2a11a026c7203430006788b9de69fe589ce0f49e0e63620376c01b0978eb4849d19fb8293942ce196b0054ef1cd551603e1c915097e265c55caa7c1caef44599f2db2d575c0bb6ace1e5cb8425e64113b55beb35102a89f56672492887fe80bf2a2a2492682ecfbc8709621ab419a3d038d7a248dd4ece76def6cd17d3ef990d8cd0003748f5413186ceb3d8256b023424826a231b2d3d728574b10a185f27be115805225caca280c94c5adb082b23db64b580ce1ef802b80a9809581f7c02f3d2d54eed53280d53279c21d5fe1eea831ba25a57cded04dc36139a0848486d5ab4a28e42b56ee729c5f765494a145cb16ad2de02608ecaaaad68910aa21d32a405c134bcb5b8cf34f83e582e509f607693fd1eb3020ae2bf7faf0afcb612e35e61d3691320e64861ca841d09906d313aef80a674cf5207bbe8a1d1372f066c7c8a81fa481d446d6b0b3f771488056978c8f1b2594a038b53120989cfb0a7473eb83b2d7514995fcc54c1690800dd4e1913b07397c07e262a787629f8b3782e23d7ca16f9c4a038d06e8367741920350ff8c744e3d9e142431b753264e98327924076c125a7eccb8415c1d8aeef2c92f9f7cbe3f26da061dc01c7a837286a368dc9d2aa0b4a484ef3df008e88e40440cad3a74871aa3853df9364e2cc717d1b611d90bbac3feec37dd9b863c5fa68c75f583d9489480da8eba84f49411cd8f203d210a33daabf400a9f71fd403ba3acef118304729753d3afe73dff4c8c8f5d1dcc7913297fb8c5e980e61533037b40a5d464612fc970dfe4cee43b1883c65ca96735238af80146d284b7d0abd2d154814902e0fa9dfac937572d7f3d3aed13149fc2f14ec04e9ccc9bd69f879f67f96e89e9f12e70082a046d0aa14e1c761f1044b900ab74605b4103c60aa420e600524d6c6819d0a42ff66ed9edbb778bca9aa10e00daf59dc4f4082f85152227e18334f7c2bf325455f70eb7f5a37e5ed451f63d9949016e197175d2d9e4b38df62a6f2898f920329cf4863329f654c792e322522b820028712c1c4609c884624777408246370c5aa15330d0177742b86d0be58673bf68aa719c63796b982fe9e23d64640ae5094471d250d63954111a9ec230af9e04dc410209019d89cb744c555795154038b068f1800474424a8e6bb41221365d37e8387189e9bb8b17baae2b5345cb13b01422d262a53fe1f3e7ef5c46fcda149a0fd9f2e2c64f9e999c6a533b1908cc05eee059c8828663bd6058a819c3ca389dfdd960aecc66707f1b6d7cebcea8b2d2d38ce2a41d9725e2f5959f8d433769967d813cff6d2f3ce5e39c9252270cf7978f7d4999498975f9476e945fbe7e67343363fab6e78b0e9d2e8df9f9983d77d55856c800b58acc1d7d5592266ced8ad04cea3dfc92656189f0de5963a0b24ed9e659e961e2b67ebc13eaa4be6894727a825af54a5a580d2960237a2ad98836f7f93aa1b44a090ad3f42f791874c196e560760ce288c734b8e07640cb1317161ec66e489aa0b64fd6360801a4685c5df2e4c8f9745813a20e2a109dee5c2f972e46801b5d9e9842aaf4b2b81102a168451e3385fe3715193c8a7f5f740cac13717dedeb391e4a38835f9b1d59ada4eaa0fc9d9cd0087a38e82f37955e52a0588c77acee2bc7037f40bdbf7ab5dd9012186faa2259c7c078ae2d2a28d79ecb3de5b39e70a45cb86a0adc7ec4200ba0848c7c10bf4aaecd54e9cf6a281e8314de80afc3c5d0d3a577e3b3472aeb9bee5ab2271fdffad13aed7209709752b121e737fc581cb480a4d109b91c2f6386fdd4efd2686f13ac541e0a73c5c403c44b636060f2c212343b1dae7ce5ffb90ea47b72d7655e0a38daa9c3d068ac813911fe0525eb39c91149789cca2ac40a0ed1b357a8a90120a00791d49bf0f623784cbbccdc5bd1f5b768df57f02452cc9319dacb20d239a364c45527f0ce9fc90fe2d713c90ae6dd4afe9d8ed332122aeaf2813448c9e8893811f8bda1a73772af0588c0c2137662c47543e0580622cda34c191868dd0bf7e14e966832e3dccdd21d7766ba4c4d6692eb72ae36d902180fd7df315a8a2928a4a2a09c8454aa48f278cd957e1245bdabbec42c9f0cab1e2fe7cd24356d5d29afadd493e650deaab52e87205aa27d3a17320583930b388ed058f9eb8ca81cc173a7044fb3e2ceb50e7308406121a6808601ee55939c3f1547795406655f94657aba87b135c182ff811d00ca7033138a4b71771049e1649735230a4a1da36c8bf7966c4f373e756ed456cb2e57a6a176b5ebb642e2c7de517a6c43e42e044071e64c841058f44584e03cc91c0e65eff33e77fb3bd705aa8c40c9508f083254fb6f67766fa26a40083a9f398d1929eec5081cc6fcd2a94229c07d316c750f05f68635b6538536cd34f039c6f52e798821ab13b99cc6946fd20c28d4bb152b8398d7011c0e899b121b6f93a0b3658a34865f0a7b1b3715f30aedafb61127900102c43b27e9b997644630e28c7c2270273ef317e85370e0302277fefe11d94d2b8c7bee17d1bf51eddc07a0b3bc49e5bb344dea756804b49bb7905b9587ab2af3de4bf8337e890fae2554840bc191cdc0e6e5fbd136a6d40104aa483a51516cf52e6dd486cf5c2ac7b6be229f03ad608b20eea138caeae41812842104f0c86ce67a8549ee6c20aa6fbeb107a032aaae473abd23e9f5e3331b30b9404ff2193ab99a4e9107db599d4192e640e8de34930f023cc9f99826d81984bf2a420d5176de43314a8cdad813d2580e4982d99ffe6bd12f5a2485afe030683ded6e153aafcb5e35996c79e29d4083481dee92438edee166d2f4d917039a622daad38938f43a93614fddbfed9810ca030def3b2da4188389c15c04cb398711c87dac82e9bc33bea62c46836ab2fe2c5cedf887c5bd396b8ce770b8f1d5ce9ea499370771f916c50a02c19cb00c6c673411d9b9feec93425032788aaba7a50a14217cf2101fedc319ecccf95d10cedb58b4fe178d4c72f1c72632c5dcc2530436ec89cd157479cfaecef706f2312802f3684230331922456a5836e5b918ad81f75c5b806ba2328c4142b9052d7b353de744d4e26cd0a63d38bedd04a5390458f5092322baf82622e64761922e635cb92a6bdd78ffaf96bd52f65a7ae6f131cd9ae7e52f8a91ae36d788c5d151391d4a19c755a13190044c16b0b2478305394d0f1d81331ae0389a42c1b5f4e35901e66bd5e77006ebcf9acf16e84cbe77562157421dcabc2272fbdc02b045f0d2db33367bf8120c137f5c080639082a85dae4957e547dd2519bc809f39340fe1f91f38b59d6d272588cdb2e6b98c672998349b649e8143be6b90d0fcf5934b3aeea4ac5333d39783c90d4d9bd93581495dfc3ae924139587ebedc99dbbdac6d4fbc894470b3af67c80d2e92a9a5cffaa2529872409c5e96f4a4ee68b353b891c4c62e2fe8958c610c88107c15abfb3669b3fa3c002c2df9857ae9093058ad1f2f6e208e565106f4fd3e2c7987350c65a40a6ce4db116685eb8352ffbe04a9ca162573003fdfc677d7c68d1a82be518c52608d2e978d99b62f02d03c93703e3f013b34324d6693bf4a58ee212ae51c52348f54d2518f2e46c948818fe6f1e0b3a6c7deeefcb3edba1fb7426a832e81c386c9bdc304f1ca05dbcbcad2c073bb4114645419b59a05b4641bc29f146845c33ad666751e26a8593ecfd200e91b0c550b90f7f84da9d171320efceb153a39047be20b345ddc3abd45db1a5d71be8e267ec022b12b538580ff77d2f3bc1f91988186fc435d785595f0dbaa800ffc5a2b7194e6064ed401212c66c14ddb6fe3bf25755a149bdf5f5349f882e504eb53c137a89232668cb6991b75a9d31015b737ec2412c9ba3b67f81b48505b1bb832ba142b735e1b4a57853ad46d6c26a0ef3ded1d726b20bf035a4bd72801ea23ca0960a8c45ac028112eaa275d75df01716efacdad09fc2932be26a57d9b932f18705d479c90f9a3469eb7486651e6ad9a93032cdaf534c0d899196003c002b08e3594700e9c0a2dae079f6cca9ca9837fbb090496e63670554dffc27315b2ab74bd513b1506aa7e82549a0b54c3400a012508d10dad4fab546f83a18df0f768e403d8cc7eec4517f568bf885d8f9d0942c90c9a3f8a20b0127e2812acbc9e73c9f281839c3ff4feb007d946656f6b1625b41062a65df551bd345e5c184b6fc96fa8fe52d77d05623e31c927d940d30fc97c541ffde98581c688d0113fb272188f300f76a8aa8a264c7bd9114e4e8940e62bcb8f8203f25aa18c43dc3317836035096237963e8934a6065c08c38bb02d2a0baf00d50a18abcf102f371fcd5bc36ec8c6e9ce76ed9fe2eb60adc190a8ef59e6c6399085cad718208fd6b5be07579d61ffb895b4a1156979340ecf225d01e0335c79e6bf38a243d31eec8bdd85d2f5c4189b621aa363e43db6fc5450d34c0382ca15df76d65645d526af594c772026b1311a086f8a01692310679c751700d1da406a1b4030f973a5bc643c26ae98c3124fda81d5449d1b7021f41cebf67524e4b4c13e00c3b2b4d24fe7eca5504fcb5bab325a16b6aedb45dddf78adcdc30ae259bcacf4128105985c79eed1a3b695e383c643ec1b68bfcf9a979bceb2f1e59dafbc9ccae17ee150cbedfa316ffa327fc96aa1f24d7a64ad01d4f79627f82dc705008df5cf58985fc366612d919712fdde866c4020bd943ccea8be6a2d47474e47c02bcc10ddd542cb029cb61e283b2cd271caa0dba44ad4a7f6b9ef8bc429f27514ab9b956686377b2cccf357c2de2e7d4135e4cb0492721aa38294b3693e38bf71d556e019e3edd8454568eb5802af5839f367b1ae8364d5def7da3beaaa298fbce8db3ab36a88822c0c2769c7673bfc0b951467242fb183b08f52ebdd08bbba689469b3e1ba3e1d3687b6f05b4097c758ca193b0b78344d2643baf7a21037f5ca32e28e55fde23e90d19fc731d75a134ffc97bcf767bd96ee99403f121eb8b01d756edf991ad1655cd00b2c7defbd800a61f0c8598ee295105eb37808824d1ce028ec73770b29edd585c8054902eba4511db07b902dc0bd04b839f7c9439511da5d02b2c40e0a6edcee509400766015f418c4f82bc0a20b27019daf7350ec83415be3a05e41dcace08186a45940bf5849e10ccb5cd69d5b9dc06087af6810433898dbe6845609e607dd82d6884ad6b557c1ffee81fc4e3cc18d92ec6b5eab8daa373cceb63657c8b0144af39d4bebc736cb3c700f39d3588d2177226bc33401e3f11cda6ae7af9aaff6d86269bc4a02e91a259fa7a20a65ac81ce4daec96e8a1d5836e568ffa44814da449a2d93499f2a04d325c60443f50aa52230c32789c7d71d23eb04ed5184c050834622b3c5b58819a1f45195ea1af1071911a43fbe7bd1e3156fbc0c8c7e0843839c5088bfca71f1260f816164407c07a21a0fbeb5247f8f54bd1b966106e61955ec84f76dffefe382aecdba88a34700f76f7667d04c6e2d8df4d1854bd81d27bbf2cebad90e74cf7826561ff77d5c338bdfb011b64bd83a20f4f16e4714ebd98d4182d5b6d481684032676c311f6ec67036b326f50f433f4d864f262cd127ad4889b2831ca529831aaa682f0565b93ac51c149e85ac587980fb0363d93f2df65ce53758b7674f322ba2ca98ae4b28b7d8b43067e7adbf22643651d66ebdd2c1c9fe3e1bd70ab7fac91edc0e01f72a93c2766af8483273d5e2374e2eaa367b14eb909f70a23d809be141a352e5076f32becf8d626695c04ec10b4a68b9a351c0ee45f327900cc8bf6a53b732c66402c39fbe24f9f6af120a019510b614c71bf6c6020ec65e77d3523afe54dc8fedf1dd293b7144d7f15af7272b8afc0a9a4a1ad668dfaf513687143c3d4f8319f72942f952a0f51c49ae7ad017c148f98ee02954137279b8edd23771c9433b96a090232f094834c7836bdc285dc3645e6502eff23cecc2f6efe76a5d367676a0c5b975900979dc74dc341416d11f9df1b73b8ddef0fb1b3d6c9f5cbbaeef86f5e2c7d6de4583eb0b209fd8576b6bbd2098e08d16d1f8e606bf37caaa965b9d5816eb55d0acef2dc2799d52316a25ac293bbdeff3594d27210b9ba64433cf322b981202d5b4eab5976b10f772988039e9b1378e8c2cefb6311b20cf11ac28642ab72a47f64df5195e0782dc768f0cabde64d77dcc09ef22d2538b8afd795726f6dc773e6796c719483682844f4219808e519cefba401e1b7f5427ce7df33caf64515ad03dcdf8157c53a91f9a907c38e7e9d9759c36b4b702cc49a0209f04858bcdf4db8a9283fe954fddf6374eb0288b7466ddac42ade2fa440d591c4dd9b21d36773c66705d26ffb39f4eb0623eb4b52e7c4065883ffb71cd667646f0021ebaa678366430a195a9fc80ee716b12a78102494b7b35d7ad2f780a1d507a504a2d9d1120dd1673888cdae6dd702db6cd9eff96f532a932edd74b52a7203de7070d18bd9977ed701d8de4c97cc1d57c0d7736a4f8cb4d0360961cce0dd3da1403c8ec97b4fbca08fb52250f186d835ce53574082bca35a99ae6c9c10aab22e78c6715a361fc9813ef1dcb1bc70810fe7eb52274bb175da9d6503a83a34e3b7609c7e119329f6ec267abc554e5e1cd7904d5a9d1a02909a8622783fb350d0057204c020ee61fb3287029fa955f171e12b2f4c8ad60fa5023740bd101d00d5bb7904a2fe92579c31b522b33456eeb9227614724a6e0d399c82625afbd8ca04df85d8515c5270da1037cf618821546a88e21e5136d56730e6365ea98c4055040452e017a5a5fd0ef6a3804905bf462e04b45e251ed8270fc1a8ccf24b1a33b4e8c7dff78f16b92937ec95ca8d1b65beef944c2778c8caad9b78c8378a8033540f7b20bb095e93694022da1b2cb4dbff00741d5e7e60f80355ad17b05a0b3968c6214b7e6f1c85225fe1780bfb7623820794c8e5b0adc16be2d835b6cb7ac5e0cb8977e129c4e036020daab2a8d580bc71f22e7e2f994cf8881ad8b6a990a24fc3b446d4af8c104c006b2babeb39fafe830106fff09c509f72858dec2e227d3e8468fb1698b5e521ea7d6607e46ccd8aa95da4a0a07517d08e716e8c508f1c5ac71dc6ba4ae51b8b4e993c31650567fc702a769a952ab19b45c9df511a4e63e18e4084ff6d40a9285938502734abcee19e551dd5b950d4b11af762cd86014606871d7e9923899c02037a1ca26f5b20161aa903761e10962cffa761fa3b28a6fe7598eb3b129df254c7ab140651eebd8bc1f5b8840394d6434797d2437c7161068e27b8e649fdd53ae326aed044670ddccf4b14556ad47ba9210c9803f608c912b2a5dc726f29a59432e206ee0618071cd791ffb336bb995dd781919393939383a74f4e6b4f50c8d24be96d714d1cf65a4dbd72ddbd1d4dc7ed67885a6bedbd2fd81c9af3051f67ad04811db436250b6b6994fe7295b3b51dac1ad725916c534a454c72dc57fa150cbe7b05839f62e8ba7daf8b50dd8a5a56513d7c2c95b81426310f7cb0119c0ee454dd1fbb22428c854c144d11e9f4ab101dc6ae08cc9a36f48de8d522d1c192d3a6089a968da16553657fa673e28d4d1b6a59b3549a45b1654e629bcc5dee76e0e3c6429b65b9598b3d91bd3818d5372d344b13635a85cf8a92d95249df7aa0b5d65a6bad49407c561438b48ff4fafa467518158754da9afa576a8abbcf7b3a914edffe080ef5fa94bb566bcd5dabb5d6a492bb566bcd5d526971b426959a5472d76aada9e528d5e0106f0d6970081c0287c0211214ee458c998c24c9cc9153f5d279395530581cef1330e2011f2b49a3425744872a0a02fbbdefb1c591de7a50215b63dfd22a0e14873502d53155379034b24241298929a594cbd99b41617e2f342fb3a63e9d93ce79050ad013a6486209424954194a620965f73035e07444ddf4d861e1b6cadf717124878b9e5edf8502f43a6d0d8fb9ca62b6357556c11f50c58684236047803083204688118357133c50e20822d30444d8a089cf0b08208c58d52b62e46d082a80008522abba85163028228c1e6250e496801c6a43bcbac8e20a2d56f5aba85e11672dc759cbd9bfb9c94ab0d96c369bcd870fdbff2c69c16f1fdf87c599367bbfdfbfbf0fb2e2300bbdfe8f0e589cfda29f401a09ffc21f56bcfab77d2d50dd87103cc7062e7fe75dc0001307035f4eed9ee823089efb386d0dd0e2066a4d7d0b5060dea8cf853e7e54540384f88e510f9fb6c67a48dc8444f7a26c54146a88d39e4754a7d3cbd66583f974efcd7beb103f99bd74caff6c62c2a474be2d42672349922449b2d65a31c698bb3bb50647084450e3435efa9a5ec970ae4421fd4639768c66143e421a3c92acf58ab648c4dd7eb0821510bb841513fb41561b7f78aaeaa5f48ac2b9b2a225a2c7221e3aa18e1d4ef0b192395d6caa68ad3ef585ed7fa21c766f1f1e4b5d8a630415559faba192959c24d5a9de77a21c9ebe57bf7c949064577a15bc41a61ca79f7e947e57f8141a73bee3b0f63effa69452d1f77dff8dbe6ff4bd4e157da4cf4b09ec27e6a4a2684ef7c4e7045eebbdb75482820d1aee6dbfd8de4bade5e1097cccb91cee3a0e73b8cb39773f70aca12b9a13db2b38eed8362bb110e530e6e8c4b2eab3a92c67ce4ba52f7ffcb8b9999dce1f5d6d5178027f24eebc92268e58ed006159c2ea075d4217abd107f99e3f07c513b0c41d99282b1cf06a2432d91f64b52fa539df1f73ce39e9e7dd6f58a370ae38518e17f1701caaa4d654fa93840211809e29cd5b7fa270874241891fa0d50e90cd8428abd1ef0099f1c18a2aa904a80fa4b2785889fe0b7766fc8cc4590900245c894426fb2b7de1c0674529a076dbc54045fb23c07d53187d29b1359ce047073ccff33acffb489fd72c7f8c82f0f2b22dafc2b9dff5e338fadc93a9ba4fff853555a94e9ff3c10cea144aa7b4694397b0754a0498a5cf9594e2cbc938d94b598316574bab2ccbb22ccb9c4b255e85e77f82d3a75c6971b22d1f85e272edec047f8b3b2e3f44d162b503445465c5c43e9009c60b46e1a9c7e8441f146bb035f54fb023225738e0954864a23fc86a7b1fc7cd1515e5d871ea7eff2776c0d6d4d212814d95bd61e2d03a5b628f9076057556cb3aab256bda0899357549cf81ec4408d4d5167f38417255f0719619983fca59ceb2562a4235356baa4bd14ea41c121c3f03a6584bddb921703cf33e4abf3bd9a7ddbe165f272b5292fabc44516ff5eb50ad35e79cbb9c3b4cfad4b2962d2eaea4c672ae3014a6146f4b726961e1e088b22c0e4974c9b985731691c562dd80675b435954c864659ac3a4466aa83f36406f684a29fdf616ed2dfa36e9f35202fb89b15835f655fd035995715a65a3969a82c1e29486f88d666f357562c095a99a5c4c5517738bfc15c589f7e66cad28c78e0aeb3f37db85c85e9159d172316dead74ac30222a0e30133856952f4ca7ddc732219acb5767b3167391807c169f7df04d7306d748443a9a96eaaecbf64d405e38ad0197037501f7a7d9d60aabe0fe3c8951e6ca5d624018c295ff48a69b586befe3d7ad18f738a01b4307b4c15f82cbce5a540e16442a913a8e35a5c0f15a17206f4e4fb4ad5cb766b9097e87873c312629f10bf6640e5b4a122c41199365c8bebe160dc0f7743ce494d271183e97c73a638eecdfa0a4b87a187bad55cdc9f28352897e2d04b307169333e6e32a64bdacbe2e82198c5d92c1f6640ee96b6a2b94032537a0b7d23b517da8abecdf4ed67666751685066404f62451831c378866736d60411685066404f62451831c378866736f624966340585653f6c98c08188a4e279817520bcccb09e685d4e2420a673f8578e502738a79920bc905e6852472399d62462f745ba261f72d2ce1ecda0618da40f58f421b5e0afd95c2b9ea4c5a6b6d32954c2653c96432994a3095461196d2b760785184224054e16262659fa081154bb4200a19912273dac933731e35a7cdaca9ef824d68ff5a11123815f35fd8b7821d289973ce5ca77ac1517002ca93821964a638ea9a43f7ee3973eeb85c81fa1af0b1b5675d1e7f78ff7fdfb767402595a113bcf49299acd7ed72b1e1e7d8f5c23017297365970bbb48d767cf098eb8eebef83f790190146324f1c4102b073841044fcd893076e0050ab7d05f98f388cebbd7cb396b1f54adb42f3b45dfd65ecebff646fb634ef8ddd3a2fdad5cb6c5736e18df5b62d550df52c1b9cf98f479dd6ab0afae7a344ab3e5dce6fc3fa98fa952512315a038b40594064ae8f527a532b02267878f9c1d5335b92fa7c4738ece8c12042848ac805c9e1e569fa883150edcea13996c5a5fd4e239c36ef96dde310dfbe1a5996bb8dd6e9d97b397bf7f515dbf16904a928dded4e8699aa970a2ea8f616c68aa6610e845d5d40cc76a6f2136f1144e44e510157dc4434ffa88a3847dc4363c622af8de7b5f86da6f9745b7d7168bc54a4ecac8e314538a65e848819f74303c2d171f676dc70446505356ec416798562616538ad975a559bab9b9b9a9ed4042df65ba9984acb5d65a6b6db6a65a9bb5ffd66612774c1f23ee745a78d16405a42aa1c2831513fc4156a315b2d6f6a3bdd9b28e3cfdddefdd75dc8745dc534f94837b8cf108c4d63d405fe71188ad6b159c7ee786202b9937bdccd747d59f315f6d1173bc79c940454ddb5181143d2cb13abda6995ca6999f117764def4415633af5363683c0d7187c6c7c8d090094f3d66bccccf106debe4bdcccf781ae1a9c73f8d7f1ae2c9fb19decccfc8881646b381af6b3a8ab6919ce4247f8fb438d66623496bb3366bd33192b4361dcb4ef051d346fb82828f56a8a63c4db3654dd9f023c8fde5ebccd7b7546a4ac6c3c462ba247a33a195013313d6958e591c4da3c5683a2603e6c545d3ace847d1935ec2d96742bc22c99891f997b004b9935ec72c4e8e7d4f92117efc565fc4917bf9469af9da97cc883b405632e26ef1fe85ee893a36c6e51492a0094ac8169670b4b49164c3daac6d248d3676fd4c31f87548c3ec62624c31313131261af33726c61413131363d2344d33dd64545316b362eced3d1a8530561096d1999fb7defbaa0a17c5d54ccbb2d3e69df90d4cbef4e76eeb916887d8488d81eb9d885d59864666551a1998195756c40e59de9c2fa218b89ec55c9a535888397d2c261b321f9d2a3a6d02300300167d927cbd64650a534553c3b3dfe1ef7ecb10e5e87296c930b65fcfe2f0d0be8872745686ed6c8d0fb36ccd672bf898675290990200153eca63b2a9b44200606cbc8cb7531b165a64b0207e6241fcc8623f41c8623f3051986fb0dcf0165494b3904a534824962f71242e8011f72387914872c93d243eb0970f12d80bfb60d1db0310e1d7888d1c213d239dbe3ecabd4ecd47a8178eb9676bbf4d806f4ed5ee13a7be39551aa7a6ee0bdfad5345f3d3d9471a1b376848a70a778c73c6ac0eb33cfcd64697f173e10dfe1b9ca7f0024ccc0df03d1126ddef17d93962199e79f379de52e8d7af89c2f07e172e11fd0e796ac0302fdcf50b310bb7ace02396d929e244273654d8e85d886132a0fa0a9d0b312b4fe1ac8e1b9d14c075fcb563719ca15f31d66bba86a11ee0bbb535858f57851b004881a6060b363602b0420d4a859b1198ab0b28948c85832569715844b0cce5bdd7de79e9e8f76c81eb3e8265877dacb573de39f1c7d2759f0b18fc1403d7adc872a4b7f4112cc1d2444a51614aafaf423955337aa2f4fa358e30c9668466c82c0efffa3366e14cbcd598d5a0d5805271586a00895bf423fa38e3885e67b23015d1eb9b904c1c9616c820090b0d82982ca65837326dea4f118b6bdaf0c047b0ec3390cc14e9489d414ed57e520c66f874520f33b4a9f25e869c2afd2652ebd06b2d412a35d5d970d47a665ff42c40e0a3fd0f7c1d3b0a3b30fc2db2a39f223bea1edbee7197bffd844909cb7f3e150616d2f4aaa9efe65a739f74a4a6c05645c560a6c01d4023a41ec052099d0506890ebb075be00ea011b07401837bbd9b5902342283a49431912e13c979e24cb56f8327de5867718fd661c45244d12b1d63c545ccb23543741ba81437a65fc04713d9eb5f1369224d248a6508528cb46badda55532eb5a95aa1d38f8169f1d9a9e85302c7ad1629e604da9b260c14889f27985801d1b0daaacbe2cec8c90a07bcea4426f4e7cfd55c8d34606a7ccca22ee80dea063ee69a99338942815fd0e6ceac2dc102d70ac844620732c8c1aac331fb48a3ebc41d192956404840586551a61260c2f4fa638d70e220d11b9586447184f3467d182cfe0f9729c97442fd5e8c63083bdcf6572a51a48a168be571ae5b0e68a2590eb0c841b3aea052654895175c61c565537ba287f46e250e5e2cb746bbb5a6f434d135d64408fad6a48ad94be94ac2163db4aec5e5c38afde04ac2a749123ead0f42bf8635d30b36546b41c0e08b29190a8265e35460ddd715ac11eb0a1af420a1a5f684e62609403d37ee55ca605636e919eab81908b172501561044d7901129c94445cde370312f2e2b72488d8412d8921a824d1c4092c7bb5e411c24c099e32d6d59b2d5f5b24e161266a61fd58961244a4f8ca24c67029c1e3a4e69562f706440319d00c2835b99ccc90f85e41384809bae1090cbdb642a932dc5e6f9daa9c6c4a67b33068b834cc3890458b9605ab4f9ad06d3e953e69425168424d74243aedc08be54468b3dc467dd2aa28b9558ef431d3aab0a0d7ae4f5a9522bd484c862d4aa181d7df311e20e2536d4e50822d2f911e7a79a2b09bc09c17a219879d3022a2e3ace44ca50aaf270a0fe201e279b283787ef2b7451344f4419f8fc74896e15901ee3388a7457fc850d0102b1b884f71493196a02150720d5a9c64972d5840ba2f2d9d7ed0901dc810923124a6a130692662eee9cadc94c80c710d2122bb726ff47d4449c833381834a6a01f94202140b5d915f2848757888b3948c88feb93d1f830492148484f06c0eef4bda14f8810153e6fc8e586fa3e2b1f9f024a108b7e101158104b88920f4c9f412c3207b15a3b0c9a9d58c14a0eaed0938c08c067db42e0fa041a03a8f3d077d2fdbc0fd018ae315843b0180ff009248610901865cf3c5c9484851b2f5ddc7c330401af1ff3013e81c4a8d5795a82504f9f342cc2e823c7e24a9f342ca8f4b144c3228aced2270d0b9a06684264d7274da84906c2bd3e6942b00b8033fe933f81d375dd035caddeb4a11cc63604a9680141fafefa1451549f1535d2e02e0ac1efdfb7e1d7b7fd2c8ef5cdd98ae9e4b89fa163717718dcef39974af42d5745fe515e53249c73c7f33eb621a7d3a067ddfae07b3911f8ebd852feb89ebdb538e023aa7b0e865ce78d16b715902946912744345965919447f32bb17c7619f12e7827c4f1157c9d576262e8de7befbd498bc349fe4fc3d20db9d3020fab1d200458710f248515de64143f5062c46a074867c5b5e2442640e81076b0c2229393fd498e9b446d7293577c81227f45e0b4e724a6929c2aaeb49bec2072924dbef8b85bbb3555f37b0b13672399353bc90b1bb64920c8ddb3c9eddaa316e7844c614d151e22b730d2b3c8e166aa6a9f33ba8e9586c0b13629a36d729331baf4a8474d197e32cd685a68c206ad24532af118e7bc2c513459888fa8299bc6711cc7715ce65a64d23d4c101f39979d541cb1d07f5478f75c69083e6e1a2e2baa72373728d47fa9e4c2f9771f51dec55f479c05c536a169c3c55c70793145e7002ae29685db09ddb18aaadc8b83712e8ebc9773712e8b23809b929a9a35f54468dc3120eb72411fbf3e72ae5b173f7de4605db0fac839e9dcb5b19a1af74faf3f6ea00e5453261ab355e40053a722e7aad5402bf8056fb83778f7bd37ac818e6f3ff17d10801a2afcdf7bbdbcc3daefbdfbde8b4b2a40a2ea51b17ff0819cb8855bb8855bb8855bb8b5e70f94fa005bd259fb83edb4855f74c458ff5454fd81d3310dd33f552f99364ef8885bb05e47bda4d7ee7b2a0cddd7c7ad9ac28f3b171e7ef14c071c47a3e93089c1473c5553264e381f978fcbc7a50ed1d39ea683c602ebc56a5a78a1fbdf61a856ab518a6b187f353e5ac2c71c6a73d09c4dcc09c59cd356cc713ab48aca969b514c22e4d430116a388b2832c65d875da3d73996070465cd382f95fe77ce5927773cd37f9d1c78ce62ce39ebcee7a544470739b8f75e2bca31ff26e751b4bf177bb6808ff396b2f7eb9b60a6bcff5942bb238581a867d222778c1e62d02b183594600496e26800bd51ff46895e7fee60ff4879d0bf1b2070dcfeeeebd452f75fc9cb5ed65f1a8d46fa77585bb3355b0347a3111f8df8e8752a38e288085594973b0e5f2b75cabc41adcd19c2ad86f2bbc116a2d168341a4d870e1aad5a1d343c693414ed86d6799f3f7b9976d3bdac5f935eb823d3302661c1e992eeb1e0b58fbf4307c997b47ed5893b745454fd061c818f58bc4e9acf9e372f2e7cbbddf0ed6663f66ec85a8f7bda516a738862008d31c6a81d279a8ef0ef23be591c8f891f6421e58b1a38018a9576c29217fc00093b2c81c56d08cf4a43d84c1c25b831552528f54ba70a874b3e05cc2becb5f66a91b5dd87653555baf86665336edf09bed94ebcdda6aaebf549328ef330158c85708951a84fccb319c90ac74bf6df70c927b67eb5451cbbd4326052f9f2ed76bbbdb8443498f35e7bcab65f8cb9d7a95c6d669259adb5d65a6bb2541235acf4a38ee9d708a42c7bffb64edc1cf9752ab7f77e53787a298527d29f3ec86ad34eb2581b686d73de9ff3de52e965716e6e4439ec11f3a627853d4a7f12774e5ffa1d738a094f3d643ee66562625ee64fe1a9c7cc9f7ee62473fa530c77219d605eb4d6326404b9cfbf3575e9eb548c852a8afbb2a6e8a7ae7d4c824d550bbd7e0d0efe79e1f28567af5ad22894962aaa721cf858cab7487d3e6b6a46dff5dbb75e3aafbd1dd8b7fd46323e621bb6511cf4feedc01b3804de3af742bef8549c3c5537bdbeabd75a839590642aa6dd7bfffebde0ad9f76e4cfe20e5d7541562f55dc38cbe2989a7091048b299e2419b2aacf5b1627480da4a81da1a6031251b0c1aa3e78ab0f0e7dd7c12b171c026f5f70db47f046e3893d69c6eceaddcfdca70ddf8f20f725a2daca2b1e5e7f5b1e7e4532ccf4fc3a9c73efbdb79e7a761730b8a67dd2dfdcf785b8a7d6744f5bf56b5554d753511d0f628b77cf6b6acc3c7cf67bfadddf0ac3f75de661aa66effedbd6e256f7a20fdd77b4d5716baae6e7eee967d713b09bf17551a577de6e944154df3ef0eea6737f6371ec73cf3dd7396caba929ea6868aa6e742ea7f473dc17a0e27c1c89fb51a68f37bd135f87978484d354f7dcbb30edcff4ee31aca66cef6c745dd88d379dfb9a0bf6a419790ad5277df182d3b71d029bfea41967ccfafd2dbaa4fad11249e6d24e965335801ab9e3a6966ff7a90f2aeea04ffafd273b7c541415eff521eea8a87c732352522bc61863f055511784f50bfa54d43dc26f7ce6df1d38fe2bae80e35fd2eda03bc230f8089235d2e2f02a9232d011bc74d611c52c52c5795b93a7f0d91ec206770b4f0b0f1f739f5364adb5d6d6bf61c93eadd45ad99bde1a7ed3d2af9d5e716be57352fab5f0f02ab6dc400249393e1b2e495c92601afeec7b4b3c77327f3716e5b0d75edaeda5d8a6cfcf54f0f1ebd4c657bf9ee77d190b575c847011c2450817215c84b0c2d5f36ee1e12396d19b9e8b70eff7b493d63bd29beeb0e68ab2f9edbdf4ee19866a6ab4024c8b8f7e7ca16dbb2fa528cd7fb858ace777d2bbaff29f8acadf75b4c3a39302b8193a875554be1faf3cbea0a100608527fa2c272a2ec1cf9fa3de54794f7f449b2a2e8cb1c594b6c685588dee42cc05d9547d5fc3b9e2e15ced161cf8fd961b780b8bb37cfe08b022d0b238dce78f4004228064aabc177bfe185b25407e1a8e29b8c2cec5943d7f8d11eaf95370a540d6989a135cc9473dd39a3601ee597e8a26809f8b3c6eb626f318b2828f2fb41110af7f82c1a64d7e16213ed29434258dd0547d9f9f268ba9f23e3fcd8da6e4ac520a2d1e57780c591cba7a7158e9d58b40c2f880b7b0f83891a8f120a7ea7b7e04b410e1237f2151eb79b70ce194260a9a29c00743fb72c444bd0091b67039e265366db2fd2a926ed326bfcb6cda64198f1bc55185f4fc58cf66760c7a0b0fdf369bce009baafb52a694207aa6a2d5f396627f8ca9d91f4f337dd4b32c6a19c2316bdad89825668aa68ca14d95fe4c938489ca3fc640e979347dd1f39b86a6eafe09565aa2e72fd1a60a7c1d8e1e0cf5d394b549cf9f9f26093335679e328a4949d2f38f31b53ea1d8a2e71f4f3009dca64d052fa8ebfe56c8b259cfcf5f39736e5fbd8a72bcd0720a3656cb104e59d3863e8d6dda6429f9479a1c7a7e9ad654819f6d939e7f14a3e8f9c5d654ddcf4f639b2afbf9471a33bca64d7ed1070e963ddfe48aca6fc358cf2faa6961f10cc8a68a46cff389a19e9fc7cde254fd8936a0a64d7e196cf42d2ee15f2a712e661e575eb6e03c8678dcc4d10efc36adc8f5c4c59e34230d57a7bf5b4a3e99a0b24ea3a7d3a7d15353159c812d259f3f45b5dbacf8a2084c78d1454c8759f3c1c150173c4d84e041a9a64e31d8da671687ae288de6061c7cf5f9e37718191f73af280ad64021fa608d3e68a3619b11eb97525a2beff8aba830f808b630ede0919ac21c37539b2a54bf235ad7f92a0adb2e16ea77c64fbfdf7dfd193f35759af7a50aef441da28ec80b8bf3f9770f7c045bf73e27551c7094e9f74325f808b6fafd1a58f0116c81ad9aaa3dae23644d555186d97d2af802ef893ef85353dc5fb0e54426c37cd2c11908d42f48ebb78a1f147e6de0c4fccd88754bb69ef5fcfbb4b7ee964582d26dffdebe8d59fffa0c7242d6ede714a0a6669091ad6badb57adc7798356d3cd1cd31a7cd2c6b47bbd975dde5a331c8988259afe29863b8dffd1712d9a51355ba17ce8abab34e43c789f7235159cfef510f7c4f3bcd0db87e91d45a44c245bfc523fcd3bf77a87f536f24fadc455dc77ee1ec983555bbebc7446a6abf7e2f365530304df88d4d154cd7e228c6c3ed8f9ad5f108d6760a7d8b73dae807e43e63f09e7b1deb719f1fd0891cc96ab1e706f80c6ac1e66afe14c72cea81ff7e15f5e0c4bb03bb6ccde562b8d169d0179c0a40c2be7f7f056fd310d1c476114165a6cbcb7252849a9327ec50cbaf1d6ea841a95b5ef575c313fb062a019c14a8444d77263175686804000000006315000020100c06440281482c220c7bb20714800c69804a70543c9648244190c448088218630834840043080106142298290e028d38491fd080276221f42a9e46029fa503f9fd9715a2f3e10884ba90932373582caba459a423e7246e55bdff9529ed2657276b9602ef22bd7fbf161e32cf607404b4f2f0db7aeb669ca57c4b8e43805bd20308671dcb435c4a3b24b37b3ed23d41d74e23cb79b7b10b6cb770cd6dc4a1c8057aad44c8f3c954b6a076096d549bc2e0fa99928c22b0e6930c7aab36d3d504b705aa1be3da7eac507258e092782a93b95f21ec68b6c01176536bdd6596713bf759412bcdc073516d0c358e606938fb59d0b8e35a94d04888349bf6836eade0246f4d623245e91e729f2c6aad3ecba53e5fee064f30ae953ec8de3ee5aa992dc949a7625b949bc124ee849988d6ca8ec7556c0c2c4016c9cf19367218ca38d98dcb4d7028e828c2468006201631572e5b01820024c927b1416730df577565c42b90e284445e0e93073865d1c360e78fc12956e04b8d6e7c8ba5dab1924ed2bed0a3e571557be0941351885a06b4a935a189c8a108285f9aef0eaca88e48f8ea1106da5050157e55938b8175592268a30c782f2fa8199cad1b26540c256a81c39ec747a2deba3da98b41e0a2e872084a09938cc92b1d5a3fabe29f2fded3b00c7e13ce4f05573fbc7a59508b5b0d0112cafb09447b1d82450b2070643f90ada0179be1e60c2161ca725f36aa6a29ed4ad9d06e11bb299d1410e29e46cb3bf2cdfb8224139915eb318db4c58bfa0ccde1e59dc6d0541d6a6179055bb2ff1cfd225579f7785557e6f47935360273652a50b2ec99d6db543a5513b02880db7b9bb54b5a0d960dfc43680867fa58ae1a76fd8b052d06c61ca1b1a363b29d581d8af45722853b8c58bac325fa8b5fbe21e5abf12b79747af8c67ea5c19ada3070a018776168f48589155af317e95831ff8215d428977ce06c8c262f4bb63e4217c9dd1c7ed4a60395c50cef3d577d5cd756090f7f9536cdde7ef0252c41d83e973ee559fe744770096357c05ddbc5ca73be183a04be181a857375fb703d88b865c3b95287679a5e2798f6511e45c6f18b1d11732d86ce389340de14b3774b8912e3e9893ce1140e9dbb002495bc92f87e59ba53e63b535809e6f157c08c72967ec3a2a091353b9f6343be5e3c087ba14123912b8a107c0fbca4078c67278d0fa22a8a54b5a95a5f3b1d8764b1a4a7127321dce8186d2f46f5929d31ed09dd6245e1a96cf75ad4f68b26f0d1fdc6d9088e51b1637317493d62b7d2862439e9c483fb1618618d4a72814c4a99a8bd79c59a22011206bf2f0733b7ad73f3f5631668cbd8d97514dfc29010d452bbc62d44cce36800af007394617049d0e94f798cd48025614eee6f431aa97a1257c8cb8601ce7de227e6934280410f00e288c3ab1194aaf0f396738917f2c0a18e1b784eae0b6b7f9b80317e6503eec9210dbb84e7cb7886a19c07476d061164d46a8f3f5d2c1a09b6adcaf7d136a7a7288447d68868287a6ac4aba77b0ced104c612e646df05b931abf38414474192f114857856cc30e72af91c017491f519ae2bef64e3f7f3e56aab058594005513c867877794b80142c4fa1fbc181f58355b0864db6e60eaa1980402af5cd0630b9d2dde71130291e92cb80e42ea08b73aac5049265eb6dc9ed07ec24cdd024fa5a98fb44931f1ed29381a0d124ca67acefca94e4383eaf23066c57e2aacaf3a2264593aa42a00c872683184d2a97a07734035d49f545bb3cbf84e9514922ba4f8bafb34f8a1d260af12f26cf868c1b3281385405c17c814bb99adacddf64e1f724bd6aa785222978ffb4ce4d58fdc9ad79687652efce70c0130613f37128d399698b7c898df56c8e3334577ea03ae5743272bcd9e3530250792c77939d609e6545ce49f975b5cf8f050b281d3da598ec1bd3796a2162e730badda663f55f4f177fd1fb458a1db3947f2b84eb6cbdeee09d494d25fb66b5e4fc4153cb8695ea42deaffdbaf068c72e4e330077acd6ddcd098bebef2bb34349f671a5a0685a50544779b7e4cdcd54473ab8bb601f964d5090aefdfa522c68dc72dc51ab13e892d4242231560c2bff1052c639c92088d24c4b16f257160085b3368af1c42e2f3399f44e4f5be976a1adfecfc7c059edc243d15fe54f0f0a09217c6499af329996bac545fa6043483b3a435c9f6248195aa5b0f20256a89c34e7f805e67d5003231d0b42f70d1100738a79dc5426d38306203da2d8bf4d402178448b9251e3a072998a1bb4227e27c1fa7b22386a718ed70f9e91057b7c31d5d74b616b078ce891793ac59ce47774aa08f0d340dfc262b1eb0bce79308da77bb13b45eb5bdcc0969a1ec3b444686b8a6cafe34c6c054e797fbe601d3eb5917d01385a44c58ee0cfd4e73aad607a0b605c730d18db5bad77f048095a3423f27f731b14d31291530f4dd7ea26f9c39797d1eb9febb58a0a6ffaf793a20e419653e04d5538a957d7924801201d858b99d10ba620f0ee080af3c09087bc09c26ae67ff2e4f50dc5c1261381755e7e01531942cf3bd181479b6ede4506fc33e4997616c94068dd47983dfff76e5eed50b7ad7fb9d8e076fa84d0eb676ec31a0e54916746e7f74ba17e0cc35082fd7391d6a524a3b165e99d442d80cc56aa524f00b03b6ea9e6b4f714d67a7d61e916aa2d533844a5f89f54b3051d9d632896ec8b1408abcd3b224b71433d222881e744f7bf4c224170d92c5a39d5caaa89d4b52582bd7be2d3903a4722ab87c9bc674ac4b654bd00ad2b1132600feee30b59a316a82f6bc885d56c87625738bc61e2f3611e7916504dcc1115f7e03d0d16c0d622b0f69af1ac8368abd4589a396fcdaf114b29116b8008bfba2742e25c7d6e8fae99569e2a2598b78f2e5370a4412230a463d13c2e18b09c48500decae6416852a48908eb92299e5fb8bba64612b0b309cab7d72e9417493d2c41e11b6729ca30f6dc420517c5d7338d19646f8da8d0299c85c655491cfc571880399f38c32d199556b6833f5d8cfa71121b5ffa882ac4c1cd7d029610e99cc5e3a1d78e710cba9fa0d4c20e196de29e3c2fdb227cd99ba7336cd03505aff3205ad951014d55ca63f8e9327825ce9ece8bda7d417aae75b15e117fccd736b1549686ab20da5b5fcd889d07e08f6053d42e146b2d2918a9c06ecc863a3d275c5e1963800557ed6afe5b8af6911c884eb0cec3a8cb0a3c8e490d8bf0eccd900b9af05394ba274d1e481006b553b9df506b076665278e30fabe07bd1ae3d073dc440fc831c9be47dd2fceaaf8941f6c3929ab4144f2f697376e82ac7ec1ff44bdf0ea1f800788367998c6e37dbc702a1a950452fddc629592882fed32c924c3cc85ea7f79e87eafea4c12e343864efa7ad2f663e0b7cccee003f48016cf44e6061cba70228c50d0704e8285f127ca4fce69187079eb0c8a0549477955cc5ef6b105cd8b496b81082f9c3705d13883ae588927f6588071754652d4b9c3790f443044b2ef59b2d22a95d414041ff3668541910a5c9cddf22bf5a1ade60212e77ea7a9d4d0425843ac1950dbc82d525259c7830e37bf66113293401de57900f7226fdb02d2481440117f1f729a1cede9f3199c759ab018f4d0062379e43368ff5d325cab325ab0ddc3a742f761e5c5295811b5bccf307bc107e6705a539765941a35d44756d32a24bd398bbb8e134dba56c4acfec8f141e120c5536c85f0ecc771c4087d3430878c0cd38125f0da26bb40debe85944b79b498362a7e5f26b7aa01cb9ebe0f41c9ad0d65fac36aa897a7106921a615c39a881e500b24314223ff4be296fedd834de5af12e5d91469ca1db2752e43db0137aa15223513376f2b48de1bb76b647d536c2688b0550dc526267b02886ed2d5629bb3be3e8eb58358611bb2549f17d2b044842805814f86798b7d11186d2c411e9bfe29c78fa9e3522145a655e64ea0fb0e2bf17030e4ebdd17007ed71b359f593f3153194be1c19991ef2777106dc1ef04d070edde5eedb2bc3b9e42996bfcabcd45eed051d71e900c37d7990d0f2a3d384bfe944709fb7ba108aa0af9161507c3434786adc576f19314c48148c93e99a0297e1f41507741f5662c99f4b7fc46332682b0861a72030362b6ef32427657123e57e469156c7c0cad27919c3ac6729820e7600ad5c3c10c632186ba03f0e1850cd332bcf08649c03e95338c414202aa4f287c8573b031c1b54b930d4b64a8990490d64242f608c37fe20b2cdffdeb9cf47bc20c7859c36fb240fb5f21932168aa1934ac1f24eaf01d734c1eaa7c8c72059f9ecfffc6691e77c9a0cebac2c94e391fda4d85711a77cec9e1229988abe18703dbbacc44146f0d3839bc6e8ebc8919aabff5717722136223fd028ac648bd133576eab0450970e33b6b6a31fd5928ea3eb70578e89aef30f049a019a4647fb181fff4d5688174cf6195999cac2dc7f2f78bd06f5993c6b5eff3f1906f507c5156efc04cfc4a4dcebf833be3928c112a422fb3b223b501d884011d8c69b3c7992cbef72863a9d40c14d427ba45e7ac96ba52a827984e2a05a835ac4cfa7988eb3c1d309202a954c65c9802920a973c0e1dd835e0db5943d73589e9d58ce7f48a2c7f1ba93982a18238c431c7fb27de455ea1420b5b7dd6176035b3da2129e386a8c9027f056e4084857e54d101a4822d9a8e217571ebd582f80172479a4965e1bccb4886a3bc241716e739c765c7c63c41bdd0c3c19bb18a8970cd00f7ebb5c75fc706381127af16a90ea4bb6c12dca6047ce9d7263b823ede05d4ac3571f56048dfb7755f0f239a6f0fa27d096938939af9dbbd50667b63905ab3f50e58676939d8612167702755418ffd032659fdda2a7cff5457bc7f08b865292ad99b547df87a531a5b810b33e96649ec70075bf5e821162acefa0b6687af9638fffe95571f17a4e8c8231efba12e1fcd4f5eef4ffd1fe7f88ad0b415c01e034fc31d779f530bc2170ca7c7ee8635b1f0b46fb7fdb89f74565ea836a80b67e36e3fc5be11f98ace27fa9ed9210b97a237c34c9487d2014b5d7a0f68f59a7fc2b238189b51979f2cb55cefd531fafb00fdcccf1fc10b1f88203531e4ce60f05cc42f761ca528b2e84df77277c84cc2096fc092966f27eeefa460819b9ea96b2a6a223a3be66abb7ef0cbf6ff5002c23db234f07995042c45af488f67be1d3c7cac0675038dc0dfb1a963860cb0241c6cfbd03fa54cb6d53640c51b85e773f7ca070c47d2f9bd1cf668890a0cd70a2b65e84f39670a55932bb0eb45613f34705f2703c187821e35640b5f62b7db5b97a84fec6ef78ab3ecac49f0699353d72e0df5c8cc4f84e187b50b2faffb10d809b6fb4d8a11d0e091539ba0653967fbfde3dfbe4331abf65fc03a1bf7367f2b1268a38e767259eeb9aaacfbf0ffa28f0b097c46e7ee327507ed39d705f810e7b40d52dc81c1bd18ec00e41d4124b8b91364bcbd4ef866e2be346535fc3438184a1047c687ba909a1674e18aeca3e00b3044c9263d405f4a6264423d9f6d651f63c3665f188081119f20fb0d49b4ca61914f993f88f80c512c8205d8fb1da765878f5c50e10fb620fc0bb70d7adc16eb75be984ac86cae515012122cc4fa673eefb966d4f0d9d9e1885db41e4f9f472b151124cd7049f846ad79b7b04fe3994386a4c42333230166b104641ec1dd31561fd44bdfbc6e5f91d24e9f707dbf43e81dd1e68f853a1e8163b29693ec27f784c8d06076e20227de0e1f3a7e8aa9d3a8bfc8e21ae58db4024ca25bd29d7cc03c01f31eb91360495d7affdab9887be92083ae106b784bb3e246d766761d4374e9d503e421f3e291cf02df2306cc983b18c1e9a5728c4a2f9e29c0856430bb65506c8da9c269b2349639cd610c855ba134a28e72337a2c0e0154a5490f0ac95c4f58d8284ac9ecd4951ed0f65d8577e7cc552a2052a0254849e8dcda3c41a11ea79f120c881835365595ca88c2a3642d57a1cc85c96453fa3d63d4ccd758a0cbde8fe6cf9928bb8d8a70354ef79109eeda0f5b3cb533b9c536431e4ee17eb6a2e1cea8e81ff657c348072b20c08f2f52019ff5177ec731116483517cb3b981f864be4c51ed46911f7957255c79273e82bdb478f397bb2d8da83ea80f92de6fd9fa57930aab38d0d85970be61c3815d180ea848950f4f33e25bdea41b7f7cc0f538ce3e3c1e3dc4d3801e9be5757f65f9c0497f6aab1e48357144df562f5c06b917810468e4ec683c131ab580e632ae91dabaeafcc43a50d9285d7c64a836d5a9f7c810469c3420e8fab198d5cd087e46567707b680a831508cb770e8e52e9ccfa169d9c6130195fc79d043b2ef3dc529f2ccfcd85f832b731a9529ddb23b4d1b4e0e94c2a3c16c2d32ef84aa50c3c205763459329da1654aebd056f3d35cf05b3a613ba4917248dc3eef006b46ab0534e755141c94d7e06ec2f14bef6983c92d603102a2163ff2cc7c41e5b5b11022a25822252960ad0575506fc610973c9d7a208227623656e7f49deb1907c6554f1baa6f708f20a5b81ce63e153b2cb5d27f251487ab9035172873400f5049c45bf8bd3d34fdae0c05d97949b42f12da45075ee4235c250b57c899f89eb4b66732c4a43fc53248c76a66e7e97d98df2bb1637eb538cd9ef703905df68c17502b4996cb13617c951909e5384c809bde614e3dc64119b757713ebad12145b76086b0f6f429bd7c25820ba039296efd1c250af438fd070bdb651ab98d2395d8046f38f730883329e0601ca29488bf0ade06ac12b7499a5e4c2f7390eea96118fd48c957896ab028305c133a341f0c64c80341ecf993866100ff99973afcb6c45d920b855a1e08180afa3d5351134c3b53c392b03e2610e9689e6e062853e9cd075a5af720da6d117b1faa45b1235903b18c920584ba0ea383d998649d84cb337e42c4607300039c35e4631eaf7644204fef45835011666ec23fe9e27334533de5ce3880b2ea4f5a8f3c744fb55c55736b977d7e44b228c35bd20b044e5622f970379745a638d137e05683204cadde125210631fe27fcd0f2dff90ccf1624391b82fca09b958b8778cda06ba5be3c0fe5d248d5af81bc086cc62adcda1ffe0c16327b0268762a2d0daf7696c5d7e70d50c864a7d22196fbcdaf7b3c0a0dc98821dfc5d28efbc36309eeefac5368a9842eb6c2f9e20e335958e8058183751883eea2239f24691feea5ffc8cfc2082467e19e0a1383e035c987528fef33379d3704a8f205313018fadc15d56b968ced9a97cd0f3ac54cb13c2e99b4c50dbcccb9eb0c55b66e58848d9dda6833260149dc70491adbb3c52f22f57f0b3346b458748e1ac499c4c63609734777faba91f64ce42a7e2e489dfa96de62e1103cc0302b8d716025ebd8fd210ea4a65a6c49742c8a6f72100b140070e020d5cd135be37aba45f3b2a467fb4325ad0beb330cdd93b63b5c52a06bb309172e805184a3d09d9d3e5e0aae388b33c7247d59299867d8765eef49cf0c820b6bd85faf4ae1a0b6ddfbe6280e59977591a6dea95d817e596d8725c2486454b5c7b14639828fa822a0c3af70176697bd9554a092b90c703d9a5e8419cf4bd72c225833094d0c9645c0087ee23497c1ff9451f81ff03aa42e8c236c3080dcd07de4e2d6f78fdc38ad53385dd8406522d4a9f0bc619520b7f07d0687414a4cb907176a0d17380812f9b9434d929574a8a9f16e867d676171b58e5d4546b0c34b89fba6895040f69c08149ac27798a82c54a1e21ab6ba88caee4348ac58226d6e56e00def5eb2ea204a8dc92daf84692cf18451a86a8d8e0e3060af2565d001f95aedcbfb3fd65301bfaf886b2180459349d9ccc180f7721decefab7570cdd37859fe516222959218152bd28fc78091809778f575224dbf4616ac57d998e8b59f78ebcffa742cf8d0acd44983d39a49ab806343940402b9f2c96d7fc39f5220ada5a81b7b050b98164321a8d6c86e8aec6e646417d12bf8686a3fb12b0d2b2981440520f146bcceabfc79f398b4f886ff89551c436b757693c5d762d6c39b3b218cf429354a44f3e73333e7e48046892af5f30cdcd73de794fd205353754f975e375cf8145f466cd988805ab418ebf45d69320a0db2d032214f4fc779e7a910f50fc8a69a1426f8e5c2d86c13f02c4a83def4169e10d39f8b7964ad1a716b73a17ea813d8907edeff230a4a646a224386e7a0e94e87b018397ebccc05e6c56d7a96b095f697f3fa22838f3f973753f95558af2330846e4b77736eaff8a15b3a290cc1bb24fa178af25d45902209828f6b5219cb058d0d43f7c5a6da9698aed6aeb766e9ada4688aff541a821e0bd932449b33e568b64a39b627e5b0182a22db45c3c24c6a9b7eb316fddf9076eae897dc8a851caab946cae7c87140fcb900af8945498a7732a319810a08ee3987885b4f6eb9c875155bf6de4a3d9ee6b2481e7606a9007e78d6b131b6fb9ca2769eb261809317e41c711c678c300166627899d8cfe9fd824b5445bd06244c6b06a3fc2cdf4a905353c8f0ecce7a1e796fa4f7d983842e8bf634f823401ba062bf9174fbfe619032c34e83d6311ee4e56931c0b7a4ce2376fa4318b8c70882f50603efd45528fefa8372fc45c366c77ccf163e7fa914aabd7431f1055ec5b29fea678d7055761d9bfa4f9cbd742313791ba930c0411a4302145a24aec3f78e56614332808ca57b30f25fa136091a5c325442e125194984a10365b280919ecf3659e9a474f1d0be8f877290ff2e1805f3e1c31b80a680ebd9f11cb5279bdff56398d9823fdd20f71954807eff1c070933677ddc26a4d0c8a964c0a901dd694a1edd18e0591892254b71230f0640ab49982489bb4657199fa0d3e17c3d75581202a5cac1b83a850c7624399949633c37b774f4a583ed6148cf1a5708ce9572af2c1138ba7620bcd959151afd18d44182cb7cc1664ec269e371f84aed05458f5165283ad4d61a813e90b03e6c48b69f5f37bffd220fbe89494836435d59a87cf529d1ff7afd620dbdc66a5062ad999f40e8b39c3b42b3763e62daa705f54958f81ede5366bf1c9e43b24ff46eb5a1f1a1fdc9b3fe668d23a0c48251b4056caf68928a3ae464be427b1bdd5295b84a6e2265e9fcd86b9c11f5a976cd37640c188fe820878c4966cf1efe90b1c696cb018e89a6e01e19adced29b6cfe9bc61a04c3f06f861c32da2026d37c6dcc8b8338237a9b291c3eb0bf2c386c37ec3bc5a97e025b000ba5a6c84f92d89e72db057ae15a08655fd1a22a5ba20004c36850562cb226f60b5df9cb7e8500d28adabfe2fe633c682bc6ab491a8985043a8a64fecfeca17a1a9476d75a24e9270e552ca21089f1f0f173b12aa55cc430e5effc513810120f1e319c58adb34018561026280d4124ed8a5574e16a1e7bfd19d61699c6bd9f72f5ca3017a36b5c2db12a2723a3b3deb20ee7c88aef253c71624cf5d6d9fccb78332894b7f521c0be894bf73aff015b7927d45134cbc11eea1b9d431dbab54a0ad00a11b79d151eb4e0e8bc188c3de0aba68830f9391e44a107669f709efdcec621644e0871f3368757718eaa0a810b223db8ac8a9ea038e247db163422d3e38a8e6aeac17582b7c586fc0c03896f3ce0fd672677fea233258ac5e9b00f41e96f094691ea6f5fe3eb806947057b302e3255418cc859c545bc94aaf5d10f9a4450c56119b0f772c20bfe08092699381a09a9d0c4f0a8287b6666e759397948608ec6c5883c32cc20cd84ef0e398d574a10c8ba998c0ca8447a279a8d6765d2866f2046d27d7dd7c2e53509d02f3b412cc4adb46709bb989bc21d8edc8bba356d812c041fa7112ece9cad9b0fae2afadc00189aa75c3fc499809d282374c49524742fbb4a087c8df618e90f9e3059d1b9600282db312bdb1de3dfc849dca316e5fae43655c410901150708cb8803331bb3a790ee7a51bb0146ff68b727a746cc4419b031bfdc1038781601e3e1e36e0a825042eb5d1b379a33a2b2ec807ffbf77e0cea2d9cd429dc1e866a917b14eed2515ce206c11de94ffc86ada0959b37c1e579fb220feb67412a94e5ae7d527fa3a087bfea2ab5766d48d59a53af910b9fae5de5e813a7b045e9b5d851d9c8db0f6cde382fe613b1a55ef5b10a8fd16eaa3666627181cb0cb6274b1b853a0afefc133d0004371fac6b759fe8b3890e221e34b1c206642d45fecb43b8dc762c79efae9cf634107d4ea29b5b136263ffc8dd388f3c3f1292941b259d261f1d263c08325a4bba2868f601da08d7f37039dc255125495495095baf51fc2eab2b57c925e12a63887b58880b38f1f3e78f4fa6164bc1d1f335f66d83f60550b4b8a685537a0970951b9d3ecfec9ff420609337880a690a22059f6a0caf33c1a4c49b1c63b6b5528334fa3d28368cf24b8d198b834a325e3502e05743d4bd2479959b6320e23a48c4b948415b5ce24ea6cd8331fc909f7653e5cebe29a0269fc9fc637cdfc500e652113136b6d0bf0a420b72dc15e0f12ca6656cd2d4e3ad928d0bf3060b7035430061b5e934ee6be61fe99bafafe916f9819a8da96b5febe4c3d3c2908c1e4dca36a199d3402957f4e96bc2ec141601d23d8e055a6d4b66f459674641ba5b82f97055accce55241b548b0f44d8d0ef60683052e0fab80121fbfc45c50e5e98c4b33309cc58809845ec035fc98f01ee5529b2a94490ec123643299f3865ec9abcf925b7219bbcb02efdb4a1630562a3cb95ab41863d725f60404570a503b92591587ca368f5e49617772dfacecc6fb741ffbf6c2ee83705603efdf410c0daaef71788c5a844f7d59ea27471792ec9d31729a4cc7bee4b5bc9602056dabbfbd5ba0a248d45c0018482710950c0e52c01d0c629b21d63132ec880a2313ef10319fa4887e70fefa091e0263751d277d39fe8e3efc13c896267b2209a562047aa528ca888eb23c0f9e529f1e010362b4297e4de4ee2dee674d90ad0adc98ca2763c017b46367250309b288a7740532dbc7c91eb234d51e9fa65957b64a04268c6dbd2214dc0eb67c9452df441ff29eeb2d343e1a00af9687539af41b50bbc4cd4080d8ba67e51a357a202741cd01bff5c8291106c9152ef8b97800f1d5348cdd46e3af051cffb083edde8d064d7d0837b4d1d3bedff97e09100ccad2511e3cd8946c5322276f92f1e9102130dace180a63355d3aac054c298129481a31775283bb57f58cc1c6aaa58175551c614f08bc82a2e5e8a2e17ec4737a845834d550b350a61740de90229578c6665b428f5c540a230d1260451e8b393ed0b810f7ce753494cb4108af9422ce544edd1178e8b15f7364dfc78170f44bf80b2d8b0aac0a806d95591e9877ae029d5bd35d084cfaa07d8443403f4eaaba7ddfb4d7ef3ff3050302f5ef53b5eb5f84cf3c62f1a57b6755b1c285023dad3ae857736c528c6fc7b586a50625ec7d5549d63142e7b3d09e2463fa2cafad6dc2899ab484059f550bda7fb3cb85f45ee38f43c65559f7c6cbf57a5734bd28d0e86ddfcc8ef27e4b88a51f92f50d9152af5d2289b1c4a0862bef6962afb4029fee86d2b26b7869be5dce3e6644eb39d5ee9190aab31b0460862f39ca0925fd5f07d7f13518605bc1f43cc997f57071739ea088f4be9c2609cf5eeb187900de2165a43e73d48145440cf4f0ae02aab036b0112cabce92c8dddc8185ae14dbe068f647c7cb7ebd185d64d2e9cefa9c822545d4ebb8d5dac65217c20085921416f86dff6e47a2a5a2fbefb7aa54ef5c2f6e180859d2dbc2f034a45fad018c915f825762ae0b3a0792ec3fe6a79a91c6118679e78adbc0a021b02f4c88f35bd758aae10613fa60a164ea764325598003aac259d032ccb7e9917019435e6412ad6b3484177355e4ad21797bea9dccb4f929fa83e0bb43cdf16559fd22314668a91081edff4e08f70830e78b9609f6ff3aca7f93f9101073ca44e5eb7094b8227ef668e285aa3c021a302e8aac17c0b138ba94c2735921c60d240c40d549dd23ce22105a052bd8725f746f0827a5891dce4488d734d0307746080b5b7407045979675d84744c0e98ea6c3120f0e377d891262326c86b82fa6ed8868a9f4b7e5e9973cd9974a3c3ec5b913d9c8602ce753a9f53eda18abde01ad4080e1fdece07e51fa701fcb0da167e655cc38a11f14ffe1ccfafa945f27c27dda804218112824618ad7c034940b1a0edc868b21b1129b17486f8092b83cc0f51e3c86ca3edef5591801a4f49dd33b8eb4db2604f5c5a86da1a91c0051cd2920b8c4cfe85f3bf1a1d6e6bd3161afd79ec3e56541cbd51cfaff87244c4abe21d101c089428c12a9ef30d9e9a91bf864436fe09d19d5e381a24e66647fa95fb99f7732543f24fc4120dfc4af2d820d1554f6d07432a380d13ae126475fc3bd276734e38fa68e007c2aa8bd161060f8bb134bc583491d17e551729bbe1a7c60c2ea0cfa6b46f932b08bf61cd0cdcd081d6006aff19185d5683f89e49ea710aaf8698e05069771f9b89016ba1cf132b803f01540b5b48a241e4e4a7135832112e65626312c5541b21a49d7da085d39c947ac21db73059958ccda07db169f9b91d2fd99e1d67051477d62d48e4ec5f2e69acfe0cd41ef8c8e87b4af113709a8bb133024a83e7458ebcd3a16c66c0f89b650373ace31cdf235f720c11f497813455f504e6525ddef7c8d60d592d44cf34e3fcf3bd21d1dde6e92074d9c7f79114a389dff4d1736018b75d81043d4c2ee3015f8a8cc84544933651d47859290381d50c4d48d7eeaa98287ec3d5815f7ab44129eb05d0fc3257af5e6f9d6516d33dc822ac744049f1a797d617f8e0d0f81311571b5b01006b98b4191a26b67e78918e8baa51f35da59464ab632a711944c08eac4d06f8fa836a3df9b20919d38858ce852093abd4e34014357a59ee5b2379d3c12c8ad919530d44c1358c6ad12a8cb2bf981e0651f7829f8d1d9e3361f3c706cc0479aee4c2b8be8f3f0622112bfb6a503db6b15a2ab54ac9b65362753ac0d14b3c2eddfd2b9243bf8e720a1312d7573c1fc1026af8d039bb6cb7e690858dbcd837ea22ddeffebccf4bf521273ed04fe8d18ebb57c460e22a9313d8e27db56e1b8fc256551bae3ea491f8c8a1099031ec664380a36de907d6f3878155b781fe3286c69b09f9dd974d9cce0777e213e0f8c5c652500d6cbf3a8a841c2902926b4961810d831c3f2415089d1a568b41c6e2d685273bf6496afd719dd88290e8067c73344e2083e0021173397845351470cbf905bc06e77ca8e25e67c1673ee57183f89f933b2f3732891eda09b6742a88e298f98cffc51c539bec280e0ec667c734ff1f3810c0253422eaca930c269c2b7a272753db46060ed62b6e410dcece536debc5d7596dc92f8ef5dc4d66cc24cedfb23263a2f8a7e47937fbc8cf491e7d3a0913a197efe3a9b924c836e2a8168e498ced485c01528a88e50e91c3de012910c4f6d3f49c882c499579a687f5c2e627e66622f061f449e0021c1577248405862b4fdfd41b12238f01c59b9a4f0755b47f77cc6dd1d0f6b3d24b80a4be66bbfb8c068c9578437842ebffbac6876d208341035592b9cd73c10e6687be3c63129e7c488348e99caf7146041de525c01b38fdc938feb2b8027cf8d6d57b5208c23a171cb654c9849ebacf28e1d09cfb15b141131c42617c7e8dc9055e139db70b10af0acdf81909665e31ed4eca2a28675bbee7b399a0cbbffa4f68ad84fa941a0279ecf8c4e08aeb9de3d77e793502be6361ed43f444ab473ca9faaa8007f4c983f60d2c62966998eda219f11ca66d5f8fbf3026841225fe18d206963ae7a36541dae061aa8a2809c6311a718e9159c41b63a0a1d46e109cee2af431ac5fdffcb051f6a24169826f1803d41d115901e71d37d758eaf35b12e854c3cc46e47852ef3d06a8b7c00282f285410461e12df7f91940def035b08f9ad48e4b5979b68f1e16a2f4a7a3df18001e913dc27d51487a252290b793ecbd15c32b929c520e2d1c81ac69b4ac9cdda663e4584089c209c8007ae585b026c956e458722e3355fdc89337185e631ca86520992124a5022c37a1a41de0f554e93bf7a505e062086dd046e215d91dba890698b4fac8d2075f86c0ca7b8112ce47931d64fc0fe4e2ee55b308f1ac13d20618a0f478ecc429735662633a68836f7cf08f65545dedfce482ba0f1c5027d64f48793b1ea4486298985d4bd17854fb847d127d65932cc62427f2e387f173d564214361f1185eb544d11047e1764fdba3b6b5cf5b6e87c2cc32554c1e7d1be373fab52343039b20797162dc995af63b80d470ce73919e6be026d9fc889331e31906d42f77f02be8765be38649be80b33bef231ea06d72d1f23c95d53d76b39829270d42aa00d46ebe98f82eea33c8f49c1a3ed05a9985de5382c53fb7947e92943bc13bbc403e14d3ca43100e4ff9c536e3f36abfc61e190c4dcbf8cb32d0083271991bffabccdb9fe24e74dbded6234791cd3f3323c46bbbe257cbe5da10213429c1f8bec66865691802da12d9af95cdb152874259f18a4c3d4f739867c1aafb62bb0fd673d1c938227cb0b52516c4fdeae38ab3438148a9b9934b87e96a1ba11b62b4866eb6f739020054eff8101622d465e0f4436b2f250b62b8e127c7c24dd9d87678608fdd0be81b0786d45d1f1ebf8cf7645bb83a7517259f91a69ddcd5f203fe22df965c74eeedb15f933beb7f65a619990fe251029afb87baed897bd60a6b16ca34e2124f7d886f29cbe1285af306fd2d8e767b030d6c18598f6f36901f41bfac0cf03ae88e795ee6a07e79bba83b2152afb3a25ca100208b21599fb3b525e0e5cdd56d4d4f000b5db31867ba146ea4786b315c186ca4d4bc96370d349fd22626bc56135e44a18b7145909d10abf7eea60eb783f9e0be62c00c4a1ff837948b770aca9f86b34a81bd14d4cfce2ec1d30b9ccb5a802949bea286a64db841bc2cc72f767b5f599be8aaca6bb1bdc29ca9aee6c01d089e94d57f41478002425e69b7ad1b8109ea264c9030b6a8287d79053dae4c54d96bcc992885ce5b90a8ddc6e03c7320093a870265cda8e7f865271017d46fae99cfc4edec08b227d9f4003c6e34dc563117924be5cd028010d25d8d9c0738bf46507d4c5f1a9da5195c82c84f3194f7febd208582116f074ee750f055dd4b63984b3a5fd78528dea9cc807c325a919f1917b99fc253ed685f8a82e843fe09a752f0f110dfa8182eb6d1f632a8531cf0bbc7a89b8a7c588616797f4f72ea69c2f8f24a4970bb6480d53ca9810d31d03af674cadf06b92acf4f7df2f074f517385986160880c6495e18d82c26c783fc3e2c5b9e7c9d2e6b05f2a088283da2c4382598e5de91a5a9c494fe8775efbeec6d7e1610ef075f289199e55b7829a1aa75e813102db9eb3b9296922edab896270f929f84d0126ae3a515ff8599bf721d5bd3b0e9b47dc604bb582795b6d9c1e39fd8afcdec55c6e6d6be6190a84ad1f0e8741cdca4e0317dfe40d41a0567298ce26b7847698b8a4abcfe8b1b1e33f8a5998b8f536b5a4220a480442755219907a6de8fdeb474905aa760ed5237bef5f1cbd40ff9686c96f271a0955707e331193bd1def9b73a2d40d55e66f41fb25c7933d1b51b438457b841e89744404d93735d5407f66778f684315b9098e77bdaa8ad0cc7e80177a3bccc57d2f75cc170851589675fbe59b746f5d507d77be5c7fbcba74e180095d781e12d5bf011e67a3c1d22092dd9cb676ec17d6f394fbee9e6ccf813fb187c745d11d20cdda701b0916fc2ea5e3917eadada92bd244d89a154e22c0ba9e9d9df2443b4eccdf0b1e4c99e2494065c544fd3d8532fd916ce343368892889076dd9aa77de7f6dcf584278859a68dc3dbfe30c1c6ba6e8039b9ffc78c13e1d8d094073f1f7e7bf5ab83cd6755d7aa2a62e106ad2a8a5df10f3cabf9348105ec8e5b86499653aa53c2b721893a53aeccd0bab342444b51b04196c9d7a6ca39fd813fd5030b59b4740155b914f4ce540da0dace89f0463175037815641d659ff50a605e4240ce223ebd6a98b5c1af2bc4c98a00c09cafe1f95cd9050c25a14251c2f710a0407dcc7924170a886317aa2abde7a6a200a5a9ddf4503de031e4e61d0447bb1b303054f8590a1cc2d34e481630c14bed2547cca982b474a20285162208783c8eb3d7262cda0a74e6fc89e0940090bb2ce78c30c0238b4fa1de9665a8b6e8e9e997a08a85ce04f220d832d3eb7604baf72c53db4084ab66f4894e8ea0062dc9b49f298d9a2b43179542c6fe6fd7a7ea033e2a6a694f397f40b40e41127a0950e7b5bc8bc00f3bafb2cb6fab4f85843123597f1998c8f4528731bc2f2712423c999fd2cc2441b28b7d817a4544deb46f44fa756d3ad1e76423e8f2f14c80525bae079f9dd281dec691168cb0f25ae44c5e8c124b3794ba8a6c0d26f6d03eb2eb18961a4309f77ce5afe2853e5ac1ce7b39bc7f3aa291ce4228a48f1ea4f172d91d313a23c5e5e80355e2686d0ae2e99f513fd3d6991fa9509e72f7f6fcb8cd112615b2e8941dd41bcc2a4e7f0596f3d053dad3161bfa5606d2cbe33ed6407b00e1a938649b51df9a3336368fbe0cedfb20eb8264cc8965d786ea8075a529027853c5f1ae449a14884c452ba8636d4c5ec46f9eea26c024b7a53da80644d7fe916230764f8fc106c5d23b65c5c9e5152ad565e8318312523763187e10e99f67ba449690e244fdee7eb3864738c401f8919c4ff33b1681f3c1696f88dda956e3a722a4fa3f93f98850982a4d43c1d7e7dbac17bac50f476246177189b1a18b0415e8fa0ab098cdefb24e45218a7dea974efd9274aa40a453ab8bd4922e2169409bbd9ee80662113e510792c9c56ddf6562fc53472c8d19987d4404ebbab453f4706b0611c72dbc71df6113ce60bce256de3e238906d8352a415c0860ec1c7f3f30bfed681100005bfd6d22e69edfccb6d389cda9b6d76a2c7e031362f7103d62f20972ce3b0f90f412ad56cfd1ef17215c1672c667d8b31a57b230a6a0c9d8aa3ffafe2da161e406086216bac0b3d4c2902d2ffea19f02874026a843671be19c368d3fe88120fddf45bab5db5f647a73566e33bb1db587c51f3e1657dc53c90e784f198903751d3d710274cbd6cc6f3ad82b3efe3cbcf4ef8d593e003aae550160bb7da48c473be1e9e773ae00a1ba43709f938d2f7fca59c0a5f982b6aa7d3cf6c3d096d103aa7b0adf4e61364b5c6e79feb352b91430c17ca7dc7a68f24588e5550e0ea7c985f7b5b047a439c9e964a6795eb289de94df3adceb5034c703643ddc4d5634d370b31c2a0683d7d580a57ba360521f1e412ae983bedeaf5353244e53c28fd1ef80ed2e6486c28dc55c175fc1195c237119a0ab55e77663b0f2b62465ab7c3572804481021ad8832f6462cc4ef0c5670e0c27f8e2692462a4c47c84af8ba151b4491910dee5d849a45f1517d6a79ca033d5587674c58c279c019ff27c5430ae5812d8a8dc28fbe7fdb0ee04f02dba36b866686c00863e890d5771bad599b6021b3ce29a5ef3906dd33751c60b734bba4dc84b5e398421550cea9157f9bb6d07d424739915cb16fadcb21383f1e26405fbfedacd0d89612d55ef4410f7f114bee52c47c6835d03445809c423ee7c95880f825b62d0b28f5496e23662cdd1249b417e1167d950fd9753de55dbd88aea9f0e16365bd158a639a495879050784744d0a872585f9ae3aa0527e4d82312e52b16aa4ead2b2a1453ec293eb994f3db065d8832f03b23bf7627123fe75b8fd39ace8717578df0bf6b548e865dc3c3a612068edf99e018f27c4af7f7fa49cd386e4a7074bad366308ceb1b8828b58512117d38041c5ab07fc55ac850561f3df3a35674b4bfd2bd7cef7c38f464cbe7c8bdf08f46f70fa30b8de300851d3cdd879d55777236ff45ad14a238e593e21449c657b84894a189c8c545512dc25588ac22c140691448e0d4510c33aeb21257ccf7f87af014455c6d98a69011f7dc8a3e8ce5422f43c25443da9a9ac05d1cd1c39fae962fae8666fe46c42a50143ff9a62b6648c366b4e4acfb9d7188ce4ee79a2b1565c125caefea90840bd1c806c25e119b9e45eccaf3a75a53255caa041a885545bd526f8b41196f9f93a202479bb472e2fc63887eb6ea5aa0202d2ead39b80a17d91811a46fe4c3c6765584523b136b0192ef117e13815e6192cde14f731855ef489d2f16ef506b8d4ea84f672e723c9d0d6b7704cb04efb105b1b8a40c512c918824b51158e65edbd9df8683d5a5272c18f72440dba9b1744feea4da1537c15cebac788f3804a0f5ae66cabb07eac547ee89196fa57d63ac6e09e639a98e2c21af933dfa220134c0eee4fa2c4f6937f03084ead7fba0dfe9312928a9d58c694d4e8fd8173f913fee42b694e7f6a77efbf0341db548a50eb0cfa0c05b9328e40af6a67f7c0cc573a6590f4d175d3c0c134301e2267b73e4e982afaf1d9b219e17e21fa337ee1f4c2763558abe62ff1a0c5a5b19af99327f46c55875e4423a98d7a366edcb4b5bb66a1cfa4d7ee22846e206a0da1e5ac163f1dcedb790b118950e1e8d6609b0a63755b2cb2c97cfb2a09205c40b6613735e9c8923ac3d2cc49d91a68ad629ebcc38dde867cc1f6bbf212c8e6110d1006701e5884e19310556fc4772a53082772e969d600900b1e7bf011ed84d173b97b2f3eaa4a254c327f6457dd0c34da5e07d3cdcee32e6c149e1e44c25e41a7b3c9104c433ce301b1bd45f0d0482c6469859b7a05cc94c641558513a4075e643b2121421e3341e2fa38cf395c7cdcaa60a55eb4952e9eeaa8d9008673566d9b214f2fc0c7feb651ff386b2e224ea742ddbebf28f841eb622fbb2411643f23661752073328191557868313c5f89066b6b85afeab89fddb72b73d11ba0eee6abbbfac350126a5734646a041ac5f0b21a0127653d8c2dcf90b7b88cac99460b62e2963bef8b99b0ae11857367b36da8842bfcdb726c47266a445ec594f131af7d12b6810dce63be40a4c021fbdb0bd061f03f1bdbe07ebda755a7ff42b4e1b5e21bd7ed55922b4534332e127a89de437a7ede43f41efc5da57490d0822b5af3a878653c652cd9082a80074536496ec7ccbdb5a9c0ba32ff224d732d9962ea57894b583b2be45e2f3d2434b6e81e4dbe191eae598cf78bf6c7a0e2ee6bca803400ff138963fcb04120cee1786f518da4df875d85631f9fa50fc60cb0bbdd4c37406f6fb22e3ac7a07b360e1e67fb84de053ed60d2b7f6d468fcf08f1ffcd1800f393d0d08b358b2af60e92e4d5e171c065ec7efb580ac8fbe4a2b0045fc61f91b94f5117c9feafd4b19e69c6c8570a15c09ecc18da8f19ffb157230c15591d1444d6bb31649b6beaa2f380da91d9b832e7e1512366bd97899f4da85743db08e77299103dca563b104e2f324809ef453569002216cfb0f44c98fdd4d79e9b914f70221ba176be5e76df57eb38371d546c6164e6876a5603980ebc5f78f4d6012631b3c76e497680a8249079c268d021bc73d08dac1822037cc01437e81a97be55eddc6991e2c8821d0546fb3a73b6a208c4374e77acaf78876856191ddbe8ddf8ae5f7197bdfb86e5389b0cd1d7015ddbe88e28ee5ac7c0970cd5f78ce990d3b798a808cef24b1334da560566a30b48258a7bfc26e3d95b62aabb704b977c9f2060cf28f554b11dad66357e221cb45cbcb39c1aa08d30ebeea1bee70930a3cb254ff400a628ef3a9ddebbc04f794fcff79ae6f3d8f9c9f58ef69d9b34a3bfdde32c589880b754ee5e3b116ead2f06d5a90973e97b71ace43eed75e459ffafd3ee6c99bb012ed6bf97b3b754ef0a8a705c098d9c5e8106b4482c51af967ea5cc3c970a09d9f2c0de31866aa110f5833d8f2be91ced75f9e06c97b5c0e275f02831dc342863f265b210aef82b18c015cf4436c0bdfe4f8bf5678256bc5c697c37aa40e49bb70451b16ee76cd3a3db7192d307645c27b941cc58d2f7a9573af3a407c90c157b0c816dc9b55973e99ed8a682c2195ce690449cd6510f9ed9ef6825eb988d31632745deb23c3081b5f4fab13eb626cf20fe3745124a90f31e3d789067a5a1de3fdde7db604480fe5b2d29a5c448c795db94e90d6f355ec13460074b950da109182323156df304da73393e53c3c407c50c0ac3f26950a868a05ad7d9642059b9c34268e131b9f8a8b27cacf0ea2c20014132091ed01cdd5982292bac433df3e36be6d768e2d1fcf1e2765dd39dfc2bc70c1cde859e51c7a76ccaa3291772cb19006c0d62aada908daed9fd3922cb16664c94a2e4e9e07886dc3d94dbee3a38a1e18d0e1e35b4e0ea28be980421bb10227dc3abdcedf2c5be70be12221072bf3bd82352a25c687c62bc46cd40737558308aa825e4c79c5e063813918ad65d81faf3e6564c281e4100d68db6a3bc239ad283a9f64761b145e9d0c186e5d0a03d005da376345fa990ed1b801752f214fc8d122c2d318363ef78f60b316b4e52c470c6e16302ff06c88417f63eb5da0924c97010824a07e9c18f11e6aedc58d00c4e4a49e68d648b63506e80a6a7665e3f1d15655d551eab56c617aadb0b720506b0199cfee5c8b0091110c47e6c359d1013433f37572461682b799389c6a2b18ff6999e1553fd22b243813df9e9f99e28932423c3b4830cf515bf5a50102512f5126c2451543b0b45e2d4da4ef99b946ff88a90e29a8ace31b8bbb0ce8cb52cf5457c05ea5820374c30a24aaaa412125bca19e4b8c64ecaaf673d4b25a8f36be50b98d0f0817df3d19d7e09b7c8e9915514ec1a14a8f1e9ab1fc913e744c1953a48ecf10250cac596a98fc78e605a119745a3d8105c3c5306f30d91294b09e75e5b71049ecd11d9111aa6a19eab71a4572491609365f8007e21436c28897bfdcbbf83149af722f509c4ac2fcf44899dadd9b9dab588890372c43dd79503dea7bbcad7e197436da8aff0ad43aefae30c487369b343a62b86bf9905d1dfba8701f38f8fed9765b13bfc0aed072a9cf21d28ee174638097964ec7b6ba8d043ffe7afad68ed92b425dd1f27cbb8f9d489f022e92ab00b00a4cc273a71793cf9566ed39d0efc4b5a288926b5ab46994d99ae15d3006c4aa50f3dbb8dc0973a082ac6a78aa34087842310a79ea0cac8b6fb6ab7d0f053d29c8b4e0aa14471b47f30349be2962df98d4ce79681c8fe4ca13ca7ba2c319c4a4a97a2328bbfaf1829d6eb8538fc4d61f1e4db4f69aeef6f9009e58622b4265bb039dc7200a16072e210dfbc70a258b0df4cf8e665888b854d5414cb70cee970ad215ee8e9e236c57105dd775accf98bebe4b276b4c24eb73a2624db3fea03cd3ee02cf2c0c73f535078d8fde6e49df07ae461c038221cac20a55f1ce6223b10c8a1bacd113556281733c68dba26cedec70b43cc13b3a09f3838c0e1add6c400ded3527def968683a8a1199df4990060822f93f61b88b4b906a489f179bea21bee37ffe608a49a67ac242e5274a498e25507ea958f0fcaa410bac67094a4bb935ed6fb7c526512d19a62df1a6116c5d7655a656e33f3c358477eeaf802d35a6df87ac8344c9970478f43aac42a5b2d9a3cf90128b6794628ce747f1433a9ff01a40455d1026bbe0affb39ddc803de030f528be958fe2febb9419f5c98112009ed5905056c129379d4e4c6b302ebb974d3d2baae914dbdf3d981eba6888208033b8abbfff105b5c0ed0cd2a4874a632edd86638da7adb82142b7df0924d4bb97543561f0f9943fa8ed98d86d1386ae6d3fce2111558662761e7e70039656b89200607aa2f4991ffab28d09cdd860b292199305cbfd5839a880e2af17737c82d951e194369e2c8e39190d2c310f9e706fd3bfc9da6dbaf00755d54db1eb1986f0d71f36d55580c9a08fc62f5758bcf24b4c0ccf063652f24117f680a522c709ae685c6add3f6efd55c8400e21e4efc772fc95d78e1ecd7438ede8a7ac94117d29565b1361f3f876276db408566274bb0ec04f385537f35661f4209a7a7fdd8a5d520a3681e5d4e7569252330f43612a0a4de5035d1e0de9bd9eea9474bd905190783ca9088c09fed17c4bf0ea6030fda4f1ee992069bdbe2d0e97003644a55fd2764545a68d52554807e6b778068070c96882f5063c8d04a98a472dd36b70880c317498464326f964f075aa86329a68425ae1a76f84282d49a702fd033f51822535445a0a42922d7aba7560e85608633043df8c57d5644085bca90ade3ea56ed99397c26a590471716c90e3011613296ab8ec298fe0816a4c474feb878c4d0518f48e098b5e581ce238fb339efa11fe279311630fd61fdcb1081563d91dcc3042798d400be8dd59312e37cd301c99a9313212ac61d34cd1ef27f40bfa0625ac1b86b74ae338e191e6ce0b5a8fd1a48015b8785edd5134bbdd706c18d5b55c6578cc69b53034738c68d1b62f48a89aa64004b070160ccc92524b2d12e735f1318d735ca13112400090ae08b21cf10537f067b23e64e2610e7185470b1b739cec55a09b31884140c341f9a233aefcaeb3398d7131d3094a05aa8f3788eff5d9a8ae4c3c7c5478bbd843c3e617f013ddb5980e55493b49715024e08d7b214fd2ba29c3fe8253333bd873a50bc967a5ce11db760bf055040473f02222e385037cf8fb6601a50a78e74738977cbe8855b53984147770d08c1baa43bf93bd0b00391f4b88984baaaed2da79d58e1b6065a9b405ac6724d6bf710f036689c422a00b060b3efc03039b994cf943768c2dc693600433f100d588cd17d4f1a28c6f6d5fe696ca42581c2e6251bee9374f2e8f68b35204bc2d4ea8a93400083f16461e624558ff888bbc7a0b2b3325321aed22b76b6de858f32c5b446dc324a0666a62bfe7a0ccfc0813e6fa6d61fd12301852ef55995291a5cc6c391561119013039674ae6a8a70bded278a73a38f4fc2986a80ee8f7112fc78cc8da7522680f20a9ba03a718e1f1a6e6d6d1f820e7cf88cef9027179f0a66e86834e2634a4920a13c82e5c288e9054c56b9ed8e73ec5d1c5d8a9b1a25ad674b51a89b082435be1781d86f12956f96c6b3d4908e6dbbfacb8c060405c8d9e2b2bb990d0c1c688fcdfaf0f0fea1b17ba45adce31b6916fa01ec135caffeb9b1a2091530b44752e20768bae0ab0812b56095e3c79cb35f30f0896dd3b82efb4e70018aaab0354107c8f78d39092d8d47561022573f56ffa5c3acb25a9a4753d00ec40c55188a2952e83dc35ec5c2d8d5433dd47ff55a1556794b538094661e85f387e257e85dba3a089187955cd44c3d34a797dbe13fa0e62407abb6531b6bf9560d8c971b559adc57f71c1bb96cd1458e6d4b25a67bda2db186b5782c048b3fc678e954eb7068956781811a6d38a91c032626264c67f653404c88cfe7871d527cadc07f3103bc98d3b520d6591eda323df5606e045317ceb79e0d4574596a28ddc94e98429991ad91e8480f63c9afc9e92797733395ed8c656faf3b476296979b0e6ebe3634cad1710fafbeda235d72f1e430cae100d6d25a52db5b74434da42f165a93b2b07a41509f983458d0b8ed1d5164d5b9a3e089ea924c3f9e5f6d21491edc67de2a6b103e960e75d0c88618b62a11035fd7ad0872e5e2c3f571cf19288871a893a9a5f865804e14f4ab55f9b9d1e214fd0a1b770a6fc4a586be12e6b43f53985d91dba6f6022c830e604bc7e5439637946eef3a6c834b9050a60cf49ccf10b7e5b033f46a0fa77d29d5c061edd3ffc296d3c0fcd05c70bc3471e64cebc528dba6ccf047c09035008042ee64b3b2e43dadcce14ed613feecb1f2fdcb763b03b9b2e6f605cb423f95eb23e43efe83ed75fd34bb29b763ace0f49651ce16cd9d4f34784b82c1bddec260b9481eb90fd65c47f2bd46f3a098a2bb1ce118492cd046e389dce64a51d0c8ca08e6db398df1451a4d143ea4af9aa6a512a8dee1a9f4d7fa14384954025ac1f44903ace959a31fd3b1d737e777267da7f7fefdd76535666853c9fdc4a281f2cf167c7a0507b3a472ee65dbd6caeeb99c5919b94385604eb9d8a13467b96d1aebd4002c4ad148f66be46b745332dd337770cc8cc1e44d2cc5c35f947e00435e7bb7b2aceed0e35a88f11c90efc98c4b9c4a8cab4258237f3e3496dcafa8cb121ce9474d793b3d816dd0b60dbd3ecf3aab00aaa950eab3707b9111a228cd660e8d1c9d21b5136397ee5612e216ae303543313aefd7dfea3c5f39b5dc8b0be7fff86630538d3ff07ea0e583630bdcd6af36c811f4232caf77487fe9bb803b6fb72ef25420e5c5d7a7ab0a20483e75410aecb152293d06110ed24ebd09d6eee268a425f4b200064e74e5c43da03d88637b6451e2e27d05e2570e17542592a02f92acddd1aeb465820eb6c6abe6d84d285b8835f9117ec413573c7e5570884de22288c8b0dc6c2675c7c9ca16be5b89269acf935460d248e49a0ee5e87862b8f0ee9e5dae5776a610aa47ab2af412e9a9ba4bb919747b142304a33789c532c532eae2bdd37455b17804b11c65311e3f2123aa30eca8ac0534eeb56b12c70be52b664ba528295f338dbd70e5fc82a5af0891f51700a12fea4224410007416e0378fd51b04c5d50999fe5a66301c1001a785b2fc28dfb049295376c72e91ecc816f8b226b2a22855e894926c3e86a829d98e02c4a8030ac31e8f5c3052aaa20e6ae3c595a87026aaa9c9d8326351ad92f3b16e2bbd8d79a3ad915e22ef69bc2b73e2546ad0208b89540fa0c790dcc4500cf3884140eda65be6cafa109f73957e2e1c2e68ede5fc504b578da462c9debbc9de5bca94640a25098c08c908b4564a6ba5b4567777f7530a6c7d902b816249a5c5d5329200801120045f4628a1005f0446107590a3cbdb108001a0346982b343f602d1904cf682c32c17352c36d5259e8a18c03b004d772a62e9e740c009334e66ea4a0b01614c489bfe304509f873ef1221608226c5203b63985946ca49052bd1861e60c65376a54aa9a0624277774f80ed9c38295261e79fc453115b7f9a4a090869663d19b1f5459b6ac553111a8e23892c1ca0f8a1cf2fe5cb703fb931f4d873dda6091b768665661c50407f7ea135a6a9df69f0cbdf63e09829c5670a2d4a0f949993ebdf4d7698863ebf77ed8e94b8fdb2bbc363779b69783c5e0c3e507a64f58bc92db7775ca66bd2b07e27b2273deba0744f1785d64db9b56b4c76fc656dd0a77f3b80fcd2f494024b1facdd8d4e2b96903d17d0dd7f457e2a951515a932424844827db9378dd332def788ce7cc94fdac9cccc3b6c8b17cd418928d06b0335c23c8de0dde82e00d82fe74ec900d04a27f75edfc907031076dd7147893694522a04a543461e11a817989b007082996aada40042f79f25d1a69222133ba90da502289d6896fe3c0d61fda70c24714b0a2673b5ab6054daf30764af23c76aad2fdc7568d3ba73a340349f2b68340fc3b22e03d164150aab2aa3d2b0c50d96741968881b4dc1104e386d082239b0a9cb4043e4c009615743f02fac4a0f3cc80d981022c80c21945822041145104207f7b1a8cb4043a670480c815283f52e030d79427fac78196888165c10f67419680810cdc2d2cb4043a2a83eb0a3cb40437e86d486c8ba313c6bad6a0832a0d2185211c3c7498d5baa0b1b4c68f4a0aee8c1aee1738a418908339307f36303c9b35e68cfb0b3243e4459c98309b243e8592fb4356b482179331c7200d590893314dcf01521a8a608b7d0c278526c18c1ccc0e4989922047a3062e0e079d60b6dcd61bc050e356808dd72a839638806b7257a6a84e043040f3543900191d544a9e570839427a430b1403aa4e0861a22486918d7a4b1e3f55b9b213b3039664ee87a19488816b6b1059ec7cd8af23acfebbc0a6b2f030991817321a4e63dd6e53290901d280bec9351d1b0366cd0635b2ee08ab0a6cb404190dcd2b3411022140cbbba0c14e4865b7a488298d252ac149b208a8aa097818220e209816db71ae646e8aebb2bd180054f8ed07e18f2e4082d68332481220d2343418c8ae4a037fce05440aa0d0a132a20dc0d340c82e7f6d36775103fdc7e8f6d2b61dc463fe028c596deedcb4cfa9da40b059dab734157bfce6db29c970c627b24c3f6fbdb98af73274906b17324c3ce06996328686be0a331daebee7e66a7d4296dca38b8b637e3f0eec938aa577797cdaeee946c89f1cd6eb7b737bbfcb35be4e29482a6a7196ce9fd8bf5259fdb25da4cd552355a0937b5a4f4734b4b1ec0328112cd653855b3dd4efdd05c6eea8706a95a7982ae39dcb244eb59c4eddaaab186564a704ceb67c5d33275b6aaad765a4eac96dcfe495233e22384f6e376cfcac757449b90b590131de335f04f149f1efa53ebcc65fa490f145a94ead35378bc16e26657bb54cdc6e57e349b4da0a99a37cb9ccb4304de24534dec7492594375d6c56d22908e5fcf570466c1a16e2db74453b94ea6e7d5c6f55989bc068ea9b36e272df3f5b8cb98a6f6c0afeeef674a2d4a43b9fdd152355416279fdb7fa2318ea21e4e466e9f8860db8f9f1a8da26e5c8bc93485c6e3e3a376fa7112f2d94ab454edf65753518976bb3e3ba9d4b9542509f3a4d4dd9999d90c4f62eb6520203fc0c1962e0301c1814b0104048bdb0dce8e0b94c0e474c1cb40409a180aa37aee25203aa531d5b0a5c7bd77bd9374a1f65cda44ec24efe987eda7b4baba3be9e49ac7b27fe904998b2242a894260e203e6e3f49b4e90dd06a10030b30b8880207b1124688cf6d0927b72b78b0511b7428f13045d1c6674f93990bf2d0d303b218562481823294a80186193a4c8031c5163100c28f0f2431fa3c75cca73564614f3b580a041901b8ed0d3919e196a91f80e4e0873280b882a5f2e2860f3d4e7c8872e97bf6891697d2ef3cd5173f829c703d2e48138beea10a1ea2dcb636d09265872528100f4a2e7dff1e8450b1a1de9405093df2f66ccaed3b4db3d9a50f7617f9cd7bd4b158ba71dda3ee7b7e173358e6234b4d4897342e7dd0e7fc6c45242919e957c9a75fb464849bec2466d3b5379f62e9c638e8a782b0a5cbcde5664b4d969e672d8bf52f8f2c5f3030a5d98c4b11e3a07fb2351b5298c600cffd4a55f971194b53b15d5a5ae1c0962e37152538e6b3816b4cc31d597e385c952565aa8b4b3f35c434fd74c8badc2e7d4beb18efe95b23d6c703738d12ad63fc5d8ac899fd614b465aa6f4a461f459585e5e482021478ef20497229729ddaa4b69089cf58bfee8179d937bfa454b33910b5b966637fa9c8be3eadb9acb4c276af68749c7dc3a865efad689934b4bb72797e680c62d430b9403945bda2656e8526b892e7daeced2ad634a9722a18e294bb34bdf9fbe4b51c79475a749c7f8102e9572cb90fe7c00bdf3db61d2f72a0db7b4b54bbfdf85eefaeead94b60527145806aa21a8c796a6e4cf4e48e418025169d8eef2abec5cef72b58a369f907e317fb47e5115ed8568c5833d3dea4f8ffad2448315318df79d1091cb7c3d9ec90bfbba11e4b0ee59b4b9b9617358f7354dd2c2965fcfd7f309e97c38b9dff735b99fea48908af64571bfe769421f71bf7a3faa2ac29eea882f261c825fdd1452a2e2ce52932bceb0081a7792a4dc598a54dcf9a518742789082aeefcfae332b6cfc634e29d5f1012df9d77bec734f5e78f98a6f473aaecdc51062695918e217df72a242e8fbea5514504e3e8de5534c6d1fdc8c49626da35756f32d231a5ef5ee5c634aadbfd0d219731d11cc684633e31380a8ef988fad5318dc96550269fa1dbddb8ddce7e7983e8768f1abdd3f889515d86f51175b51bd94d64f9ba952c5da82a252c693ca11e958695405f90ac69d409acdff77d5fad20739c38479511154d45531931d16edc3aa634d16e54717a26ad80d3777fc37623c8443b85423a1ca24858c62d4944dceec17004ddddbffc88c4b1821fd2d17470f4f97df7a31fa601bffbaf068ef9669f8c69e677cf1cf3f5c0afaeca4a8fc19331cde8c139863f1ae77fb31efabbf68f28849171bbee15c5edbefc886ef7a3f165631c9d8976bbffc61b36c6d17dc38a462adaed5e45639a0f249971ec8ce50ddbed6ed86ef7b0a2f2862dc7908acc46285ed20d5c8b435e335787fd52eabdffde7ffe90de4940763e11518f1ae74c07b702505fb2d08de7f4f65323c74eef8d7634b23ffad3c87e6a9c31708a29b86e4e278b1a491898399b38ef791f9239a5f748d734fd68f43ab1197a61619886d290c00053a604a75bb21418960233c9b02a700cf54d49185a74519802b0ccdc8167a3399b71bfba3ef75cc768a05f2e337a07475eaa66bbcbe3e6e4a2e4cd68347d9c69baeb5f12629a13ae97e60fcb565aef0645f2f0880f821d6a609ae04a6134aa9f63222b89e3bd25734a24a843123f04ffe319bdf7d4c1512475ee43241dda221520cf0c5e6cfe0c36b67a96c1c4563f838db5beb42c0672a2c9651e5c0672c10e17ec70656a6eb59e1f24c1c0962cb48385d33beafde78c28e553f693dcd12fa124e30e873927fe690c5f652c3d6a24bd6a1c3d6bb4dfab6fadfe1b5b29e8c4c05741270692393ab11c2538ad077ff53839457e40892106b67e659cb11653e0184fcad5d5b4ed6f8421165c8081a57052458ccf9812c63f021e34270b86d55fb2b87700897484ed6fd2d59137abd6d31e5b81162c3049130125f7e0fa4f728710b6a65f1e206dea0ac966bbefc8d5aaf52c521887a990299207453e691da602c778784a2f3e0fe9c3a7a3eb06fc154c23c74ce38cd11b1e1e197476de3e0f4fe979c4079f87f43ce17f3946d08b46e30e87398c10cc49876b9147c883946f4df58b862d20e53fe0f542024c8d0e3ae57ae1a5956f3e862eed260d63384ea100bbe0a876c9f2dcd2e3c626629cb47e192935a98edc54762be197dc7bfdb233d8ee99672a954aa552dcfbe5480f3c802f330e07d4d453f089fbe34b6afd4aadbea6e78ca69eae9e8a362926a9d183bc8a7eb9cd659cdee8d3d403bad557719d49bfdcd663c992abb05d5aface9ccd1f3d1dd33dfd2984569b0cf402216057bad73aa6f39fce9fb8f4bdf36fb14cddda7c4f42df8d507ff71d9749358c3e8bacf49ed498a35ff457b24be9f33421f5e5b4e172e18de3b8d955e14dca1c97f60cb3047ac62de76cb60c8c83feea06b6f41d9f099926cc7b7da76364f48928737669e9e94f9e8e213dfd29631af1e9cf1a98a67bfa34d5a95f3deae937a06554a7a77fd331a6b74fdf53f997c22abab4298b84f2a564b17921c2faf7832aa4cf9df35723370c3572aba613d3c8fdb2e3fc52cf7c71a49533c99d45a3913b7f44e446a065688cfa944d13a697838417964b2977631371e74f21730af121334e57085992e4329325766ec99799aca0080cfb75bac2ce39e7ac7e9d2c7348967ed10f29e5045cda621865b57a2cd51181daa57fc3c27c5ab2ed05b2cb3ddfd27b005faea477528ee4e9554aad60666666669ffd444f0962f9171d355328714bbee560fb32109124285769df6e70765c008888111088888c0822dcf03210919e1580fcd232dc8797235924940318800c0b6b76c3a4c0bffa1d09929e63e0582a913eec01bef82b7c6fc91ea5ff5e247b28c129fdf73d4c0fbae68fa49f4f227d48ba664ef825d2354b8f037ee9e72cfdf739a6075954611c9e6bfe3bcc27c903277cebb154e018e92d9993c36f1a7394e098be44e628298f947e85190416cc6027d6e304e44e893c418f1a87f9876fdf44c238ccdfc3f74864696d23c07bd297be843942226f1ce6fe2f452cc7f836eac4c25127f6a691f416027ee783e13877725e70983f0b0e73181ce6cf43058eb5e0307f0fa8c031d3abc031f139167e3977c2e7988974d127bde94b2eb2a48b724cec3b4e9ac37c46eba1cdc00ec7d2b33881d183731c9122981ee86973987f8b3c7072484f2267cd61fe25921da602c778e64fc94bcf31d297737e3f69c6589c64ca05d6edbe73d19fff912e4a922ccc5bd71e9306e88800093cb8368b1ddc6abaee667dd72c015c0622b2c4254921e4470ce1c3e1b08611ce83252100ea21890cba98e2c81648e8173e90d02917f0e1663f747c21c318498684d064880f352bc07802451a34104132448f5f316b46008102249c13ad031217c2115a042d38253920a14040e1e3482e30448747861b9c1cb1c6112a5a60441ab71b9c1d17f07117b0e86d0a24d5480f4e34d849230c1ca8b1b3844f3702f79456da790d40010d06b7e4dbcd0d88e6c48be704f5be8eab946581682c40e203205e3feb07fc327d3063a735ae2391b0fc93645dfe6aedd63b49309ca3bd3c47ef8222299ca34706b121a5dded8e22859564f082b69c7754d67ef14ccdd2bb73923d3ab9f0d9ee24c920b6fccba8708e20a75234d56fbafddd508612cf76e7aad22947d1da8979967a2effd773d9c4d56a3bb02586bb7b7577777777afb3445340781d7fad3d244abdcafac52f7e3ed47dfac54f6be8ee734b52d8f9fd9a237777b79432b32ae9eefc899ed7d53a224d5abaeeee5ec9e3ce722616ec55dddd7d443d6a6be0eeee2ef37dc93c59d6ee2a36f86a62f8dc5a274df5d8f9cc2b9207e61ad785c2ca749d2c3310d3c4ddf9abfe7dc372187507dd999ff68beb65920c62bdd2bf9b47a573922eafdd5a2be787fdf24ae5bcb774c1c5d5ee67bbe19daf73e909a68e77c8c3376d1776be97aceb39ed98527777f7caeeee4eb9ea558ebabb3ba5350b761270a320704d3daf63bcb27b1156774a29a53eddddad0dbe4b82db756e5464a77fdf5aa9bbbbbb4f128606e0ecd71ab5b228a594564a2ba594524a69a5b4524a69754a5b3ba0dc754a5b6174c73d6d3229a524e0466470b5bbdca5b752cadead9e4767ffa0ad3b197aa0c5020ca1d8f9ce8594fef4687dffc0141a4d4051abad0a1185bef31720f5ea951271d4a72bd9dd9cd96b91bbbb3ba59452ea4e29a594361547226a85b562631c0100ce711714c048c2f72e36585a6cfc068e4a8738ced55ab1701080005e821fb1ae126dbc0418af832940ad94fb1551f55789369cbb333bbbbb1bc0d150892724043880aba450e2e9480128a594d21c959a80ec7c2b9e8e90449b7a24873b02dcc7d6176daa289e8e587f04a8e00920b4e4eeec5c0367159441e94821407a3f989999999999b956ea60705ed772654f663d3e5dc751ce1b0d1aa3da6876e77b4d3aa6f4a47842777e1d6346c74cd0ecced789f570346ea7ac41f5e7ce6f2d8e7417a777621db9c361d3fb161c36f9498c63dd974cb48277e3912ea7c5642ebb420e13ba33080c392c2508a6e9ef40dbbc6d3b3bd749d7dce1d901c234fe1d70819f406016edec5c4abaa6ac5f3e9edc1ef9c995fd98fd98b58ee8600623acf061073e3c069322409898e2c30c1f7ad623a49c3e3ac63547b6d16d2434b28d8226a5a10a0c9e733e8bf3f96f69756230c20b1a7c20c310627841ece4b3460d4340c8e1e68218bf65813d611a893ae7ffe418fe796bfa857e1858e01cb75f0cebf71e2c5e315c1b1a968ccb2f301620f30ce3672c6e97073081e70c6e4d8a9871cbb0c8936eeadcecc4e5511ca88fa1176060a185be40c7f09720737b01261e2cc641dfc43874621387ccd1a1139b3d2be7cf6dcb38e6f390c3267d6e74e174cf7d477a247b0902ef111090a76cfa68f7b14922da74a5d30c961f2c8d449b2597e7f4efa3dfe7fdcd8f55a4526795813b9f9971f07ba5cb1e52a7b429a5935206492509ee2449418ca34201e9a360ba9351702157256f3c8739c893275b87f1cff9debc6ff9999941a13b995fc70f968882c80f8ad240b213e3d7e1321478e22406b22366a8e18918333fbf30c901bec500e417e654101ba68258bf2cdad4ee23a1d099d197bb2c450d4b5c17f8df83a39165e47524d491092be5c3faefb840c7d87e8d210a42100db5a0c65f4777f7083342b1a5cee52f61be52ba86f56410c68f0fd6f8020b20311c45c8000540480182085148405d062a42c45d31628bd470fd73d8cb40b42e2e0cfdbfd47900f28b859979c1b817bae76488fbea554f0bda20f8cd9616140b4b6bc7f40efaca55fce4ee9ea40b7d3af756cb6b61e9097e5dd7755dc751f6b827f851ee9e3ee5e1f2c89b96ae003506f860c0d5e87ad5b802d3d2fa29dea89eb2a85a2bd9b3b85f372c630fd67fdf32f650e27d8fd6d7d5bb1e67f5aed6afbe237154bf42e6b05ed57af0713c12a7bb5ce56a0e16b82e0d81fce2b158e04cebcb178af5acb9a27a374d9f9fa0e96336655336fa7332ca6940c6b15acf6afd37b2580f7e8b55d305a83100a8001a2aa3543613e2b384a53c21a325a9fdd0b9d331250fc190c35274c0b09ed6d0334e1bc0299b3cc864ad16eb3fa0c3f1a45ef52c979932596b049f357e4fbaeefa9515d2c5fdca736c05765847bab8955f01fc15b287121cd67fdfa3b5c2f7ad6f913d62616a24fd691cbd69b48f3acd7a683eb51f5b904c3687503a5c9782e8280c5d5c5c5a542c2cae15f0f494a5429378abe5e3f22cbfe2f2601886ef12b290c61e4a705cdffa1e2dbff2e2d8c3f5add0a5562e7419d51f9136dcbbb87c40e7f2f04857f72ba07ee557487deb4196d1555d465725bfd607dfc6ebc4c0511d8dbc951aa594025d21e552182bc6b8253f01bac2062b88eec8ab0c64c5d0a59fc39542187a6f83cc69215df551bf023e0b99e3225d1d9902ea57de55491cd4af7cea5befc2497deb530fae8ca46f8de2b346fbabb1f42aae9ab1144aa5c3b57d010f10d8db0f02ef86322fb681a9e77fd68f5462e93f15d290111f5abfc254683b456b50650c5f3582bf42bde95923c7be11f5a3d1f4ac71c65630638dc366beef7bd447e6e8c44c2aaf42bd0a1c439126d2aa46953105156609fedf887381867145f566c49388496496e030ffd13893348c56ebbb08ec3d82fa98e9651f439950a92ff909caf4fe7da337a1d8613c300ef379b20595f6a67840da0f13a16c74d26e9dcaab902f382c354e99c3fc51230ca6f184034b69d348c7d4f7c28ea4240d5932250bbe3f8ccb88ef3842def7a3d4e803439154f23c1acb5a9b49a77689079e3e85d4555452a753cb3bf8de0a575094ba5377a75ec9c753f9d3b78c1c5379703c7df86ac44232472776fa16717435695cad540f923d585ec5f2aaefe1fad5730c9ca26bf43b5cbffa1d2caf7a165d5ed353483dcfa31ea55cc7f55dde899ec28edc41bfa3df9136dc7f60defa2e8fbc515139f1508163ae119982eb57bf828b5cfd0a2ca4eabd6f79d7e3b4bc8bcc5132fa1c966f1991382d6f83cc717d0bd931e3a02ce3758da3459d46301449256bfadc5574ba2e0961c1b0c1b073b48c0664ca138658f06f210cc196075b7ab87c48bafa43b069413716171d2957cb832bd650149a38694534978d2fd906c75a54211c591e1c5d3f573e7c195a0ffeb37e65c3a3791c0c94081a0c0d8646f39e7a4f491beee9533255b375c8f5f55b3cd5b39e47e5573f7fdc4b441e8d69bceba99a75ff0db00c096200020c8ca36fc9525c29b07ccbef70bd8d9fe28dcbfce162a365f6cc19cdbbe159f9d6832eda80e40dcbabc03116b28792ee7bacbc8becd1f2c2950f1f6725fc8ec4693d6b24fd6a145f35daef4fa3e9b99ae252e3449d468e4d1f9154b2a68fd6020bb4215bd7168b0fec8f9c0167be679ea80596d789f9bff03d0ef8dff77f2c64ce4ae7b81e245dfd1c035f2736da1ebd9a8737a116d78d896525f5a9bcff147299d57beb4115cbe7927ef9ffd4fae5b5e679a1851a910bb376e3322cdff2e00c51a3929667f954cb7f230b08b23cf82d208bea555a58bea629cd8c8166ca4c14cc9d99b933d3230cdd9cd8db93599b41b389d09015ea187bb3b7165c66f61011cd1ec6d133775898c693994ad4666ab3c6b3e679a44dfd9af6de9be918174e60422f0f1eae8ebc696179ca7ad5f3ac5ee5c196d1e559461bef1a51bf32a66a415c4dca8fbd2e8f03be0b99a384fb1cd483cf9138dfdb2073522d23f82ce3f7ae916374e4db1a39661a674cc575834a9dc6d1b746fbacb1f42bf155c6f05328f03b9538e6c2fc71982de826344454547ba1851ad1d04a87ebd3103a3a9d50a7198b7a14385b4f29553da5264aa22b9aa294521f29f59a9661c6547680a631fc6f047b44fd1479745f2aa1be54427d6b9c31d378fa6f447df3e8bea663b429f5dce54e29a594524a29a594524a29a5d463c6417970ff81799dd247513a2277300e3ac5fae0146ddc1b55e0d8c8b1d5c831d5c8b13af255193976e38df3a6c6ef59a3e957a37dd5587a9571c6ba71de6a9ff43eba6ec2107c6e44fdf7a64f8df64ba417c3074f233b185212fdd2684d1fa5945a9df3820c63df6b8f6bf7a4dc74194bbf2f5df2434740e7fa09083b9f19471066daab273c4aa9bb66fa355d37f5656e77c1d9b34947b8f731e67264ce0962759a413d2fa4b4f4e8e4b8d07a61a5bd467b6711042f40570fd6963fbffefcfe4a822d1df8a4a5bd6dfbc5a2a97ef5accf5916472905e22d316c7fe5d912c33e9d244839afa20d37bba44f06b1b59cde636dc0dc382ab2ce8dd4051775b26f20753fc3dd69674801d64aa3542ba240f1329f8ae7296c7d4edd4ace143f0c5e8ceeee76eeeeeeeeee76eeeeee6e89512b33c97195523f41778f51b271b963e6ef50873a5937f3daddd0fdd43a9f8ed6d9a2a83bdc167bc45938d4dd20fee8641d23eef033c5a78764239a7d82d9cd5c267cd2b07e283d51c2299d8fc8d3d5441fddcf37eb6ce1d0577fc6054deb43896fde7084139ccf96cd76bbb10029a5df5fe374e4dbf4c9727429d9ba2d91c5385844b6742175ddbba391a9359f65cb01183ed2e842061dac2046012e9cd0e0065270614491d8fc1a9761401449c438a38826867083d8dc4206550ca1086bf83004148ba2766be566faf52dc3b57e09d33341f5fba77f5ce656abed675830d65f757585a5df45ee3f3ac6c36fc48d604d4dbfbaaeab351d53da2087d527cdf4cbb3c2765fce9cd0affa5d7db1c4ba246b496499224bcf69fdaa4eb364e9d94e4596acdb3db3cc0b54b4e99ce63e412ed32a3388f43fd872ce1e06b6fbb27d6e7dd238672fc0c0bc5eff3d67d556d65dd5c0d2efba279dbe3e4ec7984828d3d76f01448df64fa37dd238af69a4fdeabe347afdeaf892b891c7bc3e8a63399bdc4a2f13b6eca25b548bba882cbfc6ead7d45b798a174cb91e59b2ba4a72c06b9747d0414d910c905f4adfb9df8762c78041f7fbbea69fe8d7f7cdc97124379fb8df9c4ceec7170cc1ae310e66fdd34cfad64e68fda49fe8a06ed2423dd444f77b6e36cd888dbbfbe5b8c9edfb41eff73349d15c72bf174cf9a0d8e196b3e705526e398ddcef9bdff7dcf4ae754cd952ee477fb89fbbff03e875f12708bece05c5d7b9220fae837b14041f14c7eec5af69d2d83287915e1c5bfc151c26ad63fcbf6f232d43fa66fd5a1142225be6b0af79faf57d8d8b9c8d288ae2d83bfdfa7ec563cbd968308df8df4f224c13c0e741fbbf07c7298459c2d72239cf601c5fd7eef7fd7ddb3aa68aae750cfdef7b89f7a47ee27e0f92461ed2cff03112a944143f146d405114492fbc1fc901df218de1d4b6bb3fc501e497151e2c7d3f8136a5ddfd7505075bdadbce23cf120741b183cb220aa5db4cdcdddd27f725a5947a9cbb3b5986d79f7b2f5d082b8b4c962d783eb06cf8d929f5e9b465bace2983468020b7d0dc5c53105c9edd03bae72f29e729dae3acf16e2c2b0ae1e5c2ae7bda915e7720bc1c5982e056d285f0f2053d2c4b5b396ff446ccdcdc2f1fd9abd1a7a20ca7ef3deba0a2043acfe1348b3268b59551392acae03a2a3c1ec1c8ebbc1115658cbc1a8a28783db8bb1267d03ae73bad952a71460f67c4e00c25ce50e20ccf3d18bcd137bd33bc6fe4753f407e19bd4b5ba6c66b66669a36a05f9d0386562e8925e1f5aa5ce5c1befc779485c5f23c75290a23e6300de78870410d3029b0e265a026a61cb1df65a026ca68e28b1bbae630b6f18a9a10aaa189a0266a1aa023021c122cef880f1ff5269975451441078ac40e5744183d78f560ac18d29ef542aba4a7614cf394f8348c6f6959452c114412b69b445011467418ba481035d113aa0144061c60b6900105b7f498b042a03cb0e065201e31fc099e263df0545195e081825a61b9cb403c3fa9cb403348f1f377449bd563c9403c987241d0977683dc1ca95fd0bbdb277358303393efd24d96e3e56f67b13ccfbddd9d76777777cb9899a7b093b923729eddb3bb632e1cacfb5ce3d23e02328c7d5d7adbd2f0cebe5def82a5c93cc4acee0eeafee99870e8965dfb6ed9428270bb9138c1079969dbd9d9f111eb272fe41065cae68f1642dbe2b6d7f44777f7100db7db07cf6bd8fc2552c2dbc3ed116800f4832884a01161a7790841b233c50c8ef8e2876e2a6e521081b1c4080e4662e5ac3d518327a0c440080d5cf410e37212b9600a1a76008208312c91442c0c2fa44881411159123ec47a03424a966431640ca29eaf8a5bb25c965bbedcef3987fbfdf7bd6dc1cffd9e35c3fd7e6af0bd4c10c00d7f24da84cde2c5087eb6135efa35bf49b2525bd892c5001b6c0de3a086f1bdbd84608666881ac6d786a286f12d398809219d68339229418b18ecc4bc679601cf28b2c5bce7441bcf764ddcee772e4705702b0b786ee598b6edecbc7676766228dad98985326d5bc224c7f59f2ab8ddbe89443c3bf9367329f5bca1a2cb3d04223612cf2544aeff8a57841058b375ba6508b46406b44413d79f657d66a0325736588117d75f65819f1d98a0024ad14f0e62a5bdab22682063670737fc70448c0723459c546eb0821dae7f4ab4f1db8d09160c310203190c11f37fb94c8c0e4a0051810d68184a22e6b49d9d1d1b1cc7dd77b8eeeeeeeea71bdce4962c5924e09624dcfe3e8199dc92ab50e2e476bf87840a6ebf65213183dbff490871fb5f498c71fb61667c806a6a002991c5ed37dd8ce8e19b31962a41e2fa97441bf778707390b0805be6b87d440cb75fb7fb0824b78f28ea7f19b9fd3049c698e9c208a0dbfda268d32a27462061b9fd211b61c2cd1890c600c917f6553b072640325187cbb040355868078b05897f47834f1900b8fd9c68d31e1076de7c885c6b4749789092831c4469622856dadb342489c25314b48517b1d6e13c33d205589ac1e6b373c9ebef1eb70aa0dce616d01a5cffe9957c98477a683e8c227e5c062a82e796e1cf9d4fc26520150885b63b39886d33239bc3e6b35e64bc32e50959e627a15d76c3321ccd61f393d8dc39b2f4ac93d3872c59b3664281e63362d2af515093231b145b62600d9b043e86eb4ff3a258177dd0f354476c0916b9fc59e632a32818369f8a5916777e0eee9cf55ca78d6c1c6d549bcffdcce7689ccf688b5c66225103a5f0843306325274678e5076e7cb2dc1a2b0e7ce907667182b439f3bddc7476df6f3c3062428885b1021431d53b616655d32c7b8a5d7e4ce9fe548873b7ffe4807a6e9f904939726396e397d9e40995174b8e59c72670eb76c9ecb7ab15ea00c9c8d6c01a181a8242d1845392915d10804000000a315002020100c084462b1609624891c6d1f14000d6c8a4066563a19c963498ec3308a8228648c21861863802106d0141189032549b0166741d072b78df8e2967fde700286edab5c74c801eb1007c02350741489796073f39a098b1dbb638b3bcbcd41f3c23a390acd2e9f06761f5238c6e8ec857b8cebb00b15301b9c62bc100c6de9b85e6ff3cb2227b1967f922092d89e657395c3d39fdc47908be4883085f274c8288e38e5dcd1380a3f276f39da8a8014b110d649defdfebdffe35571cb960611c348702e76ab086e5c06f58a159d10aa6d9f9ab34d83e089c2fcb08ffd864e27aecd655bb6aa6c697e68b06ddf175ccd65c340bdcd1a741dfb8fb6319018bd9f18654449d0d3018e4d981b4c345ab27480212b816caf6ef111237a91dabd87cb30c4072646c514df1faef3be281edb531a6a165b944cf337ad5fe38a3f3447e6b1739063bf46eb7a1cb51a7a4a805ee3e19d9642e1304748e79c2ca0b6b3b4d6e6684f9ee6ad5c97a10ce13cafe488b662b929693a134759710b4d1e043cbf012d7a540ae54d8a74a9d07a17635d145417ec0a885c63f9262922d767c1cbab76e08247b08f16b5924e6b33aaf118c975a4a97240691857e49aedfae94d77430cfd9e1ddb8ceff42a017006d5161b1d570004bf33084363400c4df3e346882d6edbbc2905aa0832261c2a0a498ef226ae579cd1ad2a746910208e0853b59cd8488604503592311b3078699f4c94a14702b15ef0dec35da11ebef248521d1c69d72fa345f4bf8c6cba2dfd0360c76a060fdaa60bbb9c2f601d5ca394648ffece99ecdb367a7f6adfc66901ed25235b7afad40d37c5d6b32c4536a860eab6f75e48516f0750ef7015944b6b8bb764149948036aacc8d79a9306a81024fe1a605c3235135134e58aa6fef8ad2577929bb1ebe662a1c23b5b9575b4dd60fb8436974b6829b6405a23700d101cce0a215a4380e9003ee2daf5ca2b0947b15af6bd0cb4760ef3882a1665665e2736a9018a27287bc57e18c946faa988682fc80229761970330718b77a29e40712205b7df176245cbf03ab2215c0acb2dce28920956c0ed53dc00879ff674b5c9f9727f2484dd367d66cc1cb021fcde82c78e96d01cdb3026a638d8c2d28a636b6871e13b7ab8e91d10001d91a00cf05c497900b4ffc381bfbceeece34cbf5eb3b339d77ee9fbd39fea74d0cee1aa8e25a1677241597118a173b47b55439c3a1698c97265d7d81c9bd5bb315f9e8d43032de9e0a8d3356ba9d7e9fd56c43604be7f8b232609c04fc4b8d54f954c14168111fd4bf7cdde99b95bebf9e748a77a9944860174183d54b882fc89ac52500ae4d76cb876196008839f83b174bc771e373463af5ceb8786658d148b669d55ae952aca6f9942370851c148fa0d138d4a0a65d137f425118ee15e2a940b862bf093dcc67d865569fae7139d354ee3c6f55a11fad760599dec646fc11ae5cc3b0b4dd4606482cfd76a3c7bd6cd72c81a31d52bf8dbdfe1f3fd8d520a34960ca83bdb0b68ae06169363093a29ed83de49becfe6f6346758dedf988cd7d1c9728552375b6a0be166544327b076bccba49b9b8b47d669db0aa69d857fd5a39da3a89f3a5edd116664a9c6f56c73480e96b2c88da8d29ba627b02ec63ea696ebe5c2c95c35e4f1dae6f2924470b5e46a284b8887c2707c5b78ba1db4eaeaf2b6024ade9bc0a27d81651c49d1e9337b78e41b136330b67acf6abb7e33bb6768af40c9c4ecfa6b5dbdaee1eadbf00abf2177cabfa0f553790a50f487cfba5ca2d08ac05b5c0e58f4a74d792d29bb6e49151489085bb98836d35542db1fc7bfdce3276bf85481ead1e3dc360f2e2c37a8770d296d3f3c7d6c3bfb0ccb1dab049e610db626f37c909014baa5aae21a7828f784a7df065f3f1b72e47678316ca0612adcb537bc70a730ce5464f48c46505f5cc2bea4f4659779fefd7cc22a60d1d3072919cfe7c8ecb116171e9766b6029cd48392a389bf156f1001e2c29b331fb69d5a5d0526f3ed90876465325bafa7a170d23602baaa0408e8a0ea9e171c6737cb2afe788d2970c129d5ca40a3dd8aa48b4bb1a175319583c989d92d9fab264d3289fcf89fd50a3eb0aaa3d8cc34b9e06940ff1de620c33dba7904b38273dfb6d6cd5b4e283ddf9940b34fbde6e2abb94dac4e1a9064a3f59e01da804577380ef2b48ef91ed211784251bd11c55b68bbd5d3dd802e76e48b8facdc758d8a82b531a60c0d5febabb81b0f17b9d251d1406c271fff40f782a66873587ba02d7bb0e6a57a32d65bdb7c96db7176d0d8528c18d4bcd55d94d87aeb36f03ed3762ba3da3fcb261e6e2c5936f498b5eb5a4623a4d16c3e30fd74a30b8162bc46a9b5d9ba8b31c157cf6e09f55c3a46184aec4238654e45fc9265c16012014a873bbee9be714c546737552a99a870c8462aaf72eabd6d6d38cdb35de5da8eb0ce6a8a084738076be5a189f176b49bcabdd1a622dcecdafb652da5eebf00e36e804a9566f0f11f63682a3ce17881239c29a1beaaf92766676b56bd3a9b3ffc3abb94fb9f53b95260bce991e6a12794c779851f57588e9eb99f4ec7074b4ed3c18689a33a1c545170bfb154a8dd0bde92260492cd44927f1aadc796a9b3d67f3f5a777801b8f7fecf35b0dc39df3f075fd0823b8bc1f9bc17af46419d6dd9185c07ecd16abfcab0517e08f08a10ecffcd9c7612f9a81d0fd351c1d20dfb9eb7165e07bd88b670cca22d1a9c7de53d2afad32e60d47bd7dbd80da368fe5a7ba993d8da1f675bc3c9e9f8ffe425a62d73707dd18259abe773f19375c4dbb7ac742013aab52b711eb2f0d96849d55df1058092e20709b8e51ffd6994bbba5a91a1d4247b51be2e8380db6dd399d53c9e42323407c2ebc0791444a95f6cfd2e04a4845e214e661416ad44bbbea62009376438d238642b44804e563cacae34578060b1c22f45caff11a1d08df9254ab0f0871a2cc583a97f5a0add0e8decc52484c62d118ae9060f7337c132883dbbe3311b9faea2d2f3e817aca776912819713a4de28a36ed634bfa11ca39f024308b60fa57a578bae869b1f468f5777c2677e5b444ca127a80d0b00dfb944cd288b495a6a6609351cb98060e411a084cf989608bae229a3f2a12e5849b48c7d8778c4bc5009d760b8e70ea25e725a01f7a9e6b603916a279beeb36a79fbc845d92c44d95207f36109f509673a3908430f7197d94106bfd328be7e315ad3c87684296654ae749d5fb05f1de0d96f10d9a222c98931b672e2b4dddeff48cd0737f4b9e3f65bd8d29b27a8783d4f9818b8a82d331928fe16ec7ebaa2b33ea20314ec26e47e031e47218e035cfd603750e61c566b63298543dff05cf162aa1fa786da764d3a6ed5575fdb904de144c394de6568f473da3e3110977e39840af298d9eec349c91b90e88f4771c2898b4d7fd734e0be4dd911d2e9b113908fdaf9cacec15042418d9b53d0749d1a247e292010b989250d5c7520d2b22fd2fe9aaf9d87842f1ef38a5c787bab04ed9481708e826a670e7cd32435c4e2aaa12905e5ac318305b4db5ef815e6dbd58d075ea37ff787ec7f501719457587c3882426d5e831e04f612abe4e8520376c348730ffc4e01b8ab56376d1f65f7badc315f84c112048a14270652874a7b251c126b4655a3a409d3ab69a7d80fa2e282f7f3f42dfbd5637bbe20a9d08eae1c9bf17cb3542d97104936dcb601c10280c2d8088aa7369f285c407ea3a1708558d9de661bbedac519576f3d261b50d4d0c6610f8858586ac02369a7af223bc795c2e6d142390f48c5d9543187a62d8b738071cdda3bb1849dc2768a8d5157325fbb288c37270a2a0c62e9f82f6b798a598a0eb9b20ed282e408beed0f1c269d3a85d2b5f4e88000f4243588d86062978d24d300a057668fc59914581039730ef23cac86e61ca84b612b615a0b3d4ec899353681cce6d9b16ebaeb4a4d2ae006e5fd507ecbdc34e0464d0a1ec095b25fa69efd057b1dafb382dcdc7eb123e31ad4be28e27d83abeade6260d1cd0a6550841d2618d0044bb2a4ec80962a58373f201ae3ab1220b93776a9b08083fb08c0122d3fe83f71ce6fe4aab494e14396742e6ec670b0ed59f2dad1347dff21bdba8b706a064d59f042fa6d032957476e61f5a7d7127f1e3c1ed9c20436c1c7de0e8ea7cb82a4bb0dfff87dfb18b2454f87b379baec9593d3a3e4b75a868d9f4c323a4c78dfb48100b6e2ec2a7d01afa6e1f559c888add178237e7428bab3cbe3e82a91ddda3ad49d57ded5aeae5bdd5a32cb3146b33be2645bc12354d07e3565194a7da105ffae2c1379dd507e011accd613a5eec2dcc6c385a58d552a0e3350464b8bb5b7a3ecc1f9e28d04d0af4f21c3ad1ce961a8db1e3ccfe6dddd15f2843e7821762b306a75903a75905a7591318ca9b4699637a00b88d6a9332368425069c525e58bf82de251d00c5c5ed5f3bd75f44032cc6f320e228e645272e468ded662b8c3956cafb25227c9054b581a33bf62bd3f49aca9b9feeff9dd632b4c0c355f11b0338b226a74348e1831a686b64ddf9ca5a0e61169a80d4d55ab071d2e022776e9ead3203611224b20e75c94d4142d650ba8371d9059d85017e0488d7ebe0ef8c0e7d195d07ff8ee18daf7079a6f61f116e069a7901702b1867b2b826553a7590e2430b0fbc4f81c39d5a51e88d498f62fa0e2d934c022bd8b990b53c928a29257345e3acaf8f2729628472de31f3975ebe5d0db6f9c4d88c1e0a2fae9fd86193842dc4b8597ea4802d3afd34a60bbb0dbcc3e4b1205144c23ac11a81b4998eac36b67582a7b46b6c970e005e8af254e81a142ba1bf90b590b09bf838f8153dc8bc2916ae0eff168a798b858c70c0528dc641a5bc3b0fd521af111539640977f9646ea98f6ed2cedc0439b18912faf44b525cab88b624922904ed5e1fbaded7b8a6f5bd51c767ff04df7839f81c2fa992456cb5e21b0f50e959abab442fac52038a0a0a1a88dda8fb78a7e2e5f5dade7bd3c39a1df5b81ee854164fb025c306872ce3fcb1586be290f52d1bb86db89193c79b3d5ef2a3d5d6cd3098c948baed09c821b1d99efc1c51074298ca29b00f2cf7b98f812580fed7a9f23e01e45b1b0140601725815eabde976b04966e2102472a9886ca0caa7847f649f1697a761c72beb147bbdfcf365a87e03a64c586475871801c9c0998840f6b082e84f39823c3ee99063ef580cc421dfe6da6eb5b873b79eca491cbe69221661cd61b38d9b919fca4318f15dd30f0217f711ed012b85fbe69c3d928413d66fa60c36b21e735012a491368e9f4c08db93d53b1e8efbabe6cde1e6d67a30a636bad8b66691b9947e3e2f31eafafd320bf18b13a64de89cac869363e155009eb7d9f96b958cacf905e3910e9d2c6c2deffd85558047997b7548b120b1d593f54be251ee5c7c4551810355d95015ca545f4a92e7f1e5ec6f1a6f40d0af8c0842c6e49996b9b151fa4db1f0d15020cc0d2d2bdea7463669ad76b6382ac138d02a3767153153eb97cf0e58e691e05d470b2887921098df361534d739b94f505555b250d7cb8b37738d8b53a8290b59cc9856e67eb32127ad73e5639b6b2a2c06875d765521e2a53ec8901daf5a47f3e1ee3c6c8cfb2eb7208cbed7203af033504ad4cc948b806d263537570a0b6e1ea59c6571c21f20a24bccc2e94cdb8892abeee07d31c9197fb9685c44bd0ad9868e2ec72421641e79a94eccb14daea5dfdcf89e9ddd0d5dce3cb2182a1d2ff65c91180f48e2dd5cfc70bf1508de8d4b7807b12ddd58ecc56608909c3bb3bb9b93e32db63c238d2a95c72eec22deaf00ef192d2b87f952f0b25e202386283bec71edd8cdfb2ad493fde7a4064213eb944e4fe433def849925a6148139daba0b816c0042716b5c7321969fcaf8d66e27b06185191f8d2e4c6a2676f162eb80cd3bd3d899b49a3f577305c66613b75c8fbd9011811720d8008d96046e2b2048301e4cc1a243ec276277006d22f424d35aaed05f707d94b826a222917b9a41bcc69c5c9cc5cfafb76fc0269a346dec0c67b4d6e37125655e0ed548cd0ed3f66419de64b62b666d27ae536f85e3180cc49e7e191e9a2dd4681b2d4331441b9ae1d998ce35bce26a7041fc29267bc65bcf5a640054f35d0977cc81fa9f1817816f07c6908771a876f2f27801d326643cab66a24975948eda85f4dbb3cbebd2c193f4db0005c4c0c9c731b91ec8dff06d6e616a610b09d62bbeb253e1392ac36e19b211edce7c1337992093052b0d6d74a397225ef169cfc8c9213394a15d96149fcd9732f66a7b0da136a2f3f30b9761379cd6ffd1ad23cd58813834221082686070e550e32c2e9ee260238a085525be7b2d5602d94201f1cbadc6bcb4b292fc72c0c1a75678ed56682e796dff32da14b58b0ea3299684a8a6d0a467b67c5dfd0cc99329009357920676a29883e3c929228821bb8e303792b087a49a6db4a25244e04c7084dacc0f695b41f635183772b3dc6a41ff804bb774900753268625f821921592d139016436b59b7dac2e38667f62801b992d4c29d2191a2e7869fd710d2e3b040dd1c072986dd009ce28434f52b26add12ef97e6da231e125d83d92d0627f20dc73698954c16771f0ba4db0b73dfb8187e692176acba762c3ca8c0abf878c4863ec254ce426c68d34de8ec206124098107ddff60e200c41b9f3b021714afec66f70ed142200c5c53ec2a122a023ebaaf854b98c3c7c4a64459ef364dc98a3f885bb1acc9ba54b940151df48e1aec19d03fe070dfef18698100d5574250bb1c43e8f23f7ed8f400e8228cc665fe8ce46d9c7f1486b2c7d6c173031504492af098406d8dacffcae36af2d24f41920969117d92696464a2a01c0fb822d17fcc3c57c42438e83f9cb8da7c5a7ec4f1783b86847d53d7742d25d08933539e1c9b2f92db41c3b1422fbbd0a989253e6e15043f1a522a31293f81954d2f9ede51f4efd85455be6f25ca0d29612ba809713edbf9b67607247240d265bd9aac551018b4e42c7a179fc230251ee33ff98a0da142484e0a218caa1c9d3439a702b9e7dfce7d32e692c61fffc223d1f7fe7c46dfac42862485dd5e861b79aebd7989fa2f80d34bbae434f4cd4e76244ef54e58beeda1c120a13b25c1c094cb7a16f7b425ad54aaf39aeeea8720a8e0615d41e80aba03e5a0b23e179fff8a3925660dd37ff175ca4dec4fab548c9e95e92992bb34b53983e6abb8730448c1769e4c2cd4a3862b4109bb142935e01f645239c36ae72ca38ad0aeb7bcd566b7acc1222f2dc5c2149e0ac81ebd932e8619097b3bf101ac2c490368d65146216fcfd571c4d5b86ec707b2db3ec8470c643bee93f0344be49a83c55e0a1a8d57258383875aa3efcafbef2bbc6aea37c5b957588e552c3e8752dd8530cc24df0fd802f3c8221b7d7a1a72a43465951456277983b1b995425908387a91c94808be440abbee0da32d48e484f81e5bc6bac148eeeb6c07d17c07a7ef45d1eb4b382160e79adffd2139bc4b89eaaa198e9c0e949a0928a7f9ca234a9aa0b299e360af076f9d82faa58c282adbadb63da8ff1eb789dd131b20c425a4a474933542fb67ed7298f10b1090d1e500ae2b35f3eb1b59ec506946e5d91cf49ff02b77a565ffed5d4d2c92b95d484227c4754a9fcc7a60c82c15aa2baea57a65de185ad0a9d01a7945f497768ac27537e7905a356f69225954ed610248eb97c577cf0fd149e7a9e79ced0293d76ef9ab92902842011e6454aee0c6023a39bcb05f162b2da8fef00eb5ed4bcfa1448272fc4e7d50374d4619d92cbcc78fab11f2282a1fd7e923d6c774bb720e927569857a8f7213056ae0667a976d4ffc028a3cf0871a040d4579f3dba41735573b7635e4e0bc66999812061b51d017e6f738001bf3ed8da806db600232ec31f7f731962ed11ab9341ea618d752f5faf6c07c84c25014bd2804f5c671482ab07027a22bd0b13b2f922edf7a71e24c0825b91c67fcaae701c12956a3f10cda4440455837381c3fd95a66e952db8b038116c8e5c7d5987bbf8c21e972c9b613db7063dcfc6f1e829e87f21686ec395ce2b2463d1007d5277dfaec6fb80ce96cb55d1376f05df704356354c53c09664eb96353ba85aa48dd8f5878fff6a339bb1d0a955a8f278ebc0b17e738217c8113cde538fcbcb9ce8dbddba947100ece2660cf1072f91aa9cc2afdd193e7c57d8e2b78e3634221cd5560c18b656308a286ede99eab3373fbf93a58ff7dca6e162c6b808536cd7ff852844f4d6d7d5ea3ff25fbeeccaa9e22b8145c7b5cfe87ae56d9a1b9317d11ada281039c7d2bf868464a88c5cd3a84a85bdb2b3a29f35929d9bcdc89d614eda9ae04fd7cf34f3bece743b2f85d75dc254660b7272b8c40d00fef25093adc418a8ff7fe52a5d5f0bcc4ffade28921f7f6829690a9641f26bd37b3bd8d14882f14a76f8660b198483db408750b4838de85a0886814267c36634494d8af3ab4331ea74c45b93b06eca6b1708470935647d35c8ef1876b6ed780a8eccb209ab0ab9ec5f96aa5a4ce2341810c8aa3002432569add4dd909a14c2379c6e927e0dfe2a2576d1e8e374b6d0e912c61f5b2abb369d7ef37b3d287cf118446abdcff7b4ae9420e3886f9ef64a3fa61a2633b7147b5c74490a5ab628e047def9e2e9250ab6097a7384f4db6d2ef1e12953274f8b5b4626566b752b548799ab38af609518bc64bd84b4b506be5e5b879265a2b66590f397aded5d4591ed2913ca3fffc6a03ae00d15e20940cc2b35ef5349b813b79fd5b184fdf46bcf6fad09d8581f9148bf9d8a4e42fbda7c1bb975f9a86ff0dde34e0298eef8f9793c65a0317209d898d7722fbd00da9111c5c9aee8ecc7ce60577931a24666373297cf954f8733891eef1ca12b010814ee80874c2148dee6386f7978c18ace47f8bd1231eae63da9dc24975c2e6916f315cc993ca674f0734ca81f99b13ee944e5ebee5079203f2f0203cb0752a97cee21394c0a9f44ea1b69d26a2d9bf17e9c5366dc9b29eb26103dc907ec3486a98020b9a64a433e0f0ae4d742c5051fded52e0dee974816c8a82f367b5bb8370046c354b06ba6a11210a89e6439bcf4345f02277d67fb039b15ab78e266e2ef8a961a8075d8f605cfb028ad5d254706db05c6dd52623169d98f08311f63e597efba8be8f85823cad57f6037989066834a25f387a44d4134b239740e02f5b1952a891bb6e5d033501d8e9962174eb6cee39aecab967a2dc0387e576e55a92454d5479961c33632aac1b461ba697e06af3deef0c91a1bb02127af420eda593989304db6ba630b0f9788e95de53523199c3c1f7cd85332252e9205736bf1ae9841058a83a40b095faa9510048c3447acaedd5cd60c09a35cf17b431ca5136cb477d1bdf5a3ba410187b5b6e5d80335285808b5e5905c551ed76df55cbccb04a1b994c9df9346702c32ac5b392476c0ac112e929a0abb8ecf74678b87629a8e19456f4bdad7a4549825108d4c90c720b58d7bc5499dbb8b2249f7db7628a05725d8fcd28948cd140b973160206160c30e9aedf4d9ae237ed382dd9e73121a431c702d5397c0ae216ddf88b38eb042c9d691c1a948af6875b3f05f08f6c81da74646eec1a03ce03a6a0bcbcb6b684f6a237819032a40458bc5a823061faec55c33d7f02e6dd153006c234a3063040e968443edcf4f017356551100ca603718a14f45f3cd9b0e181d09b1bc9f657b6f2d5f947f87406cf4f4c6e746b6a5c88cd00e0ed87bb066b14053e358ef13916853c3d8e3cf7c2daf47e9d1bb1f34190d23d80494c1e8733686a3c89e00d2842ce5d1e11a320ef30431ab833be5a01342d55e11e5fa29fdc56bfd7bcc7d167c6a196de80f580e4be836de1c18f1c0257c78f9437954caf586506d339675b1da49c2d7f594101fad28e83a1e56e52129b4ff1f90d2e6f03143c31cbf03d04bb1469561384ff1176bd5d4f7e30e2c1a15302384f33377a53f76ebb339500205f660df2bd4b56277b776db7442ee6260d7b370226b4d984925bbdaf72daf41eabe8c0c400a8c75e11f2914b97fefbeb5bb412f4fb86e6fdb629f338a2cd18949ef10bb922b2924ff288dcf3bbfd4f269e105bfefa20baa5560dc0f257b5dd5c71796d6f3f2d2ff9061c94fa45ef9e78fcd217ac9da9edb4418820cbb939a4c75c3f171b6b7366ff2246a42a01c57a6f21b7188bca8532f62de942d485326fd3cd2c4ea4fd086eef772f1964bc805912cafc5cfeead11fe4fdbd6250b5a7369bc3bda8d69d765f4bde33ed0cd693c6285a5e57c85c0bdc5084d8109b93e2cb6a5dc0c0da24420e58a750f7caeb02c7b3803fac3b3aa160ef38bab7cab3c8b9c3723ccf4447b878fea3cc6fb3443d41a925c01aa80ba1873aea70f1fe7ff169ef7b24fd1e552e6ac0786e2d3fe77f66d0299b21d7fcdff2d29e6bc7f1d7eb660444d54612a430f7b22ef269566e037334ed1cf1fba543f33c561391a02c9513d0c57c0ca6b606fecc74cd26b71ab95e37967e9f1e427c356a47527ebdbe6c03c8dc1809e95ee0b71c39b70f196378e433a90a320cccadd40f0de8451a9cdd17b030596d49565321f53288ef73ccfc1c094a7935340719c5dc90fdf1604f00a7de177554be726618ec8251dfdb3a1138f87827c037dc70f8caaea7ecbadf697c335be7084b94f39882d3c6643ff023c34e005dc0da633a9b00ffbd29ee0d9e14cad812c8f476f48e9a9d2d04618c820652059dad931596b992813ab91a88dfa72bc178ffd28cb04390eab5e35de5db67758c2d0fb4ac9306f4e0daf16a617d69ba9607add1a1b231d772454aa73fce894667ce81dd7cf5725a67df8751cf07fc16063520791ead5b6c58d9eee16343528794ee9616205c1e510516705d88f330a31304aaa0926b0bb9657a205ffb37cd16c1614e2e3774623fef052e3b8c6c653a1e666f0663bde5c8382f15e0bb3418ca899f701cc9fc40fe4f9714fe7ed08a36dece154b71d0d67476741b5803f460ccdcb923cceb64d89b779f3b672511b388ea029cf6308a83c7367de2590a8df09e9ba1c5123a972a8ed90a71211fb59746908f8bb6165267a3be219013e8b54e0490f13ef77ab4bc05b14ca9e39e0e69dec8bc3133e635d300eb7d343077222613b405724074a6a9ff74c750b3df28dc510010bf38328a627ef12317f8ef4ff1a519804890cf319e6bae276ce006fd14bb9df9a12dc7985fc358073f7e45a8c3f1a7b0e62a239fe18fd81a4d3c67c781f29e872fd245241f9de43b4c782c0643f464aad171e5d81fb6d817f4a1636b526a1562acf9a8acd8cf04dd417b5ac6ad4bd8191ec1d7dafa1da216007785955e415012215257e519dea8b46240aa588eb6ac759022768229a1b799358de3b12f3287f22ab2273c7938c5f12bec526de757935ebcba21605b0605511956408a4bb3a92a8dc10c9601bf091dbf8dd0fca51a00dd6a8f82703e3a1bf69472e8ac12b799fbf397f2098adfbf9b392acd1c88cfc8840084c7e826e9a7b2cfdc28050bd0913ff0cce15224adcf8425a08bd4f6181e5257c9e40ee91496026b6f851cc433d9bd0b81d693b26c7e8a1012ec90ef819369b20231d11b4aae7703d37fdc4a82a98d819c4453b7f56e02849e1fee797d26c6ef3d9734d050803ba861502fe0b4e8475e0022a7c49f771bc1040c1ee41846e0522641dceaa19e528293cc78c9d763325761bff50b07bc1b54c8649ceb101fd83401e35a4de9cf2a4099cb4b81799d723c2c2d82d334b61a5941a2cb9ea5cccc2bb04e297e17ad41815cbd869b08dba2526bbcb8e38ffaf5f5fb5d3c81704ec4d42f58e500a35e390a4e243e40d32f5a344441bcb0a01a2525b718989fee8bca5b163c098da4863b0a96dc7c632f80fe98052e920963c5d7752d05ce9a9b25f01f5e836d986c1d595cb4c5463add874dc8bd1eaac12afa26866d6fe1b845f669bab2bf6d11059ae18c24e6dbbee1193c81db293a1a694b1619fa17aa581068dc9d8aa7a0dd078a35012972fa04b609cb6c50a3b9d71ca05f1303ec6650f1dc7950fced3b9969adeb6f6a206f0870a8baee5b43fe262e0eb2ec6ecf8b7342d32b97b604695b809a3dd43c8b817f97e3cf765f6f6a836467dea181688f2221c5a814565831a651fd14aaaf489f60d78879bd56aed3ed466355b02276536e6abc2fb0879ae093eb2ad789ceaf6047b99f181d3a95233005aac1b0d4d8ec03d9ad8249acb3348c61667c544666a424a53f31fcd7fc9e6c198d100efd7fd6b9ba6c86c46411048db002b6052f0fc37c833300e0bc7446f133b8e7166d54d9eaf713090a6915221974b67599fc813c530fc992132680c56f619a32e618eb8dcfcffceaa10389ac1168f01b32cc02655eb5c49e860224c707a5caaa0e4a8c3535ca1fbe6b457890e91b2107bed5ef37388fcc33fa09a09c97ebe1b32cef0b7ff1182a273ac6583e6fe139b6805dbd9ade8b62f651ba21461321e2cba35688c6442dcc59a36931e4111ebea63322a244444b24eb8676291eae1e199121c1112005d46667eec5bd3e96182a4f4e9dfe2133e833775f97dd9dbc5661952bbd1de6ff5a7a8d145d06cb075b0b9ef3c1514e4f46df5c846969199cef862d27d5ee20e09ddf096123534efba539809dd822db2fc0ba1b2a6a1474466078764194ea7a2cea9bf8717d71f8b7b57bc6c2eef8f86c1c1094a149d7eeac729076766c953b83267b837412113ff23fa255b62760dcd35ec6b5d2293a29f9c8baafdcaf592529019e770b1a580cc3f6006abfb360c9bcc80e6dcfe3713fdfb29dbabb0ab8c138f41ea9e5601c774a20344d3c298fa1ec3c5140895decf90d2accf99a584747fbac8292c549e2032d9c910a66c35595f05455fbe949d4f68f55e8079585a8586272f2dec86993008774aa92b4efc98103d2c0920243cfa4129cc6546210b13e3deded86bf95e0232af82b84a7d0f3a54ff44e519f7032012b2aedfdf31c4b327718d39ef5e5c098857fb72481f3c2a803fb5989d470a713cc77ee2b571702008681009b75fec23ccfc7f3a05f98401351275b70586ad95b9e05ae86c6d1ee893f9efaffa010a74c55c970029d82ae4c1a24ec6607b6345935e6a180d4a3862b8ce2feac375acb652065f5bd1308594b50014a59a5d4fec151933bda97fd4cf7f50eb62a71cbd787ea274b5fc8e13d210b8bc9599944d2d6472fbc13e951134f949cd1e8aa46025d87ba450d806d55b8cfc4de9e795d55bb5990fbec436421bc2068ab8a7b25b322179f9c0a75f8645061d1ee2a38933ca45604fbb34a71d1710cf80e7ac4ebb6eea78e4ae75ac8dd328ea442cb292c3bbbe22da5712140823ca59c837e0a9094addc787ed358ce5e7aca180bf3de735ece1f2e6b0f77cccc4720c9f790ab3b217e65b1a0f160242ab63409b4bf975df2b39677f5403ae3619c061908afc4ea4f8474384e622e8fb19be829fecf1a9dd71547210d607eae317aa54d10658c4071c564a20795b712271784a53c321438eac77520c07b337f3ec28f35b66fac863bbfaab3f7e7600736f12dfd59e40e6719d6317e2b206b489085f627429fac0384c4a0cd8a3b9e1e6259f94dbc5295a2ddde2fb9167e01dc93d394d4b9b1b5391530275495194a5541a81207d83e596876c0e8875294568282975049d5835b713e05871baf333af631b5e44c2518c23c360260852ff201ed9d6814908534caee25b9abf9e59a66230f5eebcceb23a1d162c28763ace527918212e932133f6ef3c1d0879a38ff1d4221a45f5db190a0990625193b082c536a42383227552bb935c225446dee805aa5386247937f5180fc6a2c836e23a735b0368213e86b146bf0b2d551626f9f232814298d11c2c6ef77b35db904adb6e44800be1f22dc558e43b81ee55cff3a4dd0094674d575f202f7b48f366e18bed319719cecf609688475fe9fc106f5fd712adce6580d08895bbbbd4e85e428075b37c7ca2f2da306276ad54ec8fc023500b25205ae985a4625ef0a20507fdf075d5325aa0e245508157353e07cb94b1563b854313bfa26f9bf4b8be88afc8cd5a66d955e81baa70d080b930fcdbcd23453c142179435fd70ce2ce376b14e8256b2e62ad180fc843567e46d209291bd46faddf3a8acb76c8cbd396d44c0e79cdb8b1fe21ce39e4d2fa2c6b192a1a45071883902ce5421eae69933b2584c33663b2d490412822a987b79d120bfd13105c5b790e49515b41f211790731e512190f2476afe33fac22848e9cfa6b835f2c166e55ea79a62f970a261d4ff3e4316469153c97ec6a6a2e3a55b03ee3840c37d5caef94d3bba2fe1ea2e9f24e54ea5af9fa2d767bb6e7edf556f3dff72186fc5a98bd754b4af936552760142bbb6438b4e0d0aa8141477e58dd1fe3041a6c0cfb352906bd1b457fc6f9d5d5fd81780ce61a59d7ee59e963809a0d36a89cdcfea28326ad03c8894fa72a475bb6ed0d955d2134c34e25a82a30aa722258154f367cc58de0d50395a4fd36dc0b5fbb11358b11a5c246fb3fb30e152b5582f6a036348f23d10e275508a694e0a6fc2698b7e46b411ba675c9e07eab0f195c254c856860250682a738fe1f12664c8b5748109aeaf9411f8c37c1f8977fd4ee5a8df0b389ddac9b2fa5e06a66aee020a7066e5f858c07aa44d30493033927a9afac68ff287bb80648ef77f807cf3d9b3d818d391a729604c9dd93313497bda71436be9843d2585fc0c6379cca46ff48917c80fec732ad71b5eb2620c89f0730f65c051fb743339a95c64df012f21fc32bcf6fe09d89ddc1de96652af1181a366fc83a918df2e83c9db0a1803e22c8115961dfa04ecb612e1441e5109f9074a4ed51664dbba02e29673e736ab2e3ac359aa7e59d82b1f00cd5942c74a0e6daf9170e9be8b30128d448a67e07dc026a3eb9e37893b6aa4be0e87702121d7b25331b320cb761fd1bb502e4ca1ce0a9cd73235799ff669a338df2bc23b57809dce3816a35b39d789f0f48dfe866d56d1ffcf8181b225c288b71e4ca74404559acc8941675fcb931398f8907dda7a93a9024c2e3a25d5974e921643413c8601947de646e6bbe9bbc4cfc3f7d55ad235418b67d5425618e924d56376fd12954b679ff39c79cd62f104c77809423b1f614bf9d87a39490004d732024e174496563a299b0d5d1438d1b8dfc3ab0900f0a65b2b1911feb88ee9bc319bd9b6a6885e76825ad17c30dd710b359151d6db962aff64bfe422bee4096326900276c992a11f4bbd80cd92fc8640b317c8e9415ccbea921a63bfe3d67b008b55577546e0b1571daee3fbf0856fc833032159120c7f1300443c31d1cccea1a063da8312d0694c8d1229e47fb9433f7c1c8e4c3de1c63b3e9ac72545e81b06689ac1a50accb36a340e3d23fe3e1aaf73a9445619e35a10f2ef6fd46daa2e5dc59c9bdc82473cc930c2fdd68695fd1dee82d588cbf39fe3b138d55a205b6f7944de1899481f0d7ae57641f55b9740156dedc8b33a9a5b1fec13b88950a7ca82fdd4ab6395cc653333c63d5bfe1902a869d1ee0014d6da3653463a88a73b7133e7221571531a2bf9298a80845c72e9ac17e5f267b7e2054aa16f1d2d9c5aedda0189cbe590a0e8a8a1f488de0e6ae99d14039201d7934a9224f8b628c2b4de8427102b67cd1ec1eb18c0fe4ed620ac8c6462e4cd5326a0a117716d45083a4e815d7516584e0320592848599b053fa6154880975b444f8023f4612c9576e51f990795862ff5984e17a278988575d42d9f0fec98a1763074b9d3102bf43c9a012b3a10b6c427c1effda4cad1eb3469c06c584ef1bccd79a14cfe7c05d1a196f3483ec27f22bf240871ee1d489bb84fbfbdb71f7b16b637e511dbab8775b5471e05a18ea730b3a6e8500921b7748ce513afee246a614d8ee0b5fc102dc2d08870e6c2aceff23cdebe81105502eb02c72b5d458b8dccc3b1c28ac687c6c0a59c79f21b6e81f1007420ba502d0ec22cb88f109f44190ef1b9603b8297cd8fc22f8cd1676225a9672f21d3254a1d38268f7b284f7f0712c013b2bb335ac368c0a24dc6feca221904b5c9bab846ac33fc4e4fc33b61dc84ee90d40a4595562017a8b6782bbcc112f8b40ba6505918e3d457969620321a004f21ca800434e24833a5082323cdda20093a9bf3c9955ce7d2ee985acdd874258d4ee19a0b05e001e63584cfae483669015040ac4b75df9d40ea264b0a13169d07962b88101607a34752d76db8120689724f09dd0901a2e219bbb3ff01aa82cf4a67ed713e2e5da765043ec0bc5d96c7c8e9bb69c3c7c06d07da23b5cb2fb0d91fde65dff78b027ef538eb41613de940025b9527c9fa8687057b455a626a3606eb38518ea3bbfd0e347855364f3ffc50b86eea247c301da1229d5b4e61ede1fb883a24915af1e598f5d8eccb0653b1609695cc3915861fd06de42c0c20eddfd495c2f15bfd60ff7572be1ce795181c409e39241ffd9095fb1cf52f4d80ad2e1c69de1d466fa45d3abea4e97049c8fe49b220d087d70f6890d5ed52ca1059f35fa97b53e93aece5061ae35ce0443d625f8667599678670b9d25dda6f7169629bbec45c732a01b69413ec8aa72f0517369d2630db46dc1267a5e95223e379b0d7672c34a74122c52997c8d6a36efd864d9ccd2a537f7206f5787cfd44981afc4a2448ba41d6443b1a94b6cfbd46ce870de2441e9cc81225494f54fa804cc0d1d1e5d3883daeae5f366eb4b2aca2cf0863e0785e0fa2ebf0bca9af90037f124f1d556aa51c8234269e2d644fa855800e3c1d35a3a713500d8de6f5155abee31554f24a966df986a9db4aab342b3a0d5a1f3efbbbef8475a291b3752efbc1f1613bf013f5a932fed63da87006a3b21c93b8702f64aaaea4947427b56d019fcc29683a9fe128e0cd0a2edc8b497961741a89722a9003e1bc4fbf764be94074cce0004daedc0a0f20a5c6e48afdb56048b28bd2d0eba585cfa09e63758f2c67600bba847dfe6370c18a6874532cf44c86f4832728bbc118c1c65bd5e712b5b57df66dc05de278045898938c0fc61bc2bb887350f71b7a36048a9e875dcefc3597d82e0cc958d5b278879c70ebd9f84cd05ab7f93728708bf4c97d04bd0bf3b9df43e242f967d6a93c7f58725c4ef532bc2fba447995608c08558578aa9c4d48667e0007714229247c36320e9131741ee81eabf6bb8542271ef80d0356de2ea61c001db5bf38a9a04223b7033a46e4c415be906fa6a7c9bc17cc10cde2d3ee94e6ff7da6f0c60ad288c74c04bb18842966d9ca6575b27ad1b7e70480a578ecfee97b2f4f9ffd243d5728316940894d54799eda83c05409c91d6733791e227f6428b3148e8d137638595b887d253c5d45f82b71b04d155f278ff10812f99ca44f0b77bfb00e072905edfd06723ebf465184e8f7852996c5221c9bd41f1a429d4da867752a0362a323373b4507ac434a4d9a02554811ecca48b2db4249526050ef682b79bc9c267f24ed0157a9c19c451f22fd3702c203f1318ddf80425d52d52b0f69f632ce1a953412dd3d28c3caf0c2aaa768a69f61d16c46f5bfd14df8487194deda3267f5d6c47be3bde875ff79622d0d0dfac506de52685ee8cf27685ce983b3bd957127dac154eb50262e7eee14262eeed9e981ffad0dfac702deeea77bc4261a50c5bf5572afdc75681152b5811d42f4bd79f8ccca4afa4748f1df0aaaa083506ed341db3f220ab0cda3c9ff44b4b9fb12ab44adabed5b46e8bbf15f56f560c35215a2a44109e6ea512bc57f53a45eeab25215762233696390931fc95a817ab82aea352dde9e1ae7288527756f595803e76144e5ea547787833ac81cef0862a5fe9f41acb15abfb6693d19334599267b412b85c81fe574eefe68a4593cf67827762767ca6987c55ef8a5c574b362fa126f8b49c1197f0665e4974157b452b275845915b67f5305709355b27a86785e9ef66c02b659e7093e78b3d7551732b11dab2b2557da5f58c7d6dd5791fa2087b48744eb5ed91c2c49ec0e32b9fc17609e3411ffa1b0f76d919b5bde05a4577f6d9577ba98071c509323a459c25954e1f0f7ad0dfa830b284f08e2e6fa1d5faed5dad92ef1c48172379b6510c2419c6be7c7a8f4bee9c2888ef0d36482a7f20faf61a3f8562180945341a8eaeb341988a22b87cfed6987149108da99bb028899a0912a9eea0cca9d57e097b4d60e7a48635af637e8ca17650039a562663201f790b1a34476ae9c57c7fd1eb1608f5903755666a7eef40d5cb7ab1cace242bbc2214f3c26bcdd2b29beb8bf104bcb4bf5fb3d6035372686eec4516e506d7c095bceae9780e10027bf521d581c9adb743df7fb31329f0581bf8d7abb78735869b7af43798e27c45b04037c32a43999fa049f5285d162cbe4cbc91ac280ebe65417b1f147fdd6a858a50ddc3dd8793e9f9bbf3bcb8951e7787b1ba4bf082184d7f48e554c2d012afc2c95f0315019e4303eead910c1cf187a1008b02137c8f0330c43a8c0b224c0940d4ac999393e0d96e26408a4ef008072019031dd51de291029195ce6996de8414691f0eaaec3ab81c08af4c8d39a60fb33a9623e4ade11139f257d6f3d82ecc9e2c8bdf0fbd1160714f285eef0838b9270df0c58a03cec1ba88e6ca9171544f0cd2ab67a87f2f818f649bf704806a29b4b6161308ee0a00404e262dbae7f24fb81e84b292f69f67e67e8144570958992869fde663624223dd68cf4c0409c77ad4f6c2cbcfe16f64fc655535edc93d6108907ef1441cb6ced1fe4925101ceb6ba08ed410acb5ba9700c61e6b72c6124894d69ee19447562a6dc9e93ed36d41c36caccdde4625e478e998a900692bdd9eb85ee08c0eb65cbabcca2d52bd39ebae7cdc5f6c3bbbbe52ad9e55ada72d3e7d2f0e70e9a5e1481f2ae140faabcd286dee7dd2e06c5c8798cca1f37074bae3e5527c9f54c4005f8e95d327a2d8515a4eed77f7770bdbdb8efe2d97dad05b06f05fe75151f7bc1b51afab2166f362a1dcc1c281f5150557f4810d0f87f8c977408742e2624c20570bc9c2a6e8ecb0a4ea0aafede077e0b127e839820849b8a9d84fb10a06993acde8086b97bb193315451a58e8745c8cc3a7f05b979da197cbe4f87acfc98ccd8b7c67f5edf6eb52e7fa28f0c5ae0ac9278084d32a9ff7c28a722a99aaa115a4972742605a5edf2d2022c58d3378c9d4e722bd0a77a8d2046a398a5c929a65a119ec271a24417fbf0dc35356ea08c3feeb162aee05dafbb5aa02380ee31a5b60e431e23a8897b3003fac839458ab86c2e4c1539e4e7cbf16d59d8aa75fe419f71f5de0f5fc902eac896f2a00d42ba8a3dda884254020a77727ab7320ef409b6815ab4d15b9a220308740e78cb1971e682b5fe2c8ebecd8a7a01827d51fa18774bd899cd1ac424f43b48e2aa125321ef9beaa68f07f0c0f448e35b67e6c60e33bd97e45fa696256a5099b94ba9b4da813c54503d28decc0a59a404486f3a46d093eadade94a5c83fc4804ae38811c1a805094550e315df2162f3880af4bfa9a02ccb266493ac5dff810a22b65d713d353b46ebbffcfa5a71933f0ec9559413454e18042769bce7c94405efaef9b81c48ba9ff6109d1bf375477b20d2ebef9f8c2dcc3e0cd72fad55d87fb133c121b33273d934423f9c27b44d388f784a94ed57248ab6c304248acc471e6a1c20fa7d478055ca1630efe5218193f45d6aa63d7494d734069976d3564cc9aab38db0af1fe6507ce852c940c8c1269309a7dd545a1614c934a0d31b8290059937d581d2845c7c5ad5e699744ba72dc7f1754d33c2c971f0263fa524a26e4fcad09fb0d11fb4d88d6b21230663eeca9c89857946334c601b4bad3d61fc2c7aa4440d1ab4ae1770ca8d1cd98db2bd58708e5251af305609b30f4f35d5f446522f46a598dbb836bad2b7ba9ea98581bd17a5f9ae9cc55585832466cb877c4cc3ebc28cc85129aa161d8afc9807a4c05fef417ae90983ae3fe2c5c634d8e3449b51ba091a980f5dacde9f68d330fb3563823e2d9f83a80b79e636f40c71bfb1c7fef1cc3e07394c02fe341eff24a2f26394966073e5c54b9af60608fdb55276079851ed3a5b3d6c7defd1bcd6b1bd651dd2ce2a4b170687b59a8ebcc3950b832e06de4c9974d1f68ee5ef499878b3e557020a680ffcb696ba91f541fcb51e6f11a4e226dabfea7661f1cdd0e48d09ae54229518990c7b4a076f611f66816909037ba1c6be3a1a212bda4e301eb18081ac6371a0a858afeb705b7cfef9dfe48c4701f7d517d523cd6d211c82d984fc9506a560fb728d14cc0e343e1fd53f77f54e58312a1639cd79b8d922f48a5b9644846c2ec4166e581779049fa7e843f05f5579c429fdb09bbc3ec433f65142d900fee69037abe1f00f44b85bc5ee3f718043982b32ae03ddfba6062e912342e4920fc0f37b1263600f6342cd34f5911f330fe34042c01521dc7fe8a112c1b614ff05cf05a334c5a09214c9750d6ff5296145e0966f9c8265d5a299c3a76b84121a3b7b3079a9b5b93d0592c2aba9b34b7431723c4a51831bb02813e9d84d39582226cb24e1d6ee939ae2731f709483024a1ca80ba90abe7470e355a697a50d886f863838c42c58754e0b2ded4893e3aa8d200e6efb2ea67ce7d603590d33b79358e751c0c02129a9352a5d44dfe32a735c857ae7a5f8b8397c89a6660c8d4e292c549c68fbfe9f593c756616067d8c5dc61ce81cfe13215fba7682514b5a11e98301e254b227ce26848bc3db294bbb5007855f457a3cf95dd0d394a3bc9215d4a196b6e05ad265fc825c158904e1ea44677874a821a8c3ba150f012f9a4b8a1a78058cffb68b7eb74854454bca32bd3a45d49f2e0c27bcfa7ce3bca03e8bbaec8c947c2269fba9b0b0449831a8b13eb3d8da1d6398263a01440e78c2a2f3bc0f97d2fd6664537982385422443a75f9118b257ba003b6ae8eaeaea74124790948251826398231915b79ff745378e4f637a01d56efaa3ee32b24a50454e66a017c104030694981a469b174f6f373c3c4fc19e01894889ea7a6b623b94228c8eb2762217b90f9ceb6c8ca9812e22c9b6c52080466dd7a49727528f9f2e67a03b1eb69cc467c343841ddc75922f6c49596f43f9993ec66ffff5cd09c968ba5ada2ae323870fbc12238af694078bac25ddfdc40e0eb96fe2438f8f16724666d387ec9f0c52090063467399750469c05adc448ebd9bb4bd538cdf69b4c68921b3fd55492fcfddc3a12bb4b08b20e6753e946913a6410b9475e52087860ea1ce48e675bbca865afbc95a35e4bb681fac4a8be761c93e5892b20613e53b66c46d34767db1b5ae2e789a8380a09f207d72b5d803111de3e27bd2881c12cc939d82a584dc821fd2d141ad74e61413db917bf52a90272aafb21a184e73181e88a28f25c649e04aac6bff4101b67b83a13cd16286386c69975cc6894e744004d226a1e21f70e4eaa1e2b8630ade4e0751992a2c644e95c22204f762c1281002e831bd884172af9b4387d1d9a0a56b1f2a32ea262ba0e5f46955159198d1962eaa039a39bbe550c08ec6af5c3b9e4a6a3236346d95d85f7706c7634212c449cada81c334bf5fb90fc58204653b0cfe3d5f492230c06ac13007246da613b461d57161c8211150781815344980d2b09088b1ac3aff0d933a2f3409b8886007ff406e7e74831f8c5c045c3a4061fbc79106a683c2a41475fa9b13e06cf23bd3f799db4272ef3193d33b0def1054fd22256b51929a5a09930b8e8982549690a5ec44603c2d123a7932c43b2c426313b487e237d9c97f98ded2992f84d61a1a2b04c4173e85d95b4a5cb9817dbd22d4ca9eb18f56dab53f3ec27dd6188ebe1546fd8a2eecad0ca8fa09307015e64586c55930aefb17995b97f32d58b9c3fce1a23853ada788eca5a84cb37e4744734e4ad8b6848e5e1ace0c164e806428e23fe63a6382d1454376078e22cc8f1b29db888ca4c641063df7cf1a8f780968416ef909f4875801a607401d3a90b43dc1469e6293e0856f9f01234ce4321ef1dc27cab94b02d1bfcf10100b3981f61a59210602067d00878c8183243a0f01101510ad310702c9a26d20502394aeeea80f559194fc435b1ab1ee03b5aeeda550fdae74ba4545277bcdb69e25eb13fd42e58056cc18e72b9dc5b479746a99a70c0281c175347baf8c9ef95980c9a84e760b891f5c77cdfefb24b3d39c014ff2e31621bf0e8406f352c5dcf28981d89928c5505c4b38a0541086bb6f7d6d20f5e5f42594781cbb3e0280434f5f9660066161ce144d899f121eea3d0af3d313519270e3304ec32c7df6d46db97fbea54b050a19f7f0869090fbd310bb87b95fa5a351f869200409057d9e2e05a2d0b4bf96837d58a263d8a3fafd99da85dcd502ccff6c38d28bd48bb16e6708c9fafdbdd1a1f510a410b69e24322d501d45f235e1e006b3eacfa751d7d6d77e4ee778681e08c91723df42c192ac7dd47946f9881fc28b56c2b08d40cbec67d238304430b7523562f116b819aa689bff1c7892db7ace76414eb006444b4d56dfcb3b718d121060c34b320cc0fd3d6af60785b6476d43ec29d1ea8e389e0ff535e39153777f547e129c1e2a3c53324d4bb9583ec5a27fa20a44aadce12a7f8f5f24e5fa44ef2d2926c507c75923fd9847671a0abfa77320e91d74f448ddfbf42b93a4862141748472454c951e17eee69fd83a7ee23fe3d82a016f711cbf127e94b63d067a8fe8cc7f89c2bc0f89986ad49d2a260fe75e12f0709f9b9b0751529488a4135f90f6c74904fde69fb65e54f427d58fdff07cb8939d422a04b8dfff77ba2a950dd17a7a324ef1e5dd433dd634935879b32e3f7bd32e22765ac40cf0dad702ac7243a30eb11225e1162aaffce4b8bba698d8c053337ce89c2839798850a8a25c95436efab0e7eae1028496fb7a30f64e522ef74ca9a4f90a8c712c366198ebf1fc55e97828af3ff0152d2648d2c5f96ef0c000f4ee5cf97209779bb9918cc29b1e1158e6400902817ca1bbf752b9a74422b75f027d398678c0c3b4599e73574741eff5c0e8e0dae72b8daaabb600ef98806ebdb1701e0026858084cc8f5190cf5a2b04b4291347e3879bed6fb02269efe9cdbb1ab43d2f3c780c8bfe2b374f11e558d56b2e4f56d3958c0e3da370819547aeb83b064df25316579139e9f45bae62f309e2d05ffa3476a15f3ac9c37d0d995903404ae646a29a8a92b49a97a0c0248a17d0f051c5b8bd4bb97c20015ab4e69c728d7c481a2a9ad1170c3dcc333c25c45c858f9e99c4418b1d42f40703adc04f91c2345c887ce2ca3de7937b0f548d2c3b791740c1855e5d72e82e83b7de99e632c2d670ad6a79a812d45993d58081adea6b9472a200c9890ae55bb93b1d5e875ce057c46dd93fcebe7bb53498f3d2ad3331d960d305b03863d15227089b586b46dc4e781a393dd583fc2278d6a1e473c08de584dbe2733c2743717401894e5e69bb604e704f83f5a2b73006b4b2796e03620d150e2ad5f735b2cf7e90ea3e210f128969910ae0176ef420f9cc2493c7392e5bba3cf0451d6373460beb30afc4d8abc4f668b93bc8f9ff2735aaa8738d0fb208032c28d13344642f0009da433372572cd4716878535d295d8e4de282671c0b0658662a6dd1b9f441cb1d6c9b26113281d200141e05e2db865419558c0d731c5b482f4a6ed7a59596993eb65c23facc1a048750e5c55b283f96bcdba7c78edc8d472a75ff5d7214ec31621f61bad685444780c1613e3884e741b751cd1b0e0c08da4eca33b6855e71b5f3724a138c8768bf80b1819201f204300e4f89f1ea1c5cab96b00086dc7b72ecc724b5a8c84c8365c5f3d81a3bc11826711cfab168d5067c4765441e24f76aa6a3601210c768a39952f82ef8882f171a9cd68a55d42cb917bbcfdd7e122677f880121fcbdeb7b16557bda19ea33dbd66b223c482388fc719efe88698447677a946185762a7690587f9b6775629e48d11929b52b0eb860b87733813aded10b6b0e627391f575d2ea2986c7f272894d37623dd89f399809a11a0cc6aeefa5574d6a300794bb38b4caaaac3f61929ed1059c71a752c694db8d6084308d16f4fb00b3b950e001730f4fb50ac76b085aa1a129fc632d2f68f902913905d1750f825e2a835246882f5b48ed7f5b39b1ff37f7103a221d19911e548addc647ed3163a5ed5972d950aec9876e28a12095922903061f117194d3b25330df8e529f5625f377825204301f3b12e2f406bd10ec37901b3c49b0efdada301de624b910ee6e643d28502f4d09b16b1003e9e455bf376311f26399f9bf5de79288ad9166ee72631e666a9fc97ffcf9fb92c3dc7467b6b8bda8d65f72d3ea628248c2d6786b697a036c75aa6bdb58b6e7d83dde9594523c110c0c3568b66fec41e56503b5cc3925d77884412ac046590c1049f28991051203448c08e4880556e4c040e291d151791b4541cee7d41327b59f2a7e6206eaf15c9849a217179d6dc136b8e1520d682e29eb866247ece9a7be29a8338fd56f1979a46817c279258f5b1da8a2fcb342764b4b04d5a1ec832a565094673482c5632995598d14ace08c83e09c03324fdf5a003ea4cd017f2868e8c74d93c47940bb66de485cd375809b2ec73424bca7c0aab3a8c2586ce299f768bd594ac2aa8c5493e744096653a64b5fb9f35ff76b12a7c580c1c6efd974b6a28261f51d2d4f6da8f65110cd311ed9e63d2cba13659573834c0cc4154f3194df0dac63672eb3dbf9bb5d46c8bc75489895a331ce6242ada85dce55e84e30c325758c78274af7ef5e5e67b64a998d33a929b05d6be22fdbce647ea5d7a78350574d9dbc854d9a4afc1279c46e3d350b3b96200a3b6492b2d65444961b19897c29badc370a953be1935f0836f26491d48436d6f25917afd5707421eae02ac2ad81e644311325dd7433aca25b2956ec2dbe40a58096247d021ffe97bf3912f9d73f6e903bb946335d14fe96e5e4912fee9f363cb8b9fe850e6625e9827e1e616c5706b4e5531330a3d27b835be260a518730757f9d1670bab8159895c619140f95c7b4233711329328a802fa3d60d0048ab0a247082496b4d2f7dfefb6b106a2db36b88b62660aa976a734121259ed4e17257ededa1356a3d841aa2b39f222273f1105c8ea20e4d473afbb79f08c757709b8359759c148ab0899aadbf89a60fa166ce0e5ef798e4824716163990f5fb1b36fe633a5a2c0ea5796cbaf02acddad179f07397be0fa5435f80ad22e55afb73a25cda81a994edb0208b550bb499d1304d61b4c7ea8f8c5a071a1a0911e86ceae3a5d048ef276818a690a6ac2c3dad61a1f944bc06cc0ce2b9daf205b2590db35044c092867a25503aeb371f64de26251a0a9970616101019f2ae02a859adadf6c75c19b1c4ab367a253167d8fd41848916507d1a1bb63c6930ca041064e298be3759a04abf96a572c07e499096fd3f18d18817694902d4850b380daa41afeba3a7d584ac075be94a45cb174dd6816abdf88f421523a5f50da7fd4107aca5b9ae0249c2fc72cde15ee7851bce697b40c8b1bf10738410395e1888b635efa612b320df86c500cccf9feef1971524ee1a79b177205f7c31a10ff72e70f8097cf0ae09ec64bc36f023fc46e2d8cbec766ec33ebee36858c5b04bdadea42bd52b0df8e23da71948d136b8ce2346273fa0e0a774bdc5cd2793d3a4b889ed92b9766562c66e0efa893b3f79cb4e1f6ea88f6d20d817605d9372db63cab3409c0f28636a81bda3a630a34e778de244f0bda1a56cd2bb54962face8c208c4db0e6e96aad91a5a28f9b6260909869e784f5e1c3d65a411c28b23dab19b09146884a9d59ebb72210ef82050970e686be509f17cb35c8d33a8eb1a2acc542c59d08c4d6e8ac098f337d4b0b8dd21ff020b99d044ce8b576068c456ff7bae04351b0a00f36c2d02f0d867d8ace078c907798f7cb7c05254d4d13204bc65e19bf6b397acea321c68563ca1c2221c15c807f323f86c0e97dad9fa465879b7ae4916b4e2c6ef2520fd613ffa827d148fcdf800526dc604ef8151da1cc5902d042dd15896f146d5756e0f3da6075502fc8f50696804ad7eabe6bf3b9a8f6530df6ca1d3fa7aa71b8aa4c56b52d03c665ca7b3954826243489d0c6b68cfb755be334f37ebfa5b132bdb78491ddb338db7a7c6edc7a2c5670079f18c472c81584ef7f1c121752740994db0e2903caf4b119ebe4041824897af2c0ae7c31a991fcc2df3f09c735bd884b612ad4fe44b9515e390f277d2a04310ea877b64203e4210ec6d72573b7092d5cd5fd6263ba0a529acf02e9ecf759a11b6ed3afc959ad0336b656779736e70b0ef351b3ec5e3823772c3ab1912ebba7eabf41fbe246edca39227ddf46eb4b252b8a82e75ea6114fa43f665e0f2aa7bf079eddffeba00212286c446b10bc16b5269ad37a8e0155a4e56fc03be7002f0e6d28a77026d6029c03c7deae49611087f19950025cc4386c5bdca7e344af5a24471e09ba2ee1c6ef870bcbbbc942f7a72df5e70bf43f0182977b5ee61e3b9da3382d4c905720073ec97f11c076d296e656507e78bca1776e14e1f5e21c1c210adac8f64890f6ba672983daacecbb5045a1c330d1c7ccd0a555018d50dd8cd9d7acd0261f1c56ea633281b41c89b9487c5d7e63b2d8c2c39e685f2c5abab7591e1b3948e61970da2de424ea2421ab2d92d6d74b22cb0683b5bd5597097b84d15e4a440f13402da91fc5b4eba34be760a262a4da2d65c171771ccebdc5e7086f4fe489d1de1a0d45bf91d07122be0a2db9cb408b68a0a41c879f7add366f6c36f44228e040fb04209673fa5ff055f8e091fefe019ba2991ba0a459859d4b06ef2f2082a03651daec5269a3bb2de29a42abeac9d522298c37ad2a2183b2ed33d4c9014117927926528005d40f2158382008df419e1839e881c8c8f1ca183985ca56033861e17da6aaa7c59eb522d88d2cbd506ddd733d0777df56761b3a0d04d4cdd0e84a6484af628b929816ae7551d449dabcd1ccfbd6594d7aba9edf62da4cf6d93c76d98eff4d3a439bf648d3ddb225ba6dfbc33ae4591bc23ce9e5dd8027a9c54645d360531fc5e6d56efbab58d6a1146c8ae5c609a30a176c6ed50467b522cc9062d82a8608af757c776241d92c3de1aead0c930a1e44cced0695b769b6965d21523216b27e46d06f466c454a168c2ddb5b22b9d0d86b2707a46aaaa5a5a9f95e9d0b8c19be0a57a9b472832a7d41680ab762e04f0261f9749a36e102af309b6cb93fca9f0a356d7e64f89c5742365199fbf3904b9b36b1b114065b0038c7cb4e543cc6a42a0854cfed1bf6c66d71572050930301354ceabffa9e06b0b05ab508f0fea1a8c04a2d2a5c8f1b5d592982afeb5557676a4fc7c0debcb40992a9a888a253c3ffdb2c525371ee28d295e4c4d54072773500a0a635b3eeedc7cac2177bea7e7ebfa9cf7dc116bc3cd10943825d19a1f1a955bdd9c81c54fe3800e1afc08bca6ddcbd1f74ded79b56226763212430a90dc8775c61aee5c3eb216a181acce7bfaecb4050b0538ddde85b905ba2bb30c7392205911cb7cd6b94d154dc3e61b812c9e163270545c47ba68d4d6d4bb7d4948ebaa5886529da02f00a00006d6b42777aa39cdb5b31e5cb613c3c6909caab1ef9340511f2d3480953829c415e1ad342fd9aba77d4c4a6149048b8784b98a0d68655a567267c18146a4a5a78d74f254b73c94cdd846fee077d12600baabb9e64b07d36f20cc51c6c7c4be95fc82955ec064c99286a7dedba8dba09b5b17cccabd0f6052526413d98e502d28e53212a056024b507e5cff0743e22e8027416e1861cf6e49f69e69da5b73552134b6c274b90a2e76f8b5cef0b92ea47e009e29e71de7f165b9418853cd0f6e34c2c642d08148cd1e87c5ba5a799c942ea3b2418aa3ac2a152efee1183a607a5870c396bad9c2e053d5800726aa7b326c1b06c6589dbc6926537d773cd7e19acd056690b3d8098e4c6460d064be296f0741079f52f9c25085e8b60992de87b2b7e4241d1274d9b0b161eb99b648cd7b32d6ae23f365470e50010acee7b43a20e7ae1cafa13cc736541de7f257bc10cc2e2002386a1b79ad2cfcfe232b7c270238eb7b238e09603de7ff2d830f2759490d59818acae2ac957f844021a4d518babe0ad547e2397d00de306a2066f25ebe39ea7c2cdace37a2556e7af7ff61cfedb3a526b240dfc64ac7e6bf563059fc34cec646f00bbcbbdfe68731130e04f3429649eaeefcac345385954ddc23d49b6eca032ee55af8b96a6247277d1fab796cd0cc7b956e6284f6ca7a2b87c4dd146721e8a1e4544bf50f1f9c65d78924894fa15143749cc945b24e7d5276907dd818ae5a5eb605a10407a14fe1b6bf841f94e78fad3fbd1e58d8d84c8b2d8e00eeb5d28a4d84c1c7ea761255ee09a8386497a8ca8d9bcb06fbbe5ef59a7bef82cb34fb2a1c6291ffbd2c37d9b5dab848280ae54653147c68aac842a108f3cf76ce2758033bf6083396af48f527a79b5972201320142d39c0e0eaefe17b37370e9adba9c015fda3e4d304389c9001a49214bc83f8081e92471f5e568d32e577531633bb170890d827f2a61e6651370effec9758b51c5bac0ef5761b7a049c2eeb3b96be96f17d6c08cb7657a3edcd23c4731885bc563d9faf3b06cfe55332d33ca0dc74d8d715ea61e82e62bd8ec45fdaa047c8d96e0aea01a7709b7acc2fd899ad8a885fec54120efe3d0dd50c79b0afd555edc4d9c95839b59da307f77a411e451e7120139676cd9e29bc763a442731f10ca3333a8103f0598f07d5b30ccedb2f057665c788fd5a0f18b67121452fcba94e9ca48cee0904c239933fec7a970a6c4e20e53767c33f42883e822dca3b8fb179a68345b3db2d91e4f6fb4ef5e1d6fb549949d746cd370b6193b0828ac87bc3715ce2a89e5af0a2c7866415a66d22e26ca3723263d5cbf4c12e2ecc723b4804a8c028f90b0c8205534c7d5295d36212143d4a8b390ec9a4b78dee7fb1fd399fcd6b9f2562eddfe492b565121ef5126583f5118b03cacfe7e81c04c18c0ab613e277493d0e726c66acd171c6a8f9f414ba329ad924e7a71b362919e06d23d5260d9917700623ae2aca4dbdd5f7892940d3217198680a655cc29351b1800df65e646b409240ef18b3ce1d871292bfb7723e04e603547e7905c0e925956bc7cc0670868c57fd352664d291829b778570f5fcd20304b7f0472a220a68c59fa9220010883bb0ed6645a64c75b780c1ffd3a4518788b1e4c0821a489c67a1702270ab05a1db9c212bc06042a43f7a7551050ca6a3a92e136a6d34ecedb9ce91dd4cc020d3a7b3df90e7796437ee16b46ca6f1bafe4c8fb71e1586168c6bc0ee325b8aa86ed485b517d86bfbef5905dcfe2766cc56330d00d9887a2ddbbdb967b4b29539201c50a100a430a6d4413d14374100d44ffd03e340f45284841851dbad53db4925ed2462d4433e922dad547b49356a28f9a8986d24ff4ab55d0517a8a466a2a7acafb03bd3fd0d3143be9fd57684db15ff0fe2b184db1a9bcff0aae158e8494a490189c58e65c795ce1f4c8a64ed7dd30b9abb37a57593718ef83bc0bacc327c127f8ce824df0cd84917c73814bf08d0593e07b098fe0fb0acee1db0a16c1f716f8c877156ce41b8671f8d60287e03b0b0c826f1be00f7c63816ff8ae01b6e19b0678fcbe027be05b0977e07b069803df32c01bf88e01d6c03715acf30d039c81ef17e09d6f2b3006be9330906f17e00b7cb70007f9ae025be07b0ae6f96601aec037151800df2bc014f846c201f8968227f03d05eef996024be03b0af6f98e0247e05b05f8e71b0a0c81ef17cef94e017ec0f71398f5ed0476c037142c7e37816bf86602037d2f811bf07d8457f87e8219f0ad0416f29d045ec0b713ccc237129886ef23700bdf4db002be5d5800df46e019be8bc003f82602cbf0cd0413e07b085ce45b081cf41d044ec0b711cedf4060047c2fc142df3fe0037c2bc12e7cfb800df0dd037ee19b074ce4bb8587be0817e077c0303c0a30d1ab80877c0a38866f1c9363b00ad905272e1cb9e0f250a7bbc027f8ce8275f866c226f8e60223f9c6824bf0bd8449f07d058fe0db0acee17b0b2c82ef2af8c8370c1bf9d602e3f09d050ec1b70d3008beb1c01ff8ae01bee19b06d886ef2bf0f8ad843df03d03dc816f19600e7c8875be638037f04d05ef7cc3006be0fb0518c8b7153803df4938c8b70b3006be5b8079beabc017f89e8201f0cd026c816f2a7000be57802bf08d847bbea5600a7c4f817dbea5c013f88e827fbea3c012f85601cef9860247e0fb8559df29c010f87e028bdf4ee0077c43c140df4d60077c338157f85e02d7f07d84857c3fc10df85602b3f09d0466c0b713dcc237127801df4760017c37c1347cbbf000be8dc00af82e0213e09b083cc337131cf43d0496e15b089cbf83c045be8db0d037103801df4bb00bdf3f60047c2bc12f7cfb800ff0dd031efae6011be0bb8561f8224ce477c0431e05b800af028ee153c0442f83bfc6dec7609d8c43c543c751c24992565cd97fc6cb1d7b66234e52f677c1354515dedf85a329a6f0fe2ebca618bebf0b483a4d497010a6a9e38ff39aa2f41ed988f3ea91e520310f0749c241a804515ab5c62049d9bf6736c513bc7fcfd31475787f9fd6144df0fe3e465344f2fe3eae2996e0fd7d8ea64882f7f7794d7104efef8334c51cdedf27698a22787f1fa5291e797f1fd8148dbcbf0fd31471787f9fd81443f0fe3e4d5304c1fbfbc8a6f881f7f7719ae20defef339ba20defeff334c5f1fd7f5a53f4c0fbff184db103efffe39a2207deffe7688a1b78ff9fd71435f0fe3f4853ccc0fbff244d1103efffa334c50bbcff0f6c8a1678ff1fa62956e0fd7f6253a4c0fbff344d7102efff239ba204deffc7698a1178ff9fd91421f0fe3f4f537cc0fbb35a5374c0fbb38ca658c3fbb35c536cc0fbb38ea6c880f767bda6b880f767214d9186f767254d5101efcf529ae20cefcf824d5186f767314db1c8fbb362534cc0fbb39aa68880f767c9a67880f767394dd100efcf9a4d91c8fbb39ea65880f7175b53247a7fd1688a31bcbfe89ae290f7178fa608c3fb8baf290ebdbf8834c517de5f4c9aa20bef2f2a4d51e8fd45d814f3fb8b4c530c7a7f31364502bcbfd834c501bcbf289ba200de5f749a620bef2fcea6c8c2fb8b4f5314f2fe40ad29aef0fe404653047a7f20d714c5f7073a9a226b8a39a012ef9758a11fef0f8434c59ff7074a9aa2cffb03294db1e7fd8160530cc0fb03314d1100ef0f149b22cffb03354d31c8fb03c9a608e4fd819ca6b8f3fe40b3556ba5a4dfaaf09dc27777ffe6f53744a709867902dc33eb79f269f918f9b87c8e7c5e3e483e493e4a3e301f269f984f938fccc7c967e6f3f4d3fa31fa71fd1cfdbc7e907e927e947e603f4c3fb19fa61fd98fd3cfece789d56219b15cac23d68b85c44a6229b1602c26568cd5c492b19c5833d693d8128d44977824be44243149541261229318139b4499e824cec427a0169011900be8080809280948090806c40414036a0292013901cda4e4fc0f6c64857240a0d7d4f1308fdcb97702bc72e980574726c0ab1712bc422a015e259100af94468057b01cf08a490478153b82574d46f04a86035e398500af6620c0aba70f609bd60dd8c6c8066ce31ab1cd9107b0cdab03d8068903d8266903d8464903d80696016cc384016c13bb00b669b200b6915500db385100dbcc26806d9e248079b4228079184100f3703d00f3387200e6f1aa01f3406a00e691c400cc43690198078c06cc83490198476c06cca34906cc435604f3704a00e6314300e6f17400dca36500dcc38808eee12a00ee7144847bbc62c03d9086e01e4930e01e4a43b807ec05dcc305dc4308f7c8b84710ee4100dc6300b88700f04d0bf886057c2304dfac806f5e53c71f08df88f82669eaf8b3f0cd0fbef1c1373df82600f80600f88607df04c1374f53c71f08fe1dfc3a5849cefbb0434b48e77f6054f73755e48f07dec07062ac990480e3c4be213c5833a09714c223fb6325dc51c7c33f9ae48e035101d7a4806b425c339b3a35334d3a4d78bc196f96b23f1724297b79ec998d2b40c92b208d728b2b7290588d1111770432d30444364520b29e2fce9a0f44d6f3a567d633d3e1e4ce3c02f1e103fbc0417ab0456b5a2536255040dc9c1f6fecc63aa61c0cf434753a264f4127cce9903aa40ea94352e24acfb93879d8a5f0a3ed9c1474c29cce5c3c747066268c079cf03ec0150d3e3ee773c0243ebe48a8d3a1bd56ae1b185ec29d79ec2317d093877de4034b21ff684009a100f4923b2923ee4cd314753efcd1e6cc34cd34657f2453d4017b426b7340b067e6c344c7d19579ecb9b4e584e94781e5cafe27e0164a8865d433c3c90d76c00796423aa85c10637c93a07a36429e28b822eeb87265ff956b8a3d48903afe3d6d1cf1f0caee1344f61f5748b967d633cbfe361828488a18701123dcae2106e9f6637151299a710898c185145a720d4138e5fe22525cc9fd347418bd038a2e688a3c3ccd33a3f2e256a003456a98df0f3445ff1a29772557f2a78e8c79684809ce04a1083746ca954850a954ddb545611c114ac8fe34ae56ab7514b33f647f159515e144f6df3167ad564b88ce05d95f87acd56a2dd1e2aec8fe3333081d64ff94ca458590fd73c85aad561134475b115eb23f8e25b4974c0fd95f06d66ab59ad058816a22fb5f57abd52282c2b429d93fa609d37645f68799b55aad216862b48becff1151d3a48191fdbda456abc5c41838ccc8fedd8b66668df892fd51466c43647faeb51613ae1a174745f6df642f1a647fcd0824ebca92fd6b1134495b11b02f8dec3f5daa18e7f292fd3d05b7d592c528c9fe4ded109e8b9e104d762b4da2a03946745d51f70a9d742bb2075c79590f97acccb21635c82d1dd0c929cacb53b71c53d3b64aa7f3f800b5d023cba51712e6189f14b2058ec46d1d323115060b8de95ca7ab54d676ad39875a7f6a01c3460e354f2d29207c168a94d4bdd6f546d5f91539a3f67b77576fab5bddaa3672997a746ec131b9fe23cd74e61bbcdc4d867645b372fb9750b5d142b61eb6906516251bb99327b822a2949e91456730ee686bedda0d1ea9be44c321cfee6debba5b6b7c73a079db502f22a0665f67d9a359676d9a1f702ee5cee5b0d586f4f51ef5568adda3c0517b0ed49a7bd4771c4a4369dc731b889489b45f6d5f948bc026aec548b8f6474d93c91aa861b0894b1f23e182fd1c6a4937440b798239d43c143154932b8f15a971e4a839bea10ac543a7b41e79e8b5480869eab8c54542314ea0949c25b9647f2a1efa5ccd496758384b662ed9514a954af60aa3a24b1eab961a6ba292fd7d76911d45c559445018b1a0d457279de4b1a649eef7240bd62c380bb24c6ea17146499e61926b8eb2fdb1064aee1f6b5cb9a994acfafd55320d2c77194d72ab5cb9dd892bf7c7dca43c8b5734d824dd0c676f8c0ebbc5c0ecf0b8edd3aca66dda06f3595c24d4695fe570915057a5581cb20c27d40776054872c7a73be19adc85042221714ddf37441bebf4102e77e22e2716903b5e916419d991a650b1c0c4d47a58912ad20489b8da53ef1ba23434d369686868684b9a8ee36181962b944e9ff4b3b14b7dce9fa0778d604954b444e9af2de8240989a7cc05124e597281441350965c348122f737b4e30657e6fa9303bbc9dd3c8efb89e2a678589439d4a35e7e1d6864cba89487dd4f2835d7503c54f5917f3bbab8326b1f348f7427b992ae690f3a0b172d4eb25cd2a2248f5d44964b59bce44e7e433547d7b36cc97229cb957eb994e512d3973cbfa11ad7f51d3c78cec2a9db8833afd77d7fbfc3018e3117cb7ca59491a11e4e616cf31827fcc1b361a0168298b89dbf15919ae74fd01f476f4be86c4a29ad3952a206892b51b3a74ca9b4a37838e54a942c3d74b0b778b9ea77edd5975d83cfa1fec0b8a81fdbe897bcd08e9f54ca8eef9ebe54659855d77d17e4397494b31dc77d4339baeee73744b730bc548e8d76f4da6fe8822b0a12e9668ee7707be927dc5fbe9eede076ff7f7ffe0daad50589d47cff824856f4e96fdf9ffafe8652df6126f4fe44f5d7c982a6912dd31df22ccadd7d5fd4fdfeee5e79df753d0ea7dee21cef5f7fd7611d3ff1cc771dc5593ab0f470065329f3f53bcaf7dc7b46a8efe276d2466dd4af7b713b398a01bd98198eef597d670233839935cc99e4fa9d07da981f6dcb9a8b87f5276ea70ec359b2c34861ee83668e2314071e1b96ebc3d497a9ffdcefa8df75dfe1843f9c75bffe77df771da54559d65dc31465187a9fc67cddd3bf1dfdaefbc6f43b98a7fd5d98eb0eac44facf6873a73cac9f638a3b4a580b1ed62e3d8bf9ef7b06737fb0fa08fd76567f3000618ae321cf05473bda0f1c6f46194d9dfaa8591bd1afa16b53aedfbdb3a42ac71417556518354d2e0dbf9978589decd8c1a5afb970f80e22ba9a252e7d1c94490bdd11bbf329fdf94bba9a23eebc1bb76ddb96ed73b8e6c9f5b71b0f9dc4f1baef971e721cc7d94775b826894b7f4aee072cb4cdad57d7aaddbe8578b4fa12e4a13c74e42952e3e4ce6985694aad754ea794d2596badd56badb5d65a2badf56badb5d65a7f47ecd2afb4863280b55876b3381e0625e6bbee1bc2f15d77333181f1a4b3605ebefc9edf755d7f435b0e99b96f2807b8daba39bf211cef2fc4800df0715fdffd517f832aaf1c2452b3bf83483c447dfd6290d9822b7f1be66beff39f7b98ef6f08e63b0ec72c0ad64436dbe0df10ce06235be65e6e2f3f239bcc43f3a745cdf73a88fdc65d1863d1fc86b21379dfa9fa3b1aafbf2132eff5fd89631e85bf979f91ce6eb70f9a381ed2efbc175c54924a8155c43cfda098bfdf4f3b2626e661bca0ef0797fb51c246e9e1f737a8b40689d4dcdf20120fbfa71e7edf37e6de94f7b41ba6db77c8de8dc2dee7a1fa51e0c4fd28f76ed47747baef6f081dd2fd7c14a612538e3ef75de8f3527e0c33f53780b33c532a9d74298e2fa42ca6d5cf82eb354ddc7e1af617a03c2578717871fd7bc87c87750f9dcffaaec959b1ccb4a9f42eaa5cbbb6e7e1adf5777c419b76b7e761a56f9f49277166578de220ed46290e4866370e5a937d6fcdd0cad955c9999c316d200e36aeff18e639ca598da15fb9bfa1fce06921a8b9516ad4c6591a486dcafeac3818b5825e4a701146964b5c68e1c972890b2819c8ce69576ad0ab810d1424bb3bd22b481dfa55e804923bf4717841813a0c5f60b9d4e4b0548d1c88430977fbcfdc8f76c7d2a51eda97efdcd71471b9b7dca3b8dfc1c31d6db66f55a1b3bcefec719f7256f71dc8bd7defda745c90875c4c761c28ee9c6f9b6831cb31592e65c14696325dea897cea8e75e05252ea137477772f433e9dbd844aa517f8a80b5b2d686b7d0f5dba199d4f4fa2a3de43679db5d228c53459957710cdba614deacc873992fdb5cd7228cfdbbc0f2646c6db6470a452333abc1d9ecaa3aa1d35353014ac7267be0ed9bf7f6a563409a42adb2b6d1e9e2485f4e8e95a6d79aa8bdbefdf351843160bd4b66401a93c050670d81f953512648acaf439a9a33d0baa29ca481dcdc7f0350a665ac1963b9a67ada2b2a6756fd429c3e9df31b38aa6d373516d07a23677834ee28c3cb4bfd65a5ba5ea951af7c7677f6a79702ab6eeee06b50db2e06f975ccfd406da9f431fe95fc9ee6c9370e5a7a410edaf8c14827aed67a410ee3bce48e7a296167969e9298f96a52d1965ed3dad73980be37f93bbe9c96c837d7f2203c8fe4782b205574403c8fe03901fe5715d69c9d049a1523ed194e55f53d0c3910516a410e90d5927ee11eafde8d6b8a32a4f3aa7e8b422dc7ef9396670bd225c34e48efc1c32b8fd63bd922528a5943368425d04ede9bbb5f7aa545a11c56eff723f4eef5178b463735c928c7af551bbdae8e9cbcc498b694c9d06c4d3acedc71f2a4db378b44692643bee902d38168da13644918c0ef3a31953bf9e366c0449de7edcc1c896b7969ebdbef6f2d328784348a3250d18647fff2d5d8d59816515b25cda824aeea651de90e4e99d6c9c46b63c7f875cc722993b19bd417ed1ba2e8cb1fde911fff90d19e2f6a537a9f090a427995f1ab3bb0a1657ce01df07f83d6c6a546e64254948f5f886c7097f029864b5e37dbc0ff0bb8e73e2a183ab239519f75734495e4c41031ea65ce942c8024751880146175614d10221ff9e9e95cb574e5647ceaaefdf90f6a0f7ddd92850dc57702ccade773958b2c1041addf45a87958bc91d7b6640be0319fad31bbb38a87fd64c0ad97ea6e96f8c877c778013d3699a691a6b2b37eee6cbfca8b301bd56ae463dd8171c2b0f73d4619647ee6fa8aeece5b0e0c50b60aa2777ec9971df3373d6d831e19e59cf538f17a63bf6e8c072832439cb7bff20548228390bf5fe41b07016a6395b9b446562e1a1c33c6c9caae500914d1d77a20315933bac42cef1a8cfc1409ab04e4e3d1019ccfbcf34c1701c4ac7d623eb91f570c9d109679d738a39ff23e37ce7de8c6ca6c94336eea8d334d3a413e6bcbf8f91b3a6b3b69f19f5409aa4900e278a99655e406440822401e14431715e3133effa7e04229b69f21a2369c5d5ed34d88f13cb89e9e8e03ffa1cfc48f8933ec8833c45c41d71927092ecbd38494eae7d99616662be99269da6ca431e759ac6992ed93f079d9e87a5873b37969233e39483db331020320f1d08971aef2728690caecc40bc7818489797418ea375c79e59cfcc595e7a9e9c2593a4bbe82ccdd45c34965eea2b6da5b7e82a0d6b2d3a8bb64163d135681af415add4336819740c1a066d45bba0ab6816f40a5a4a4bd15134149d82f7671d4db19de8267a897ed2493412dd24e0d013153288cc6ee7902e1be937ea532d77eeafb56c339d344a972d4f4e98bc1791303b139dc419ef6f3fe7f6a1b3b4b73a997e9d5e0d0e1597fa262b6eafdbf7870099379d8a00995d27f7cb55fd30d3301ca2bdfa8dab86354ca1b8f2fb697f98b7d71a2412e60d0c3d94f6bbb1c2e055fb30d32ce9aa56d0be6efd5aabf69a0dfdfe3668e04afbba812b0d2412e6fa61ae6038a7964e62208a840015e9040938301679b713a847715cf26789a5c995dcb9e75e7dee2bfd6ef35098e6feb68f08f71ba77dc9154b935696585c3315b2c4e2b2922dd1f6c61b6f34a1b997da5b222dd36ef350154be9c01d3ca12a5c7e445ac6abfa7545f3d39fb3cefb6d03b9df304d3d71e56af3f06afb0f86d5f6357b6f3d50d2efbe49942c93259626aedc4d4f07ec8e36bf878365f6de3e1874a871e7d7d786582f7b2967c9acbdf79e4f0f7b4768a609b0bfe1950612a9dca3f06ac889ab3d9167ed49c081a2ed3570ecdf401b3670b585122452b3f6356ba0b53220820c092624645255ab2a25699ec7410d74560dd2759dfef7d9244f5cb384a5d143eebca7740a4324779c620943a38d3c3197fb1b8a8105d7fa8c1e751267dc5a796a524621450b3614d7993e7fd458d06dc1189c49f6ceaa626a4e4da67971d1ce99b32890b5d1601e4eed8a875363d2609a6cc3edf29009b6538c806bb229c6d04a78be4c264d96e7fcc8b81a4c83e5d9ad25d3534fbebd3be79c93ae88660dd9b7e4340a7e829413c7470535bcbdbde17aa0787436deeaab81a18951dd1d520ad1914729a594386a9d9933472a956306870e991d5715430353f3ad3c9b8e07aa0777637fc31a587d509ce952e6c8102675461bb7bf7dd2aae1b1fe4cd597361de7511f7ba8a949e9a594766fdca673ce395373da4c2beda627b19432499ee0d6046e09dc1af66e9e0fd552b923a59c73a6f2cc916d9834356753aa5235f87fe306a5544a29a5e4e6b74502adb43ed1aa463710ddcd84a6b4d64a6bad20a55f68a5b50d5abfd05a6ba5b55690d22fddeda588f649e9acb352362a9d330955dbac9d760661e7b4767e918f1aaa8f9a1d8ef56eea8654e74dcfce4a2d1b95dac904cffb86ea7bf3a394d259b1015a8381724cf8e69c6bc070312aba27f5ad67bf219de9e7e5a97d10a7049497aff33ccfcb32c88d3c2e8f7709aacf66ea755fee603c986f683e4c8c2771a8f5eeb521958aa91f3345149da92703a0e6df6f48cb0b8edce7fa82874ec120ae09304a6512aeb33e14d70327a3d631238568a92e26668491d7fb969c8ebc6ef4b5963b72c787cc3c697feda7cd4253ef1ea42cb7cca8b3d716576cca95171215251893962614579d6885525df5555f354a7dd5577dd51717b1295621d92d39f328dd6aa376d247fd725623394b472ba1b866ca3924f9a9237d3c1c6953aa0f7ff000b5124b2d95553a89336a0fb872290d59463df75db77419ee57634d4a79c87d9d552d954bf710934dd5a98bb3e452109c64fffad4a138cd283bad01c7719c578324551eb60ddca37ee46ce44ebf95996fb90a9b38e561ea4718b95bb26bf3682421fb873ab2a3b12577b6dcac3067515a8339e7f4cf4e299ee761857920acc28cbc9fdbe6713f5f72d7c76b5f9acb8641bbae7d56edb56f2807a759aef36258f7c7304b9e2c7ff4912d83a50cdd679e9dfc66286a2289073594c0520518640849d741bde30fcc21cbe0ce3e26c9f727bec1cb38fca5a41e07c6711dfa32b873fd86ae94ebd998efa3f4439251dfe197bdcf0b5338a187f4df434a9f4793a269952f14a195d2212ce1c7194a724e964b43d881194f2a35ba2a5956f12a597edb209fbacb4a69cf39a7851140cafa846759258ff5352245596c916995de3422095b214b898914699165152209a34f9d94423eaf9312252567dddddd7d73d7a4ac52d2f1667797524a29a59412068653814ddd2c55f2df599fe54b108c1206c4d3cda484278a5af06a42086db8f1c5084c96644cfdb65f85a593ce9242678cdf67e47e69bd68c1134db600a3490f80c045102b34c863981b075344790112962e457841bf6d1d5f8821c372040f5b8c10eae669260946135750e13244ab0912e8154a5071450f4b56f0c5d311da0c26592e99e1946f90e5921950f20e1d3352c836fd2992c472c4539e600e9e47a0ca239256ab95735051eea6fbd1fbf29123f5b7973bf3513b73664ae58edcf1d7b0b6c91d67818233771e8bb2141d9626b39cc3d4c87822148ae1a57a77140f99fc4d3909a9cabbb4a6643746e98e5788aebec4a9f729b7accbe82633eed37d8aa99ebe5c3194b27fcae67a57e9e9c61af6147b72585fb11e35b2d4b65233714a0d9be21634938c1dcbab6e702583fdfa34d85a9f0393543009e8d627488fe8121b485d1a48a59066c61d5d2685ccb1955ce65cc2f8a2dda025289352bbc11d5b297b96206d2597695adc911a512367319194beb4178f8f8a29fbdbe0f8bc5704d550240c57f6a74186e16da548bfbf2f85e28eb23efd0aba93d3a07daddf82877494b122ce1a8168006a61eac0ba90aecb09109a26e51eeea7e48e968a52927f526e7d412177bc1eb99e69b684462b43522ba957c91d9d294f71ab115366b24078657f2f959d364d9da64bb57492473e65ebfd602661ddcab80355dcd1da09bad356ffa66e1de28e96caf7a4f4d06e3147d59c54e53160be1114bef058647f9c1f526c5e90415285a3b2692354fdf881122a553eb81a112efdce9d369db2c1b73f26193e605a529baa12163e70d2db4b9c2e5d3c74f722f3b06ab2be8cf993dc71951317883b56a55e227b75c91d18954d9d0f0b8f559936065227214d712a3329fbcf485162c23e25098b8e22fb85e46192fff8abd0b8da10ee8c32e5e8f6eb45f3c4df7a49b4874e491554a3ddfde3df45b913048a013f68e3a14b9596db1425fbfff09172c730d3f7a7b8f38f6ec15932bf30940a67a4b8f7a6b850dd1e74c9fe291bfa4b70c676a566b76d73dbe6b6cd0dcfb9d95cedcd38b828b92a1c675cd7ab53b2bdc419ebcb63fed3e43ffedf13d7874b655374aa2ddb7fde7b534b3dd8e228372ecc43f797bff2781d094982a32725b9521e3de6310da4d565c57f05a1e28196252f549ffef88ffff683ebb9884742656423ebcea1e48e160ceb9447556bcb2a1e3ab8f3c30c441bc9253090b27f2b69265eb73c34f21f7f1b22dc5b03c61d553c76c0e58eddcab335e569ec597bb957b27fcaa685667777cf39da4cc1dbf570c73bbbadaf06dd6acdba169238a3f370c7965fb28f7e94dd89b3e893ec4b5b98645643a151e2e6f17a78d52fff256176074dd9df4bcd5ff242f4797e34181483fff8a7c6b84c37a66afaec3277f2596cc2e075e0a58afe252fa4bdf51fff181f6e08be8738685c7f9517d779a0e8404976555eca81a7a45b530c99d09c46ce42c910a5a0a9ebbc4b972c33911333674926a31811144a9c05124161844e4e91be10993bc749a611967012daa173812bf9224968871654d0c41142f4274ed22da11d2416210a56d1cd20727024b4439037dac84295c88e8476e01162268562e7c208222041492849f3404593d00e738990f49fd1cb6da5852902d31933a1893b2f841c77dec18bdabd656f60d97a1ef77d55db3c989898ef7a9c8c4c0c97983272c7b8be323e9992dcdda82b19c584d2325101ef2f3f22db0ddeca66e25077b771ab7d1d6bd5be6ab5bbe9e26dfe35db8f9a663f0176bbe972ed8f77c584ab8152d2994cc11bbc3cc1fea2bc89d1db96fbfd55ea485ffa9452d6b9cd393d04b5fad3d6ad769e52e894524a1fa64fa7ee73ce897d4e3a5dd0c9af544e4c29a5537a28d3689f96566db31caaf33e98985b65707c3952333a76a8686a56363c7adc3c067de09ce0a150b5ccaa6d960b9faa9c50a13aef8389b9323872a46674ec50e5f8a46c62d0d4ac6c78f4b8790cfac03901859cb0e64e2705157e8428ec84301486a20a03cf66b4d9c9d9137032b75928d3071c5a2d29751ac9ec9abb1350f0eccc5d8e4e4e18c24c90563a639d4a2585f866a590efb10e8df43ccf5b61489e8ffd0355341cc8333524eb26bd9eb3ee88fc23395c3ce4dfb8a3fd9fffc48d824e5462df8718eea588aa99c35228ccc9dd442177f484dc55efce2085ac8fdc6d60ee2cce1df7b943dde4aeeb913b8f47ee3e9bdcc1ac72175393bb4b933b191c3b7297236539b04a9dfae52a8299191d3972b70347ee5434352b8fb3f972c7c3cb5d8f2e7737ef71d8e60edc72e743cb1dce09337728e4e8e4843014a472a77edd28d5acc0d26272043bea72bbbce19ac11b3d54e1861a3fb8210416b851c614c2e5b25c72a3c98d98ddecf53c5c02113f507bad779f683c3cb60d261c317980787c808e66f51bd26c1b5c9e1c2141315a02d6c616d71247a822822023e6b445f5c1f5b25c22430660908194473bbfb85a964b64a8a0a6716d964b6430a1ca72a98c24e8115d5771680e1984d4dd6795b44e1c77779728a6fedccd10850c2417659bbbaa59b9d6432fc3e4a29ca5eb7088421e573fb818abe571e571fd45d7d539c38a63ad4af5234bf739a79deeda95dbef3e03eab96bdd950643266b953075878ac6db1e6b34372a550f0cfe4d0feca3ce2a637367b5e141a35aedd051e3835a70878e8f0805f0e3883c40751699b1415206bde07627cc03ccafafe323720257a97c26b559cf1387ccc6116d3f3f46a290a3595a2796db9f11ffad0717274c7581a50c3b9496e97f97dbde6e5e8e26c3438cf6799d4ced501daaeb3a0fc5c9d05a6ba51b9d5c501495c732a427640a012bddf15682ae7972a88e8be75032a40f73244f4d861445823cbf2b0756b9435fcb7486f46ba627e866be2cda27adda6639940713a37d5e878ab932d5721d67bbce437d4395fb0a3c0ef7b1a82b55e10f1779a67bfd87c1f327c9904e97db47f439478a4e4a854c2df559b9d45619d65a02ce7e4434db13e48fa866fa1d27db6136b08bb0acda4744f38c26bd84331ee9462a8854f2e58bcfab562bce9730727d5aebdf28727dd50a726d4213720d692bd3a52f3f74a16db93dcbf40b6a63a48c314aa5f2b459021a036042147932a18d3c3fe688b98423f2fc2052c488a1327bcf952bd3ef5255ae67df400b65e848ee745e9cf554a32485ac90e94f9cdae27a7d02eb8c883b76b3d9a40f46f724462bd30e0da34cb5c81d6a843bbf7b65da2d9169772477e868539b34a3296a4f559a910c9a90f6b5698a753675e8ad4d5af268d33d4d1dfad476b34b35b09b4d1d9824eea8198dddcc75b472552c5df7d64dfb5d5b6bad7d59e5f6d6d65a6beda4f637fb6ded5bfbd35a6bb597b5d3d2cd76b6f5ed6b4464abfd906d6d42b6758d6c374badf6145bca6109b39bddec66378bb2288bfa51d5a136d4b6fdb444503f5744a89fa82fcad65a6badb55a140f3524fb5f13ac5247a956553031b8aaa20368dfe970946b4f9babcc34b5aaa09c29c2557d4c984d6d5c393a3a9ab279afbc7de7336b503ac8a64d719dad3556cac32d87dcd9545367939141369a265cedb5bdb5f74eeda5bde40e521428cd8206850cb2fd1685dcd9de82a3f644deb478b8c53cdc3a26b9b369588be2a126a429a5b4b8238f1123443adb1f2233f7db572f5248125208fd6d7bb959d8dcb61acb5b6592f9cecde2b1b3a67deaca9ded5355ee2462df1faf88acbffda26cf34c1af7b396b4bda6b4bdf6da5e43f25e9b14360696278ed6e384304e52c80a795aeeab86afca4322aeb5208dc11dffa7285128d44bab25a32af7634522d7af4db8af5f6bfdea9242bcaf151c35abc5d53c5c3b5c9d7878e4a1a31c25cba3954113fa9ec3a86c6badb55aaf4eb9fef69c7f326842f5adcc4e596b650db4754ef1de9922dcf09970a7dc89816d5cb41145f6c5c66696eb65b9f4c4441e25ecca93ebc94896058f35e2761d71f258411f0f6da008cd0ff223ecbd4034699a9110b5d65a858c8e34adaad668d55a37209ea68ecca06c99fa36d726cbc6140bc5767363daa2550de4f101830d29f22861f408b766b9c4c62b8f36b3714469ee5f9231a1041cc4aad0189a84ad26a16e75a349d86a965b6b6b1a68d1b0620d2bd6b0620d2bd6b8a23b7529f59414adca0ae23c116f654a2715a02b28dbbdb4460eb22c29810995b76890bfbccc9ec09ec438976d058aa7e9f906ddfc7eaf9fb2307ab9c7546e2fe24a2d766390f0c2b49a2f97bc9491e59297a62c2708434ce672980235c278d27af2d292c0450997124c75ba1448e8027342cd40c68b0cd5a21302ad151c29a5f4a7b4b62ba5e0eaca1df95ab6b99dbad67880281502ad1265c925c50b8cd0d4450aad52a402a61e1c51060f46539cb1024df33162e035d0369e5910dcc26c964b3332a4a8546f038436ae4c8932031bbc6e4004a52c5b989019116b92b28dd1020ad3d0c822cb932c3f08820b2b0d48e3288a1856ec808d2fb278f23160a8165bb6251b9d75ce173c84f5c0054f349103298ab022c73052238b0bca162ba818a355c7f80145b31803096dce39e7ac623c594b837aab8c6104ad028325b666527bc4f162693683dc65b9349ba2b2557412c7d297459468cf7d91d0469f364921335248675a93b2cd3229077911d5d4995f050d9b05935830365aa11505a5a0381a8038a62455d0a0fd062669239660690969603875660d4580ea8f612ee2a13bbd01051b2ae2ac1551bb83d6e9942c4330c932442bcb2c42ccb2fc2fcb2c42989151596611a229f77b33c4f2f65d8e2d4d521625e98c588571f12126898b0bce98e5888294042382c2e893a10a6d5548e6cb1db598c6e4e1066a5aba2b7772ac88b26b5770663326ee585adf55efc86a2392ecee815ad34743076ab1a9e39e637e0940e9a034c76bf41179ee26e259fb0ed0443c6fbdb94b9aa1065744796ad19836a36ea3295ad9e6daa06c481b9523b4362cb6d736654bda943658debe7d6a4ece1ab52b79fb6dd498b4a796b3468d4bde3427ed8b92bcf53bb6af5d698d49d3e22c2dd6c4c559dc6faf4571d6d8471a92b3ec146769a00df33d4909e60477c5dd1fd104b597875bb83dfd66a8429bd1d4d95ea60977d45edb7b17674dcdcb6b43e2e1d6b3db675a585a4aed537a692739204962b479287839451474ef3d0ca8cda6cef61f68a74ef79e968435a7a983b22814575f428082e2ac16d39cb424ed3b5cbf5b5a4cdb32c5999644430d11a8c0364315eac03e9271e38e9a53dedeb7ed3527676d14ffd4d95ec33f3cd4e88f384f9a3c65f2dc7e809aa71c5f974979b8ea55dbb4be5f5bcddbd2116079db5a4bdeb2e4d1db8490c626042cb6866ddbb7cfcdc859a3e772d6788f9c35aa5ece1a7fe4edb7df98386bb26183cd286fb13c6e50f286451eb72879fbb16d311e5b8c8085478da0a5084c491c253145077d1a992ccf0842076ae496e1913ee77cff86a09a62b7308d428fec2f5b9442a38e3c7f04879ea690a1cc1da2faa8646cd686550bd590000000088022002315002020100a07c441b148281c6aa25e3e14800d7aa44c74509a49c424875114648c21c41863000080004280ccd4909009a2baa70a73f4727a2732aea493a5e534902f3a488af06d5620212fe8c2635e57636f957c4a7c4fc3e621ca1f1ffc10e27ececb4371fd8f115328fed28f9682cb27e3f328f4b0ef7b5ef07bb4b9a48227a17a87cadac2c1b179114abaa1899a7a076dd9ed73429be110cc431b14b3962b641811929fdb0d752729df0256e49c9bda97b6b0fb09574421aad297ccaf1a4b45f8426aa4c431f2e9670219665dab8b4e235219ef0b61149e5a59529b32ec89bcdd7e08818d85a294db7c4331fde4b6e6eb7eab265be46fc2fa2783d31f8f032ba0f6d06e6d31a7fe902f785c429da6b39dd3f8c82439c64f7a54f52900aa9bf842253c4eea6a06d8bf12c2e90991556caeb3c3ab022bdd519e7a311e5c8028a62855cef74337db77c667335ac2e8be0445df6f5f104b1fd1e763a7f3026a8b53793c6e6d679ef6afa6a3a506f21b9c598f5108858d299e533940382fc8914dfd6fc195f4307a7103e25118d0a3e4c60e16e9a15acaf95ec7ca59137d8f8984f7613f375843df33efd705def8d1402012432e8499349da5e3ac34994b0d1041619aa67bb0797ecd4649a6a57f29c5a4492e805238bc614e003ab92afb5bfa4844b687f7a05b12b0dc8b4bc4d6d0d6a32916f760ad2f2f995b2aecb1c5425e3ef4d2d7bcc0b5edd1c37dd054e29ea8060b8eca7b926a22735fa4db3e3147add88318d7843c758f984d758a1105ffdcff49227b694c66093016ea3c79c2c4848145ff318400e6c585263a282e3e062e0c364c0c5c5c80bb696bcac0ed8ebdbdad8dbb9ddb1d7b7b5b1b77635bb33c4fc316286afed1f66b2649aa66864dae715d9f4b9fcc4a2963436429c6e5484f72466056628c5984d8d27add534ef82570d59c37580ebde88b36fa4015f9d10d1ee92948a8e4b6c0fabd0b51856065a5cfaec8ab43f4d911e54b8926a4d2a3fef248a42baaa5ea88f0513132a2e22282d87d8340a0d927b608f4b82655654f8bea2cac172cf8c82c61bb292a8e7b499b14263fa58a135e4a46651e7238390e508652438ca03a598ba40f93cbee01ebb0dbeffc0f6e71fcf4d5d1c467cd3d9260f6fbefb5c3052e5addc11efc5545b75c724e58b6b68eb362e115b48c981f9b6d652895076481ea1d555c62294f05ddd92b4eb7b62b446b1d5f5c9f7b328b9d0a1c2df4db68c9cb935b266541c586645a7d1df39472654ab3316d725644148cd780aa00384014977987702705f74b6e87e9be66e8b9510566c55fdf6d9a40dcbf604ee6668d259ddfcf4f1ed1bc41ab8eba8805f54024c4fd7ef1667cc6d2560bef070dc146a8a5d9449293f08d4580c872a3581516a32ba0898da87f87ee7a9fdcaa042a265b60973519ad6d2898285133abe53613f01a2b79f8ee263be079db7a820097a639d5a01c76895e2b2dca4f2db3151ceaff3a8966806b9dfca83956c25837f5e24de4913072d8c72b2c30a6420025e3ee4ef1185f5e044c6f14167b69e85ba1194f04b6c4ee5ba2942c95fd8a49c82b5e161ea97751c3610e9d3e025e38ec642d1c9a025f2b1cdeb119912cac9c110e8923a66b0913f80613137964a165918f51931781206b85e8966e68096192f2c174fdf701286f0091433c2058d0d843caf0bb35245efbf92c3c7784a36e2d6402c805612c87f1858915882a4a0ff4c9fae094777d72f9a26ebdda17cc89128fbaec93a2c71f95b7e7b9852495f647a5f41357c9934bb767f80c90b4f1b4fa46d2176f275635fb8aa922b349a0b10e9b3555c4690d66e404e35aa880193522c1e883894dcb84d5091b88d9a1d642026eb7420f031fda1279aaae2cf24090b9fc05f5df0b44ef7f8bef003607a2a96463e93810143667e5cd12c72a7dcfa470aadbb516a18b7f00af3beae80e9d3866f79431e5ddc1a477cbf47c6089e66651dc0e078e6581cfbcadb20451a7737d95b776d50262181f4e8520dd67ce9dcef6478059d1ea4c10d38d6e0b4735348593cc53daf1a09d3d8bf3781f8a4d0b4a4ae762478e781437e303aa856ac5ce3e2b5b6686c46e9814ef2f8b35330d73c35d085296a876907f80b82e0d04af1508e2e550af07e4e9a7d76fdaa4a426620dd138e5ef08ef07c896a234d501c4480f377bc4c065c9cfb830e7f138b542c0952e10b7b7b3a782ce263abe4e4c592f0412df30c46506fc12a503ea04bfd72f3acfb9ed54cf42c89c4a791beb105808ba709383c2df02edfba4a40553d2107f1218e9cb542816ff6d08603d05605c6099b9241620b910ece88c47e1c5e03f7d6a0debab4f0a198048ec269eac04f3a261fd4178bb852e4882d44d64b9ee3b5842d9572d567f9ab7108683e57171d790c48c498c8e8c11e876de6bbe56a2c8d2b90d89cc2c72c8f453a1b427d07ffe3b1db8443650cdb7fbe7c413429f4b16ff75a24c50ab5aba11b1f3540761278a7cf8f3a7305cd5515100fe3bb474914875b0badbadb52c67d51ccf28662710726d8d462be1a72b1632c812d634a14f2a63c9a6b97af7af71b452e8abea06674d9dd10594b4df32dbcab6ea47532d662328b4c5b18380569cf5983c88741a6b7d8508b53e2c67f2aef13fb178c97ced7df6a97dc4d09bf3a996d19cd61f44d1d6bb0257e2ead3c8d1246d33ef2284e6297c1427c89dcfb0a59eaeab842ae7d90f3d311b31412ac278510f2cb97bad90dc2f954dcdb6718f19df04c195ed8db3be84cc87bfd75961b2c7dfe588d5ebef97ea2d5dcf8d4398b2a3628d315e01db9d8888b584da2d5e4e0de3c6aa7d9794b40976f5703b2c236c23ca6c594f5b2ccd840d01a1811768bc10366c615860513002992a3086e6c24852e144ec87f169a0bd2e325ca055b848960c5b8062fa612916718dede172c9e80411a9e466504bde3db2e028ce1ac904ddf5319b9ece4ba52201397136e9d8ed3670599a20a72cc63b046b609779d91da3d8b84061af18d231481a0cb58a9cff5092746673ce1540cc7509ee4c1e10a437ca1a34509e37672d7382e31300a4b84c78164821de5ea43a4fccff2debd42f1c46408995da4dd37d7efc54d2fe1995c3b7cbd5161a718e14ae4c01a5d76ccb6260e7dea1f78f08d83fbc867df6918624e62a2753dfa906086b967df78016c6e17072bfce58adc743dae3ff9d9931f566826c6279af79d0a4d621cc908ea7b133570f62a7f591fab1d30f5462762f3402d14f8f538697a1ae913170be68b34b3d7a81b542b67224bb39e5e5263f7a376deeb88527d461f03f9bf0ec279166f72a9e682489f0f92b46222f785b52049adbe1792b389e1ff379bb8865378a9e12e5039b8bb845eda2f14f668b140f3f81232495dff1ce45ed61831e8cc05b28a6d3d064d3b20c626682f2f058b8b11ced6359ca1888e583a6dbbe16b739ec924ac66d09fca603975214531f40e14f3e4488a1bf3d40634c36c71cfddb17ce00973666c172c453f128ee01005c5be9c974e67ad921298aa8d310bbdbad2c12ff145244b457d1680a1db224a60ce7270a1d070deeb8e16958941719b51a3ec04563db08b61c8e347bea1628ca9b93a3429c8a997bcc3c5cdeab6797815b5b7f88f90368b5bc5ed1aca0d71f0203efb6c5898fb6acd3892dad426c5e10520e065ac27decbd17b46ed19f4362139281b9faf04432b085f502286c1ee777f5386ff846acb83d0d0033d90d1b8727d72ab49a26231707903b9764d3a2f0e8c3f5b6f7026496f68ab7eb525a9941e9d490b6524287abd934377e5db91343c8d132a1838610456f5119f3af556a8c3895bd636a093dcf189aaef6c7bcab5edc4061c01311207c6d4339d04a043c629c70ba2bf870140221730f3df403d8be0978d9a8838ba682984d1676a67c1154ab3605d4144e119592b00ed78a37629a7061e959495d023586b3f0bed79cf99d7db074443904c1326508465cd51e9f8e23f524ab3d17ed762805e1a888ecf0061c1e42dfadd4aec8b43e90ef59e0eb9d40e8aaf372f373c4a30195085c3995d1454bec7358ed596a9112f7ddfd4eb193c89095bbfbed49c587325375c8069c196f18d5a90e3eeb60003f0db11fba980559f439801ed0ad196902d5e41b6d9611fd32460a2a5d67801331abf40fb06c078a3c25a2b29c1ee2dfa597a9d488ff0a00eabdcddb1610e679230b43f803752120a28a9f6d80861de0c71e894e6c4facfb3e90acbe0319e944650d47ebbc1b8f57401ee4709d5f75fc301095a424626e0f4a64479dbd50675d1803608135e22eb7c9be4f5856d9a46c1a53451535c672ce623f4e0154feca603c6b9381f5d3170ef1c077c9a6ff9dd647d1b47f318e7419bf982ffcac37c40efd6985971becc27f4ee8246bd6ee301823a3494587b75d463ad57d2d60052e1051a3d5a890ad82a3c65302a5ce34f6313b17b828f04efc8384c6f463034d1bc4ce8fb118883209141824468269a2031f140595c7e14ed2d684bf795edc0288f19f9c2e794e298032e78b4fb4a7564837d5fa74b873e6a23e1ec227dc2c4ead48a9e166c9f0bb07fac30d3ee80b75d372e156aa063c80b038fa67c4900c1e890d55bd9edd09c47e8b585b291126263f115f9c22667393f957bff46086d19b25f3ff25acfc6e5c70f6ac84d994350d70480f96db41b09a8a24ac8fadc4b06f19c35ca57cfd94a5583e4edf40b2db78c4b662c4e36ddcf735cd033944b1b21b08bbe143863b227c900a9add7dd269a6e9defe95682b11d1a551e917cf9b0ed8ab07ea814e75b3a56419e1697b012babaa44ceda3881a34e62a2bcb51817e269888506139a24389410eaa037797b011493d879e051c182cf0a299b561a9d513520e41000546c8f826b54c69955e8fd908aad0473b614a7d4e6c22b487a999cb7bcee30c92cb2d13cfc76328894e8b3d303cd0c030a2f8e633cfccee443db4056b0f84497e639095909ddcb84d979c4e641e3e2576e18519cc80476b2e949be286c4ba310303bc31dc9b650a5fec4d62e0afc413d1d345ad98743a071ef9b8669bfb730ece79fa17a87799cda2b80d138f3c23b24aa26576d145e7a120b50acca00ea0d3d42663a5a73427738ce3272ea68ab27e102948482625bc0de4cc8d38f6d2647119e18b330d5de2f2423f7588013b15a764f277e3c9c84f6469784b751283c83015f75af5003d09650629baaf3c1121005f10d3dac89f4e2f5a0e08ad596666f1e0875684bdcda303092748a3f9266899a35a4e9f0c95fedd528df0c84a4a924197fc6fbf7f0b126e46c3be48d0b52c72ee6b4d77455a8258b333b9cd107597a6be4b804057753a82a95092d0930883bb1f499d5999005a3769e16184811f20ec8a1709ff8df5ac6680c247db5c9b62d038fa5685cfcbdb993dda897142af74a549c322f279c67223ea2d5626868cf7643d179bb65f80fa43fa83b50e584ac3de14f9899af91f7ff9cfb8a8fff9ba26ddcd764ce38e9568bd6f6601cc6873f094c14b78299a64240d02baf19121a6eee5b3230487a22eb94b72bae81011d6cce6a4627e960dc35aa18799e2992775a4668a0595f120709d3684c0d94c5e132405e851f682faefd30d0594fad96a7e63c14e1224fdf1ac0897f6842e524ce689dce93e02d4a71f2fa566c4112bd9b70a3b4a7287c528a26ff2704ae94a4fe0634f01bc08cdfe99feb4e8821507cba371ce823de967f6a35f2ea058fbdde12eef4e79f71b186606526ef5f3f8ba9419bda8f2f2a20162aa32232300163c41d448e0e30b76c0f0d94652c6f43d8743bfccbe295a08356c74d32c94002cc17ae6fc179261b443b5aaf0dd81c32fdfd6034ed49302c7dce7b1fbe11a6e19aa61a4b2827aa91cfbebcd0ef64547d1d2f913f598502ede512b4205abcf85ab9d8a537bb0dcc0e658595c02ece9812849be5c4aa34e1aeee57db9d497288ecf2d16116e5920676b407456bacfbd641a913dda1e3ae1d980c1e31f4cf91dd5d4dd70ae4cad077040cbed8cdb95a44cb366d16dc70968c1c41f693779cf32ae4f69f96b4d72ee509844a1670bf14511d14287fa08fe27afb37fe1bac3cb94428f3664b40902a8ca584fcb47730edeaf80c14698cda603feb54ea0e5eb5a8c96b8d6a78b26cc8e850549de06d7058b5b90854bbd8812bd89cde883dc73e0af227d822cd8448fb68179d1ef7986c5b1d4214c584582c33e8eaf77e18998deaecfb7e241cf3851adee2fae69aabfdc7ad44dfaeef7a5fe9ab1a4af3e27e0c291b44928a87edbbb481d50ad4d181d1dea854b4da887bbadce13ef8efcb8a465a5fab7cfa419b8ac821a74cb1a8fc10ff8f25908656ea99dab9b42f6f0519e7f57f10fa7b3e8d903f285be9dd5da938ccd606a47cc1e44bb64850d5a020a3a94bffc479bc51ee34c2aacb15efbddfcc75184a47facb91fe7b31015e88cf8852412583a165e17a0778b1ed9f03df3ae6ac62723b933bd667f61c8958695a1897e34d881dd00944af42216315385466bb8413f95747c7b2048d1d1609581a6caaa1a4c8f20d0d584c7a02b22a780badfa92b7994ea3939bbad43628126b5f1eb71d458851bad4fd77c525c49b485fe9451fe973b457395d8d9d2b695712218df01b5921ea64311635d9fb706b1f44154a8400f0bc074d420863ada93d7fe0c0506f3998cceb6fe627e6697588119956215c4fc2cee879d252190484e1026a225a5aefb268ba5403c2d4e2bddcbb121fcf822bd5c00454eb4bf45cc65cd7c058640664495da1704de36a6c33300107b4d786f53e12d98e3f00a4973aee4a62f0aa44d8ce03fe6f98157b88e46dd84a6831110717f54e02b1d58da4712e6383a5fa9fe9b250f876a90edcb6cf8b20cdd91d2f6c4196f64f89d853de5bfd7425819d00f6dcc75950e5f4356065d029cd40e562e50f91047a39b65e74105d0625632d4bff5280fe9c96a896fef167b962eb1475d9b55ab8aeb6906d672dc47a79f86f91fe625a87c22889f15acd09e2e79e39b155f94f941bce36d68eeab483b38d77748bfefeaccb6b142ada01cbd1953d589724c0f9c58dee1248785d5232ce25b5d82714f2d31f153459bf07d2119328ce392788b2f1864a9a0037bc1d47882418aabbeb9d0c524224d662537e6e5f07e4af597581bad9319da3cc9e5ecfbfb1ae17be17b72f2ebd3393646bd6e5d64f8accf7f43ee2633f83f36a42358bc932e30470113adb5c7b3e6b528f4c791dab0c6e68192f89ace1dd2ef8c9f396b26391fc3e616d20cad70da2ec59ac87d38696aa59965dc3511f52ac6412f60b3f9e4216c3e4450577a367a2a73308e0580af1531de5113df11a5d2019473ae2526b602127cb5a5ac014eaca013ecd856dfe32b81fa128212efea938b1746ab6a433991a3a203bc91fbc89bcd1bb5fc4c17ccd715988a8fbcd39e356165473a16363ffcc01a5fe33f88e1bc405971926c6b4ac913bec9b000f8265073211cc3111aa1e5efc2fd9e09231fd11519409325725452991014dac04154a31911362274e6a0dfcb8d7567308a636cc04fa7979354764fd62f942e8ac72f3c6e9d650b5576f1298196b930a7cd4340d83f078ad6cc6f075ce693d05a2ccf01470fb7f272118068142b10843d15af63b870ee4d03f66de80452ef7ff8b006d4a09d92d45ce78d197b6d276c6bb322652c958fd4c693e7ca71d858c480275193ab54a7f4a8da9a7d803f2f5dbe08675966713839426aa5813449957f90794d3d67162071e0671f16ed9febe4d78369d5dc6a0f2e786f0371460cf805b3a0299b2a13ea66d494706700dc585d1810e4d7c04f5ef7978bc16999d8de25ac35b8a96229c7c22ccaac5ff0e15511124d95dd3eb1c6b9bc260f535c1dbc4cb93f81ecc0fda932809fcbcf0269021d6a428765e0204189638aa0684cff359cb32cadd16a185dff88130a9ee6d0f29f9bb8d6819b083b053c1ebc42c4f24170973a5e57c5b503c812074448d01fb6f4d24ad170316c5cf3f3c1b894b8c6e0b06c7e2b24eeb47472548cf85f7d600e809e2357f92708f3699133d0f99690e8916468c828d9ce9593d84ed7739abfe1b441ef28a995c86c3106ebc7ff4519e1d0538a12be0bdd4f4790beb81fa4d0914164bde489303c4f311fb0888e3e6bf4c109be0de28b0ac5754c48aa25a1ece5e0aa3594481298a6c98203f5c0c0003ec37f84bfcaa72f803a29bcad38cea85ccbb691e7001070f699f2132be850a91b9a35e97266875da80c05c73357b6bb9d2447c170313ed4a80a86049832babb1cc3b5702a7197d16fbe995a5a35f2b5d1e0569764970cee2527f9a2aef9ea3de6be5feaea5e02474222d5f336b4bc80a9f3496d7e9b7c422dc2b0c6259579430ac5878eeab2d61e1e86ccca51c8aa9eef54aa2bd61998f304a57e5ca5217ffff4a65d4a2073edb346c05787833108c57399c7add4d2ba2c979e0346bcd8b53e224908d3e7477a5abad5d6f3ae286a790bb920c0bc69ae558a66c6c3f9c9a6539d80c4c3e2316540c50693bb027e614daf2b2b8867f68d51302d635996b5d6a6a486cb8a077d2a3849e3c924e368c1c325ae601fd601be0c441c615195600f5ac1940626e6501d7ebe158124504bfc382dda14e2bd43413d3584cab1053ddeeaf6e5152f1d30bdc66fca07d3c11ddb6b3f6a8624eada5f151469b76fbc911044998ccef154afdf0a5a93b0416aa734f38b55cc2b05dcb67402e58d44a5ecc654dd8688f952b98afd3ec215600baeaf2a148275a3cb72348eb487c3843323b428d61ace2c3b17460ae1106a47f1c4603092ffcef75b5251a56d74e0ce691a713190e210d4b7149e75122f74fa182b64c0fedfc08ae851c597cc6c269d0dc0fecbce718fdb363f72289dfc9636d81bf73a957a863eec676f418e6bd650b31d8552bbac920b3a3b450420779790d07557ab5954918ba8d2cf3127af692f44e9599364ce43e72f2ba7a519110c296d60044316d2fc7275b6fb0b3724ad8190fc7211a1dc7f1f7881550a31ec966467f1012de8ddd9275da4d7316e97fb975fd6e45d9f9058211be893511b0c013bb99642a3578a216231c4fd3f436d0cd66386774c0eadfa173eb3d3c9f3f31db55cf4466c7a6d3620a31f188abc9af9be99938d5753454ccd29f0d096e393160ba789bc61c4baf229260484f31a5e93c2a1624277c3a57dcddbe088996d533deaab08c24596f6f16efcae665c7352a2654570640c8ff95aa302e08a57c074dfbe3de281fbcd2c93f907b62510b3c7ea7006f7d0bdaf1fe6fb6afba1f07ad380715b34f9f88687920dc72e617191b718bd084ce59194a022a611523d8ec015ce0ad2b2c582aa9bc8843c959bb8139f9a125ecb536edce7526a02f497dff15e61cb94b286b154d9006f20266d889e743eb7c8d493a2a9c001068bef07dd9da70ca16c85ed320d473aec4ebc44c778961ca603be9f717a7705a28e61c862d8afc289862385d210ed42ba66d42c1dc7aa82acfb19bdb22eda69342ab04fb40c435c610bc92b0d999d19bfd308fc4eb12178fb38ac272a19cfac515e15bc4409b488d67c5fe75e0f754b7b1b9594562ab14848834090a01c9e0c3974770f961277132d8159ad8afc70a05054d47f3d8de9671e28d84de64834a5cdd49db01cd14ac16c319162d0e4415b1d9e44906a5ea9b28678b0dc43803d9a4588a451d89c6edbad5305441f42cd31fde317e2535a202c7fa4ad63a5536d7b73bea0592d8d4951cc6ebac47650f82be5109e350cb98c01a630bd726d76c4aff5be46632968cf13e9cbc00a7763eb815c5a5ceb49260974f91cdad65e838fb4e613a9d715f074e0df17acbc52e061eda98ba6b0ae5869881bc19b9eee59cbb8ccf862779c64f6dd932df4560f573b2d5fa8b98c73b74b1d1f1d8748ad589b13bf49a0ffbd6d08072db7cfd5a306377243e8d8f4b0663efb25aef2ac61368fde4b675fce27985ebcc2e00136f84c56f39ad4dce17acb45347ed703dd79f6f47401baa0b6edafbab3b5489a9802c2487c059100362c45d8bf5b9a9a050b443b158b0cd3f261769cc3a282beafc074817c8bc4a96c72cc41dd58727dc4e52bc935c6cf9e015750296b89afb4c9a19b103e252f71a67280943803c1afd4802aec067e0aaaa132b78f8b1ac04d74a8dd33c9367b9e1185d3791d366f6b06c1458f2aa5ee0fcf4674aae5f42985fc23ec77caf40acf1442a28b576470dab98e1f119b461b66981c1b89baf7fefd5914515c4d623b9bd20966a3e65ea916abfce7bcae2ad5b477bf4dcb96052c9edd19bedd67f75562ab0149c661a4936159d9b0e292b811d32cf5091596977a1a03f8d3bfbe64d919839496cf4b43e17cfa5628cb91b08a50d8de9dc4838eb1f6b5cea17bd453c288fe56f29211dd047e13984adc68a51042d4978455cd3228e8456632722fec12044b38fe5101b8c0ac40989a2ef2c1cea07c246f9e955d501c9a835bae0fcdc704c71b67804a8f4f05484f79ef873ff55c7d58531e5dfecb4dab98359e7fc5064a9443f6d7a0eaf2645dbaba2805bd29d1b74531a302bee6c868eaae2ab95165e4fd2f8aca2d5d86b23b1897d2e58ecf0bfff03a8dcc64e548839e441c59fc09fc43fb28172f87a890ca9f7c05f6a4e352f1931e7ae86e334b8ddded13d803a6403742950d51e3ed859c088eef8ee62739aaa3d10b271e4f280e189664473ab2b7abdaf713dcdbb7dd7986d277ea2d25485cc6c34eeede82c0c0e5d3b690bfe774d56bbd09ef7c6fedc5dfed21be5af5336babd6e8398be75a0b5c10d6085ea7761c1ace3ff3efd8fa3bfb9fa9ba7bf79fc1b67ff73f5671effe6fd7f9cfeccedfdfd8b8ed38477fa2bc348f88549bc018ea32b6388ac1037ac3fb090689babcb681402ecc5ffbafdadc3ffb9fcdb8bff75fb5b87ff73fabf37ffebf2b74effe6f06f2ffed6e96f1ddebfbe3c06b96b8175aee21b39f59d351e811f945e3a10263b5cca635146bea1a9be1d8f2aabc3f52c448edeebb3e229cc4d84942702087ed586700a55e32125a94e9e01f8219912cf100887c160c81990726ccb2427ea60b2097fa6eec3e2afef65632c13d0b2000d55643c513b33088c47955ee31d11c7a5d6ae157c108cd3875bf1ab7439a5b28ba8c623ef0c53230ce48ff0815c88f7bbb0145f94803e70c9ef9f92d9c259bb9d280dca88dd7b0e38d078fdc7b3a7a10290bd271a3d98ede13617ea842b2ecb61c71817b8f18b79ca9511efb7040221112f8c709bb84ef69aaebfab6ba3bbbdf0a9dd4dee50426381669102f09e5329333c3ab0bec96e0754dbd79256517e24db0683abcfcb0e8c6cb3aba95a20cd737007b32cbc1ada9438ee2eee46d67d7aa34d8715b577a3ace2ef035f9b8e1b633dbef66483b92c106a64f8ecf5ed7a44b3d72be9855021d0b80b9c60679d2307b9c73f6a72d2bc93eb3df77f3ee6eb5f7b628053a4509583cabec2c0546c3a28e58859d22704c6acdef2e9913333dfb2472613bbe2ddc243e964746047ad138a97814e9dadd381be3331cb0e235334c7c051ae034f148abefdb0e51cb588d070e9d7700263e9af9641aabbe0a7be444f53581eadd5502e3c743748a0e1841097ff0943b759f249666c8adb5094e287c98a5db4699aa9308931ef270a0647e793f3cf23efc46258ed9a49cdea0167c6af243eb6a7341e3cfb630c5d6c0b2b7c0eb6cd130f2935dd2783cda86b8a83bd32a07da153a8e05375f6253734d9f03f4461477d0315dc74c7ee89324b48d2e48062646556c0cb7be7e3ebeb0b5488451051e771a70f61a725b95407a5a2c64bdea650c998b8338b112f8895b7037dce5ce42101d6c4184ace840d6b64a892ac3fb55d25b6a2748365e58d86a61e67770fa3b9719f1a3755748992b5d1c2ea154802117299b36b4a0693b2040b876e0607d1e90b814ff1d74e7ecace80cdac605284a93a069bad8f9e6be161854a02c83f7028bc521dafd621b1a6b3c1eb7657b85f963ef7bf69831f4d482c2c8282b479a00818d35f1e20ae44b3f802d5f1d707ed2513efcf1b0491c2b3e1e14ad7ecc89f30746079010830e84b468dcfa62ce3a2989e3799be67d9eec7403e095ab4a89799c7ffd10fafc3473d8b9814acd2563bc5b7bca28938a863743077630c849bf56f2f8f008a732daf4722830f5e8476db1330daac54a845ccf20eb51d33180eac58c6aadcca3bd28414ce2c8451a432c73f8d3870472101ffc66f19a202624b1edeeb38da85b2c3c67e8b61a199f243ce658b111455bb94426ef38e5a3cb5f37af88f69ca56f96832ea20de864753f985b8ccbc987b1dc16e30634aaab25d5b1c01478fd335f464a6d85e40174737d474dd776ccd8b6f90b224d174ddb09776844d35d25febed78272b25cc7771f7a1fda59571ca22b30f4ea03cc7e972f05ded70ea916d5e2036ca1517f20736d04ce5d72e7b4e954c0aa5e658e182dfab142fab208ff2833ca9b3fd42553474f0bd250f07888fc05f99dfbd082193f11e07381063a41793d263696eb481438531b445445fef521c321a54529cd46435de895637e0eb6c2f87a4c7dd3469b17ffa4bf6de77c97e1323d4620e67f0d5b3dc251bae99868115c80c6b3c3d92adeaa520c24283ad6d52f4bc3d84ef4e84564cefe3b31bd058a929babc8623fcf3749fa82107da0d30d1d7902d81e18b30b8cad54025c6b7d5ceaebe44d7e33d3ea20c7e07bb2392077d14b309ebc700137351120e2e21d3a9b2574a45fdb91a7ef8ed2081202186a02384ad442f39047d83d845b3896a5961e560917e19103df79e6444e347eb450a02d03aea11517a7163291d8f5755c24219d2e458fadeb397fe668ee31fa2c4e33b35158f0b5509b4c28ccd2c7e2057d2424c880b9f20494e08c5d9a084489f49f152fc4876e7d746aa802f2c32d7fc11d28ceed938650d49d5a124dacf35093a24b050b793e1ec647d58d412b856dfa0c795041e3e46371f47315db688aa80e6457e0f14afd2c398143cf8c18a6e8e12a38aa75cc0496e8a1603ed4142ae889ccc7311079a8a46dde65688b8014654990fb7c92dc1f3b4581f57979bd06230fb70338da1c9f28a9b569641eb3678cd6f33361cd7f424bc80d035579f7ab94e36bd6fa76fd158223e17ab28e2a4b0763d4e816ebe29c2f4d4a9f28347f1b28343fbac8877b7c2d677c85346677dd6c848fe63b1d561165ed92b6f9cd70573d1b1986126ab6b9ac6fecf5f22951c1a1642b2e37e11859ef5954107bbe80b975e7ce5593077ec9cd6fabcd9b6b0d88926ab72067a5322223457cb6a2e1587a32b3ba92c833636645bd14cb4dd093ca90b0692eab2b6eadb7903665d8a657e4a8bec7b9e350efa8423dbec9ebaca857d9d32b6d0558494ad14aabbac8400e0b970fb1b052a407b223a216860ea74f3c8f5d7d67f9fdd9df08996052e628a9fe65e3d47728557f0e81b6f50cbd5dd4e028580c71422c9b67e5015dd869c49a4e2c807b7e6a8acaced61ea522b581e359f802adffa360c28327032f72dd0aaf1868cb661444749b6e3804c84939e6b964952085086e126d3150038521c35262d573a67807a3e90ad3949eb2aee86216d6f8d7506753e8216e409ea0de2096358c11313a7d1fcb1e42f0cb0625c14bbcea59ad9de7111f196f3461b4a1fefdab059069ca2566df6321ab3fc12a23843cddf7f2ca2ab7e134c59923d57cb7acb2242dc2cd2bf2568ea966c086e11f5f97eee21f4e8f98221f7cdfd4b89143144dba70aff1134b74692ecfa2fec47386a1c7fbc0497ad72d942d74d67d9885b8e6138e029a502ab01a8a9babf32066c5f8f6f885165508f9f0bf6c851cf430103de8c6884a5f4503fbf7d2587620af0959be0bf1dea6e6aacfa1570cdafc9b7b4090549397b5966aceb27da5549b0e56f6b2401de3e22c888f39f087d417968f0b71b0bf0b9e09a419e8a35042984e46957d2af63c4a7ac0a267c01cc805feae1d8ae146065b7b51fc06ef2b1b24ccac613898266aebaf9806a6d1daddc87c7ba181836e213e991613b28401dc245cddde3f652445e879a288b2f49215f90c048cefba62fef6dc4a871d844e8c723c1fd972064f0d3272b6c0db11ebc9ab299302d6f4a41b8033ea5b21c7671fe2d03d24734b071a2066fa3717dff4dbebb212b388cf560cedf49508a4de8d91148910964bef5335e55f003a8331566aac0bcc9db9841158b19e9fa5c692bfda8c08014437fe5034afa50eec236cbd4824f334b0c2a14bb703f641e40f65de18ddcec2d7230e49aba7961a3ce5bfa6849f530146e68ebb2449d1db496299ea6f57c7f8c132df08d9d1d2817c70b3c30d77b0ad67fc7f3c4f63b4481224a18c39fc28837cb5b7aa6b11018eff7030639b22284a69eb11240f1a01b952602934c1fe510829f827c2c72a56427333583c32550c3b329377388a92682bdd2c05494f972732ac6a4d6c14eaadf060d0d94d9bb04b6bed41c4f01eadb101a644d1d74c92cbb972509a688c717b2c6650e749d454b7bc5e671c7cb5953c133ae680ea7bdc465ab3d72dcaa9e94a2f8fc6768f42a5fcc1334266bc8acf04e14c950b1ff4b1aa134a5bf65cb8c8d0cca0d0e6c922c6b303a901cd090e164c7b2f749f9169cc6ada3a7bb75e8ed2b2cc5e20f8b73d8b9c5469b20177791b17a4bf1799135a4db4349a642c9553c96c399259b3429dc644a970b58f6f656e1cd198264524b068128d6cd685267371b3a4534e6f040856be48c2bd247beb7e9e2dccd6009a66ebb543569c8b36a4ff3668a6ea3ef7713940c68099d38984af203bce20ea366d2a5cb84cf96731c03b022b35d499ad04a121f5d61f0d535b1b3909e4051731590d4bdf121ece40808dfe08f62cd84a33c97ed34f0f16d7f72d947e4c84443e474c32e41646fa31b7c8de4518a6b9e854e88a7c9e40eec1f94f1ce729c30a4b5e564512645c114e38a91f8c26a68a82a936807861119b42398e645309df89bcc36d7c10e1b25f558eac60ba66ec1f7f897b2293245f20fecdfa5c7c30563b14a34e1acaf63fd597e1147764c5161190182ecbb9eadf66f5588a99dd69d677a2a54e703e81654643f239d074e3f6906bd738d5077b76ad4b8b9f0406bbd1021422725fce7c54ec00532249948d0d953df7102da8c793a5ba5825aa8945eb5f56858a1c22dedd1884bce83d2df3196c4f79b84ec21e90bf3c75b50526f68b82c5f923f001adf883c53e8ca4fc988d0592c719bf4b44c0341d9336eeed8f95ef07418c38e48c0801785283cf308001931c4161a0f64aa2747c10fc8c87a23a2a532371e212fddf4bcdff8ffac30be6b4b7ca5256ff4271f2090953062114c8140765884fd8c1138aa6dc609b5663758bea801526344034c4a81559dfbb419803eabb530cbe4255cc6add13905136467414612e650b349911d8232cd18045d9717c8c9030446bf1a8739274af86589eca3af8c90a4c80ecf6e96227c5b069f9fe46cc76685fef87591ee4622512aa0143e6cc8a37ce46a8c0bce1629fa8a756890b84157998bb069b321c100279495b116abc6a4baaa4b85828251a4372bd0feccee6fc554875edbf464a9b6987f3da76a77d32d6e9a0db1c491f411ba0eee41c2d7078d43bff7243ca4a272fd8c1efb4fde585330f0682b7882907ff63d0c4673bd6c4c772aa61b1bec803d2373937c44c74213933e2e9e511e14f1b023543156b1c71f9b01ac959c96b30888b9e134f3150aac77c19ff0ded7165ef593007865ee105bf144abe11dc0c672ec330aac6c8732b691964cae46e6861f2b3705a49c31b7e4ec884ae16e13a96fd51894792a132500f21121f52a9dd20845a9592475a3e09f39b1681b4f6e8308ff9293b5a15ab5c5d8561c0de315e1c413b846c726cbe2ce08b5a44d8fb7858495980dd8914a824894d4b20ddeae9c3145444165252a55cb31c51e6cf5ae52f472fc82d4963a968595f9aa17acecaf92229d817c85f79ce530a5fc4e552845d01e76c8058ee3a4755ab9068bf57175ad4e1fd047ccbb4c3e3b2b6940cdaecb4b43392bb9b22c5888b4a295e8cfb2d3704539d029afcb3eaf2191566ca0725f919428a634e1f5c1cfda9be2a6baabe18053401db7868bc2f803b0b8bfb4f4548fe548899fe2ce2ba59d84068552adbd6d9a655e672a073d9c403fbd4d03bfd55dbc8f2f6f1b3759c449884e51cf1b18a52363c5d28599d59830ad8ac6e638405fe8e5f6b406a9ce73d89897616222c242f49bdd065a0d7851d06e378c9c66544feed399f45e6a92c0043d95dd3ab19fef1a42d284135bb088006a5448acf15051f29a0c734a15a5646dce27eb4e8b315a31847a2e8407905e0093ef3d22fcb678f9c2fc409d56d512768867524cb16f6db1c62711b6e20c3d004c5b556add73a190ee77e9f334a184e271f431fe221d94e9812ed29ad5bfbb03bcb0401744c737d2b52fc0fb7c352d16d13801b3b602fc83b93d2af1116ef41b378553c4c017e653018782da9f0220fc89b681895bb91062b2ba8494455931b46d577549b172359da947f7c48dcb82bde158d4b39a40318fd6eedee1a47dcb2fdb8f61d2142ff306a6689c49c5f90c5b125be1620994b04303ff2ea14b0dd076f800242f67ce541641db2411a110e682d9690fa190afc47c8b09491e0b619224fac5018f4691d8e2bb3389e3623f1daf051e445ab8484d43009d96d92481951e53b8128b79e4f5ce68396805974ba348b742311861be49bf21045308e6a4c9f155c960966ba68cfd3bae45e26568182c0f036001e0b5ad61891c35e2c82ad5c763b5a0c40bde9b9c06c9d6eb6b8d61267a3ee5426a15397a6bd1276495e0b68f2f3008c9abd14cf386086b5968cb71a9127ef68fe164121501d606ac104f0b4f8971a81a104a915e2f561bd4291796ebbd7ab22c5ee079a69460697caf6860ec53aed9e1a200dc5742db8c407599abd3cbdd62a373e99d78b77c513df91981183a451b763669dab431f7a2079552048edccd03d1204e41983554fc6658d8874bfef7c85c9593e276165220218fc297d8ff2d20de6e9aa03a5beba6f39e2ef9fa310a5558fa55682407ba238a79ce257c80c2bbc769e20033841ce54606285a9d6901944315c809f222f63486f93c3f9aab6e1ed0c2a47ae4286ab4715e51238baadbfbf2ad0e572d82bc2b88f6e89200879654033c15cbd6bfe8530562060332c0dd809272ae572da11847406893230c597db56549036f4a91e770b5611481203a8c96802c19d2dc5b52ef05e6dad187945f21eb9432cc130f7c24c1101620118ea29e229b5b0b7051ac4157f3e70820f9803806b566a7dc5c740029fb9745e4267869fe71a05160c2edbdbd078a3ee274e7c53b4fe7b249181e61bd18c2c7f868fe31b7d1c8a5b87749dcfa16924c642a322d009d4e4bec3b734edd9b6fdeaf02e793b9ab40dec8f57fa47339b4f8915abb42b9ccea56f252e62a61ce19d640482c89bd6c5b1e55a18a53a81c587c936b33cad2539341fbe062d5c9263f67c6e83c554976bd6dc26b9197a5ab7ab23d4d94452cdbfa591d0baea7d746ba153032f095f2a4308c267b4b0bb9c02eff5f80f8ee77f9c3d027e0a059a74c6e9f651a8d91987e6582dcfafb5e2c2d53dae71fca8c855c10ba791ba0266594f6244dd4caee86503ccfced94d93b981b40f82c9c1a3fbea7a9630a9a112f33d0285134437b88cb9bedbba4dc256001597ea10263c78f7c33605e61a661a0649ecea73766ec135589b6115b129c83c00e9cfaf7d14f5aaf99b796f5dbdb2ac5bb8979633cb4b70ee0075ed0dd86ce2a8b150c14c2a20a3848f6aec6362c33a502355f2231a9d28d9f83f13c53f0c8cb9b4e006a6a5824e8a4936caf2a09acb4cc64b0f10632fe891095f086aa2b8ae2f5274ac4b484fbf87aaf3e5cd9398d8160bd7f8c1cf64e4bce57dc8a166933b45f6645869792618b888bca6f3210483c8c63ba2991185555137cd66b46ef23552ee75ef8f7640966a14c327573143c6db413b0d340959d4131af34404232b418a4122f665aee1e529991629e7cee0a78c90a384f8ac2507d1ed1875a355c19eb15ae734a2b637a2326e4121b0aeba792aea6b6f55566cca2213ff8637c244623f6f809fd2f2b15dabb69a43fefc99d9d54d88aadf53b52d9ad25fa6fb54c312b027ede2e689a9dcae95a874756419be74f76969c0c76dda0ef67734cb22df28ffef2d888ab5e9a1de78587a275b33337eeba557217d67abaa347c9c10d64a17d4ef148593490c357bd0b37d0a2ab591b71c009d5e94d235bd33d9d17db6fcd2fead5a06324017388ed2ae4c839be3f54e1c79d66b84792a23c2b22650421d471ccbf64870a517b28af9836235ca1d48f83079ebc9b4249f0392341ef26cb7abf40baa5f94e10266f140231bc6f4ccd9e04c7307aabce19d5ce802d94dd4aeaed88cbb223446d692f07741844a903a49f0f33d6bd41377ff395468a96f32c99714f4b60b7fb991260f2dde1fc1a3fe879943f18781a45cb6ece31390d89b71152980859efa4f2a0321b49007bba72dad9564620f5557a6bacb7e2c3e88cb77adeb3c3efd95ae96917543ebcba73b3539a212c1cb7b0e67184668433900dfdf6ed8c89d81f15a60f1e57c796d9952f427d63544bcd6a46ab07badd165a29ac5c623b54ee715cb9449518623aac7639bc3648301f42a060f93e17fc43591e1e9027734393da11a2db606de55c5155400100bf1db94dc56aeb11f3adfcccc82820542caa6385e4c8cdb107c976498f7fa4981df1e65617a367cfd1dd9683f793e7c6c4976cc99a7defa0ba324786f78efc404aebd46d1cbd88898e0b257517aa9fc7cf4f89c13de91141409550f2e76874c3598d844f53df0548f220174a468db7e60b86ba9ef251c3e5334e71166be3328291bb670728ac61b8b78ae045647ebc6f691186e3b1691592bb0490e8b481d1305d70d687d8dd3b630851e39c4185c5d34d01f61d7d6bd182fdc75562614a6569a51488ff68f7c5e8c8f18e1026b66b680f666912e3ca02aa4262fd290c2973d9fb8e9512d380975796edac4ecc4840e34602ac74c28c36180f16f6b916eba0b20a5dd077e520891360a6c139cd0e3cbb0f3ed20651c0c00001ecb0d1094c41588f6a8dad81a302950fc754ec0dcc1b18faf55553e99d57683ba6e1586481deed6217e68e144a553ebfd96f5fd656d23ec1f996a432d0c1b9e860a2fdaf499c6b5e76e7b062e91d7faee148021fcc116483a8b5f50fd73d011ef39b650c7a58641f42349c4dba99ad2d6c6a4fc9a4d91875653d269103ff2e8a20135724578fcec857a789733250330e50ec3416cb3db5f2eb3381c22f9450ecd19144706823a38ef4edfdbc000c26dac6eecdd694f80c31d52ef4f446f9eb501f22b18d24caa19cc5393812af5292e5b9354d713c136e39d31da37a8af6d7417ce5da68b563ff153526bc106b7a68ea42e5e2e622546594f01911aa9527280b553bb28566a9165dc36525336f1116959a9627e9a6573d4948b4616015b9f8850389c51a40e382c9bec7f9ad3895d6cc980d6f1cc5895595231f27d3c01c076311965febb0c897a0e9fb778047dbd044b18dd7f9d45bf88d40827710018037427d1d6c4286488bf2bfdb8ecca6f3043966b18669b13c28cc76595d8cb58a28eb829cb9e16102127838bd23f52ff34937fbb194c1bcd971bb15f9ddefdadc1a88d08b443e74a813b9c0d66d05790a7a720722f93045428e3c9bc6bc2414b00167280daddabd6bddaae3bedbc484aff150fd6cdeae80b3d4313c819e8b052ad3d0f9234726c1bc553d530de41d06a98483d067da36eb9ad138ba3a588718311c8d21e19b0322ee8810524c011b8f350d7390bb996e5d4d0451614fb3112dd94d1eeec5b483d915f3de573fd932fa1c40038d4b023f94bb001d2248b01dbf70f7dfa2be24981937f2197161fb60b1c3b2c7d7b7c6b70a4cb1353b8e167abe9c9ea70ca7c29bbef174fb36ae55f200fd3d03d02cc126e6a7ace0a8d33096a1c9212e6223de52a0811b2b2bc20d71bfef2d4948e1c18d3268268cc1b47307fc38b1179ea2a2949a8a2afcaa57e28d9b8494d7db83602b1b92ae732027451abf900be3217375e382b7cfcc3d9dab7962a0c4e498988826dc2206f1717d91f2a0d6504d685f88df845971accf59aea2e465ed8e422716153907c129fc5a544c7579c7079fbffeb49e52043b8c7bd1ec05b830a47ba8f3e1640acecb7d3f599d6f2736833c72615239bd55d0f27bfd4a80c1700aa2c01d5d803141b8c8323fda5741e97fad18dbacea90da4c4e88dc85fe96546febcd76c852ada3a4c944d04a477abadaa302390db6ad6562fdd1b57595e009c8029020c3d20ffa41b255f66f326753085836e9c56f4158c466799f7496afacdefc2d883ec31d30cd9e4e7c1ac25768e01de81931ec1bffbb2e3397b9490826930dad421f0e02f849e0d84f73dd3088f8710feec4e0fb22405bbb0dbfe1028c568edd6cf90b44a04c8d000629c4f7cf3cdefdaac63e5a9642c6900a506b3dca8326a8c32f8aa8ea8040c06ee4316190c0aef54926001f7ae2044f5a6204f2610b6491df1357804e507bfa1f447b4bc2f3d00cb8b0ea7d7e40852fd4fade85ed9a895f1fb40abf8cbc0897986977ee0e3e1000026d235500c293e037305e2f6f981035699205595384e138ff9279ab862c747e9e79de4168e62f50d55921151b9a00b6b85320af33389507123800025d56cf38438193c0b44103f7f5fa1ff21857b525e94734b1d210e0ccd1c7780d919ec8bb4b77d361b61c249a3833d92d1bad3a8f3d8371b859a5b07859c867ea8e0e02d985405d113ca12ee46ca3c9831928184835daca4ae4c32e25acf7908429e8edf4e904cea28604d065b17ce8ea9edb96b8051a80e4dbe3488009b24e1a9c47025628d9f19be1a925a049548307d4c983b97a7c4c56a7d20982ba1b5d752f573ad8aac8abc54f205eabc678546db90a8817cf8c453223067cb10c36c75be28767474bd75311700e0de4fade5d7a438afc88156fae09b1fd577275a7fabed4fddddbfd16221bcfc02bc05d8443a00eabb3186dfc2ab2a843ef11c07d4f8bcfd15f6d64487116de75f2665c7a1bf4003e424a1a102f8debd9b178a4246a2f41c77f2743db8749730174ed57c4896eb8777911409230683c3d288902d8b75a153a9d0a996b821e01c526a1773f28e4afb47643da652d0192a8fa54b666d3a8310ec8c9056dfa2b1805e226b608c459315a7862e9e960d879e83066a927592f25445b7fce38b2ad15ea6ed5bab7b3da2a3ad218d6698442f4c4eef2d24e2bac1ae2af723d548b31ac8a09928cea14c7afc86f245ffe39836c87817c00f124d813a1b723067372bbbdb9d8aeb4f5f71545c29d6f80fddd7b606a77955624d0221feb957fcc84102df0d1e8dd74a6224f564bec3612140188b1e8cbd52499b53a664c97d4bb41d1f04698b2980476775ddc37a59f153110672ab344beb22e7bd4afc706acd5d8426479ffc1b32639599bae28c65f91c422b16ae11032e3ac1713dd6478968f6405ad8c551e9a19fcfa0a3bea382f9a968e345f45e12e7f50c1b4cfd5d55f9951ca6597c7c110970d2a1176c1b5b345dcb8880a918c1232e8c9cacfa26c60d59e8ddaf5367ec02009b6ffcf5f089ba5f003a4e7e4421946c081b3e9f11de70b1c7a33828320e47ff4246811060fcf38568b33283841d02990ba24ff3917210badbd51cc6a467b0f0048064aa8cb8011897ed01ba895b2211843d3ef0b3e40366e9a667e5da17c0b189a8e6a12f39e2782c48f28c68ce4c57b1d64768d96f3015bf4a1e42d162f5b623e7232d1438b991b2309cefee70080787b7910dff19b17127c5369d7865fd0a7236dbb8cf771f227f22c77439044b4222788be13b2bf0e8d63dd69e2f0cf048acec8a361ae71706d282320b87ac6d5b646e1c43f2e6671d57063c48af19c2e3e42d2fa28c4d93c94d314885e02d49b203e00b5278b438d2354152865f2117f3db5edc9d607982efbfa082bbbc26349b0e742284588cd98180b48b346e0fcadf65f2582d842c48c3bf8230109e5acd13b34d6215ffec5ec243b9bccf098812541a0bf54d234f0975f43544288d258f17f03d167238783cb58cb1a0029c1740df232b09d26a9801ce4952b5bb41abac36e6266f3005cfa15b57a7be3c9ec739957d294b4ef671ced390eb445bd01ab28d4f247bf738198c10819b0fdb1e5e706762a55dfee5303b347d8838ad54e21f3502446ab720cee0cf410f9e362089073a857ae6fbd415e9f224ab18817ad45e3f89231fc5696f2dea8886f83797caf62ca73383803e6dd538eb8b83b76155fdbcf0865e2e0ae2ea4fa2b8ca2d6fc0bcc7837900beff4e86f7517bb2fb7782eb0baf9d2301b64d221fe180d8d3604234c1a37ee63ed5390c0ad16ec5f38d47b1139f42bfa8b8121620803f37bd4029260a5321aa5acd6f84f77d4d59ab884f9d7b5653431c11d9b19a29cbb18fef22e062b9870bc565cb70208dae3a4a0a140eeec0b32cc83be12ba38e2e083b5fbdb613d376f840768f0805854501019809899de659fe927128bb7ea51d111b977856d0070f40e261e883b76da9ea90e65576731e14b785e560bd5015f7dd4d3a411041990f4cc0f462c78bdcfa41195d9052256fd18da3463f66ba5fde3cf24424d0e8f99d80986ab59d282bba1397f35367d8f0e9245ffd97de3c613e8190924b4df487b809b328cf1d80009fa1eb9b2f309ab743ab30773e48ca7668bcb5f579b9d31470d64a4449238e93ef9136abd095803055ce021db97d4158fcd0b468434c090136cbe25a0bdc3a83e239d302cd0556339f5a730189ddb819ea5036406a05e30d1090f8a4f87513102b70de52251c379842654c20a068af89ca02a6a1370481e7a4f674632e73c293267929347130fbed244643c6bda0667759744e1cd20c5695a91add51e23350f151d59941134795aee9a3c09aea5e41f362de3772e0cc5a52606482a46ccb7ded28807bd09eec702ca924dff188028ce8484883a1988b2b73a1993f5d500f0f586e7770a719c5ab7979b6df1f582069d98f56f2aaf9d283f049391a3f5f52d59c483ab4fe7e43cd2b184b3cbd65fbee43d144a5e61f6fb929ad55067a3721b3fb83574bb7d6f886fb2b59e44d46605ecbd288c7c34f8765768012e3ad5e322c7b222caadeaeffa497d06f89d412fe733f4a9e067996e1676de13431fe2c2c0478f9b851611e9b503de010e3244bf63365a3d80c138c7c53f112ee0dd597eb6570b58674eab5f7dbb2889ccabaff653b0a19f4a18fb06885687ae8ea762bbb1e1aadd54056e0f1b27b80ee5db972f4c8018aaf38f4e2293b78e48b8860c07d27e870c33dc4d33325a5815862b5d3a698d12b659330ab8cc0ff55bf53f57cb892009c889d25fda3d27db4373f01c0b7b70626b7ed3a0f06a5315b0835a2125b7db9731552fda5b29fd103eecab857fd1bd7179bbe0e2aa5c0e74556e56bb86e863b088b49e5e38660c3762a62858b9d2881503d542c10e6f5c86ec2bb0a1a60351ea361a2b190ac34572e69ffb771ae77199ef5e068b6eac23292df2bccb5a623ae8cfcce58c5ed9b6b2c901c2ab3aa555cc2e59eb0d32bfc9a33222835fc61d654d1479c6848b438ed273097b9614dbcfef57770df279ed217894f6a444ba3ec4a783000ba5ecedc8576a20ec239bd93c5182a22889767bd70a688a397090606d6f4c477c970b645140b99228980f9deaf7a5cd268ec86598a95ec5ebac87a4f6101502070279a6d2a7bffb44c4e73c554f62d3802e9865df137fc13a8909872c634bace054ad7c1e9a1c3db096a3208b8747edd290148a73f50c951666eef33f62014c18f4c3a343c1c284523e3199740ad9c7a11d984b4f2016eee340a79697b451086f13318257e7c7498d00ce78e9e9346df4c64702d8dc749525e0ccca489ccebc6e7b37cd386fab0be68225051fdc32d149072a6941558a41a1b7a6269a3d3e9ced4f82e247f7e0dee46d79e76455999a75aab3a6e04e0c9f53a2c5f7a9d001256de44f91a3523f6ff48750823fb31e33223ba1118b32a7806370f76a33121292dd60cb852cc155909599597299c8aca727a8c9d14fc29a0289a7dec4f0af0a7108e6384f4764722f28001b980970ac46f97c12e715176658958584221decb6694586dcae444022ea30afaad5823c0816e978153251a08c183e70240066d0e5259007b5e73b15ff2762d7afd8237bc44a96e9e58c83e53449f79230c42c2fda952fcd7486e832dca8ed4a1c6c2b3991ea635346798ff469f8a6ca7909965644d06c6f4148546704081ea189e99125bbd9c9d5cfa82467cf75f640da7ba4d4596ff41d791f3ddfdef9df827eafd634d08dff3047c55605082833ce6b566b004676bb05fce73cfa7c9d51729be156ad22f85e46d68b61984930a3caee473d41621ab9f42bb34c2d54f91076fc74bc28f3ad7715723ea4ca6def60bb48b36d39b40d1ef81274267b5d4c50761d87c96bdd387e0cff9036f3f4deb8d5a51000c0ba18c5f2f3b1167bcea1cd863b18730da9713dea5cd34a8737765ae4368bdb7acd4d5fd4537ee789aaf271a3c7a8ae1d29e88ef4f293dc1dc03f3612dd9dc8f84f81c1fe5a5fffbd63d340015c713a2bb521bdf2914090e93f721050442d4fb6643c74ffa2ebfd9809a16ce9043a73f72f24246c3f5d0fcff3d42b16aa25490a43455858a596b2c76aac6eef47c16eabb6a69a60067a4b2cb32a33fdd5d82f674a1e7b613ca9ea4a96fb57915f083ecd448fc3f08475289b66621115ec0cb21c8e624319382bc9ceff73af8f8c120eca5e13dcf9c91742540e24081a8a5b222a49b3de7ef2327d2732964566e2d00c09074879299a679827c056089332d858fa64944aa8a998dc18c3434b31d4e249944df10793f402d2b31fb45fb1a2789929b53b9e96524dff68c9ae8ec06c9e80aa14ceb41f808135d7cced7518ba078134db672f8931ed9e4f034d301771349e3f4719c1854b16915fc68078f0bfa866644be83404ae13f7d8c90cb8d61930577a75c3b49aa7b56c55df755411883e4f6cceb0a6107fc4395057f04fbf2f4e794acc0277f90054a1a921341edbfb2c925803190b9097eff7bf071e6144b1a0047d59e31e0fac74a613662df59c2c5a1bf6638e63ba20825a1218b0cdd5f1cc525869cd57b66ac429aa4c113348bef18ed4d7178cc0f021ba9c170d7e6a22698ccd68894317195cd37628380cc01b181f21ce9358d413269b8ca6b8820589595f96377bd01b5ef6a2be00791b8568f2027d9d6f23da0d53b9c80b81155c8694695d1f3085dda6c18a99d0b6c18500c89f13cc1de3044a868e888ce1bad092c13abab60e2b943207f166388b4b8c31ab98376c7bc7198ef8ed19e62237b359de3c972205b397f88f7d2b3f243f502ad23ed69697dff365d046b65468119afc2215235c0e06315eb470b6b1cd77f4ca751638f2babfbb80679b524ea3b5106175d4750432dd50bc658bb8e0a7f176dc2110f218dd3540cc047278988130ee07f02d81fae578d0ed0663461fd15561ad4ee70714fc4b62b7fd69ef53057329d80aefe0169b8dca143852ec9ec83ee1a157ff5c3e19b41aef96c16d0852a7126d42864310b420772c3ad7afb87ee19f522409bf2049a1caf31d2518f2d9e702daa1302c7a5e9d5bff3cdc3ec89bbddd0cdb12a0f01bf8d8481bdd50a859826a8e417c62c8972c25bd88c3919b1b68e571704b06ce3e0ef804d434c7c0e8767ed6ff92b9585e354eeea7ec0f00449e69f861f21935a0aa596dbdaff1d5a0ce1407e3f1dabf14c22258b4eac5b2b3ccb5a1597a7c5acd266ec1601c4497ea172ede6839002315a7527c3f01f55cd10a8f9d49b0a4810534afd355882de0a3f8cbb6f3a89034fa871c9b0ec08cfeb314a3655ea57490336cdda8eef3dea48aa07775ba3bbd024c70469d29aa818661ca1f2b2bca24913780a69e28bc6ab076c8c2e058f3e23c52bfc49061c34b4e785a65bca6b6a2ce584432f246b0e92d374272160a38b03e4618a41a91411c664c1d29c74f3c13b8923df3499ee0945fb2336226b44af39026ae3e6fb8e6963b884f55d68d9c0d7519ce9639600a93824db928c02ec93a9eaabff714d0887e838f08afc2db936b5f81082ceb895b147d144629534a1e2d7cbaeb63fd42fb125aa9af5905a1eaf6e37ce61a03a7a399d736fb7a5bdf45ec68ca2e77d6e174429d0723dcc16c4feac8b6319e742cf641fc74839adf5d20fd36e8987753c712d83eafef3cf5e514f887d93b1589b05c7930d38e8a8373bbc0f730d284bc43a2818ba6a58b2124b22724d35c201ff521caf55af4b2fd365d49196e918c31243a854af58a7271d9cc8705502a0fc8895cf4a11cf3509189237078ce5f22460a170cf4d9818069724c6ef94e70415821ae519d68985f6f8ada61f4251c95e29a041d72f8fc0759adbeb61576bf1209344eb526e4682c780656751b5193fe5f45c13420f0d2631cb2deca8fbd5b0370066f80e5bf2ad07cac6b7f7e0d6c96b5c06c1ddf05d4290bd301a8ab0b720e671829051421b833556f2bf334924dc2c9fea081e53624cc4e6e688913ece152109d94879fa533a6232699c36c7c2e155134cd0d289bfc00cb1c3a979539a53fc6519a31cbb35d4664c747cf935047a6bba55489bbb7ab506defd274c1e47c4391c26779acf5b27226234762c0f087f22a20281802016c41761de0858c7167ab993bbcf22250e83c82247d176e4cae78a28a39d6ddcab1ad0ee57748f6984f1c610384669b6565d6b69ff61d30e3242e61bef08fd68ca4e006d3f7cdeefd3c68a69098913467ce26264be7e171ea5a8995ebdbdf2ace5646a018a6e7ece1529833a6e7a161d54da04f296c19b5f65095bcbf3b9f41629796f1b79046a3b82e86c7fa0fd33b438d29b69e0f3eb63da415814a3885725cf37b65e6948666da333abdd37a465313796496b403561a50df392d61ac72f136f6389236d049610da610ad30c6b1c8e9f681827caa3a8d5513880f511d78ceb4f2c7c317d7c27fe86d59581912358b91f5f63ad71a574e157473d693a31736d02425863a23b794b05986835008824bbf2d8494c0a893e66a9638293b56929ce7ea43f803c8ac3a593ac675a7a8c41e36465f083d06331e6e27d0d63e6195f98945e9e6587fa231db93fb29bbf5107e27457447ada457fc51e158aacf1f87361d323c7d4ea4c2a70e470de89926c3824c79dcdeba4732856a1f3e72eb49e8df1a36444cefa53be0fdfae05aab47eb08bb3ead60d40a8f1fd242f447bfed56d57474f727baf8bed386a2f4791a99dba464f409057ee7674d63275d8ce5cba3360fb1d3c5dfa0668c47e6adc888170b5ed4481fe06185ac6631aeb548ff077a10a24052d4fe0658cdc0a07ec089c394457221d4797569f547e7633a6311d83fdc4d3e4f4cdf13f6167b2ec3f8d1b5124778a940379b2301a6b4cd6f99fd62656c7c5586b7023daa18da9a8c9e6b37ccdd4c113336b1be78ebfd93800580a1e857bfe88b9f997619629552765883ab62aace27b87c7baf6a346fb33598b83aeba1da76e7fd49ab89624f972b06e455212d6142eeed43f87b36dee6fe0d0fb30c05eb9ee4ddae9476cd50724fcb56ccd65b3466daba127d5807c6a748d1aca3b0d789946e1a5a1daa401dc68b4241afa0f0d88068dee3e4329cf007b67f49a3334b719306946f999a1df9801b0cba8ca3294af0ca8a68cfe2643439201fbc8281b32d4f61870728ce6b9c6d0fd62004b31fa4f0c85420c501e4619c3d04a61c01b61343618ba120ce003a3d680a1b7bf80945f6c985f98eae9be6c812ff7bf170dd20b5de505107851fb5de8915d40aa2e3ad085f2e7029ee4a2a0b850055c00cf172dda0b7de90504f2a27bbc50d25d80c92e7aa80bcd8b2e7066c4f0a248fa437e78cb8463d8ad17bf4dd4e8b3f0450131583a2222f78bb3331489580e7144553719291b30e3b20596d597c07b9bf4967e4b820cf987d69396dc2b214066eaccd78b3e3bbaa79d5648ce6d3c2f3631f48e397bc8760f65b01e1222879287e31f17b4ccfcb8f58f1f260df628b3ffc1677811bf9c356885131562ed63d36ccd94e619f0f1b6ed7bb7d11816b58795100b995110a08ceb2373625d7b92526cf5724230f1dbd919fe786028dffdd6558e3227361c5c04c83d997f0d726a93a65062886829e3035025759f0db86c72a2a904e1d9d4468be31424490679a02444df114a71e75442f40ba13c7e4a5d44be93c8a1279425a46b8214f648498aba229063cf29c5e81b3229e6984a847c2192458fa84a48176459fc91b2f8f874b9f82200387f81e21334c7fbbe0460ec3604e0fe5a8262f176c1e6e07a51b1ea42a1f37d01d1b3ba292132bf6e1198bf95a038bcbab059b85f509cba50e4ecbe40f8bc2e4a84cc6f5b08ecaf252a066fae5fad02b384274eb5bdbb915911ac024d06e47f4384da8f2881a25851a4ce660a673ee7de85529b0ef479ca7f80acebd2b64b4dbc1bd1abbc1bd2dc4345ad46e04be6283124df19bca90da2c2a4b3195597ae9e55ee104969d8d5df518f820d1ea0005f266e6d41f62dc027c5060bdaf1320d9f8e96e4dbcb231da394844f57b73cab55bbe29342a3ab79a882ca14d3eb1eb5a79a019a175d48c8c2db2b4d2175d1c24267b128a2912a3fd435fed2b341a79559f2d50424dbc89fae97abe5eb0c8c0b0ee6820b3f2b112a17b227964551829c414e52b19f4b228b2f0defa948b43a0c956242c15c1aa938455c62021a68e373d71adf199e1ab7871e1528b457c074df374a8b8a8f44a36f2a4cbf1eb19b90537a1c91b57ab0a6231724a6a77c74322d615618e707aa67c5788f8ecc7aad5fd74ff9be784de77fd7d829202b56de755afbeeeb32df555f73776e35a2fd44b0ca775c9cef1a23158e03feb8bc913eeafbf6a9ebff61c69139abaa745ead1a4d4c774a581141b5d742fb2692e82e2d4ef6822c401e95104d7bf0d58fd19f92946d7dd2ab563d1d14b35c1fcce7d4593c09dcd81f629e3c75bf58f0c72c7df5af104ff653d453b3d027fea28402446c4f8efc97ceed4d720ccfae73cffd8c6ef3f62e51a96d08b5bc3483ec88c14b48d5001477656e8f6a78a0049f000446163b902e847ae0d812b53b1cda60cb8fd18f864b445c54aa953e1ce1c014290fc365301c1005682676dc5ef8175ad76487a19d11df9b9cf5c4f07d5d3b0c31453650d1b60b340e4a0257fae7f5b0047835462f8de3eab0958a15a04ae7bd72a43f2204883038dcd1b66be06da8ecc4abb3ae3b0f54eb617db12e8e246e5615da82d48ca3719effc49adf7273e1ccce548b96dbbf99b590cea657e2fe13006c98548cae1d8837c392afa455d7877b51306c61239c4eb88bef85177c683c8c1bb814468373d92b3725bc19d905c7dad8106bed8bf18243b5b70957a5f18cebd03328e89f9b4fd83079ea085866c09e0b44fee7110b6d26837560db0c73f3a54b7005f679063a7e10981079374097134d223758853664041154c79f57d8e8e40df23b48d21484d8d7901205bcca1eb80b9ea44fa4e97c4f18929d0904016148fc4126740de4824b3d91722465c790920594b21f786cc4bd4b1c7d4dc7d0ad08384f863a42c15db003ef75158fa3c9dfa387b3a454b80deab277e00f7c000f70708559307ec30bb31b88a51f407ad0afe0754fde3a6d873b9540ed44fde016dde34b7a067290fbb5b559d736ff3cf10d7ee3e1af6c4b1157dd7c80ebb4e7a941534441e8b16440f754bae1130ef261368a513949ddffade4069b35dc8098d561c6b90bd253de60c54a82f4d86fb32539f51233bea8c56f8e35b133884b15e219f803ce10ad7b5bd663acc649b7c8fbedbc27d1d024f1aee6cba919febaa3195c7b58d897011a35eaeabe6d019cddce298f2d216bf585aa668c81e48f12561272003d1c0b471d21c7025365e05386a70841334a8817e6321cf125eec1ca59711f41827c116f50776ab196cefdeda2d6f3d5fdfe085c4ac43a3240dac23f5ff9b83305b06e5449afdd70c90ddfaaa1017848faedd11a8b3e439e092fb0969da015a5165bc2fcc9601c41e4de3fd49a96a890bdf471db1615698f6b9719562602fed197a5ef8fba9f2809bc637fc5276c1eec3fd8420a07263471c8687300bdfcb8ad2b1a82c62ac04fa8b17b85f7285511efcec153ed567903368936c108e1ad34a2eee9ef209f9a9836139a5cd4042c63d6d94d465613d79f3acbf6d36aea8178ca63c98a5433777125b7833f4c88e656338a46c91201e57f9922dbf20786387c5957978768eef26012d647f1953e72ab77d79f953ae71f6b558ad38c4273c76a1103ded0605be124bbaecfac15432741b25cd9bd9880044c3c03d57d3abd19261c64bbb3506a6cacb7dbcd15b17c270a03e58162388df96cb770dc27fcd391f38de92551d879602acd299142fd3c34d26a0b5677d43b46d09514818aed10f89a04bf4a8987bfb1770d41d424d44f215df5ea66ff02eb9c7cefc735d19922e049bd044ecc67afe7e091ee04c53f4f0d78b816014a7608d598471de4465429dd68356106e2abcb92443e2ead4547c471cad43f1051066ad847494da507e0f18c7768c0906b58f1920327391325496847965ee1294a2adde2c6017c6830b97205d0067702ffbc7255d641aeb766b963b830c000f49f172f658bdb477f0fa8b70040140dced289bc9190c473fec1f25e44f693863b95496bd64f1f2aa14dc06893bffe92509a9f143019926a10170318170ff1f26f2940140fe3b5dd40b4e2bdb636f668a186cc51f35806015fee41e63cb8d87c255ffae0e0a44f3267083db8ea58f254cbfc4fdf226aec340107c237dccaacea1f1fd79e811632759dfb8a4491ae158359b35ecc74f8883d19bcbbf08f6c8c4d1c53c55858a4570a860650c0702cdfe3368bd385782db0d890d7b5db82eed15b70c39fa9c65b15b2c2ece26d1a759e1f0569c363084b3ae1ade61d85882f34004d6d49677a4883bf2254cc9bd421e063ba1818a24182e734917456ccac5547a692719672b6aa035d3b0b9b137b745b1a93df412f0c82e8eccd9f74e6d0161f74e1891a8bdade1c79f426170df467ed1d6588a76c8bd4b72af6302f0cbf161f1c03964a44e7af2cbf427aeded80863e49e991facf24cad99c02005f1bed4b39c3a98d8bb555a103b8c150efeeb645e71c27a40b0803ad07a3470555a9aeb9d00d95fd982a6a398a1067010c4703aa74567b58209c59a50355cdf862918f27cd6163e7a88685d587f371c1e0f2f5d175918dd65109fa521b943420fd0804cd621e0014508281456be5c51b1a97c136cc2ce82a5a67798ba05c30060eacb12c6a9b90bd37d9724b29539232cf0785077607fe71e736f6fa67def90c7bbbcf3aaf612ff759e73358086bcce017f5a70ca86b18f53366d8223ad4e0ac19cec37db80e7fcfe136ceb2b14574d8711dae033ecb73f80ebfa79a61a5bc1fc07bf80654c302fd0cf6a2fe6e3ebc1dfe9e0fefe1bddf783247d026e59cf28b82a91ede0ef7e1c9189dde8795117a4f46a648e8d9b3a5a748dc8bd176c4ab22376ea47e0d67df8c362cbc9ac1d937245ee96c429b508f1a7ad8233caccc520e212cdfe13bec9103581925abc28159afea11ffe6c6630b0942ac48440f7c584858393c5b7af61a1e0dfe5e73190dcc37da0c1e0ed7f16e780dcf86bfc7ac4da87364a286c3a3373c0ae4c5b7f1c2e909e00c7619250c935182324a5a8dc9caaaf65e133940d67b0daf87fa3726bff1e80c1e8da2e35120218ec3842ae5ef13bdf1e0b39c5f0acb1ef981f596b6ba863d87a7ba71d60dcb75d8f1f7771d370e594766acb0de59f6882a63b1aceac6dfa6b4e01aec395e8c966e6c6ae90a9c0bbfb9b1324a60e062fcca28d5a0e1b71ac02ff73105f0dbbd8cdf183ec6b32bf0c60c8ee3ecd9149c31c1ab196e036fdc10c06f3700bf5c8ddffaa8cfa1175970d361c77738dc84e8f01df6886ae54766acb0763864e970b8a96acce0ef47707420458bf59ec38bff1e0fc10845ac1d5e13399e452dc7abe12b0ffe7b47a20f178486583f602360edb04dd4f0ac8637c3b378e335bc1c49867ea773260f608d7420bc741af6d62a5eba01ec4cc24b2f80bddd6779e9323e83f40378d30ad748c7f16678f346ba8d07f9936129d039330ad7441c530470867402c024e903b09789975e6349f0d23f7b590036fe4c2d6e3ee2c3b0373e0c6f96ef30ec1cca92ceb2341e83c7ed86184e63e5d643861e1a8fbfd3ed590f80071f001e0d9297a1dd7a0e4f25fd3d87ebf054d216d121822bb8c03a92c37f8049a2095613ed2cd7e15d12dc9571eb324abcba354face7fcd52d86cca48fe131c4e0ec3a9e07df3d0943060bfe58d55ebf5d7a5b0c4fd57633faede80a4e068695d9b2e0a85f19251d769ce571d3a1067f8f9b101dceb247e8128a60e9f0b809c9e16f8f44274428c105560edfe9190fbeca43f22fbc4b8d787619efc6f09d77671431decdaa78761797b66efd4b5b3256747f37a319450b6dcd27545e1cf1ecdb7db92f32b4957a197f37a31c9e0e2fa382053704449651f2e99c08e8c08830b4b058010c5d60b1bff8e91c19a690a5063e4c3ee0032b58ec324a9d0397ae100328ae3c2104567882c52eb3d4391a08c2145040e4042a92ac603115ac1ddbe958408e2948a0c4aac172393cc8a257b8cbd500e160eb051020199104e60354a008419922464b49a914b502e1c0e370419bd3ba2671887230850450684289942cf12f0f8994b4ba0905a2244a444a40f09048890ff69747733308238411c2e8c508afabab5f17e5c1880f47a20fe7601c5cfa2c54d42b069c16ab30d919893fed4934925d98495d33a90f163f61f0d34d41f006fba43e3409af3067c2abeab37d6653809c00bf3991b2253fe7ecee4ee2551526d38b93a6d2d4e2a74f23245ecd249e4e80ab4905f84d9fd54e68c54fe78b52613af5993e93e6eceea6dd4dbb9bb6a7a2ddcd2af6d45fcddede4593409b49954019d39be98f46b9b9b9b9d9935a6bbc519f261cebd8d0d14975f0060502da4c9f2e0373a80762cdf449a94fc7f6d211fcf4dbd2f6d210fcec524b70d3358ffa501f56314f24fae38457905201c2c9cf4babfc9cf4c94fcac4bb98970afd74ee183453b1ca9c736641a82fd868655cad52a86ba40c48e0ee348ac2af0988976ef28137a64bead2e7155e612ea54f2ca623d3d24b2519402cab1964b2e24d482fe5e69a652be474b230da4b8578658573b8cde3ad61c244bad12708f3e8d18a8d1f1b4d220e1ed146eb7bc4802e34247d0275ce9c42530670356f003fe946f5a3bdd20aa037597ad56dde00aeba9e42d165f7d8cf2bd0467a153fa9d83cfa6c21b4311a01071fbee61b157308de04997904a3295d9b49731a01c0681ef12a8b164634c9349a49138bb9447d26c79f98c4273bdd20ab9dd3043b84020485cad2b335c27f714d44f029307c2635a5cfa6c6de4b123ea35a2c5a52e561d112273c7baacb67fccae5079f558d3d0d8a7769e23393168b8638816a7a4a63cf44c474f6a8966df07492016da4db4019d2d9db3e7ab068080ffcc4a121f3d84326439199b926b2276372c255c73c5678a306da48978ec19c01c41ae932077ee3a55f99970578e9b7e58336d2534b70f2c3c1bef8c9008443c30f21414cc1f2c1213885d1111247e9d35d50ba90b087bc1a82888f5ef7595cfae8c57cc69a151fbd183e931c61cb79928136d2eb4f0f4ac164e8a327f3dfc3ad4b3181a76ace1863484a395f1279408b0ba748227570422202224912014145c22218b96ad2e7af06adcc568cf046d7aea921530579215c6625f71b0f6f1e6aa590bd51ce492b4fdae3da7cd08b446674f301bfdbf2d4e1a5c5ad07e48fbf72d0667ab51cb4a11b9dee411bba0549a2444956b5b9f588d086a64ca64cd3b6cca45d1b0e3a5d433dcb361fa6af1b0ed5b36ddb72386158ad9b8fcbaba55ea1cdf42cd3aab6f930fde5d9a6c50d87b8f9b84e1ae7503d43dd785d9b8fea57355d17c54c27cc4d168b5fedc5407bd609277958289cbddfc7291f5d3c7b8d383a229e7dfe1c3d6d2da92e7bb26466c938505c57a8865d26bfd7755d260f62536adc755590bf1affcebffca2f687688fc4198a6cfe70ec91e8044fde087f0462462969401b1cfeaec9ddf565166a1fa3a313a3b9a639e79dbf6c3c3aabd22c90ef35d72ce4cfef0bef3cd35e78903fcc69a0709cab3ae71cf2c775febdca5f585567817cafb2329e11f9310e638c5511890fe33dc88f7122a88f714df398186f6fd96e901e637b880fe32f5b0f1877f14c86163df83449b82b5b355a8b5f2d57cbd5726d97bf5c975f8af4d7e5540af00691a8f4f12f7fd96e904e9178d5d4c5c575e12f9c5ee1d5d5e811af7a343f711b9028c509b0f8ea273fa1361ecd4ff4e47950bfd0a0be68d05f7ea269c271b7731957f935e39767331e1194cb78a7f2e26f1b02348f8971adf3349fd13cc67758d5f510bf8b33321c0dbee633b61e1901b4086f441f30f6be701877f16bf3a13a6d1b4f1773793441c8564fe746e2c7f80b4b13047765eb2f974f78d5d916af64eceddc09af626c4fe7317ef916e3dac6d3c518408bf0468f1e98cba309a2b71e718b25dc659fbf2e97537875dd16cffcea69f1e8976b1b90cad362a3e51a61cf53e58f3af54a6de54fab4eeb05c0d30be3294c44daaa53d7e08d93537b87e03cf5ea038ebaa42fae5a35171e7c9817ef5617cf487ce92ddea54bfe72cebbda471f4ec2ab8b2e8135978be0047f39ca5e8e2af19723fde5278ffe409bcb6e56f32413fccdccca1d9e3ef99b9355390e525d6e724c755920dfd378eee3755d9552992843124a2fdfe7e567288632aad044a5992b99c89151f887059d4623fd652bcf51e92b5b91d1c2285c7cd8031c38f9cb41b18a7f4bb6dae77778484a9f6f771106ee6ad7df047108997fe1d116725cf1edb7c6b5c97100ac69bf0090263bb3232c3874c01c94c39c9c87380f61d7434338dfe71d172134c24357005cedf0d72e8487ee03e6fce85e8a3884c419edb7bfb0c38fce893e42228ec824b2897beb1197b0e0afb766e2f5efc0c4f793ef2570467b4f016a2134ffe9037ead1cd74be02aba8b5f0e610d28e724aea9cc495cc39c24371e9a338f4d07dc8d4931895755884a598c58f0aa9792f82bea222e8af6760dbf482c122fafc87c79e4452c36c087fc49f9c434a755fd803fdd0764effa3fe0238d12f18a97cbab6d8abfde61f8313aac5a2a0cfd6cef111d29709737b159e79cdfcf2791bf1e13e575ab6b3afa64190f8c2312af34eed443f188bf469a7ee31196a11eeacdf6138b79ddf21a487bc25f47e1af5bfc75cc47871b4fccb713c884eb1f22b8cb6fff6cd10e35e1621e120971e54d7e7bc87469a021e34d0d34937a936b9cd33f5d6304fcda515e4c02be03600ee4559401fcda3b4a81354c228ef824ce68efe016e015f009df9106df2f80026ddaafa9a3f8e99c2e5afaf66a2f0ece65eff7753d3404776312ffb49296888418facb4cbe3d1e45a427392ebce21a5afca63a0afe5c6a8b779c1d8a42283b24d443fcb5e380bb43b46f69a58f2f191aca2aa52e96208cf1c8c386de7cb691a190719d63a18739ad174b29a5945262b6dacc5e1e2e96524a29a5eceeeeee9656098435d787aa049ab8ce91dedd4d29f50fe8b0a82b39329d999999995a25d4db4a67086b40a7472034009ce122f90bdd442d8433408f9b8ff826971e645120f14d0ea4bec933873ebd1fe0d1143028b992a58a3034c13ad22e999999999999a594fe011d96b44ada3661b2aacc02f9dee426b65cd74447c23f54d676d05ae2a3a4848464642401a29fa1679e14c8204d9641b63dd04dd7e4d7e964f286680f21c713f4cbbbd52f8f2ea7c9a735c22fdd3444fb9367d2eba1ee03d3ecd55eab9b6b1ee42f83d3657494efb04439fccbbbd50e31f24ca41f6587f47b3dec90339ad90c461fd13169b3a8c939abf42e3bd6f656ceabdbf42efbbc01faa4be39e41ccea5739bbd359b6e8a1ebbc9bb438c3c1ca27df5aed6f640871f55c049a77ea71dd203fd86ec55d2f270f7173a036d9c3971c411dac6838b927131324bd92dbb33a9c949e93527a55502bd74ed4aa5b80e89ab559b3233d37952165c06b3e02ecf5863ad1ebdf4aaa5b24865d16d3d950597559426e59c94524a65702d2d73524a299553b2ef347b333ea930c8185c842143c1298aa63091c407098b15a1274eb050329a82ca949f24599086ac4479b284c515231c19d006bad11454a6c81f99240bd29095252cae1805516126fc9394258aa108a4c5d211843638d0863fa34bc307d3e00fd6c0cc089c9c3f3c0a4aaa0ba92ed8200b70417f67889600fded663acf2351abca4f9011538aa251901da44fd7213ab41d801e7dda0e3421047a9cde81e8d2aa200b074783024794652866e62044e2088d07849d0aa4a4b2485d21a5c9487d21f5851aa067d7e1d0b3cd6833e255bbb755f1b8cabb485ee52aa7d4f3e92a1eeaf33403eeca28c928c960c12b777699255ec5f0183c6e3c3c86bd483e86b7d7b16370b8f188e13bdc9d80f80170b879d6e1c60300bec3591637180270d8392c974ee3f5c070f8321cb23cca9af16efc192f54f9184ee3196b0108006f387436c3e1c6c3e6c6f36e7c0f872d878bc55a39cba3adae99b75eee769f655563a2d27846e3713436038236375e8b6798d665e9927cc4ef90a08d74f1195cbc868bcf70711bcf3c93b1027773e36d9e4d49679f32a016bfb619cf5257e06eb6d42cbb4f1d92f6e2a72428543cd16ffcc6ded5a5ad1bcf8c3ee7ff6c66c49f974dc1dfdc7864453e9c8cd20b27bc7ac22b1a677f1105deb8710ef5f2f6a05fdced97cfee9e3d23bbe0e8f2b0eb0a17657b380fa1094269920e319f18f4ab7a177c08a39027af2874f664227402cc034bb480094d3703028e6607265a13dcfd3ed638feea16b8fb7ddf0e76b8b25c9a955bc4f213294b962620edd08498250b16a9115992c43b24954589da85959453b2efe095b430064605dcfd6224d14f7bb31b89b737895cb3a3d73a2776f94c61d74fc7e6c5f969ef10ed35171c15b50f5f79e3b91eebbeae6bc4a7b377437422cef03aceb8b1ca4fe7e8449c31a7c793bd9d7aec177bdcd8673b7fa6785d41e8655cc24d2392a31311077c2985e409b8ebd15d46080276f8040e51a5037509bdea30bdfd873f9e9ee752c43d515252629f1825e248824168c120b4585095036425a951a50ad29e0364b5d5a15d4adbd858a8e024e288cf900559374537b0810f0bb2220ca87881922a4cf1f161411664ddf803b48498f2529867b123ec13e49ccce10c6639d678da87edd1d8f12099d3ac40b26672ea4931f9e559fd41e98e1d3fa47045e4b663f2beae71199c5359ddfeb2b3e347e7989c7d36557d2ab9c6e75f44b2f38157ed1dec3a8750c838de00216440951be8b3cbcfe6c6b6cecba95f4ca9c78de7b252aac34d6e3da4d309447a4b29a5e51a0b19b72381a28bec7c3b12680327fc9e76666619c3633c7b0c1d13c6301d4215f4fb03109e0a5a1ef6a111fa0e7b44e2163dd01b0e3db4728bcf7a9eae22c008412d9089456a85277b7a756e73a357dd5430bd2c336dd9a66ddbc671d3eb66a6e7025bb697ebbaaeebf2269d1366ba70111313635eb6d416a3c16c1d4cd775a91797ae6be1baae4375a7adeb3ad313b21855c003d63a27a5d7552b121886c465a2f2a62959a669dbc6411b79aa9794526ad2513ee4cf16b4495d819bce6d3c20b491de55157093e34f56972d9b2f1af5521b0f8d7a52ca140c8c0b4d4a01446801d3d0f7442457dc9e64dede3282e6ac15c3e03363d79c736273ceabd6796d3df82f9f02a40466c2b8c5df8c40ab3b9d02c11b9712f00636bdfae529df9e615d2b26af1d3ff89bd89675cc821eca80a4c6ba45eb86109ee1a9f96e49218514528e52ea297ab99ef6214ea95fb687ab131cfc69533cecd18160de8dcfd748fc9e9e6bda961ec71ff536129fe38f6ef138c4d875c430ccaa30ef699f8e55cbd33ebd7d227921fc058136d4619a705c8a5742f8a34ebdeb9c1d747070becf3d88516cc99841519a9188a1874078483444969f8e6a52e5b99f8e4dc75a7c4e476128e9b3c5e70b0df2ca849930cc64c2340cb33fea76bbcd5d6c3de4635c8379cbb81fe6287bb2268b6137be101c13aec748fc9e2cc6cc0b992ec6850b28f9ab3050a839e78bf7671ced7429bdbac748f8a5fcbeb8942fb2c2f8cbf73016f277a53c1d1a21b8eaadfdc53620a8a7eff1470cdb91c5d064743477e6b114866118966432796ae36162a346792735a3bcfd654300e6d35d361ecce7bc01f3e9524aaba3c2bcbaa6c230fbc5763ec2bc3d6bd980c4169f1e3704b4f8e4361e944f0c8579c635ca612a8c47a1fce4590c1cca25ca678b8bb7672e28efc6c7501b02300ce561ee82b5a030d4f47a508e7217dfb48d07e51a9ca639f933e9f06adb78a8786a1e73a8c3dfc4304f7a3450b8aa427945f9f7984bab425920df630e75f8a3c11fd7dcc97923125f833628a769c25d38b48357f7c5533d2f2ebd7d07de80f1f69f30d3a5f4e94d77e14d9817ef813f2fe55de92e9e6d405a7cba69e391981311f4900a0f899a44f1590034c82b95066da2c3bf9b163d7eccbb710372e241bdecc057fe50fcb703ace2e9bf3f7c9f360d859aa799697c7ab1b703984f8f62f5ead3fde12b9db2fb04fb515e74c1bc05e59c77eba3ec1d82b3d327af484cc2796cd2e0bea6a29794458734b5d6ca715d77bfae91de0edb214faea66be5b8ae731f8203bb1bc60a6de4100e324873a346e3a54bc83976713e833025e0da79eee04fbabc7048e7250e1c92feb27b296186e062f4c18208574640022221aa90e2c27694e2c2260498d6c947c62c548b9751a816cfde5ecc525fda88042302ee6a2d242c2dc9abaea3928c481149ce874568ad77c2399b52d7b4b456d1235dadf5ec9b52e7c42cac6df5e29c98856bd8b90b828bd17dae1f40a221aefce5fe17e6528bc7a6cb169e2486b48da7e675f8ebc9047f51cad477cc848c11dce5a0cb415ca5371ffed765f25aafcd06247f79f5ea12ae34b8925e9d833732c7a1610127b3b9f1c09c277e9679447878cc31e91891f82a4a83a7a23ab6a5687e79527eb6cbdb5908335d9809bbb8c54eb886a609d7ce410c037823f3a63edbb30c731ae774e9d98e1f412ee9f5109f5a1bf863544714cbd345f23bd265f0277d670872df1c964a82bb2a935757992c90efeb85f0d3a00938f6c84351324873e975657043ea1c6e750d755a5f3847d9a014843294fa89fac933175a8c06230ef67948c404297b01216034f4d2692be8a5d3eaa7247f72ad88936b31aec51411e39d09aa4729a038f9e82dde62e221150f898830fa4c062dd28480433de7345a84370610001a1964b82fdc738721e3974626c6616c3c623a8f89e96262fcfb19ef62665432aa19183054335efc19183332323232defe42262380e60280aa172fe2bb389d9c761b908800ef1423f9d3b4f83101ec54c6a461fa8dfe83bf20d57ba2dbc05f47dbd4af94b028daae1562417ed810dd065e4593b70789fcc38620b1da9dcbe27c2f1e28fa6103afba0a4360c3222a3f2fede5723084a3d3d5e66ac779f7e9ecc05f538087234e621498147d2293d88a4f2250645885643333e740819827b81b836c03a495d2393fe0f66367c71013352d59ca2823c73885d239a5fca6a4744a49299db576b5d2224c486d2a3215998c78754d47a6294c45a6225c4ac05dd39069c814c59b9064931ff086741de8431f2bf30a60baf1d1777af2e0348b5973feb540365ba6775d3e7a6c797e6939681399a346a550e99e46701388f4f9c92da5945ae86e1f82d8428bbf19d8620b2d98af20e794dd524ac9ecce8528827460140fe89c1e8a465cd3295d084b2965edb80b8b7ed060834ee77c1e83e494eeeeeeeeeeeeeeeeee7e4177ec18bdb9f9baa00ca2d65a679d1ab65da0562cd38c54ccd4c3552b76d9ea83c430498390418f3153cd19638c31c618638cd1278c1e63841042e6134ba13434f247e8be84c952723733f394c29c73eee0237a7ca0c5df09f8400b8e91af50fa3e1c1a7e0839c2f20d4d617484b44ac2128f8a446873a35134924a4c68e060ec9a2401e3e0e8ec08d2809805a7e8ca119c72897f5e8bb8f42da5944f441c441cd10a71463b7ce2af200277a31216f1098e506ae00da6944e3a6b6e6e1e4208071057377eed3b153851c17d326ae00d7e2020e4b827c203a7c9226af520aca92c850f67680aa3233ae511aef3fe70beef2be606dc854a3c1801819452123912af8074522aa99c73ce39dd05dce4d8f20873a0fb879f724e1be5257d70b16a64611e84ccb13420ba9d66ce79cd4beee8fb4df845fffaaf1ee48c787d6de92d27b4894e25b489b47d7a107e3132c7662ba57ad7da55b90477fcf1a5992c999999999999594e1d8e73ce39673452ffe308bff62f3acb22b35bcae019fb6b3bc3fe2d1ac49541737ae88790070ce906ea930f9112434da444abb966169d525eede34bf7115f6a1d077584f04a831f73b086fdeb1c1c9dfe6103af6685d39397871eda4b22473e4ab99c86bf8e4f249d12873f1dfe5af648a7a1e331c6fa819ee832daaeab639e554f0787067f8d032486974e036b8f864edfcbee60650b4f1253da251071b0b7ab48c05d68b48390a640b7eceed443a2165cf1b2956616588b1f5dce6837d2bd0a484b2bb36572ba9cb6c8e546eacb409bbefab21db4696a55f3a795de46e0d8a3fb1060a010c20b9cb8c006473861c52738c1092954f144148090c28828f8808a1028088316948ca033022080d082078e58c2128f47faf8f4c03670409bd8ecf36c8b483752df06b4899ec9696dc08f379ef93c23ed815f46284f44faa5bd40fca8e289f069f8e8d1bfe85cf40e0acf5c1fe02ecdeff86143109a5617bf2f70b73e125d53b2535f65741f8eb603774d54ef5a9a2211eee7652fffe5d8ed9e7d382287f020fd1a7976130f2f1da32ebd3bf3a9af7688f6d4f6207f7adc806ca00a1654f1829fb6a7a509da09d2cf1d4203db894c0177dd8f20947509290759c6a8172b5c7476bedd84ec461afe608c518b30ad31cfe638a38a876ff489499e74075cc71fa4308b28607736e86277145c8410da10411359b626d94e17564a4e52096d6033d7d120480ef414e6d555d2295be66052da34a898e9baae8a61f5a28129bbead2b5d499d4620eb4f6be68f3a49206b6f4a106f4aad775550cab570d2a76d5ea85cb0bd0a1290e4953ac3f88ccb5469138a2bbbbbbcb9a3237654a61b6c0b535997cc44cd614e52eaf5270377777777777777777777777e5300c33994c599665106e9b299301fbc4a798659ab66d5b94340f7d46abdc0623058742715a4b0b33bb68305268304b6039ba3264443a97eaee865a8a9393761a279d12e9aca5a526716dafe6e2f2f202391984e2949ca33980e72fce608772d24b469f23fcc524fc451c1a8033d89d3c3b130e409bfbf9d009c122dc7e1533993eaeda0fda087130527055520c7a17245edd532e511fa00d145cd79715ab822e6184bf389ce9211110107cb822a02120237e803511504b088e3fa0a5ae81b507d0cf756174cac6a1a1430351125170b233312905d2ac01773d244ac20a7a0407f3902889289ee0e443a224867a242184d5a8c4958b82c4cb87444854a11a659175ceaef5f3a7ff10f200afe8f90619132621f8090113189938c99897c8e6cf34626d34b1c1c4c64f10bc11c3c68f8d1664927330679de8848c42140659abd5e226cca409b76490fd68912921c302e19049a532f11ac6026c4a056a00bcc115a889ec769d96456b8286c43ffca365b19255d1d80adb80856210db200659612b36c8865c57f775f5d5389efc6d5ac483c30471c694389c30bb648f51ec4d1c2d1f1ac713feb835feaab771a44992847084849ca8e28450925065e2ef106d0844c2a654208c4a92d010888451c1a6d80a84b100a302446bcba6d735021c0cf184074453d880064768e2851af840094a0c90604921d85b6b771cabf08008891974444850993d8855a21033e126dce2961273d68e0e1f6e4adc18f477c8fc31226db46c30b1f163a3898d968d5614ec3c332c90ad244a5961849b5d4a26b55ef60ac1f4e2cf0e216032354d0249297be4ac97f499254b139076684296a1ccdbc3fcf2aadf6b625fe9e557bac9dbbb4c97c9b6fff4e6ef74e6f934f9959e797bd857fa99adfccdf99008cc8e7840cbdd1886610ea1c9ce9dafa8d44d1665390999a21100000014003315400028140887c34291482c0b8461cf1d14000c819244704c1e4983418ea3208a8218658c31881803103086c0080dd1982000ed9a752c5e82ee82e2cb4b762af5a75da43900276149ccd058df48dfc04610a35ccb9ca0cf40c158691ca904baf4175f88939ae452c149f468f8d34834494367920bbbcb4a6f5118510dd8dd159399b1ccbf7385c996fb4aed4018e570bed8d88139b40ae61e529d901c53d4466c094ac16af8cb960cbd38e8f767c0c0d7518e25792ece13804fb6a4e31cfb7720d1801b69607082422a4c32a57529a53902f76ca5f54d9b3c1081576e3a202dba330924df2ceb4abcdf360a04ca2777bb625159758d15c0796076caee851c6ca22d15a125df6ca82302d2b5e025cd697e1fe1e24d2496923c76947fb18c1d085e0134221e83218c8fbf22fd882ccf72b5ab9370bdc429b56be5ab99c365ee7d1d6aeb621d5cc207ce9e8c381b7a53cd3c78f5b37b98aa25f9873a2dae554f94ad717f9d60e0e81fc554f3306b66afbfd6a098dd3c5efad4cc9a000e58602ef09f59d544deb797d6aafdbd530f6eeb183bf6ab55c7cd8a86ed8574a7e8de451e6a9d8198521e24085ad31394cf8b71cf5eefe134c137d98853421c220d4439a03043fadf3fbedaf21c4dd97796970734792ac755afd3dfed0b41c84b9182a433999c29590b86558e56d2a242c3d2b7220aa8d93c6cc5eea53123cc396962e796bc77f9960bf167e3b90fff5adf5addbc5f3144b72b71ee11770c3c0bba5657df062853ab87d7b72aefae3ca9462bcaeca5ca64b6068ad4aa8b75ecba8fe1d6aee190e7284cc508d0eb32514c9bada11a80bd4ded6033a1868c078e782c1b1b109b832bd6b927cbef6fbab3377de1ce8edf6605207ba2a643ac3849668c91935a168d18bb7bc16be9f776ba9f92dcc5a6153d01a69117ed47e255e2bf192d633071af537289fb162dc8110966c7caa59a98344dbc6b514670c321e8de726f2d1e981a29831b202340216041e487366536980876857a9d746c339d8e5d5ef51ac28329417f69e018f9e0d377ac5787a3b57b0160d7207f0ef868228f7df48813ec8b637d4d4b9e802df98385b7b4368ea8230daf7de1ba2e1c0cb72705e98d5ef7636e6a116b1fa5f75b5e8aa97556df765694c2784ced7cc76f9b999f9ee3601012de2ba7b1c04c08ca92f18b78812a8bb409f4814ad09a159c036b52dfec41b5d1327f8dd11b4c99a9fb021d7f71c3b6b3ff4f7e6789d8412d8578b5d237d48aa7ebd8e53900e85dc69d47e9b653a1759eb47717b1a89d6db8d53ab058c92cc24e7586c4d2af6d87ff9ab2ed76b8c5dae4cd0efec400dba45906713910ac01ea61b11b60fa921fc44df8215a06f2327dab94d2e4b6cee137b0014bd5fd90a6fc09b9c941834a1a6418442a23af0b5467244fb20519b2c3a06bbd2259e9ead57c23d525844335a34b807e376ada16a72df74e526dc77cff50851c467a96ad6e23ab03575891a98f95edfdba67ae28c5ee188a8c2db7f00a0e8627633b44f6eca652907f8875bd58a3f0b598ce9723236936006ca4b5e416462abbb8b552e733e24575ac780a47a0000bb5d16e2c76d8285f2355d2a2dffa625c44016471e0ae8496ffcd50b1fbd2ff17a4f469f87f0d0f77c02b3110e509d5d617c00cd453f31f17d1d133e1928d173b2fc6bf84c87aef51b58f5cf4ca2be780260404336bfdea64be83317a22fbdc1567ade2f808ca1cbb1db51f061ac5d0755d0d08f91c27a982e75bb1878f2750571ff5a2ccc2401bae6346a5083dc78450e9ba637800765f54fd08fb1ca59bb46b989f3cb8e21aa99c560152c782dc260711732144766e84f9a297b28d93a3000e8a53fd1b2dae2566ff3848705236bb3084bb2421619a5c0f165ecf849bd224e3fe45df48821c7ee1c01606a2e469fce24d59bf4191fdc9cfad2de97091adc1abff7a206c33c29ebbe9b6f15bb52f9de7e05ccec90eba27448a8208368ca7c05081a2773c1c33ceef811146b6c1fc33e617c62d24a3423e1c83cea851814339d4714a424116afec3fa8a9c663a073422de630b3e8b2d2132ab01b32fe1cc62350f9bbf134203683c6d6baa11e9f54d149d813ee47be6bcc7ed7182c0e47182f1bbd8be02a00b5a71ce262eda520875352f32f50269043e4b72703ac059a4ba91c200f8f26800c81a237739ab30b853e174414e042db951768f473c0ede43d9a08066388f051a8b82ae37d1eeb3fd740334bf465d00754c1a3706b40b5a6a1f7e56f16a2cfa4db225c09118a1225bed95f8538a397eadad8030265a24070de40205ef8ea9fc8881914ab4fbf7401010e52e17392af4bb3aa12527f78dbdc7c18a462a22cbc59efd8ba2dd36e22864a3a3bc19d5d64669cd7943f78e29a016896cf1de7fa2d9eb02e370d5074f0bc5256c2b7d5c65384ef1e5b22ad6e81567763d6ebc239083095fc60c56338f6e8dd15896348f71b115c3949ee4935ac7bce3411210401d729b8621f5e39ee7ecdde15c62a8e3c4aee0c6e732a31f89228ded8a41c7f2ff4026648919f0ff7c204b16c8a6341c761e52738c0239d26ec7e5253447f567807dc73cb72abb9c7f9522658a18c6296c19a589b473375b779a305940ffbbb2c0bff208ce22073aa8794cdd55fc9bd3daaf91bbfba05747c15763f328e29a1d98b74640e9b761d3fd2742e7c346d3d26d1be6b0e8ec1ae2333efe827664df6cf446e79a8d316ce76f976903c884f9fa9f460afe7415e0f4ba419e1b4ff12d3cb20164bca7326c78a970fea8ba203af0613ae29d3cacecf101d32ad540b9495c5548767749815879e05ba41ad9a630c4c6d09b0e5c515ead19d4047a7e64f1b40e3123b6a3949791e60480cfba476d1ee2de4a3c10488718cf763447e1b24f943e98d7839fdf9412171ccbcb41841cf449949318c6baa1b5336499925db941c3442da995402a50bbe094ba6378256ab2b0bf85073771bae585255765fad117e084bc5fd2c5bff364a2114596c255d145425649182a9db4945121ef33a91c491285cb2400d371689df49dfa04fcdb5519ab1bcfa529a3c7cd1edc7a94b321f8db5dfc747d4e42bc209e899a8dc0f085de51c0e96ce64c1b968de85e3172919a91c3e11f90893a233f2b18854c9554336e984b196738dcf44bd1420fcb310a17792f9be5ce1b6f0d50a8b3dd3195428c2184144c0a86f11da27419fff02b6917daf8dd843df5fab7ca1bd6c6acddba57219a1b2b3e3ac1f64ef7178f3503e35337c078922669b041c28227e1aa47b6c2bd2313ccde30c1d2db39201edb2021fd239aafc092fb15ca6ce80cbc7e57887d653d50afe020fb9ce4add29c1d0df17d2504a11a577d53681c40899d662d39a86b362f6f9917333d07402b9f6242c9033d9b78113609e25e1ec058f7dab2fb195787d33e2c8d1b2147c11f90e5bd1325694ecd0a2df55fc5470cbead363ef6cc7e4f2e7cd104b9ec12a6429663ea75ac83679a7c5e0e2c80693a5185c04911e086892add300748c6978e3eba45bff8f2bd096e11416bf017dd4d896ce8cbb797a108c08baa5f4b570f74507938967e033121cb52466fbbb77afe006e495fb9f3ee6744789d81d2ae461cff6dcd2ae0c6a2ad445e7ea87f12765b4e1c04be6ff3da7eca45b459f35d65ea171c512530fc94f9b9c2c32b4e520602e86ee369a51d20e4229229db225ce51f0658500629266a2f07aab590bafe61a742d64d2fac1bb1f10201921133d00b62a36f4340c1709c55fa8dca42b2b92d5ecd5c9c3c145d6ed51edbdca22e858ddf3b1564cbf8225cf58750f4d7b031638dee98199cc06cead586ca6c6f40463013d71596c841ed2633fe7534989396c3ae59143abdc0140f0efb8fbfb611ccd7e5726b33b78fbe1c3a7e3e4f5a0ff841879647915c27c8f0c6171197b233935f9f866b02262bf1e19293600557aac00256b990563917c15d4147155441d7ff20840305474e5555fe05b987a4bacae07b238231bb07573128805d5bb9745f592b1ff0038a2a76e080cf48570cd3c8078f72863895eb855ec0ef3d8b9d8ec091de2a50944f544210d414ad45da0f1210ab1b80e36f7bd9078240a228ce06762ee18a7cbb3d1d9bc0284976a7159a6ab2b2eb2a58981dd841f0cbc6fc99359c82dfde46388b60f9bf0ea0144ea581567bcca5ea3749d8c4828e455cb6e08a439170fbfd91da3dc317d938658eea3dd8e7a02fd7a0f0cc62b9dff72bda9fbf9641d80a44f563b071debc91a3eb1442345850fd855fa8c1df34e3c2bfb7ae3d67af5af8b8b41994f5fcb9230581b9952ede97b0a457794094e2bea3c84875fa34934086c5448893c8b59793c0779ac06d494a52318877d73a8b4f7925b87ffec53e69ea5f5431757c8d464d629bac0a9ca6c64bf5a81b0bb1b3b15f6a01358ce790502fe63a5ca3364a590315db3bd2b592967ccf787e92b107432d35489009116969977aeb363aab913c5ff465b7068321ab56a582dba0e862e0bb0cb0713bdb8cca1149f720702f55b32d242ed8d8fe3b6e448876ca164736bec2963ddb29ea65da2c81f98d4e7448caaf3683ecfa0246f0e4c00db29b94cd048190ead0ec953c1214ca8ced2d3dbea3d46e7db0fff4ab9fedd677dab73385cb4e1bc8fa0e4df5ae05dd24174481fa110f6a2fd6d39bdce39c20aab6cb8908ee25410afb18ad4818df94d1b1e13199082bc58f5fe17c46fee115ed30f23e6f501878ad6ac45cda00d828ab7094a0e1449a9d7049377c38cab725ecfe560f0e82430412bfde9164ef45e961be15c87abca4b3517c6efbde81a746110bf800fa806e5b5d3122692e9600c13c40e0898acda853347f42c5ba51657a8095c25f5e5a56f37adcf1394cfb01efc3118ef68cc4e0078ec85b7ffe9099a245b3c3c4893d5181f3c87f52bb117467c83d99da49d206f020ef8dc24945b47c3b66ba09863d1316ea51231b089fc7cfec0792aa198cede357cf4e6dd36620f9d6c214e717f2a17b9b702dd8f5558c93139811fbaca8277f1a5536f7a6162bcb4ceab0a33565fbcc1eb615ed2c5afde2c41febc7604fe78be66056ed0916626f63264a9441b102f0ba6468d89aa68dc926a02fe619221598c46afbf80ef1bb6950a84fbdf8d9ec204e35649606acb2d3f8ce940ad2e12f2644afc0cec794a60b1595a2305b17c5b998de320c1af3048bf4fc3496ccb69b8584a76010eab2521f5934004714796c39006a332e8dc0a461d57fe3a5758ec5bfb729eb345306d7f994b0592d3ed5ff0af5291ef585dc8c4cf3fae51c3508fe4486f68a3e7900c77748a5b4c36d1376426bb864cdc87cf172786f88b39ac16883189f0fafbfb022b6b9d8f247e8d68c63b508ea909cb1065509dc435dd398453521bf2013c1dc04e64d8d57830822320409e9ae93b0239568b49973c795ec0f3b501249ae5de32fda5c388080b293fd0cc2a7716ee5546bfb9534f75531bc02e5053e70f4bc091a7adc9c958527386588cf3359321b7103af35fba3e8b8ad030e7f603484adab4d6028b07a161c9f1a0e250de19cb83faeac342e7de58f663ac4e864fce735ac53b4b2536ee25aed66d67de76c69f70e8b532ed6895ca200d6e14b95be51e5420aaa068140025b3e8262651e347c002a6873f041830daf566804abe4bbc71a0b54b286aeee99951a05c556de9fb9a211233c1f5d0fa6859fb051bf6f6a19e031062d2d2abb48c40e1fb75731689a2714ef620406ad59156f11a5d064dc4c2ce8b215815e4acceebc83ebd2dd59a3aba49aba7af6dd6baeaa0dc4e4c67efb49969d3e3b95cf00f2787a829b4d931cde86b618ed210750955a8ca7e7b2c0db61d04135fcdd52de3de94feaee4c6a9fef7bfd6dd8666902ed910c5f96fe006ab3ff6b190e334c4a1811c4c869ae90c0d1bf755f6ba2012ad4af91e9a67e64925a99f4a53d6b9445c4897b2a931a51ece457660885298ad3004c4bec7014e471e5f445ee9e49a0778ea54fce3587b74ba869723bc0e00117422dcedfcd7e4eef71ed2713dd6a62f841c4e7f1d8603e5376267940672f637d65f43b4c6b491723318854a68c102542317cbeb5af3ec51c958e452639735d202cbcc64a37f4e79f290c0bdcd26178d6d5ca053d08c681499feea5add6285892796504163a4b18d19c9581a0fc7e4a05721ca204bf16396dcfe020b166260f3be3b668c39e8e5cce18ac42dd56389c971f58e64b910990098909807e2856cfc0e61778a975f394c0e97896c1580aa60981c7ae8d3d3543035268f521cfe276c0ea06f12e4d3030806d264ac2730e0004ea319c20d03c88c8991ee5565daef8a0e279ee10177cdd0101cf601f71405174fa81c715b2233ea40f66e7a7fc1eea0ee6183255703ade2a028cb5ecd10efd1236ee6608d4ef03688e5509a47d13c6c5ee99383840f1897fd74f8f3da304f3b7b7430732a7e3b227a3eb6c38bdfa67465209c5ada538a8ac6aadb7d8ad142250295aff3eb70f2c030b999cb1a2ca24c7e4c4f7d6a662048b4e9ed72f9d78ab3f970f7b60cb173cf8a51ff9cbb1a16fa130e237c644e583298967600784b88f4d081c0ae90652f743719f121337cd8008cfdb87081aa2a7d0524988679fda97bb54e3af23b840506705babae1f9396bf885f3b4a13d70263785504ff4197b9e37c2f569ce77c68e1244b3cb5c6582116c6176b1ec44baf60a52ccb87afec75312c69a7f68086fe20b36e07cc5528bc6d50b51c6f417e7a968e6ee79445fba6114b4f698422880203cd89b81acecc5f75282c04a9b5c1d95add7fcdac11632bfba5a47b51625c9d0a185414a91d5b279cc5af9fd60d4d18f227b5fb3409f4e2760fce09adba2bd1981e00d71186af59a1bdda7755b266001de7cba3a93c2a82ba110618bb0f23ec052249d73620dac0646033baf269aa1b7bbb53daf1c00d5e4c86d32b5f4ca5b77ec977c8d5dbc83539ac66f3d32795026c77bf0d8a763676255b95adfc24b6ee324bad065e1d2d7e4792b1e7ac368ff3b376caf553ad7312ab57e75ed465a7a396a26a10e839caee65483788ab9d9d8fa44d92ee4b86df8bfa57d4dcbc5b238d9e74297d31d1fcd4f12c6493ace1c2041c69a13c532e165c3c1a85daa40ac99b10b4ead464e5ebd9cb57d670550d6b4cc1054bf34c790b5eea2476847ccd7b8b94dfd8bc1b7d3ec11130ab28da120f4f7f688e7a7d14d042cc673ae878dc191886fdb8b574ac920909d077ed626c6c37d381fe4f7e2c63aa78b992ad355c090d6ede855437fe401e520110670335f640dc675352f0c2db0a5cc566a909837eaeb14a9026e479f04f1b1f79357da7e49b92c1b61ce0fce6db2da519c4f985b50c7cecb39b80d29d13be95e116384760ed712fa8c2e1a5b3370d8655adfe9e8c550feee9d8ef49b0ff9e6b4b95ec5204bc9c9359250b313452d578c99d7d8146274fe27a7273d10fb276a94dfc91f42d4c17128117dc4258bc21ebe61959330c9d96a467edb757400bc344c097aaab5fb1d7003aa6c41dd83ef0709466db72b44e528e51905ac2b33326c759905f35952cb846a2d3998c705f180daca4b27ff8910e8ad77f3d986ca9280d3f5c660e1c75b8eb93658473d330c6c69d892a68a1c00994a123050ea119dd6966d7e733335611c8ecc6a56d4db5fdf788cd8009c53ed1d6398ded2dd2cd72aa05043f200439b856fdfa2c99d7586f712969509ab8d699df26a196daef3aca6b6e57b0796e5cf3b297874bf90f1175634db0f40740b4fb3a81185566e47e20f97d604cec00f5939b50fb7793d11e5940d31a0b67400c574d0d0e0c1117f77fdc746f4d90b1d20434d6ed808ce7170dc6bc62695290ac8780f340c3d364743c2228991491f8c490d55ca26c5672f063928189360d3ad6d33d779bbcf9e88c2f1551c89c55d4104543978daa77e823359d1d677830dd6c5c9bd02c711e1db284a0d43cf14ade9eff63ed7f1ddd0757c46acc8d58babc7c93b00c62b22032356a7d1c5e8bd19264c7530eec16b3e64d9e5697c57d9dea895b89c3a554c75bc6a96bd7af277cae2178a31696dfd4942c99a522a86d4480d45db917bdcb65e90c7035d767604cd7ce3749866b53963eb31c1a06c5423f3c1601dbcb83142ec2b37a54eca64b61bd1c2f5674e2a70e871a1452a97b5ba15466c40e7b8a4ccfbac6afea63b9baf9a9812780c4706d3ae2236b620381d8fc0cef03ede0227c5a5908edca558a73b847f29d258e4177fd582045c2c30a9ac96462d84efe229feda5a7e1ccdd116e5b323f9a000da7c5f8e0178a2f1a1c305ab7410274bc08109fb8618ffc1ceb83bde407d4766aa6bde6626fbb558579b6667d5bb3fee40e9bbb97d2e33d8ab6e58d0a87c3f37d57cfa0d87e521d71c0f2bdf645765af8b96ca20219e678a547a26ffd6ebb9a5a1f9774da2141dd0a7e4cd2357d2bc5255f8f2a6181086157ab6d05b9ad5ff9c60b222e1dc595c32863eee1cb3734680b0b11a4a4d95b18ce1fa55ce02e0a7a43b46f48486f7b30ab9ecbfd04a40d5139c07a9963f541d453a581b0131d3597e5d70ee6bfb53232845f41e593886b1439dac9dd9fa3761856e641b8c7ada288d85c9116e567fee30eefef7d43fd1728ff748053bb8270f69eb70f75557f2e1f1f80e7d478864245e2c4767596d302e191eab99e815014153bdf31629ebcc5c6ba567cdad70ce847e55190e5b5dfc5308a03e06da97b61d92c5a56a26bfff4b51a36e01087f381afcefe3345756b4e103c0e2088d5f55a7e4c40d4f194e4746b66e2837896288b09b6937f3316c224fb0c65aef4fa93689728324ae9cbe9e9232df830a665e718e7d46c8b9528a3c2ffc503b5053ab8ef61f03f41e5918aeb68056a07eee2a79e9f271d2420c7f78258ec18fa4760f975247bae188bccaef42efb5f31871c25e2e2c3c4f18ab2c1813e8864bc3a4de2cdbbc7176ac516bd3846b9eaae96abf72a60574d8ce7316801214e8a69d0bcd0f6a5d074ad4f3038d62f24c916b0c2f8b347369d0c0cfe5f5039f3a045fdead09d4c4c3e4ac91c7e94820b9a2527c60a49619c59f5d75489b8f9af1c87968955f16332151a155a84a347c2590904329be0aa222cf685af7f0538bb9cee3fbc87d85660c2356814da20b64ee225a66c41d0f57ba9290177312dbc503e6ef48eb1e71a00baffc8fd1ba6b1ba45d0c7cce19e42d489864cc0fc80a3a18353d2ffb94646f79b5745018c155d536cdda020c401e47dcdeb3aaead136125ded43871d5da9b664453bbb6740379319d8d3a517871536f7f87684474456fa9a4b991bafd18244f115e5fb4a99c9ccb5eaff218df4ff442c35ca3e0d0e9add392ce21d1c2a4ebb517cc8202113da03a18de4f6eae3116280391a2201f02a052785be8a5c2cafd76f4cca7e0c44001544a3d9ccea0b17f4d949a620c44403749f37af35ca54c5c25d27c9e74e85051a4e08092d3433b5c2c7a64c0a79cc4c669a32d04202f1ce1857b11c4d75e8edf6a3f9f5bcaf5be33a1854e97923a7eae4592b25724f8a8889a1687db025c6d5d971c4f2aeeed7019bbd1482f1a2548f7923c8ba62eb7518b47318079ac51b16213ae0c9b86835a06f595d1d2bb441a435ae8e33e7382cdc596a3e1a2b576002cd4da222f213444b0b96c90268a734d3228fa97361d02692713dad12bf769ab03719bb02f566c280138df54ced8ad2aee81d161a5c2b809b9600725ed14a0d65437032e7b80a5fe229b823dd260808690a87736ecd2de636bd5146c268a91b9c04291204fd3bb7b980e0350eec97c2ac3475f2239072dc12e3abc8e020832c7b63d3a267333292973b0296e4242fde105926f383844fa7dace096010261fb49356944411b115149ade83575e814c275401c5818bef13373664948e9b4d83d0547400fe9940c3f62024a6107ac3923caf353793e6b5fedfd8ce584908314518acc91c910a93b02bb8baa1da5b867c122c692c9fad8b8141e3c9935c1c2f8ff2415e16d15d2a87297588500b7b057aca8865b7b17cab239a6bbe04573dd3007614e922960a4ce5418ab5cc69012664e50dd658f1d086052f3f513291070739063dbc733679ec657d0d876b3465c590976f93e06f6dbde16923b3e781a458626250cd95c3a1ca556775131250d17091b4a45e849bddf781d16289ccc76e3060371d91620f798aa01efbf8a9edbb6ee23b7c3db9e60d12e89d2bd4fe4d300c7346e5140a007704e5199ee280e7a4b55a54d8434a9ad468896aff2578066156e5134728a7f67a115e8b53cf643d05af22c0835e7dfe325adfdf3964cbcb3ab06cc2e2caa74221cd4cf61dbcffcb6e4dc9d97163a95259ee1d7d5c5f1e1d755f46f2e35202f82902cd9f93d3acab529b32b6985c58cd9e97cd9a35533bb24e241272a808b6fa0f31242c383d4a3998ab28849e91e14224a553cabd896c71bd1c7e9f70252cbb298b354ced85cf5372d9278bc822a1b772b840555ed68b9a4dea7d0f15804b0f3c0af13d697417af45fb258e67325cf6d0ef7104a99990794ea483cdd93ce0d471d3e596492df3f7ad57c41dadb4c01e5f5ee41b2d9de15d0a2ebc017b1ee2bfd5b482d799c98ea7b891868a8016e259e142a3680a7ff8d8891c33bf4c50aeed58a0489f43be76f2cdb83febdc64ac052448d15b5bbe6868f614c15bafdfe8322345d09e904ea064d232803142015a29bad836d9e5e1e465951660047d1231838820f5092d8a0b800114e79fbaf1bd3a3643c1ddca41d39560844eea66d4724b9b0910ad976fc3b5f8e77901962a5fbe1b387657637aaab514992743427320eea31814e08d9ba46218614df9efb85c8674b48aad01b388093a4c83b7286dacc9228bff616de492564010a82e112b3ac7f446023d196c8c723080ed225a19e2833c8f175e29b82f2e06a64d81b91508501f90b97a71783a96529ad1536acde91b5f4d01d436a25d14264eb307f77399bb3f8a50af8badca2f9b8f586220d541888844c4e30c59b508eb25eface219d519d144dbd472b0284816a86a3e25c433b41d3e86f7d5eec7e48b562bffe1f474396eece28ac56a811c7039a8cf48d7b76ef13cfe936fe604ecd3bce72048ba46a76061ef7806aceb88ade3a4afefee8692846928e8e1663a85648521a60c2211b3b6bfe93e90380494bb3d6d8af465783e4f387272c269fed3dd43c78f5c58d1763629cffe8462577ccb3667ca460632c45c58e18d674309980b5279b96935e578728aa8fc5c0cd2d98b9ca0f31c9c429a437ca6c17e285794502859f13e31eed0b6450362efb9119086c1927d8a91646c26d8803b2cc326f990839af1a0ed0f213e18e0bec3f3ef06dbad29f6ab75dcbdaf8d81b29da4d97a679c6594993916ed6701d3659877ea133e35c86f67f16990ffffd04fde25b9e0232e89afa4dd3c4290d1f85f081848e4954f8619535148f73edf953edae42efd0ac72e54edc3fff1bd83e2f74d4f1861c45bb9433dfc6c87f252a944c6c784fcbde0546bd7109692a0fe18723376aad2c67b54420fce75384aa36f745032e0197c6a587ec21515809c04156bfa2eea8516b6893d2e40ab21e0d22a2f7a681755013a2f4f1915dcb6f912d9d899a786e796635bc79509807fb613ef7c6700c935683dd4dd5defcb413f7067ad16586d4aa7d8a224af8b3f36c001e9e091259067118099a825de102564d2225a5eb614092ab78bde6364266ea20b7eb1758845997fbf5a8615b51bd39fedc011d35d084340f486ed0dd54bc217bf6fc10c01ad1c4456b76e9e07104480312cf7f0a1806d01ad2f3789723d65b0dee5691e900eaa6a53f3962504f98964573bf41e5f9be9f48e4d4be8f1643518273f6732f68c05d5c3ddaaf755b89c4af92fa3be4a263d5a00df80e6b93e100d10a8ae47048b40d5b6f376abebdf0f7b0f694b3a0f4db9afac182c7cfcea17e9dc8c1be9b8be68d836f241a29cd00dc7ef983f5cf3ef9019b98ee5ddd33f8f51a5a0e5ce2f329336ba4a388ed75694f530525478649b99839a7fee44727dc27e83593d6227c31f6b85e162490e899eb55eeb3f25897afa173fa4380cd61fa9d46eb204192d286867fbaa58d6e89f19aac1ad0023f8799cc224f04adc015c6199a88e9bca279a4f7596fde98af722b3e8c90e2fc8c3f40077ccf93a0406c76149d36a8ee752ccdc61d94204e899c1807bdfd6befe044a88550e3625e309192eb32a1fab9841c5d5e28f6faf53c8e6f2df6ed487fa951993e126eb4e81dc0ad193afe801dd25d9a8b004dac1d385e0dfc8df59087300a0b953a770547c62f52ba506df8c7b6918280a76074bc21508617678c5a3a85bcb24f66f81268a82cf56950068106b03e08aaa10eb95ab7f5814e55b231516300ea5a70c7a152f237ff2f17dea89995c9fc8e53549fa2e4a08e03d8e04f378453a78cae19c3972f14606e1a9aa15a329463349854047b01a5e647bcb1dc0023e8c3e2c02b10820588152f183e734eeb1d7fbdf21f9c9f7ba6e28cdba3180808dfed0c7368bb0b1c5965231b974bcd2005e7b8e27e00e9c87e1bdbfde501cfe5bde73db1b29c48cabaa14a04f21a5065e70894730b35fc3b89ec9e2676668d2b61a61131b815fda8d57bb07587064ce3e629072e793f544be4eb34630dcc6c8b049933f187aef253b9400dbee9c1f0f26b638a5afb35aa124dae21f0e25f5d0728c2fa68883348069d0c7020b1867de9f34cce276c03442a5327c1fff4e7765fe9daea1949a7feaaf5d3ce8d4650a9a33dac0305dd63650d89534c151c7b1959da351ba638e18365d4b58a118230fffc511ec6f80968a83987fd1753895e5e92a2d92434fcac499616e1ed3a90886f8ad0b32e02bb36b4c65307e3e8c9addfc5dae71428df1d3760eed55ba396bb22edad373aaf834cb7c786f85a21400cf18afa1075d0e5fd51de792798a13914d943cba45e912dc68b19196f91309e334835b2dbcb71fe771a2f04126e936581da252c1b2a7183249c062d788d6ceb59bf8311d7b3e6c1c1afac1b8e93e24cb6c39c395be719cfa9dd7c0efba654bcabff7be9f65179be71032b37f14910c7556f4a799c2b19d7994c999d09399fe1dbce53ff29fe6224dd447bfa589e3c1167467e1b23651bcebe88a9b80cbc5b97343180a38b57919da27c5a0391559797670f76100c0836b015efc6a326d889bee23e3420ea25caf35bc21b4cc4a89b6033896bac7316e58ffac00bfcd07a345cc59ae111bd0e5a2f99bd6ef295adcfaa27b007100763d0f40a8d89548196bef0d681647fd3d82e38edf2c2d75c441bf573289383ab4e8a2b7e0ee372baac0d56964c9d5d3bd2afc3d2babc8a4b27c4daeec06b42867084fca03952d52543784322703fb2821294913fca3173013ca28a714c113347a20fd6fbe2578070513f4b22eb672d4093e8c0817465e94f91fd38423536f2048179950bb377b156766242ad1f54cfb5cd5efcae42e18263e9776b8285f0c06647818a7f02d58f0635bfe95f7ee62cececb039b683eb5533ace85650e0de048ce837fc43beaa0f7bbe6578660a7ece74830b8870a10b358376b9df26578abd8de7faa38a63949f5df9817a85b27d19efbfaf99b06eeade1834e65ae18091220dbc4193a47021184e6511d46c04a2763e4e46e6c2e4236eba378ff6b54ffefde69965af2aa4e12026fb18f0b78bb5f26c60c33847c45c0b5d284027e3c1be87595eb3fe8745c7ccff717a7bf9179186cb386d9665d0c88ddcee3846034e350718a26e038b816252e845c42b9df9a51cde3a47b91106a0ae34ecac79d3a17dd364d6969d6a7183cbf185e7bb295285b9f12abbae4381625c5d30d26c63711ef0784eb87185310476079e96e2dabc586829281877f6dae9269312ab80b6d1ea6c07a87831326af5885a7f2d51900c0404cec09e06ad78ce9faea65bb9e9bdac193101fe5483a5f56df1fe05e1d4ff5138260ba102eb331f27b63d37710ae435cc1a9128898f7acb1c4ee360f990da571da26631567d44c00d1798938c03009214d974e23b7a75e448ac9a2d8515f775d37ce3ae40f1129142a308a45cd16b3102425b1c15392e9489f2771e9bd0c19b7ee825229ce54b41e382d7a44af1141a883c08b9b12582d4052b7ef94b59fc12971144f8bce4ea8699d40d0c2b3ff3481700da1b98e33d2a30f34b7187844cc4fcae7c5b4a1a07ea4c9b6536539e9e71ea361f09e92a787859018521c0418700ab4f29e491d5f72f65af4d84b2461221d1b6d1f757a783ce1936f15dc39995001169f65821027deba2bdb7628ebbcd59d86ff01d05ef15bb0523d29b0fe79c1369bdcd911c9f32a0af94d7781f6c29ba60ee9331737e1bd7a5c5f7a4c45eea3bfb66d19ede737043101141c3ed1773f74603e4d69db728ffd389980224bff0065712e1a4cee29496878b80c72ee25d96d7d55e7eeab0128c13ebc561cd369f1d11cc520a8d27d4421193cc3b1fa53f20a98754706489e52a49d11021afee177b1753fce259a969a947a94a2bc4d9f798dc53dc1840ac54d421f7bb6eb4f4440489b3968e7a5cd9a6f55c60626eac610a490e27f1c2b45df0f6805fc3d9c214e6c2345ab8b2675867a28ebbd516d33c430581dca246b42b48cbe2c186467c15ce769b9cb8979de2c5d294df13c07a57b660e82321c0a9ccab233d0e9abdc6876677439b67708119230b82bc49274cd9f04d222344e677703cd96c71119b7c136be542d63901df29427d0fecac9e8f8345ca7b6d05e46743968e94199ca2f240e30c698d4a385ab4bbfd990ab472962b7d64d1d5bcf18e7caa374ca10a3488d8a0a6025bb593d2addfea1e8f45966db5002546799d1f66ec02266bb0bc9dd396fa8684140492ba6752d52a6f19d07ee73b0348a97117843badd7213f967dd755d69087919d22d3d614cb093d276cf1fe96ddb12b87adb64051e106004e0b1ea0c34c3ae0553756bc62c7e7df01c56e87004542523818f0cb40fb8617a1bfd7b79c7babb2ce4d025059929478eba48047c9f1678a9b74d174e25310fff4d599caf80d9eff0d175c77187f055445968cf8de35e4304880d8d98e43d56479bcd696cd70a87a933eef861c94a6fbc3d712dc3ea49bd5939a81fdf8b7e5481827845c5d050a704b0ce38d2f24e26a868249b57a7d9ff902017ed730806175e3fee7109f25031af84f005888e81bb2f51f7ecedfaa3006b98c1913689c2edd9bb8cde731e155b9ea9a76afd6cb472ad32d40311722109abe9d08b8211c407d07366135721e0b5c9f7a8db417c847d53d97704d087d7b2e079a3ad236bb2988018d75adab109c9ddcdf15ffbfe4dffe5e6c42fe234a17d68b8feab97568e28ffd4f93fcb9ffd7af57081a5caabe464a5e9fb3815b6c382a1b3865ff4f7b59314b4d65bfeaa13b6342f89b35781231481c2ce28719657ca9756ab05a46570a3100461f6b13917376da272c8970d9cf297c5c1524cfb834d15996d9db9002669a817f480beebb84aa71f739ed6548fda19de3f65df3e53ab2f46edda958b75ad032ce8f3d0d8bf6ee8fa6af714fe3ab0254e356d4f11a28db14661298721fff11ffbe5f44da9420c61695757071a0b5298e4c191a555b54f296e1ede21e4f43c2b81ecaeea4afc6d7e4bfdff48650bdcd2225da8a85f66899d5eef0680ad7cecdc27bf211637fd5af0d9bff3f1098b8ccd23ec1e8e09922befe8020168bcc0da9cd95badadb05e91ee40018f0f6402160766d4714f5b0b3533c61a385db6377297a7b40bdc0af6b8f03089571cc95b5428d86728a933715166fb7fa3aa19bd25ad6be0c2d201163b23cd0f7f68b0878a06d9de1b0ffa59f3ee1082c05a5311d67ed0250f6dd1b08e8e9df01280e9b89ab49447242cab606ba657a696b7c661ead6c8d431f8e3bb9c80c6bfc24ba86b3a8c9be7cd32dea758c38416ceb6fa692f1d49818b0b4e8cdbd49016c5b40a1ff7dcfcbffd4bec666ea6bd09d368c98552346aa417b1f92cd5655015d7ef271712db38479d91ea3f73f525d30ca3810111728825dea8985e589aa445ef86d02fde274bf4397f36b12a3b7f56594668178c785b5902c6df021d21ba908f172ecaa403a768ebfb734ab91094c6cdc4d0fee8243f557d4e2cffcf49b611c20e9e4189ef1caa941b98b955fc678e552693138fa0917595889351191698bb5ce049b0b7b424741ca33a46ac8d92e13bae9795d3f23efb3b2b73b8f0ae47d85f45636f4cf5a1ea1aed94bfe117c6ef7f706f74ee4425ccfd8a013715e6abd88529d8a4bd1b34710eb6d1d05076ec27a9fd46a9e3495908224dbc06b3d29b6c2aa7a9bdf5a889b1c0524683d0534b7640f6c452e4f9bcacd58886bcdde82100e3b0bf36c12625529134156fbd54ee476bb0c32fe52f0d11fee16ae2bb7572c2b7317d459795171afef1d568e86250127a4b712e168419570481dbbbc299a937f15a92ec744248db5efe97fa043ae00c68035113d9aa7729c32cddc8c564226cd5476a4be9443f6be9d44dae1df5f14dcf25232ac191f2532dc4987641447967216dfd36dfc659682bdb55809946a522be6530dbce07e46fe9d52c279c91ba13a6923972e9e00c1c48099c350fbd4712654f5e5726403199b16347fd392cc28077560d84e88161be2b255cbf69310e7e94a838b229e2442b616a32d82cb787a265f33d8cf59ec230df326dfbc21d34c2124a8ba78734b9a24dcbb0395a6ff697d111c03e94a0d234b6452d3353b240147b6288d6950dad8db8c7aa86fdd87dd5eede4f28cdd67bbca1830daafb3a45c4c0971a21e61b8150d3376d63f5a3134b12dce26effcbf320a01b78518a0b48a1af1448c9cc31e3042f06368a7cbe0eab69553f76f2ffd2a6e315eacfd396c02090838f129ccca9f59e57e9883db4d0ac4700898e24977a8f87b1546282da8afcf3ec52df846dc1e4d884703a0e41d2d9b3898c01c5b9c8f3d6803d4dd4245d821110515e9cd1fa1b03e0016a75592d84b29e63e1d478b94c4aca32cd067224ec406549cfe596b12ae4ae2d43b3e695ad228c6767838d2e71ed50e7b5f5b8d8df8d6b2b8e6edbb329205195f4346d4de081a27387d39422a101ef559c18cece781d827dcf4452221fa65404af3b88392950dc729a1ec1f15eb5fa7ff3e274866b8fb050b5bd258981f34f10949f982633b4c6f8e609a7a5575cff0e2ec5a79bde39624f409230f0da554d7038edf876e9d487aa5b2bcc72f2bdaf8bc298a8559c0feeacb14f2f4f2cd0a0c2e34db1181fe96ba6a92acd5f7a2bb459ee5dd4e50a0e56745f358edbf0ea20b39a3e5e04e660161866918f6a5d954cc1035b9a0a256ff995e75849e1414f5901a644f2c7a03138c7b9438a56f63e1e18edc83444752f896e43038a26e11b69b48872d254ba0d2c0cb167010267e2a551ec2ba3b934b4cf2834c613adfd818ec2122db7c014ab7fa15bec861edf7b8f1faedb1537b168b781d328e237556dad5aa06144a048537931e5bac34f99f300d9a776baa8f3c836f00e6c5a7143438ac96ff54a61cb0e3e90af0fa00a98432ff1007047f40b4c17464ae5323f52a840e1bc0698e637b46d250d12a141c0358604b2755ba72557701cc71ca4ae6f92bd3e6e2e4405d0c9d19026487a1c425d91c8ae274e97b61abeef1a9de01c50f62544adb039cc33d226026cba03b36642810169a56a342acbab790ea8d67e3db1951cbf109ebb3488ac1d9ca78cae6e4dd1fcc994fffd0fbaef3269f1cecfdfcf103f5fe80fe731d9a06c3af74e3ea3af6bc7c5c2cf66cd70f7eb7d05ab6b7c91cdd2d8728bb1ccbd6a0cb5a64416c744c05626ed4bac88d1a59a0241ed6f591fdaebd0bd80d8e58227ed047bc24dda670ef1ab9fe4210834c81008ac20675c3a22882a184954ddd9c2be1dc9ed8c41b60a6bee6407d50349c5e6e6ddce6ea1b61a0a758cb6731e2f09d0921ec4dce0d1bf5dbd5986314b1f395d958fa5b0c8c81fbf89e20605a9ae3b30390c64551671824fca9bb5f6d64cdca02635e8608327ff5ce6224bc32717ec4813e4847836aa80d62208481aad5ab9c11e1cbe03080151cfa23c33c8a4acc1a522116f09c20d2c7e6c3b0616ae7bbaa483d808c297a4582b83d3fcb2bd013c4b0d42d5805105855e090ef569d87ddb64b595939224682215d58d8663f7ea4317a1580441153e67df05e339d146384008d79a763c4194228d26c8a750e38aa808239507bfb858634c1336b852cd9294ea0307ae0606964548189e4147ed4d36699c044335267e13752d75cdd0e230ae7e80b1a832e82554023dd91fb03e782c3cfe046367ce6e6d69d82f6e58bfd545a013a930ae7cfb777076a68d46f6913ebf56007ce0833c197db91601565afa468c9fec5777defd4920ffd1e14264381a69e506f01be33ef94195de83e0d0a249a30056509d914ccaa0a88ff23b52606013a9e366b5c0688cbe4bff9d205fc0c406812e3b7d9a30796d138b865801729315222349e55a36af320dd8bda63d9c906431aa13cfad9d6b2afdf29fdbe0520e9b2f7b7af7843da7db660860a45b5002863776da966857c5054dcbc141c00ad1d7ab2fc0f6075ce2d09c3a15a6efa1559904e211fe698051eb8c3d0deb75229a3bfa99e3a0a6b0c999079f299723ff6752dadf0973a84c509caee1c002d628c20658a247ba1f0a4aa04c875460d6b14d8226387ebd2c9d3230843b23c278704d2a38d4e955cc922b02482c914a3025b118ec31e324ab2ce5f388082392c04c82c1f5ee922817ba982eff379e445aef75513b5315c054a35f9ce805aa46f0008a802091d3afe86893031285ba3be309155c38c1543fd219e37ca45ee3cb38720854315f5fe2e145b218d9f01c093d82702eda2c500268454af3d2ef0d752ddc4a7b08872c2e0d06ce69b74022d504867b34615c7cdecebdb6e0f32cb2808fa04c62776a19235b52787502e6f94fcc723921fd92941a6d155579b2474970611fac94590f37b5eb7367193a89a7a3d0d8bf0db5b7b9b71a8518a57abbef35d01362bb23d7103bf9e78d32d63c62498c94358760d4091d249db4af57a9aab0713ee391c0c46e914dfafe966c144f87e3d4e297046bcaff24152ad5a572d15cc10602e972ea602ce87d5b5a0220fc77488fddc52242cebd9745d1f4405a6c5c00e64fd0e9aa329242391d9c96a00a7d91cf8bdba4b831c5732692ce55f228f0e16f096c3b004c93dba2b3c38c6b88e023edc00422ee8f259f9024187c1209a40b21ef2966af9606f696e0062c97a2adadfe645d14c7575bb68318f15d46ec1ef91d2fc64354de293ad8f5db61fcfde4553e41b2e80e166f3ce149243f2f474499a2191c4ecb5138bbf5f8437d1ff64b73aad4d87bd6004b6296a3143e821570745b31c392f3b8c53f3106708808ac97832af061fe23a74050c51c23462fa4c3b080c727ca592245c9d10cf0c2b5d828f764af72daa0273ad9eafd0e790f3412179b330771bbe67ac3f1d06ec4511a1b65a87f816ba59898c175e86107c76971dc414cf6c38b9552885955d9a09befb87c575dad09bbaa4f9158a1952b90548e6c0a7b69e7d9c21558314d19c9bc88c842d2437a7867ae8e8dca77e0447d4dc9399b2effb8d8509ff504c0ac3bd068c68865a813d5b9912e83d2232aebb5bbbc1e2836ea1b5ad9128d885ad87bf58726832683e945a8ffadea4bd438d9b9323481f11608d8a8220cf7db52c3479ecd2e5de35218edff4489176b6d451327729d703a0aa162bcd1452a7147c379eee46793640f969f30e0b29a5c4698ca1d7cdcb681597f5a3eb8be4eeb626552c92c903bc70d94f0d6cba8034997105d9eb54ae529e53f83c52bb2d35af943df8ae5dcde4cd99695ff128677824a8e155c614477f34f2913bec9b0a51e7da338a5df9ec6455651be250e6072f01d55ecca07ea4390f824a064e68c5fc8119f684974eb5e8d8c51b210b283c86e2597253242d3e079a95ef0f37cab3e23d65063075b12053954a7a765bbf3f82aed7f138ed12aae02cb73ae17495090567f8b396122f2c61b578cc0513bc64c1efc0f3f53d9916a4ecceaaef5fa8fd09bd3d39f4b3a4a8886ced179be72c40018394fe54a79cfe6e1db5384c4c989cdcc26cd9e7b9758ab279cd23bf791a52b33673c01f18afca16865d9d42e8808c8c14b97b4a789c59e3fd1183bf7c34f99315eff90f88a183e54ed1b113096a8ec54bcd2470901f9b99fd9b5979b31b951bce23ff7d0437c81a3817d20fbc5f85f6f51c322304535a5f2a9d0b2357b664221bc83d17fd5d6209260b614c595d0a19f3a3850f2eea98ac6428e5715ca2892a4deae47fd3a112c645cfb83b69d2e8ca0af3b3de578aef13d57a9b5a69f4623bc93742a0a04829f4ea660c74e860a04384f66fd83dc185299c9d66f8c51e62a0ab2b3cd56db942f4e8984ebfebe1a25e20374052f7626adfa7b8dfc5b92108101f848f5a246b9e48ac29bdf4285af0fede83a8acc2d6e83a92b72fbb992cc949c636de1e049776a5acc80c9bf2094296af4415e523ed596e2043f896f276c23cd4e4f8c233ebebd77b7f994ee0fa3d3cfeb4b7bf2d63c6e4f6be71c46fe821b4931dfe2a97f174e1fb8288b440eff2ce71b65242de66f418e7084d4f8ea251141515b53fff0f75b4ce2513a6a55681dd109f4a45bf442e1be41fec90b9b6531808a0c6c712d123029f03f3326287dee773394efa8593c96cd4f27a37dc990fb13e169e94fc68fdfe6c9ed020d400fb9cb6055b6bde738e169719a8c0768981e0a1dc85d8c075e4fb9c5d596e174e659317993ff1e9c4e9e4daf650d7dd4dd03e043e6af3d53737e1d5cd49627a418939d45e1ff822d91cbe74559fc67a351271d6b9dd165285f5d63a4a88891787d23f4bb206dd779a872f9155f6586aa210d8dd1798f70674478e6a41420a585edfd0da70b31aec3ec835e7511bb34e5a691b6e8d8368f6779c2cc2d6ed8c231aaf6ae844754e3e1edc27b13ffd11c64e0551644db997ac98ff29fa8cf5192355293f2d1ef180e09355073486c1412ec2d6f4bffec0e9e59930f83da56e9de711a91f8a67bc1e3bb25510752487885ec4f1e822305f9ee30cb86c6052e4ee5ba4391257cce93a7df81af21b010819ab1e887eda0c0369d3e94e2648fee63cbf6f79129da832c19a40753f22f91da0483549462cd249dac1c5def554a552e9d3f0f0e692c19cb673e2da544fd4889b76db037f599e87e55612655f42ba2862d9a18a289136da5839a80265a58f0a4b0e554a6929d1c38aa315a624bd28585ac7b9a72c440a0b0309037e2474658b76987bf50cbdde5aab9462696ab9078b0a0b0e569e8c5a5bb6c9c9fd068222a947c3324715ec121e1025ac1c5b012fad24ee57eb8ef38aeaba1b91250ad0b4e3d4d4cda570aaaaf1d54bd0541a18b71c0edb8fb1573b4a8257bd7fe03849eafc861030124eab787c26ca1e7a07ffb3609e8854e491905c492a0a1d489dc56583b69a39b6b2813d7421c3bd46a33aa30add55c1b7b0d4440885ac869770dd3c9bf770d868869770df64362f70dd7c26afe0ca1bcf2cbdc059d86e75444a731687bd35266aa7006c40b2fec5517096a4c1c7a07220de3615e1c9956589bf5ad84833db686ce15471ef19ddc6b55dedb0079bc944913631024645f5ef7e7979d25cb1a33f64bc8adc15f1c22921c03ff0ff61786b097abc255d8ca59962cddd93124178214da38788e04c9aca8f9037e063b2ddd5650a784f61f0f13d179885c9bd354d46e89854942b4306c6506b65066e835d39fc2959493fc79a635695abd36764cdc2ca7dec8ef2a4516563b3c39b82bdc658f3ee246ed0213ea810b9b1fd565f68ddb93824289e81278c8aa2e64cd51563faabd7e7d57608d87ce7c1d084c3350f6164b54dba5e8f6ba86474c774cd83c1edb34e2dfb072b30a1eefa5c566837ad18675f7aac90172bcd7bd29149351f2c166a5a583437e2bd219f671c48fdc9c58e9e72f498c73b00f17761c396afeec5fb210626b6710ba091f5d98688d5203a6d45218d8e8fba8d8552dd185497489f9ca64121c56e89bcda711f0bfdc29e4821cb99987dcdefa249499bbb4db686afd171838c2b9dcaf048fefcfb2708bd5f311fcdccca234ab5fa074e0997965719d1a427b25ec74964afbbea7ce5deab2175ba5fdcc10d2182004aa10f2214515c71bf0025cf800a70fd49ebb7d76cfaa3f2e8bfe7308f1c3041e9c025a4e8ce61d8cd414a67ef2a00936f732087fc211b7e087b40aa143ecb8ad5d4ed001f670cfdcca2eb1871ebcaa539c2324ecbada1850c2b74b05b3896390a139661d598c068ead4ae6825791effc2f9e5080c1d6cf7a7d4bc26468e814fd1c14754c3d69300c880a4255e4290e9a65fb66666dd47ac027459bd29cc522498469bd38290beb03732075032bbb9a0d79dcf14148bcd75a35ff32eb435bf14a2201e3fde29795ce144dabd7a2768fd826994cfdca4a8950080789ea4245747dca0b3a4a3888567402f138b7356b227065a9a220490c38de75d0e8d1dd998f88970c63269577e6a5b420e84b0f5f02bb869af1f5251e1ed0fb038d74764b14f0bd6765b16ff6b188dbd7839a6f189d9635bf50e993368fb4bdfe7dcf43ea05853e1ef9c048da126e9e71c8d19a913cc2fd02552420d3741ffc5e42f1ec433218828c9998e09d1ccb5a858647fa747a49939b25256b84def975c02d87c68f5658006f92508ad3f842e05e421aabc088bedbb5d560f8f762467dfb82e734cd7113ab28377c44d94ebff9c55a0ad508619f126ee30c50e95665320b74c1e8f6f2838109d59aa70bc3ac87ee8f14cc008074ba07ab4028c15293b44ebccf5ccef3adf4c27e43205d7336086cea8a21e50979bb38156366e4c8ccae252314d59a60fb4e26e325d0ec4fd7b65129a57904a1da8be506013bc4948fd0af8a85129e354296817482854936a1017e0a43498256919f78ae057ca1fccbdad03c5b6df1a68623ef31099da0b488eee8a8fc033c516fde143b642159cba9e6a1745dee90915d99622c4c07df4f431b0d1270d0bb3901f95dd52e87ff2854f2aa9d1fa1ebd9bf9248a56fe7d6cb063f1cfd4f1cefa512eadfb50c578fa8f4af9e1c1da2155f4e9768804be8b0544f471efad6fbd1d1c3413cab0f1865faea8966c897c4f75f5b00613796a9e0271768250a6c34440dadf44b8e993e6c27467387a389ad14713838285f65cdfec9f1edf7fd5b5bb8e82e60427d9dd7d9f745687f3feade28cd631248f900a8d1839a1279b9d0816a3bcce173549630eb7e83747df4cfad2e06b94ba4bd2d71d69f1bd10582af0587fe88a0b2e53cdeb97d3b7678821ed35b72e75b36143dbe3aee6818d36436212a8194313285349b5f64ab5fcf187731a50c3e4783c1f0182a8e7830f25c1141420013ff4c9f26525ba2641e71fa3d83b167553ec20e516c3e9cd4b2eaaabd39d4da9aa3b5eee12564d38fc1ba633ba7453824add58dc5a356344c2aed5087b8d8622b04adee3607c65881150addf41b2199fc08c98024a41ec245311834f7b216d76c8fe93642beabe5164b68b490eb07515daa25822e5487f3a5ccb34f48dde1afc4ea47277798c114daf5db6863dac69925cca487bf40ad79aa9973415fadbfc90b1841133b6015546e9e03906a30e55989b5761d330ef67e851275861794c897deef7d5162f3180d8675cd6916a088a5465b06382ebd9f7ac83a0f1dca899dae969a1118a1e41273b12fb255b01a521f72bede22e15997812bc85a25cc055ab08345c078182226df509ef5cd72b6b31293bedd3c0eb2d2f8fc21c5778c45b070a8b6ef106247ef6226e73bf43b47c1e6a9a26b26830c6d46a2a8b9a630f0f5cb604f15c7cc3344290133a9f818259d99197fae82cafa1c51faed732880491e37265826fa4597a5c20401138b084777471355978cf170a5b582caad72422c604bac154c82bb89c887093057bb65ce60809500f97ab01070fb78dacff980f2f168df5ffa4178d78b4bfbf228847f5d97dbfff7f14d4438034c6ff2f3ade56d15f1ec9c27f5ca4a59130454cf1fc4fb5a19614d813f956ca4dfb7f2132aa8c4a1c5527edc4a0a4630d5cae12f85239d5ffeb9035b3feff6eba9ce881acede31398b76dc2facfb5e8e5da089471eef51f6f20ca9d64eac07f0aa8da1b919df977c5f80f8d9a3f74a9fc7135bd7962eb35ed26754bdc95e30621b93df2d6aa556eb0f9c75e4531f285f6b7a826be113650d92383fb2f68cacf7355930b5734c4b839bda1eea896a7e66e2d263b9790ea97872669ef4bf71652bb8c53202dce47cd9261b45401e3f8b019d7ff864810c38f51ae07b259a5ccac5fcce445711cc2ed6bcd361b3786e872aa9235131172b89a3ed7381cade06c846ba5af63ce04a8b1b878112ef8772d81364d16b5a85dc9443dd74ad87c25dbaf8508371776b15debd8060d218d3410d8a471ac60b7cf4d17d97e479c9f93d4ebbdaf323887929145d874c42d33e31ad365ae61f975633072c201a0228bf04d898d0c0aa0bcb991202afd608127c34838b56b612951a23de7724895cee34237538ecf1902dd4eab4888a3301386b7b91c215c05be7acf291817ad4b046822431ea7ccc640ef9dc77af577402f30091e56d909b41dc92b2bccdf3c00ab07ca9768cca8a42f48ee9b1f3cc5f601f5d403945b0ccc80e5ed69040cc84ba6dd67598a61b36df5f6e8a630c6c026b4b29bbb8cd077a3b988d3cb08a5d9e1d8ebdd8406afce4612556e620744efed866938b2528b5d72a1dc31b3dfcc71d0670844cb25ab3a9f84209710de98ee414f5b91762b7d2c51fe1868ef04cfb11d8a92efb7cf9381c4c7a9433b0bf4fb64e20608cfd3110dc61c0e2925e4788791855488c0e70cdd2544e3eac60abd1231b7e1beeab5870a1f80a34045036a3c68d42dd19e8e36f831933c51841f8a3555e384f4811e72b4c45ab92910c9d8224a8672bb74bc10d0709c395de46b378757f9eddce049793e454cacc0a2d52096d47e047ffaace68639e9f240b8eae08975e01b71d9325e1985c84f3ae672e173bc0bdae92ac20374a03a884b5f0a7da777206f99dcb3ca7223201e018b8d047d0a98bc00c502708e934bbe4990ac7f80affe6fa4ae5666fe81436a2a3bad99cebdac96de187e37fb2380006cb9ec903f23acc3880f1db20950c3b8fb666c62d8085fe65378eed3e582c8f97a074a2ba254a886faf6ebbbd3d381f74a6a4849baedec13319dcdfcc3a715b8f943afd5f87af914834d67e52a2e1eddee0e32c7304204c839a36a954daf0ff4c043e55bdde89db52336dd48e961abcb2e5dad7b2cb54beca48e712ac9885dd11bfcd42970b252f124c59e225bf9ff809dfa89e467f0142564705d24984b47f9454c60dda53dedb18c89f06958b3fbddd575f81a0d8af5330cea96a2025ecef4e449292e913e0eecdf8e4a468dfd5797250a77073b5bc1069bccb7f4e44b20c2a28e92db80122beb56584f67da644a2f79d75532268ad9b27908a512c4ac01b6c0106c5f7dfa30ee27b98a91430e8aabfdc47a1242f18fb3d79dcd18460876860285eb5aff4590d0d78a2489e9f42c1c1ae88e4f7a1026ff4ce6cb07160b6f6fc3979e95e31355a95f9af431ac958d05f475bc069f7b4668c05da0ba83cb066dfe3db055f20e8cfc8a496c81b4e21ed67f27a7bf512590fa90e4077b90f6a2ef1aa5ccfef5326d3b2a200abf7dcbb1013412b61dfa29824f7b09a7f6c960388657137d9a2f724aa00c5d63c8103c7b1059c3e729d090835b946533a5f1d8f4e9b3bc656522fa5b2ca5b71a224e3d1ad29a133adef721f1911be8053bca6414dd36419ba6de61fc1db08b70ea776b74705ba3d5eebe638efd8e8945f35e199bcaac9277f094d5ad3ec7f05767abc2f2a6a2c4566cf17265810f7022d8c2667b93e267840774cd733a91e4c4be06d197f0420799debb736e9da0a6c4d0aade4725c78a9064e461fd80388589fb7af61e3ebc7cadb11eb76968275a5125442056608612a5326a9ce13ff605f420046724a9e3e09206a39c655ede7d450888cac97e394d3d22fdb20ccd224c5c73139a9c6b1bdbfaee2357a8fcf08577c2d90dc2fc6a66cafd53d302fa41370373e75f70c3a0356d9f719d4a8c2badc1c26674c1001bd4ebca8aeac36377c4ab7a2e80d3d9775f2e947de16d193b5cd66c89ba0c5a87821b66c4cf71de6b08d960a93f67adb2284833af85c1c0c77e5e8ec9708859bd15ea856377271d366b8a1194b443ca8c2c7b7c94bc23837aea13ec1f48df98d6fd81a17a3c6de241ce267805e9e83c673985cce61fc232a78c6c7b8993f16c238ec80a06ecbe2aa0650095adbe5ce80138b6009af2f202b22d089c83bb9e249c22ebbc58eec3419cfef3b7d45d32d042d6f154c72d0344e48e5846533acde3fbf32f22319c14ea344a6440592e6958a1bea9047489867cf462c2b02f5f0d4dafdc2a56dfd0beb832042eaec23b37c7ee500718881bc63bc2271866023135bdfc93b5252e2f7efd7ef2787761c63270641b0a20130a707e20969bfb9a591c937a6726c09b741a3cfa093d92c1a202fe47a6b778146ea80f845115ee1899237d7ff71286302706759bf1e9ac6050934aa07d61ab444b074e000f0e550c4676d7e3154797eb2b8ab09b852c16e8456a7fd69a1a4a00d19a5c7072e0160134b2036aa95a885b3054aa9a0e31b233f3702fb94de0ef2acd8eff35660cd7bc80c580758c4d9e395efbfbd112fab2b0a5c25363e28b32faf8efd7366cc8c9b59878fb252e5e53b1885180a3dacf69ea737975d68085455b6c37b2f7de724b29654a324e08ec085c08e0b462ebb7e99fa1d976b873d514067b6de1093f4d86602fcf66cacf924a8310191a52a3945227ed48d2dd6f8403039021229a9fd1c19a2e09a5064ea218c241194f6ec071841b8cfc208a0c8818e2d5ff62ada19fe84ff5cbfe6b6954a4babde95eab8beeee8e5fe2981427d974b8c8ba9fb35cec176f74bffb0dd9445cdc5ab66df65be68324e80914199013a1d9666b1151adb5f6f8aaffc845022ef1d61893bb65a92390e21c1779bc357192fbfd44a60be71a1de1b8d8efa3a6dfa67f86a6688917f5ec993dd348a7e045d3c8ec993d62dc7477adb5de4c574db7121048e2a081406e7ce07894527a451735f080831827e899c10d1b6650c61129496e00c476441229d97f6977adb5ca233dbdfb53fdf24ed1df3fa69ad529f0ec679f7151be9450bebcaaaa554a29a594524a29e5d7295f4a39e79cf65a1d2eca972f592e4a5696adcf72ca172a4001175494dcf0da401550cc98628824d840082ff952feed20203c09e34929a5bc60ea49351b8e8b0debf959d24e7257da4d29a50dde14f8bde18695a0008900c9c1992e1b239b1a1efd34ac189a11b5729c6cd9db6f3f7e0c4859a82ed4bf45c0ce747a76417691e96f61cde18f5aadb5b6da4a9fe21a049a4e41d7fdb2ffb620f575ef000022f4a0084c3cb1850d313943c291257ea081063eb8f2f29fa1a9b50af0e63105762a75ef8c7b0942096fbb57091864c875a77171cec7995f33df6626e1dec5e1d45ccd1ba29429e56da3d5dc0b8273c72706c87df71b476db838e714a980b4266f78ac6135fd1bd66420ac5c71f8d3549672a5d88c52527812c66eb75a9a1917fd2a01691c082bc7b8e84fc4ff06270977af7dfb18e038295302ddd62fc5f2588ae5fbfe36bc290138ca59a54188dce0f8bd0e5a3ba100e7bbb07991e7db164ad9e21b89c35590249816dcd1da3b31c80270bc306ea75fdeb569777777777777d3dafddd5d6bad3e7cd5ddd5695ef0a679a1695ea094e685f616bbfbc194bc5178396a6c66689274ad512725654ad96be63e77979b0b3fee958c87d47cf1685f064bef9522a7abbe248e9491457756b959a5a51c672de5e68fa73cb7492705c720734e3aa974af59cc9a1573f6ec8dfa9cdb8c9933bef97673c4cc998ec9311353a381539f4d8b1cc8ee8d09c58c28517f60825c3759cc89847682dc0a9057f9712a329f32bb4c18d9a1fe40f6095901f291cd663249eb53f1c9b556a09d201e21d9ec2b9249aaa2f4823644155afe062b26076d936ceba20a567521031c6372e5a6ab9bae1b93432945d1c55a6fb8787fae6a7def08e02856232963bf7e15aa3b2891eb4f1e776db329d49b9193a225b956da91d9ec294213b99298b03b9066a1d112a2a1ae491cf54b30dab6d974917a7c55ffc81012da12a25c9d14e5fac428d76e56cbb53149e662fd1288c06ec62271d457c15b1dc83e7d4e0ad66c7c08e51a0425d76f468bc12c576964c4923c4a2a939ab2bf6936fd96518b280eb6d9302ef66fbd756ff6636675af2c22b7a20833acb43b60cad1fe7c8a676874d89fff637e631d342de54cbec4ee32356966dce7dfaf934e1d3438c61d07886cce3967918e229a17e6749fee3ebdb671de4604b6b8b8d51867e354f7240874ffa3bf45bad8df6ddf7d3765534ae9a594357330c373340fa0cb191938a2de7ae99d025bc0967e6945d7d871fbae14d7b868c38326b1945276777777cbee962d69204803971ca1d1ec0fe4fbf7785fbe7c8a696a5e90f2372ca594524a295b8271a7f4a8b705e84fdd6f707c1435f68183735384f3ff8f73e3a3c8c70dce8d0f1c1b9ade91d164453d3e473a062bb23193c164b09ba2ffa22fb2d13f453e7ce72aa43ac6ed696d7c83e3a3c8b10f1c9c9b221cf9ff8f73e3a3c8c70d0e9d373e70666ec6ded98915ddd07cd07080d0e84dd1ff17c1362b3c093353604c0e77596ef6c41902e3e92992473b31994f6da0eeee7b41b088fa6ada00ec97539a2220e7d0319bbe0c0b37012303b6a724193cb7378e59a185ec3f6f664f9aec9f4a5d4961c049650a12a1b46da88db7287e018698a1983126fc33c0201548df029473f614ea6e7ad7b5e5ae2b66aee8a744f944a61faae67b73e2efb9cff1bcfe7c76617dd548da06bba1f75cf8bd0d227198f21893854c796ca1aeab81dd77dfbddc70d76110ee0a914fb815dab5c269cd5cd197338b5be88990d1cc3ef1965bf75725f970820891324152e6bef75d846c812eba52338676c54cd691eee998511ad11fdb89e3298b90e9d78891e953d393fe86327fffe11813c6f9c2faea6ae0f7df8b33d47975a1ca710e13c73cbc2fe19ccf99df96bf8fc314cbb9fa7ec68b904e429cb9a27fc30e9238e86f61108983be0d85fca4a62b863ed203760d120931571a591deb77089e84a194ce9e421de4e40ad049cff9aa24a44afa19bf992ed2d3c769200d4857cafb2f020dd90bc1a79132251a89833e29acaf962040a7f545a372a183a693db4e5cb42fb34d42fa0f97b06ae3d13f7365b16aebbe87f7a637e1194a24dc40214ed83e7345bf0be55ca5a64b0372451740a94b0dac18c4d7c50c7066c198ef3643b3d215e0d833396bac6281e67e5512fba78cb36c22cfb8046a90e9b23fbf85a48c12b20512992e104ca5fe4591c5aaa1a4d81204e81d661b2953cad3ca9694f3a712529c4f242686c512c5afa56a2e3590e2db342b9452dadddd94d24a29a5d429a5dfb24816512ecb28443031cad90683768b83285058d4d0b8bb3bc77177a3518888a23ee9eeee76eadeeeeededddddd94d5dddd4537383e80b064ac8d069ba5133c444fb80a3a6adcbfc6431b7f1e364f9bd2d0c6e65290dad4f0a0798d8dd7384dccf4213058ef782bd6ef8d89047171aa7a008e5f2d37ac06432d480d0d046920cd1ea1c2cc0c9de9a0a199a1a199d131d3314343e78c0e9a18969ccdd04cd1f1c294293e46960e3a29a574664659b224d39f51ceec15329dc73af783394718a3c39cfd1539e179266f072f5fbc7ce1eda0b4846b881edc308612470c51c494e659722511a41c61841f7a9c304291ce8614961c916236822e9ad88083164d8aa861d22e32e5c0122d9488f193022b5cf0e034318e38038ba23292f002879e24868686009252059073f18325346c10a0e9604515a21f1f9a4ce08a0e60498e302209306af0588f1935237e8002335e63ca8b589952fa2e48c284942328968872c68bbee82ec58b6401cc10c215297a1086cf115ee0510e49f04cd1831e1e5e232b534a7f8b4cb52082099ed91424509ae830d4f3a22f4e5705c6f842f6c30d3b42e0e1c5a3c6045e2b02820f174457888c04e10322622c2d42434d7af0a2082b4450167523289962ffc8132408e1040c74c8e206da10b25042848b04562005d1183e248189250a30a50c124471860b94f8d08321aeb020614118b419c87aa842860c9ab8028ad00ec8d0a2c816580c91e4b4c20c8098d1108611508831e3ba90c2070849f450c64e531e0029b13c1802081b9c8062648a265ec48837be08ff9c7425414208298b208417265985131de070c40d3528b1320347d19b53bae89f032503c7548a0b08186912eb89fd340102d10b885af2fc3be79c935af104955e28514314497220450c867680a44a77820a9880117404144f7048a5c4940d96cb80a34bb8e08c3be79c73736f719c9477bb158f20c563ea53df9970a0e5c008403022db913a70418df4011e24d1050c6a40451112bce69c73361370baba3ce3fe296749917beaa08049911f88e861074090e0752365e81579061104b62c310b82071f74c8c105af99c48b123009600e77d1974bcf812761bc9839db67e4d3c867c98fe911471e4fc8130079b648999e2e03c8955c41be5812874b172f5f7c0102e54b18b9c45eae8574cbb632964c32ace459462ccf29037251980065ee69955452d5985e2501f932fd29bcd9a9393dcb33e101e6305145c0f4a7e761fa93099b9e05e798b0689a26acf2397ddeccc7b9dfa507f2e5eebe77dfc396df2d759c9099390f3bd9efeeddd350c808deb3252ff9e6db56fa619f7bff52d8bde721bd5f31902fdfaf5728c937ec38f769d9ed01b4dfcdc7713b247b6f43fa1e9672a9f4a5fef0ccb4e3900ce4cbdc77c735fe4858d500fade30b838633c92a6f2a72a7fc72dcb1bee1e17a74b18e0286937f371e6d7d8cc67e981b66cba2856f5ebbcb6c6353bb47e1884fbcf61c283befd1c26394cb6e7708e3857d8e65c9c7371d1df97af0da45835ff566c81fadbf3a07fe94f5c5fe7255f16ab1ad3d4c43c0a5418d142490d611421854eec0728599421041e243abcfc6f70ea15b5922ac6a314e07cea75b5f2ab9477d6e049971280d2092b7cf2d84042642656b26422cb284c8472bb0c217bc90311b9c1c9494c3f5d267c2f08caafef634c9612bb0c61492c249132ddf7db90329efb5b0829e3611b12477f873b05de038eb2688894297dffcd74d1cc55733f9a90fd92365096708bc4e12257f2fb692627e578f18ccbd084fb920c49fb67db8f3776ee0677003f8f2fdaf0d608b2625e9c3fe8bb27abac15ff185287541b76aeb5061e5d821190a779865ad640a424a69f2e13be170453a97f51640ddd998b671cff905028a594da4a43e9cdaf49f369e8bd0dbba72e961ae04f9fe251ba487a8ac7965c72817af47bff5cb0cf7d0b168f4072e40f8ff4cef8c651cff3bce7b84f277bcd43b9b758760af669c8c5327d4a31a53353c896adb595d6dbd2d2c207060c86b24c965160c0933dd3c5a0c5de2e43805e0fa088820c8c9afc40460c8a1c216f12c0f1458fc9dbb77e6c4fdf3f26db393347172031990281b3313c0963fb52d9a23de3f363e6f43005ce158d1e40ff97234c503a037c114c85d4c57148fe211fc897e96f9dc268f3f6b25318697d1b8ecd82bf7471c3a39440be4c2f0dc07e3fe2402e9a96c8eeee719f93d20a5af976db82008edf9d023a1e5b52a9ce3daf3d7fcf8e470a08b9289f502a44bf41af65d2cf08f0592a500f6a80db1a38f17855b9b34ed6c91c12d95e9ff5ee2dfac5b4abe0ad31879f419180b5cee953061ae8000a22c6a8c20916df4405372cb1c1a786134cb95ea5b47eadb5b660ce4927ddc4fe54bfbc5a78d2bb254b9a215f04533b482db89f7a40e972b4597ee717c11465e2dd917084072a2628638a218a7813933b4905e078e37523cf780a46867386d3930600bdfacd39b739679de1a8537fce3a7b647d1ace1d4e257e18175bb0f029de771fedbe7b0fdfe7c250be47ffca71caf20e2ae5537ab78dd2f04adfc2397ff4a7d3e784c97ebfee86f0f9bb37d09fbbb39432eeb90625510be30446c8307ab5ce0b4ae024092b20c2cf151a5edd3e903c9587a7484c16e1f18196b2f130e20d9c2aeeeeeed3d53b9d42f24b72bf8ba416d0f9d92056a381091e1bd8c0091218c58684a8ece8e0d5cf8aa1d5a0c8c0022faec841127c18c216103032050ab080a2881d23a83a740902f8f24519bc2b45bf5e058929268022e6b34392d509665b18e119424a125efdb2ffce78c08327a45bcaee6ef752e3e99ee5a7a4a445cc6cd84c0942644776a416ebf1f9d96c9d09d55aeb901d1e529024c0511ad5e8258a7971063443a5586bade82d45cf7bca396fbc544194031b70000611571a8aba594fb9686f9a6b8edbb66db3ff020cf7c5fbddbfe0adae310d8eb70f17dbdde9744ae99cee8ea5e7dd2ab69ab96a2269ddda6aabbbbbe79ae9b876fbbbd717daa7add5ebd7eb6d4d690edd704bb18a606ed3331d4740f26f931537c7712490ab6b03c483d6c2cd4288e439936c7f834a4d054588f205123f56844be490840e52a4c0082a5efdf206512d3ceb9e8734575bab57b76fadb5d73601ad4f296e20c8f3bbce49639f5a1c83fd2197e6056aadc53e5f98c125f5524b1c94867a9e1f2d39a6775584900d967431461329af0e02838192174031028b325ebd39b9f7e6822fd9fdb456daeeeebecd5837827a468fd88a18a5e0088a124b38f927b62022c1125800657103afbdbbbb7be224f667dca76449d2d1e1c81350888a2041c5ce027c30f4050e4c8c3041b4032b46c4b830e20c2e7040e1c912289240228a2fbc6052944afd8b228b15134361b097c5e1e725fd25a3986d2183bd242d13e99d584c7604c8c993d8cf9220a15911912c168bc53ad631d6504ccc0444349680dd83a41d9e4ce298ef09b9389fb0b04c6bbd988bd39327d20e0f7622594b4ba0130ff5954270898b6050cb570ac12027e01217e76c717179f93a2b2e7a301767772471cc0f553c4ca837bdce0b0c553cc06779169cc3f2e0ebbc2489c7e959700e95241e2c8fc2391e4be872f4029babe9525b0138bafce85263093d98e779374b690c41ae2ca17cb9d0bca5430aedbbd02657492f48ea00682e56623d453edefa88f2fc979f1720d2ad2e462e54bc45c370a14d978b900bcd45c88526669728c0d1a536258f2e4279be0bcd48c85ba30bcdc5e8fbee88d5d5208fcdca1563ff3933a998bf3086f6baa3d173a189f986b736fa30d4a5365d28c85c8e765e64deaa79fecb111cfc742f48f27c89e58983591e5f7a5e7c46975a9e2f4047de1a635445b059cc5ba347cb326f8dde7756bc4589d01df1e4e9f5e4f9f94b093c093306a096afd72531a1d07d8257a3888a2a95ca7c28187e85eda192477be4f4335df5fedcd4d3d801343d287f328dc4719f6900305972d36319b2afa3aa9865365797c568aeee16b214cdd57defb4c371242e3cf19c642ede3ff5b8f87da4e7c2d229e6adf00473f13e293cedb878dfc3939575dd89e679b4b93afdccd5fd3e0dcd84662c43d3a5e2b19d6673757fc32c4373755fe7754f3f2c24d40e17b6b8a82261163c936c646154e5c85b356e8024df47c1bcd5f93e2a469a5c35f2d678faa954bc45874043068ea79f7c537766f68936da1e96a27cff0b47965abe351e3f1d91324527d874ddd77d96a31ea3538c28d386f27d8f28df1f53271b94ef5b988fb7588082846810cd6789794bd228ca978651be346ab27c598ee47b6fc7e111ccd3710de54a25a4739d491c970909d457359aabfb2d4280dc7f5f8df2fd1a5485ea7defdeffc254f89d771d5702ac962fcc67419c68b228532011658a588d393bce61deba77bc76c75b7e45be5f5cdb73ef532229f392ef572012f7f76bf4a00f3e18ee30e94821b53117ef7ba1e571f1bee986f4fa012c6c052077ff44bbef71610d72f1fe78a2e5fb27da74d1da89688ab76af74f56ee4b6fa176f23d6591efc928df53957c4f47f9a260f9f66b44c5f27dafe3c4fbf76f786b4691af7f0d82b9f847006a34aa586b29a5d4d6a7317cb03cbf6d110c06a341542196fb677d8315237dc85ba307e5fe7e9f399416421ebf3cfaac7ebf0dfd4bea51f19dab2c24a7131facbd9b7a3f3028319467cae4ede38d6cc3288f1fcdf45ba0998631d0f1e689550d50499dcc9ab913744f94322e71d01f1d019c4c010132dceca2ce4bbe2865e80bd3c001f49738e87c6fe259c2e09f249ee47a5b2aea45ae41ea13a97f83636d38c319d2b0e6a9526b35d55adf7acf04c13335017ece91ebd7d4b7a93f539fa616dd4c57bfeae380a9fab5d61edc0cdb73f8f698e105be200167e89efb2d9ce146a093c055f1e03a7c7f7bae83dc6f105e0c43463acb36cb509a68f839f256504b1a3880f2673cc84c89799435d71cdaf078238f37c3583cc264a72dd961f29803dfc8638e76f959e289d358620ac946ce558f2b817e3549888dbf3894693653c848c5a3fbef3f9c333b3c87e68ad443ce1ef725a9a67b395773759fbb58deabaa751e4d17ca9fc2bcc543b3cb2832e0c93ed29d22248ac823951d61258ff408fda14034287bcbaffe872f89c7f71ccee1fe0bc769344e22fa73a866c7c3acb9eaef30cda78fb2ff2cfb50ffa878dc9ace8b0b553cb8efbec3396d34578ec13b8790b8d8028923884ec17f68f0f4cfccba090929259078ea4525906414b28c82c409b297659418cc2045742910f21360286102206430032a65bc3e13f460248723ba50a2c5cb3fe55dd0b081860d60adb5d6995b1e21371129e3b95222522646aae0a2ff8cbb571b0e21921364ba1a669f7e6d61888b330ce2038e729623e3ccbc1094fd6b6414294758378fa94c7fcc41756ce851a4c45894922c7522e3a93507990c1cd6b16df38a3c2dbc222a9e3c79b28450072df1a48958adefb22e8286f6ef8fddb6fbf7526aaddb22600d1ba6bf6d48f2051aa21db784bbdcb5963ea5f6fe4c697ffb19bfd5da69ed4f7ae77c4b6ba5d337292e2e5821b6826c851c5688ad90c30a322bb5d672a542b3ad52ea64a990c35336aa0b355b6c2d1e81d46ddbb66fcac7c537a5fb62e6b194cb3c078f790e2e3bc25677af754acfbeff0c2d46804cce3aa7bbb575d6a29732a4942d2def9dfaf20538fa943c02a947721cb1398ed41c3fd49ac327c70f35c7911c47fc69d837d86018077223530ac56ed556a74dd05a299dd12668a55028141afaad603481e2832c7f964ef8f4e46ebcb9b3e9bfef599e86757bfba4bf178fa50d8fcd915ce8f295b625f5a07d6f23edb073c6ed348d940bc74fcac9bd8ce1c93c7eadfbdcd3e7f0b87999ab7fc36b2f116abb48a750eb73a41d35099e84b175a672b022b35c80a95bc3930e4618798e0706754a69bf64e28a1242af1a7a60bcdcc793d2a58ef7102b34efb8dbf762157f53ba5ed1e9e14297f1b83879c0b1af4899f99327cf1c4023fc402587593af1c390c740f3e831af7a452e764ca7c6e8b2d0793c763bc671b55677f7e77e66721baee1fca125d868dbf61bfecc00c7ef7df32ff27223cdd23b0d75f8ca75d0d09ef3adb59ee77958f5fd0fefeb7fb8eae42de4c27148e6be50dea9932fee229dc27c2a9d56e1dd8bc12ae078bf25d7faf5ce5b495501a9e4ef7b18beef7b1bda048562bd35bdff3aea5d0f8ff75e3ca6529d98af4bbaa550b66d9b737e29ecc29148eefe86e38d7cdff368febccebe17eae42e1c3233c79a91e1d5a8c1e1ef93985e724b32cd9e7f3552e67e4600c72fb358f329c7815c08a304e45e727f91707f7f38258d80ce1cb7445277999efe077e83a10e5fd1fcbdd3a7b53ae93d1256d1c84cfa1664266155e97f907e7b12debec485e3370e2985a470bcf9d3c95e08e4cb1de694740af5b97a2b0f8fed11c031254a118f36b207734eaf83cccea39d178e3af99312ab68649658b5fd0ff9d6fef6b4d64d923892e77d0dc79cecfdccfc3cefd26e7698bae83e7277da97ee33ccf6624a37329ed06f0c70fc5c924561d4693b71979cab25fc09e967fcc6f691ba399df6f5d031e94ba5b7a41da5aeebde3ed7bdfd6e7b9d3c2437d8b9d73ab9fd4a127ebbe1775184f9308c8b9dc5d11dc6bda75f83fbd17bfb9e178ae1bb48651edfdf765ee72db1c363981d53fb763ef9cb4a496955008e725633bfceafaf8366d6af78bc17045374877cfaf32da5b6ce323c0933829976dd4f124de7b69e8fb57f03e6ceb9699f0b75f2a49da5a4ed3ffad5f0e636e77b5f931c20732849fe84f4a570d429ddffc1bdf71c967fbfbe4e9e7348de6ccb697a49dab610c8974dd897e814484e72904cfa4cc29f8bdcb6614a6f98ff613a7100ce9fdb773f5e7a81bcfdecc6306f1ca6610d3989633ec85df124cc888bbc4e17cb7499a60b7cfba8a2e9ea6f89a18c66ea07f499ac16596d1eb5c058be149ab6efbce1d1a614ca170d513d2eda6709513e7365df14a27ee6ca3e18a2806e92120af914f6cbe5ed8f31ac36b960b0251583c272ae46d664892c98f5a67b41dc58cad544c9642dc0b430805cdfdbc213720d07904fc8f63d1dd088281895a2b2b044d365efb52819cac7c5214188b8684b6ffa1ad77d0d079039948fb7606032ea275b1450b6f583788b72ef9d84fa755e203e054d9dd78968aeac8727daa94a93767c343c5941a176bc25513b2e7ade7f4f43d211293c7de1a9cae908b66da87b5160ee9e8628a120a0a093d074a978f8f737ce4105e193d05cd9d7795994cc454b3f54156f8d96887e9f0d2944538cbc55c33eaa863a9aae7ed9ff2891b746942c0b8b9ad564394845cd50b3bced8c27daa9289f8aac388ae7443bd5ec9f82ecc9285bd44eb627a26ced6928dbd32cdb9350b676fb89d93fc9a64bbe7c7e805243d3c56239f296a41115657b8265cb93edd780d5fc6dc52398ca60e85825a4b3f59138ec8f2c1fb2b5b3b9b2df2204587ad3d3e7def6dbb732eb2365e48d736110222eda5719d1435946a1e227d76c5f16d9236fd9b735fbb6ca6bfcbefcb2b01a24655cb27dd920437af49b5e927af89776986c5dc8c3c6455b13da236bc5c50d966d4dc8c3c60f606b73657fc651b3d1d6ec7bd5be6adb5033fba8212beca38aeca3a8d89755b24549c91645942d6a4ab628a36c6bd91e65fb1badbd63a9e5e1aed2dbf79a00db8f2829282b6e64fb3876a5a0acc8f6252a0b52ed1d5f594b296d988b36267158d42cdb47d15052bc3502b141b94271059466a8216babb868bf14daa3b9b217db9a8b7608701c6d2ddb67d9bf600a179970468de5bd19ca97e7de739c69287fdf5d4194bf37bdb77d1b6907e9bdee4bde7dcff3bacef3ba11e4aff47def03e78628c3e0ad1fdd7f5fdfe6bf0b04de5afa61faef4dff59d20e963087e5c130077c70aeaa47c307942e7a5f5fd5c3c1f7972f558ffed39ff00c2cdf2f5f9785ee4d3f33c3d273e1109abf37852a17baecbd877f7459e62ef49e66ef49b9e3aacac3f976a18b18208e8bf5397cf3242ba0fd99c912ca17184a1c147fb51fd07f6939cbd56aaf74fddfa7b2d57f6f0d637aca1097fefaf7debeb75e4e88918bb4c845da555c1c02ec23dc3517e993ac802d7886e670f1c3e3e51e6ca9b5deb7ddf8b77ffadc0ba1590600640fe8646e7b8f86c6451abecbd7fa5e4b4833d304d8f22de8c03449c297a47a828539fdfa14f009dff1f02e4ffbc3ef9a009ebecfa60be6e9fbd074e1a7efb4e93ae14b2c2596d2d84f6ccb4b77f5e94da7938fa956ea298d1aaa12fea584124a08657e79a9f1f2335e4228b3eae5a5c68e140d1aa990661a31346033ca3b48426c6cfc096f0380c7afe261c2a3f028e01c135ee7e530fa1ea3df35fa7d44ff047c823d6154e32d03640ad278fa94b67cea2569478d962fe16b387a6e0992ebcbda12ca5c42286404b984afe1d892535f82cc3542219d4bc034293c43da41831b42f3cb7324171670e5ca95fcf292f4008e4648f34ba872a193d9a39f09618e096f931380bf992b8a0ac7cea8a7e113c260558f19000160550f7ffc18cf60c2fb7361d8557c45df256c2b2ed2afe164803f493bc07cfdbebddf8251610a2118c64069b65d1bc53c762dd32785a08bdbdfff9035574f77588efbed01312ed2cfe1227d13c20084a00c3473f8c7c54da307704c0100612afc26e0cb11600a5246661659ca53379c80a795e8c9ab2ca308195129a4b73c0ec91be6c0971bffa815a7b08d2f09e9673c49495eefe66094ccd93d9bb3fdb64b3635bf7bcfdbdefebddb53cfe33c15282561e92bfa75988ef6b7afc1fdb8e1eba2ccbec16cd3bab5587c16ab62eacdc2c4016ca775de7131c5a3ef352d491779643c3d30177ba7d60ff652869435f48e48e993fbe95bfb3e3d16f6e3aded3d198f3de2ad8a7972eff8d81ddbfd52319ef5bc8e4503b2415e6729f5228c187ab10ade02b71df6bd19aa78cc9b03bece8be50a78590040defe620bb330ea6e61dbab38ee16e087524a6f50cb9452eb9329ad41e973b5d6c8baa99937c894d6680c5eac87cfe085aa1ed31b9aabd7d70568faefbd2fb441e7557a53a8aa6f7a1b745e5f7d96d779d1b7992e10fcfa60e959700ee94b58f539a6ffb0aa96c29f2bfa354cb948bf2080f2f585f26512cafd241c94a100470b8b416048e7cf4796fb8332ad9138e8978e008eaca64d978a87a947c9647a9d57bf47345d24acea417af0413cc3f7a4975f0f13f668d89b91c226caed055d370931cba617bd457a39e79d2b971fc0f1f3f4f7ba85e8f17ce6a43b3b3a2bb55abb6df7721c10485c0481ba1fcffb3e12c9e3f1645e4ce29825d20e0fd659d9e9017da44ce2981f8f8ba0ccc509c6c02fa1f3a8d4edd67441e9d0d48c000041002315000020100a0504428158301e68c26a3b14000e819244724e1a0a845992e328ca20440032840063c08001819991113600e2ed3b30d21fe0dea543bc91630d4189ee0d12a084d46edafdbab91c7b0a8a39b4c500f6c25fad1ac05abe7370a2994b0fed585247d43727cf7be4532937539c5cecdc1811e6640f03f760d26fd683aedf11090cd3d57ba6bc95389963717d2fed0a1e8b13bd9c407b9f648520ebbbfb1c34e3777e2f9289f34fe28163d15394a6670487dc8d1429bf4142540cb234dc696099404ab2651d6c13bc52b4b4ca43f9975cfd7c0dd0800deb7cac571a74b3881211cec456c58639c70e21dcd47735e2ad96a4e88dce442ff4538a4e55580d2429c8e8d566e29b1c67b9459ab88c5d672e248b48dcf4ce2352c120ea88af72200a66e9033f0b6cb861b36ea3c135ff1b2127a184f726740c1dcefcf903828d20aa0af7c429dbc572a68fa40b497983bb1b8ac29af8fc06b1cd166ac92d49114c5ea965935bb2892f775fda2353ce1fdf80596122682588315332a11dd1069ab0100d8371e43967950ea9c9965cb5f6da6269f3440d94da41740277ca4937a4fa04fb83bcacb8a3300521c87ff034e433566fac3abf6a74961e75eeecbd8797e537c3371e69edf991394c8ec51b4e58f2555330f17533e06b67603fa04e6e0c6f21314a6eef979c0e128cc9183e30bbe80fe6a3c9e84765b906a607b46cb76f193c71be0342f3ff376cb6e9325b7d92ea6eeab0b067d685f8e5f6f52fc91a6eb1b242bf0782076cd6818a295fdfa6d5c168f9f32bacf4d679f173298c15826dabec6755fade90046884a7f17d52d87e429732b61356575b98d26c8145e351afa009395385db10662aa1928868fae4ecf36fb2bd81fd1e64b2dcf4039c6892ad36e2906eab43de3244cce805485f1a55d4ac323aa7e50b37b1258a1de065348d946542e27a7bc8cc948c3ad0b0444bb3f8b63a479d1fb23abf4fce4e23e97b6a1d7d6e56931329e920bded6aa508fc25da7b103dd25cd39253470fa3d352e2985f7bf022e8847c9f32296d30643c35ed06e3866837c149e58019aa8739c13d22a096f315f71161602f69addfd9dadb32925499d873e9301b3e9ef8e63607361a2620a960f23900bdd67a8f27826c5222b902eb541dda53b28592f6b8479d25276183ff61148b5b78a1da5cfbcbca7c2f0685e8ad744d41fbbd592efeacba25259649156aa5dc64a96bfb3e1de305f36c607779d29d5307af8dc3cd6d09932e1969747a703272a45aa4d7d78e9b109ea739550444f984f9ab788ad08e30bab54b5822b87e3290a1eb7aabbfa9b54e333e125cafcbf6dcc14dee766c3aa1f8158e04aad553a0240267c52473e65d1dd043f66182c8e035eb197cb602ceaa64e218244448a1e9a080718e8b6f78b85a4cf17dcceaf75126e33cf5d49b3578301db52283d55436af727a2b479b6446b579f5a5677cd86d57ce2a5d5463c3b10c247d9a019e6e2dcaff0946bdb0331acb1ae24e5c1ef1781b79a9991599ab6bc5d24a2b9ca6edfb402b9e637a3d3f1f1d53492d07a36c43a3c45fc9b5bbf73fd38a9f06290ec246d91e71422e57bdd28f67387af94cfc9fb21a713981ac7a0edddbf004fa3fcaf1712cf5a4f0996231445aa3fe8a02b35375b5e445fd26f106107c76100875c00bc662e94aefbc24b63f3394de6eb4510baab17a05ed8d0a32e4741f4fd83065970cb6e0b6d31b8aac1af9a0ab697cb37e772e25448005e791106048385c8d53853a71a3016db66d74f55446a90e663a39b87682c5567dd0a4e17230e6e2b79a95db581a39f22b6af293bfb3566a304dd668ea8115c486d240c7a53e6b8d11e1d23c27c693a2d72c1034e8ad930d1f97834100d1043c79a2d12bcac12c7433d118f7f2e11affa5e3f4679a41c095fc6d7201959ce96450017f6e5f7410411cba3bd7405ee78cb841a6d8048cfcf030e4d4eaf534bf326bc74787e7178fd3b7d6f4567fa8d6193194a37acd3e54bdea3a82d2f181ecfde43a1491b6cec9e8a7b1a551a8980c3520451da13c377c1c21d38902368f9e24439b8017ad025132eba6d39459be27a8d82eb6ec9e0726753892760d3864da6eb726c68b56de1d6f6af0b4210b43e63f125aa5edd8836ee35f0539ad50e87cac2f9c21f6c3bd32a232e829996f31043ae54a98faaab543a35f4e6ec1dd43b05406b18a66e50d78eb2aaaa00d8cd14eb251a103754270650c255ac42537967d1bfa9497d957fc3ca0b46f706adb09e51ddb0fed7c19675e5a92069c9e7f43d45c327182cce7906cca931bd03bc1ed170c6310948c5e80ce57439a59ea2be0dec544e510629368700ea0175a562c55e6654aa606fdf7e58bb8af7ee8f9ed15b52999e810d2b5a2c93737352c7d18fa30b688a499d4299718ec8f8c31493c32843c94b528d349e36060a2007ad99955794a937205aeb7545d2655101dd3a16635dc19c19e1c1a80fc24e35485716d4e474a4c7592596640f6afb772a7a5b0ae19cc9b33589efe54c554b436937ad3711f46abc24cc865a46087af1d63f431f8fde704c82fd8de80626f9c632129e03f3aaf68fe4114b66ba3424bf1ae032d86ca1cdbe7ffeb212d64ba4b59f9fc3c5d94cae2ef326c0e9af70ba8e596e0d1a42268390c7dabfad1222a10f57e2f80dde6e5a7b8fbf1ef1fff3b1eff27f660f763dc59f70366aba92a05ea49141c6cf98d17a2dd4968ef540e937836977ae929df54c8a9725c5e1d714bf73b11dd4f2f125cb3e20039a5779c72ccbdd804354f3a177e2fddbecc0d84ac4da07029b906d0a4cc8ddb28bfe6688a4da3a153bb3339c35da3a1b19749d47543839a66f8060db5558d666d9f1f9543426b348bb54b1072daf014dd65b2020dc2329a219d95d4746faa65bf68cc29e748984e71d50b084a42ca714d0c29cd2e12e2450782a00f4618ffe40a85670471c83e0fdcfdd1d8cfc10408116531ba07404eb822bded9d3309c49866734c40e571b8cbb8348a608330b459644dab5fe41c35cc5bb208639d2a5edd82fc53c28781f9b69d11b39c788073cc0cdfc5e7cf7090e25315763d27557390cc1c27bd8ba56de0a65008e0f33717bb7a08ee1d4aa10fa059bdf8678ffe26252bc2ea1a162da0454378f40c42d1170a2b8aaec5e4371181defc58f76ff5d337d1157629d7d0f86bbe2b1d38912623583148eec8a7bfd00175f98cac0cddc6e260160d6ea6090731742d381e123afa16865fd4347d83533707b6c135890859a7d91427b16fc5f9cdb7dee19f81c4401139e48fc3653b21836eef01a708549b1059f294fb17ad3f303c568aff63321e570645ae2c8edb14fd56f2ce4f4400099a799497094992536b292db731c444d31ac0b13f5d2b92767f588ca0fa52d4e9eddaf9381d3904fef10f301f94df4b0f54b347b77de356a36d263305a7241b5c1b3199fc76c19d581c47bc95624d78674f92ca10ef645e6cb17a5decd9e30c57e4ebfa27dbc155b746b69a16d101b82c59c1346a9c25a502bb2c8836f2adeb6d40dc6cdae214c8bbe5cd50144580f01c158d797aed03f5deb6a37318ce06069d37cbacf816d5e4baed90972308521dd02b045deb7745c7b4c6e9301847e2006f934ef06854ee6f37a411691351c5a410435a766b4108690769eada5bde7d5036466726a89c241b938419bc6d9751e1f64f946a83098eaa439f39f3fb98ccc13cbbeaf0d67696004a231540384b4d92151708c5939fe80a8c5890f36c1acd8f10b4289988b3fcd970541eba6128d4d6078089a8e7576fb962794694f9ae010f1eac69d871a33ec932e52837671be30efea33ada1eb2dbf02d054427a4632487794a2e0071f7a35c27de4acaa89a1c68b5a9ced93c1b6210d7712587139430a948cfaa6f112e2a3c9df014cae7573071fb78355dfe5bcebb4db4672e8283fda81b1973dbcd51d51c6d587ad59e222c106022272f13ab2fe649627c9145a1952936e6a5ff46e0211ffc5497e47b40b722de6db606458778cb401fe1592c031544f25809a6477d318ca7ac48b15b1af2fc669bfc5493cb56c3e93d13ca58e9f403f3e05a6505e2d997e63319124976e998a23c97f36d68bb1a1374b639cd22857872731f09a3a572ca9db36898016746123a2aed3acc6521be5004281f00d4bb9af9e839466595c5fe2330c412c2a82f38502a876b03a52212dba68b23b669f2f425d3ad681ff0541e25880267fc7af1df1310c136d5b81f23536637b8543de41b7eae2a29745583469b61d1778627bcc1362f0538ce185e71c3d193340891ca456a0f748d512b7a4f4aa30cb88caf11219257621d172fddd08d8c0f56d94e858ca9f3d5e13d41a48ca1e45ea23c5ba26e997d3fac3459348579f343782fbb8b285332774cbad5b41ef6c98b386ab2287f6b98c4fc03679dd0fa82f42da308f5025db09d4498807f41cbb00c56d1b51244ba503746eaa0bfa558c771c665578a9e9851553cdcf36229d7dc9b82c3dfe8fc4e299d23353ade40d35dc361f26811cb8d981ad7210307d3583eef1936070569c35d8dafdb853f6f6dcb9849d19dfc7c76c6c3aacf75c4d604dacd0ffc8a1c02fa6a64919484f4c9b1a78012a1061487cf005f0fe8d5964e7a39bd0fac789fb31e30c91d58e81b41faf964fd34e132b624a550e27c683c943f11afc525190c8b27830f94d9e6342d419b1c3d057f2c9ef880530847461f864ef488e1d1e55776e007650f30222d29f4c9e5ae2a979be8b1457080f19ba4a8503b47710407e68567491d5643bad1e7d4d6afa80e6ff286358de83d031e1ef797eb3c9ad600e3615e015af04f4cd52720eb7560f7c2d9ce8072be4b6bc5d82c98241959433a70144e78b886bafb7ffb9fd908ded4a8cc4ad354c5dbfdd3430c45ef83eb92d844550c76ad690b10e305425fdd9558f09c453550cab4a49f07173343bc88890c5f29dbd0d14388fae81a0900c4c377bb8207ce8abbb80ea0c722fe74dc742f166d83017ae6268e1eed63011b2cbd350dc1f8127be0e397fc9e1de06eed9e5fb335d2c40e70b27c5e333904808c119da2eff83a0587f150bd36a4f87492d20d7c81a31596f85e9c69d24c02dec6fae54f033e0b6140824417cb8601b3242777dfc59af1c41708d274ecfdb21bc0ba225d55578173654ea35089df758eb96f32630e7da30558d6e56e4114b21c14492b7e3a49a6329ce267d49a9b0f63d0965ee9d23bfac948deff0f2ee09e9c331f21edfaebb769ba7fe19713823ce03a2d7e8efe330c9b7a802794b042471582f9f75770d3a100df4e27ddc0c5f7c7f451331df67dd2e4b34b681a7187637531a2d428f6a0f5ff1c5fec55098f15447819114706639b0f34f6ad56b95880d3042505d8efc7af51e3384e25bf037ad738b2cf87b696b8e0027824afa15bcd3d75f4f3435877ae96b9a9d7c8422fd3aff3b67aaab04c2ed24f65e61ec789bb4a570fb992159592b77ebfbe0186b18cafc3acdddc9562d2ce3e99f0ca4aa16afacf1831b247c74869715388b1e7dbbc59a9a398f2d6acb34cc6c1558fe11f4852942ea521dd8502b347e68e4fed97d272a20aa5c09ce29c51f2c97b04e6a43853e43afa07a178ef2f7b591a1cde2523cf0e01ae48b9d46a8463ea49ba567b1451697e56af13193401d5bfda3004926d352f19f6eae5e585809ba25827f97a31bcd95064c05e878e1b6ea057dc25c729cff93a652569f41d1ed1d5c224578cd359c8e8bd1db605d8da86b1bbf69aafdde31a1cc4038a98af7dba1b1963a04eb0e91f4b0311dffefd38363f90337f9d334d4770bd3de40f5c70533dea6824a13ed6fea6de6f064fe739946cb34e85b677414fff60208483a56851125d55ba90d48551874e0f9ca8ab6974e10d9d86ed265e7a62fef453fce852f639f7a9789ca29288ec17834d41026971e864f357dd1459c784c34408a933e1be612e659a6411aa508b98a3c571b0b1c7a6b0408b51043ab81e89c1e94a6a5dfb98b6ef306a0232a6fff719606ae29d8243d7bec500374e0ceb87ff8e265b68074d2fee3038159252316ad8c9c038632bbfc22e42c79c1a2b2ee44826468667f95d5283fe4ac33ec155aebeb357a7b60ee1a8f830d48fb8cc7f920a96e6e525536615a9e2b8c8d05427d4000a19e0230dc8a7895157800225301ce26f7ed863fe47d288230f446f9e06a00441b7baedc442ba1056598774f394150d93bfc5c8484e3ab28f1e06267ef5324abf56b7dc1ba0f4cfacffec018a06e4c84ee3e7bb841411ad6c36005708a8e6ccf79b7520de6b0465f8c10c94289f64e241fc6144fdb4cf9f31a7c0ba6b00710fb2248f114bdef27ea95990ef2affc6624f49e1c600947976ddf14d9536044fd1391c45a87575cccb73e356856f1c23b2dea12b9290d1dae90bcddfc2c5e44e91108e4a5948c3b366b3423d2a445895c5dec94008eff420e27f23717c980b651466673f0ab940294f32940c6eeda1f844e813295ef36ae4a8fbfc731250c5ba87fa0071bd3278dd4272831a2e3ee54428647a7714e342697915898b1334d24ea3b86df725c6b859b9373ff9f1a0c061d95b58874125265c351662b56bff60d6d53e4a9b3256d90cf2e0fbf882da8f997fe570519f06df12f0e0097b2914761a3fbf835fcd9331b817c40c8c15f78372daa4cf5521f03cffcc16046154a3adfef2d081a22f4e2549acb1ecbf462809b1478f00b16250f96b53cde90e3a67f73641ed5c0838629fbc67851451eb762b8967b7819098efab4e681506d058a7d5e2427b88cf0b9e4c30bc63060b7231b102abe040d22a8a915492d08fda9f8b75a85320d28a625040036d07667e43f278043f0744aa01b1ef00204c40060c51090b3bad71bb4c493ab14428456f905011f14108df769a32919308f46c3d0fb3fc1b11ba4bdde72eb1dd063b0fc956188af0b569d9a1f1c5aa5f41740d544cad55aaf940924b9569093ca94e5ed05512607f17dee326afe51971291922d3648dda864bbc87f65619ef78e5c5228b28267aefa4a296b06b045a71c0cf98ee950f71d654f5c35d72a6028342796504f344e682961a2d4f97b82026b9704d732ab0b680791b8fa98f45da0d2408d465756a013c510d7a4e813506214347afb829587f1c3468142d9f5f66a28c48d7d6ecd53aa4281f739adb3a33d9c35e338e9f61d1222055ea52dc054c7cacc4787ade0cbec1d6fdbb95236b0cd3508cb0496a8fa1e739baad3a9160ad9944380cae5248c13832d37f5fda00a60492da68f85dc6e3fb2b9ff11becfddaef296483c775d28554afda0510305543b780602bfcca520f7acc527f2476f76b56df0852d84c6d223c6a79f264dad2b31120b97806be6ff0fc989f7be8c269ae141a63c954e82608d5a6593e45838dc2257c09a1dbfa02c63ed5ad71b4d8e3740f1de949d4ed889969c2b17b28c189f6e6b182275bf63948f0f09ea249a9070d68be38ad7f127e6515c0f4805044831cfc83fdabe991a73b3eb017ce62bb44032c19312d4701d683565b74f5fe7415ada18c69ab3c2dad1f5a331d86842ab754d62d8c5db2f52cd911ba54f5d30422c3d4789670be490814380e993db3391e593f1da62798f7818a7a9c9e16b638e81f7a13282682a58f0441939f981d080a3027fe26c44bddc1f76e93775af2f3d3b6402b8b1407413a0df8374e8f29a6e399ae1b029b55f133ec3c61abafe05a08554b83464db1fb6da0f87739f80ee1b9fa6cb3364fba0f98f655c679c88b5f6f598e1a1275d71ea43a2884fb202d27eab8ee9e704138f30a67baaba9428e1a83ea1bb5d004eb9198a3a61963ddb8832ac0f935c43cda6fda763ed8c39470f712dcf47af928fab06e6d170655a090c51baa56b402d951436864b4f2c3167a1c8933cd28655a0df0288414fc0646e6d6b9030724a46e61ddd243c8a879a1620d39cded179b8119dcbd180764444645529dfb561ada0ed6c167c7b88d4ff6d073ceb78c3caf4af31f3e8291788336734ebc0859388d5bff041540cc3a3fd29590734c553b4855a9693b69961686ff131a26d73bc6652fb60df6d1d973cfec65f17a3de0f410a477d424fcb90f3a7a770ccf8e3c5b8bf5567b1b0ad849e1d0fd142e3a685814c88e44e35a2caf05d27d35997dbbb5b9edae0c9bb8c380267d5f0a910047c68e2b2dcc9d2220a374c286a02427d1da9006d37f0cb081bbf33b4f792e33248357147f0510c251c539e123d8503875df8ce94e04f58854c40bdadc91b780da31286c15a15e3e50f696fcf4ce5a1e14b9a54aa6cda7dbadff30c94a12c7030a795efeb7132befab29dd509a16030909c81f0368b3a0607df4e6b74acd7e00644876ac913271a7593781b761a0c37684033fb1e66ae960fd2f2b80785224db6b2579da4669a129d5b5679a4d2c9c668f5ac1aeac7dc7ad51069c581f17f466fe233d2f3f3dc00e221d87b80401861d6adbb5dd02a985143a3535fe51c7661729d626fc659c5260d868fa4d42bfa7e4a6514b4e41842249865985ca3584707795985ba764277d388ce1f1a73d2d7f484f5eeed8e42ec1404135b7604d35393401e72c18803a2fe28ab128fbd96d1c46eeae7e92aabad8b00c2fb39083f844193c6a2f5d6d5cd945810cab44f7f19746354d187f89a7d049c8554bcc8755eba09363b4ea8439f422b6b686ed5f49d710b7034999513b0fed079b84f76a8979397b2137d3931a2e0154a0f1a6cbb47198b0b78ee91bab144c21907489dc7681e0dc4c45f9ec54689e83387866b5b10f00aa9397d1ce910966b5a9f49460f92cbfa5aa34249613282da8f292011b9a4e901b0d57d2a750844d626fc5abe9daa5d6356e394723dbd2346bda94194ad7969b2372f22e9e18b711ec4dad0d7fdb48848464f1e4cbeb118696a45151df09adeaac0f533e966f93364f6ae1cf3190c99a45c021e39bc4b9a906d73ff739747ae1ca1f25ea426985a2fdd1c5a6b0c5ff657f2142710e7ccc504f139acf87702e415f3cab1a7922dae9607b347fe5ee7b64e7aa1ee429a11b921242db91b0e02abbaa44504557fad9a028a6f842035187c36df206a8c382a6e70cc63a29462cb3fdacbd7ec683fdd0fa9a2b574e71905cebaa6678fc423649fce6be1a40033c637267cd1eb2476fa2117ff13cdfc4bef4f352c914be526f77b6928948a893110382a51c37487fe32f78013197b96c5fd468d8d61150bfb4a15109dc5b13880d4aa5101ee801309c14f083cb9a2c740cb4fa224d89bb1255b6f2953f804b0b8ce76b39c537f3b4148935d2100c677efb8034769e6249520082e066150882ee481c12208bbb9d0bd1064d74787f2839b2ef669939db6c14df2386e27a06a1f71b842a9b9489cc3b00f7df233441506a272a5748501c257366a1e9080b80bf660a10362a0e637b9bfb21022b3405c5f806dcb103ad9a1d7a0a0737997cc17bbf6cb3a05517f9027af49403a03245794fb50489d66e36811a115fb725a068d11860df103e4d861565c5c68c5a82b079f334c8d8354b56a38021c41e4c8d497f9a9d55a8a661f8b29b502509d48b14f7592e207034bb7d493d3673c1976b71ddbff40c4b32f2e4cfc50e78e0b791bf00b7b5514022a5ac8d116c96706ff6c2791a5fa8aed56ac38be6c39c26c2e47399e5e3912f8797cafb0d7de1b49b916686e498656b45d5fb289c14b0984423132fdd62931368d68df4dc4b4d85071595912f84842283d6d9bb9c38cbae9fd8cb8450a0e44b14edfd2b65d46e2b6cb38afa635858f9c1871fefe01df56f06d983ea75c9abc3ad610a77c6d7a6fb9d4ac7c018f6cbf2c6c194fec59d32b324f37c4ff435b35cfd3c372b3c18d27eed1445bb17c6179f33107f0af9bd8f81e34c1e8eefcfcfbb00147e1a3fc3ede6bda08eaabd8513df00e3a1442b8c7da6c76704e0ef58caf94700b11c92dc56229a77e3c4f8e3e4c423012d1ffc901bb3480645eaed3fa6b5448f2faa9b7b118d70675c1398d3a6ab0adb7e008d16a8f715ce9081ff3a79248871e6b519882d90573587f0c19e4840fbed53fdf1d55dba321093d5915ca29c9a9bfe6507d82a7c2019a67c431e701f985aabc26b28e6d80d05a677787eb7e2c2757e1063758c0f605923c7a5d0145be5a040aaf712e29a1ee192414cc6c4c703609dae641ffb81894a438c395b9b386e52a215a1016271b8d64b25b683c0af5b96c204855ff1dd2a8d4b0131505d498f7953192a3e307679fc4ea589f3125b06543b3753a8dbb222c9e4f91bd36e64383a564f6c640279d13c5ce75206347601028ea25964eb3ce0f7b7c47c9b5ebe52a7b1a4259ed676a2d5e030f10be4b49b206a131b1b6ced637b2cc0243fb8436f70d295d22909e323483935f63e647d9dcf6d1ced516bcb9a7480b6a5560909f3699d80072d9c55894106b32b7ddcbd66e17929cedd9c2a98970921f34252eb31aa0f70558074900575a947c8c5903f1c2371b32feb5d10c8f696cb867c2dc50428606a06a9999ee7e31bc90338fc3918994a3408b148de9b2e980b38805824638f3d123782f1b44c1434d18981fb919802adc94b8558777415e17a41b2147b8b18768d5273b83f82ab7968affa67737e89116c13d4d8d117789504cf0242bd7ff0e8051123c2012c0fe4b2c1ae52c9617eaec94662e03e954edf9eb1035562f6715235c4d0698311bcc9cbead232f440d953e98464e2cdde88e5aedf6084328db00ddbbd5622cb5d211f986590793d36df3b6e343b470dc292102bf6f3ad611fa4aeadd752e4f4127393b9a06414d841a98fdbcd1c386fd6bf850577485ecd5ed0d52f81162951931057ae7c7bf79d9c7a807b880a3ab3e92d6cc81c8638c62dc484fe2ef43fb276f439ab7e4d382e416ba91ef26e8309a3108cd1cecefa8262f067cfdd6ca112798731c7c1cf5367e8ead0feee29171f2e0c73285e8d72db18f53c229093c930e7675a6d98ef6e50ddbccf0e983487c1781c25a430362cd920140b81ef5dc81400889bab0720c6f26f00bc5245564afffb27be23c30870a96d67161559640d0210cd5c1f96956a1603df7c124e63144d057b2a46d7a674884a1757d7ad1088bca7d8acbcb8b6fdb193d20b66b28186ad2aa551e313d3c994b8e0465a32de573b98abcb035661e0d3774c00f31d9bf41e2765e79955410bbb153b0d91da17169e38ad434400ff9898fb7773da2f5666b83c72913228d07036bea6495bc3f9ffa953d41aaa9c54e54286f36b4d120052897ee81e761bf0fc3f6f239fd59c30862bff33a1c19f615b56876133b2e551b7c80cf23e44950114130470d78072cce4d9fc9160d366986edb8c80a6c034cd0b17e46d2c2204364f1d7836392cbcf3bf849e5bd496cf768ab4aa558ab699f513da2aae05029da6c7885c7f757aa527c8041815a0d72b6ee347d4a7ca1f5651e0a022f2f455d4feaadbbfa90bcd3fe7c3fad275efb1d538a41a8fc9605e6042ff1fb0b2c715df772537c9f352b8acd356e8c07c98fe8e7259db514a2919442d50a4a7ea8b0a3f0fb3918ce933033ec22fc6ca0ac026cc6fa7b84b2d8c45394d2c73eabd0239735827c9fe90d97c6337bd1cd05f4834801c8d820303af0c4a4b1c71779d5232717c181eb7ca4787bb1834cfe3d8dcacb49560f106b6b47cdc39ef6d3cee2b80c07ccc68f22a3675fad13709b4fc8743bd1666531446e68701d478038adcf7fa5cb6f8e02fe3caa7c162d44961f2902102f009747478519bde234e6e2b243b0ce2b235a82c19047b449eb67f47e9d8148431f29eace931819763aca468864fc3ead43948779e3de6ae611ff68bcc11f079e77947885347174f0e25bfd2cf0d65777c4aceb9506f60b50c67c81339c1267447a5f141f6e0870ee278227e8a0aa0a685c931657987242f458a16bf6367b80da3c578cdcad1e9685403976e3aeefa4c6fe9b6cc8b0a1d59d69529d9192e90e95048be1f2dab211dd84105f305fb3df4ad3dc97f5fc2d50443a6f09e5e1deb88c3ae9b4ac1f82f548c4a235251f69845fc94e0306522336b2ff65525532786088dc5d834d959d96a7168c197114db0d074c49a61ec09140dc8b69c3a5198c249e745283055b1944490b0cb10d09e401ce8f621259c7b0139a7bc3d55eb900f79cf7959f205fe19e6f1fa1d655d563d31b4c348b9c4087f82361613875f1bfd1d583e68d3087815522667472c57f59e7d92bf3cd65a358edf1209039fc85949aeddf57e4529d652fb18298da66dcbc905befdcc9604d40f0d0ec89fd06c2f159bf653aec20a88f1d6b88ff0d72b3184c42de91c45b889c00af041c998069fb967d063395f5ac08fc7da3c2b8f3d56278440a4b83817de1e3a9fb9cdc0dda5ee7026f6f8bf609b6ef22d9a414842938f3868b6e161134c2b7ffc403ce0d72c82400eb895ca55ae57cbf02e5789efaff9067918823ec815effda25ca606315a7903c67a9066a733f54b12597e295e112abf0dc513f641bf6d9b7e0ffcd46ce38a970743b762f2e9e1ad8f47269fef2d0b1be29a774eaf9ca5083639de5f0195c1523cf45ab0e6424d89a2dd96893e70258e863120428f4456bdf9d0c9f4c495f282118f9a93c7992b07debb3458de32e735574e304cb2590a7a5c0f1f159958d0ffef6657aa7557725d13886ae2abfd1ca449055c6101450407843aa1545709f0979519609066ea0a656fcabdcac16860eaa9b513771c608988fb482101f5d873c1d593d1f240d46a64f9fbc7ea971178e9771c47f120c93a27dadeef79a82359ab2534b4e91fd2a3d053d8b61a9b775814788883f8e4ec3940b5dd0bb51086415a67ebf4518f2157326ea85444c71fad5b2d12c5b77f433b408d753059022a328ae07e80e4dbafd0de19a78e5d6ae02c5d440eed576d9d2fc1932d7d37197a5447479ceffa1bb9e890d617a7f68c307aaed131317ee71aa9c6f4d8518feab0469458fe8ea33dd53cfb9e2195d87d252f329638175204445a47cca6a7ad04afd25d9ac495cd0c9f9cbfdd08d2a4e1284714ac0f9082c4051d8b5d1e0c59214c29a80edb8559d7550a17d26a170fc5908242d83d80cdd5a1d1a5fcea7587d346bdecf1757cc440f620469150d4f979807c22d9d868a3f4ef0ea834d498b2467d014376c7dda2d639158007133f09f3e371f46f45197692080e5b40977db9602c34c16639de74cb540013a70ea42758e709f26b0a179f49cb23a2e6332ef597e1ddb7e1ef9e9063938340bae115dde91c11ab9f0c923cb635694fdc1e985fbc043cac409878a8c621b5242dc48314186a3b12878381b8616f6e35722e5b1380f8d53e3a1a8b3ff97811093d12498b3bb6fc8af41d14b2ca8031ec2e8de0be6a6a5cfac9ce443ea7778b4d7576d78cbc1a0d6c4aefdf23c52889e7f447a22bbc3e53f78878c2d96946eaac1962fa1df71ee12042b5c190f0c62bf140ee8d186044c4eb742199f382262b5d260137fa2c2b247ab69ff2638bdbfa9acceb8452d910f31906471cb2859286696f2af5fb893bfeb2439111a838e42f42f74695c47cadd4ce20ce6351f9da598bfd309922c4e8336e4ec7ea6233f54bdc2dc101911ca8b704cb6edc7247c232c5bb22f044219f7360dda54a6da98b542f0905c70c740717e53469ae04fa36abaa7c84b34e2bbce91e8bbc8b813fe8643f2d156a813985a7b6ecd8e04943ec54801307cac882ec0d883ebd032fe50bca492ed63f8cd49af0a71076aa170d98e5c7cc528dcd74b7c91a9942432634645a0d4cd4d0040d33a521133532a5c62668c8844699a881891acc26128dbc9ea071aa42d5ddfa2b0d56416d8ac64c68c8a41a99a8b1291a654243266acc440d4dd090491a33510353359a4d251aa6cc69e2766770a55fe115490fed104b450e97540d4305b1199e9666c3dfd50ce9567e481bdbeb16f1af0acd03c7e88f5606e00b1d280c11e86d36896bab61d52b7982b2e31362444174497c7966e11b5d89aaf47f84e914e97ee1b06912df55f0b5db8800eedf97504e85f9e18cfc32a9a0e02c340e208a33e221ab5034357250414f1938b189b2ada7cb7add8ed5e1e52262b118db3c4375b95ce978696be358aa6f31a88feea9c68607dfcb830c83bc5116d327293e1958fcafe858234712a92aa25112942fd342d6f903b519b2c9f365dfeda78c901b315793aca443f3beacfab02890e183b764363ec9428fc3642766ee8b19de267e7c7e883c244d81814f5e604c8a1099d9d43eeb5b2dfc8bd30a78292c441b5fa1a625145686c48f18a5b6d0dc185927d34d9fa39fc9026375e7c80f24d3fce4ac79ea9a241287b3b7faa7fd4522149cbd0f6e3f70d3b4604497a9ed71f2c3768c80a617ede893a2e71f36e4fcba72880d77e8547a479fdf39423893fe690c232f358ef0af797215313d11a732c8a8a4e9d28c30a8843db7770a1fe0a91835ee248d473f0de57ce3949fbfa1ed8a39f9765eddf94bcda8f787f2f7a005883e8655240e96cd92517d1a9e711f3804364dbaf39c1c9b14ed2ec97249bb0addf0c34bee60362c4222c7beea757c00df093bee03686fc41be2321380fd9ed13fa44e81b881fca1d426e1dfd62595ea7a83f527000918f9ee6662d904ec8fb806c43705fa06765859283a193a46db4ca7602a2cd192026864403a05cb9f9bda494f300d6f602e8a1fe2aceee7d2c60fdf154016684b1772a87fe0546e2d8ecc7002e192133d052dd64cac11a73e57979757118ae0a75abc1052046eb884420c44970a29706f3d0fd6b2b2f8a0ba961d6e0c8dcab21592fba6238445fe41576e1d406e984174398c459760e62ddd2f45b2e4652425bcfdd9bf26b5a9e718616db19ed39128eb2f50837a71320399176b61f7135cf62bc99053969682f931da7c2acc2c5f56355f7fa2bef2f2366da075f18a2c645445c9ba009016dd96b4cd191529d3868e4ddc170c8a0016a3990da5caf01263c5cc0e2a3420e9572eab8884e1736bc89d091d412db9888521b3f889776147f0aaa72357fb4a589e1d19c4f2da2f294968726ffdf0cf729710a1aeeb664e22f6ba94041c7a31b4ad26f1486c73ce696acc8a8298d78f17b98c1ca6e7067726fdfc6ade3b7f0046401f4832c1b36d5382037d578e95774dc01939fe0747838f5ea2fcaffa92db575d06054841bdeab7a96bca3b408dba00a96bf860d9080132c0346548d68cc0a9f5747d0d673481da6f09d3526ac5a2a812828ff10d30b24403651838b312405f9c04b94a102a9e4390204c60de595dc633a044a3232a0e8975005f406f4033e17e40957301a642e9157996e2b8eb5aae101bc94693d04b0d95e05829073fa56e0e963039946363910534d19ca31c29c88aeabb242466ccc00044b71a0de4c4e2bed0dd10b29b30eb51d8253a9d6a00efe3e4a54c6ebbbd3a7185c740a264fdf8981ebbd17872c4c1e9b89537e009aae64a59c9141d7441ef79b5f4eb0121587944de609449db2da8f4181648d229295d8c13b9f216289e736b3bf72f071257b48e4154078834865a8ed4416697c0c2e10393c52624629e29e0157b87bdb588fb019d91ce0ffd0e52184ab979e13b4f5050da013102f79aa4a2c1b32a0c37a82d4a47f0699e800c0aa15b5dc87a26e71ee1a48213b218b9420a0aae6ba8da5af2e6f5d812598c927f3624dafce77d671148387e26209ea0a53211d03cd230b408afbce760ffc171439e8fd0513f9f5fe7947bf04c488bd19cb0f20a7ecc57e4d5c52e7183bb138eb9493f1ef2517278817b7414e5a3207f6813f2bee4f87d857555356e50099f75e4b5d0ec8113dcc58c5d213bc2c3025661e976b483228618073f4d7a73c3e74d5727463928ee86f520fa0b609c483c2085e82f72cfd8fe959ef89bccaa5748a4ccc6d14d0b743d423939e07cb536d5801c2552b9819071b9d39e818a3a6f6afe56b26d3aaf34d30f0eef6af85b530d89d27d77d868c49449f74f669b624bdfa6760203e0e7c2c00426c99c07a101446d1c274de7539ee2079e2d4abf51d8076274a2608a2f11ea48f8dca05e52340ede69f7f53192ec71d47f08464314118c8a28e840eb23eda538b8ed7888c51fa76f1c670beee913dbe8c175fa38666a35ca4edc5e098257cfd1bacb6563e342991a2e1e44fa76ebc4c6bb603c34364e32a0ead373fd2d9ced495d0e5e10828a1c3099a2f1f6a0d075f2a36337e0738a16c331b7b3a212048bb68900c106d66e2e40f3b74ae5ad058bad6c511f2de902bfe8baf99566c7ff50b594d71fac3c0aee889e3d501d72d44ffbac96df5540b416be29f319af02a9542703a92482f732fbaa4c22470213d5187cd041bfa339a1023838a693271872e822c84b6051074e610099a4fa80e40ae9a339301ba5f42c57392d32323438f5e6d4ffc9e78ac358314d6678d1ee5a603b312684ba1b103a894368f69fc2ea6cc34808e6dda0ca2ea8d312bf8b0d68c56cb798637cff6e40c71698e406599c4fcc0995b90bc0329e2b912b58c2794efb3f9222bd6e026b19150f3b9d5ce5a0b2ecea68a3bfbb13d35e6c99e56ebaa3993d482a5fefdb7a6809d51c9bb4ede91b59ca58246e51c1afbac7c5d62bf5cd0cce4078e473bc63a8dfb7b09be1aa2fcf5f76129374a634b26e147c2ddaa7e90acd8cbd7c16571d3e133ab1cfd1ede7af0502b2891774ea79573e10d773d7c04112e4b32c7ddbabbe1a1f565fdd32b659d41191027ebdcc96eb6dc838ae5101a795da90b2f6ed7213734a11a2557f962a46d64605c0df376c25ac396ebd53faeb8a0e807b05481924da7a0d041a5bed5bc9cf10d9cc2f346d4a4e7da1183b57fa138d97f93c9f263a0f4350ec107988411dd381ba6e721b1909127099603abe9aa84fa3fd3818311cda28ee7d424bf8379c64e3a107e0767d9c02513243bebcbcdaba06bf528834186f6504af66c9e5dd5d39bbb4610f94e97146044e1e956fff9ba41021d26ccea55f468c058c15911d88045afe2da27797c453bda33c2fea2c32dcf9fe8d748bbf6f5195168a3cd4b2aa1224ff1b676ac5cd9bffeff9f0faaf02e2a74a9b852330606ca6388b12546871ae113ebe2e8ffd427825211b5651e1a655e548ab621f430003c074c8b65dd9650915a80d7a900d72399f05188d76a7c75451340e8ee38f1ea4ac5ca3243e56c6e3edca5ebbe61b83c0da119433e2bc92b5252f3fcbf9cf9467aff5f7c765a837ff7eec90e1d083ffafbaaaff33445e0fed4dc31156c0879d60df0ffc05263f986f3f61b1cf1ddcc5cee309e56b7450e3094a8b6c356e38797f78a1c4bce40b401880c27ab7c2f704847d465c6b794846b397fe10647ac12ed002eb3d6388d3cb9fd859fa32f1e5b8e4e8afdcb3a56246c4fdd611503b7d59a6a42487893134c9bd9cd054522f535417d1a72870d7ad1bb016c660a4cfb3d5ce28593c9add090afe645788338896869827ae70afdd7b70c8aeaa0ccd2842a5d3d3cf0f49e004e3539db3e83d42c7ceb730f02d735b5d0b6a7fe915ff18c6b01b5cdd282978ae8f41588049d3b901d33a9d5028fa1767a920875fc56a31c20ffe55a87ea9860eeeb5b392045bcda8c998fb97f20e0789b84723646e7b64012336c54c4cec1e4f433a798a2aba7504084a081d8369b45ae790da85c841607387767d4285a8d27765d85b60eaadde3a63984294d81913af426d6c133be297b601b51e00b2984d31180dc030f2588fd5ba68008104987059c550bf5588e715c983735b4d451e0b1bdbc2aa844794ab64e55629f3055fb278feca6775f844f1fbcea0fe6c132efd1b9fed232d17ce7de7009f723c4f9386e7d3fea8705e5b95126beb1bd3d535ddd18d2074268b616d34c36bcf3e6e78e2ca4dae9beb8016d3ea012393e8db3fe3609fddaef45a333063b8720f40a119eeb5b9399a8f4f1c64076427627208fd1d6a1551ef13b08959b5f2bad16bf7c7585a65cebf30498f26b9086cef125543011fae72685b432379f6ea1ef032c22dff0856a7f9e2db8da05bf0f2641c2b460897feb3950f62907a288d26c0797b51a33d83085a4ad9edfad66b2cd2da6c545bbb0e5b23368d6b179b133940ff44380ff5f6fb20119aa764f2008c781ec8b5dc51925eba885d25f409f096a45e58e3f629f07c4a2011edf2a991c00f5ae040d80f93c0cae07ef12c756b24d1da558eadb28f96e8d52f6afb4b06d3698f00a2b64f1fc6cd8289459a4862fb4321318a61bf81c9a902f7a75f1e571adea110bd0d3c0fce4b88401f5e451648deb5073c5a95a885f3fa11a29cdf281c7df3a2f2c6ebd6fa173988ba79911b16a23fec42c5b8cd0b2935a5a1e7da71f3e53a1978729f86e1dd7a5ebe25a8f1b2dbeb0a8af52467c61b7667519f6d4824b9175f62f25fdc058d68396351da8fa4b82ec0cc87a5535b8c8edcc8b3ac8833ad273a14264f900a72f332b8fa6199682ff02f3844874fc77f097a80e4e9cf5bb1a6f143b315d005ae2e437d3fbbc0209941d0596fb8feed6e445e91c371eac9efa65579c278c1a227280d7db73f75f6bd89eef380eaf55446b5757016d646b2bfe0c4e2ccfa26eb2a76d1a4c90a8faa2e1af7b17be64e06b806245dd4caa9b4f5afc8c99237dc177920a2042c37b36798c87d1d53b1410e647d7fe2e92e81d71d6411f4ed1fbb7f3340fbaf732e8af8348abddba8d4ca4af7ccac593930fa90433e1b24ece4cfca0f997d264a031cb3e4ff3dc1b3f0ee68cac3d80d1fb4a82bc83e1b0d5c5d7f92bae805dab61135a1fb2cba557826252d113c1e8fa456d7514a3ba892d059a8122345b7874285b25ea799e224a01bb3680166eb837467bab856502f82098c91bd1d105dcfbc34f095096073b4ae342c6e2475e632b0247b15726b8f6ebeac1eed49e3f0e4a67a953e730b468eae5da520e3e8e392a54c8f29669bc029bba970bd0175a4046c372194ea3123edbb0e4cccd344c0d0a614d34f4e99dd862eae044127d45c05dcb0f1b75cf22cdbe86143472902ad0b04251ae057a15d20caae03efe2ac2eb91f12685d54b15903d8f6ba5c9b8b5e28743cf653b97edc80c8ff77882c446daa5cb57da7385d8d6e32891c1dc53eebd866502eb4c5d7a159aae8019af83390e67dba950e62ad3aa7677c3e0480c23bc60d79e0ee4da7c05b79a7dc07d7514e9debf1c9249157f0993dce34131078d94a2205bd8ad0ef98b1f05bb9ce466b28b8d828896d8a5e056d841261db5e1a7ef89824de8ddb34bb31414c9d8869b5724950bbc816e3c888dcc3a89ceed76ae262f43456f53e3cfd6bbf0c4d2e042fbb21829fecc004e6d1ebc566c21f6beffc4246395c88d597b1fccdf8a4419647bf5a59ee28f67f332c613383fa0db4cd20826071afa1e2008f5ed3498f4bd53797102a6ee4eca7633f12eef380729e96cab436a87235716daedc9c04487464dd76dd100f9fb1336667fb180531b7cedce577030b8ca81ef6f51aa98a7e4331abced3c3f5356abe0eb152e8e95efe571025781fc629afd738c6ee71b3119a81c88675d5ebdd488d9c7854521048f071066cc18a30d824a12b8acb091882ccde776e84cd6019ffee6deb14b240f1fe87ec042707ee24071526d56baec9bada19f7725499c7c63dc31b5ca2ec11eb0d60b67ed31a63c5b84d74297d0b71490889524e6cf615c03f2f6704e94d750262981d0a1b5754f6d5b323831f6a94dd7437704b9e4639918ea76f2cbeeba51040b6b8796e0e902c10f5a4f9d114b8c069d9c4562fa3408942bc93d9606d20fe96ddb5fee25da75264db7224b650bd6b865a712c1e3bbda42f4bdc85f98aa9130c4a3e0b60bda0f4afe3cf6c4bd4e664675cf8a4afe64135b11a0cbc3abad49a1844e9ab58fa305bc458dd92345b9f6caebc1791f8bfa40254a73a4781b77e943120d11f8de267a1bc7f4211b50946848273de7daa94b4b34087911ebee642a18b55986982eb4df002350c559d707ffe1f253f43ca8fa15232a4da28ff28b402815671f38ad42ff7d69545bdd8398a9e3494df7753bd2129193d99a40d46412a85b1ad2a72e59021a312e10d0bcb22d59a3d9aabb768c1b734f596299b5e4b03510a1426f5a493026a2b46691101665453908db7b88b14e811ef291551297d91f1a5250da9694917dbfc021194b5e41b90ea23f910a9207c541f2af906264feafe8479b3c443aafa75787ff020dc08e5c3364c845cf6b6e2f482fcf62ac5ffa12ffe2b367bfa35faf58ca385723c8e1a82e4210a27efbcbe7296afaf8067927fe395eeafd288abc2c2e0318624ac930c69927fdef31293067975069787f242d650faeeb40feda8bb8e1b5cb910b8a5c72347d9044d040b7d752ebb7a68891153883d80885a5ed4011daf693d67172295255f8d02e75231df3fb9398a0bc01a1552fe597ae75761628d8b9aac277a951a3873822f6428c91289f69178a8a50f29df5d002137481ff86e5fe0f462ca8595529d309a60b6130e3d1d57fba4c103e7ac0763b582bae90550e03c37f0b0c9f22c5286492fe94753e018fad8eb8cf091d183cc171ae6eca22261eac08a2e1f789e602807825ec689d7040614ad8f8e970043fd86d45ce6f3cc4b0c4fa22489d62e3d78fa73dfcc93cadf84979e72a2f030b180c97ff8ad4f506f3bd2af83cec20ead685d58cca858f63282d7fa64dbe369f1f12a3277892487d5ceddccd8e3400e034c80792707d1993df4188f8f64b6fa8d620a4fa1b9813cde8fc942843b23a9149d9be191548413b0b2f1a0576557a81bdd978d454961cb2348ed27da7f890947084e03093817a1859570b577e35cd516899b77e816898c20537fba7ee511b7a5873e4d7a93d2d688cdeacb17ee3de7da2463889e5367de1d09e453edc74eb22fb962582da9f907bd3e0426d771f5618fffaa1464b07c7bc596543cd980c0df0f63d9ad522ccc2a0ada4d5abd81c5ee0b35581066a4bc1ef85e956f9f23427bc585bf8a10304c1b721097da701a0b69c8364e1bdafe00deb331109ff7cb9ca1e551d1ab43153ba5b0998343cf50433bfd5cebe2db641b6bc73c19e1323cf7f618cd0355de6ff86e3016f6752e822edc6de94922238be6e554460fcd080cc2cbf876ceee3edf9429f7560a6c281ec860929021e7043cb846e2dee10732905a659f25788db4dee5a4e1a2c25ed8d4eaa952206c1c22293e18b541d44cc05a259c7f5eefea0fc06388e61bb6efb79c23fc5a91902ee8e782513c4e2f2a9915403c4868eca73bacbfe26572d06f83982f37aa29ab1d96307d568efddc5d68f62f8c18f352bc4fe3df7bfee43cd369eaccf0a4081f45d087746cf0115dabe84d58b0752433fcb0cc3f04928e9f1ff7a111f79a1dbe11082fddac2312760fb1285b2c4f6e88b2a46885468f48fa7565aee1b10cf98bc104c31d1028697d9ca2aac4029e9f73423c535f04b9f596cb2a72478994f0328e94c659bef9a0424ca4d013b51a971051a79ec14652c0e069ea45c0cd0ac6bf694574f21c9380edb7b11c27ffc0bec0f14677c56831b86b140d715f36d3bb9dd39cba49bb8e941677a8bc39f783881dfa6126a794a9c35d30980eb8082201e3829a1e1ac4daf2c9637c776f490f821a33849fd33c7700072544a1ef922f714ab7ff116287b23817f9942a017c25111fca6b03cb84101f36a0e85de8fe9218f28569a750a02320d780231a6904bf5b89504825a294b4ec9e493d7a08225ae1664884f8c73bcc87706c3b8c20afe005c71851b023ccf53cdb50bf1aebeb36554e7252802fe0701b1e1380474935f2cc6ff70e70faa3f85e9895e37b61397471564eddef06927e2e47dfef8151fc9a3e4db98cede15de1ababb78b12b01ca884061e87c0687bb9c61c0dea256b3bb268c92b0ae023bc164ca3bef827aae0b5fa3fb66a8c2892915c49037c19ae1219e5cb6b44e5a87f83dab2cd3b45fedfe98df7d51372148e0a51e5f2e3155664fd7eb6d03baeaafe57b330146419c3ce36f8ebe65c44af387526d00c7082b7d4ddcdaf25a87a949f0599f596c095ab526caca874f74f7b26df6b39b3ae2af9ca16df547004c6d0540999582d3ffa10407e06a2fc191e20ebc5a66ed22d90a2aa2a921078fdd3c8b982fb73738d42e096ca4b9891d581e909dbca1b7831d59ffa204bd38829490cc48e1f8b903761156527c57b95066062023e1e9595ee382bb88bb8277e84b7b17ca6999ff1daf34b4fb23c3b5a5554008cb2fc9c01eaed4555642c23141f86efb570562d3dfe50af813bcb340e773deafe2dc52f2d16e991360d9d4e69e713bf8016b1f20d0450c292ae59fe845a8bb24753598bdef9a5182a962ad5fb79dc12a81769160376504b60dfacb4e0880ea3cf3ec7e7b52b95897b1f0b46b0e069b7a2fa71e9b05d492d53f550c30a8de057598fa8915a1175442b81d516ada402c8de2f7229ee1d75d446bbf77637de8b30d0cf4bd86d3a1a7571f937e5201101ac104cf88cfddf3c7a3b32ec3d93d89a33d44687c1f822d379446bcc5351439499f4d682a5e2493ee671e9ef231975975f1d3524f48f5f57c273b6c03d0d92cf91387a21c408cb346b0e8fc064172e817590084b56110e9ee1249b71cb9b266bed8a04ea345a0a7c7b8b86410ca7a17c27d31a03b03d4b66a2416f0251c58aa4084bb5709bad44374aaa578e6fb82fcadee2a6eede13fd4a178a7e99d321957b0aa06491e15f21753177e4f38294ef6563512efbffe9294d1aeaf09700b595453f6b7958e28c3243b5df931178bc2b193ab95bebb8df4b4957e4474615778f333c53fea2fb10443123a2be152efcf4aa5d3f4a48c05cda95097678d540f75a2230e7bb398640105ea982f52fb9ea5c2a47e12a4f06bab11cd442c37d1403faa6a24b9541593bbfd8b1c92fee94c6aed3ec37bd6b9c4bf1ee74a7ce87a80cd4386151e17c5a07ff75f150d160c0926b9dc328a2cbb3cdca76e358f6a0b7779ab3f131baf53aa5dc5180ef086ef667de1d8ae51f5a9acb705d71e550bd3a2c6795f4251a61c0abab3242ef5b8478e6a07e71b2ebfa98589aa048e8f99363bb3610e7ee370b59a962b0a98f0ce085bb3ffe28a632e2411c1585478460cbc2d6a5bb4c259c151236754a04829e7f0e0f7d0edbe66ae4acdd7742fa0a858fa29380e4baa3c5ceb110211650ad80c4ca70bd995ffa4de024fe276a1ae4fe82a75638a7ce3a9a9aa064ebe40aa58dbea9b60977cfbfa654682be92853f88cae65bd36c69644015e5135d0ef14f49e87c5b8378f008c423a4eaa9c161bd0b5fcc3b7e561e9904aac67426ced5bc1949af014e884cf2b01482284c40ec9f4b3f6deb3f42f55e2b286f67751163ba60501810670485f0487cef43e5d20180a77602a8c8c332d42891cce56202e0ae65dedec80cc87aa59e6c76a1bb415502cc7faf62a465110557270b64673eaacfb0b0e03e7b056e1fa2641b85775e01559306a460607fe35d2064b103f92af4057352c4695c288c178ef38f3e00a979b16dcfed12ab0e6f44b78073fc070e55a8e98e501a82cda5ef5c0d07fe1dc84c10fae30ad170bd375c2e057eb669782546c3ea45e6b9bc7c10c82ddf1901f82ea13abbe3068121e4aa4aeca7100dacbb228525a83be206961993ddbfbbe0623798c3e797fb7c1fd67b7d1be092e362eaefc16ba26165fb9f9d9695f5ec8f2e19f0ff9f817dbc71384116ee5420cbefc04af5cfe0805f62d1e6aa33652d6ae0d3bdec2550d4e6b10e3645c687f82eb1a6b629e4f8eb490cf6f2bf706b69a5d998da2b1f4fcaf10e0cd20deddd0952d4822dfc23a9776864c8274d4bd0aff83b34edb10494629f7235bd20afad50e4b2304ac09c7bded07682aea5636ad692e53348c71f792561ea74c1cd19759b9537050d4650129d2eebf61858ff618e9c913fedd3f07e404b17e06dc9952d49d85fcfbcc76ef88c02beb41cf921d026906ce50fdf7ee5a08d94977c6d68bec8667e7ac1c13191a06fc85bf795cdf969db659c5f889ba792d6421e231d096225b86a6135adea540284446744977022f87c671d286ed73cbc5d075a5a6f78d67b5243c5cac52bd2e2f858d93f6058d6ce2fee1ff67e176c03b75c7e0d0841a144d0cb21413b82935d6bb650f22baceb86d92243b48457b54f3caeca2cd97270f030f622d58fa1f58cbf2f700d93eb54d958165ac087dae8d1dc3f907f5772dc1f5c74e36d93da84e9c58eba730f065e617dd783bc52a25c906a87450e06c6ae61c55702a923860d6c52ee8c00906b1715d995d2dc5f8bed48cdc9f4bf55651cb1d25d40c0aad2c0ec020d4bd7148673a3cb1aa2286e657cf252e3378669b36f78ec277f03a4a68625e76c495e522cfce098c7b8bbcf16513bafca64a3f6a2267c425a69fea445b3f1097b4f8356e9390a09345a6623b1b1159522c44a43d56c0e99642ef02541f4d2dfe24bf49d051c3f157b1ac4efc029d29de4a6548caccc0bb8d3428d641982802c90fc8eef5ebb62b2104de243fbe0c6091001a86140fd120aa8d09a3e7adcdba44324d0896912805c7ae2607f3accd50b8fa46ba795c005587e4cfe46c80e02c0565476def410af4871e13bb4652c1fb2e4a0f9cf2ebbc34b4bd566d77cee0e34e022b50ae8da59d0a0590df0e22277b6ac0cf021bd1132888e106eacbacce1084b4674a489b6e0a69df550485c435665697d75554a161c72bbdaa2f73dfdc239a737f3fd3a72f6fc319cf4770a9b6fc74659aa0a6951905557408082f0b4097ba9d73aa8ff175e139a216ccc355a65de19fc435ca2d5aeb39a4c28b8fcdf3702004690e8a746316540730562396a5790b0477e92efacb15bc7d081df61750e02c99427f8660deb4e6ab7bc4d13f3eb514bce45b4cf090741fd120eb9bf77fd13dae73ebe3cf3cb3a22c02dd70b1239d944bc8dc2ee7123ab1d6d0c777f8fc7ffb008eb39706002624865d90f462e474605f720a5828d75193bc94ded5c93f4c24fa95cfc7de1993b639a9d9c50d38e32f1b0e6f613c3afc737631096fda9c198d29050b996cf65313bcbeb3036330ad54bbeab4bb5b3429b4374a3df045753c9d916f38cc68de678ec29e51ff42d9937c93c5d7a1280deb336aa2ba252a4f2c2fd69417c1503c8e8529e9a189f830847bd1ad1fa61ac0c32c509df1aa57e1bc48bc75f8bac2889b92360aac1e70dc355e556e831f053c3d11c76222322b85d0979832965a9ab0250fe732b588e3192cfc31d1f8d7994c51fa056e9a93608554a8b42d127070b4402dcbdb2a4e9a9d64d13991eff2175f28822049ece672936a1291536c151b7f94a7d9ee16035378f92db4dcf742fd73925925e5554c2421f431183f2f5210a27a2db76aad2098230529ec6b24fa041fe6c49803c81520b2312fbbdbaece816c6e990e1ef75306bfb1d6e398471ddbd2e3533f863690e7d23a2f624ce185cc88a48a958db619b8f86782f09f299397b981dc25627e4822149a468a61af5610303e6c6f63464f0fd2a51bf75ffaf0bd5e178e6e59f6bc831ed0f97de67251c1cbf8fcdd3258aa797999567ab2243e91bb8c1885dcf9da6615286e6a5cbc161aa3c34c5bf6791f0d4ae2d31276a7acbf915f69bfc6eb60450093698f92acab59a57fd55c07eea8f564bb2f717333d8df6313660814941610438eb8ed69ce806bbe540e3e32de4c32488ed363c055ecca03333a51927df768b08414f15ae7d434946007eca2ef209922320d07751f1931a32b9b07e481b0842f8d5f1969f890fb4a94660f99b75405eb51945113231f69f8c0151acc8435e4e7cfbc22eb8ef1db17f0c52f45c517efbaad8ec098f940dd19ca8842a5e6216561e72488f0cdfd1dd76df0ec83fab03856fb28c2714c859db7f203472075c3bea097565e1d5fef998c1e374861126bc09a909c59269ba48beb9517bcdb027e982137ce3ef9b685b50bc81e206c14a124b3f5889e5bb0d6d4facab79df82b2741169fb1d42ec3abca7f4ccc74736d365c517340ac2dff87c156d43ce40f7646736b73b9dcae28fb7798de32ae4efdba0ea3832421e0987ae740ad02ce41bd9f6fb60dfed5cc9434929053b665024c51c5939652d8d29bb5b4e358511986fc719c63d92abb8fed32216b2963eb2908b71e75e31513ed0e4d9ac1af818a52bf14658a79c94ac7d7489028c819495adc08192c045873d77bbc9f29c632d06b890b70dc64a9925b69c97473831b3b69ddf7fa16de367a4f2a0c8fec2aa6c68ba7a1e5bdc4242b0f7bd393cdb9548c92915f263057189a78c3e47d12ed0a14635711de11385519cb2832643a62fd26c7bd24882ba1f0d87105485b56ab95efaa3c399391869e3a44ab118d4403ae8f229d5edda8b890c5ed17c693bfee51a47f6df331fe6db43e98f91aa7130c99efea76752366c73bc4f1579b5bc23357d785c83df4d0864f5a92c5aacd864511a7dd872511a653a84c1729b7892db2f861455d645fa596157756b18b6db44c334acb70c0b8bbb897c957481c661329622d6a132fa34ea39449528760ca010a389ce5bf062f5b68547d80a088ceb386057b7e78a659ddbeeba8b71039f0537249de84017b4051c6475642385d697f7cd1f19abac9e9206523c8a799d877bdc235e80ee76a45b225c0c9f058c82cc82bfb57991ea22b5a2ed681f6b70f1d568486a0a4e240e7de488f2c61f82a9d52e43130a22a61a12615c5d462ff2867c4c811ceb21d75986edba0e8ad5b1e87b1817bfb574706cf54403dc07b8fb4035f2c4f78b19e64cc85c0898e313d9c3e4baf9b229f5e2a065c321dbf86ffeb95e12df1270256842a88fb143ac6a0904b537842583c8d4585440a1c0e91684a5936caca723866190ba28b79175028c01b37d56f98e9285a02e03d7865e12ab2b20e2bb33bf28a3b34c79097daa0b5b672db9001c92dd0ae1c1ce50f90e5cf0bda6d9a5c011ab011c5af5b612f05d2147c6179d2385fb63fe8138620d0cba46fe19ba9082642b9f4eca9ab0eb1c120068389cf82cf34d83e8648e94d8408b0e849010c96b740c75e753bf385d2b0e733b0d1a9b8c275239a9aa97a60a56a8f70155e9219340b35a8522fd18a3dc88ff9cff5834708ce58b1c55a7cd53022f2a75a5c3cda5d67ae78af968c9aebd716348e62dc94ac3ef342230324eddb5e78e275ff427275fc7d00cb514d1c9da178a54642c083851e65447d032d6114cd7022d42fbcd13aea6919312566153a69b566eaa77701572c947f3183f1c06849a1730eda59123fa1fbffe880ecddf22d06af0cf48b8375e99686a8703365134582d8432bb336db722ea1adad705bca41eb1d2ecb74d14e460e5befc03b9fcdcb3e8c09029d67d33a141795268427a9ec85ba8e50cb17ad7060ee9c291a7250beee8301b1601615741c5d53629927f4512d702976721bd10ed6b5b77c054f9008ff4b988b6ec0aea8d9dee0ba50a70807ed26b8e01b77eeffbc8000c346ef69d25fc63ef92bc4bf6c39172e0e5bab310f1e187a38bc4106a7917cd3ef2fa9a90c52563b39bf328a0238501b91495d7c9678fa9e9b0b605652d821836ccecaeb76d75ba66fdff0bbe1bcb3da28bbe95c85835fcbc7d8afca1417378c3c44b4e432096b9e94840637c91bae6dfeb5f542758877dc6721d4956116fdd6654c2faec86a615c873f097004986f7199661066c1d46f3d20326391a9a2903b9490b295a573c17a7e42cca5236a98c663c020108b465b2bff0edc14b49dcec0da2cc8338a509217982a6bbc696a14067b6d33f222d3e241848d9f310ad38276bf581ced8c8e0afac6861050fc9d2b28883d73ace91f675a345b1cc1066b997654694c9dc76b73e575e2f2166be1e8164ca21c518044ec7190604113b051b09f5d7c2de08c9ff9a0dfdca4cbd6270d9c3e167c5085901ed3f4c704081576313d71e07566777f329dfeb26b9007d5b39383c351d9f51c3d622dd0360df12de758125fa0da89412ac67f823fb9563001f909db5c4f91e2e3a2be4132aa147907fdf337214ab70707c25e0af87868baf1ebd5a87b970832115f500c1a7ef5da79da6788b1a638acf2e79dd0a42c0709af49347a8c289bbfb76ce47d8cd28aad04ada39ab4b26d625b21043743115fa67d36fcf5115ff78f3294823b4b68ba64f6be74c97e848f66300699f3e066b401dfe9decda98db0d5d81a31faf110268e4af9b0b2d436e1ccc971c52c561dff32ebc102363e6a52b9ae03288f3c5e90689de5aeeb9d1511b5927cf9187aaf647d33a16ef525134bbb78a87118328dd0e61a4c6d9a6be924d3fdf7f667ffba84edff813991de7e776891e2d5a0c2553f48964ea444dde65ab7b64bd66033beed65d0adcdf74c351298374cb1b66b97bce886253edb35fa8227dd88d0b5cb6b674769407cca9364d2ee6aaed0bd4f585154f11011f90efd4c14ed1c83a0ea82eddd616433864c9112fa17102f51f5bc123c4303979a6c5cbd82463c9ba0c5c3f7125d5bcbff44105d9e3cc10d86eea4df9de157fa991b3a16aa43c30a9d9f6613dbaec44426700053c5a416c372e0fa67099ec894fcd5587ba842835f1888c5667555efadf4ed4febbf53a713af5c722041e6f781f124c2de839055f0242888d2d4e3cfd95c987da27bb090a7537bf60f6f158545393b81b61dadb6ded89dfcabcc880ff4604053a38fcf1fb1de8de5a9e53a41522979251e93488b1290b56077fb277fb2a94733ef1fccabb86b77f0165d7be434649b218592ef7361f02a9def5fabc8fd661cc812eb7268b254d2dca4639b32e339efa20ed45b7c5153c5dfc6cc9a2012cd4897782b553b5908de0cf8ed5d5a0af92b160cc6e172f17530d31b114a5d2a2bc146e53eae4c81a9ca2b5c7c985201894476039948ae436e089b23f89ec80c723dcd58d94e05cb79ca25c06ecea6f6da6425fe726d1d0dcd2251024f0ffbbc4bc84cc2a128cd62293be5106ff0246a7ab65df879cdcd523ac9bfd7abd287b981a47d8b26b427ea3cf2e5515198cfcae5f40f6d9a1bafad807a6f26dc9daef9bd2fca788a69186c9a4e902dea689fae8b1d1e1385233dc1d0229e68972fcc3c9ef9089215f65acaa57ff8075f9bd032934ade9382e011e2a286f2ada819e4d04b7e3cd8ee045722d317083f5c238712f8efb9f3bfcfa1103b22a8e4f04511894658ffb01eba82ac3ba63bcaa39d68c3804acdc33f1dda7d52f1933ec48fd84b5c80546724f124ce426dc2e6e2540307974d1b1af7c12e98f896704eb9ca3f828f131f83dfcbf2576131426822294df5b2e50b18521c971cc7a44c708ffb5827153b0f8134be797b3e76d8194481b30a6bea412b30c5d5dc5daf2c1441701b48c263637ddc24a346a94751d2dc889e31265897172e6c1e0c11fcf554257ad1da980163a85e4f3b9433982228f1093acdaca66dac5a2c70c42c58b6f5241a7e2787f2147331519a62b6aa7a502bacc8b5141e47e9764cc3da3d43a480ae686c451e70dbb5af6bd722c6f4899f9f8aecd4e3203c426b597779a623b90d8e27b8ebea494be6eab74d7718a8fc21caacbfc2aef902ff14a29643c77fe12d6e2467a2f295788177532969dfe6a2baffa203309636bcd8bc7031a32a8ab39b161b4511f91cf4208f2bf6360f2619bd0211962a804245f00cb9198f75d3ff3d9a4f716c5089e56730f12b20822281ba1bf007f4b367de9b0379c8044f6ae7c6075fde8178568a4be9cfe2197dec693d8f2193619a2017273aca2f58b52988f436ec4740e98441c84ebfa2457b8a09025ddf768884a1447cd7bb87842b7d02e59e60584a35b6c228167b9d209d06557e18a5c51ff5074b20602f06e5a6d2b85ae5e49386b47a15a9682d9d7493a8d57c7e39cadf642d13a1d0e9ecb353e65043305f59d941ff34d710c353d74c1e3db7a94cbae94228091651ed27a084e48fe4f1e72eeb74f204944821531ff8d5f8c09880171897993ca1ba55481b360ee592b3ac55ab42838d1d0ca108c8dd0011e30f263deb81d7bc1e39ed96b2ad0c7e618d91e2900c367627f75ff82a5b067fc9e830b99475e73ddfa454f1d0ded03554d79d8d4adac2c2e02f38d352c9da1329272a16edb724dc8d99939986b149566d7252f183eb86cceff7b4daf86661c929f56fc9f863eb7432fd1b3a6d107badb382200e0f9164b31985e7f87f67bfe5aff1223c2ce9664b59a7d9da821f2c18f4d823a1b3c9ad441aaaac1c4971f65a88bc6a56d013b12844a6b6be20f2aaca648c3b95f10244e6cb5a79384f488062cb9f8ee51f52d84643a48d5f49b4ec197fc299c535e510a91e217e6678454b3f893bd212ea2712e66882531652cbb3661815e6221a4313eaf92c1663bcd3000d5d0a09233f69661428b7254df59158f798b57392086f08cff55a04b57b63ecdee914052b9fc47a3eaea020d50f26141c4404caf9e6965b30981da703e9661e26aa2e6d8f1ffaef56d6445bd46236a555d04e658ae5e5e43a2b0e134b8d996602670e5ee08ec31b943f40d8bf19dae3684036067e0651ae10ea3eed596cf18f7251bf095f50644b42dadeddb6dc524a99a40c530967099109dfc5ae716902a649cd4c22653685bd06ebd2b175e9562bf231cb77f88bb3e4b1a3346f532079d257c4c9e557bb1a52eb945f681e4ae0f07adca496ab6e6fce72e41ef5110131d8545a13846b539f74905029e594534e29a38c724a19659453ca28a39c524619e59c39d29ed45336d34fcd6c53df4883523a10986c451f16f950731bbcbf6e5d01b1257644487e726ca441cd4d5ffc5e844e6e4b2d1f9216e780f768c9465ceca5d22cdd12cea992c70f27a0b9c96df0be5464e5a3d014a3a7f9283405f65b73a52f9571d0b40ce1db20cde9e44632cd5bec26b781fb922987f854ba2a49d4e05083d62d14b084358b14149340d62dcd368574416e453f58d5ace8d63d066c96c96d28733edc7c337dd1b7efbaec48d7e59b7c931863ff111fe7d4c96bc07e1d673f39a9f48545bee4a6ef84355369872f6d53481b9b6b5f487fa35d8d76edd5ae94455c6b4e08a2bed58fe2e0454873d734bf3104d134cd35cf489474332d1b69b05e8cdd7eaa66d59a4d8a448969abfec2d57d506f2fd2315553357237b650018eded6eb57cfb2cdd1d35a6b6e8f6e83f7b67afd8c4c3997d8acc7988e057dccf25148a803bf61147d528ea1c1ea2f42f77e1490efd2047c5d73ce6de07ef321cd2279f508e09bbad9a6fef59b39d28ff89244ca99dbe0dd2ce364d739fb381c488f1d0c3287aefaba050e626856e8600e201b8eea2f54af41b3a366ef31740a57e0a32688a04b54e143ce12453ff4f0e19565245be9a4c19163471376083945b882b98f424b3c6922075b8c91babcc216630fb5cdb4b5b3c980ecd8fd3f76b0525e79b1d80196de944e1e3ac0d2a3cc31e79c73ce99a3c1ee3ac19e35c7ee9e50d87264ee79cfb8b9fc4a69bd99464b233df23e3dc75575520b5fdddd0390809f30e0b72eab479b4dd6e21b03b0f9e952fbe2aa567a43869f8ebfce5b4fd935449895415153a152190a3283101aba07f8a3d0123418a228881c52790c101e2f4c244bbce0c338c4b3440a3ef43cd78682cc208406db3fa05922044bf07c9b3e0a2de1faeea35050143ea429aa42c8ba7d784510440515437012d4030a04de3e0a05e1a0caacb17dbb41237ca09bc290294a08b8a357c90909b6ae0620205d71c4fd00a159e1b3f95c290c9178c0939319693cf0810416cbd1352a418d025036c508e89191a5b94d4c9a1c343872584154efa569228229f8d0aee6d2c86b4408244d0e1a1c39b0fccc55bc3b40c10e148ab28c642b9d3872ecd0da5b01fdc01139308c3f0a011d4901df8f424046d485511f8580a4bc7c14a2c10da86cdb8cb5d65a6badb5ce596d8d526aad5fb8e3a3cd724cb7b5e2a094528aa294f69c7376507777c774b4629d46e05ecfeb6e494d524af97df4eea63f4f5088941e001fb3a494ce10613010b1322f33915417a94fa96fdd0d83f4a9b24fa4486dc96522f48bd4ee2a0021e5927ebfd2e817669366dced6a6ca871945a6b7da35bc6dd8e2bd5f98516572024a594ca59a9b5d6faa494461cd2c6043d6fce39690e9a1d40a48de8cdb9540d46679104969ee1f66cce1ad246f439b98d527a773418bbb48149abcd489de9de169e0b98694997aa222ab6804cd2174396bd979897cebd05ca05460583665b07e2c8b18347102011fcee18cba8e0162e2d27140b158bcef34c25fc22cb3ca3756af6928210014141b6d91880e4e020365dcdcda1f461338e8143611c6d84d5ad0e1386fe1aaacff9d13a2d8d01892148839d816446a527d366d9256d9c3591482412b55ba68142be52ed6a31d223d56eaaadf33c92a974daaea595ebb46c88deae256dfe9b6f5dd5fe6adbc6751c4943617cb1b52d96d64c236d43743ec0b246f05e7bfd926e06deda782d8f1d74098b45461b946e2d5c5763e9cc9183b2a0b4532265cf9e36bba41267afe3a84fb318e96b473e73ea5c462b49e5795ac94120d2854873d0e0c8b183c70ba07739e8107f1269d32eea7618b706fa6509a6b36552d5902eccf9d131caf39818dd540a9243ebd94835829ac7ea11d43ceb60a0bf79ccc06f37ca2e6994da8cab91b6ad9f834557637d47b36c0e1eece091e5f8b8a359b688eb920a2ef5e2ebe5f6924ae75228e8052f6512a94413582e7ce6b6abc96ef55b1d2bc1f3d5a312d53311b1c3fa60313f6b44277efa5dc24ff7747e3a81f253a8073cb012fcf4a669750f6c63d56314dac107fe720d6207b12789d83613f65c984b010ab8183dcf853d1736bd2cc1a8ae33954a96e36abc5ce1e50a3e822dd21a42697b767b952718fa5b3d62df78f416370f9d7635a638731d8a103e45516447c081e99f105b417e883cfcb553788b443ff1aac054e2856223cdd86c4dbf6e5fb3658b26d15f7be5c5087cdd1a59264417a275c28bb77097fcf2b97c33f3a8a3b33549db0b449cb91ec670a1fe106d5cae4a8a3a02cbff8de41689bf16f6d71e1157d747e93b7351c0593e52ab3882064b5c3db27c89d871f5883d7a9857b8420f23dac3cb71dbcb92ee43ef6a6e0bb7a919ec0086e861736aba8b532bd9979aa1456a7ae62e99b6c847e40f560cc1240a778a107a18a1c52550308415f438a2818d891e469c5c03568aab8711da0086e8117a1fb324194fb34a7175bd08b74ffe5a277f2d12581aff0d339d6aa35c29b88abdf2d72b1011e56125418b87758878dde5039854a917d108e461c12c3c9c3c1367cb8212cdd5f51617461d451dadbf25bf6eabd82362abe60411d499ce95ce94fc0db39ebf5992ce90fcf5d066b1582e141bc54af96b94335bf409d515049dc25f679115d03d6ca64373756d1086fed2213a448570fdd2219c434ce5ce1f0e0ab8adccd5bdee2282db3573fb9aabebb37380750b4405ae1cea08dcffb20487164886cd5968f11a0d5e6fb0c1eb306cd95f6280a5d37c7df2805fcab74af783cbb468fb6de3b68ff4b10b9ba7a8875c90d034cff5dbf21191d76f08325bf367aeaedf520e2f777d3b7df367b6645c55d7804eaf7701b34071a6e6ccd5f57b313ee5ba936b58ab4ed04eb3b4ae66bb5d0c3b58257068812ab6407175ddbb35a7e65caf3a354992eeab0d76d702fd004d29bd9f3f73fefcf5165dbf684294d2ba75eaf4082cfd6a1f29fbd8c51081e5679df455b745ead322b65e49cf3d124be902036c2f2ec07de5cb69af6c296bfd2dbbf2d678d9a09c57d3b41d7ec8f5b6f56da6269872c7c72cb30afbc2a78f42492c8149124efc00bb7c144a0296c42b899d24accd2a9d4d8323c78e26535cd814750aac7d146a52840fef0c70e9a350131f00a1c9ab09508b8f4247fc40075528a594524a29a57126d24c69488f361c997c87784ae065083ae79c73ce39e79cf706a9ed746a29b23291b85c394556a69440721019a3d952b9f4ed68b6522ebb755e524a81c460307983398cbff017e176f4d26172ecacfa706271ae70607385828e556c620dce54adcfb355da374cdc349931b6b140b5c0d2eb6ab0575b2327eaa03eb22f79ad91f3d34db6334eecc309c28135d892836bd79c3b5b7cf4cda5c503d8c238a50ef3dd144d55fb62b9961f70dd5c2ffd4bd1fc8403b18f4f7c8022808f4f7ce0f9eaa25b7e266f6aa994b2e4a66f9372769c3214c629517ebae90be314a21fd9e3c062e8d6732e5c743538410dba3cf8d163303125c642ca083e7866525c6c16283b05f8007f805f7d010b48799cab69bdfa66db522badb536aa4aa1051ef583feb80d76c52a150c4c94dea576978fbebde05acaf93db48894d3fc3cb395cad4e7e78b17db0b15180716e3d681d882c936439b6b0b42e6eb6a64741a9c1ea352c48429c62a625599375e37fa061442f8763a147550ef0000fd6c6f950700281ae10950c42060146788701863334e94b4ca53a9cc0dfd7c29c236f345ecc50764ae66ca551e9dab204e50afa6db0f27f5e10ccd15cd38b006270d968432393fbda983eff33cdf03e22f2593335b54e6c58bcdf35cc488d1d5683638c82b7c0e787312e5bcf3ea1bf51e37d86e9db6dbf7f99ee75901fef0a7fa2e47da6038c83282dd0435ab71607375a9c09452c932e2bad6a29a63c478226e315c9c73c6660b26abee8d4cc8e064e414dc2f50601ca2d9da5c731514593774109d44d68d174e6cb654453f3dc4718a151dcc77bddae77c1ce41576ecfc4cc97c6d0eeb4ff36c311cd7d3ae513955f1d2eb135e3a14e08c195d4d06b6c0d90421b66054f80926a6fc9c02e37e24e9a7dfbcbc1bc5cb876ba1851668d0a0d1fda01f638c3221882d98acc2417c6a9351c1bbe2cc14af9fe1e6fae936b1a8837403d6ac167efa8da06e3dcf0d283f69b41e9888753331f9f46fd2ac124f5029ff884f9d0c45f9e98488e69ba01b280d4ab989f50dece675d3a4c1190308388cb1fa537d68d4e050dfd3f9250a6c64f493c6510bc6630a27a85b30f97d5aaacca5b213a0d2114eb9cac3cd8706d16c7d4fd328ca61744283e8278b7f9e185070fca060d517e74aa646b3b2fff122058f7e9ea863eb71713902cf703300e02a0fb859291f304f8be2ccd1f77d0e2256138b3a4c3e1d0786130401a3d2e77204fe9eb923680995259efc740244d3a034e5feecd7766d00b0716d701b0d1761686ebc48c13531166e7037ba9a8c050170b2fb41f2ce618c27388c4e786227c3b6d3e37205a5b5736a4bb6e4f3797e9a55ddf43d3e4a9a551da859d8a73f9366d5fc3ea6ef953438bfc744ffe7fb25df03a91e68aebe4f7def3357cfe305612dc6706001e87c644fe9379dfba6c0485f684305a2e96a3a8ad74fd75234d3fc4737ae2b4d13a6f5d4c202d5c2e5c573c1424a05f302867f36cb316264c8dc19e0aa058d468d1900d8a08934a51867da9df03ccf6ce9789f25fffaa0293027507e46274a7e0e45f9303a69e27d189dc07e3a893919fae9b6e2c070829a459ff0b38addc16bd98226b618c3c2bb5c81c3eb811545b9fb1f2ad306efed18b13b6b0e699e462658f6b759aa8fb1025526455187cb472eb6b8b8928e52f231768e790ab2fb01f35a91ac1588f49ab2a804787a487a5117a2374961522ecb249eb6b9ee743f2950dcea4ed891784a4b38f9d0d4c3f3a5255e8ee2cc5cf2a61e16790ab87f8371c599e9f908872c62390786e8615cb904b83d84211afae930443052724ed4e1e2720466117b09f3b908065b8ca9aeef014f0fab8bbacc3fe277aadd639a95395823ff88395272f68df1031c7f4ea7d3e9e77204de89a15d7d66e9ab3c7325bdfbeace5cd12dac402e57cc49ca7c6a572391787e9ab579d5d949527daa92669172dd69f0e372d569503aa9ab394138bef4b0e6bcb4a1027d1288d413085b8cd9707cec2215883a4a6e8a610ce2628cf2c7f421313907bc87291b6125b5d34a559c6987f991f2f9e78a8cc9a1189359fea8c1e9128b518b24b84510d8baf4cc45859050d23fcd0a65ceb7ab91e4e8f44efb342b655dce56f233f338fd4aa3238925cb4fef1b1b944657164d79a559d36595daf55e8c2710af0234c495f42ae09cde5e370f1b8a4817e447af116d0b863923143f27159b81c499e92f4d60ead2bb948218638c11034343bd5365080d425ea260e95b5b6b5b1cf7492944324a777288077732471fe992274a2160e93d0d56f7f1e1e100dee1a37c1ed953ea6a6eee2cc96af65a9b59cb59fbc9283c7548f278433c43430d5697392138011b6e286244ea741e42c36c21f2c670411094428082ca5759851c8a3343a629534c99a266fa509418146f1c1f63ead5f02974114304f6ea471a8c317af2ce39e79c31cecc4ae4794442141161c588ca1123f5355b9268aeaa4b7a442269b01211c9dcc91d2a45475fbd12c9979544f7623cab7ccd9690b9aaf5f5d575644eb3c2187aa4592e9ab25608d156bd3ad157f7eabd35c2dfcb97ed6a09ea59028b128486062b955bc5d7ead543af42e24ca53ec3bbd3ac1f2e797a9a555dfa28f144758904489018a200b1a0cd1c9c2d2904112ff89a55ef973b307b444facb94883b5c1ea351aace04645ccbe6ba459d58bd499596f7b43b382781664b6567155bd5602e09ad5b7198c33d59bc0ed95a789a419a20d6b4a03de8b71ebfacc2dbfd0a0c541ace7e1eeee6ecfc318069bad286528fed00c417c664bc2e68a3a7d210620b099c3abc90cdbf205e28a3a89077cb367448a14380a4101fa504a9f3fba1763cf730fc1496311f9dd502987a2aaa7b51ab5788089a34d8ba7e8e2e3a4dd0fffeec6d1e0a491524a295f6870bed0e06ceaf547fc6ea761fa901b8c60f968a4752b510ff200bb4660daae7f3579a973af25d3bd5d96f9cd5c8cab1a9397f4a93e5f33a7d7b3963cb73a4695bc96bee8242d2bf90ebf994c2693c93393676eca9963e7fe7e87bf18deef7c87efb84b1b24dd9bc9ec66433608498e84008981448a40502cca105d02d4e43593f02839e28ac0048adc20c5c50887315644ca6aede9a99474926739ec9d9f13c94f9ac3d6f999e7a4d65a4da39af61121425f09932493ebeeec56d23612497392e635904845fab53c499c36442369453eec86685c965dcda6719e72529e468cb82c015727f9909ad22ced86800003a1a65ccab15772480f8af0d04693fcc0e865113e0a3de17181e1f0ce2ff47e4aeb2f704a1a9cb175767a7866112354ba9a8606bbbd65131e4ec03c7a4a9b3bc7b4a3122649228e061d9f9c473b1258ba759b6fb65d917e9953968769926a485a3e7db457d8e4b159d84ddf0e39dfa564e736773be804416c53186dd56618457365d632077ff857a7df36310dd6cc3598c106adf81c7030bd748e6607901986d86004c94ecf0f139884d2acfe9f466c6d43f2ce1d09b5bdd6614ce447fcac3f461ba175d9363a6c24df6c48768aa2ef7b2795d6466e998c695005d2ceb30287de5f63c21ce4470047a129aeef8800d969190709de883334ea905f67cb5aa23a3cedc1a17b8cd1d65a0c4c488c88b273a5a60d60e932ca19847a74f2a7e7d173155d3a618b1d5bc6c498b1508540f2f1090f96a7f1f1094fecb748233be758e1f56a761a674bb1c5981622c03130c052ca47cda9e654e3329f5d0d6cba77e5dbb5a22983ba557d26ac59da9db0099b574ea75f2b50956e55a9e50a34630d76cb4e462f4e5883edf3c43558dd7a385f514745e265d09c66afa823da684eb58f3698710d6631bb3233c2f64205ac25a972a741a3d8ae98851249b15265c28286a0cc97fbc81e9bfa31774ecfcf4ed2ab9d393b4c514fd19c06dba7070ad893dcb521179a87274d92fadbbc9ba673eb1be524c93712e55af66b4ec30408a03976e23d794dd3342dabd1a0e6f2a36950cb60839ac77992ae798ec94d6ddbb6acfbe14f22713972441df335d7347aa3d1099ee8e43cd1717d7c0284d147d73e3e01a2cac7274044f9faf109104d7cf7f10910b097cef9200bcc07599ac4e890b1c5b9bde1f791e4e18d8f04f8e840668bcb5e886be61157d2c368a5fb11618fc310f983e671b8e13b452936a2610245e6d1cf2c3fe74eb705c27c11fdf7510807414fbf366e4779d369a6bda25f23399a24362558e09aee93db849eb8f2a03f51e5db6366a86edd663c5741ee5cb54b13ecd202cc1d810474ae9ac0a10da7eeb3359d01d30a18f551e809243ebc15865b8ae0c1132510e2090e50e184154fa81205771f859c78a2aac00920fcb0c48a133ee8c0929d1ae0968f424ed8c03f0a3121023e71a4ab750b01ca0f9efcd6941609894f3e28f6008893df66c6018e943aadc2523ae7ec212191525ad4f446a27929a594d65a2b4829ad32c618670a86ac015f82d19bc5399978ec71332d56b774ca46c1a53ef4b108277a5c7c9b4220e40410f7079112942431041f22c478228225b0299a40e2a8477bbce2a5c91e1417a10a3f9f4059f9a64400b31b6de454c189158e20e28722ec10021d1a24e102253ff440821ed40a2125572ea5574619d6cf22ac20ca959f2ebd7b5b945881117c3065a70a29aaa0f2c3ce0774d04303287a5029b8c0079b0fb0ec21e5890f55df1fc60c41082fe3db2fb6220a116108515ef05dad0c3da52cbab7cd5dae90927369b51a133b0dcacbde7d8f99ad929bc0b9a2a5cf9babea24cf6cc8a4cb5c1d162309b8c2de5335cb4eb0060d8e1d4154de8f5658d441b99e3823b769ad80d1ecf8019f0e21f6218ea71fe6c8ecacb118723d4fb13c2c0a1fd6284fa1f061955249439a0db6ed65098e71c9dfd836972b7018f3319b4b161c572f52bc48f122c58b142f528435cc6c7d3842e6faea02c722af54d4cb2ed58aa2f459360ee179e6aaba2087a48d8a6d51d1f710e51562152258bb03710514c457ef107c7518303ca0db2c4a29a53d9d479b7e9b75f62c652826bdaaf2050938c478b6eec5d8f3dc419d2e9257ba3564078e1a31aa0f25114b4ab38aaa34abf39a798de9108338b61c7a8d0f71888be667b93fd4e73558993458bb5fdd144c04449469727bb24589c1908bb02dc68430433f1da6e6d41c9d57add90653e7e7d46cd06225ceccd24ba7f4ea17a33833bdd24b75c402e6c558c0bcd88b91178b7950544751874be9053334a350c3e72dad288e9b735e0ea57a2e577bed0b151ce61d58f4bc335b31efe49d0c9660a5201b29bd1ec63ca57e31c9298ffe30252579ebd6432d89b72ffeb2e08122511ae2eace6cb120ea95756bb7ebf9c0c35bf7a410bdd53cf47cf85e71c6c2e44881c953c09987303932b038633d1f61981c1ab1a8a3dd3a0be10c9ece32b0ccc3193c6f3dcc3b6f7d86f5193d34acf6f5f7ca7998afa159a1bed1efc508587aa43e601a070a9461a822dbf1b6516be262a000779d92963e2a6b775fa8c02d3ce02afd534e3dbc35b138533d926f3844b1b9d2b2ae8684b1bb5cd1dd79531335c9a1a26659f93841cd8a5f72968cd2ac488423a55932e3942cce104e940f870807c6b93ba6cd91a8cdb24be9bd7951c1618c01893ab69c9bdd2bb7499ab4e663020343afb9cb15dd15e84d9c37c6a5ae2b75a5fe250ff43c52c09bc96da8403239323b38a375f39723c08ea41c00e32a57651d52ed300ec3613cf648a93ce580940ea9ce45b8a7fc85a73cf650712fbe87f1f9f73c3d80c9712f4b705763138b33d3a8c189657355ae9f80c35865e8a7bd5d8a3048d7b74bd7db48d7770ef2fd2ad414dc37f762ec790e6a74f3ef06d603980ee38bfdf417dfcd6bae8280559ecaefe380945b2a304cb38e3e8603a55b4054269db7efd3a0edc1a34580abbba28e46390eac5713ab7adee6303a51e2c34364bd1011441259df13c179fac829c16164e2e8a77c7d77aef0d501f3a48da3a41eb08bbe54c109b289e1c06a6f3d6c2ed34b95cdb5f56073c52666136322c6c4956a136b5643198a4224c5a6a859556cac342b456dae308185892c505c509040c981a2f3d3693dc57efa3dc54a26176eea6a50d6bab02c94c0253799625a381728172e64f53c77165fb8e998685e9abc3a4d6c10a4a69b2252cea3eb977221fae92e50d68528c6135c3dd6809ca8a37d7a0376c2f9d267c3306ff2d8955cf5f9f801325bd12686bb58671f3e39c0a6cd254b0b27a42fac3c5d1422e2a79b8462458845c8f929a994d4546adb6d539d314e5083507c04e188de9d201cfd89bb796daeae5b0ca1a452bf01bbf1cac1d5dbf461bfd144267edb922d759ac382629ab5267bd3a48bf103dc35b19bd76c4d89d299e29ab2f2d371577332995a5cacc02cb84b15b00d945ecdce3631af07377470e385ba814531e42d816dcc9f27eaf0612282d3b552cc37fad92fd18cc3bb29bd664b26e77600cbe47ccba945264746673aa99da840c6d6f3c4d5fc21620b07c682ef9727701863f7626cc3844d0c046968e8cd618ca2a88a959f1ec628ae446184c2e2e2618ce2e86718a3c8f2d3fb93ef3c9afec89eb667393b718503f3e91fbe73ece0eb371ca5a45a69bdb1d2e0bca9d2e0f4be29ea9b2c37591a9c3737af6675671e47e0707e9789c8ff42eec3cd15a390f2207e1c46274037af6675135850cc0594a166b9f0e937516e889a9572918b80f1f85e2e42e5d36fa434eba5a84ab3ac34cbc5a7df5c69d64bfe11dfe8064bb3503efde6a8592eb988944fbfc9d2ac163985ca9b4eb8b9587c1b12174e50f7cae5472da71be339c24f7ca83c35e480179ef254d601c65f78ec01933aa2ca2907a81c86c3c83aa45ce5b1472ae52a9817aa2e6982cce5149f974e9a02f4fed76b945107c9af4d66a3c3935ccacd650e638814913f3d9bbedd7bb37cbddf5f0f62b25e4d26d38caceb61bb10a30deced99c93b87d65aeb5f550dceefec6d00672e3f8cb0f6229c07317281a8236bf1925f56aa25db80dfe22db946839d9fbc3a90669dbedb60d75d4dbb5973fadd137f44a4e90be97799fbb1653a5bca1a64a59987dddd190791798b523a26797849b9356ddecb855748b32e07b0fc314316d260f56e1964ec5277a6f9d53e1c4cdfce451ddd4bcfecd56aae1635ae360f9a26b93823bd050a7018873ce982fc7ab32c07f9ede10e6febc98a293b4ffd523a85d014b19f73ca2307d0349294524a9ee93bbcf6851e0e798965a67dd46f96a90968df603b40fc28658c3246f99e7c8227c64c7384431a97744decbaa16619b695b72ddef27551b786506a02e9020f47a44ec0061a84ccf002375b38cb16ae1b3df2d95be4338fdd01e24fca7de72db30e407f332f995cdbe1b5af487d53a6269036382f7d610f3de719d75ce6a46bbaea474abb6ebaed7e50bf3ebb1a92e699df1a9be9d6a4245b8c316930ac3569d67a7e4d346f71f56960655dabcf88cd4d2e7d9b5d8ddcb64d9abe18628c3272a422797d688f8c1cb1d6963879c452b7d5c864cad5a862a134ab46158be521b6da448f10cd9674f178474d74d4455f7dc034498320c62d19579b574d27c9e6a1ede1a80cb73cc85825cdba3f6011845688aff627b44bdeba2e0e36fe9b67bec9cfa4651f32b68cdc7c9b9c6c6e73b9d99ccebaacd7014cda716d39667296aa0c19d985440811dda13b7487ee987248532a95628c2d21264d33b58c48a46a94b256c8cd03562d5a68a1b56861b516569a0ccaa22b812dcc9269ebb2ad58643562d2ac19f3c5ad0b494e35b20e7e1d6b28bdaabe755be98849ba8c1899e1ad9557a73f1488be680f5d429928f9ea33689066994c7487eed02494276b261958981ce53cba89acce8e4d425d3648b34c3994e126169926a13b7467b6a82b09abeeecbc5c81b3c3f80be772785e7875fbd3acdbf57cf552926cf2981ef09129d76062e135d82346668bc60665f5dc4d1a36579e874d247772a88b44a22e237447ab469bdd5870174060c0d0b2ad46a994db6a64b35b8bc475eec943ecbdca6354559a84f2b8664b88664d361259ba03e3a175bdf090eed8924be9b2b6c43dcc876ad05a5788fa90ee10a1d549f128944988641f46a222f2590899b52587176720a58fca4b6a495314d32b2358df6ee0b616d3512ce694301e5b802641f6746a719353e936c604371469d062975f8633cfe6bca159f3e4d62595e855f1d6ad9dc25b97124f1adb49df24f653e6d837ca4d4aad8c19badc54c57e92a2dcc972ad355a303e613fe51ce4b7f8a801e708344869add9cbd4a7394ffe32e5577ebd5ef305be246ce328277776263033c7c1f459f62199e35c447e9623401b04ad5bdfac3d7db24983d23d6fbe7cc027c71eca22246fbd97d07c96666539babc423db31275449ca92cf294e0eec1f1a12cfab61eb6ce5beb5bdcf1d3837ca0fc70389b56be5ed66513ebb2c85adf2e37657debb28af579bb1a393324cd9a9dc7c8c52d76190d0d5ae7d1b29b25f97aebd45fb2892c4ac2a34d287983d190fb34681f0d921be8c9e65bf4cd8bfddbe64660882d6fae36df36dfb6cdc348e5378f77c3f25b969865f28ba2e8e3958f425060f94d7637d30665e570d429bbc67a5d039f6dcea3378ff71485a028fa30c76f5ef18e66398f66b56f0ec4b7b892cee590bba84db5b5f79bb77b0d4acfe17d4972cd81441df3378fa159d3b74dd5ac2cbbb76dd26505d857cad91734ddd57cbed16651cee61a2fe710c47e3d6a85d4f2f1e8ab872cd82279345b3472758577c6433c935d2e9794aec89251ced6cc0c57799cad169ff9645c9de4139e1f0f4a019e0411457ef26d910d71f5d9a1ba3c9fe12ebce62ce3343cf46038cd2ef3d65cfdf9ea5b8c0972f653935d7e34d34c25ed80441f3b3c8f297988d587c852798b87f507190feb0760785845c072e1612dc15721bed2c8ee39e7799e7083323ccef83c99e9e530ca53794cb51c46792ab797c6cca7bb868b9cbdec5ece41be8b1c52cf356429e91529abaa4506860b0ada0ca33c181ec3653ed38618ca71d9b31dce73ce81cb59124e7e994f8321cd781aacb3033804677c9e6f99ca2cbd2f46558b0c0c1794c617e3008aa8e134be1cef51c3b7ed099cfd3458a5dc666c16e79e5797df8c1d3182a0cc172308e38bd1c51723e8de8783c6e4e090be74212946cfe41bca472129567a8455475259bb1a2a2b9d1da9d3a719c617ca87515d52c66394f11865649cd2344873a6d360c5f19e58f0282485cb663f3a4b9a157a402e263ed9ab5961a6e4ab576f46885b3cf494340b865718a80665b8cc47447ee6335b73465679d55b72b6e339731dcd96e7617cc4e5989db80665f8f4ce4eb8c1285d040df769d9dd1d4e1f397d4e2e612797d608534ae91703038efbf13cdf3cbbd703f6d9d57c6e8ba40bd9ab5b2aa20ee9d5ad11224b86d7fb28fca847c5157594cbf86604a9e72f461b712684f1d46bbc3c751adf53185f08c365ac28e8fe521c7d8b4b1fda4cb885165a68c1ae56de02085a195f0d324e44be8c93a494cad0e234e7205fe6907359834c8e0d6697918bc8cf96c8ecc73269d60caf6e5fb345c3abbb787521c9c97eb2d3f864d15cb5b0faa4513d4d1678b388c98389833983e93357307d64c8983e32a68f0c9f1ffe20055dc69c31c37934fde9337da692f9435339d0978e83c9635c8616973907c9390b6fe155872691f1c922f09355322ecb69169743191992ada5faa8213638c38bc897317d5cd347c667e4f07e4bf8d5a0e1e1e9675835ac1f7dfaccd64cae5505af1a41003d8d1c821f17aa4bdaa81ef6c70dc499ea21754dd7a4949b9cc7f480c3cc956be0bc88fc16af217b11f92a6fb6b29db9aa39c70637165cacdf55867f524a83f5c543794453a3c11dcfabe732f9763eeacbc85e83d567fa34cb662eb287f75da49c05f7982f7bf185f25fd85c5d0dfea83c460eefab3c673f5fddeb014b773779585dd5559154f72a1d06c3786c98ef9b4abef9d3607552e79a2d5be479663e7d7e902e6538b974ea6a16f6ea1549b364677372e932ec1c86f398f15f7cf161be10abea17a258f842948b8f08f53c97cf551df511c9587c45e4b7e40c89abde3fe12f7e383e9afbb46b7b0433984c1bc00532a730a8144e9575450b118d00000080023314000028140c070463d160389ce89aec1e14000b87a2487c601b4ac3204821850c31860002040000000000803469400063e89551f7811e076d69d63f6e648810e2aa8d4d54c9c521be00807d96c51c6d86947c41c3d3313811256250efc558530dc2c67d8922ca151c9460968b50e2fd53257b228a110e90080f2b1ba73d115bb95c7e76930743a14f2d99d550857ddc172a1e62f40b7526b485480530b48aa243a025f8fd8abc9848b79152bc0fb52f4497e25d5bc7372ce2e3e4bf843d6ed1a57e750bac7866e726ff85fbd4c226b193392354d4a7866a5428ab8ea8348f1319b4c3812a40c7bf28a8e0f460665feefe7c2f3476431260c8c297691c48b3ec1d6f95ba1bd728734e4435256d7f05cde6707c763e415d3f622149be6edad19d31988aa439121825f18f4f9c6cef957668c09c0711865a534561755cdd92527cf336b8de4374215943841391120c06e06cabd44198b9f952186e9e411a9c6b26916837b9a60452e7748ff7c6913cfe296e25de23dfccf8091c388378615f0406cc1984691fbf7092575675d1647878f26bfa947275f07de577f48b19343d1c5dcd5be2e64a136cf31235011d7be5b7063d18f88cfb56ca76f5280b5cbd692306a04bc0b290ad2ac2e6f364c1fdf2837cecca2b3f1ef944598955cf3d9c6ee57a781d8dbd957b88f45e077a4add648a5f66b98e7cfa5d3353bf1b546427f4c023e4d5674f73ccc257fb93b6bc763e0b1917887f9622666fe20c4467081a99145399842ec21b9c6f9d40d74bd2b9e3e135a7f3894ce7d26658c5366b8e6f7788d819b2c2883997389e09fcab764cffa760dffd29d463473dc515e105f8cf7bbaf0a3f56f9192e222008bd2bb3f6c901d82e7a7c6b979427f190a7113df5ab5a30bac742fe0ae523e799169e4785911086f0c28f44e9b1ccd9790c5c40732cfed0fee086060c6805c05c60640d7fdf1ee971fd92b76e4d62ce10982fcda710c6eb3890855fe2ac193cc6b6da8780013585f0700c780c20f731f7f6d31a2e394586bd137af29a97a198017eb1aef5310a06850b6af6bfaff719984393b1860f300e268559e1f56087483af8bc1821c462d053765dc526c1db94c92da0bbb689727927170b96cdf6436898c57d6d170f84d111f5342e901ae52f1c2d8ed376d7ac69f554ff05e4e23b7146cd6468ec4946a93682d68f3033419e9651650193ac81da6ad1563422d9015d5065551444145e2d56d5f4606db6da15c68ec0f6721432ad63db88497906848f87930a58839f9097dc27f1169abde518a19a6f25eb925ea92ea8a9e4940d4896e25970c947ad90e380bf08a31519749399d37055db4256158865de528f9154863555dd8db2af38c359de3583746dbf2dc0e1170539e2548dfa9366fbda661a58ef70efe55354c4dc6059cea8f6711505c0045e7b1d97961d52a0343523be6cb37f4ee7d0f882b026a7d39d9d4a14b632ea6f845e282623aad210ee6b2702c7697a39d3e025fd72d013c0a41f237a51f51171e5857e109563bbed7075e14f0fb999a54cb5e80daa7feeebf41aabbe214401c796a84ef14763f472414939ba2a2dfbad93f608f573de2ec67c92e6ee9087e4cdbe36c43b51ab5ab18b0b446f4adb6fc1076cad4dae820ad5f23a2a7d9e6d77157203dc8c2d3730e35fb1bff2ca00cdd6ee9826f330d7d447f25577c714b43e8698381e545a8d4225d2d68e5e05eb7d848b8ea4738924c3b51792f3801441849b97dd489b71a7a8dfb26917e0adb367a910e14c8547fb198ad9b56b874b5fc2e4d84097fcef41cff24539ff709606f7f41501a4d9eb56a8fa119b10a2cf14c004797c96e26ae496e06cf21acafb06d830be3947a75256dd04dbc0bd2903d6b7a3ce3d1705586a5aaa953956d67cf67aaf05afe7422ac356193a552a478e79f66262458d953392136413f583afa3907e77226ffbaa0782dd557bbccf33d6d25673a83334b9db6c1120d7976a1ae14dbe552b6709530b765d49f4d082d8b9833410aae6b7fc940c02cc201d3e927df7ed634a1dcd1e43f6be4c93a89f0c54a66850a305eea1491afa922314524c3acdfab80e8f20363c23d5f40b81ea7a210fec14f4f35d5afc648999bc814ce3585346dff710f6d5be55ee064db73872641af83d90bd017b9caf7481946339e61593c1ae45330a078ee594aed843346d952983af35c905b7d282d28d07c24cde92cb0d878e525ae162e6c403000c146c2e40696bd34881cce7cb61e015ea5a7cd063394993a907c26b483aa96d74a740a90b044a0db63ebb041efd766da6578d6ae45b01bbb128f7a8b04a5254f98a18fc912546f080192fb7889be924e77b4378aa229e798c3a0d13cc1e480c461a69f71c098d65d902e9a88bf3ff2fb685c908c4a318a65b7e0671ab7cfa8b00b8b164e7394c92babc29f16056b54dea08761ee96a94c86aae7a569f000d0f9265d9a83ce734859ccc4977045d0dbbcd6220b593719c2d29517491d8c4f487885363a2cddaa2951a85331e1c1d20b3324960b4babf954454e667da0f9511a4b8f4c41d23b4365cfc300219092a462ae8acbff56b1d40b0b6aa5374b47dabcedbeaa1be4ec96fd2769696f9028e00f29eeaeea6e1e68a1d8f74141446cfe940be722564ea5d1132b5aa8127bdb97495b1bac781209ca8d000e9e23beba0485e21cd8c7b896948376685d71a1e2279b28405cc2aab2c77dd6aacc29518a36d3c999b4164da70379741eaae52bb9bdbbaa72f61fce7729d267bdacf3801a00b1cb4aad1b3bc0c1a0cea2a86670d16af8c5d8f6ae974a9d1e31d60a0b7bc8c95b9b9b86acb37ed5c0ddf0da4c0d80a766c80f06d479b20630576931bfcc63eb6ff323e88c78ac5798848ada77a0bf8d554d5e96b87d80f7a9f154062ca8208be77b83efaaa39fbb757724493a34867e23f759fc97b959eac8f800de1004e9778a37494e064978d509d8a70f77ef9674ffb6f1c9edaac3d70d6c1d66fdfbb64c780ab600f006bfbded41946ad796598e616fd3c29cb5da08efc62301856c8a8df52dbded3f46fd7184c9b8bcd3595bcc31b7b5ca0c71d1a96d1ce7c5eb7c1fa2d90c80a304ba0041a11d45db5520170c9347cfa87f61495a0a6d4f137f05a67e246344b46d2226411f720348b48dac23678afce823a21ac90f87a3216d5a0ffe37ace078f6edcb12630ff92bc7e36f6ce1f25b757bb8e28106a467e89fb837b59acb2bebd896722587b5f0b0c3a183947ec736105b42350d9bd1ec8fd16747766cbde43645b30d49386c279792a18d42f8dd722d8b3882d87abc1696e94e34e190ea6ad1b0d69e25b7723733490f2dab25aaa8c1feb113abf16e2c2955aa5e4e889afd53ba878fc289e8ececbce2920501296e0c91db1b5c8859203d4e68dbc084fda342cbaf355a441eb6349ed6ca0ba81ed486166790e52c9a281a7636fe918758248b19b111b464d97dbafe4cabac712fcab7d71c987bb913581944bd29c10bc63920c653fee251624f92aa337e596c365d6ae50e6428609a7109e89184c2ddb37bc6c7ab6edeceebb71c34fa270399d5a16fe833a1f45ed903a44965d6a5ff5659f8caf131de0a13c3a9f672a1e50a4bfcf5d74e7f9f6aca09459d02a6511d13e59514d0a89029f1d07c0164f7c6b29ee60c09f86d259040122760166748b8d28702d7373b8acf48e9065741bd04cf5c40613c790859c0b69d2954ae7015c901ce9e86be5dbb680d8620c971a3332be71478a706c2c4f19d39dc52d328bd0c6237334ca7f8a29434f5cd10bbf941d6f036d8ce740c0cc9301f0e8f6e7ffa933f79aeca7e83f51e540b85eee9654f284484ab438379275bcd387c4f62968ad7148cbd686dfdf6a3e72b3ff3935c8358e06cb67eb3e882a33f712bf7ee6c69a867797006eb9b51a6a5fa5fb19ba1f82157f547443eed89eabadc7b59fe3577d6373959a0b2ca6035b32baf5f2f3ccebafa99bb9d4f1ddf1585cebeda17b9cd92996903f04dc6a6f175fa5564665d051ddab2d79dc11d4ae88d07ce175e4c9b8dbc4c3675f695e66a55c2f424441cc36d87a5ded4db0384ae5f7868340df2d7b870a0cf87992abfc664096d891b34ef38b5020557011e4a8810e411c9054566787aaacfeb54ac78d73baeb9bc8302c8ce702af8ba803ea43b9099c19638d0df3137ea83758cda196e7d6d83fa06adeb9f7e1557e409a1af6142b32e471e28e12f7bcc60285d7de3dc0341427aa8972b534ced3a2cb8dfa0fb8083450ee3084e15781abaee74c7111576765dc285820cf3e58f1bd363ff80088a0c0d58dbce9f52f715f58c4b8a0cd1e30700c5b3c4f11f0cf2125c49e11d9c2e2b02a68497ab3a8abb2c016138ef14bb3da4251d60eb12d30c875451c3ae00f3c9b62d0f8a1e6105530e38cbebf461d81d742aeb89138149317ae2f4a4c0086a3055d9af9015e2f1a9e8c4b1e73dab950a8f8bc12cbc5938bc4bfc2fe02228b5299c92aca9296e3ab9331a6fd997911c8e1fbde833e0c206b68412413946b2b5893edc91a5996465deda835ae6e308e8be9d2fb1ff9c9abd483d247838e09f0d2ae4fb0d8ea6c0a27727974de60c5e17cb065890ee6e2a1b4ede9673a3d622c3dbdade0a6d3551cd5a23727a4edca7d7d376db2c88c34955d5a5c618d319eeee90111aa28db40a855008ba01a42cd4f649b231059bd285af9d186132b95c615bf0c93630734311ceba5778a0dd742b80c42a76474d467393250dff9450eef025e99c1ae39d87ad1dd2ad4c442cc9020096e887ae3c4672f9fbc94f02e4a604b8a780e945f5da059918a6cd7a257cb98789d558424e175e2f44e3c22eaa807f34d13291c6a81c82e60dc58df7eb4c6cadfc0756c7a04f2e092a1feb1199b500748c6c8f6108497489f07f5a05c15f389c7af18b5b782e416c1aac17d40c6360a2cad8f84206547acbd19a4d11d742bfae38856e37f9928252308a0f0203f7423cf12f0f41f1b9709bea6353d2380207e917ef4de8da4832457cb3703628d8b2361f0b7ca9aedb4d94eebec447a02774c2b68723aa955116c28653b2adc6f14c599fdba59ec7b4ed7d85e72122fa947cd6528d4b287a5788a7c96eb2b298e8ffe6697180a19c50dd2fc2a615f453334c2c492628a22d6c721fa00486960953bfd9015437803cee18f3f42ab203b3b4ba46800cae031c3b1819539e4d19444ef6f451ad6023201fab01e92a05050056dfa4918e9ca7d468de68823ff319e308ddbe60eca69a3c8d643294de2a11d5e19528994b9595cd24319899fde789b59bfeaf4de2a502a192f5267da02bdcaf7ac3c8e3b2afa215b68200441850ab8d811bc8987d80d82c333cfd86fda46090bbc41a42fbc7eabdb68478828bf3cdd1655205eb3f7da1d09da2aebc354699565f6931c9c99f4d3c6bba46dd49f3250db9f184d2c27b6db0a91296f7626393eb52652cfe049764b7506e4cafedce60deb96d5211ca924687f28404bcd0349b69108976a601b3163b62eb2c8f36d5f9b0db5a381be3d3fb8139853efa0dc72def5bb9eada7dda398619a32b99e9282a6b7ab8b08ac6b967a59eb7f017edccb26a5ac21ee63b11395d1793aafa3484da381e642739667e1092b2dcc5075e4087ad4b88f041f37c9920d08a215c3d0f5526266e93bf46a4f897151960d3fe264a979fa60d4204c06a0e1966ad8fe8da04353183d8b8259f5c5242fda3b2237ce7ed55f2974c79f18442fb9333ef4a5f69c39a21893e2d7e011dc2a90cd96d8432122a4cb920c65d838a023aad61f62c7999791b121fb744a3957f28463ed56a12fdf2a336bceb60e73f921aad8b33bdb7aa3c4e6d8aa3f5e1ec64ceff106138cc1be8478cad4f3c30b049b12f86126a047d9d2d79e41a3d5ba54a55591b8a05ae81f68697116c73996f0bf805379778fd7f2d3689efc42c147b56ccd6387bd0fabc6806637a13a2a8bdc565bc1afd8ec1e1e4827a22be110009b3103bd4b447836a54f26e544ba20d84dbd07620ebedc9c97f73f4276baee4e80c268b6e1f5e19f71e63323ad5744e86d5c9af01c96baa458b0ff61d4ff3134d094334b4df703cbd90340fa5e2469ea249b1397150b7dbc9f9d979dd64a4830fd5ad18c0ac03ae58535e3f4efc00a5fa95ac2430cd855f43beae3393298c2b46ef2d9e46b75fae7775f3f63da1e32f4628f25f1747c78f0bca45b19d4159d084c9105c25d3dd6f927f0c4a65a754ad438400757275459588d6a41cd94f7723128eb956a50a1cb87946927b99698ea20863de1f3175ebfff999619374cd964d17843f7a31afbbc8406fec49983d302378fc074af9452dbc058ad2d1abf7746a8937f8bb3cdae6c5fe71233e937d298df6d62bdc800b5c88a5d86b5e1a2a88e6d113dc4d312b26aff6c1fde3da6f722f6274a102ac5caa74edae961ceb4a49f03daf60cac6378d74044ec3524bd6fc7e959087c8ec139844e6284e56f41ff1bda6a77b1526d0e18024d96b6e8f3de68f9ff93c36db51e45ea485ee90244a7d6a7ad3752989cfbcb28d25a3bd9521138e0108a4554d54d6a61d4750e1f1fb74503b2c20be68a3886bfd42e0beeae393d1096f6f2e19e00594a04e21abd843e67200020cecc1839af070e78e2e9b3d0afcafeaf0e4e2a0bd65762c97952b02cd7d9b3964b26d7cb1b8c3046ffb4d2342257c6a6e676d9620932dfbfb3dbcf644ed8402e3be3c90bbd295e9113d1debd0b2dc91440c5f0dd6cb49823ee5f697c99e2c81d9cbb24c31567a21693c11870d50f1d6946497ba87ee001100c6f30db5cbedd760407cde4a1ac2686259f5c9c519da9dbea9e7a683f428af4ea89753742faf684aeffaf70955f1146ea571497f155b539043d9cfacf38e581759d139aa8cfc7fb873d82d9b9f944358adb4be7ac5c0bb1d4ee36b68b315c94cc5096e0a5a373a62bcd6a61331f3b7011bbd44e828c215712d658ba3ccbf871def135e94c82333a3e9b97eec95993f507bec91b6b2f5cf2048826295114b684607d9d0786080a446215cbd6137001e24709a118645e4230a61d72ac65aafe722c37c51d589bb0ab5ab48bcc1ce5504d27bd8a175c3a675e0149df3b1f1d97842495f0bf7526a77b216550f5d45e976882a1554c5edcc8d0886580dd804c47cbe08bf059273598d16e9e2dadfaf4c1d9eb79913f9979c0920a96f7582cd816ef2c68869039460a917d271ad84dd8e808da4c216d97f584384695eace4c7a0bf39a47c4724cff98543f45f3bda221b443446a450e7a86920802aedc5ac90b3676a7ed1509d2bf310ad28908d92cce290cce045c21768094397e56d93d029caf8b97bb159ba78c0b069059292d29fc31cdca11a9b013d1b48a6c5b6cad1a4042140d429682aaf4703af3ef84b0939fdf7d486160a375b3f58a54a567d26b86215d72842d77d61728001b3f18284044466d0632df087bd9f1504c74a209260988d10076897d4421c11446266f57dd96576038575d83a450c237eacb4273165d7672520979705c520729f7d878703b0a84536fcf2e9048e299d00fc0b1307b645769f27e9fceebdbc84643545caf38a7dc867c3043355676f691a9692a35968287390c6a447a76828617695ae1f3c17eb0b7accfb067924bb99d623f5ce4a5b063d5d6abe8b2450b996c9d1650e7257e7aa9c5cb9bdec6ac9f06d8f4c18abacd67cb1ff62ddb3413e04661da6e39d717df509a0bba233b2c394ed8f5bcd6117f22836a8e49f1efce5614091190bc8b0d031ada21a3c175531a769c160c2932aa47a1dc99ea13cf9001e217a2a053bc1865ff08153e10783ad00a9f292c07edb09046cb91514c3aad4774e2f14e8f431f3731947c5216f0801fa5d5d84824c7f8cb405043a80aecfc6b91b2789f4bb71d9b9963bd6c7bbdb2f8c3640c72f2056ac39a877eaf51659d69a844b26ca585490a0ac8a51be3370549bfbe6a167db746054871c559f1210bd654a47a0bbda2f5cfa2253c6b829aa0f7780c5c2527eeca2e2a9c058639ad2082254642ebcd4325e601c5c35380c94ff0f5e274e4a45f1fa559514964aaed41033d559a04c056783fadd65ffcc8981c38fdb7d991ee37ff638c816db4bd5c0784406e9b2f9e449be8c1067338224eec6348a6081e9a33584c8c79c9ed0b812620ade78e6230d0eadbc907a896efd0a09aaa5f2beadc6897566c86614e384a8c96b599f79ff4df9f7d77cb6fa9408d9eb26e8516c29dc908ba22e732d1d806f6e0b083d4d107679a52524f1fdb1f2983e44a826293964cb179ae61d54c2ec22822d5323363954f02dc2dbc3b44daa722da55e85c5dd1b863886762a7a2087dac88f6baa52a894465b4002f8efcea48293bd8e3fcadb64522cb5e102484af449a8d32b0c95ac3c268f73dee6ba8c229754837c4d0baf7d038026a232859b73bd733d7b67aa80a725a6409288a17bd1c015307e48eea1c447b52e8aa26e36012cabbc3eef9fa00f827c9c2e6e6b234d78f996116e8155b76356b88c7d6e5f195b445f629c60c206165037eaf03c9b3a47228b2cbe0d41d45edcfa55a944e13131a31b499e0c5e8020c90abbe0b4e04207f85c8907c0c579a9464c7d9e010d29da9a27d2435d2fc59deac694b5565c45bb6200c8c908f407437996061f7acc5d24c81bb6539840fe4e689058971cb50b04a52a0d65e80b3ddf5bffee850f673bafc3cdd031ac432ef9c31d13e39749f6a26a0aaf448e6d8e3c620468989309404e85368e22b47ba8448ecbbb3228b238d5bc77b8307a5485b0b6b9da6094c23d9aec38ddb1fae312a2e843b92c9ee265b85697e562de7e545aa67e284def56a9c76e5d1dfdc4ae7853cc059957a8f37a55b7ccbd271535ec32449a33cb8703e65c70d5d287a643318509632f2004a5a71512f8438d31b4eb7001a299d34ab553a83d1a77c6b2769be38af286a32b1798e8a05888d0e1b04c50ef6d095d12bdd3da221d5086e65dc500c766ffd3051e4a4a4f6b347b15ef2e2bb3c007ef5bd14c79ea3aa362236b2630d2c26af87d2efb071fb4c6a9064deb3911e0741df341d90f57b49c2b93baec7b9c688ca5175d00108758f42175ddae3b3878f69c247e7c8684cea4dc119954ceded9bc43450c799cc91607cc7e96a4ac71a74bf57be88a85d7ece3d06b74a02fef39c0a98d390a758e9ae637222c4b4cd82199341666ba838d5bb58293e49310f178b6b47d7435e7ef6b9b1ed1a2be542872447dfb1a90b23ae4aa2798e2248fb784756258ec985602d5ca1e56ade5cc47473714c1001887d0f3d320eddde7d2d7558432b96697bc7bceefa078fea9afc27fb4fe0c38ca98c1771df25950624ea20493eeaf62edcb94d4187ae3fd6f9638b237485c7a0bd84709d8569ee635817c34c19b52060dc6527889c239102233d4eb5e94f58523941af67c9c9b0aee76828d2b2e28ba02f0cea5386d8259827a38f808dd4a53a4b6396623158bfb41cd9f63ed62104494a9e9e6e98f8cf8d4aea8e162475b95f928273a347f916934cec84e0894cc09873c274fef8b62d135cfceaf9d9058d2b76a8ece719a95666ac0366fdd4282599bdf01551cdd15a2ae922bfba7dd9131459bb6644d639de7a34ad8fbad79f3978a7b53d3014fa8a798e3800008bb837b42103824fcc7b3e783717a8d24ea77c58a2752895f002bfbd44882e6b925c651c3d4c4208f31209eafc7dcb1080a2ee4ff6a63d45ded13b0d294f447148dc60c4f16befb1e0b79976894a388b5cbbb521c933cc312194d8af39967cefeb4d8cb62654feb227df6d714dc2333941b269234230c79f601f44bf1b3a4b567ead4d5365579d9d725fbd2d842ec759d5692ff5d333cb67afc72b6d80ff4fefb92fce855270508b23f6334ded5f2d2441be3ee53cd79e6115d4d8eb730adcd4bbdd1d131d9744cc61b1d4f0b392d9209eec481383478aef5dbf95dc4ecded6ab85a443194536c010add3a10e26229dc4abaa43f7d27b085f9f9ce6ea0cc1a3551d21c4975ba31103969b47bb62d307737c99a57b0e396aab355a41e1a24de94d8dadda8276c056a5fabd13f76038fe3091b8ec013bf71bad9b2791dbcd9bad5fb11a7573bbb60b23aa7823e2cea8e47884a0d8f4e395693aa044be4493e4cd5cd61a75e461f4152b5611f16074f981fae14948b0d9bfa874e3087e21fef0417081ff1defa223b9aea4a027325a1b4b0158b1d3773aad0dc4cbbb2252361c89614c15b00259bb581db6188690b5de24214798c2c30ec4911e21ccca84f352b07a89c2ecd9cecb9598daeeb9c41308ca1e89d57b037974c85c6567ca0d708252d72fc9da060ee8b7e8a49c1f1b5e8b92b090341213a6ba465223ac6961d0cf21cb41d2b743af651f8cfa5faf6fd550840632bba6e3b71ca28ba95ec2829f877497e532e14eb7dabb361e7291856865c8d4cd90a9f4556c2b2c0936885891406a7820a04124350d2323cd44c46a56c85f398aa1e83e0fea7db2cdac07a638af28a7cd0c341ad0490567839a3e68331765cc386f01f8b5f0d0b43e206d059edba60d4363c3ef0acbca796e6c700ab2005050f583b8fde07849af71b59578ffbf187f84406c594a725062a45e6f98b8959fc9e7b71028e818c8dd2c107cce585f665f8a554982e02b26602245cb2f227f339c235c7faf2d2a18141159f89a65c10d147795601fd0733c42024a31604070d15d0d0e4b7de311c554ce683caf06ae904b4d96641e7b2f6776a308c64b6fec6d85e701fcb8ffde76bd8fc8512a097ab9834679d6794131c274569c64df0ec2a5f1bf014d45bca4b07af1efa42256c3cac359c6f887b64edad0c5b5846b402f632dca1ef2e0d69a9a6f0ed722c34073b07c904be15f2f3802274cc0cfb13805cfa6e64cc92a5fd264ead69ba709c17a9257183e1e1cb98877f0944944ad9970cb9987292fa9ce8fa9b7f732a03b5ca038da558a8603167291c72410fa3d7b2ad11445f5a10d17355159f640671768800d8f13ebd34d7038a8b9e3c9cce12c737ba7b5c8b5886769665921c98fb50c98e2ba266b856b08c591b5332d1abcb6ae12e8044f01a7cb36e287121e333ae064d1962d55860352cdf0d124b00bf80ff6d111c871fe42416155008a1a11174ab6364496283e2f838879c229458cb3043ec8fff6a468816c7289839621d97acbb321fa3860502d79e27ad0876d6a3abee6f173b164cd3e9f072c3cae4046204bb851bc851b8dda78dbb6cf5cda4b8d192648cdebd66cffea0a26c3676411ae13d41d0b56def48e167286f24834634c7ce0ba15e869622e5695527a019907ba19afe4c808304a03ef66d64eabe4163115a33a906b68fc0066bf3ec42052b79565edb7b5f513c47f6ea38545c068b4d2830925bdbd70d0331da7ea16f51cb1e4b86a857824b4a6ef8e6b455bec5e0d84a6c50e27494c6072bca225ea6d8243a4f2b5acd034fee85574bde8eb5ef7be1fb1e4ed672304c438a8a2fd4054e3b5d0de9b8af7f381dbee27394b3ad3def4bfc07894d850c197367535c010d09d80de04acdb459e45a76da3d1ed684295a9be8c89d2d199dc0789a99785da1e66fe1f3bc7f58ffd00153531f53147de0067dbe6cee0f47aae62d6c4c671725f9222d2cc8454ee9e6c68ba6b0ee256acf74abb2746354abb6b85d1600ae93265d9218a3031138a51b1aebf5c31cdebba36047f5d7315cedcbda4d1d4afc5be8343fe502948517bfd4186c2c12637169f2fa6d962bfd2e0aeecda0586ee8b624760e4437062d1faf7b49c442a6e0b522cfa057283c115d2f1aa364476cf46c0b07e05fbe4f05028aa48e118e49734aacbd72b6b056a83f67f3456ab33f660e2aa24a469e560c1e6ea0ee020c68eb891de9fc2a0fc51947081c114c649957c98f1a9645239de63308750552754abc23803404e1d6463a1a6d454a261b4328f2d65ca4ea049b51a210add76208d44feae12761c7b2164c0d4284dd54c0d813725988ec5437ebb143412b51247b07c2ac16789bb3f526bb3ab4721215b92a00c32bf322127c4a8ff17a171ea5903b23be842f33c6aa4280dd4927022273850e3373a76c93b0d9a2f72893202f3bc93e3c563a0b2028aa311a0a3ccaa2efa86b03ffd9c1a9a95657819b2779205e221b8b36206659c7d3c65593d05cbf33c7253a286450cc34d75eb9b5c11564c241b49ff3685e7b62e6d5546659db632763f3ae1d4652fd76fa67b698a7aedd8af54516a5363d74311e28f031cbd7939358606e6686f115231d600d9fbb8771470862553f933fed776c9613ca0dcf9ad112b5d1b02964da538eb5738fda07ad2a7a60032f5e7c7ee02197667059ca3bac70fa2997c20e8bc02f8663fe13db5ed2376fe4c68a06d27bc4fb57d66549c8534a2cda5aedc5752166dc6b18666da0d99a0d579596b0b96b433919b5c19b58473260f57b28e8bdeae83f4170b59c5af10ce27a712347906796216d237d992bc19f0ac7df28bb861341a602af9dbc4ceb3bd00282e4ecab441564a317488e0faec8c59250cf84984f585436026680ebf542af031518a0376774f04f78412095bba8ccde096d4b0f9dce37c69c190787e41dcdf31d958081fa7eba50097617a65450980ab51aad28f344168ddf45723c3aadb5ba204a583d49c2aaa612884b49fe1022a11c874ed2ca6ec9e7ef0dd2161499d537c37566254ac787195d29184c988314d87b5bb93b9aaf909d636291693bef405536833b6785090c882b06597250b5220387a5d511e6163a72041dc7a747be010ac72f7de7f9754b68bebc4cc2e09635d71d2189d97af778b265bb62507f2e3e3c3f5567a434ac3edab697b396be9bf4a25b2713039e2a78fc660951c972d806221f4e736eb1edb35dbd21e0e45c51d2e51b5a7048ba87ef4817feb432564eb845cc22ee0a171c97c27386b6df13c2c9de965ab41e080cbba4ba5f55634483fd7ec1d3dd58d8619254e4fab0d6d6c8dc0a5445bad9662600b8da584031a8da72a00b82b931a5eb4a888cb2fcda0367a7423935f2f554d9269ebf4ec94d9209162c7c440a3697b947175219aa1c87219528e7513d478b50721be8580c26a3e14cf4cb8214c5f179828a465c1460a26f449212839ff4d258081e8000b66ebabace1f352b42f451541d3cc500889e33d85cdcb991a136510240df91e6c106d5016bf23e624ce6543da6a32feacb3e792b3a1a1d1bd615421e249ceb9d7de7cb26382d47afa4715e626a62ff04eda9475e3427ee130acc6df1d105958837fd992964e9d54ed41ea82762bbd521c0daf91b096b0c3418a582305be12d6a6dff9a735c93168e6276287be9e832dd4e1905d080c9af456aa82cad55513e79de18711407ae9617c2339ebc17d0eecb89d2fdb2f4d32dea7278e42e5d498817470d3ba2dea5a3e0fa2943cadb42c5e36f6706e2480e4dc7a5953e1710d394b2587060b86791aa48943f2c3c215cd41df8c6d71136e2150b11cc24322be78aa8e9ee184d5f31f39ed5768fd46af3ac00d4327d8f6499975f96d99bca4fc8ffe523c638997352c4f7f946e6cfd114447d44dd2f6710282c9fa8025267a99741e9b633695c49e02794532ce95ca19152a3988d1ef89bff1029e2f5902c41c7684550181949c730fb52a1078280ca91bdc3bd8f7b78c0177c2623924156ea2033e85740d0bac541d8fca85a80a3f061732c49482bcdf0f6c2447b32ce0eeb064fab0872826380f0eaa83abddd39668346f37c9d593187ea7c5d6f2868ee0190356dcfc752da0d2c6ac34a7fd45a61c2f0a047cae429a583aa88e935b5d5280aa5f71e18dedb458babbb524a5f81db9566df8c66a56d46ae0fe1eb65453a8f6508816a5dbb772846cedec00236c740e49b516aa36749a628796fe17a0cd315535f45962f5ad5a519c45556f5ce20966e7f7559c8ed2498f6c197164cf1b6c305b5ca35b3575c8c473ff53ff17f612cb2e465f65742eb7aa8a4cf11198b7d4710b4e2c637abe8dd3638f29a49f1555873b459ad3f4112611f0bceff3c9f16c57710df7fe524d65232b3cb46c5fd7c737fdf9a20360df8b04033ee28d6e31c328fc0fa3db03424face6d7f8f80a1b74166b04d152a6a4383416402935a4f235cd89a914361b99b2589906f29bb63362da855dd8fee7c38ad4dc8987a9803653b121a4a761f0e3771457ef382310cbad88d4b6644db34e9e5b6589ea01b4732e48781ce09c8f294af0bb257fe6197c11155b21ac0d82699e1d81b3d9172ca4434b1a474396c5143c62c296ad8d96486481ded82f94946b8ba852ac1733cbeb0cefcfb9d92d4272f3e46aee539cb008fd767d221bf9e253a1dac0136c3f7246045fd05544495bcb104663355ac1b19a155aa595c1a317905a0914a22785c0477ef74a102f0e2014727844d652adc97d804bd7350a73f9fa8c5b9a9e840bb70f11273e43fb87f757ed78750402b2f3250042c1cd4e7199c7525788ef05a3ef61394b18e78eb3fbd336e782549926108028a086f972a53c90f44e307baf67a306c2b631da93834435b706d8296b7461b56321067be72ac3bdac6eb848e94862e84ff72c0f922ad602e25c0bb426595b619ec73666cf07662509a02ef929f462fe1e351fc24a220d73ab59b9e645bc564ed71ca1b5035161149fd832d0360b841092762ff4fb1ed28f9829f1198c9808185e8036878f1238c24259296acc305f5be219160caff5e4bb1e24db4b4b66a6a4506f986bee90094c25a2e75d40b34a1d8a101c2c88552a6742c282d7a44b8f18d4550c25b04630da3a74c1952614962bc6a9e0c27cea3e9536f7fa2bbf0810812d23a31bf86c40d8270784541501592b0d63e076d416f65f3c156888c931b08fbb9e4ddbb7860a4ecbfe6c756b0c8211c16dd427e62bcc580c6d1c7b958c85db4db2a655bb1a45dbdc49815176ef41b82af8f549b3f71b4e51ebacbfb86adf23e38536268b642a3c46774b100ac09907cf1fa7673c3ed224213779067fd8324d6daaf014940f76590ec3ef68101782f1631d6cd1487994661da3da356c9538f0e7c7d5459fcad1ad8e5aa4105559fed188c19b2177a26c6898f8cc72ea47806acb4292f63625a5d34a449c1d40bd9820913a1c2977ad5292653743027e46109b625fb3f4d507b681d33ee0c25a864626769b8f9510e41141cb9363d48802b9fd6feed7ff64e33326aa028a8b71c0eff94c59eb9fbf6c61d38deab60559df043017ff86c43945fe2a495429d58be1d541cf43d60536241ecc9be40e1f26a742b316b494c1d0aa15a7770641591caccc50800b8e2a5ec652e606e913e4e43af0d76b844d22e27420e014b1d62a862ecab9b90e0b706ab7a34dab71704d170f91cfc617dd18a9c30930893f85e45d7a637ce17e54ef0b8d98c7d9b3cb218c6de9435cb7abff70a9e41a9ceb7a6dbfdeaf8dc7a8113cd1efb729c9c1b1e430d9c30eb56e59d3e2e5a0821fb9cf154a5632a197121043d01e30a299b4efe0207ca1cebfede03460ba13e1a934e739b6cf486598d2cab7cfa237bc3774b335c30cc07109ff0eb4b3ba70c4c1278fbf01e2598e29abc6db4744ef93deae85c51ea904603410351234c330492092b89e08f13dba4602c3677bebe6db0c15bcafa746face521c435c27406d48260e01b33d28a20ce48b3eaa5f123c01abccca408c0637c006e0cf1b6c127a0c898b8ce21a4d860c04b95ef1ddf3340dd127f9a656c9caa3fb91c053cf47ed055ba6de951d6cc5b7ae42a3b148bd542cfe802dc98b8eddd3702299f5806864b3f5ee303a9e15a555bdcab36c8172b4f34bb599f4cb5230d397415b9c71049c09d532843536296e474dd8428e065c7f3181a03e626846a91672c2fd233714ff97fdc05111eb576c0abc8b72af1cbcdcd6d76ff037c01dee2f6a6af432d54af9352d015eb00ebf25305a1e3ac7a21cf1c3b9cf0d96453a99e58d2558cc82d9717b5000006c45d25360626068cad54886fa55df476d9d0411ff8f4d4ef3f4565a3176307a38898f6f1d47350f3b970fbad8361074abb528bda1610e7218895cdda03129823632ba3b11a87c30ce277afea8e2ca090b4ae364ebf28054682bf5d5a58ae4d74e506f20dd6c376026974c1457516f8d8acb9afdb9b160aa79043cdd818b308740cf941ea2076cb83cfc648f956a4fe8d5f693d813aaeb180806a3310e01cc7558de2b4e30b2714440298a02626d438c7660c16fc6ffc9313f04b68b537bc9302690d18d4693f1330a5ba9d13f94f164e399dbb04a7458e28d4ba11695c9aca4f02d10cc35498f966cc9ce02bd000d04faac5dcb20acc46988986cf813ce8c52da7190571cda26c8544ec902931d81505faae336fcb34240421f93791f2e9246c7322e54e692e064086bd004e60a3e3d2c8d8010eacf30c51151eca19d47f18ac458cf5c8b6d81f746021a407df87af8e1f6d5f60625043904beffb07082b1b6b7b41c1c83aac98a280eb9fef7182910674985313f4414afc0803d73a8f54966b848843532615ab60877427a694eb053f964aad0e924f2045faa7154b843023ae0a36a70cd6222fb28e9b54d906b1b1ea53df8520a70ef9f61d0b198cd12b7337c3f2087630dc2e6fe2a15912b6680964b88c83d268fd5a51d6e929df1c53196a53dde640a47d4269c253676595adfc483cca5d0787f8a0e987559051356310c008d7f4b1baed715cbf0aa95d3627f85e82f66d065b72463d53d7e509fc43f9f207831f0a6d41bc0d195109e7ad200f7c7a26bdeef6a710df0842a9d0b80193b34d4d5b89690b276c5e2d86c4d086e2006056df5066f8e1497b3a530f15def5c10b1042b433c674fd2e43e4ce684063fc7a32ba07738c9db778c905df16f01c156f390fcb40c26cad9964a89924b2a456acb9b0c2da462b91e9d65c185cdea1ab9264efccd2879b8250b4c6adc2e77f31339c6f2fb0e61da21632e0aa74d33940d9d1fddcd4a02e7ce37e9ca39967c027c8f4b7c8073c1e211c5a6156249df35dffefa37ce882f513ac24cfa2bd720a3d95d37b00e88c56132aa6b018d1c1b3fd90a97c51bc7511320f0366c07f1729a7c8ab4248abe26a816d7a4412ec0229f16fba9b844c5414eec320c8e699be6dab3841890e6dc5f117daa8358c13939d9260738f1adca14a949a7283b4702fd4556ba1c9b5683430e44aaf6e5a27ef9da649e7e47012aae3e9df15e2e4ef8b5c92a29ca651fd1cb8527418fbdac7a7e60baa9d1b335157bf2d7086d7281613fde8cb930bd84a39d299ba417ca5aa17556ecae1bd7d4233b46ecc809cd4d1fef5a13799c99d92ad10d29dcc275e01598c41d99e6f18494f64089bb47ac633e49951bb2a134eeb7bf4b836705847eca816cdfebd17df970627147fc9f1b8aa4ca4c3de63fdcab046896b00484d8d90da28f3ead6f41db1565f28aa090073916964826e4c14f4892f834b913623827f5506e2b5754eac22713463d9ea4e294fb35215deec9a558ed1582d652d78468b706fb45b2016dae13d4745c2ead4218126963d5d91ffbe5dd5645b03f900f17c5dac35c56460053b162c3730091878d7c6d93afe8c8f71d7c049b38ede3e0b8c1d6d1553be6ceef2504f708de5e413523fdd1193fb6e927ce963a1d0e5c7da4d2f66a40849dd0f0bdf28c14f624b4a5bdeffa13c061f5040ce68aedcac909f6988ec0d569287197d6f356bae5f995c9a590c8b0c7d3d601126d4cacd82f4b9dc879a9178836eb068840dab917de0e328644e7d1a0b1d8383476b160c7ae3fd7cf7014ff0582ded530b3af42b2833717a9abddab5708703f67a79ddf93bd692edfacccc68bb2ef53c307ee1ac044252ab5b52ac1731c4d1b481c56cb105a31a32515ac768fefd8447e4c7f5e65f29aa0028d76c3f260a94fc7cb1f7a5ca80fa59ad9847c6e6caf69c30e08324a29302a0fc85144d9fd2e5da59e17b475a3091079fac123197ee73d03ce002d007fe013246639a133649ffa8a488633562a97846b566d4dfbc66073becd3b9fa473ecae47010606ea4751b3aea7de1a92bb343db954c5f52d8841d2b23907d60a521af06074b2c2fe6ca82bfd9ccff40478ecc41cb315a48332f6a722cb763fb80b0636604c9d1ad5d41e49cd6e67a16ef34983cca8894b7b8b1ac9a060a4ea5a7aa9667f2b297d8fa4eae20ee7e314279db572a1a16c30d3f9c7ba38a82ed473c7d6012929c64b0a4e1582534ffbda22965509c2462a02005753941c09236e67edafe74796969e692b381b83bc6e1f27f7cd68e8089b34afbec00459e7419ba4c79fc0cef78a03260b9e10d2d2484bf8822911cf08466d41b4e5a3833d0a9402369c8e2f3307020e224fe3a8a0dd16d57e0ad755b1ae5aae58b78ad110324a6b35154138b094ae7291f71d3afff93ae1f7de2a7a29da66687874db6330945aea8f40aead411b57a3572992ea484a89763c0875caf8933fb31b6a14ce48cb4712b976e1c88c938bd0e42ba6e94472e4eae4df7a730157d5e6deb090b446d77539baf4c92d205d9fc68bb76d545d603e189215480e67ae9ba382415b7126e8d0cfbc9f1b3e2d5aee36387a4165b32523b39152ad32e10bf8afc7c196cec3e73ef7706fbc1f97247f2dae73a8bafeed13c0c6a0666594fbe4a6d211cfbbbef424bdc424c4b36fc52afbf9d34c9e5bb750508ec29ef985a11bf48b061d785992f5118630b2054b0019529b3dbe957f801309019a33c8181d0dd55ba428f54353b2b24e4be0fa9c9db99513a1c6db423527794cd30a64d25639bdb7ae60700720c148f3c7ebe8ec4cc0be2ae7e1bc2f8d8c6586e654fc26c5bc977f8413a529f19d7a19817d3e4e3a220a41a3c2519d869abaa7f82b1e0c40d1eef975d1709e897a3869c40368d5234019878d2bee537542a60eb9a11e88616bdbd986f0b58efcac1759d0f528637e324397c99f4ec6ba26b43bb6b09e1fba9d64bc6065beca5b3693a3c31e7b100ef9af739b84e2e6f51e70af2924481b0df206083b1f8bacc5bc4a560ac4eb638c651153d545ccad255764b64830e972dd7f2e9242c3ffeb1175b000958bdd4c7b0bbae08a8e6952583c7ad673afdadf1c77be9c1625f5dc2489399afab0fd1fc97ebfc3f74866f3043641e01a2cc9ceaa5426d37e65fd0b4ebea5ef9c302b03faf0501af372801c0405f7005079d0156272cd19853e71c287493bdfe9737cfeb3d23a875d0c72f7d8a45b267daeb5dc44037deb529acda11c81335dea7d277007792af8a666ffaddc5d98c8042b587253df05dcf6caebf3dcac1a9d0df5ec31a0dc659d3acc2787d486924eb338d13879e12cdc35457678558c5f2d9802108c71ee610c58942469c6ecef5592c0a4519cc4f4c5cc022eb2f352beb9cc90f13a6d10db8c5c9c71bfa49dd6e6b22297b99170d03b903bbb0135c13d785a620668d622302b8c7efbf685de325356e1ae4c6ea0e5cf592ad304e67cf8c6b2abc93384f8e2b58f15f8ae355836a6716e0f30a4b162b3a99cd3fa5fb9bf5e49880544406e199545e5da4d358c9a87ec8270caa0a844b87430937c24dbb0a36c60aa4bbaff4df9f53f3f44ef7ff10183c995f9958ae4a5b0cbceff733f2c456a084fffb16390bd52ef068948f3c47ad17d59e6781949d57162f1c32e992caf479f61dfba1848d4e86ff65f14ba3f06ecaa76eeea37533534f09125109d45a66870d006dc3c5e8e1a54ad585eaabec766da11f0920ffd4735e118e5eb110e75c66e54c0059479b2913d3be114a59850d11a55192a87f4541541befeca67fa967548d8d23156826deceaa8f6697e5802a0ee246dd8b54bceb2e6a0c1d57808b6c109b0f146d9bc6c19a67dce93208c543c904beae2c06b07b6b7078624eb2d4ce1e30c03aa8dc9736dd21ba446e9f531b22e2067310144dbdf90636a57d659453120c7ab25a7ed73c20830055ccca161dfff29c8a0a14b6e866baa6c294dc87f2dd012843a9266de93a97f610944f0d35dca5e8492dfef46d1c26ad5df2be20312663ccabc55f4aa58b5ac295d9a04d1a6474dd1ca042d1f1acd8d591df3eb3c59a2c67d460511d94e076649838e51a2067a6fff202653c10ec719926b11d04487b0d14a05ee0e70e9e085ef4011f0c26a75964730c2f9780ec4c186860b137024579ce9a4fe64cac6e19a9e0098fea47e59df9db30a32fb341190d1261ae7c583bc93cfedd9490143d31509e12ced3a4a16ff15c2d75fb5c6dfe229f25692aabca383058e05716059a56fc5d13d596f615b3488dbe125b5e9a14be813c88e48a4ebc63ccc4a0a2d394c5128f8e039154f41bf9cc9cb978a28569d66c6d003db90ced32ef69672887b149b940f18f7be530a16fe4a3ccf3754875b639fb3c6b330088fe1187401041a74a40f41a6de20dd9c74360ed38e7b12050356451ad90a15841d05a50ebbfc49d80152e53999c04085bec6e2c3136857b5431614cd255230042c212e3f80ddbadc1cb9c8f1f3a3551785449fee7457c7c9a4f3e848aa57b49cca1c6e20fb54b4d1799781f1f1d34052d2b45baece3f484189fa188d8cd7b4fb8a5677fb96f619f3c95842e796726fed859ebbebf53eb819639494f812583fc19e457159d418ede69a7402a7d422d1b4ae453c0e3863617df44259d1598cb86c258fd34fdac637f1e6471dcfc942d51f97fca91bdfb86dfb9b2a8f6cf7d6236177735b7db1ef92916fd0b9aa23a30e397beebd86c371faf7f2e316e52eba357b157d31ae4483ecadc97a56d0b43ad9a0c6c0a1a51a34fa84ae2fa43a6b2ce3a295292760218404c0125a9c42e2fa9c65859e7124af15f11030e331456f2860b2d6679ada4943a2b1400b31e88f9f7053579409f45487054807e9bee7fc62732d0e7e42ef96507f44c58ca53523c0724d5b11a6ae261ae419249609ea5eea9dfa9d6a94c1685581dc6a0db9245594c19132bd8bf52101edd132d97ac820a3d3b9050245efc9e9c220a666e483cd74bea94979c97b671c77c795c20db5e71e63ed040bb2a3e14cf6d1668c95aa39cfb91adb216a801ab0e94a51c43eab071aa477ef0e163c1b159bd7d02a870023e93da6945f3daeb50e96f6d406d366ba0cc93a49b294aa5da0e275ce3c1ef7031b0ad1c2c8f99e90b89fdd149b2a5982ee5c4df2e2469d390ed13b2fbd2e546df3522e81fbe68d7c6892698392fa8b12cbabd6b7956d4aa59c87f587263e284ec84c6539465d629d98c95629c7649d2339587486a5acb0e7f161108b420f614c123534572c2007ccacf26a864ef1cb21bcde9367555d4096ee6649aa9ec599709fa130d75dc9e8b5d795d10e896752e721d2b78c8274e405ea444c20b06d4ad264e71269fdda838a33fe226b1904efd3acdb07d2008b55930cd151bdf88be52a1b1589aee1c30abf74c5a44cb11d629e35f4ee6c54c8ce159e88f7981c437bd64a0d11e7c9c8f98166a9c9c697f4247a7740a10cd1285152acc866e80f176d0534aaff25cb59d8fdb0907717d2631acfc9494b4dc4db9e91f0af92f023de746917f373bda8bac180b6274310fe5f90a63077423d7ad6c16c64e08b4b578c3a32513e80ff5873829d3596073a30ae412139e5d8daf225391fe15c2fd4d0d0c2cf6200101fb587ae0861dd0eca5b7150fa32528a24dc1e26a33df2b9bbaa7fc62d06ff087b521c959fa038beb1413fcd966b719e72dc5a8a80924d51970f732581aa112568ec2c5ee94c4543ee56a8506b2825b782b6a4e937c32db6dba96b6200c08b4f983f1aa36ebacbf58fda1b520bead9a5c6277156ab11812caabad848826ee3b647050691c5645b1d291934884132b0bec74f016ead292bb9a4cf9fc0ca336387ff6ddd2ae5b35b1952241a785fbfcf2ea646954532872aac9af027d9b2d570d2bc80594ecdcdfd15a43044fd8794b1c1e6e5c5d80c6f6265eaeb10ad45cc4065d6f8d0af7b37ecdabf0889cc27006d4a27df38b0477ef97a4a3248b45e52cc6e0c999063f654b27c9ec62418c0bd4b5399194a168ad99f86de0ed1a5867a4c16dcc1bc83b313013f59e04b43ffe2a757823ab5a4677e755a25b9d8ca1e58cd0572f78e21dc0a1b7334e7c25224a19442274ef21508686b02bd25d31840f128eb4b6c2dd88a85b9cc3934d2d86327249464e7eb2024591052dd2f9303a4f395d147b2b18880156153b7fe649f28bc9c7961a0243883c90fd60323a465ab4be630aa802c8a1d1c6422b29e449889b56989dd239ca28e1c4e87951c8b75e784a9687c837498a008572662af95f5c84e6fe5b8b2326a845b8add1aa960602484b80592a5778c92c945c838448ea50295ccd880a44ff61519700ab80da6498f9031e5fc28a5727596b522f2420cbe2e6e156880c0de0048d3e8d611ea28e92953f09cac450543caf303caed13fa658240c1c1d35ffba64fde48e14397490f8bf8a880cb094ae41312f28d1e773d02ddae1593d341aef0119e6f25f941a6a544211eb241e21a3fb0f7d25bc957cebe612aaed32402a01f8a636221af0d4025808250cea6c2806f976a3d7577fb2ccb76fb1702f6bf4bf8e093e9f0176e3cae8b43b5df6d38b6c62936e67a56e8971b822099591fa3cc10007a2e2628b21292fb4ec495e6c11230ddd0621eb44400fa5c6231f3e5620ec835c525bee2257f1127ee9ba853fa092e5a2cb05fb8acc211131b0bdc9eb5678a29c89fba8d2e8959f5bb50f41e4e733c53a01f152849a52e31c788553c3504cda923736c3efb669b62618933316c1e86bac97e0564e64beafe2cd055aa3dea525b4b67d1cb5748cadeac2c53fce27ebea28a2be6a23f90e69b7ad4f39438739622b6a3f3aa3d83b427c6ce66c08b0650c62bfde4c5c3f74c59404f2e6404da4bae784749e93490160a40de9278832ca39f27aab19088a76a2c2b7655067575d17416310dbe004165f5ce0e7a2faa0a72e41902cf531d5d1feb972baa889b612f2ad092fdced59d90ef604c33eeeb32e40a20105966384f6eeff885063fba2bfa67bd77207f877755efd1c4db965e652405b86b470964f1e8937b54f1c6e9e8c53591cf692e36c3fc9408ef9fb4dc47543f83c7c3ad1fe48e6163d9275cbb778f923126c73f5910b59545d8eadc5bd28e1a58f4343c332817931b36478dcb4021eadb89bbe6311eb3303434a19d581b93da35df7c903ceb7ce6e979f56e292d3a41a394589efba0ea3316184b64444dc8bc04bbca459aaf024c641579cb0a30bd7e3dab494b55456720945b6a8c2b1aa2a09ee18c90def22d3aaf416b934712bcd97fefd6cb92bba28337c57aa273976cbc5c3b31caebf06e7ffc2cd947d2a123637bc21a9de560e51fe51eab7bf9fe1c5c6732e260d310cfe520562b7e4520b68cc5c61f7a2fba55415bc82cab389dd248d8c5c1cf7ff03661024cffc5ee9b4c5fd0f9b7bb563dd4856b0c919d8c7547970a67c22472123fbdcada128e2a1af2f3912aaec8c8a6dc03a52c6e9659ac61ad17c6fa75cd370d4473686b0d72f5822bff633ce03673bdd05b1f9eb19177ade3395a04817cc646fdd107220be2f26c9314b9403fe373000c3dd6206ce7d04d35886e4ab559af42b75d2e99cc86f2731229cf7094ddc5b436935515fadb8af3163c1fd96472baaa115884349b93f1c0ccdb0a2d7fbf4f61054e0fb6827e3506228e3237f01c313f4f4e72a87a4a6f72655d014c51a4ab79bdf007260bfd8beb1ae91b43d03f797f038522cb6ac2ec714f5f05e64d1f773cd8a8e69a2c2d5acbbcbe35a0a186a8649a96ccd4e2c2d1cae724f29b730db656371d24567be15013a6f3257d38cc607a5e0f31df18d4c549eab6cdd799cc24a384a348e90088c6919d0a81a53a59430cd1cdd3fb8c9d763ad1760eee909461266449d2e3b14c32eb59d31632bed64defc3a64545ee688c7c270e4a4535f70b10ed268b408849a071491133b2101530fe31afef61088e002071060559dee02e47e3761357b1b0d0b584f6c4a45281649814d6642ccd7a8007979329342f49c62d90e36fa467b44cf9d1159e2c53da124952ed0de00580d6aaa7d9e37dc3215eb1e76c8b43a39256897514ac6f82f53e9bee284b01b72661bca2ff71d6e4bd17edf783283f4a8fcb89fe2762d58483df0d61e91e933b0bdc73d6f094cbef971f4e25eb99217a5eda25953a884439ffd3c2b1d88dadefdd58871d107a60c9bb2dbd03caa00f722bf53832f4fabdc1ad8664edfedf8036fed3c77d7561ef47cc7016fe1762b6896f4a74b5a4c46f6acf1d084d8a08a5427ee1b0c8bf39f2ef7881e590c7a3b06c890c48370e5b3f30d8666af7383275530c079ca3dccfe68a6a3ec13f51584b980ac00c668030a151142d25c81e04275e2ba75d93d2441c7ba84640151debef5b4fb67ed00154533ae9671500d5499f80af63e9ce77567702e1249b27ae99eae6e8ee9e5925de13a7bce4c44fc43e7f428221c00019634c9db5ad6e301a4a47e1dba512f06b0b201f6fe9a05083b285f19de07548445dc3d1f7d8e0e5862cd71a71abfa8bb423a6a8b918b081901dd83d03f23f796a95a64a91444f58bd5a22da01a291a346b3555a638dc06bfe39b183afafcadf5fc848bf70af631016f79d236fd84a458abd2a58ac6a5ab63abc73b6d09b5e9a71982447c5e2d8dce88bc913c2d47d940ebd86af95e1c90bd1e5283c5acc6292d2918f64c664ee403d0513fd6beed3544ec5289d802be6f894588eb76f4f1b6a46689edc2794df07305014d42d5b97ee827ccc13b41ee9ce8422ba59136e5460c57cbfdbb7516f9a3b75ebc555caa5a3f8bdb368a15bfb40e822994a5fb5dcd412e366c00f45c4aa59dde98418de7dfe5beec40223f7fe9bd452b2b40e0c19a44c5b6e0449c5522e35fea9186110578ef6c192d67c63730fe6d4ee1260b69d2c23853648fb1af0b4936db902a980b8e2ff93d43b2a447b6202c80451c84a7527169af373fe16287b17561aa2449342f51dbb0525390aaaf26ba57773ccc85b798b439df2cb78648ac0489cf2ec4a3b348a4aaab833aa6fa28e1d2a3e55fc85b1a602b03b7588df427879fc2111d43d6ba11b859681b17aca6a0fdb72fefab03bbf81fe07783f624455c8a28fa046d5937d0f2a6dd0ffd920ac193aee0497385902a0c69da77a7ba893ec65790773bebbdde57e446e91ee7c88a292e0f521dd1f7d8ce339259f62445150ecd5b45e91a720d6445270947396cee6836605a2ab86d5053b4438574d37013d13450025c2cf03c9d72f65a908228afd3a14fadee9c19ccb02efcc5e11f2fd80f1ce7431f773c9cf6e192807ba253bc3bb20f11f71427f4c2712ca99622d1bcfff0fd1f6c7de89a30d7826b7e9e2787e7cfe35ff1216bb943663613e01781be085212ec11edbb1f75a01326d1c1425340e0011d6669a1f315bb1600202047b5495095533b6b47138318117f04406aa2f99fa3402e7e78511523392aaf0037f66a0fa3e40825d15d088d0a9d5f8bacdc991804cad664cc01d38d214499e1b5d92d444ddc14bbfd3f51f93888b3757bfbb9c03da16d5267c3d5784f4c189c283b057884c9be600ba08293786cdb10d221c485fb54baea2ee27802fa2b1ae41b8e87d9cf94af689937b69cd0b2faf4fd2a56e417e1acb7e8ca2858e0ef0a3fb900e630dee6e36b55e5d177f4dcfc0e2361b83fcbc369a3cfabc20c2c1b0247188e366b20c6a49260f2b5e2dfb5b0fac7565d55f29d03bb4ddda1dab40843b04da025d0161e0bfc631af670d0589637aea3955e1920d75058157d2c3ed0556224fe617abba0753fe30635b1fa02b883579fdb8f4d014a29e2187cade49878521d7e6f3ca41b2dbb79d27c8ca151e6767dd1c0b9418ceedc35dfb0262e68653e6ba7d6220a9e4a6b5f4058c0de4d0bad76cb191f1303c0b15ce76a131fe9fc49e2854a7dfbf52914a20e363a1da07d1ed98a74f6ae04565189a3dae5340d1e5128582cc938c8b0e9181740cdd754e13d5333a8ef4eb30cc92e2bb792d18946e65a82ac20a27cf9993202e00841ad3dc108f9d9a2ca4cf1a84d8bc3c12afd6d244208fcdc8798bc13403a05e2192f5ce83f7930268cc2a68470417cf9ee85104fc036482f3125d6c72648fcc8bf2fc965f7844226d7e38611832347c7cb8a7c79931b7850079a88e4410c51111e607f74004bb20d418720ff0f0b4516a43c668094d0ed64e43d3072b5477c1f9aa5e4c6ddc83b68dd542f02e8414b137bcb59afacaaa349e9731ccdd5b03fdf2f225a4a94e49e4d1f81b53e83d61b10b7a3a6e2824c2c4484edfac310d902136771781da0a41cbd7bbaf161d4da071a125dedd94ffe86496abfde383496e1d56bbdbf9f7a63581cbafba5794802d66403e1a46404bfb8e9ab8160eca9bcd1ca9bb75618c0ca2267dda96be6bc80311bc0b1a1f015b5036e157d8c1a2e78316e01e35ea3d45b7c798aead07570caf456241cea74bb70aacd80188fc3b08036a13c5c79671c0499901a4d3ac504242571b406a234c5715a1b6da1745c9a3d2d6282530fe2be1b0f31d15eac6c03d8393284e2aa91ddf6398f26eb2c4fd1a9ae47e533a0b65bbbe3dbec101818293a560616d9123f64d07c1335759e44c47898fc9552abd20925691b63ff8f473cfa38fe6ab149fc5831b7f08b433f0cf42c0e145c5004031340692551011f720b96973e651a34011481fb5ad424aa0f0fc2300ae08c013a146d502404a24267e785b81dc91b0ccc4c1d57fb4311aa13a429e21dc085b7110596216f8d9d1148725d8993809dc721361c7762be5639bf06675e235437c651c610e8b4fbe73bc98485fe2cd8ae6b22ae8f0e67d3afcf099fa33935625056b2e02cd3565774b05874ddce68017b4b364f7bc13ed6670b87078df38edb486adba41c002b5c8db934d52a8492144a3c0a49f1c2c9b407e8f84ce1a930518147f784bcb351f9217218a563d072aaf4e8e94a42e6cac3d14d7bcc34e7ed9dd0318a713516183ae41ac3da50dad365f4c43a022883cf65df72cb0c8d22d1b7b49b933c204b06034d2c60a73101d317d184184768f8989442bc17275c3f565808ea79cc3f707b5f03997be6414b34198289aee81fa6cd0fdf41618f4e08099f698bd4100a914df3182ecf81d901e8863e24b3dd0d5b30b92cfa799a42b103da0c3601ca26d94121c05352f4d04d0fdc90bc5a6e044bb01ee3e1a45e2cf771ef7dfd6431dd310084567eb27210642f4184874160623e19d80052f4f52e92a49f29c957fd251e042b96407a640a124e7667197b915a5e66ba1eaf069790ea1743e46af577706641c8978db14dbbf4461baac0b02abf7ccf269d0aad72e978a72dc8a8bb035a5e4584513d6443e3d887c56bd4ffa16de96923b994be5f9a5f37a9847264a00ad8f3547cdd262496850e96c51e2e8ae1728fec08548a205ede70b64250bbd7ee2a8d86e52a0d65b0d2247730c70b3a18e21fbde4b36c5d25614a86645695a72c60f67469688625270a8f56756ca3ceacacab191b4f35098fafbe416ba7cdac6f1f68cd48680c1b380fd631eb40d5f1e063c81cb284aa7b84e623586b1066c36b039491fef3606077252817e476adc002c6ac0c58ffd02474a6409b218c71635f813151bd2bef48fa26e1b567503a53f3a278b6323a83f24bb026ff910ec76784c7fb85a3b311fd9b7321c2c0064d548810ff4787821c447ad41e23ca28bb5f0421e31470e4fc2675291aa6c90e1cb17dcb0ab50ec477efa3bef3e2d0a1ab44ede65cc313e0528df78e61838e9aae6110b74f6d7e000a426b8e6ac5a9f5aae0f69ad256e1c872064c24d6e88dc0b41817b6664fdd109b77090cb5c5f747ac01baa4b07e0df4b45619ed161ee119fbe866373f05c92ead24ca6acaa6d3b5c4d96aff2923b77ae35fd7d2d76ec54002434e54c414f9e54d745a2d111007277c4bb23d75e7722b079b66dd56ede0bb213db5cbc116889d7cd8684d8a6d23d49a4ba902888b63beb241e3273671274434a6dbb1482d72b1497dcd5c16be68626bbb4591cace3d0a3e7a48c8b28086d3d0ba9cc236285fa06488f6820ba37c0378f670465c95e5d42ea3df012a44f531f56f0a7acf24e495f78e2bbc1d9b02e1f0437e4c26b4d5a9f1309312ca215f46ead63d9e4f2431987ed4d3a14d0a8ee3c433ab45a867e6eda1ba12e5d7b1323b6315e92e53b51493668178e16ec22be12e60d45248701549b628ed42ec5c0656599ca2a9902b29c337c48ba0c8091d7fa060ddf3cf42d6956393eaa4d3f07a16f389c9ecd8c383008f280a5da0be8c8e4875af13595c607d7a206482ee341ca13a0db93d766c572e878b127b77cd42f3bb26bca0d9483a95b381ac238cefe551f6095fa1622ad74fbda37b504f23d11feba30de2850069865463de81ecea5d1dbe8d3511df6be3768ea6eb27d92f114c841c86c3a39a7895d79b17cbcc4ec738f4994d7ddf727fc01a99ba5daaf4485a1f6370089f5aebe369d7d54bdb328185972de2b6346bad90bf26194c78994f5600f2df911395e760926fcb95733cefab601a8fd5732379f5f05676a3ab7ac448b45ff1ceff91f2eb9c809959f66aaa7d6505e139447f4a1979b2ddac7bf83a6ab0f8b348b77cf65810a147e9c328195f041765bbf88b3bcd10e164df0f904328680af34f0c8e200436b22bac5b9224007586e93a49219c64f9dbba52e9c009b0cb162bc7adfcedb5fe44933b99b683527c1b7ed41354d7a75624fc1d0f6608563e6c4d1815af0fdb4ad8aa12e500fbb9c959800fac9ba23aa494e2a3a24483fe2730cf7409512f70e4b8eb3eba2fa69649844d9a4ffa9ccfe534cb4e73ab75b8d17858c9117072f1daf14b68f458abe8e1f0d0959994715f16143b96e7327287478c7a344ab2ef7dc6305711290e745e07d070af981d497a3fb2003d9de8b7c1ca9eb81654d302f32b30e8b5b5252727dc306855aa8634631fefb5f8d979425faf956e934e95272e49f374a3941a3894d34cf0e9a4088d871bcf86fcc1cff9d38a8b6b0381e16ece0fae9a026dcac7446fb5695e2e066ed10b7da3ac3d8de69de9700e8ef58dcd7ea18ef421f75f6076914a9600dd51240e9f32f10ecef232a7b2804c0557021052fddb210e27f65a8c4386c9cd7f2fb6e97e2d4c5f91001b09ae75010f17910658e21b3588a5d01d864cc405a9996fd9e7c9f085965495b842d6dee3740978d285c677d48003822cf933aa87b9f1dd89da45f2e2aea57116975138f26244ddb8c4e487a1afc07690e7ebf691ff7458f271bb5fb617d9c02beca6744273688352b03bbd8497daa1540e3fb44cd658f699339871455d33ccfcf0cbc1819228cd862cf00d2aea3a0a9fb192ae4c7830d742f83dea7c88fb02099cfdd8a183ea74f94c033038bdd0ff9710be879fd18911fbd9211cb206f17dd5e739ad766db752b5f9cf016c7d80185c18a6d08a396aa6f90f868258064c9cf14ab59e7242769e0a49738a1db2ba2e1e66fe73a7207cafc52e035253bd66d96c4b89cae3cc8ca85a8279bda2bafb7b523d3696c2a404aebc16408a12b2665198fd49e86165dc9c7f1cc359f266589c7d14a831655d9c7d38d46158bb905784f5b1ab0a294fb783734a0a428f931a2d7c0a226f111b2ac814151e62375e71a9efd7129d6e5efa35de22be92cc81638f40a427d28508dcc23010f400755d90ce8a20a35371f51e16e858175008bbfc83c92db4669ad44b5013558c54a810f7c5fdee2c81871c28c69571338e56a94a68863881689ca7bf77ac9a95d3301ae67a2e206b0c7185e835db4540f21c0a5ed7f0033ae0cdb5f02ce2f6d10d8b7d36df7841d9df40cde6d6dd197ce39d2e9ffcedf78c1e6b83e00f90c6b15d4f1942f616985ae571226146a4eb0aff416432aa4b9f36db982081955433af577ed0a2da7876edca38e0726cdc4d16567994ce809280ee7bb870be8aba7206c25385df6a0bbb81124c7bb186b7685a546eba703b3bf7a7bf798cce3b5f00d7b805d2e73b610fdae0b7040c0e382a4d81f8117e4891eaa7481dd2c806a670e2e36785b3843ff53625dead0b18a70bf56c34ee1414c5a5493ab38072a77e2311978817fd61ab727f6b52f803d3d33844ce5614facff58cc14d2e9d5bc9a258dd86d6ba9c3a523aba34ad25d9243b6b0e8a1ba6bfb05f525e69a53550acc04daeeab0a8eecb8b093d1af0a48f7ad11a77ec961a8c22f0f8a80cb39a50611b8be504b0204832cd188ad36cfe57054ce74b76791c107da3acc5aa5a9f9a39edfd147b0a66c452d4a11338a1bdf2cdb6ad59a110a014152c4b21589f8b7174a345a6519f02a283a1c31c88ebb31524b896cd022b5ad0356239d5dc5df2a06dfa0a36b7ea23a6dea8407efa6a3c1653b677fc0d041a5eb9208158843a5a80d482dd230c9a9fa982c012d8007f14724db87c8698bec5eb6260e33b419bda4f7435438b0982d85ef1a71436d58bd1da909668f15e21e83381159f4400a8500990a4f16d0fd2796b7e299106c95ad31a172d326a9996d4376066d60a28bd73bbf6d2f275c6892f0c8e2de71953bbea57a21b2cc1eb80fe1e2ee24cdf7c3af7c85d77694bc36e817f485be10af34ccc7db3e183ef2231c3f7979fc8c03da8b148d48c7f5b102fffdecc13eb9af86adb0eecfccfd4173e01be787b87690dade1f482bb247dadcbcf4e994a24deae792e96f35812587028feb6bd5c4c9788b2480cbe70cf57282e7e052f73e690a54f44afb8ba2452727bea082f58118e9cf3d3f756cfa8b6a194fc78f67a9715912e3c354703bb740ff3de059110d7743516d570e9e00ba63fc76c94e953dbb5e419c8466dcbd998c24d1358f09c87065632dd3a111ee6accb1f067186e57073cbbe73a57ad50bda7e3fe58002c92c38ac736add558adda745fe36bc7548078f1e0a419bee1db1baae9639d6dd0d4559b122fa5ee15f1e15bc4270a677aa99cd4975e64644ccb4a65e3ad8460a85811caafe0c6ae28440468274e1dae41d07784b06c4b667c863188949ad3feae93c8efaac388bb75344c7d190760b43ceb98727b33c60525aa22b8fe9be42b8c3ce3b5f6339225f379d314c593faeaad4308bc02b117a8b40e854be9400353d076183221da529626be540b278332d1478673e33593af000c713ee70c0c4e09a3d8c507f3157c4a34e58bef5d94ef45276071562c8c6feb71e8e2c70761271d7e1912f66182b4bc9a5e3e448c8f3d60575ea6b84be3fdb3b420ae1068d792909ba24393454813225559fb746c4ce6124302caa9377a6c6f34fd248f5fb2653081580753470efe13b76e1825d41a1590b077b53c6317e2ec14da49462516d40d6b0d8c9a2d44bb83d5179d7476b857a769168e4adbd4969400a6bb5fbf21373cf60d82e7cce51743aab801f21394642cb0a4e6333c4c67b8936de622252aaa8301b2ffa787b419ece291c5b3522853abfedbf0a94201a4ce64d5784411855275907baabced2f6f4ff80ea552047ef0e4d9e67c7b1886c2160ca1fc002566c5d048e120452a758c927b0e4037b36019aa53cf8d144cff876e350fa4510a9aa40a4de92a863b7530b7d293a4965b3816a7618aaeafb47e6878c1c317c2d9767e8d46d21d28a372d2aba7f653fe4cd732c8c79a6d9bfec85c5f1eb2d35c83503467bcb9c981b6ab99dba76a78327c4acaece8028ac7cf8d263a5f6dae53a7bea3e28a3abecade65048405b9a38189c76570911b77efbe12d2d0d0eeeb118e4ece55e36b4960752c778a8bc267fd159f804d264d78920f712e2cf050b3f78112e10fb3791318de7eb090f565f5d2639a7b3f670b790cdccd4aaba91e1e1f98dc3b722646e551b6d49623be3de67e78f49e14b553a8d7716cf7dbb96e8875aa41f23592d71f5907f6894af07663613720e07227aa05b98ff844e182d5f2c1e3a042826b3cb363d6dfa70dc7216adad8f71851d890a26ec99569c1421fc3151d9f18ae49448c40bbb047b2bde9a23e15ca3d3379d1ed0fc5f995247bdc6d9d463b3b8ef9bc8a78870406183b9857b14f53ada9adef240ec703c491122c963d321411b70c44c562466511b7f801a7da202ed5828b7d090f2c56625e7c9df1c0275b030621226f15b7071786f7701256a5cd83274b9756ebe4d2d2dbe38531743327e781929857d2dcfe92708ade3741dbf50cad6ae3d97b45ba6e0d491383afdb600bfbf255d8007c8f52defb439ced651c301adfc7689d9f7e505fb6816d7cb4b1f52ad9f1872c80b3b1f8231b538de8067a9d6557c0e54a0dc841c2db7a4b0abb33f6447099fe9ed565f950ba28ba0a46ca79212a1e023157075f08b36844ee8206553d755470265f15c61a3fa467b34f5ff55faee1de701b9e6762add64210d0ff32b5bb94170f6c62b3c69da4f1a0dac96aa35317846ff17c04c4024035c8a49d7648efa4ec93243e152983db4fbf85b6600d61ca2489948ca9d90028cdec9101c374a7f1a8e5c6a08938a29150e264f9134294281249648d01006afe5a1d7ad73d165cedfc2652c7aa1df4870727ae13a997463f9bd2fb972ba1010bd43894e0da20bcac3a5803a0a6a867ae7c2f4bf053cba51f0ecdd5a0f406ea9304c111eb67b523f56df372645634e1ed1d4237a36fb16c4be93f0ed0b0d3ab215f41f0d724ea853d493d8181192b3b76afdbca0928919caed5c469be042579fdc68932d7a0fd7b0ecb0267e8c8d2773de6ffaf20fdb2b36f4ff741a8066d8b40d191d50f6cb572001d1f84de648c678ab6e2f0f5bc3565a1bf57ea86678a23985844b6f067de8e1feeb9ab6c4e2dec910678f8537233fed2fef1a8b2075ddd6b436901158a1fa0418ff293f5caf141f0075737621d64058e30b82cb8305bd561b35541287fbe9388d0d1bbf72e18b4a8e6bafe7767e5b848ca3aaa7db8969756a25ab15036b3923b641c7622a5d3c419116af2d530973cf93e7452926a8c25b4168d4b7b62437e9394b127fcacd058d76ec5af92b8b6492a8e18239f90e750fbd5156514ee8329a743759973fc31803f8d1db7060219c70d4b7a8726a46a57e9c5473328ab6e223dcaec4a83a0fd1b6efe9de5afcc85c9e6c4de46d1c5051ee0572f7a2abaf0f3de1b5d351df0ea6c7746f04489ce5003aeeaf68f5d529d3a4a4318625b3e7e922ba049320cd731304bda7b11d3f4495e295faf2541f455ca9743a41da3c1f72d148a58927c4f52bf7ee16c57ebb555262d31dcfa79d52894813e92284097660e5e3f556e96b79bdc7ad2115b6be92dc53ae017b49a26790850a3e9a6834cd4da0a7e9ac983fe38867325916dc7c731d4e0b15f51394c3c8c4f9aa7e10aae8c934d87b3cdebc0fade1c0ef0481c43812801e3438ceb657e4be6280910e25b60bcd46233561768199e117473f882fcabe47fab82b04b0a4ee61cd1103b9c4d41776e286828532fe680baedc2f1141a520bb3c8b8a5ca9079720d387f17b5516d83f42a7ee70d04fa51e4b949fce20f98adf775315bd22b308f6c0c354f35b484fc511341e68e35a25084fd93749c652cf07fc1e295e7140c55ea2e1b8b5b5b544c3633e773090f028df696bfae763d422ffd62d74092db5f88ec1764e8e29eca940bddbfc64f9ee8345dc945991c4f39422aa619084b49a4b808798b9bd7f9ac55ba90f02dc1c785f3cfb6fd1fb093b10142569795755d8bdaa86af317589360d15b2156617a4c773cdec67959cd6891e686634bf517572ae28cefa56e902346a6a2c1b96e7a2b1da5138b9175638afd23751157d9c37a075e748280ee709471a245df958a68a1904627885c2e78cf3d1ad31ee7bee1824a069a1281f7b2476cff9549c19ae29e5e1609d150addc4d9faf70faecf97a976f24ddfeb132e106cc3c94125651f16e6c70b54e766b27ec621d5f3ac267bb9d5c97f38e8b3865e08cff1ba2f796cb644666d86f5e1ba3875e3e67b0c137a65885360bed533d73a30854400d20973b443c36e9650737a699bea1301f5eb7f4263d5e9bbd6a9856a059a16791a4b98e01b0f2f95961ef23a237e8e23acf9a7f4275042bcb46b6ba202a21fdedb49593c6ee6246e6099065bb2223d8964017499d6c31b36cc3ec8ccd4e911c7c4aa33fe83e0e2a5dbd917774e70a032ac748114c315e71cb2a9b541b8e5abe051acdd9ddfb38f83aba6a8c84d399d74b2c94baa95c0e57d60766467df258d17367c3f55860c295d37731a5c41ec5dfa8a8b41418880cf62a363085443a6fd3504cc7e75a7ba3bfef69d295e561869ff467da8702a0ba508efe4e27233f2208aa57ead3e5391dc7be484fee06ca0f4ce49379e02ddcb32276461298616aa661bab70df0be1cb57f798dc7f92cf1b3c18f14a1aa7f434a4ac85198bea1f57038d5f480da1d58e83c6aa06123824bec5b52b9f7287262bb930c3767d0fd533223983c2641508c1f3163f5dd75fcc92d03d8c78530aa918ddc1a2befc2a32eefc5f9ea27fbf4a8db873d430b86c3994b199bb781bdc579875178e5771fff87434ebf00acbd8f665b20caf631e868b844367e22b581241c44b8c6841691a6f4a8dd2892d3631638733a7986adc2cc0ef9214286b5c05a7e93e934631a25067b2cd29a32b1530c165777e5e45c5301bd883e0afa69f8be61c9f4612be0729d4c140a18bcd5b20afbee08de0604aa0dc9005998a505af3aedf546bfe1e4985bc05118341abbd9231e6ade9973ec79fe07d5141be4d7bc9538cc60bd7f7061b880eea8e72e397778dbd9a4a47186d87e5aa29dd473d640e6fdb90eb3254ee1f6bc2fb9d9a1da6c663d77b343f564af35ce1d654b6bef0108f3dcb162cffdcd662d7b7d76c81df07e6253fa9c79af1a384ca057854603f73e74e1d0da5ee9d1166fcf74b3b5ba0f8a8a6b288b9428b3eacef16af3395c35ad080f708a22d7ea0dcae7aecfd30a4bdc230c4c59acbb8b0c1f7b3f7a6561cf758d416eacae246dda97430dbbb09f26b53a993a3cd7630c11aecdf333ab8bc79c6ecb438fd6f6eaf012cbda629905a8706d8bc6825cc517cb1dba467bb1045618b8e3396d6f09e2c37d2cf475bda4c16afa962610b16a474e8e67ffa55f35902f4cf2a8239275f21ae91c79776981e9e0cb87a37fd601d56b6419b54c1ed46aee910cad98bf9a76f8b4442424bd2bb565f103a1ae6e793cec75bcf353011b39a2da893f96435f41f31146468c85c06cd85c0548abb627b0280262afddda93118885b571b80af8916d558c7532bdafa03b501688e1b12441b00f8264689ea4a821e396102b7456e28561a1ebb32961704a9d543f08e3f53ab866072b627ac8f8299ef42b27b47797c57a3c577bd5ce9492ac133db84d02bd8b0a36f67aea42dd24cd3762a7ffe691e8161990e230b812e70821e734cddfe03724c7ff463034f730357b749ac26a51ebe5fb9ca228431e5845d1a0f456798833e7b0084eb38400a4420b7fbf31c220527492cdec4607feccb989fcb0a1dcf7fdff42a4e8b5462a842f92e62bb6e8ae0984fe3fa3b94b9a4b500f6b0c5d5572581c3b3f3febd41486876ca8ea76c905998fa4546db77a8b213bc2d80726a68055dccc265137d278f273bf14d1cfef9509189c96de81970df12aaa3047a622c7228876242685cda16e9ee9c28e2b9401c065dc00e5a9be2cda0e18c6da8dcacb4031108ce41eeb244fd9b8b57dd19ce16136fa77d0c62694b846d9f9d887ae2b018b5b243848a8804d159b8ccb922ce5035a385fa359305652498b0135bcb7127f463982d6726d903840ff40380e2bcbc0da34c43024cbc2526711be37fa3f80b08fdf32643c9e8e8ffd2900e260db7618b32e8676100bc3623b5588256350fda98dadb5269288904d44686577f70e69094e0aa80a31c7ef88a2654c9a14f353b86e944f27e5d361a296234aa7c3ceafb886f82de7dc7d679489f4d1dfd6a14399b40c69fb48071df6f6dc8df209e5f4ac674e27e99912cbd6340dcb3ee9d2df51b894612b186318866d1ba6a2a2f28b5389014977361ad7e9b0b59b70ec88636f29a7bddd74dab12bed7842790af7620a459bb8ad74eda6e378d7b8ca42b2611b7de3a416350b0dcbf3d181e508eb05c754c66aada8fb99a9674cd5ef107d76b2d1f147df7e471ce9db687495130e16d2a3ee7ac8fb07d4d6f047ba1b7ddbb6accd981a8dfed1bbfc776cc48d467a231d8ff20b0a7bf4408e9d1f8f1d60b3b346699fc19eaf6199878df1475d1e613cca3ed233d9313da3f251cddca3c76cd35dcd1c8d621c7dc3a36f23bc6ddbb66ddb0edca311d6db16756771e46d3b8a83915b3d1e8d46a3d16874ed99233d72f81b27f367e2f1733cd6a4ed3072c4c5bd8d50a3cf6c8f1f6d8fdf32cb29665bdc56953dacaa5fd6feaa2a8cb339d094ce8613194bf975a99c4ecab6e76fd7ae65288f3fe4d8a68deb4a5bd3341bbf5d2b1d65c32ab661db76edd3f45c710ddaa3468d1e3d9063971e47da0136bba43b1a9a9dbf7523cc84bda467b09bf44c4653da344d69ab5ccbfebe42ca54f08944c218636dd3f0a669292929bfb8144dd3344d7362347aa9f46d33699a16230a8a267dbbe928137ee9dfb87a523efe086207d844d99576c45af6aeb4694a25798ab8082f44ac5f20e8ab03d05b4e8a6a4a09896ec4b24abf4cbf4e3fe1a71c45e52bf937d330ec2a162b6998ccbee97cf14958bec780c847918e61242d33c2fe3610f877bb86f1497a46e598dcd86be43e3dabfc7d057bc4322a7ac6d4493f0505c56432994ca552e917573262599665599665d9e76374124977736bdf746cba9b1bc32c6bbba6374e968028da3571a82bb974d8bebff71dcdb6ae0df61103c17e698ceb6872d898eeac3fccc16ddd4cbb1708bebaa3793155d5bf474d534ae29e96c84a44212f2caee34b4fbff877e52bd9558e82223d9ff4ed97c4a57ce364521e7547538ad8867c5207be715d696fa5adb495befd96b87813a901a397485ce9295c47fabb03b29b0e134ba56f9fa5d2358b95ac9429afb886ed914422bdf44be2e22fc432984ee2b2ee00dca6bf9d1f674cba07991753a4e7376074d3df8e2392ee6876bc2977a452966243f6929ec96ed2248ea6b44b8f5c97354d69677ad31d4d696b7f47a194b4157cfa92ee5450506ac0f86ebf1bbe7786aef42ddfd237acbb21fb9ede52bedb76bafa344fbfdce96ef8dbddb67bfaedd8bdc4326c17bba725b27514dca447ad7d62fc8b74fd6193ee6cb6a944b34b79c4bd98da7497f7b66d8f31254577766fba4379e9a3e3e074973d1f4666eebdc4d5a3701d4d69939eddf407f10c5886f44b471d767c7cd51f4c247171e3937e495c3ea9f411677ae424961901d94c9cccf69296242eeec875d9ed2109cb8cbe95626ad3da9f9ec187a7296dacafbfbc2f97ea41b3df1f4c2ced1fa04ad49a98b6aab69abfeea5ad96bcd5d657954ea944b6f6d7b232ec37e3f0314ed3f0b5cc6e0c85b5cc486fd9b52cbb59961dcbcf32ec5a76afa66558bb19a66996655916965996f67cccb22c2db334ccb238928561168661bf2cccb294b0d65a6badb59aa66998760cb3d66299a6734cd5cc7db5cd1ba302aca7dcb4ac5f8b7bbf2f5a8795a5bf1cdc11bb7467ab63dc8c2d95a56b66ad999106519c5a90315229e5292b47b9e974150dff6a5c76ccc59c7ffa39e160f909070bea31b3215fc3342ad332a34d6b8fc7db515c37d2568e692b878999ebb46f1a671d0f5b7bc535e0c74da3301b46dffe360f1d0ad332a3b779d8f15a375a79e6bafc4cb34091b3ae997b7b5cf9a667568ee999d36be6ce8f5ca7e99ab957f48ba994e3d3df554c32273d632a45772826538ca552291effe2523ed6e2f371296b119348a45f1c291e638c2fbe2dc8f651cf60b79e61119bc1304cc322378a7a3b0bdc8b181f07f7620bce1eb9ae66ee0ed3304dd31eb9ed98ebf2c61163aec35a96697a063becb0ae991bd3d65fdeaf87ea8d37de20da3592874ac44538f1d905d88f89139df94b71a24bd5f639d0721dcd992b961a1153d5861753bafb00d1aeafaaee3a0f08edee9d86e6ec68615c220a7ad2c970c31ae0864a4430b8d8d6c1c06213603f265f10edfb668070cbdd75c066938e7214959b5e3acd60d78e3dfbc5b895675c86d784b6f6941f265f287982d07e4290ccca337e7ec53668c7b067d8379db3ed2b7780ca31c66d7ff80170ab60df340b14197bf659c3cab563d82bae217b46e16bba43d970bf69cfba43612d73f337adfded0f10ed7cacbbafdb290e02b7ca8a6681226b9a26ab7cd3332ac77a26e51c4d56d12fa6509ee994bf9f38896780d71eb14c8a9e3185a26fd22fa64a9f3155ca35906a2091b80e04fbcad77e354e46ee0bcfd061d776d8990d735f3568d72f1be4bef2311e76a63bfa1ab9af6e8e7467b32f3d3a7ddca35fdc4877705f39eb8e638122d7c87d9d3edf723530d7cc7d5dd7c9a819e0ce873b5fd333871a2503affddad709ce7e613f266034d937621a37736ffde67b0bdefa02c9b67e33ddd9ec4cdbae1dd38e7de358a0c8125fe33a1a9a93713fc09df3ad5bbabbcfe7321b321777d6d9356ecb91d1bee997b9b8312e3ecbe06b5a67e3b8333d730fb90ed33434675f6d5d79575ca7f1ecf7ca751f20a2379386e6ec1fa0699f20e605102921d0758d7cfd26158f05962116412497922d31e60026e66b8fa721de47ea6233ca35fa175dbad1af9c7be4009b2db13d3a4cbcb9f4fc8deb6cf656fac3db61a2e9339aa589ac4daf6eb327d7617b8eb89289abb3c491feb0b4d992943ff3475cc7c3ce39a65e8c11dbafba22772f28072140541d76c8000d0f35afb4271653d0c6042d0be6c61dc005313288c7850f8810410c08aa13e020c6c603c0db25685831831810d42d8062aa204481045bc480a01ac21131957ef1005d8f0d6f1373001754d6ab35ac1388809280ad6e696be301a2bd15cb5067a5fa00ddc9da5b2d7440d4450c08641462aadbc41ce0b4714c3aa544c2c58eb74c9e40231582dc859343e1208390433b3731525bf8735f84a790d237dfe58dc179aaab8a524adfa44364fa197839f58c2e1d7d06523ac5d4a49452cac10d29a5735694be2d4ff4f48618d78dbf5aadd5dedb19ae7bc85d69533ed81ab8e15758a0b8ae992b865d7b441bb81df57bd715a36559918ba1420e6e7bafeb9ab98e457ad93a448615d65a6388c1d2eaaab5d65aebad3ac7547dbc2e6959b5d6577b8aa91af563aa5a7b59f6b2d53e1f725bd7f52e8c5ef5b2769e76b5d809c7ab656dcdc40881183b1a168139903be2e98837ede4ee05c123e011d80e3914c938579c0e4e7228428798da012795fa4fa71cef4486b74e5c6b9d54209453daf7521ffc9687890f72b001df104a2f484149968063040a4844246c903031c50d72e0832508e1ecb04f276bf5734809638c14c62caccd9956fe49299570a59452dae842fc8e118d1aec88460a768c6714a1ae704b4f8013cef9fe230411ca7c300bcaf39dedd143bea0c0d09043069a6c2965a553b2bc20e58b6c65c1481948caf0d152d20861e8f1135dba1820503ed5aa13534eb27c3c46afbc9c4a0c86495a14536ed49b9822125b0e50732a912cf6fc2c5275a28bd4793ea2906c41b2c653624fa29bc49ed7c8e5c1b0dfa2e8e2c63c7c632891b6b245d1e55523f63c15922f3547b6cc17d1359e0badc24bcdcf4b68cf312c25565617ab42cd298a2fe67252c437885ca1485ee10a3c52ca5aa4aaa07213ce2ba94a2ef4810086e15f3de41edf21f818566bad594eadb55eaeeac89679cce5d49c989a4419eeb8efb120cf4795792fb50ad524d416ec397318105313e3ce9d606a4eadb55621a8a4d65a6bad3e7b5625d067095402c3801860e8719554910485108594c6951f327cc810e2a4a4110a59c2830fceeede13980346969f34441f2918e1a292da3631f310c7babf1e84359d91038dcc439e7998337f71270e0bcaf63b60e0cd1739015b30c69e39a523598798b26ceace1311d4892e6f0762b1468f105c0273200f4c027ba0121f970cc0e7a083d08cd614ee63a191529832c610553284030dc9501864dc7014c6772c6dcc2967cefbc1078394bec8f2330bcaf441e48bc9c80d3a08a9892e8fc91a3f6974f17c7ed25063774f480d3476f7cc30edee11bda2aad2257bb6b1e7df8c8761000b8ed79bfb585e500ff5e2a51e221f512fbe974d67e4efee12be878497918afba2cb0f75cfcc00dcd723be67036137658e2ed5e129c702c5674ce119e6ab4f2c23eb8c1a7104103e019250461ede6c0b8b6aac62a4c00b9a708386107edaa042916b891d8f4517ec18638c31461dc5125544252a2b95c03020080d56d4c1c113392d38438d2a88ae88e9780ce1d4a8c4d00976bc5dd98f891867ec318a4829df7befbd09e78452caf7267c39739a664c32ce39a79c72cec7cd39f59b5248294b3454c6f95ca87c9d919f55bf492994ef3d39a58436b204b4d6dbcc3d63da536237e6e842eba5987f5dfd8ca9ebaeb0ece4f92743655553cfd489510b2da82d9e41fe029b93f99ea997a71cdd57ce8cea5a2fe9ae37c40000cd801c2cd9dda949b6ae9821c8723f2662f4ec5a45a6fb3111a30627183011830aec0a31941003066210d99850129eb0cf0ad085fd98a0112446173bf66382c615f6683f26622041c9b6d16e0e9c6c0f129e08732410271ee8898c208625769c2086116e86ba88a97a04390059d144052f70020e861043f50eb22572dd137a1b265212ec2e35c4ee9e9211ecee0511d9dd231262771047049b866053d1f305911114c1448811c454a00725d0a9c20cbc5882508c7cc30a30a250c4461b3f8899ba7b3f3f3050c2196aa0e0e7094dc4487d811c98318424243104d01262932fb8e882046fc0a0878d68060d88d0c11460946184989b187e5004326e704591154b622c700435942ce10409252022c6014c88411488e0c609aa70414c3c0ff9f2809a6871041338618b170821c6e62607491481084560e3c8d02bc3084b8ea84210a648b2469013f02461c5185240838c18023819c20d144861a8093788d9018a2c92b0410404274c2126e60a053f30d5a4b3b2f03c5d6c78025b553a95c03020080d6858018c34a050944614fbda8f491a4e9c6ab005dc62c73f190c410538e0228c244a7043e3450c8aa044912108618b30b0aad65aabc37a69c9f7eea5bb7cda55e2aabb1a0a5343e50c909c6e1d9572ec2a2b2765199757b2ee7af8fe61659b9e379a655976edef0e48f9e830514b394cdcb46c87ad599b7377a2db0339f60e7b2b6929df4c3a25e5233db352e26ae8a66b28ea99ee6ae85ef93b49650575c254544ea753f69b9db467db49dbb27bef2dee6659966519928c9a616bcf59fb2e7dcb32dd99b2ee72b4d0020b2ce0c08142adaca8a89c4e292928282653a944228d46db96b3a66519c61876ef75593bb3764e49d1a6ec5db5b3a3fe9e0fd33bbaf3dff391f2134a77756757f90af79e0e15ddd57cd2dddcf9e940d1262efb7b2ea6672f957587d5d091a669b7babbd79e69db657e8e3b6bdde9bedae6f71d8476cd2ced007bb92cabc6bab8195b6a6a6a846c4c715df7a2301773ce1e311a6c93481a8565a89350580da9a6a6a60685d16028140d46836d14d61d0d76efbdf7de7befc5972b618c2fbe778aebbaaeebbaae6b47120d765d18b6f1863176bd7caac1786012c84bdaf6dbfb81c11df2d6da5b2c3f1fd7356a35cd7a9518c8bd1a758f92c1cf0782b3cdbe1a25739f0fe43edf6657ceba18cb407add4a5aa61e7bd558d5d1d234a5fdca763618fc712f7fb9ededa8b7b84ae21e372fcefa0524678dca9b769b9d354a267f3b90fced361b97b997e18b312d635d3a3f1d1588f52a3f1d96c662aa56fa976d3982f589287255fdb22ab7c791e3a8afb4503ae9a59b7e4b9c7613892bcd90f2d24935a08c467bf4ab71d84d1c06f18692416dda867c8d944d1ca63b9a92e925ae239da6b4b34635003fbb4c03323d9f0efc6de3b6eb6cda24d335d261e2b58ce98e669b360907815b7b894b618143f9bd10cb8c6eba36905eba1a0acaafc6997e6dd89e4bbf71db346a3b4a26fb752059f60bdf666f1a25b3fd3a90edd7b5e16ce2946b18a671588a7688816c3a3f1da59bae658dc554e9264c438e6f2f71da290ea2a17cfe5658894b39c50f803bc749a61cd7f44c8e6f7a86859b72e81753388ec2c2df5b586141cf98c241575654ae727b98a86255ac353da3586b7a56b1d69a506cb6fa64b993bdacb56cb6d66d14193bbcae575575bdba7055fd42e1bad246b989eb68b6a994b3a66d19c7bdd852ba47b989abcfb8ee9e5455babbb0c420c5244e4989efe1df89654cb4542a6d1ad759141357d22a7cff3089a471a4ab6550ae1dc5a43b9a9d8198747e3a3a9ad2ee6cf6283f1d39d3584c65ec1a97452c2337fe888bdb64d228d35132a4a31c0849bfa7837414fd9e8ed26db649a3644c473910d3516eb333c7a17026aec491b673d8466d5a265fcb3a3f1dd835968d69cf348dc514f60cc37ae63aecaea629ed4b5779b7105180aaead9ce5accda638a1db3b4101acce6c2e80328f2c558ce3fe4d8d9f348fb68d3322d67ed6218569335d47df6408ead75a89b69cfb45f5db3316d44c2f857cb9806cb39633963395fbb592872bef9666ee6de9b5dac666752ce723d76330d08d2338761da67f2b16b98060496e59c350df61a6cff002116f994311b5deeadcfe8a209c9b94a9db6cffc0b8b2dd571a5dd7bac859c6e38651c65121e530aca557ec2256cb1d20f394a1f8db4110a4aa9541232ca99e654b256c816b24b28254d734241c134a73dd234a78d4273daf88453544ea794949494524ac96432fde24c3c9a7612b24b24148a84627ae9a4a348d8c47534a73d3abe0644e9542a3dbe04c44f3d849cb429ceb2e92f8e6d617c1db05575a70aabe629d361572c3ab0c82e62a082fdcafe568e51da471cca23b795ea86f26d648329e69803f3594e329c50830b354ab0731324072134dc80830e3b64005eecde7b317b3a9d4e271a220e0245be81862047320d3e404188f0a121a66e7845279f93cfc9e7e4730a72247f61311319be9bdbbe696525adfdb3d6daaaaaaa2aa99c52ca0a5226640fdae3b2ca4a6685c922479697a254fea5e8a33a9c76bffc0c81ad5cad94564a2ba5b5562a9f003d59b2b37d825513508e47d122db3f4c017b141864196b712f068c5cd5987a5ad14a77f51dcda629edf944eeec670dee932f2fa3b4f19ef517ab088d6c78f8eb3b3c3d58c06d4b75e7428b8d645ce59111ffdd69af780292da50f720ef7018577125234bf2fc8d193a66f410604e1c67494133367df0e9ca5377a2409224562c62ca484c8551396bdf0839952db98ac355236a4e2d4289b0e9af9fe7439e22d97587a7a23e4a8478a928ea4d940192dbb369869f1d07fc2c3bd68e8f7510f8da841467725e994395a846640b8d2e15a70af15c6a111791b4aa9d15ce8cd079022436e432e44afb56a27d2b266cc891f6b558e4501172a8a8776c977dada20b8bba8720b6075076cdc5228645c861fb622936e4461b555155c322f77caeea3eec5e96adb69765f23e2610c1861cde957b02bfe29ec0790c9475c7c817f96dfcecdd0bea710311fc2c8709bc3bc91764edee051981a10927a04a0f955d45d7030a234f07e5518d58aefe056bc4daead5887cc1f1c39324ba28892e5c3cc9d9b4026d6a64d39e4d976ceaf3b369d0a6b7557d61d3773c8480e80fe5e05fe001038eb3fca4187129a531c6cf3f277b4235e41ba2032d842863892434e1248a878611885a70052090000958a0e00736550435610330927863891b24b9820b2348e1054363508184234a7ec01842091f2f96502b76e0042f9e5842133a28e20749269d95b55778a1820454f4000955718515d820f103183ca1074c601004448417533c4107489c61c5107296b860092a962842460dcc184212cb06921148d1451a5608a1abe001149240d406148c38428b2a3800a444164aa0b0a4c9926a022a8ae8400a28c4c00427b0810b4f927045911457dc10a9020819561029517284cf0d6e7a8820e1021210410c1364f1d860828b2d844ec04384266f3451441247fce08b3346608523b0e0c7491253d0c28898836ad259595b002dc2101a2368073218c25aa1088e138a4091d35369115be02089288282d00223d660226271ce39f51354a25c91a5942290022506f9b514f103329eb03706123f1f2cc95884caaab54608213d629a02765246fc7440f8eaee6ae496a7c1b66c42e7a474061e7b3012d2b965e4a9efbd779452faeed47308a2f7911b391f7827f1d0a133aaea71734efd1c39a664552b9d4f865155b592b56acc44eeecae958da95c553ac794b41d4d0c9b9ee65c317cfb8bb92cf1e59ec1afb4b417c6bac3b86c31bb65f5f6b5f4e9b5bcd763d2569546c9d4aa5132ddc476d53431eca96d76183051c8a6a529f2948f6a9ad39e12966189a494520a299520c3530e58a0a4b2ac162c56c7b2548048782a0d79c0e0b9e1e9884464f81bc821ccc7797921f2254e96e7e3fabb10f972ff0e6f700773b2e85ce870c0001fe441bec077cce527ac1b52c810883117472143eb5aec6057324f0b186fe8d183078f54cafaf9f9c962db571eec4ae66571d55a5f903ae5067d148e810961af0f35733f718392008ca1873154e3602d6fa364b42dafed273e40b585989452caecc67d2cdd14daf537f20429a13ac54e47c830423d73e00e289e8fa8270a9e8efa89f37c44a149048f90909090100f0f4ff4a2d65abde2d7898397aaaf58cf1c5cb3aad55c8fe9ee8519836afd9c2927804591a728de449ce872ab9c5824eac868e4f9803b4621b10c17b30e132f37f73d92bbc81345e4892e51864be2197e64f06136098aa9fa6c8a1c2d4a0243b2e3fbc8971724344484b92122c0d71e84a65d0b02df80b5c5373cd92205ea492452890f929e5a6badb50ae10108780371604e8f1e30416ec86107bbeb3b9b4faf4ff1803f4a37fb3d4e1df96213538f399b98d9f37ce4c8172375f24c21aca887752dcbb22ccbbaf75e1f1059e31482ead6400757043577718ae7614f9718b9c988ccd4fee265c7dbc7cb1e6443446b733e9dfe2bb9bc851122ecf8f8533c0ffb1eb6e3b16f6adf5f49d3635fda3e2232dc5677a74a773ca89ebabbd4b1c7ce2425dcb3d0091fdf43963110129243924816cd9b89236f9e0ff97979235f64f05c6412a8964864cbec5edf9dec0b9dbcb1d656395724413ae8083906c11f514b245109cf87d4b20aa965d0d39152445151bc89383127ea44233e3e3f4142434450e7c5d820e951f28684f00004bc7912490f982037e4b0c357906d7e4a523c9e0fb87f228f7c795de4993995136fc3f7430a813fa4864474b008f8926f6e48a0464cf79650185ed88fa5142bddf1d8b1eaaec78e42e40ba6a786d5e2323214a28734d542e40b24224621f2e5c5c45784f37444d81353f1f1ed0e22a146ae0f3dc037f67bc550f3d61f6a6a1404aa5f9780bda58758b7bff4102970b06e356a0eb1d3723ce87bd09f3e45df1d6e9868d9085580628ca955a71091e7b7e6215b6e6612f007ece20fa861e08efafad1f31175ccdb72aaf41207846ca97a64ed96733e9d347dac79503142b6740a4ea65992dc3d0889401c684474b178902fd9adcdf974b2af8e3d6eb9216e40e583f50b6e5bb9fa9c9d7145bb1e7341f2a94b61cee6f4148f5d7bec0a235b6a8c2928431e6824a62a0effe11bb2c3c41b72a887a90f52affdce6309391e22b15410e5844a963c1fd5e16918cf473d3c25c9516c084f95882f4f400a363c45e2fd8801ee8887a75bbc17db45f66243266ca861648b16104e488330e0f285861803fcb1df8ef8aec78e4de2029e8ef82e01309819af1e5a9b338c94dca617d892abe84f7d028d28310349c50126620740b8220736a08216502c8108156480c693256f34f1032564432e401d9cb23092335db0e3b1c718638c15134f8c1e18364ed8600c2b88a00a1e24187152230722f0a20c32a0d0464cfc6322040cfa40526864d212dc1d9888ddbd2248a488dd411d1b21c098c2159848e3091bc474291b158c91842660f0c3c4c818311d0f9f0498200a3770e30c1b3c4114d3411c98938608261b690c914609d250c10c35d0020a61e80ce94023793f26446a108d8179c1a40824fb6d51144501f66352822536e643bcd9efd76f10f9f2dead45bd20ec2d6d1373ba6cb96e7110434290eb17be243e0a78902f2f06ebce62faeaee2424babc5fa7892ed8be1e36a4baf50bf5ae8b88bc7522f615f55edd266642c0fafcfbd44148f1340e550fb141c85b7a881438587bd443e140ab571f2235ea691cea6f6f13535dbfd76f902fd5e52560ddea21dad2a83bc47aa551f7c55c8e474c5d975c0fd972bde2b12f78731de25ce7e13a10d725bea1fae3e2be50462833d47b0ddc28ec38c85bc7a8f72152dc0f91026b1ce6ed87c85baf38d4d3284c43c0ba3c0ed6a546bdc75c8d83fdfc90a9514f03215b2e0c8d8cbaaffe625057a32060bdba04ac57f643e6ad4bc0c6bc778f685f4f5c454a3fb4e41353712221a54122da5153b2a1d61394290e45e2511cf9523d6e9b8a4ad7511c1c811a43351cbc97f7b49ee7836a44d8f107dbca62977e54f09e02e04d154c2e68c412584414c6a1b0e361c4d89109d1d08e5100fb3121dac1def6634224c54f17f7b148311fab4bfa17534f392b79f4784a46e0c51089874f6246142510d2aad65cf84e83b5181024c563bf1cdd59ecf6c58d1db37f5c0f20b87e998e08014207ee0cd0f0103b3b3b3b3b3b3b3b3b3b3b4e38e184134e1c3972e4c89123478e1c3972e488134e38e1844f1b3d3b6f21ab723a49291f84d167b6b0270ef864b402171bdaa8ad6492e1256cc286a7ef076c0277cc43eb831e5e85885ced781b609c41c9eca8e12968c326f007f7764c003c1d1336d993eaabbc20bf833733d257f952f4e1a09fa7141aa99c32be5203463969adac755d0c679a923df7dd46a4920925e5a4b282c2c1420b39384cc6f9a3319c5dcb384497dba2a3a3d3738281be1ff2e7fd4a20f84343928732d0841ca6e346d193a783fee22ed1d381dd48e1edd09060396d68482a9fcaa7e222be0cc0858babb6ac7c74b022b7e83e7123563e466c4a64d30361d3abe0e4ce0e592fa9d3df14d6d2c261a08bab3b72380803e5dc2462224ca92375ccc04eb0119e0e8d7f9e8e2586ec9035c312459778a222fc8381620a07e12ae39f0c246efc160e2b125b72628a8848479875340d00d7b400682e5cbb3e3e3e3e1acbb53b34a4e96b9787878747cb71ed2e59a271d72e8ea669daafdd9d1dad856bd7d0d0d09086ba7689682c5cbb7c7c7c341cd72e274eb4956b170f0f0f8f9672ed5ab24453b976e168da85a35d38daa376edec6828d7aca1a1a121cd74ed22a2699ae5e3a3593e9ae5a31d36b19c38d148d72c1e1e1e1e6d74cd5a0277d0251abc66e1689a66e168879a66ed68d6c7c7c7c789f60dbc1fd609d4ce4374d9ae9de6f9c83c1a0f8ff61be28be5912d748966976839061c0d8786e8625dbbf65474c9bea3699a6677589e8f7a6d48b6d06b1a11b8835ed3de8265d000505d01982e682c3e433e00f0f119daf4299de5b83c4b782ecfe559b2e905c0e15f9cbb7371725c9c8b7377367d005ac0504397c8d0d0d025b2e95d60e1e2f071e283f2f171b2e95956ae948b67090f0fcf924d0f0015eb74e1ec74a714dd9df28573ed6c7a8d624dd6d045646868e822b2e9b95285f9383965ede364d39f5447168fb5c4e2e1b178ac259b3e073492a98563ed9c2c1c0b47b3766c0e49b39bec46fa38f1f1913e9ab64eb616b2a63db13c4b2c8fe5b13cd22eb15898715b9c1d8b632d8ec5d954efc47d331c4daa214ba41aaa8666356489a062dc552392c24d8082a24bbc1074125be8e74e7ca97c7ca2f04932b1d8d9a791e81280679f2f783f2a272cef26133bfb54e2f900c0b3cf9bf852e94c9c9c4c4fe1fda89224a942d1f3c135892fb5a8c8499119454f82a2cbbd783faa2248007a3e72f4c4971a14a424c827e867672d50f17ed4274f6a80e4f960e1d96591f8527b94e8d9e9c92e73a20b8e679726783f2a10d0113bbb34e2f9403d7b248a2fd5c6a2ad83b3b39531de8f9a24491943cf870a17f18516150115352972e2135d4e5bbc1fb5482de28325cf470a4f7ca1414148827a94ec0ce5d96313ef077df2e4c8ce1e8d4422f185f6f444237a62914c5ae1fda040406fb8f17c9484e20bd5d119d221ca4849783f6892244bd81916f16516152d29e222b3cf0ead783f6811b883de606787499e8fedd9a14e7c9941468278b2c322d1253f49c1ce0e91783fe6939af832ad1b4476078dd84068ecec1b783f2610cc793ee0b3ec34cfc71dca42d96f882f53274910767699f76326c9de92a21860d8d95f882fb28886e8723d7bd609606732e831a89372bbf07ecc222ccf477c761b5f645076f87ec82770077d967d05cb9029d901f0717217b48f4fe5c3a29d6cfa08004d573a4970a5832b9dacd2a9926c7a152e7b5155242bc245b8a82ab2e94f39700b414fb2a02c08073dd9f4292c60386a0f10ae3d59edc96a0f0aeaae549d9a04571d5c75b2aa6352b94e4559112ec245a5140b25e849169405e12092c94ada0324694fd6437b28d0a61f952a12d5a149a88ed4c9749737d549b2e9b751b545b4485151112db2e9f3467757f5cca0f944cfa0a019349f6c7a8d893c7b80668f9d3d72f60069773ed9f4894e92d3d0d44992d5a7e1a1989245b388ce4556cf22715f2c13e188c514a5b8094c9441f2c50e3d813fae19a75350d0938d9bdc2743f2e51699017fdc34de0e7a9ab3e9d0c90e653bb4e91a4fc735a301f1e9a0575922cf771a929733fed1905415fe5112778585e47e30507c11c0e971132c849d5c0bbb38ba658ffc813f32dc417f89640b7dceb247fe589bb3cea6cf04f08be54bd547ae7aa97a33fcf1de8e8a9950dfe1a04d378681bc621894972e391e6e1a5b38fc84c3443145b1b539b3e8e4ee0901e0a2e8f22294efa299fc05815e2859ee2c292824f18f7c29492c5958709fc417a9232f5174a9a718d1a6973a521ac14af10503c5167a8a7faac63f31458f75ecc1e73e968e124959b4ebbc99b2be176ff6abef7d368142d049ea51623cd467578ac5adba1cc28aa43463e26854279fecfa0ba22a19aaaa8b3741b2a5be936e6c8c9366c4549544b2256a49b1e421876ad495a5a51957cb21ce07b8eb4f42647bebf0d5bffa4e65d7aaad5dab1c922df572e8e6460eddecaa9fdcb0d4507d6abe4e4bca21f8c37abd24e3f990af97653c89c67bd15eb594ddc9a17a8dab5e8bfdc5c9977a3bec337b6c2f392b7958b716b5ac156b6525a59496ae34fdc142a8f2360fc3b4b385beeb512dfb628cb10d9de703e1ee4af6f379ca22dcb7e3862c2c3005ff3aa8c9c0d2449e31f5620adf09e3933f6c146183088e13293cd98fc99327bbb34c9e38d9578b2e272259fe3032d77bc179aaef60d833062ee326a68fa99bb2d7deb2aace16f57ea410a49220b03f6b7a22c71fa2e8720f77040a6a125d307cf9684674c12e2fbeaeebbaaeeb26020561efbaaeebbaaef803831c8162504cc14ac71f199b0c45a018147f8878a801422ab95e20b4e52f0ff6cf5aae9aefbdf7dea3384feadef05a6badb5d64a3871a521910cb214ac93dd41377407897e13852a0b5e9d93523ae79c75ce2785d7e9ee13c2d2bc943a15e3a493ce3963aa2b3da90359c2626a3e4a29a595ce77bd7befbda7e5efbdf7f4e2e6d5b7d2ebd957bd57697d28198d92a1a76f4efd2ad1ab72ce4b5ef2929794efbdf72a5743f77b74d2479f0cc27df3bd54251c7f2df3959b20903631422aeedbf08f899203f7c2f8a0d6c085f1691048a6f69b4f0712f2fb7ddce4688531836f80dcf0bd17c4865a2a210c2cb6fc2104f22da5a5554f29630c908010560f3b20be692321c4512162897c989b0a44fb69b11f132a44b1afca08327402c46ea8a1500a72d0f661ee781f2691ecc3849a85055648b6c4e832ab9bea66c75b2ab4e38e07424f4264a89f258a42122aaca8e2babc2eab5f2b32bc7c252b59c94a569565b17a78952a7297da150a5ffe1e85f50ca9ebb17a655595ad2aac8ad6aaaabf50c94afe92bfaecb4ba2a47ef32c47e43a9da4c0880d1fddd8f037498e416af5d9588cc8f42a54e42eb52b2a3bbc3d2ad333a4b0dfa7e48bb5b6a652f33dbbb1c494753df5028fe7037bfdc538b8df7d67801a623c848f10fb0f7063fa05d47dfc8351cf18cf72847c4424b88fc55e66ef108055ae9b492da594dc7e972df2f0bd582dab478d2f5ff66b91b7b67c7a3ae421cc70b27c076f9e9434ce294c527031dfd5587755ad6d2bdd93a31b46daea1dbdbde4acb6550f2fea176378b74c90bba35fa804acd80a83182a453412000001a315000020100e07c40191603c4e3359301f14800f7ba44a6a4e9809c45910c420659031ca10030818000022202033200a0018d88f705b402782de82db08740af446b85d401f41efc48d07e8a54e2f86f4924f2f87f4ba26e839b845a0ef402fc2ad03fa087a1cdc46a073a017e17605fa3cbdfbe8359f5e1ea9d73b557d2b67f3a7299403074871652a0defe71b8ba6264d5512fb2e0dcd330244bcb7cd17958981f42d89652041db7df4808261e65175ad1d5143ba27c3ec92783365e7fe178f40883b5ad41b5c54a54254cbfaa206b04e1c8c4a0fa2ab3bf774e32b56f5e73085033f753849dfdf6f50f7ac107156a9de8383cf1c3f5de408d43f1352ae1d714ebf1fa27554647cff7301408d9e62f1ad8350225eea5db8086c332684702f062987100f9ef34d739117b9ba1dbd93b1fea17ee5e80e03742034cbfec9680d8a1ef650ae606d692fc17638f411212b9a78b7edc496f4a8699f33847440f27bdb93b0a27edf36608b1911e894017beb9849f682c8bdd34a346989ab788846b7fa94c03dfcc99bc73f0417eda6c2d57b30e7111d3abe8c220d0583ca94fe9f124c88d80abacfec093f40d290caecb25fb876f68485f34c8ce33dd5182fe84421f805382393a387e02704eaf1e7eaee1186ef80837cd7497d920eb84c6fa27cbf774757282ccebcaf404578b7e4e198eee9435b7e1bcce7ff28a0c4271cd17374746b22a34036f3e60f59e2c476ef764cd492f43357059c41b3183455160929f829c672ce97f238b182f77b3c437f4bd3edb6f3d769e2be7d2ddb5a875303c2ed206ecbd51242be920f5b2b77743b182291c880c37befdff3fe0d6fdf79ff9df7f45eed7c573403a61507de7cf78df76f79ffcebb6fbcfb867a67f79663f17e60e6658c1aaa2217d860915494d2c03e645650140a08e605e17be0b4f7f545be0921dbfae03ad9cbc1c83c3d8f67e58995e9bee69a959437d09c571b0a29ba77f6942837d8f9a2c423d0f3274ca19e661b88a9443862e716b8619b02b81821b588352535e0ff6693e6548e2672d3854af6b915c51a0a2c259a1acac4abcbd9f9ffbe27c9c2c4625e66781b9c08c1fa00e1dc0c8c24b122e1b7834051fd24879ad53ffecf64c43aa0bfbca57c7dfe725c6b3bb8c60f1ed1e8911426d8e7b84701b76f6528ee8abf68d10e7908ef85fdbea9b2e86048b961bdb6353483078c1a9366dfcb35b93428b6f05f1bf1cad305bf6d4ae27b043d190192bd994be8ce545f0a0fa4ec948649780d72e999de7a80b2688534df1ecc31d9e387fee243afec33d6bcccf7ef3eb68d3ba7340a0da82ce62db045965a42c2c5c4c4cf1ed492c770342d7b0e865924dabafa640816c5b2d9e67f8f591a9831bad0cec46ce30a049e95a85db08cf5ac3e140bf44c7e9a34a6e0b70d9b7c964cb611f3fbcbfc3f703f248130ed166578498c18622b46b93f3a6cd91efee13611f714d21e720f86047dd709746418b61d29c3875b8c1bde93e43a0e20b5ad45b8fb393d63aa8d35c1a27ef51ff5676acf83142a384553fc0a4c7519ad73bebc0365102e192dda9f679a93da2dfcd548a15f6485830bedf6b71cf23977cd973afeef4afa5306fd3d6084cd57f3fecbfd089caf06f60ba0e69740f6ab3a09385f6de5b794b2f200e04a408aca3640761764dfeb42c47c1dcb1f10a0c87c615e7fdeb1bd00bcffb2bb7bbe36cf433170fa41f09b2f22f9779caf365168a506d04f927ea7a012f38579fdd95342e72b00ffe1d6ffa3cafe14bfe5e6abadfe563d4e0e04c41248b1c7686863be62b612ec9e2fd8f47fbc103e5fc1cabf2ee95f55e4ef02c9f86d72c40034d59aaf60f0cf0e84b44db3f3154e20e7fc7c3532bfd386c0f96a2b7f0348bf12a0bf078410ce57f3ce6a0e101b0f6c1d604e415ff88d14e37c854d707a1bd6a2778741e002432436296e01dc8e0c1a069ee9f96a3e1531756b16c8b6b0204b9a126aca42e1cd17ec02501b3ab673f01b355ff4b1b87dd3e38814ca25cc57cd4fa81575c7d957fd52d794c1ecf699da8808685a083e684a11586831f45e6526e70b46eddc0ed91214e82ce5ab5db27c8f6a01ba4dcf57d3e9dfe9dcc20401dc20b23ff1d0fa82b7d1e2ba55e6c567aa3f4feea6c6d65491aacbde99e8642f99b95a053cadc6c655b6786b7ea2a07f96eafa1cb769909e36673c978b9fa9fe3bb94d1aa8752a422056192a7be01482f33560aa2090692a631e083a5755f1d7bda61e952089f0ae166e2b8cec1ee03c00619eee973647c640fbed21ad17fee0c3ffa38cc148b52df4e13e1303ed0d0377b9d1f3d45e538d31540f26580126bd1cc11863d60ab69d547dcfb05551e34585abbe4da67cd912789d250007b36b4682e2b97e919f769b19ea06bfa7d93fe22eaf0c8333087f951ac5f092c6b7243a2160d53ce048b8a74ba39f6ab5032ade0e8e1ac59b7f51d14bdee9897b5bfa67e766b70a0fb6759a49ee674870d64e610fea60e9a991060158c6638ce801166ae7e37ddfade966d7f3e34e615f8f5afe0152576d043bac8e76c136858f96df6bb058d1e6146508ea49fcf0859faaaf87dea6381ddaa64688e8e45b5240f91b64d38e0e30ff743c6de86960e409ea52bde6b44eab7ff42df7bb919ad158334f19f716ffe363c61f7da9a2d0903aa2dbeb0aeffc5c653d5a5f70a25bd235d62af20ab549a9f9586862b3e5479f04f6d8a5b7b279dfdf33505153e9a45a879c40dd20d6b3f1e74aa25f1423db57611aa46157f028c51526150508830d4bd4b0fd01e9eded01187f2aa2fd016f8fae5ac88d748b4279fef2b259acd3aaf4a3feaf3f0320bc36764a1f522598f6db5176a9f330e4c9b6519d94df1828a4c6caaf043824c986a2ba5ab17d0a6d3651992a3ccbf51fda0cc6316b467aa6dffcfc0f440b94456e376c9bb02ceafb01db6138db2aea19a7ce9bbc1db422866d585918b281f907db8930825fa6c9c77bf72b40b05a6de21edd2500f5809b4a8ca303b856317fbc5af1c0abfcfa5695b620b21fc68f7c6977a4765b285d304309a545531b533edaa7bb59098a56cd7d7cb91d27767610650c94d875cc046c436b9099df3b99a271c417e087c80893a91b393c4bfa148fc1c00ca6f47475e2d158641cb8945d1c5a2f60ec0c75d69f594ba53c5245702a753d72411f30241c3210bc7821278c1282805651c58e8aca413c9d244649947297a40951b515be085124a55c67f83a0a83af1ae476d222f4a9fd259f3bf01074235fb386c4c931ad71796fa6e0bdbd8b36ee93296719f02b66dec3070232e86522c1360ce8f87eb57bd85d647ff44c301c6f2f2dbeaeca6f762f84b42c233d9bbe1a6ea50b8f1547b6d276751e2e66c1d27a5826dbef9d7dd039e08bbdc72cb73673898747451e5baf9c2c45f298442d0418c5f1948c839f7c063337847e519ee296edd8a2a0b81eec945104b6d21e406cb40db83433f260fa42e4e38d840e09a8e62f6b015ab05db8c44bf0fd5a7f672f08872a1c70d27e84bef19a775c30ee821c835dad4abfdc7a0bd1a27050596359087274d26bdc56b05a22b7e87dfbfb07897238b16c60f2b7975413974b258923d71e3a02c2c0c818e118e5df825e06c70a45227cb3805ca4227b0c61c272fccc2623d261e9c74a8f64199240930e1ae01b1a92648bc6a06db8b2c2fa04b20eb0c9d4d4d17ba5a0e8084af57a0ad3ade823f994387fc690b3e515c4d61cefe77c83fe4ed53f8d9799efa38d421bbee08c3996ac7092426b01f39453f8878f9cee0d5d170637e2a41504285e20af34b31eba8327b3a806893e00c3c3c5a3af4f159b12dd40c2fa8e56982b9848e2fd31ee7e3e48b840020420bcff8830c7ef0a196f2cf664ad826785c583d69ac146051fe8c4aaf2ed4bb1b1312757aa9ee6af2d1763e3ab0390c0c66ea3bab7c035c374ad4793c3ebd9c57cc01bf591605d0928cede3dbd8288a6ecb986218df483aec6b0ceab277dd030c189d4801b433a4c618d7baa2125c21547a21c8e571690df7aa5b0febbae0707293d3305679d6ab84337ec5e3eabf6bef9c824ebcf4114455106d45ad77ad8c40f0060859ce9322937fba883e5d8077cdb683900387f4e48dae3a148d9687a638bd0960da008ffa6b781e5fbdd7f4959b920d23880d8388b5b56a4e51dea9cb8a7e7b89465c7359d5c1cb944baa07bb796ebf8882619b03d222d9ba34271488975c351a12af46d414f99334a6b5771a27212642ac2b196c37b763844260a16191def504475dc45781cdd0ac8bdc3195bdc0eaf3852d7473da7bdffe3a29a794365f9d1131799126e3517a8d66b1b4c43fef69703b9dc8172aa8314d21820405f0157676a3d456ce6a373f6c900a3ad2d868840535e01686137c6a2cc138ffcb1fecccd0fec35984fd331ca159c7c53a812bcd827a0918542cabfb6a6713110b4aef74b97815b17c16310f68f1d03335d1281111bfb03a8bf5ca32ed47bc1dc46ffaae52b00f3413d8e918cccc096b0da320d61ffc43b1965f3e8625b89aff081b9e44a49bd1e8379050809af4c65e02cd273ebeac276ac030c395f26b74f5ce5fad48b3d1cb9c1127e6bf4c309aa88ad87ff463be123608015839ee8dbc6228cedd84f9add6b53c960a9c4eba9a8cf953b1db26870dd285ab9ae389786c2129f47a1b182f007fc7d557fd8d23306341b68f2ec621cc37ae4d81019bb77a057b6aab4594429bb83502fda389ee88e173181f448665c7c4d14265155ec638bbb50cedfc1b2c66ad8c6fc82e6d250c41775a40ea483a6a820963ce93d237d534fb92cd7f01df28461e2aa82ec6bee2baec92fe9402ecb25a0da529d3ccb242857cbaee9ed6d2acb84d9828e55dd9f8630e588c57c8329affed15940dd33ecdc53dfc4075097c2ee1c5ef000c8b6a0210fa2499e506cdde8220a4eb181de4ad76ad26072348050383b8d1bae1af8bbe48fd21395f9da824aa81af2e516e2692b44b1647e524ecc920cdba3fe2e8278d8aa1dbab5b01e374a8732a3ec2d77a7b2e6bc0c5bba8c62db8471b157284b2b4ea5cd3d10125510f6a023553b00634a79e85a6d7ff5499398859031f0f4e51a750e8d802c803d26026e23986ed0a1a57c1e4edf1d94ba37958e57632259d83bc1c77c61bf0deed23db0cb07add9486343fdd9c09d382966728488114c46807723a0f0d6e11fb2e5367d1838769dfa7c5c8148d5b9f8927d7052134a370923840673fb0ad45d0a885d18a307d7c242e0ae9ea6ea2016f69543c446546b20a675e010a92ceed52025edd5dfa94614dbc8526d28a4ee669dcc796dd957715b2cbc8504ffd2e3f894574372feed820a7d6915ebaf80e088d4e92fc00f5cd521493877cbdd935c98b519f83f9d75502c656c9ac69eeba5fba0e8c7fcb0f5843ec298ca0bd4885b6b613f66515910690754db1a8b4fc98d847df3b9554814c599f0e5cc58f4117b58b1717bd016d20642f3d0e30ae4e10eb13f1d7ff669d3c414d87ef6929958c81e095618fedd1bd773ffac145cb60880a7b72aea2543338a46bea69339a3869f2bc87dcef26b9da5b166b58d5914b8792f872e4e51c61525256771ebe23a9fdad263ad178ba23d85f6ad446fb963b72ced453a8f748f1af964f27c324bda2e44f17ba4dc1e2e7f9e4d94400f6944752343c82f8bdca5794b71ffa6882bba15ec874d3cb941d442c54852c951c407f1f5256e5b5ae0beae913f71e97186d75614b6f9139c7c444220a45cf1cac62745791cc10ed4638dbb9b3a4aa6c78357f91f78d6076a24c0848810ee5bcfb3de01b43520140bf21076744781447be258fbec597dbf6332a2c6443f4760b8708a8805398563eabda7c3476e2c0294d4a469d9ef6b0ebc1c6d51a5af862f4bb55195afcb3cc18b67b65ec9bc71d1983386884aab42dc08af447b5b19ffbce50a3f61805e887681f74cb79190f80616121901638bae680033cee8836a0000a0364931fb1bebb884e66bcef3123138cf5c67b32a925339696f0ee494366435bbd013b44705a7156aa7dae3003340f8dca3f7794dc009d4a393f5d8a034bc0148af8d45d4b189fdd2ec73298599df2d8aca754387eeac7e875aa044e88b1d333391a86af2b1bf39e47963729f7fd337b174973d83a858b16e747af4aa7348f7d5914b1e51b93f6cb7c3548db9642cb9286a1d0cfd1d093c953f5b28ff3df41f10a3cfa52720116a3e71202ce1196e8b008d20ad659a6d7c4c3f58509af57b2479a142b0563d6138d111e50b59363b2344af70b861ae17a08ab2d26e0889ecc7f5e193f90cea54a7938497160219ac31440b95355026ee21edd5152c43b287e1b3c4a4b77b47c2dfe9b44a6b21b663f2719ef398e5aa6279758ac064015b332180e39d4c2e9265595f379b3ef21d124fd112b31dd647e8895cf0b977cfab9cef4951f3350aaac9e58afa3c5f7b1e00f3ac9a7dc3a09411cbf8ebde2f4ebb9de783919d8bf5af0a56c67a6dc6ed4c1ed1a33a2add2c34dda7e7c2bc3d1fddfe0a7f801dfcb819358d46f0d003401a370690d77afd51545abad8b24637adbd6b589a365576b03db2230eb59b0b3baf6a90f103228b90d3fd21af4c5cb4a9d16924cf7af096fc552ad33fbe640208569e230adad26d5e712e3389bebf078c8e5f2f774f905f2cb0746665cb5547bfd011671dc9c9831263bc8d66ec4ccac662738844d71c219f53585fc5d1f3783c995112197144c95707f0e6b466a7510c664b21be17f0ad06f657f95429eac1274e287f1547205540ce8de5924c7c44bb30e4bf088d4352005d1ea754461337c943675876434a0e96b9abdf06c7d2c7e1a23380b69cad4c1c27e3cb01abdc458d40b2b3090358c95b9f8864965b93affcde80332f79c0438469d7015b129d28692c810083afdab7f8ef704fd3e0f8d440cc8cb549518f2941fbcf6027f96c6df7776af07f8ee8b971a29e606ddff5738ab6a9212714d009ed7b53d4604b90b97137d1e5c9fa347642c979542940f5e0659aef00ebb16b3342967f9102fc76805b1bc85441aee9ef279a419d8a9744805771fd69be6954dd9ccc6a5783ab98294f98ac2e1ede049c7f0fc157bff7761eb03026bdf6ece52d17386323cfdf2e1b5d3c90760ab5b09efdd61ea64009031d3d7b0fca6ea09d717c12fb72e03c0133c4df3a68f8a2f66acf2ec74b96ea0152f30ff347fbf34ea43161494c4fd893cb99a989d07f4c0c933006f1be86a1f4d8471529211461f190361e6d742a76a3089ae30804efe52e975c89d329937d82128a58bbe75ff3fee33541a5920ba3fd81aac9beac73effe61211dbb4dbd79a8cfd8e002fd627d60f78b0a2b8ac76a65e53d1890870a78eccf0472a1a7c552df57743aefae7be900bba815ec7440ad4d3556e66c857b1c4e3f4100e0a23646c660c86362b499a9de705bef8ce8bd531e7dfea33369acbd31bc11f9d4e17e59204228601c5e0a16460751919c1f3d89540791b50182c150b94122f83a2fbaf5d5e5ca56ec5fb5fa657f3d7fc5128259068c4e8f6498ff41df7898312a5c3db274af2ad1d5f317615993da56d958ef173d61263338b9f583f06f853614c2891662b688349f73f33c565e628da99f3a5bc840a47f09d540dc515bef6238f22ac85179f3afc39155be6e479564f142a632a51af5238b88bec22ec8791ff40a407d8bf25ed0c086efaaf2f546da25d62e955d166d86dd95da6d885320af89970d3df7d15fed4703431c337c9761d5d668f698fbb0e4ceb29e13f6fc849022ab19d2894b16e8d66a6e888b249a8d9753a5cc2ee14f7c1342305bf6ff72cec3862e37086b0c3328407af1cb89d867d0b14f0109003a5514cc3cc098a484dc7035345bb7cf8058cdc79cc5fd51e2b9a16e9b9db416cee5c137d766f6e1918fcdd6eb4da9bdd2c5e7cafe1555b6c2031ec516eb5d2ff883bb0891494ee02ff2d011f36df3db06ff17f498da63e2fb3a99ef1867223ae905d7b4cdd8970a9f7ea96aa31c8434a3382020b0f219a844a1fceb59016d597d63805d9d9d85a4403a71290bce2efecac3062aba376a546064287b0e335de631420e3a211773fdd64c53e795f0e9c1a8cdce06c254432acd2ad015f46a2a560c64d5944252f9b2799155a4e91d833da43c2d057191e342cb808b0bfadf28709bbdc01a702e7263650c1061f15cf2228624857c8dccce1ae116da50e03697cdd72ae5b90ca2c4b6efa3d485a5a34bcfe2bde21da88f5bb30129d8ea6265570b1725fc10664b486231bdbeec6de8f0fc914477788dcb00236cbdf6d5119e4c0b74598ee60ac6c1a78223644a9979d2dbb7895826e7277001e75ffd12c57e9b9c6a9a583a8aaee72d6343dbfbb4e8ee7c67651409a486589f26ca193df80e1c4502b559bf1954053dd90d94e856502516e226c69d4a5421d05a1265fc5961d7b5a92c7509612303f1c6d7aceab0d30d346c67a08a7172e4144a65cf23f7a5ff133fd3d72772991173b99773af57ec65e8c31f81093e0ddd600b2c906a45a0b4a8fc21eff007a7f5c7ee18227d0a2502ce6544507f4aa7fc2bc58395a853c35f26aeb7c50af8c5f85ec43b46ae22cdcd7b8acebd01f4f16062bca9d5ca989ab89f185ffc3aa9ed03010750162f8e13f0f4a0fb6d9373cd814eda23dcb0c944758eecd3fd751e42d39959d3059f53928259a96341dcb471251654101505529db3b611b4a78a4c55e17a322ab1290b0f9bab594ef89e02f6690d1d80f2bf783a50e34d529108a30e85f858ec88b33c53c06ecd81745ddd868336112b6b93de0bc7b50ab9e4f2ef24c15c6860bac6b91bf2a0a6280e9bc1a60154805b10306b77a787d9b6df77d0186fd16f6edb100cb4f230ee692ecfb852ffb6a3d976d993030b248a32c21e08ce06a00b96666f354b1daea8693eac63a252a6d3cbc417bda364fe4a69d29d0a8e8b087ae8290d1c29df051a05495e7bd54f32d10790e2ec9e28745992725fcacd1a0af2499392bc1f879e2be015ecb9085b1d140e6d868ab37936ba764b25804716b9d83536a41f002af50214a899a44292d77a110ef27d6be7ae25a5b56be582d6841ae12666d3093f3eca3abfc0c1e1b69a1726799868abe50675e3c2981a68ddf8614d1f1430837645834bd8dd981047c1674fb57d7bccaca143733717f5d0773a8af609927e6064c6328379d04cc813d9a562a480c46038e5025a28d030cf6c41547857c255ecafc55a41e97334040562c45cc3435e6f3e5d2c23f60d9781730c5afb6a265ac4bb34532f9e7ad73de4b2d98c09b7cbd422dec3222d1ad36e266172462769cb0ee542eac4526bdbc32f89ea337e66433aeb3ce595c7d4e032b0d6f1d165149e4bf3cfd73d0a2267d0b3cc8192663b6f1acad38ae66d5572ac488a9bcedc121b9ceb7422ecc40c556cfb9f610100803009af0eccb470c4c09dedd0ac1c96070b0ef0de7a4f63f89f73f0915764d266825177af20335fe270dae206affb9b720c56afa1f2e899ac0f205549a124b00d58d19f067107b75c7966e8c86c66d52616a4e3292922dc1590f3c512fdd7eaa779d231f9b35073f67cecb40e266c04a45ecd39897273b36ee090fcd1a43c80275f07d4849893551246ed1c3fecc810f7cd0fbe265f0f9b460d50eefcf508fc645b1c8c213749d6445f485fa3aedb6e024db1baa6f96d6240659b92a34a9fb9b93e5588006c6e753ab54815343441f8ead2b06489505586493d971f4d31ab569b9971bf4560ba2535a8331c47f343899fd47b638cb35b04389b6d336f9c2cc578945d73794f852ecb8b97bef467e4da36402eab375cb43b6481c50bfde64a924ed8c507fcda13be98390bcd22d0e09fb99c74a134c1bb979f827650792c09855331500f25d5f6becf4b9b2ff3eab91c67426f5a445804ec9b3a5c6bf9829d4bf5789d5b3af5d922f2af97bbbcf85ea8b26bb5f4023845ae3bc07a111df24bdf022e5b5f1708ffb789a6ceb803e97c6796e6e1eb87fa1d5d967ef6ac3a0b9e440165ec6379986cbeecc5d0b7390be2b2572966be1029e599899b577327cd2c8ea8614efe1319ab8cbd70aace347c40d71626594eb1e746610607b049e2302633ad539d68e1bbacbc9ff7328effd9ad555dd6b6dee570e1db2a04224ce28c71b064bcbc438ba169b5bbdc0d18727af3c66d97978159baec3acd64700e6531611bb8c9b1a147fad0dbc8c06bfdbf3956a32967ef64714ff17245fe7c134eb63383334e0d45b4aae107ab890a48ca804951bc2c83195c56d2879481b6d8e579aa08d05a7b53caddb1ffca2bb01cf882976b463663f1a3cbea806aa063455b1ab22acf1bc02c893c4b7a97a51e63b3221045c725cf79c4c386da5dacd5f5501c85e178508d726223acb82fe4d6c5a8a49473981a33d7e24963f40d6000fe62cd38db6b6a39c11aca389cad231cc69fa1af296ef9333152f5802ef9536ae0e52af41a55f608a816c7d326476cf4806e31b6acaebf3d7a35cb6cc5ed685755e574c02d685e52a1ba39e243dafff48ba12fe8bcba4b54a028824b60e239f7bf546920bc87c51bfb7dda0ed44bda0313e927059b9877b6031a5db96d40992a3774a6c46c8568fa9161a474d67abd028257839697ae47914db1a39d9cae1b3501baf407aa91772bebf1856c02ed1041a7b70bd9ae5d6ec004729742e087dcc8c3c5e93d906c5dcd21bf65833bf64240471f566ee4e1fa7ae31c3b417cdcdad29b1e2e8ba57be171e8eac69d8dd3e11fda0f4dddc0bbc5e90d3ab6ae68e10a04520274acdb7db8ec0a7bd7807ee2e5803751e29154f7af0ff7c3b724c6910fbc8646783263ecec9c97c00b59de1b28c5420111f42d5e41356f8443caedaa7a56ebb7b83501c951e321fa36379c7fc11c2b9bfd81be971ef607224d46ce3832381c33a119cff0a10e32089f742dace460c9b7c4b3ad6f447ffdc4f4ff91aea283af3f7a38f961de0d5282799a5e96a3ad00aee9c884d0d2636fbdfa9218222c2f5fa0e90ae511a6d4e97f0576e4da0277aea160eb3d9e3f2a0305ebb4c9ebc42146994b2600e71b7e2f11a667eb331f3f4a55000f4ad535d238db64228acf9c4dad88decc18d28667ba3b5d44352d691ca712d608ddf7ffcc261083243b113bbed55d996c764f5d75d4782eb55b227957060d7b1a583354bd69ffcb010025623a4fe6341b78993f84e222e0eef3500b1e5024f24cf171a46bdc475e4b79a87304d6907102c4ee00e5a73abc9df275c232db06d04accff9b5e018911107599bbc748f4a4e5a01edb585eef9b0c7a6a095c84146f54f27b7293093e882e076582db2f68677655263c7f62fd6255ff74705f19db1c2be1c1058ac89b2e0edd2d95eeb7b8b26ffc2fb46894e0b37209047b36710d63215c4f9419358164a137e35791ab269e50948b64cd80e7f730afee187bf23529cac2b6a3d80babebdac81519f894eaa4505d04d62e1556bd58b6dd098348b1fc8a67382bac5a9e899a982b641fc9fb730393e81ad02b8b808f0fc870d57ae6b12334eb17c48f6f3cb7641798f70dcf44d9534fbec9bbe4f9b551b9988cbf1ef3fa80b934026518136ebbcf132d4a532085d845aac2ba595e5e752bb0c02c84cd53dad06413491a39256443f02adb8ba506ec19922fc1e84ef160d9820bb688311b33db99e0f517292d650d9c24f3ec936e0c68234464222f5348ad8d69008f9040512f0d805c1280282ae6d81660d00f589096b1002366e1c87e873942252e0c15fb9168e3192704a63122c35592809210e1a64bad4f14e3f5d6b5735310126880d68a44815ce60594c920068326a99bdbed7aca36c8198651186cf730ae052f1deb63939beebf9915a53b8e95ab58ef96fd318936ff68ee4e544901683cd759d3867d59ed6e82d76656c8ca55c7c95fec673b718d6abd07ca3280fa8e9cdcae17b668d2edf6d3dc861a52e4dffcd1f0bdcbfe81b83694516b29285ffa5c6a43a722be779753726f3baee4a9a4496dd822c51a6452880314992bafba4a1643e00c839a3c21626e8e0c4ce3b341e03f5dbbff68e00180c87f6c5affb804c327bd7e3154e878b79a09a5c5c52fb2d90a4db7623b684b95dbc5ebccd6a451a405cd5e9e5dfa4f4de404112d40eb600e227816d4be2fd6df6ca24d60ceb43b23d7b266d53f757fd9b32cbcde416dd85c8ef4f602eeac84dc1bc9badeb673ee9c66713fc0c2c337c6ba587f03dfb11de99340338c89a05680af811e17367f3f88ac52d4adf056a80c20e2f8d988f0eea9fa9c1c5aca689b6c257f2be280e8342ee633894367440a3afa67b2ca8fed8dbeb549b66ba955705b5a5a4b5d043ad2761baea0a7b47096d330b7d8c73cbd2b5979afbc3d9508f12ce2ceccb8b7d42f2faf5e0b79e7b42e1764746d6887c9a0a9679da71f5feea53586b465d1b2e6a25de381aed932ce42804e642e72c42e0670f003824cb4e65de6a1498ccbebe0f947e02ac136c7db61f71386fe3943c062a6474f8055b1c921da86747af490e55178957a7a30511ced7fe0c5b970ff032211219d40a1c42fe9439a01b5ea0b3755c3519b0f9db0e08199430da90b074b4044b48412bb6e8a3a40437542b074985a94b54c2494e96891400f49cab1fe21d3fc474702ec08f79e6eda3d02613764b7b59e82f3f7d0b5f9e3d86abdb2bcc345f0cd6b4238976b63a4cf89d0fc8d018844286d0b6224d614005db2a402320dad1bbd4d00c957c4c9e606dff747e2127cedd10ec147ad2d20fa6ccf05a8837524d2645afddeb40927582ec7ab4c5e8c18d9855fbc42a0b99b28cb248a6a351f5d2958c6baaf48524e7f722dbf34a52d39269ec82a480018364dfc157677c15a89d4a3e997a93a9b0386608ce13da0c076f161ffd49424365664fa5952a580f51d6d63140c7ba7721e96d24793fa63af5ac70d9293bdd20215c2e4f589f2f1a8ef39fc0333b0f4a2a2d274184698e100dcd04e8a1323f1e9e56878656ce20ae8436ea22ecc71e570430b389c46c7feff77d313d6fbc55fa404690fb0b3cf7549f8b3d89445f99099075461e9e470a4c73547c3ae380f3b5abea27420c3c3473ec4c1a58333602bd93cc79fcddae11faa626a48ce50977de52e2d6559537f65db9e22bfb57002e7ad362f47694ff37b7e26a13721150cf975e8322f57d4dfe91739fca18e8b929600b5bfaff8c40ed24def22097d67f8322f6d2745ca654e26db7c928296872ea10b2ca7d350b01a1359285f00d70a936529617d03bc94a469c6f4dd9ba0c316d5dec9b5cd3037e1a2f9553965fa9b16a587f891156bb86afead3bd367d702d98797bdf62b137ae3201048de715944f4144df27fc25a76f444411e974329cce63adc94d1f706b494a583dcf45824a745726aec573b6cc65bdaaf81d9feab864729fc5d181b78d3f5325a87e6c9769b6fef06384b04899d5a38cd3c35967cb0071a996ef4046bc6a4ae64b3e0c83854a950a41ea38d40c336825cd802e387aed51f79590f53b5a2b4d640dc674c27d6a40e7acb909aa560bd0af5c8c4d5b84b57ee40ba0b002a834f6054872f4ed66a398018284891094c3f1ba3751eaf0e0acb03831d9ef5b22e7986620601eefdb38c2a291357ecb9c4fce229449582dadd27867be66b95322b662eec7670292929837f3b70770a0628d2d5b59b39c63aef7914a81a3047ae709103664b1b21a5b0345b0e323ee1fa10babd9113855c1efecc649dcbd9e831562e6579921d7131676cea8a3262825b6818a79daa09dfea644ce06b64546d950c22c765e95ddcc7af46750d3883f81069aa9894641ab626b8a05591dc7e3470750bbe3895259942054b2f032b63455f0059274a8777a18ce62bc62815907f524d63d8e5a2acbebc467e2bb827768a48b4c43eacd409d449d6cc22ef325b16a662c1b54b32d232a857702b88ae5d3356601c5e97da601ea220ac2ae022080355b338dc1c6ef243eed35a36c86032ffaf70f777adb60da50a17c5b9e21575137028d40357c6de7a2effa9097a1377cc59577ec997f280b1a28706f81251bcdf4141d4facc7f44f438114bc09d07e6711d50808cba14b5b623441cfe805ab9ea15ea459bf26ceef78dd73325d07f93b2302f064efad7f93ee86f4e50b66f759524766de4f12371c919e272277be2e533bc93c7d145962d28430d66479f268c6a70dddb2be1ae757b11252bb20f3b9eeba8441768b548aa59e4945c4cb3a38d6f5504fccf06aea5046440fc95197124e8055a04bcc991016e11b83ee6404588b8f907d40eb99ae7ee0b411688089f94f58ea3438678a1f598439b50521b9489e0cbf131c4e14001896093f32ed1114c9ff08fa49d548350b23e3081a00d42651e004493207c450c9c0222146930c683b3f802cd7c7f35016b423f1c2462dcc77fa5fe9761c352997aeb861083af338d426d22a513184cb63c788545536bf808bcc91357671edd815babeabc1dd2cc7a9001b444cf1ed371e21766675901d42de19d88ee4ff4e34ed38c25fa94f06315dd2a9a2469f32a9109f48a1cf72d6e6cf73b53751aa5d206f6e4081a169a6fd64e5ad9ca0165d75ec8db5faf89840a5f918203b3d3f94044a2c5e1d7b98c55d5a0f49ab62297b250d5d4d571f020cc2770ac95a2da87709c7a1f76454035c26d2a731182c5c560b298023873259a883bb97875bba8239453004d49e1bd718d01c8b236438fa2ed18c22b006dd1550dbce37a04315f1e78297de26ee7e773090cf0fb9ce37a9db8a4e1df291e629c1f05f05e81125b36ed34917c22fb63b62d37b09fd4350d96941f080d42cfbf0fa919498366304f6d13e9a9ca06b3a6e76c13ff5272fd763d2d6e90f0eb95e42f8f60dd7118250a45982bec08335c5470253b3d642e4291a75d2af6ee8eebccf62f22939e3bc7c90999372ff857fb26b24d67619d6a0f91d6600bc9e5556000c31a5b09721210282af4a4cbe43e3c82d4b229e5ac3166f55cf568590cd6d77bddeb111cf5309a18987469615db660b5df1e72516022f346fb27b77b7bc2056dc172fe32192912b7b54618023035a5e7aa742adea3d6b8a9ec4ae1615fb728dcc56079a46fa65f116d2cf4c3c830f3f9b3ee110aeadf47256441e096422010905fd69793073b07be00cf242d1a2056efcd9d2ad6096fbceb6d6057f964d04a33f2767f88bdd4c1c30a38d77055f89117ff08f16f2a0c2e952e5aaf52f687e0c5d9e3d4a8da48c6cc005124df705e0107066081bd2c0ae27157663e960aa6d888868c0d8dfcc0cbe81f62d44d1ff1b5c0f6dced4f30b4151cfc70ee516db93265b7d5b2b88510bcb46106c2fe7c6b7f92733a1fae375ef453c4426985ee79159b98b57c775874cb03abfc3848680e25e8ac9d7b13c132b4eb0038d92b3e173fc038b36525d895b87b398db4bf6eac30ed6d1b13425618c80f55cda72044c0a564f17b4ff76bb5cfa95e8695db0caea4e18be40aca2f78dacd6c1cab348e7eed4334ca3bd07f740e097b5f8d37f346103e47f5d80babd17029f01f434928c8f0db6c5dbdff95fd2729f086368fec59f2fa09d9db1e6325f88daf017d502ebd84eb9e9cf2ad66031b57625c4bbc290aeb2c781e4e05d811f14b91ca84bf2fe44f857209bce7347c929437fd84dadb44c4719380db5a8930d99b7ecbfc597bd14836a2e7267eae7eeb9a680be7b8ca47c2431d68ed8f9ebcc5bb893e620418fc04c4ae8a0178b3b523964665ad3bcfefd95e770a4bff40bc567b4d693eb0950bb1846dc94336068c27522e9b75a174d2e9b81f923c38b70b36dd288bb406e21ee1b5ce74bc5a9004d7354ba33ee1fadab81c33d8940541f1301532f31dd61211d8e46fe38ce22195c0fc176388bf8d0db3cdd9ab262c5abfb997161cea52d5a9a02dfeb817ed4134553e4498f53d9da854a30c5134b6b5f8d5011a3e0725097c644ea91840c170c241295350c0d1ae1c78475f83784c82f34605d91eb232b02caed3341e8e17de56db3fb36422480b2ebc425f02d5f08d303f76dabf1f3a7df6b32c6d9520c89f7a49015cb68d469898223def9e96f882df1e8470aa8cfd8342e9011f4acaab25e45d499c790b7000ddf2d5f0f42b18bb4873603e5b38a0d0caa5c32995aad284bb7b13458a6abfc5241a7eb1b68d1d4dbb4d694ca232f94104b746ee9a6627ab8d18d2fb292771b122280e8610a83cfad99bddb842da76e82d71185ceeedac807f24cce568bd826f4fe0c4ec96059b07158acec9e2d9d7a972597b1f2a428b2dc25cfc6e23174de30a2db7a4a613268407cd7ca26100300fd17efa1b0b5aec4ee086dd4262d77b1d6d17641c8e616b718097daac3b9d1b6df2078d879e7f67fb869a1c49f6eb92c152da896509c039e9af1665005c8f8bb2179ebbd843ea6b1d9a9568b092ad5ede47741ddbdedef562e2bf9b66589a45918ca06bc47b07cd50f6c86c7f49b953d69283997bc9970c5fc94716ad44a49113fcb1f85768665bb2e5ed05931b5c735c545719d9fabcfe3cf8418ab8ea7521458be373129841185599a1eccdf9f90d44f652a8a8368aeb6aa245800bb3b3afc04d8de478c8a28b4a1107bfb54eea814d0e21df8df51463e4b7643fb62cab8554fb6668b4ecfd60e6aa0cf920186a442a286e168552ba0dffeb8ac99dbf12f0b24d8bd2521a257ab4f407c0115c9b10818ee1e482c017c9dd892296a0193e912fe648e7af7f1161bcccda27fa05c86995f864a33ded2fb1362bf210daf6ab901aa4bed1c389b52e913a33c391d96086f00fc6e4e4df5ba7f8db86e5030298498844faa08f22881db83a5c83a26c027261c5bae2491b226149f82149f9ece32341206b4317072a4d04a5d31baa415743073f635090aae2f8ce7d98b7b652be3d62d5f8f5d07291ba88b36ead73af0f12fe5e9e28807de326a951eeb16bd045d21209c95ead4e09dbd8cd9d959b3dbe5b919b6b3b1d38902705154a57b7e51c3abe32c671f49fb21fb0b6990d78307743cc7263bdb7d35816a16a2f283692d445c2593c3141fe27d25cd548d8a8db5c6e2fb60b4c0fe4f2f33ff664d113d1767f280a9ac681f6222c443c11d0eddccf2e2833b7ff121b6176c753b8877641b800b5ad194decba52b46d0f39d5e26f202b176c01fb0beccf66c1668a299a12161abd42ee6dfc7c01df98f7ea68a73981264cc7aa6618ef5e1d5e6ed8f18dc154344614a458e684b7784d154209e10f48104dc7a37d6319b40799af7c0863ec4efe2dda6e30b350b596a231c7aef3b94dbc4427a258e11919ea6e60be47442a64fd32a72822d1e2531138d4c34567665fa86d1fbc1156b17ea54a6ff2282a3140963ed3c3b7017dedc995bfb159a0f4f57f57720b1062fdba3a51fd98eb93c8acd697e7abdfa52998305e7d56cfaa643f9b0c0677e15b116404cbaf60e2a765f6909fa27d5e2434a126bf64291d307086ad21822fc98f8a0de89a0e04e17a2383aa9dfb5626fca90d80176d58d14dae62584fab3aacab3eac2f83dc79802d25d6fda40c3fa28538052660280379c47699f84765890ea691c13df0571900efaeb645a10aa230b83fa1f975782688dd34e74792f21a595190b1fbfd8faf98876b138170f3b2b1797524256861889486a52a1259236530ed44d1124ac8335303931b840e7beb1b0c1807a3a105a368178c409d19a846cfc3241c92273551d784200ed60a1121f6a481893116cb7515c0b09a32ceaca3adcd1fa4e1153f7586ca4e7164e10b380cd896ab8c9410b6c8abeabf6803ccb181e5929e180a7e9ac2499017bfed04553975ac56f6aa0f50e80845ef8eadb186319e34f6f0eabf385042258b9cba000b0b140caad7642a5008d28ac32f258da2eba596b61571c4aa15fe292c1dade851a7a01cad38e758ad8d6dd34664e1980c121aa017a0f05062f33818224c24466a3b633e7fd4b158ad836a8b7ce2f8ab7514986a7629d73ae6c0b92b70c78de6e0ac55c5d767bf5bcfd4e7395558ad704cd00d88043c30e89a26f842ed0613990c86e51835867f2079ba7913528020d7afd6254e609c593798b67a61bda3fbb56e03ee5058a344e2913e7c6a7191d3060122111f864ee76d26aa1d63fe87107516471518c05b9886b4cd15e0e24aeed8c20eb618f9b0ed0f9bf726bbb5d09502fe21ba03bace803f4467c2eaefd25d5de7b02017e50273d251d7a56cba07d28994f62a202f8ec0b51dfb534a0185b3aa2a72cfee0c30a40602172dde5e1c43fb67d05109dc80741e53325c16493b8dd6ca2179cd47a662c7e367b9d61f3b588c8c9f55e484c711fa840ff17be3b55992fd4873c1de05085bdde41f2797696cee1fd116f1792ed47a55e0a53c74573c83c30cde0cfe8d52493f9a6ea64eac78cdd260f241126497c13a6cf541562ee47a544f6c54b1c2dc6ad77721a693855cb8fd303f1410cd1ebeefd5c56024f48c49651dc837031073ffebcc9709ade960add9b32446f247445311aff8f123700b743434f5249f9f8c946497b6b2a2f73c2bcb28bd97149411000d662de7378217bdafbef49cdb7d2beef54fa22608479851efdc0fcfaa6e9c8845f86449e5ac86c9f5602cb8ab27e53a221d33a22b0e4d073196cf50671a77f6f77d8322accc6ba1a7ff43fefba25903971609b884e211f460a6b458508cf2aa8c0e62d28dc3367d231c41632866e9a802553e3e82dcf7955a1d2af96d4e53ce522505c7167a83685785d6139e00320ebfe839e2e04e77fae70d945b2caef9c99e18ec94c6acb36d21bf13510d008ea88da0138f5f11ddd23b3ab9fa21a04f782566af7d5783a237d01d03a1e2896fb5a3ca67f710dfbe6fafa0c4372c892152989ebcadfe802a3e46c9e2f6107dedcdea1836aa1dfbe55293936f08b605c726d9b490adf516d6f0ac9a7bd3f92d91784d8378e84582cdf0216655516d020ea6c660505870eb5e0c0582821efc9a9b9bee3ea126f599cafdac063be65c789b606cb339c03ebee45427dbfbb29926db710bdc9b6415cd918a8cbe80da282518bb66dc01b18508bcb6cecf8c0746d9035d2bd83c538b72cfdd0e27a04fdc24e9e830dd42a018078759a507be0d36689e9c38e858acc71cd01ccb02c76bdfd15b2ba89f911f3144dc6605e1181789c850e5062e67a15ca6289c226e689f929a17ed3a0416ccb1cfb695b7393f9c47e47dcbf7075d9a3005eea25e0c33fb7b6ab1fe73a2df65b3bfefe6f833d2df7d9bb0ffeb7fd53f256df9ea6fcd243be8f160e17af240d4978b2a3a4bbc8c6a2892320c954fb10e95e76fc43b171f0378627a7b84622d34c540114df8500d08c0f887988b9dba3ed57bd4c69b5de34b0baf08a6c9aa1f82ceb2d7e71dd5b39401bb98a6cb4907dfc2a8a744e6b7252faff7ed74e2d7e7ca8facb6e3f0ee3403499a02444aac455c8a68ed29e7909af0c300689952117b41644c2c0c985b7bed404a23f51c16dd0177acdc6e8338d19d624c5572d3482d54571c014cd7191297772131db6c711f79c895ffa2907a2776cb704c5068f1f5c551cd8f1a37a085ec0a0c7b1b21dcfa83e5ead778e8c096cbdfa5f20659a5864e24b197360263ad786157e3f1966ea33bcefa150eec902fa70fbb8a39b561a355f7accac868afd13b2b1235482f8c58ab3aa5b66e22b2b9b142f6006b6d022d917719bf785b474cf20fca0b4062ad0e24aa152d419e556cc06135ac13282f28a18c07d1d5329a93f6d896b8e8d293a0910d6e931732faf097b5f16964f1eb0bf638b8d1970fa168db83d5e4eba397c0286d064d1296a8b63e028c59225e639b6009044c8e8f18105f0f90f1c6cda4edbb1104b7f3928e2c8c732bbc347b6721ee0bc5bd333cc619244bddbda866e10544e4c48b73e99ad3b64203586799d894a506367c8e5f400c65f6a2fbebd1192aab538c2efed34f42d5e588387f164bf4f137f8fb2c43ff77ffec823c87905989cb63c47806fd4134d4cb8b3a95eca020cace3a0134a6e63de8d92de6969e56f1a10f0b91ff724f4b76d30c190ecd84f41d6e96fe2ed26218e42f1cfc1eec6b8834959cf1b68d41fb2b712dd9b5e5e05d07349c00d5bd25cbd91a7be2f3478144bdeea964866d37141586a9e3b0a914125eb10c613804a35bd0b4590c1e7550459d32bf29e4543e7dd6d9dc4b2b10e61701e46c779b71d35114c0bf504ff6e5c89aa78898856c7818442374b8f1c6f8739b691374fc909cdb5288a56eb70b43c54e5c6b5fe585aa95237683318d54d2306b5bfb18cb6375a476d05408f37ded228bbf176071cc8d9fd31d5b2eba7c2a9c2605d075d55db9d11cb4de18072ef4f1d5e56b03d51dfd2feb9e300f1b2a1a43825b0e91b2c81976358adc21cf44cd2060cb61b6158d41c6bd2504ca671ce76e527e1c2d9172e09cf3d9d5764c69c314fbeabc08dfa00ace804c015378f70f3d433b0b3fbdc5b5f1ee2fddc472c7e3f59bc000de0ac90486859a89ace6208e615204ca7eac0673534d0f955e3a1c78c2a77b8335e726a7e5dcca9184f85be23a04b9b6dfdfc06816aebce37f8c517adc197aae646813b54081bd92c653799b14bf86e988c5d438289b712307d8e2d4343b91156df30d3ea1c0c2ffa747d5bb1a3fc5557349e43905707405803b0733c5f746ca38f9117a1fd6cf92e8078df540c7f22015bac95693d13fd3adc76a49a0450ca1f698cf17110f6acc2ca0773fffd478f954f212562493b21bdd48b5fc0bb6a5fbb2b176e5aef1eca6d0592bf7c5a78c1360ba2f3cb4124057375fd91001f4a3cf0ee3ce0eae070c0fa79701b51ff59d4226f00903982fc79e4f0860c1fc268422e6464082aa40a73cdb5ebaaa6e1c1fa87673ca538fbb62be0b010386a7ac7041d113d0fd56e97ef6cc805a5a9ebcde1854586395ba257b2cda6c5e70a986e13f228587aca1b99cec684a9cf96ddac2b38c302ff435a62344d7f89f6524f876cf1a81b8638334818a327c239a7e1af070902600352fede3e63676df1bf98df7dce15e6c8f3dc28dce00511a1945f520a844c219af436b7aaf67775df48f4b0eb656efc81926fe230fe96a12f0c4a5609cb24564963d040a765ab6f9e585f8168a8e076a0e15ab8533b747eca1288d73d483492925c8536af587444c074134bbdaa9c1ff94fab3008be3810eeff0a967a09d544e86c289b44cbdb482162314f12807a8c14362e7595c95e725e86160de019ccf2a1969a9adea5818d06b4213e07dab100d90771c76cbdb05b8421d0bb6ff89c4cc5a8f2fd4d7daac17bb7d724672b57ec5f2131b6cdeb3037e05d9cb0ed3d6731deacbb5e4703457294fc7898a832604f5936da356b49522f5d9dd6c1e99fea7c5bbb25cb61a014241033c714c670c268deb26123f6d87c574d2cf8a951cac05a021c9f6dcd2febf8cbf1bdb9b50b115a0a1c96ebdc44b7d9838f9bbe00f03163e3733d39168a110318f6e6f9d2dab2f4712d03d8dfb14cea938a7e39cc67d1af7749cd3714ee33e8d7b3acee938a7719fc63d1de7749cd3b84fe39e4e7c5f5ee8709f600373770c10e637b4f0ebcbd271e52935377f48c3634d57ad91a1f534f9582816b6630cf1ffcb97bc5f66d788207745d52a46116807d3b2b60d9a3a3cc69446dbd2290c2738bc116f470b330d4d13d345734136159c15668b2373bf7f4978e6154dc7d166a4fa3a086de794d8d418429af82726dc53db2e8e7057a8785bf62daa0491228ab7f4675e2cfcb5dd8314e391358b51f9f6a291d6ca92190ff8402c0c63d3c01ba231bf560d1b2628fca99ec33dd9541267b66a1e5c8188d04ae9374ce894fe9d84c187790f8734cda5fd9fa23aece41115a9d5eb9cb46ab4f1a3ebea32ad41c2b2a40cf21f9867c21b5ce60e46f8562d2bbe1c2381c039b8555b8481675ae1217ca0dcbdf0d07c468ec58178aa4f92060314c27da2b755cec89fa18ac1566d549d468da63294ca4fe245a5efddaa218e4e3d1c2035399e077cec9cf6ba4b999fd35bd846cb81528a2038c2b95747d9dd6ea6e3fed9244e24384d7142931697148e1e07b804e6b400f2c0d2748629c56922769363ca032f18ef22709b8c52fd11afa9d1fcaef52cdcda0672b92400449d3ccf0f809a2905378b0937b8050389a73ab97160830c6c35f97400c891364d091c7942bc3b08adce35eb29ec6887c811c505fb7cc7490017110a360caa3489ac2335ca16919a62c6f77e76882e56d6288922622a7a44f527c14224778646f509c1218977fe727203b283f5bd5af91fa83b6939bd1bc1750bc3a19b65f504f558d901b3625845693213b82bc0c75a212071e01fc076371e5e97853a12d4507f1a83ad30f62c7dcc1d7fbaad556e049f799a845fa103e6475ed53401a0418dd72f9445bcc62b35a7c456355eb99e0a667b9bc335ec2f7b462e8d56c29f13e60cba277fb34045436a91391c418dc7d1196d6d08c5a2328ba28e8c620f7c72f03fc895ee92c819f6c04e2bf54d1f801506449ab96f573981a0e9cf200d98699a2518c8c162aadcbfe0f6c2ee7566bd1a3af3bea0e2423986bbe44090a78b4c1b52f5254639a8bb794ed6058973441b616ffde138eb38ccfe1d90e189143f7808f39b5fafc9da6555080d044b22331e46483467c2282ff9cb97de9bbf98b1c1d7ea6b1c8b0e71a9beacd85d3ae1ef5a7424d7ced875a983ce6560e7690d2bb64d948f797d5c3136b5d366131ba09a06e580bcdb12b9f7c3dfaf161aba17c6a751e292f8fb867caf709d6bb49b31b3f632d8df8a55b6aac2582ce798cfda9ac0e53eeece88a98e62f3297204c6a10d39bad9131de8aecc19de2ae4fb4ff8d970f7c92c0bf8b39bc95eacf11486d2fb2854355f9445d79159b011f4d51706d755c1e76536940f7aeaf35b1c8dd4b5675df1e5c3f3bb03b4312d5637e54b458a1c0d84a722cd76557c248d25ddc5c6eab86a27c7d4d75fa558d11fcd65af73e72dacb4f705c7ac1af2c903f228ac688ae346d6143d4778d8419d588c207c426c376072267e52054b7041188950a03ea11d80916a0a79c640344e5c4283d41f1e3ffe21491a0193801de5ddb7d0ba091f51b81b61511436eeefa22f6a5446e1c3af058ace3073792a9c0ae68746faa36bedd58ed6955ecbdbbd97fc8464c8b093acd59bfb66a7fa67e6421f53ba61c66191ad0524ad1cc9e9733abcff208c99c8cbc32cfa52c14a868f6b68f7b5304bf3c643aa5aa893cb17c4ff2a28615db086600f94bba62b9bcfc3b16fc29c09b1b9ba04845d102b724ba4af4a96cba98444b43a488d462d54bc0fafed17d18fd8f13d83361e2d37e363c495d3d65656bb41c6b769a38b80a5f83935eac55763e0d376ddbf7207f3d2e163d7682bacf6885a6ed34b887671b56dcdcbf190573eb15413af6096f6353e17eae872b27174bd9fe4dd0c79286ee881211c95cb03c40c1723dbb004761f74b82572044bcb5808e8186992eb17ab7824680c8ab628a0b6a97985b64a1b48714f432d212bec917befac558501692b3d935dda48ffba83cf71a825bb245145107fa4365ad1a588cd5dba5ff4cc52aa3f33447a1eb190a376ecddad69f97c7c882879724fd94674cf807be4c2a3d4628b5381e85646ead7ef8d2d506faaf39e5cad73159e2d60d7f352bd8ea1a3c45f4eb56ad189ef1fde8231c740026c803d96f588fd02acff0e4dc7ed3242741dd744885aadf546ecafecd9a54344eddbf7bd39a7d49e551f9b9a685306afe7fdb9cafc1e9cce39c87ec72db557cecec4e1223ff0a86d5279951a412fa4840a1fb20274aedc9ad9762070c2f39159c9bb268a180c2a0d1877672eea08b44e09cb1d2e56c1118c787eaa267997b415e816ea5036fbcc6be5ed92ad8e67d935f291341aac02aa3fd5cba7957aa82f45b323f15d53f88332cdbb188a8f04f789819815de0e69f416afa2a378c71b19ed7460fb598183b811ade511139a45dcdcd33b81a1b059c45071bf7ff7776261fff3374a77f646f04ae5c23cd99e5d55ad864d60c4b1f318ade636c2ff1c9c89adb6dc99e9c14455363406ae18b12648bcb28fe61e4348623ef45bf89e474971bfd2cc0790ce94bbcba174f311698a1cf022f713dc172a69d1cd589b24aab80ac95caa8cc5a5ce8df5248c85e99191ee6e5644a49ed12420620a2f9d257ecf382a84694c1a644ec6046eb46c352145a50389489e826c7ad4271fd5acfd4ff7bce39761ebc1b2ebed8c399bae1c9dad16e75f65c2de00ef86304bcfef8c3d30bcf2651410d6ac446ecc850685b4d312e7896bdaf14b7123f595ee468a2fabc88886f42dc891bf24ad2bef679846d7e4460e7ec688c49af70f2489bae8e61e7ff563450c60a3d70845aea778849d503f071559cb0f44a4fd6491a9069baca5acf0eca2be539f23a51581cd669c1425c6e083c149a257666d9960b29909317dfab7013d3fc12646ea268e0c398027a10194fcbb609a0a305a0c1ae90b602a44d6f57bdca116bd2e51940d7b848a67037145c4fde6017545faf3a304e79965cb291aea058d357ce1d9b2f640e0f8371c8050ed3a763febfd86329d9780e5c20018c16f085bba5fdd1a941531c0265604e8e3e5c1b871de2a652482fd4ae6b0a71778091cceef81c18b19d0bf19acde670f9d553d0bc6ab9334b0bd390c4bf93ab0e2edf5af89ef32248819e6031400a40500eb6a143aa40bdd64376663430f202b08927b1174d89f0c2b7c2b1524b73cf036f400700f4e3c08fe4c6c0682d0e09094916c334ec2f8ea0bc94e31ea7fc15f8714ff0d8f0f3dc32c3da72f8a75c347f496e8643b3d114da82861915c13b6a293b14f76655558f0fc5fa6cf7804faed2ab69cdbd10a3e43b8bda385bbf354c5f43e52b21ec78ab76a8d95489947dae75b22dc8af0a4b73aeedff00be38d4e8ceefbe8375c9852f769b563f5cb770a75c0f92ba9231fb92746ab8024d531cf30bc01b5da2f8cbf1fa69ae9e365caee62a1aae1583d4e52425ec135c422462b696343afe09995c0a70d80581f1b1123f1bc22a5c488a28cbdb7f73009c170268f2d8c23a402de27a2aa022630a4dce79633c5201cb669ebdfa5b84747d9a9a4940ecaeef0154b622da84fb7bd11ca70e75624a542c5beffbe775b823e4f3f40a4ad969aafa3e6b3cccbb68381e3b8f71feabf6868112cd8a8006f4a18e6a89ec45f4ae281cf6294522a00f1b7709feba5675d0cb2d50d5ba47c9647cb53420b1115f6b83f38fcc1a67ac0d26aadf41e9c0c330910e1f763c2438faf070cd0d2e70988dfde033e698d09e8f1cf4198997ec604cd82d8bd0cdf0df152d15895259e4051628cf84856319840d96a919ac09e8dabcebcc9dae4793e4611b84dab8923f27533d76641cf69110812e027cae0a33d640f1571047cec3a87159caf401c1bef4274d0ce026370df71664043dab2f2879952aab6eb614505d8786409f1890a250c8fdf35266cb4f19e3fec10a08f2f26e004ce0cf0f8bf6fcb794f404380e90ae878580f7fe8957256352605e96185ab586bc1e104a6b65ecfcc1fd43c2d2b852f8480ce06803747f7866c18bc068fafef5c5a43bf11f96e2ce3468c003c236ed509b8059fe0df1873272c1625bce2b3a6f6862631a96e4abb02f7085853dbcba44b4978668398efb3312f6413b5fcc60fa2bda9bf11d08aa182616288a90d1259d192a6d15b7036f991075aabc02b98f894548580b8852e60b57ad88f5978d3973754e18a8cbde42837283807e88c682cb1a878048584d3788063006f6bacc3d6a517e086a03f5f977f33bbc804c7737db3a141db3822cb72152df12d4ed1c1e3a8622d5b723d7d3886f5032f3a4356d607229815e16751d20f79c649a4e2ac8813a804e89de01ad2011abb4043e2c59ad2b8e16f22e142af4dcabdfca7a13ad00e57b22ebe432a58fd52f914adc3de03f018ced61dbb0772d43ee57fb23e785dcd9e5cb12159869a72a4b91eedb8ba024f36004fa3d8f5c1baeab13e74f2ad00279a181919013a9c3ea29328e012b18bbf57a8b84c1ef0cd54fc1050669dcbc8cd0efedf0870daa155151baf08e0a71c55ea082812dc01d26e43bf6a526b95f6c4726cc2b90ed8cbf1989abbf247a8d9743c06101da884de61b469d1e5c43536401c6943e650b5fd1a2cb443cb8103e81db1079c398f0510d15be66be924690a00c5c3660f9d9b71a7d04027d861599fa405206915b0d2c021ea01bc75df1800616a73f2d892e507233a21d4beef53f9557f21b699a6e883aac1cea202c2d7a73142002daa00fc438ac9679ec32b80cafb7947282681de30761ac72de4fc0ba3800cf3de789954a0b1c3e477f70975312ae598c3394171b6469b60e21b01e04b2a2deb73709b11834b105ae41d237dbc23a95af7604df67a518c896859cb08da92ffa9793c3c3bf973d259aa7f80305f4f2ede20a1062ccd07c3b30683a26f93e50be6e0d61b2df08fc33db2bcf29a89a957c647155b0d03ae334bcf7d788d786e45eefe6bdf8da74c7e7513a394f583b2460b057731135313effb3209676069b140418e39baf8e8be49af76bb005681b6b477bbdd1ab7a3bbcf76b95d9887bc56add8cc9caac92f3b0aa0dd879bd350ba6c14875a5a415e5a0188141776c3f57209d2d0fcf79973bb60732182f628b8aab4bd454d2a4ccdd539a6baf2192d142d4e7ad1b890d802305a2c2f6cc138f70daa414d86fe277fca43a886b0acc88ad76117d7a652d71c7934b7c5f44cca6db27eb33ad85ec710c3ccbeb4d979f9dc927408b7e98ccb898125f31ebc724369ed08fb92521651bccfcb7aac13f020eb5248267a8287e0e987c4cc488d32648ae5be0040064bfa17988b69150a4f95dba92fbadf9c14173c581924b7d1586e35c78e9bc2c5f64eb894eb09ba45a6b79fc0057bec6ede82ef0bebba6b2fe6edd03e0e4170d0632ae7ded0aa8859872e61941679e4a4884403421a12a8f01b4b33f4dd0975ae8fcae97fd8b57afee37d25f2be76eae31c7043118381a4765dccdaf328a362ae207a22f72703d7119abf6b4e8dd3e0c478f855e4c333cbf3630ece40b55faf9af97b67f6d5148f18363fd726a8494fa2bbb02d4fcef8d80a756c833d5117fea748b18edad912dfd1c8c0ed0b20d64783840ebe62f6d499ca6dfd805b2bc9fb6ff4794f92b3ccf694abaa6ea7dee5dd6fff9c598e5fce1c0a9383304f9449b2bb4382ebaebf358fc066cee5e95c76df715d09ebe0f549e485dcd6dff96251f22885c3734edacb57f6276ee413973d31ff88c1a91cb83647e00b85aa66557ae62415c5cf80c00a27e60d74cc6adcbc29adb11ff4084749419a2feda2756ae33e4452f9904b8f8c7be46c2e49dcf2bd7e6068600e7d59d51dbb1e5a48f1d8443f701c30be21dbd3fbc3bca6a51ddf89905f06eb4a2211a91b67c3fa6c332c54dfc977ea2a7c8357db43e298ae5b160e17103380e6ddde435b02a888407d8838ad951141120701746a0bd7fcb2cef5051a12eb5cb1eddc142c19b588bdcb16e7a5e72bebc21faf3f0fcebc92bd5a10ae21a8837cbd3f722dbd4511b6ddfba2f49c28bffd1fc74ae7156944d0e408d07bd21e2f86ccacd9ebacb59dd2c94a784ee352abf21c57dda4bc7534da36c7411d4e8de2c47744f93103d89a0029144cddecbb10ecf70ed1bde433201aa36bfba9f5db51a7218521582cbd5a5e7aec4254ab4402706e636108584e4df38f86375817d2563c2a5886bc8f307bb1c4eb8d14fc796b0c82bb0f026e4ce7ecc2e2df3a3000316d5c6f5bc7f1c76fc7b7a6a20befbd976b9fad3a3af3337544663dca2b0c084103c7d5211d57a5d3233b6d4ff132ee21363926d655a95c64bb6e5773dbae26ca6ba062f71c09226d5d07b030c632e9b7f54dface88c7d954149cdd9a9090f1d2a77ff4febf2b746996dddb7f97d49d7b574a825055cf3e79b43cd8de9d87a58959c6bfc54351d12482d58c5fe793b8ca850895eea0081a1ab367d4d0098590acd8d7ad950c81b3c7e7fe571c6640dd948dbae1ce651ed8bb32e95ee0e402d0da7593184e6feb8a8459057f566699f3ceabd4e20f5e32dbb4f6e511565c2c62a31a0f68bacfde2756802ef7dd102344baf29225ae9cb54c73a2e885b2623df681d90edc2f1166f26975ebaa7b3e7fbf5c9a2b6dcc7d9a62525df3651b3bb10319a2db06c33434082a718a8ea4d82977e94c772d1e7f02f5e315937cd84519ce4e5383de51a8bc68fa0013037054bb51cf5735f8a056befb4eba874628332530c695e2d75fe4a10e01df8fa7305ae2d6d3e0faf119c07d81408066429efd858700a76e124941ed210219f5f7cc630aa217c0e8122f2e8acc9f1b792f87d568fc024e0c649a46dd6acb8ab2cf0aa3f7add3c8862a30e13273510965ab98e6ca0d2f32e489d6d063a2f73f91cd84a4cadc6f06a90536034721c3bc7cf49d400e406eafd532e1a95bae60297b111508a3b3c900466f5a9d156a30f18dbb5f16fa594c7666fd5ee3fe97a47a11328e6a19ad7316e426db8e52d1b9ad7659fd82681cda15e06d4f836a6cb632d517070ef82ee38bfda901e287208d6d1e8906443a054384284f30ceab70694e97b971fcb40ce6be339ed2ad5221d40f4f9a1de5bf2e33802c38119763677a044236117dd45618972b4145fede89b639cbcc47e5377279c05a6aa0a3539be0e9653971fbb87c74a08209388f470d33273a8cf86e75759f40b528b88fec4f215d09c40a08d2ae4551ee47e6620f5dc526a52d2d6173bb2a48d1808062b1211fc5e5a5ac0c573efbcfc659d21d8820248fb1498a6ddec1414dc2ea39105a4336e09d6eb7ab19b949a9fa0e8ca9719063dbb27a771fbba3407127e55112fc7da3c1f17c319cb796617f55790d78586bc7648ae011e748b5d1492d4b7d4b5a088fe9ff62fcb322cec1cb29bdb12e71a4535360ce6a37742b0cc69d47fd9058ea1d101d2490365561b88bc82a3f7f5ff6b0eadf36b0deb6146bce1e3af3e8a809898b9ee79f2825da28b401dcfc678dbc5d9043fd4753071c37e916cc1048238f1a05357c1bb956d6439b958b5dd10d2a7ac7fc10a6ddc56d8540c4101814c1878213cfe3330850b5bae11f22d30d0265d2a301b6ec001a019d2f923d0a2fdb098ccba695f8bb4ea26b7a8248504f209d9e807b3d014dddceb876220e3b4dc1090ed4c66bd443227358f4e3b697b7aaafd51b0ca3e42cf7c57534c0e154400de2607d17d3ad4214438ac60ebbe92d31853391c492f6b209bcccec01131c23e098d333cd927b4b74958504ab6e7927088880f92c5e7eb01ddd28d3ccc4280ac4638929165559f26936f718f0ac0599112cb6bb66b8138d7e80cc9cd4f93733a61e040f3506d014663c91ce46a15bc5611553a2000d36e4810895e9770c5c924008da34fe99af794c0a15514bc9a79573e37d27514f061887590c91a0970c2cb2f97a1e3b73df3a806cf29efad086ba5c6bca39b4a144fa68095984b922bb91be21ca3f784c79188defd676ec8ba1f8aaed568b25211702684700f18bd358c3c82d33d281e11a8e5026ce9c5a6223c15505f5ead45a120670bc621ab554e1ce6b8a3b16355d45d52b28582bffb110a77a19f440b1ef11a57c589e312435c4aeb3de82a7423aacbcfd3a006a7a73caa5b61b6151a5cf322660c183f9febd8eda86c8b3bb8ffd368416a22d5631a4541ddbb96d59aab867092f2a1ff6f2371df6c963595a7ac36f5f20363238cc37d477f3728ba4547ed816c7333f8b1a4fa47dabe0fe6f56bbab7235e5bc3949b0f342d6949e877b717ab8872a935462b40464864358222ae6fe87bf8b44a542e84e102e98072660ab8b605018bb69ddcb3f06cf87dfca9b01457893b0e88545f04d6b21b5c4cd26d218fa84a55ed2b6bd446dda4e03c31ccd599159ac449162a61d8a95e9961a89e59fa717ea8b46e5604e5f06734fa8fa12cdf2b2e0971eaddd91d4a2897fe01284a7a4167b807784063a4a6b85b6f25e2f1e0462f1b9794c537de8a7e080fd2eadb40881ed1b76bd26c93ebc604ad4a1250d171580ec543878f74a249d25dbdf9433d4a33620473bad7b619d5ee64954f115bf6766c4f2e1b7296d6fc7b562794a785c25fed97772d9e4890f85adf778091263c5f26baaa2a29379f931f174b6f21887568abb5284eecc4f5a5eec11d36784da0d68a7f41d1f9c51e8b6864f9c41d7660699e64fb8ef2c3796d85d307c5fed825a9e5bdbd2eb7f484de2eebbde17350e958b12421116790cef8c9ae9a15acb88c09bd52fad578184ecc1021a531a745d5096554d070102ec81b11c9cdf3a212bb293ceb011e8616d71c01c98d20e8a57a0ed48fbe415ef64a365cdcadca906a6a84af56f937f0fee1fa10896e5c2d2f06a85cccd015397cc0c59bd15d3d29a55bebfedb6f7de7b4bb9a54c49ca5c07ed06030730d87f3a9cde8aa5f91bf07ef80721714f2fd2333fe4b7ca889b209eb69fdbf6f4660ecc72a6243ec1e4cf94cfc982022f7b0acff973243f483855fee340cd82489abf84ad019edf39c0f3db073d3de3f3e5ec9fad576d44c689fdc498bf5482e77c27d2333a1d26912df9817f61f9b254dd4855df78cdec9e1efa261f133ca7900fe9703e0c06bcec9da467b27fcb9988a79eaf6196eb21bffbe5377607a37f1ef9554d3adf87f44c06c2e850ceb7d6f35aad1cb65f602bbcd37a1dce20134b159edfc4b226c6d7a3df411e3cfac74807fdd83c7e4065f7af9ec8076355c0d9e16c0a44a10638a06768c0d73f0c0c1110be8afde370a3c9c7f559069c5fc017095f3a38241041d008dea019fdec29ade1400471d12b62cd6560cf6cfacc66f61367607e007630ce39e79c2a1d661f9b88828f6b86fe65eda87e2d9e6557866518787939229ef5b2456c40896acec8f96b7eb9f83e3d7237e43b98a51635df72ccb84e3c1ff1649f4692fc6c05cb47397981e57b252c5f74b16b67878e2db8599c65d98b6efe157006829ecafd61068e9fc3478724dc006e075e963835f1149fbe14229e86481b2a330c7cf5d03354898f00d0d883593b69b5f6f278f8b096d25085045e1e612fbf4718b82394353960fe53bd70c152ae7051da2d9e1acb2f069ea414a6035e9637572291375af046cb1b247eb3517fee518339be434aad4acaab0057ac550165bc32468c18317a7678e5e9aff9266f1e456cb19c9c8deb6443e16c5cd7755dd7355b5e7e813f9fce393fbf8d19b9d91f9b80c290f741a96c3bc1513f1076ebfa840511f8a6e0cd39e79c73424127a594524ae79c94524a29a593d24929a594524a2935821661bc573da8f07c0234be8ffb6669711352342105133c7f8673ca0c4b1416619fa40ce7cf39a3e77c1621bc99c369e7873c7cc4538c2dbd9b0ec5112c168bc562b1582c168bc562b1582c168bc562b1582c168bc562b15847b8c6cd19e50e11ea2d71467eb44870cc0748c6f8b70592282c2563be9405ca56591219ab88fa11c70f2b42c694ccca4d184e4a7e9fe7b9ac98fed4307d0c67b6d8003bd6baae1b5fe80763ad9e116261ffcc883f8623d483fdb11cc7924c6e3209000078d821c5078d0e3d5478ecc841c7490e1c376ca0e070830d5854a3061a66f068a04e3270334c3332ba1831c0f0822613e3426923b1d0028c172aac1062198c0bf0bab478f96a5b462c585654acf8ae000080871d7cd0e8d083c78e1c74e4c071c3060e37d8806bd440c30c3450271966986664c48801861764625c28c168810552b8820a2f605c80f75f5ab8b48c58b07c2b54aca4e8a8ac4c2358364e39993528424129de8365e313118e77e244b01471419d48099698d3581bc781b987603e99a68159e654a9c292e70941403e586c8265e35ae3ce05034b18b124dfb17322882619007c9e26e0e1f34c6287cfb3053e1ae5fb5d8a68ea81e6f3144287cf73881e9fa7067874ca0fa249d6ecf8ec44c8e1b31b41c76757428ecfde04b767922c1c9f5d891b9f9d091b9f1d0738f4c9f7fb05a249eedcf0d93960c3671701feec26a8d15d14d124856af8dc4ca0e1734b31c3671782468b6c104dbd427d6e1d9c3ef70f64f8dc4498f1b9937409a2a9759ce46ffadc48cc7cee15e06e25627cee553c7153445307f50470f7055ef8dc1c90e99743f194bdc77c964fb8f059465182d15a2875206dd0c2671903dc2f5b104dde7292c37c96372f3e4b245478a98188249eec37e6e2b324424ee07e8e53fce7e804dcbf80689a292779cbe70894e3132d3ec720bcf4eb8839e2a9fee8734c3203cb671925dc2a9f7fe5338b8acf272b5e44d3f4818927fa180e67a32d00c06c790077007d80f9a50737451a5007307bde23f2f8f300f38b63a91d60b63980d9d35183a5b07f0e30bfb805c201667b03cc9e0d963f0eac1d37d9d60d60b636ececb4b07f0d30bff84b213759550d60b63480d99b01cc9f55617f1a5268e5a61a8402b33d81d99301cc5f10f69fb1d27153d53181d9ce80d993a1e31f23c84d751503982d0c60f65ea82bec2fd341d82fa118305b17c0ec95407f18de72d3b5e3406eba584ef26f01cc9605307ba4967fd8b29e0a60f65e80f9f38701f38b5f3593c705985f40307f37e5ffa997d962ba4c30bff84f1f0cc74dd4c649fe2330bf7c2cc0fc792c60f6bee9635780d97a2ac0ec3905f3a702e6170d255b6533c870b29b8ca504cbc7705e3e4f4505cc93856f630f4ba98085ad30d51c726281b00a603556c806a1a080d97db06cdc7282674727476455f605f6c6b2ecca7315965d90cd80b5b135424db8aa538f507d2a4fdde97a07cbacae668073c33aa209550fd454add93630b74de36c6709403e3c3fd8c5ba6e70b52e9ceb2693adc6f636d6aeabe622c1a5ba52b248e5794210908fb58dafdb58a3373cd069e15c184e2c39a604c673440f5638506126584e20134b52db603c1c8cb3e1cc08196fe94454b66adbdd5048dcdf3414b42dbb7db025b03f8b09bcfe6c252f8693ad6076b0bb11b388f7ad56d8b39593bcda195eebd3f928637ccab409c37192a3620d31949faddc7443dc49027b0e58d8459b7cda204c112f4f1cecf41fa0f1200f50841125306201012c97c57f9705bc439268f114781bc06721d2f1e49236c99bec99e0fa83eb4dcfdfcf2d82b67e2d8edd2ddd9243dc026619d4f2b93f3087d8e5089bb7017cedafc4f70201a2e5378e86dba1bdffd55c5c3e729e73bb9544a7c5f5149126491f76e26976d721dc3588c42d2ed75adc726df8f788c56d96dbdf6d2557c5ed251dd65fa9af72bba7c3f6e9f0c7bbcda4839a08f590d7f810b7e990880eeb83d753aeeaaed9d76f2431cc5abb9dc059e25ac2c03aa79d56894c8c1c2fb7dc9169319183d333d47234f41b27a745311ee923817cd42b2fd0224cae33eab7aa0ccc4948c5b1c66711c5c5ac7badc3342ddb34ed4a6cb5aeebde7aa227719d9ef1264c70adde83ab2fc1d595e0faae52a954eef5a336853a1004c10cec0dcc381d192844e3364d522394458fb4e9ca6952a548bae66b49125c61a8124c97e03aa30999187b20228c6976da69670caa699ae633853c3bc353b6a378d15174141d454711836a1f69ba0ed4345133098938113ea487ba89b76d1eb681ad83598e46c3b89a59eb79f67a773b8dc82117ea90bb38caedd0acb5d6daef69459ae6289c0e129e463a9cd7b12cfbab9f7be7beb32cebc7fcadf5c17edbef974f27f61cf751686116706c220a44b00dd632b0c22f6cf3767fddf95abcd73b96d2729cf76c6f6f4ff5d4ffa249f64452c5be3b9e224545dc7e399a76771e1d6222acfbc662832d381d1d2844621198df85a3f1c740213264703a48981a61b180d7391db63aacd90552ff760862a97edffe408ca94f6f1be911c898fad86d11749139fb85d321c12c9b73bafb9c73ba6737cb327777f7ac45767d77e96739326112980878d973382c98b3e7c0789a4226f60722e264f76b3ecfd333da246b2eee6e69bbe7681a0cb7e77e93ddd712b13e4e0d5a39d0d9913cd7755dd7755dd7755dd7054462ee5d381b97eb38d84a7ae7c66bc2ffeff3bc56dd58eb79b5b51e7160168159f66b75eb2e7de709128487553e4588c5f3b92bc4f3c1461c4df6cde393e51f271f84c428efadb29e27ea54ae472196eaa75c9722c6d447b927b777aeb5a0d79f659cce0a6f95cf36b5ca49f5579b4ae3e0da928111c2a764820c8aa74c06c92019248370fdce322ddb168e860367cede6a9ffdb013fcb175ff9c0dee08313592cd68bdefc339a7cedc993c33864dfa5087b508aeb34887f56b34d87e2bbeae0bb9140e051f9a351dd62273d5e19026119944e0aa5977ffcd3d85ebbbf59f818a7186fabbdbed53381ab7ae49778935cebe7fbede3970f3381d172844620d04a78cadb2e078f54b80553de3e0094763bf551e717d8fdb61c189535940e009c552fd1a3d85242ae23a8768fdd64c7526fbe8048c1738c6189f46d3851349f5e35f4b44930bcd15143f84cf075e0e846a20a34bbf2f88038826197b88a767613939912d64e27e2022dc9f7556a8ceaa819bdf2bbb572b07274993ea5f3f323db87e0e5fc99c737ecfd9b3e59c73364c04bcfe1e9c7d9e424f79284f3c5db83eed19fa9a784c70cdf4a7521e8fc87715e9eb88f6d967ee332ce3c0dcef62cbeec5c4de0be8fab9974f87ad58aa8fdd8b898b0632264987f5e9bd743aacdf414eaaa64b4993ea5f42b6c6b3a929556c5d4b2e77a3b10b84e2a9e2fab4fe1c8a27c79ffd1cdbb76dba70a68ca8292463eadb8ff1f4034cf64226d61e88086bdfafd1e8191a1fb30c8e716934e171cfad70b554b5f3e9d83c03db97a96f6710cce7e2ad605b3f73d83e8da6d98348aadb5b7b616b3f4f6cc11c44a5c138eebb883130e6a823afbd4bea37c1753289f307d71e5c7f0a7d53a862bf89b6db2a4e47c74d562cd5e7ee3cd2619d374e1292a889448ca95f75beafa22096eae7ae3f36b0571cd8456072fc104f8d1b777777777737a6b75534da372844e2ec2feec68bcdef85b56ba3dfde0be75e39adff3e4fbe5f3eb87eab364e07ed958b2b2796eacf7be1bcc063e1f8913df7bdeab03e778ba85445a691d5648530dff2a978322d9d1d15b617dc8d067f7060ef74583f088935b03310460275e21ed9dfc020d38794ec08b17d0bba5087aafecdaa782ddf579926f557dbf274be9de7a9afc9d8b488fd529c5d2012dbf7ea5beb79174ebd70323087f5310b3ab80ac28924524820c1220412fe3d84bdec973dd8bf7f7677ff105efef09cced20027cd976da4c319378cb2a4c0cbcde3437ac6a667b29f52c849d36a3fbd46c855aa1f7ed87ad521473b9eb0277ab8fb631806c2188da8ca66a3a979dac77b163046bc1ff21f83cdd2a2ff7c457879fee80f4262cc4ddecf77233d93670bd339a466da4c22e289fbf9f302f1d489beeb7ebb59d4811e24f1c6f5905b7723e6b27c0f6a17f226ae2ad2a42015115e7695cae479cb9334a979707850939ec140cc857aa67dfb97ff584ea40a7b1c7e84f73dd4335bcf500fe4f92ee0fd98aa0ee7ac99a9950f78b18927f0e01fea937dc89067b5baf5703a4838c894490214d73fdd8ce1fa32dccce1fa336e3ec1f54d37afe0fa3337b3e0fa326e76c1f563dc186e7e81ebc3703309d77fe1e612ae2f73636e9681ebbb70b30cb87ee9e619707d18f55bb839da00d767e1e688035c9f7473d401ae1fdebcc2cdf107b8be0a37c720e0fa2f6e8e44c0f5616e8e4fe0fa75da58aaf557ae8bab72bf58aa7f6f4b2cd5fffbb1549fc58589a5fadf0d63a9be8a0b432696ea9fdc183362a9bebd3462a97e766be0104bf5bd9b2396eaa35c1eb1547f747dc452fd153700b1549fe5f6104bf55f2e0162a97e8b6b8058aa71d6ac6673c3381d8ef303b4b0c34ea3294a84a65c5a9ebed3771cc413f7f4e510a410e20903d889685280e4912827a2e609980a2d01d323605a77685fb5faf3eb9c35abd9749977343dc75534658f6c1e4fa7dce42d2f959a2067df56110844e26d647bc8c88e66f374d84386041132b1ed9a0ec34df2c81e107898e479ec43ec815d83254f0f914118630193018f7ecc6a5cc32acd042231f69ab6a9b8d50abd79415f8069f63475c36ddd16e3e9ca6cb0136933d464a8066bde4661cc2ae5f440f8f763f14e6a10690ae1df8f25ce68df438826da8448a2efc2c5689482330d4ad1b22613f30caf35f20f322991199a83e9c78729c2cbcd932f21a178da2ae84c7ae6e4e9bb92362920e5a9ca7f3f5e0fd092f9b1524d4c9183431c9b988208d662c728679721303f4f22f0bc00a6344f03d214cd7bcb5b1ef4291bb6ac8eb783e96b6de3a4204412fd9bf0753ec923799eb051784cf8a4c09406f5c4127dedda482244127d243b47dec85704534a84d59707a678277c4af0a411307d50f2b0c8c0d35a530c19fac130383631d4c2ad2804e1934de54f381d247cf2443ca7434a276b1ee9903e4b8ec7a2f403f1843d7daf419cd19ebed3400af806b12551d7908ca12f779cc0945ae7019e73723d34cd1dccee9e07ba379aef3fdfded1fceaaa112669402fe2465664cfc9a3d1ca88c50dc2f2ad50b1e29763f52bb763cef9d5a7901f291f84c4a31d213ef99347798933245112a7525cdfcb381cd8856111fb289371375cdb3669236da4cd7645586eb7db2eb7dd6dbbda76b3ed62dbb5dbaddbbdb64bb73bb7eb386eb7b7c62957267688727263870ae8a74970b3c4c08b54f2d02d9ee6534c9f8b2629137b96504aa9cffab35e9f4516a675b2e2e9c2c16d180f7d1ba8e5bc151718f13bee86636fa329b7d6f3beef57c0f6f30a38d3afb9de983f78821946abd7c3d71561592496b217e1eb76421dbe2eb784c3d7dd6e367c5dcd89d0f07533a00c5f174b82e1ebda5e597cdd3a74f15024145f77ca542c65135fd7f10fb1947d8dcee1d94baca96c0078fa9ef21c1e3e3b921d3efb111f341400a0b726c8c3c9e7df01fc7c80d14929148c4e5289db7b8bbe4a09bc91fd23687ede917def47f6438cfd36b2219ead204044787b2040604b035aeba580d93b01e98b546ca22b7177834c9c3d15c4c4db7bcaeeb05f6bfdd1f64166f7340ff6f48e36704788eb57fa919bd9550011fdf46bf11a03988696d250cacc586a5c658f74e0daff000a811c5a164183121c31bbdb5b4e8e46765309d4dd53b3f164251111258788315a3c490bc492b4118197636005b829c618816204d2fac43ef6d2269ea454b98db3fc4612a12c26f0728c93fa720869437ff67c59023cdd7d2267c3651476daa6391bd47f00a243a90069336d7c74a8498e82919e7c1dc60e81e8507ea7b20c28a1c412ce759b26ea36ce355126fa4ec4514ab71abaea50622b925489add3389188d33aadd3b6ef3a25ba6ee3b84eebbaaed33a51d7612f7aac03bbaed330edb3e8358e7b4d84751db7492b921dddba8ed28e7674d39ebbb3ef9422d31ada61f64573db441d7d49bbdfb8dfb6e73af9eebfd9cb8a3aad9b54b4bdedac1579228b8944980766ecb9b7f645d7e4dca548dbe8a4ddccb239a7bbcf39a77b76b32c737777cf3aed4ed165c169b7eb8188f025eab44e136d9db66d9dbbbbbbbbbbbbbbfb8b36bfb8aed3b84b5fce5f79154d24128950524e3c6c4525054574e2612291d6b9503c6dee73ced59c30e8b6aeebc01fda762bd644ce75d9623064382c9e60c870f6bb6edbb8ae8b270dac3fa588a78e1659cd0983aed338aa84c6751bb7691de79a685362d3ba4edbb46ddb366de3b68d7bd1b669a239e79cdb6b9fb9d7366dd3b6aedbb67be18ea352931406dbd66d9dc8cedf2ec5da0d42e21d8fe9332004325229bb678d54a4e3cdcfb1075b19f3b226cf9099de3753e7cfd95846d95d8600bda148fcdd27a5d4573de32d1fdd59b2cad7f2d8330c4e7994931ca38b49f012f035c7686840f0b2c52121506595a397cff272858a5f51f994970fa367505ebe4ccf9cbcfc183de3895e3e8d9ee966b8978f438e9eb12f9f878f00f4d026509334326cf12edfc28547101799eaece76df1946ed73e77b7ef2ef7a2db9d5cef51eec9a75c945751791577e5575c15ffdd15df722376b9401e5083fbfd029153f0d4e8be3c8b3bfa987efe70f67230ed1f4f39116ec3840012d54fc418fa74c8378429852296e8e758044c51c0f68981d05cb9d08563c40e64833c17fa6ade66a6be931b718fcc92504992e9496289be77bdd5f2e4cfb912bdff8a8327e04ae5f60d121ca923955c58948358a22f711063e8d77093ec9c26d15f79af6f7eb88e089458748344f4a2ee11ddf8d024fa2daec344eaa454deea63bdec1b1276261d52a9b3337b802b47b3f253a76794703b567efef6639bdf50c493100f8b9e7e3f1151a2a72a360de4a6bef1e99f9ef1fee6c60707e5caa19a0eef54b1a15c8abd1b7a4329d556aeb7b81b280f23018f7e964228e08f95204178b83eca6f576239d433161cd9df9ebe14da4030c90ae8ad04c4127d948b801843ffe4fa104bf4bd1b3bec1bfab4036f86ecca63ada05df713771c688058a22fb16cc55306dec0c020e49c37277d83082dc2f8f7f3fbe978760375777777777777777777777777bf0140976e93f471127d214cdd6a59bd2ee6f25bcbb768f16fe99a1a9f1a1f979b634cebee7eb95fd6bff9612d1e73f97aafcf6e7d4db3df6223f5b98d6e8b7925be7748122ed714897c9f7dc9cbaf9c447f7adef7997af5cfc274ae1ecca1f65d895f5a9ee368be9fbf7d3f777c3f3121d2db48b38edcb8dc161a6a12fd69dd06d30f93eddef9b75c8b671b69d6ed23b7bfdb2b6ee374485fc5ed9c95dbaddb4950e89f2c699eee764ffbf44f8740b79974d0ed7b1bbb4ec15e31e1b9bbe32c6bec6d37f9d01fa6dd17538ceb216b7aa535cbae7ac68291ce959166c553dc61ad751bea2acbe3ba6cb5f5f2a096fe8ecc60892566a089aeefeb6bfebc5ffc81e70f81296512fd9a6419c2cbdec28d33045ab144bfbe164f3cf18331a55482aa9591423598a69a06c550bba9b57e8bea43c43940445d464823a0c0f50d104f2f5fbf0011759de0044ee0fa04882796af3f8088ba9040620878c5d71740445d478e0001d70f403c8dbefe0ed107b8be8f7842f9fa3d220f707d1ef1e47d7d1db5be8d78035c1f8778cabe3e8e35c0f56bc413eaebcf5003ae4f430614ae3f438609d78ff1420cb8be4c3ca92c89c1f54b11752d6901d72745d4c5136368cf0ab8fe8b88ba7aeadf88ba7c60c4938aaf1fc6d3f7f561e289c5d7ff78fa9f175cdf25a2ae9ffa2c117501adc0f55722ea62126368fd9388ba825ae2e97efd2f9e5c7c7d95785af9fa5e3c614d44b83e17515793fa58445d4211750de18a1363e8d7dfe2e9f429ff33bed6dae29ba3a9d55f7bd7c02c6bb51d46ad5122ae05043f461a343ec61966f81869a0e163aca1868fb1468d8f11e38fd1061b3ec61b6ef81871c0e163b461e3c6c77803c7c78823c7c798e363d4a123871d3c7ab87c6eacc3c798c3c7b8e363e4f131f6f8e8f23a7c0b7b512727afe2aafc77553c8bfbfd5f167fefbf8b7b7fe5ba48b9a79f37e567dcf93adc1e3c76e4a023078e1b3670b8c1065ca3061a66a001b670a2cb08f97946b0c4c09338d31a5a23a71cc2f4fbc9dd2a98226626ebc8129aa2a93979260f0fcf6439a783c4030c4f56444134d156e8034c670ebe1a784b6016c879a46746d775fd85a5da7a1f0f8fe4117d6e23dce73601a62f855a4c56af5ad5a9b60962b1685050cbbbbccb9f4e80e934d2c46362e54febbfcff36acb5acffbc0ec41bee9707b5c1e77c7cd5710a69fc3d571f30584e9e7b838ee8d6be3e2706fb8365c7cf3756bb834dc192e8d9b2f24f9bac1d7917c21719d00532330d6dee506913708c5d95bd97180e9ab70b3eb00d35fe166ef01a61fdeec3fc0f449377b10307d166e762260fa2ddcec4f60fa306e762360faa59b3d0a4cdf859b5d09987ecccdce044c5fe6667702a6ffc2cd2e05a60fc3cd3e05a61fc3cd53084c3fc6cd730298be8c9be71098fecc35dd3c3580e9cb70f3e400a61fc0f4ebcd530498b60c3fb10c55daf0d8ccb8164f2312751d396204d3eb86be7c20a22e244842a08a27160e44d48583e30122f1b442031175e5e46c20154fa30b44d4d56a650053942122ea4a92c40236f1e44d20a22e1d9d0a60fa73483c09115197122512c0f4674d3c654fdfa788a86b47c6d0df9902a6ef43f1847afa2e05a5d6091175f13c01d3f726ce8488ba7a640cfd9e2660fa1e144f274fdf951051974f141175fd1821a22ea02722ea62c2249e5480e249c54f3c7d3ef1c4c267093f49003a021328307d2742445d414188a8abc9252463680f22ea1afaa7ef3cf1749fba88a7950f72a2c91084867c104f33a58388923832862a89270c4583640c3d3d7db741444d968ca1f194f2f49d8988a2291943df7380e96b2fb7c5bbb8e0b3dc975f71597e7457fcca75f12877f4de45f9eb7a8fdd953f5decb37b3dea6630302f5ea8a0c20a2b842189c4020b2db4000346a9e4820b313132322fbc00030c31c490316332dd0bfedffb2ceeff64f12aeef72a57c5a7dcb9dd93b777fbd34d79d4b53ed4af34e8080ccc919b172f6e90a8a002129c1556c0c909c39c1689d44ac2020b49745a684147090c184a764aa59d252eb8b084272686a74746a6c7e7857fe173ffc0f030fc60fa17500c4c6204c9683263fa1880623091113463fadcf81a9a21c3e9e94f16eae9d3d40c1924cee973a3581aeae6993ba8144c58ea9a9e538808200000004100a315000038100a050442c178280c54556e0f14800d7b9852665299c9c459122421630c418601420000000001001090a11a007ec6031193286d47c54594c0bccc692ad005aac7bbbb025217d644033d79435490f9cd19952b9624d237850bfb5c269e704ef43eb9bb74c19f0439db04e3f603e1c09f6b905c466d37b63999057716dafb3be6446c0388fc0c4304c9d4049186efd06383857c05e4f7ce410482f35cdc8d8d77010cdd926cfb235ae81aa407c8269c1bb5a5211431c2c0b6844e1a6f71f290195ce698e61c85ac69a25d38d062bd3d2b1f572615a3383317de78fdcc3c39df44f8c60b5122180d55306632444ff2fe44fd7512c5b49d40f7511f608b4de30033b6d6742a6a51891e13632e705ac050f5647fbd1c334c241c000efe886db63a1cdbb5ba0d85163ae03586e2f86c88fc5f521480d7126e0c0e7aabcadd2e02ef820372bd24237901e550af1d3b0e3398251f9eaa2d4b7a73aee35de4f9eeea15581d8466b00ad8c076f1a37403e7eaa22e0d938fd013b406d7940598cc270b0820fb16067f16dd21480c91eda7cb3b6f19d029afb8803dff34d892f270b75a0ff65f45e955325c5b34d1bd1453590279db67228df11a86b2f268ada2d698175e87878d4c1e56f5390c977288c785e00d088f2f40739100a3bcaa338d268fb223816a49087d3717b0bb7e201956e7cd4a435f235a51043853a6f1c82160976fb0a2a610af6f3c4450cdd704267c43b7f7c7f10d94fd9c48f0c48d1141555466500a719a1283861b36ad0a9c6a5f8a24f082420b26c3e27271bbe462b066c349c5226d7374376fad57d240e5451a922c86a6ff8a8af250f0da046dffeedb74097e405700abeef3ae7ac25d5355a8de5310c41676f3d533b631559db45750f815a5b25900ba6e28b323e82337c066d842b5b9797c05b325564f19618b9b591c177427050ab9e41ed2fddf78b294a6a611b68c8e7f800f634c5a36730c87025c69c99196dc35994c76638ef2993cab0688a11f23a0c5f83eef53f270b05bddd1812d1b59a613091799200dd6b0e1c3d375b634b86011dabc465d2ae417d6d1271981ce69c80e18a35b100540b43a5143845ac740c82dcbdbe2d6af4fa708666c3c703acd03bfe853b77cad08fc958944c7d672ffeef0aa01a89e75a11c81814319ce9b661a4d577bc8e2708230183e1e14927be2a21dc656395946d8514f9025acffe98664102c485602a55daf3b91a5883b4cc010f5e8a1522048718f26ea3c7b12c1bc1550b2383d6bc73b80a340a46827d0e22518e0c9b944b94c72c4bd4c9da16c28928b79e138d709cad2cff27df353179f4a33630a81a2a3083d8e6a7bc73b5324c79e0b2fc4e7e17d7f21ae182b4015922ddb8515263ea9d1632a187faf0e257d67f426611a10ba0f991fa96c24503105014c0045d89b75ba20827153c420385d252b6870f532c5dd5049e8a3fcfc37b41f8b8a460dbe0139b109bd2bc8a0e2fde30fcd5d9b2a31cad02507c5057072033c71ed876245e4f77e3f5a60949615a090df81dbf1c195d29ec77928c9087ef630a0b64217dac8cb5067120db5342f10261099508da7523a2e87658208be1d46246d207e6f3ca916998cbcdc51a6951cd1cc73073200444e6b42291fd291bb6bb4dc36c2407395e528e4a97f57497aa4712a46bde390d404f40ebed6d197fc38b734d965968e3b5629115e43c1cba205ce426e76d40fe0a05f0c6cdd95f10f0f8ffdd35703cd3074515636ff9ece56c7cf5ec2c28caf14a1888baa5dcd4d5646cebee26f86d8e35fe6f765900d1568a278d43043ce4ee3196a2e70ecd8ab162812ff6d4f9ffbd0e62ee38276197b370ecdd414530c144e4a80b6390a79992e7908b5a2d4cd1424e195a07a7bd4b016e5d9707554c4dd62fdda5d6edd1c8923ddc4c1bf85be270ebe7f01041f9edc271e745fc37f07158a5ec00bfbbfb14109297beede86a8f189461c730b9e500d98220a5adc7c51f8220c0e9219851859aad2430d1fe362aa65f4249494b560858085e5c3e4afca0d9888e044387c6d238b6ca895690cb9a1ffa1f737168d2090a63eba7b0761c0e74130648e105ca860c8ac6c9ec34ad2f4dbf4577c17b7bef6865ce26c15c3652c3dd6bb2d8c5c5b8a2f6410941541b067f062481b019a1c74e963b1b20d362dc42be4ffee8c5f6f58c044b7e6830e57ee04fafc42b497e87bc4c642a13b3cae0502251f42f42cb4cd6193d7a0fbc074b8371781c643713c56fd8b618b0516e8038adb3040be887894a00f1d866d328334094bc36bb43ba1237af8d0db2ac501f6e9df93b4d81e531b9c0aed5bf35165e17ce2f5c7ab7991b0f49d2183faaca1dae8eb37e438a856cc000e3e1ed597e00038f8fed2ee779a490ac25784936743c169c670caac24600ce2cc5f7dacb19d042b5c9c39c1300c46265893e3ccef92acb1dd0e6b3572fe1415c5824784197f42a54735409e754f0ba0c5cf16f5e1968fd8706c12c3899eee8f0e81e1b92c7e3ce7ae213921132bf9e429c73e3142ddd3fc181060a2e99987aca81945342f7b08fe9fe913b5c718fb9c8b32eec5ce00b9c7854ba648d1d1daa6f260c555856a994fc3ed080ea5caa039757d76e585d690b0929e2dc687d754d8736a4c7ff18cd24a977651a91f9a87065f8924e7fc186648d9e13895e2c70d6232a719fa001aee222ee617808f32d3e696a3b23c100de14efdf3af7a0d4ca3d4276697a46120d93c2d762976d358623cefcd51e3dc1838d5bce9c7c62c6b222ecbe45949660a02b99eb48149ed234826e244f47bf18faa3cc754818654e2e25484a2ab5105eaae2ee6cd14e21f89d3ac0f9dedf1b1bb11dc5341e35648602ca0e85c68924be2f6601f9eecf7815dbdaa57e482ec4e562863b64738f123ab23bcf811e3038bde34cdfb535d41e9b82572d5c9c6fd3376ff7ca8b1a75bafb11c5ab0290ff4ccfe6460713872e3fd11eee026fe77cd8979c4c3763dac996015f9391d52286aa7d49a223c8e50feae62b6ade3a6fffc4a422f07866935f12ddfb8dade7fc8e7be68a1f2d899b70f2dee4e1e5a12c58acbeb7810d3a1ff810272ed0a4b228fe48929d7257101ca12b742a0468e4e74caec94efa1ac5f9a201b4c903799fdfdc66072890532043638e4ee83b7634717452eae30b59af325bd3ceb6e3e2c12489b5cc56f7db61c71ccf684894ea7c3a10ecd47527796eb7f9e99dfbf8299029ac363322c30ecb733102b01555dfb592a7db93fdd120630f82c9e6b689b169b5bbd7bf967e29fa6de4c99cad6f95c0d095de708c4819e3bb8c7cdc344cddc0ac2489e8dbfbb7a9d3828d448d4ea6d05518d584e07f0a661b94303659bdbdf0fb09bc27210dde9f99c603d11f7da4a03620e9d31ae31587368b45639715a12e279468e18068299559877753d547766ab7a46b76824bbe0f993b1f2da3d2d586e237b2213c895585748b6e9b1e233204667e632951f461ca613b7d22bcee073df572c5c5c833e67b138bfe0e2d2b998491583e1c66c2676a18b03b667eba17cca4b5624ac8786b0b6513ed1382a00e9845611c87d9bf6cf22c8ee7edea780cc62ccb139031853653c42ad15a4422b9fb48f186827ef3323b8e85b573d001662fe8bc06555e3ab19a41efcba130d896b9cc34521d5fa8e0366429a425c0e83d17d0116f6f42da46126b2394ba9039adbbac3616ea30444b4a2349dffd775ee675a1eaade2850db60e2eb9c357f18f4064033f24d6abb0c7bcbdf15ccd0d68429e7d7d1e4e2edb1d7077326226ff546f503429f7bfffc39a5f8fbbadf3f690b982c8266a636439d186b68fcc3442d07eeb0b89c065110d7a8b3d2e13b3f3c0674e16908ae11b87dc903aa589379a76ac87b23d686c6c14509ccd7e348120a99943f9090e87511a52b2be46d4f78dee06bc4a2c6ca26543e287e30b89e719d1db9ff49a348d45aad4b35411310989d54a050a2ae064fc81977ec3a2fa447efea312ed54b7212928402f328bc549ce8f6ddf3077d5da0b8752536e8f2243ff8b1e0feb6e2e9e98f897a50b67180ea3a8cfdaf48ee5905b9264b2e66aad544d6f5f655d54b303920fec4f7847a99cee8e39e9ffa89187b499ec747a6d18e4e14af62d279c63b3aa2bc0a48e732eee88af25a2095cfb84327284359b2a263a8d7804635a259e00533f414ea95ec69d7286d983fab71f355f8d7e940cc5e5914b4bdb6829a58f9208abc133127c1673eaad24950f02a8ce624581bd24c5bed50d1b25946338209ad1a931033bfd164b52ed369033300859c10501c03b0700481ea10008b3300d4b9188e4c09127dffeac10670ae10457b15ee2fb60f63a75cae1a7edc859ffad3adaf3634e958cc0a7cc5ec67458758fb6508c9b67d250859efb343d2052ce8452bd492a7d56f22f06df202dcde09756a558f5a50ad08379981f4772a06e2f7390189bf4d3789d9c74fb85204bf6dc04d110ed6f21a7b218b139a937b343c1ddedd52e995513f8d6197aa6d98fc2b363aab60943d76508897412542c7ec540b656921db15ebefd90fa2bd02e6428473c09b34d6571273e7395264a7cb2dc0fe02cedd413927613fdbc383c21dc2bfe3819ac688631a1d3c1d68e52772591d4162f678c0411b42bfc1861fef3cc8c6ba0af3b56dd4c5216ec7d1aac094912e1492c202392c8ecd40c480ce4f3ee4039c1c9999335e06c6d6312f4150931cc20e51e4edb3491a11c00aaa46ee03e16ff7ebef483905e0350886c66fb0f42dacdcb763200a6586f10180a1dbab3c1f3afa73a4868918d96d0f14b06b76a5573ec0cb272ab67785b4499de324d5a1ccead2f03fcfd2eb31db7858a12cc9ce526dc5fa150289ef8dd3487ecbc1e0995dbbea786cb5af967fa7fffaa855a839b93379048f39398cab46ebf0a5dc189f50dec4010235288b07f345cd5bb8d90021c8ba5fda2546a7c2c5328a04b528c8403a9d950377365e0bfee8803c9739dbcb2c5291a6a6b74399c6a5e7f24dd26dc88d2053f5970488955c5b108716c5e6e5656322f12881eb44c46ad7e40874f9fe4943cb88d133287c6c17ded6ad24df575ea35c2a40011854b12504b5fca97475eee6384282a9f90839448418f5e659b0bc816bd16e66178761ee4265bf06d2b146e3758992a17e0f866e052f3fcb2c57570553e8a6727555ad0e00ca5362446540cccb1f0269ec9be816816ad0481635078abda8c1f46c2fe0b9895f698a3fdc62798d7ea74a8d35d78fd572e81f01264a9c173315c919d361e082d58dc0420ef66323fc8a2b013aafaa261ce597a403c563817dd8194dc651990d44df958e06af39e9376efa7acd41248740e5770d7f45db41538dcb45d9c3325b15e07fc03a942ff7ee299539e6d1f8b0f56db550c22450eaea515ab33552a2571252f57b266c655c94489eb6e280a4a7816c607e5d7b960e9748d4ae6d2e819294542fc3780af8c6e88f8f286a56d2cd7c6bbebd3bcc97be431cb57096c4756c971864b4b4a588eb8d20e9555bebe82b41fd3591b0cf5dec665e2edad072b2eb3c9d416645f27885120129acdf87adfc2d11be4bba522a719427e7eb536fe6974ef9b5e7c079a9abfcbc5a028c3f7f9f4808ab38e49b6bb16869509db8286547e32bc97d685b262af1fa3949fcf515cd0354c88e18950959fae7a816d1e2eb18f0e7d043b4493263174b64b5a38d8ff44af999e738b15aa5cdcb01750bf7681e017a7c0482ef25182d2fd1311f8f788b96d30fc9d8e1cc1fe10dd6c0280e6197a82b1ac9b1368ccf41008386d554ccaa03453d827d1fb2ecb48a70a32919bef689a1512cf0b7a9436f9304763a6cfaca5bb10abfa30fd3fd7d64930e252b13f590ded013d9ff7105d863683b491d13b413ea360ef08a7abc8c54d45d58bc08405c89ac124a419e235b168f39577ea27cda4852ff35da90d5affc423ded932010222cb19339f0034c8293877e504f6f814b79158688d233a465fbf9d3c4b512da41ca52ad2ce295a70c4bc7ccccaba6a79d970489c633ec78dad9915aeffe3e7e45e739e67ceac6c59b8230b3788330ba4888335330b398bb4898a561b921ecabdb756ec4b384de0da94e0ca1d9fdd0efa31a361f51bc0ce697a0d5e8612b6ecc2c347c212dadf19b641c6b6d88403e371c82f3a7f2cfe395f7e7699a70c2367f811413531bc790b256b149c1c7d96af522552b8385e861f8bd391cef0cf445f401a58379fc15ea7d100dc9abef551c4c224a66db0aed23fd71fe9e7122fb78349734c6c3721789ee3519b070ab96633ebf3bba838d82640c0035078006aa94da712a052692b201961e95ffdc21086e2181b3c52f092c164d3df28828e4b799e6fe9615fe6792911a909296923f0eb1b1b201e38558ca0373471e862f561d9af6eba0f2b8ff11b0cecf5c42094c0392f7b03b65cdc1bd44232b8673e315e07300a6e888955455584aa949f2a25294d828d6c5baa511d33cdb0c834f1e84a50b1a82f9de1880c1270fbfd2050dbe7c6f0cbde093075ee982865dbe37065d00f795875c9333abd5e0821c50b73a3b37b1a58e77c1ac2dd2b8a70574aa5a48c6e8cba366162564b539ffc6e05abde3546b03013927bb945e66e6a0baea1b8b75c763d611c10273e6bd7c7d00f4b866accd33b21d980627b2bc91c22719dda047f04e4c3ecfd08e9293472cb6c30fcc9dc884fca3bd5610d8b62b7fdd51dba70f653992a9633c05edc51cdd709108930f43bb3f640b0b23be3604b4ee5d630ba1136c3a88663a48cf487f7bebe2615fbb6cfce510da03812f08351bebff93de5cd957db591fc880109190debfd0ba863a07efae87fa241e652176b76177ddc5e709ead9f788dd8420cfc600206b94a5d424520ccbbb8be501e985916134e9823574d32b82994339be756686ba02f4e986251baaff0dda1f3ece56d59a18b9107760408301294d0c89f6e1d3c752b8954a63c5cc6496042d23f7bff868082242cd0be640f5b536f7cb4a350e1aa323487746f86279640acfc2f5f0a43a3c6bc92a87ade653cd3aac09c2b599dc9944e9eb6c03d2292746488d5b402f5550b83b2e41e7a7dc22c7ade474cdb3f3e2b2d92beef0de523e4f7becf28c309d6c765f04c8d4bede8579e2304f360f14c56123947e04966553421eb4548ebdc09ecc66e1ebef8a8431718437e3c374b6ee9f133bba322280d6f086236c8828e4fa182a572b2e7e407bbd6dd1678267a54c39e3ac933edc2e03cee461806bd08eb756593ee3bae098694e6455698503c336776ea260bab8739568e34a171dceca5f4573de33cc2c05118489be4ee957c16e22cdec43aeebbdd7bb2830ffd087617b2fa3aa3eb1f9d81abaf79b3afdbda2d43c26217673ae0579d8f37df228f30c07392adce166b853b21fe0b75c368793fe09ab83cc920f5544a993f988c83d5c4850c37f40a1a73af2189b800f2bfdccac084c1e90f93fb3d971d84a5517500b0bb7599761a79ad6252b64dd4bbd522bdcd604770fca4d7d5d60e8d43d60f25410ad23ee7d1d5cbef9c76c2b4d4a0476491c68b40f6f3c6b404100c0d4e58059b4d575169bb53f7028091549015caad713a0f4da4011c80dfbc59efba101ae1be12cb9e534ce79beeebba994137f772ae6cf2e66b29fd38a264153dc4d08f098c74aedcd88c226c5c71639a82b52f74b596a60f1dae20330055fe645cfb4b1eaa471ce9a557c8be235827430a5e187f6fce9be5071450bf24da058becbbb28b25ccad66ae402fe33e9a6e2348397f94af3e54a39f097062d6ee7c76ed1aab0552e2d77fa018979a9837a4b22c542f3b48927267524090337c71ecaec8b5c6f544fb6647703d7fdca226f77ce6b2bda3728c3d25492fe2efce26f75c5df8f53b28260068ab0bfddb492d7dd5666d218b839fc170abee5229eb229f7ade9a056ff463d31d5fdf2868f9b3c94ee953dc10648be655d5dddfcae1493ffb97eb78e20d8794c134214f210bc84aacc30b6ff72fbe05cdf0d4f995045ea8acf6cb9be8d986ffa20ad49fd37efe6c235200f11455faa8a837d45420bf1c3049e031003f0d118fa2f7f8ece8ecb186739c92540ae79e739b652f719d5895f42a0afbae93b1e1c7a80d07bbcf8ae5578ff8acc9b144a27b2c28764db7b231c22f22e10b6132d0dfa439282360d1b5d0570c42321ddf5338afb01edc1621452ca75632bca4b9d079bb1d7a34a37540d598df16fc2d8b310a297a24f49a85b57376fbe2f8dd763eb79fb32fe91dff0143458772c521954fcc723937c7fbc74041984d7fe912fa6d27813256208635d96e1ed03221c600a69a5637f0587189c55038b882fff88e702eb6dd02af414ae14b30eee8504b90ece54606ae6c34302c888eb874b9f336edba7ef698e31819a287bb7c2f5a7996b7e103b02b84a1c223e42692d233ecd9a5c9f3b5345879a59c7411840748c101a910e855c2411e24259ff2658f898ee6bb9081de542a9af51e40e1ca773c01b74aee206c901b567e0b53383c30af19184e9278fec603024974894e290e88a14922eb76615218aea6e038fa28c63c462220624041003c1813a112f03819291b97ea827831a4be252e6d132dadd90707d9a1df2fc91a9e6fcf1a21d9cce21e922bb2b0680ac0e7f13534ad67f047082ad5b3d190f04de4dcd1f2c1ff91bd17cf208689fe686b39789be53825913235ca2e94b1a6fc9b617d01fb0925f5f6cca237679431d320dd9f3df5d1654ebc49ca086fb98ea19e8df820c62de4a2bcae87f5f7c88dc04ffa23665083cc6c87357f89ca847f066a34350d2a3d50617c1fff28e2e96742ee4bd2b423cfe30c3e1d9b6373bc8b367ef29dde304d989bb53101c4110c40bb5b7f7c77b729d991f2e75e71288ef689cabb493728580dcfc892038e45e940029761e40720c417fa0e82d702f2385f4d0ab2648f2e379ab0a424b457a62a589c25d786f73dc68f443f18c90502011a71a481e8f6982868e2297428321c04d31372c3d8f8ca6625b8ff0e3f254848b7ca11c450392954584aa64c02ec9dbaef0830fea4f3d32af9da78b47a0b84ed3d28302cbce274b04fc85ebdaab8c1e63b7919607a092159e6543b31fffb71f305219ba93a17c45c20f77b5979882202afafe367d3cc5e87add3f77ee93bdfed9a48240cddbd24cec7d3c47e3495383669065a2fb4810868e5d24f331bfb2e176d22e5275e1c8e5a76b0e2436e2ac4309b03480ae5095d4fadf245c721140e923a5dad9062b9b955a6a16ee5cee0b74d353c36c830bddbe416654dbd4cafcec8e6c836fa9315c78b0dc13582072158bf44d10a64ddaff153aa2e40646cc8c4f65cec8bcc3702d0985596cce3f48bfa2bc7dbfcb83f9151b63297432b3e718a7e869d74d52f23dc57f534857abbc822754b4e9ba9cb1ab4dd33d74693dcab5c10504b93f75f482d7ca87f2391539c2023ee7209fc53406cced8389644d9d717b65916c9693082f7fa4d4e069e3f2b7aa9764e67fd98f461551881ef13a968cd919193edbe21fa1feda8c7e476f61128778b589c82fa68c2011292be2eb735433330d438af62210064d3b157dbe0ffd130c475fad9f855090c3bd5402e008dba090b24745a04a70ed5eb837ec8629e75d28449b58ed9dde95ebcebf983cb9f56daec726b4b1ad6cfde4618cef7766c6d0baa751169aea8cc3cd13ab89d5d0c7e323a041ff9acccd79f3c41dc5f0da62974d438c230b55da0cba06ed3d859142822611b247a88d2099f65cc00edec4d642b60297c5d4d894a584b767c6035c941da4fdc148e23748089723d986525b09901516b1947b461b9583095597ab2be7b2cd3f3dc6cc0aa18a036c507c5dea96fc975ddc6debea2f57615eb0876ea8b51d4ef540c0069012aa07ad0570e79bfc8132196305c997923924cb412b451962267f6e5a59afdff948f4dc31e756dcaf9d1c268f7f33ddc8715f853db690d09229f7a2984a2867409e8e3f16104af037224553382a1ffc4132ca075ae3395cf0577c200327f724ae645f535308b73b635acc2a4690ff9bbdff7a9af112a3000abf4aa5e94b19ab94f82fecd683dfa197c45559693d0f8966c905637c14fb04f57c93e5a1c7bbbbba9e85a5ddf42953c30d8fe86ab2f40268bacc8f6a1e455601223b945d894d92c9cc2d33a0fc288641ee80c90c91ee9a2084a116a95045770e974f8b273c0416f4523ce1b83223fbe4d81406bc9cfd2ef8f9a0c0dcde87fa700e9763e710a104bdee8e4c54a7b1221c2025344ebbf3b32844398d02d889625cd337169cb677c2e3f239602289f17e624b3138ea40f7f594e0993388549c8e1e2d36714a5aa58133550d2f55eae7a9369914d03934c760ba258a29fd159647fcb6432a5008c718723b207de7930a8ed9be61b70f4fc85b63248d6d8821e49ea3fc46e016c9a00acec44a0b523277babc3d8d85ba3ffbbfcd90e59445b6a0f691c6365ad63eb2a43dbe5b9bfd47b43be91f06fcf341fcae2052872ca239a8d152cb2d5e85d9f7b8852a753c14945a786cbf26dbf53c782fe46fb8998e3d03a97950faa08067fcbd703cd2c59744d3cb3b80079c107bf95008893aacc10295739c947703c6c800807a6e1805024702f38fb3b7070ecb4e7b3c11ca06e798eb291fd2318b7a9b029cbf062549e560bac149ceee5e9acca408d0af654c98a80f6f5a969419ec10846154a6abcd349fac9ac3803436b56e0260bc30773a8b8e45d3dcd83d7a39df8c6f414dc7803a8181999fe040eefd72c6b7fd7d33123778a2642167d47d51f56c295e7734367433263cb1c41fe7a342fd443ed6de6b2d1ded0a30fcfce1175c30ddffe1cbe1726af25485d95d905a7585497e8aa8c9fb27e604d92b251269085ba847a99b7690ce2c63ea4f13c0940501bc16f1a082537bd57068a91460b457af1c9d1216e42cd2abd1c7c74fe0e800eb948650e4e149ce5e6b87b1eb47c25e9f255bf5d4091f692a71e8f7919755ca4a7fe4d7e101569062d98972008484d475467279969d9110c44491234489cc894c929ad11df12eaa6f5c33a0747f5a3bcbac86506c96388538e0038460787902888922ede8baaf2ef749d5fee4058b0c682a81a508f812a6c3940e498308192acacf3cd7b511d1611b9c86001723d7bbd7487576248cbab546c86675d70160e42d570a717f419142be30b2871b36521997b671c7665d3d55da1b2b382ca532398a1c7a1a681915803fe3aee7803072205a3101749f6342669f598a45b695f3ce1e3fb31a72325e0d0d07350370207971ab415c830851c95925f54afba1159e1b85f22e39d43f5b1f17a68f6ad300b5d214414716d0f77799da64063b11ca2067478a9bef074864b4fe7275021e9b4614cdd31175a41ea2fa7a8258e4e6bcc06fe48bc5e7d22e12841f019a0066698006d070922d4ac77d28468530d8a3bb54ec091101b125d76fa092a988217b48700b6e5ea62d37d279d64fcf9cc9f408bae40535648f848080f16ec0945142dc66da73b6df24982a3c2150f642d8e62978d8f16c308bde314bf05ed763996403540213c048caa8eed00a1b9a9555b8fd867ede35d544ba2312b3801df45e7c4797948666b816bce8e15f5ec7889be050dce40182ad6071fdd12729400afd4f405f83d26942d7e7437a1a2a82411e358d3041a92c90a8bf0fcae98e4be69f7d30910a435e0b3ad7aea7894509a5152a6c9a80f7a7d3297c2ce0274ff0bcf087023e64bf60ff6124553a54181577264630eb887da52401df028ec1fa74d599e3de024582c4100a7112dd5384611c5b1507d1e9b0837e6c34afab98c921e79b79a9caf0336da05608d7e166bcf60d911e20ac3b901bb265b1131fcac467712e5ef14516b264efffc9e02290ba1137544de9997f6520d039ade4e59fec5ac0ffa800d5cc5acf7692b9810303ae14019366600c6aa43aab95ac388eab913a1b86b1a9ae89590ab185b84e84d19f3a583c0f572ef57d6899b2386f929b1774c8f75ef0138de20e547f93311454d4388d2cd54af02b50b481652a96684490503299d78ffa64a869c5a5ea8499471e9211fcaaabe63599db4e3c58cc172616bca96750c393602f7f40be0d585050e63ddd398abecd7ad1244c7013cf5a95e38783a09815c05b2cdb2bb437e85ed93aed4f0a6d1073627df2d2b9c0f0501579ed2ef0937318cc59ae8b71b01818f3fd22988fe8060ed71aa4126a36a639e65d1733dafa775a6283ee366cae5b1626c3802477acebe65e4976d39266c88cf86a40c73c15148f25117ff72e9e70388f9e0bd024030af706197a759852d23249c69669acb384dfd98e9687ce897a408b4e1ea285becd4ba7fa5bda69cbfde40d86b3d5495ecdc0ec744b75f5f4950e0c434f61507a057e082eeec8f488979c459d5b7ce4ed2b2012da805027cf241c8d836e0d73d72b22ce1017353097e09dc06e60b74d96907f38fc5e95f0c96b0270b29b04232bfa712a6a5d45616c59ba90f082a0b43cc93b33beb894d9958cd954c7e4a343b2ceb17c1ef4b696c60cd986a6e69c8b75d038ce02d0224f69d992efd1862d1e69aae638b02e749512c9570dcfa44931e9f5291c4d574c5175fd9f545cb90ba896f69f4527626f1af97a48ce22cb6252928ab914e9940029f91b310872d64ffe6178fc78a45b03630f3c3677c4a8434c3b780bb7544a2c8142e3307f5d7963cde8e4ecb92a2f7780b94d96d29d3f7ffb0842cca0d20e72a6758c97cfdf893e321814f88405348018c1072b6b686be411c5011b1b02f629f45a4720d4cd52ef6f0ced45ba71aa4a622e1e59b8d8b5d786025fab89d402816eb101270ca3ce3e7907d3e2058f1b13d692dcce16cff7cce6c20faab28c8a86b9a8c907ea83bebb66ed69f97327e313cb10242cdf287e38e882aeba50679f3219e9385af40419ecd87c5d37d2701db40d6e33f6836e33e70c0764709681b143771ae6a2da6d0bd2effeb2c5401cee05ca02b67895892ab9c07e83d42b62c1acbd618a0ae2fefb68831ac5f0ea9a2f9dab03f52c0be8e357b387514128ac05b6a4e882b2cf54c19dbc8495992fa61ca856dfb46dc478a1731e7cd88f56f8e3b2c2da1be6f13d6d9ba42d2e36b6b3ffbc04881c8e97a575432ff8d36344c58145cd87b7d53d996ff981de79f023a33b5ab426b45dd44f8c6405c294f05d701fbb9c064e239f87074f7bd06ed421b24f9e579e1c710d845d94106ef8087af0fb812d99de39514156e7a6fec451967a153cb74cf72883721e6449f93e61660d2b1a9203382f3e8331494fb4d16d00c8c6c5942ce1b6eed84693c14c8b0aeb3854d1ac0955621561f58d84b587f144eea08291020c4a388e1548c7c4005e5682c2bc73907d3e20fd5ef77c040456fc8ba8e1d40200be67a5364ace08be5b27189bde02229b7ba8df56d5eb32580a6ca14d67df9b4f0ac5b109171d2f65e997b88620c33303bb1870336aa764ab2fa0ed7c9eda5b21a2502e333e9d0f19cfccdf0e15ef7a52c01c34acf1e7cc7cedfc02a3170e48392d100b694cc3acd14f20b0b1a8a28e6e4e714924b97dee6cf2630d8f4e5daff5639c294d4f984792b1d53d97c34e061b6e6f2fb91200b49db8cda7fcbc2c44b8cfd11d5313a1b22b42530a0cff3763a24aff2f2e427a45388eb1a9e524d0c4155f79a24ac4e89e7534283a4426b2f322b3bf7b6ad29a1747cf12fd0a9481dad1a7041e070e8d79567dcd39a45e8980dbd9e37a4326093f2ca03195f7d845a1b73c60364592cb77dae780ad9d66975045d5891dd6a457678966438b0cdcfa92cc85f7df140513092e301184ba9b0041bf917851ae68d6fdd08746e291e45f0e7fb1b4ed7b262c0c52cbf4b256366e1bb7d7be55f5616a47bb5b39e99729bd6843d04ef0dc7b866241ac236395f8e009de025c68d3d5bf491aaa7234ccc6fcfc8677c494887da93d0d6652dec94ce7fe6a28fd1ab1c854c41bfb618724662ec6c67611dcba52e5b9a3831a60582ca28a21300f7789baad19bb886092f021774652040f0ebb5ecba4f0356884e739fc50f0c6083f92783fd5e3234a3850424bbecfa894ed86a010d0178374a15687b5002488c067a290326db77a4b3b81400cdea13ef18d8a0861d9669dbb05cf75c2e1edf38bb7bc1e26ca4f2a417a92d728dbf469feb85b17697b779cfd8f1ead52c32e9c3f8e2516d31a3aef6a13c0d08f0c08bb718e613148612573c28787588d28319606d408bf3822eec9d459d72a7a0847d1a0e37baf47b66df8313b3a8ba12e47dfa7d1c95c61d6d3f043f623e41c724bb196c0e7c702fbe5f82f44b690ec8c6db6716ed85de38bcd8e45dd182a945b7075d78f3f322d8e9b76e03d8eb3cf5e0b1d7914ee2bd78632c8731b475a86da80bb1cdc64f66527cc95fc5509c306cd777fc66059c6d945a1ee5ecc681a66690546c0c11790b60b12199707c51693cb599c70cbdefab3e6875982574858b8008fd58b14908d5f9931d10ad0b9eace9218d3a7127ad9d8bcf1fcb7458a50497af876818ce8e01c737358e148f44d561077047627ae5459cea5d18fb5f9cb1662d1580af670402965ff518841e46ea7af6402113906578938aa887ce1eb1ad9f0b320c963ab978f1703027dceebed4badbb0f0188f79d52debb4286c1e6c8ed8c33ae1ad87929f14246dc1845a79c4e9506368b82495c40053bf9f1dd0780a7320a957acfe19e6fb29d4aa94c3c48799336bcbaddb8f575047f9e9ec72b8f1b53d3cf2979856c5a5e57e9d12844569279b58f0f545ef76c5abeb842b4c5a434bae6405b401e3f6873d568343b436a950a15238e58f8c79c59280d99a22363dc94d53f130ee70934a702f9b9ee6ab416c15219b3cdcc0217679a5322d3aee01494dc932c5d553088999d40d3f4f358fab8ed094eaefad72d411932f1216f2ba5cd6cf51724bdde471e847a79dc5eaf576c48bedc32a041968a66f11b1dcbccb47f445305e079d3b674fc4c597c1f99a3819b5d5e496c398b842a160037d21227fff2bc441f8d5faacf09f11611a16d93a4f3a5d5038c7452926f7c12cbfae74a37c4c990e1f7237cd634db7b1f56266e7892ef8c392649bcbb25c2b8680f14f03c178954c36ce013ac37ca0f95928892cf2855390e416e7c822c7f4b6e7fefac60e93262c239eabce4419ca435e5ae5de620850bb4cbeca2136e22c12c607011514c3e87a604c6e26dba3f74dbe7e0d621782f146e1949701484789c15ae44ece8a21944461ae923004f5e0fd2a38205128066be74a1d12535d2201237aafc539448680a4932098d5a31692501b6b28b7d24f806221b088d82ea5f098d24211011e4fba46cdf47d01e26d93bc2aaf985cdb0f677592978374d282e5fa5d1283851d13e0acdf6217deb061f9ccba5ddf556be0898c77243292c69f2298fc5d166fea3ee5f7ac6504184804c6d016e8a4eb81540baaecc74949e5e9ee74e7bce791273ac02f4641c77cd510993221d5b95f75a32c0a2d69a3cc9ee40e1e0760a3dae71aabb082b2858ef4abb340d7197a580ad65684bbcadd88e08272020aa2039eda7dd949fb1ae7a8a126468f61816d0dfe1cc82f81a17c2af2c8ed3abd0f58394167d8a7e7db64ae331c6483ca5115d07dcd5d68b434c0915c638e5e610f378a2032327ab5d3502c1e5952049d18d3b6256ad8845a46baf68499f26bbb5ad38eda8c502075512410f6ac5606707d7212b53259bbc2ea733fb9e068f717bdf887aa3cef79882b70aa8cacff2d154e126d2b61245a28349613da147848e7801030f8ebf8bb20f2ceae663bf8f6ac801dcb017d3003c3d1ae8384ebce2313c0486dad445a0a8f276ce1b8e273b8e6b1bc6bd5831f9059abc5cd9235fb897bc84037683c47f12c70bc90c8a814fdab6d31691177c59eb3554186b1e973b00b3ac1df073270797ea8cd6f418ec861d4cf5da798148ae176ad88f6ac73a94a1d54e42c49020b75e451f61ef61fffd513624ea589c3d6544fb47b6ec2b603d38b088cc45f2929419028c7206fa260ce151a91b7f18e19f0d2962fe03d41e3c770d9f636dc4edf1e2754a5310615816e405ef4b6a400b30189908166b16a08e16eb51564263638a8ca4f8c43e91b1021424b5c61589f80758d7a68ee2d904bf34865652dff9f6c6d62548bebfe490fdefa4d38ee4b7d777c2dbd3e5fd28db31367f96bdd81eeeee5762dcc79f479c49d473325e5a215c68581a4daa458940bfc33684c778a8eb7354fd343bebc71b7125d7838b4e0419960cce79d7d11d57e29105933d5a03e2d1ad3f01f74c5d5b30874f8d01cd0ea5ab4d31e1acdaf78edce59ac5038156ce0e75f633d98203fd416f1d12d21ceaeccb2a2950edeca7e8e73c90b0ebd205c1dc3d783dcccafc781c05153c153e23d816cf2a56d68d41a5250fa50350d4c346963ca303f69ec7a034c16d1f0b39ed5c43a97659bd105aefcdda06d6be33bec769c7429946ca42e55188033c90501276250928a6ae5436956bcafb17b6587deea59ee148270892e30e3b59b974e374b3546459350f4d36e694547ffdac4b8a963fd8299a4c2ba1857c15cd27582c798cbefa999029d911e2676291efb1004b18df65961ac022f0cced4458518adfa206f5be06a21365210b1ff6200cd4df99f4c0b8651a69d5610e0bdff5877ce8cd0f6a727d05aa288992b5acbced15891fbf9ed21225276901ac3d4838bfd2f2c611c10511a544f022f7fe1b06e878c71791213622938d23b27d9f11778b0fb49fb2c7d3a338db453d1bdbe6b68145dc43d6b9304c3fae1cc4296d845ef5444f0a5a80e3f5cea00607417e7c91acd2459a2757135d69f46484cc7c0455f627c3a39f9553e315089683c90ed6e27182bf4a0e4eb30f04bdea93beafc1e607d9e051a7b91d7a4066e21ee3e433a595774dfaa8818048bf74a36072bf1c7492f5c86fe600df74a295213a6683448ae097f5bc03e455b0a19fd29220dc7476894d74f23bd012d346d6eb77a596047d5624cb27b70ab16db99561aa37536a6b02461a12f8ecc734e2437b0bf7e1c58e6952b4c362e5a0657bbd501ff46594b376ea4994259e85b02402a9452909e417026499d6fc820ac1585d9b691ed6cbb83b30c206bfe5bf13e8f573171f832c4a323ad738bfd2dad3cb9817d45ce095647337c43cc268a7b5e21d7219b70eb9ee9d6d3344af36969f388f3bc3456586fc93dde3b3810d4cc02020c3c1d7f02e9a9caaaa170896947e2622094a854d683aa6591642154736f9891236556a03b271919dc1d90ce903c42ad4754db22f4b30ee5e153f5cead85ef32a7046ee6106a7ab4bfc888d8c45ee13c9432522e60d81d9f2b2fd664d32b608ce34210e2bd29cec3c045f53b4735bab9bec01f1a7ae37b43f144a3368abd383de7b7f28649c293f1fb41b5ef9753ea044068ac60235572273f7f2d1f7d993c8a47f29a14f0cf86396e6c313c6ac3e66c5729afa3b0b96eb8aeaeaf397cb41627ef7d4c069968d9a8db9006cbc8b2c4ab5d9d9299bdf54048208a33411a3820ce3f34db626918ca9da96c12847780515f52bcd6b2e050d280964761d85a59e79c6429f6fdc20ddd1bab6470a5839e004ede54697bc64a4f38e1694d95612b248f86408e420363e6e00b2524c53b4006b0128802375c69f9848bb6ff621b1de416a45668cb376b4388fc4f0be54899abe26eda4f7e6d32842b3b8acb9829391d6c8bc4d0a8943054b50127ff2cd354dc212d211f0246a424d8af9512200200a58e34e7920fd8eb2f96e7ef5da783c16702f366d2a2f2e0e5445d09d8a0a12b5b3d99823a3bdd5cd5479ef44a5b801110eb50a2eb486340e40c75a17509a01948857f873758b03c59a0229f1afb29f1844edaaad43e7c6a279aa6f434a11ee6e99be7de3ce94328e85e7c1ffd5b9194388c83658a20cc474233083794eda45fcd2e9c5c7c51eccbe17366cdc9283208609071b9b8996236eee9df113e9a0fb67b36e54e43f153c90bd12b6151b082b0376e9d43b966a6b1df3957b8009fc72e2bafe7490c3c934e88a75d3959123c6ab7cf11060eef4536b8b23abc84f337e350e1fe04117f9be4a01b665e6754affb818dd96d1fe57dae87783559b57625a6fd5387db649dc030cab6415876d6ac9173f81eae9b37ff9297de75c2233ec9b2564676b3eec6de11bb9fe42ca9049b369ae06a1467f48d9deaa27c59f0b0d1dc7a2ef07150e200b4a9ef0f25cd5480642586a78d2904ea807ec654935a4021187483cea409d8032551baf6060c722d5c631f9502184ee83a4de0281021bc6688ff7022e7474d5d0b899d08023e4e888aadad5de1b2cda10a422d1a3d1c412216cab4c64a12c82e1065684985608f319201c217004ab112adddd5b97342fc8c07d269e717c9cb06e8ccd069adca10db65f20b909078c00db0b8244650708723b690ba24c947207a56252540fad6d8d252110236934b8c50b568f1150e9291eac9ae8a9512ff5657b6d9763c3f07ed646383b456c7494bcddac825d77a51e2279f74e39652193e7f18550e7490c9ca8377af07e5a02d00dbb02480f8b06181bb604d00dbb0a900e8b0e3016b604d01d76a53f866f5a02e8865d0548874507180b5b02e80ebb02480f8b06180b5b0ad00dbb32045fbe432dd284292d8826f0790c7ae9876753811ea4e34d98d639ad133356b173b9e10bd09908338f588a42d270e76e8ecd0de2782efe1c5e1cb116e79eeb74b1cf16e60799b02364a8135b60e222d09857c3f64905abc39f58c609b698b8e87df9cd84bcfc14a91c6e1123e3f3f86b0dc0005478a095eee4cc94a41c7eb6886337b43f28a60367d305aad6b0b2bf6963909fb074e6546b0dcde2d7e6148b6126b06d049b6bd69000e1ca3d2d304be81a8c7c4ba4094b5c4462604229af011a01d632573d3dfc34818a3311024b3e909d874c47718bced535da4414155631bb6b25f593fa7d10f6cbe7155a65094bcf66f80a16e6042ecbc4d85d050ee1467025312b8fac215af6d251c94f83bde82fbd898fb07cb52a9f585bd3ec905ca4937b9274ac47222d401ed917841d53efba3dce1f51d9a75d45d6a2b4d3d7fd690a7f715fae5c3339f5562b99eb5537f1df456f3346539426c5866c9f23aae48b3e8e2a4c9907842482698760fe8c02b37156a283567995426a1679482d744a6255382c1a851e520b999258110e8b46a187d442a6245684c3a251e821b590298915e18040a1874415122a43b033722de52ad653f030017d91f9151bbb64f4bea8567226eeeba33eec6f1ad398562d0626e2015a1a90d803683160220fd4c280443d40ab011279402d0626e2015a1a90d803683160220f341d891eaab4d1834a36d274123f5069430f956d84e924faa0f2061e2ab529b4dc0fe80c740afde3056a20fa57a46368f67c31bcee0ffbe34b53fa6726e4a89a06fced6987cf28ad0398caf8f03faf73f50f172903a0b7c41ec167e01d4e5962ff4ce854fde305fac0d4fceea9678aa5a6e48b12fb67eadc7d7b220266d2f9aa3ef8d93a75df9e084e4327ec7cf5cff101fc0c9f64382cdaaf438796710ef81fe21ecefee0d04654be2ea3cbd5f5bc7fbee0fa96f7e0a5707c73a1aba6db91e7c159069389de31f1b9ff43f13dbb143819e29fdcfc9e50c4ef1f481ed818cdeb4f56ca27b38b59abaaef9969e893ccf2493741ffd7c0fb3eda8fd144ff2feb738f943fc8a6c6cf63ae1f2aeef34f9039c80d89fa3ceeaacbfe6e8b7b54b7f80eef5cac5f99fc587cec9a35c44f92dfb03ffd32ec2f6dcc3f894ed24fec876311ad9cd5ad63e1a07518b02576469f98328bfe8f38d2df3f2fa2c8f5676991acbf85f8e61efb55fc650d9fe31775589fd34d7d7912616ada726b9a4ff54319f510f070184fac043705da4edd9d9ea8ebbe3cb41ce39d4236faf773622b87c97b4babce706b587ee4dd30acfd621e945de38b64cbe45b11d0aede27e219d8da5cbd0e4360e4978cdcb52d9bc057be009909274f398f1f55fce01bd90c7582a63edd2d2a4829f9c7eedc50e8aa458a98b34d296adcaf10fcdccb62ddadee946cb3fbbd955add02f5819dc0316332d2ad5ad2cd8323ddf8927e1bcd5a1fbe12b3406dc802d88def49df7b88d5e3081c77bebff6f5eaed6bdae1432a6780dfb6584438ace8afaa82341d0973c36a0e92f10d8bf3a7c40941a460c945fe2a1a10f74b911b224413e14fc0e2069d84f95d8f5f9415a2fbf3ee275ab70f2395a6c8777fc8cdf511ca6d4dea863a0d64bddd9d63950c21ad13ccd8295ae9869e1eeb86d0008981095453bb4fe47767b5ea18cd9ca028e9d6119a4a1ca429be822a867488ab1e6cee60b41a88fe46979dab962ed4b6300d021f1994c9a66f4fdf094c83fe6fda1a2502f22662e20c08275ea0ad61dc39dd92e0b856a12b2f11a13e59f197099656ebb5957c015fc56f075578b5f8d656b849698097624ebef0a813f92b2d809e891fbfda3553833aa8ea08dbac50a9095c99d003bd8abb9e6c363ddcc1bb2d14da03177e012912c1196d22c504b177603840e28ed12ce775fb162c00cbfce726134c16b83a9daec201573e2dc2017b940b0370d55eb660757a10ffddba4c9a9cc072321a8806443b48713f9ed05f437364152b7fce1d3207ff7381b4d534af5a1b8b05c54e79039d4955a81ceb8d8614ec2eb34c96f1bf19b8dd44c8064e4e528970e8351875dce73b25e04506c069db10d96545a67bf9131a48b5986f67673de33860cd15f79a0a3ae5fcfd7370d4e67f3841addd8d2a8f587351da7286e010a8ddc04ddb601103a94a9363361c696e4321d9a95aa89b1e4a8e65feebff66b27cadb20b911929d1af231b795cd3d30bfde3d12c137701657341cb78c11bda446d3e42908a36f5e1eddb2cb37d8b5d9dc8a4427107200985d44b1f7612d8b7963a7ea92da8d9211f217da1fc8c35da3831f7c80809f132b84a50bb26158961d40f0c3dce605df1b3afbd10c31a76dd108223d238838a7c6208a8c4fc227e2f3652b54ed40e6b64b5bd53676c69dd5614b2c82e04504997a5685ebcf36850903a4e027694e68d7803d10fda5b45c12d0f3d1659f0322344b77c6df7463b8abe5711156523777e163177780a5b2f1c7f67905c13dbdcc27b999908dc805be18c87ca07c219fcb138462a4367d7c8923d3e23a165a049800a9d8fc5cb0409e6ac9c70fd9b309c4921277f238b46f68ad6a02e6acb085bf9dd6748622ebea2057ba72a021994076d2b5d855d606d73df3fa5446eada1d99c947c4018ef763af4a761096b05ba6cba844def073b25ddb5c25a4f26edc2ce549e17efe8e8b289ecc2426e8cf4b20ef91607fcafc7272b198c8e021ac7495a593018d6a8033e7e47a939a6e9a720dda506bdf5c318290810d1dab9a37b86066157b5d0b4ed0a47a2b864e67f13875ea8b120000482764fbd177e5b4c4b1c1c07f7d9e022dba1b197a061949cf5d90b49db7b6fb9b79429a5148705a20577059d83fb48a1e8cb4af3170c0456a30fff76f1f76f51624303262ab84112a2a0fc7d889054493a02e597698f0db11f101ae1aa40b4ab4630089081f08e76c88ffc21c581c1d144b2a42dba56f94ba3e2076a7fb83160bbaa83a324d0ad2195c207bcf86579a1ba5d34e8f87725a417a03635f43c0bd0d5c20c23d508650474f20b9172621c2e6cbb668f43d7acc61068d6d22e9a134bc06263560a55beca13d445929ea05f7fd42e1958d221638245dd6b93ccbeb92dbb32a4606a6897ed2a9f879b2a25b7c4c8a28634782a2a3c51c3c5114349ade13aa9cd9f31c1aa327a129031c1aafb5df6cd6fcf02e6af173d37f0fcec0b3ffb7d19b721cb6c98dfe034adb449b6c8b8fc1c5cfefc025d2dbe0046cd3e1c22cbb24c6e4cc022b6b4f889321d8143da74aa3eec89d9a31019fb88dac3b2c427b968d852e30701c40ff12bb04070c448bdc67fb9386284a14695ec420e564266d58cb319da94d165a9d9f6b02c19911d50f9dbb74b7fe63f005181a7cf03672a953f5c28d42c32ffc76dcbba6dcb5ca8cc7e37c659320b34284192241f48e2bebdcb546513b79336f1c33c5f7512d7942968e836bc3339baa3ecdfd4020e0141dfc07e02f6ab4d8ec30f567ddaca3f88020ca76f5cb291b52c4dd030c67ed87e087eb5168bb4cb0c3d56993fc2e2ab5db827606ccc86b13159f759968131673fae5be4723c3af8c7dfa2132e7cc7cbe853ce12ac32fac5f391158ff4c9468b395cb44b04a313566cc172afe34724dfde3def3d98ef017f88f222a5a8ffd61525681863dcf3116eb27c490fe8ec342f8a256d1222f29136ad785cd2268eac65e11f34e61fdc77524a3cf7650054b99f5fe8cf819fdf18f3e8e0bf456913bf06c61d19d030c62a7f8cb94d14d64e5c1271c6d8137f7b61264149307227f83d0a9b2536232b3c09f3378c438e85a18f717809bbdac4af7d6c137b1da4510a0d272f8a9f77b8aea8a810ed52da3efaf33b0b875d8c13aafe140cb589e79c736a261ae66f9b2691f964379f13ac9cfbf4dd423843f53d6386a07213957f037be20743b259da10449b426de252e52d9e51436696ddd6b5df5e7bed43c06e1a5d96fd1edaa504845689f01a727d1e88f8c067d45e1f6df2f8bbe79d762971365c46bb94b88da24d8dc4c67016cbe27d4282b4691748b7f8072fd918ee9b7bba8df36edd62206cc33ff83d306cde3e1cc5ff04a95b5844ddc0cf67437c2e09cfcfd0a03c6cc34012b03fb6e72dc2aedc878065d94022bc22e980e7b77a100fa881e1f42ff440aafacbf8f669eff9eae12c2a8756beeac68f8776d925577852f7fbe341a6569e70c515576071c515585c81451082c0832844eca14df29d8b6ce4fec4f8fb246e7ff617ec6159e477b1a443dde89252d2ee1822ba2a5209c9f849a6501ef887fca5f1fbdb020171d7ad65b1820b275aed5cf475cb0365222a61ac6849526514558a4422faee0f72ed412291e8e3772a9ee84924a0a1503771fa49d855a8f21b26f23c0b103da85f209148049afe47234a7dfa0e4d8d8c4495e7a19ef7d9e03d28ce39e22dd808fba308391c6bd3d6f062bba430c8fbb502021a4696684e1c9c14af1d89a4f21d690434641cc6591691d7911559fed22c151c3fc54cffa311a5938e5e65b21131ce7ab18511b8e8937c3046302f68b428a59532113acddbdb692eec4b8d8d49f9d07bd153f7288df61ddff11ddf49614901f7533c0ba0600489e09a0286a29f6df2174991e841a0488483e32a52049a4cacf2be85c1c1c17157cb71dcb57916e00f7217088ca0d9f297edee06edab46a8a55fafd77a5a95efb25bb208ddee02c3fb6cf0073de8bb10e8b3c1b2c8ef2af68712cf19b5bc8f697c5a9d3878ed61595232ef4f78447530bed4a8f1f19e4034c57b1208f4e156d94120d067005441e03ee75980f620908856bb709670c22aae86172eb4b3116b5861c3037d44cc9af2d45f7cd527f951cc233449351e6b3cd678ac0147a3d1a847b4a9f1b8d5c462318f351e6b3cd6e4c89103061d3afec11d71c70e6fdeb1a61a8f351e6b6a542a95ca555155f3813b76acc4d023f6e8e1cd3dd614bdc6638dc71a8f353c764d351e6b3cd6c410430f93e97492c1830303c047f4e1c39b7dac297a8dc79a1ea61ad3c99d0229d8dddddddddddddddddddddddddddddddddddddd5dad56abd56ab55aad56abd56ab55aad56abd5ee6ab55aad7657abd56a77b55aedae562b7fb742d71ea50bba5d618f32d3a2a679b3e632d3e616b7cd9b37cee6c6755ef43c6ff6388ff33c1f108d947a33fdd0141a2aa1180a7973c885b3a408382e2e725cb19d2865ecc46411998ab5a93d9554911a466cac6aff48458a24923793524aace88192d61257cb9f38ccc1f027fef2281ef397ca6615858dea084b155d11a7f6775cd211c76318b9a8fd32a74d1d5d6dea6f42c3d8d3fbe4e0388edb7678aa597dd3ad56d23831174e8e9397b7529d934aa552a976d2af7ed2b1ded15aad56abd54aa552a9540a061d292929293c42b19d4eb59156b970729cbc5c2e97cbe552a9542a95ca5fad66b55aad56dfb45a89ab71e6abd56ab55aadef1c5213ca43c5c5389cc34e5e2a97cbe572a9542a954ae5afd8ebf5dae9541b6955db682a954aa552f9ebe5afd757c29123070c30e8d0f15ffc3e6ffe68b06adab06e5a44e693d88ecbe572b95c2a76a9542a958a7172d8c9eb89cbe572b95c2a954aa552e9d0f1df07823b76acf0883c7878338f14d6938dc558cce5a776b95c2e17b3f8865bacc4f5d1b503dcb1b2c283470c31f4304593c99b4db465c2b05c2c1cd6e6b0628c88c9f43f1ac5723ac7088b15635a8c653126632cc698c7d8ca8ac7927553fb6338124392dadfe3a687c79f10d164f2f80ba515b5ffd45a19a20c3278b30c0eaa2b32a09d53fb25aba53787d5ef81e11c7d8ecc09258fcf9c948e46ffefa9dba6901331789dd3c3eb9c7611716a0258e8560274991c8155525d263048d50e9495827838fa25a2f62bc5df628ca090ee3770a614dfd4fdccf69e6fc0a27e66039f06f5307e320921c4f3dc3760511c383361c251ca873012b528cf87b3fb4af287f82993a0100d5854107026073f65ef81a85f5449bef734d9af20a18bdac09290ed8380be2464fe33aa03a7b80012ed9174bf28076cefbd10ce036718b53df734a8f604d1be935fea8681b535db2c8ae024642b6a96657ca4665a0df9a666997425ed12fa4d2b7bb7420b105804f4decbb4dfb4cb327981126af69ea45d74d48c5129ef278dd7a5404140604988f6a0d740b7d19e51dacb347f423a90090c5e7508700af99ef71374d60e8c9acfa8f95912be7a6bbba7bf03e83dd008ef3dfa4680be5b54103eb4294b71aa1ae18cfbcdf3291fa44811ef415fa47b9a4283f27c1ecff37b52c0190ab2929f0181d97b4f83fa7c34a8aefbbcefa6c4ef791a54abc4cc9e0e64237eca2248e373e0165f735747c3dd7101e4aafdecd148d1271b53802a7f9372b485d68125074b3ee3a0906e66c8cb97e92ded7f4afb9fa741e594767766fdc481ddfb497a90501cb60a31eabcafeb3821de77ef810b725f4948f71cb7eb9ad37dd7255db0dbe22ff3f9b98f51dcb77dec9931bab514a4483f7f4ae55a92de732fc109ce74dc7b6091ed3b50c64fda735f4b497ef734289892044b0ce0b8df5eca196ffa497b99f620a17459e4a79ce473bb15de879517be6085eb09922ec4700213b280020a0cb27042cadb33b44c46262200e3465d262fd0411dd56552648c08e5470d4d2f5f74fdfb748c15184115a0880be520f51373f76e9f1f4db048a1fa5bd411cd4074bb12b69476e89efb0ee47e1f892248acb66d9bdb9c365d698719b6420bc5bd034afc0188a16602104375bb12b6d037f90b0d0fcc3801cb083960028422a87e3ae224931417d55497496a0695492a4a5d26295865a9abc51966d4fe94ed9f73ce9d5a9ca185dd9c1a7d63f5cba9fd11d69ef855a021918df1eaef31904e557f325e2b014230b23130b55fa68bda42f01a644040e56b7e00ae1998c3b2f4efafbfe8b0a7ee51bbbb0b0d94f153cf2082c22709ca7f8314a39c51d1d1dd5f996e5740cfefaf8d11fd475477633646e5f999b531349e5336863ecb6d52fdb318547f8dc9a8feb39754ffcd89eacfa97ca1a7f1a97c97f2d1f88e7e29df813efa9de80345d1f791993637aef334eff3c5177d9fe7ba19e0337034f97ca5f921c7e046c86490b80f7b09e77dbe51f7a13be17d3e1bde87fe45f5af46dda27abaf911fdaca2d0a7f20559167e1a1fb338b62ced5a1657f96b59f83d5fc8dc02ce426d20b8092a7fc655547e9154e12d8b2eca4c9bdbdca6e6aa576c45996953cb61c5dae5aa57949996e5b062ed72559499cc61c5da1565cc61c5a2e7b09a4485eeee46d291a640797f7f9f34059e010c3a7472e8e0d029e9dcd021e98c746ce8e8f84f67a46343a7868e4827a4a3a2f3813a2a3a34745274a80e4807dca103d2f9e878743c9d1d2b3a9e4ea7c3e9acf0d0e174361d1e31e86c3a31f4d0e96112590183c16030180c0683c16030180c0683c16030180c0683c16030180c0683c1609ca808c7ed5166dadcb8cef37c403485864a4854c3c68874a384e3c54ac556e9066964a346bf28070c3a70b88a25735e354421151a293abed42e560a057d3cffdd605516f3785d16abfddc079258a5b9629c06ee18f1efdf0055b5bfa76a878dfaaa5b6bbeb6d6175b8bf405e58fad8d592e251241dc38b6bb373b33a40ddd66651baa55b6a159651b2aebb4a1b14e1bead58cd0b4a15d352650fe58a70de53a6de8d619e3eeeeeeee97c5e8252177e58731c6180aa9c0788c31bae679a9ce7777b7e792a440f917072e942fa5949d19a030ba28c316b93db69432ce18c19a49d06b56a51155827459bc0f6421da9dd131f52833cd2700aaefa8fe2c253861eae43d23caec0b0150e317eea8d1b7d8264f9296c7793c207ba956c29afa43cf85738a702441f8a9bfe302a752d29723c237256ccde4ef9a3223d23d82bc2cf2b3cc659cda6f8c22a3788d516494184546915158fb384544124044e935c9ac03d59f273822cd2dfb051fc002567fb989e27f23124d999b3b53b14896057b826d220444686a5994a6d37f23124d492d8760412a6a3f17b42c4ae7548b53de3fc2a12eee94bff0a4a3d17fa7baca39cbd2af52058d0212b544558042d39ea6d2d41033f3b631d7791e8fd7715b1444356cc49969d263acdac7c310272fafda87801c322834c0c0d42003c535430b9496598165e9f761599a788cb106949716052ac1908ac806c963ed33f99b41a08235aad0d048bcfd36f2531728df005556a121aa5d0987d672e21d982d47c873801f4221151a3872b8dce29c5ae634a6701f0fc873430e1842503bf56a89cf9d0e117b12407f4e4a47a31eac4501f481c1db8de9443a441e4f6bd2abdb958edba3a886aaefce47b32fdc37072e23a97d82dadc446d0e01f5c017bfb8ca22d17e7c174db44064acf3eb81c88b3d3e3c999f9020393cb467480d321f0272a0c10313bf228898d5df03eb12c40cb86df2d9bccd7d3470698852eafeb7319133ad9fea96d171f78169397da42d0444689b5a26bd963ab72d4c2d93d123fa2cceba5af685d4f1794e4a47ad57ab47ab1f896635e148af9dadabb15d44b52343a4b2910a777777eefaeeeeee9c2ff17973dfb8d69ab8fb1638c944244f776e237351b42ca7d5e92fcbd56e877297799ae76ddcdca5fb4229c873800d6c938b5cedba6ee3c2f018bba04c05138a38a736c65fe484b2a768ba101494f7f7f743505006455637c396ba2f56b962cdcad1c27db1ca156b56a66561cb8b55ae5826b317ab5c5146c9aae82de1be1a147a8272a881da39936714bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb3a3ccff33a1ed16b3c72351eb71a8f351e6b3cd678acf158f39f8a8a8a8a4a8f1a8f5c8dc71a8f011d7bdedd24cba43637e991bd3bc6e8eecec5405d7fe10fb1dd5fede72d85c471ff13d218a1737729dd4f4046746f29ddab20436a61ce1e40891de7ce6db121f0bd36a710a0484d89ae93f509ea45f7e8b5cc5236b42d389e8a5f99492d9860d57501a1a005b4c00fbcd0f1828a0b5a88292089245bec6c210a619ce0054f5025bc578a971830b869a252c20c1475a2c910709ea42006859311911c38be48172cc9428b4997a0a1c951ec2480b2b2b10c0b8e559b9dd9999dd9bbe8cd6d44da2a0e9c659916b32c82d9cbf4f634d50a349cd2a65db40f679019e7835ba92d55b023b551eea3f2cfde68735fa33823fe32a71043d0eec714d596a81b7a72df150907ce1c81da585c13b1eafbc1019dec453a5403ea1f1d16a4cac1bba88e84e941bc27d0d084051016366673d8e69ef6659a46d3b4d5d014aa018d759174df9e1d1ad53df7b1913615490559167fcf17849ffc3d06ecc9ff890ecfc14f3e5a40504c33027f47234505f0d9d91898cadfb242582010e08303fafc2d30feb2604c4a47a30f02087fc955fad026183ff1f34a9ee02709bacf0bca89a96e7fdb146bb8bbbbbbbbbbbbcbbbde1deaee2ee920448d628ce0c912f509b1d7d632030c0d4c46a0641557b0842a6837844c0ada5d119ba01b0ea20da8a72e1324a47026a8accb048923388ca0b5f5377bd2518dba4c9218428d759988e0c92c4117768cdf11e4d9a6fdd2ac929fa63297f8b75a2addc075d6af96845424119c3902b57ee2ae0b6641a0347c5395ccee2388c131c6bad911763d4a912d915d73ec1986477777cf9650fe08a4b9f9477684936c8974cf3e214d5dfeb19fc940c6dcfda565d967f2d3c3b4c41727718ca28c38efa2c757241219906558749e876814ea3148c4f58aebf950814804f8457e7f107f91a08c156a831a0ba8d7a68ef2c9628c6d49ba96517e17a3a7cd1d6dc7e464f37c648882641c22b31f501b2288bac7403c0c84b8fb639b9e0318e19d4243d372b626ddaef00dc71a63eda20724ca8c3406f5d7bccdb4afdb02e5169393383719a2d307d49f5f93aacebd4ef34870c8151e2f149a5f86b003f825fb8c5df8c3fda2c2d42430902cc54171238b1b59dcc88234060d793e6e2cb9b1c455fdbb980634aafbade18d271b0353fdb9052b45150c86261d543f32d2a17cc36a93ff070443ec8086cc72c25eb48bf637fed2e29c7ff735aaa519d5e22f41b46843e41ad0e6167f09d2d2e2eddf3fc4a87297848ff4a905fbe305cbe22f99b52cfe9e13e806ce4cc1756010ae79936318d9fb83c4fbf6ecc0280f9c3902d581ccf2d376e31a8d34b661559bfc3f1fa0e1c682f0973943daa954aaf2b304291706690ccadfc5d45896c6a162635db218ed43fca3df6d7c2872c93420f3c3ce004592e03350dd8360a23c1a8c8c50de9b180807c2ccc040260882313536667ef78718480dfca3dfeb0fbb3ac8ac057b70883718b12cdd676484eadefb8c3c6a7ef7f9e0a7215e03030982a1d47e0ef4dc30bd25c771cb7191fb702fd3f26796a57ff212439889ba813fac8b04679a6842ed500d28572162d53e266ac74f89ca2d580cec102f41ed6f0e2c9b42860289da4d8242b7ee8cba0f0792ee47fed2bd8345f869778a9869178f9e0581f2f3b6a46b80a3e6ef4ad81f1cd0905d75a75d6446a4fbed47af5147c45f3845472846714ad54a8cf44d27e91e48234ba85626706265fabf6f5ae66c1411fed188590c60d4fc2ef3d8c523c538edb2fc623058324c632ddbbea92ae6224c06af76775bd52ecb6404512a0fa07227e9175ed227291608f3f70c368683b02cfc120cbd7a53f9995dcbc2ef398172e0cc14335d12a668bd52280e0add9e59fe22339be773196d6296e1a7f4c5ecf21315743f5374921bcc1df376dd262e9064dfddb44b57fe9a6f5c34ec1c092231f2a8ec1499938041b9c537fc6a53dcfef00d17eda473d63f2fe98453ed12d214a1bd0e35a0595d1c50991c3666bbd82a6c98e4a8546dd904b17588468000000316000028100c878362a1408e2481a6cd1d14000b71903462504218c942491283280a821808638c02001003085100316488b0260005fbce17b4f6881d29a9beaf0e1e4f45d5cde07a3507546d2907e05f419db49582a137f4cf4da46a3756b28847d0214fb810d482a65d0d7e3b905fb513621e0eed25e142223f37d75d8d2eb590328fd381b65bd5d8d3219d0ccadc81ba966963869002d109b002c886ac2af0a10e58d71c102059e31682f951b7e864bf422d07933ffea45b4eb26d01eabf67c50281bf2d74f327ca87e6b8987cd1ca97dce21f8f96b7706637cd5888ae58d16d0eefb95cd6d6a4d1e7fc54ab11959abc0bb1ee02ea9b2205fe426263dc0fc9dd6bacebbaa131f3cbed8c04fd9c2cad2d636154f341031fae4b78d32e6666d4be893b83cf3ac217dde84ef1451a095f073dbfe97e959d3a13192c7621eb0a91fcc7906c8b05926621147e835b9b5d2ec5bc9953619538ed3f7dbccafd7ffd962f2365936a94c46bf6a68547a3016161fdbd67c4f549c8f3f0f345651fbd73826ba0367377f61d66ec6edfb3559a3008300caa4399a79b050c5fa4bbaf7000aef37f7d018668cc9fd063d6c749052c4a6d6d611f1a9ab0f5f0a38b42bd1bca546bf6445b9db4a7059b7b67038ebf85f9a32d708b8af2b656497da12420be72791f9bf8490bd1362a43ee5fdfb5ce4017fe23ad482805d04c24b84087682474955b70017d2dec7765e897f51ad4d3780d37ac91d0329ede4558a3b2077c0c0b481e7ac01128d75aa7765304a2b8a98a2ad8352434eecb2479251ef4588685547602b8848cd9657db6db999997642478cb80fde0e18231aece89c3b22a294de7138cfeca1db5b9464ed7c177952b19645bd6b5b94ba4eda0a2ac0ba27dfa0bc13a8e2604b271475a52c3c94db0907ca22f61bfb424d515995212dcf05c968cc624bf707308eb1795ed1c9abc96709962bbd81447bb74ff714d8f7d5fe1de3429cf8b4b9a65a5d4cbea0b6347f01c35d5a08a8cec5d5b13c326c9a06ad87b3f990a024515ebe2c80a704a4c4781f869e67eb517bd832dc821d2193bf748b8447e759879ef89b656294158a74da12237d200ed5ac3bc2b132bc223af3c08d4d0e2e4d8e885f042d71e2a78fcca1bbf308b4bb7dfb8eb5e0e0b5e259de61c4a27f4ed10c41aeb8516124484095b5061141436c17a60872eeccdcd998413f6e3c3863d72f50f179dc97b3e3abb39aa45620d436a30ad05f325de87be40e45886e1000d03fb64c04f9d034b4adfc219f3cee90f10352f2cb03e0d7cc011f84936bb69d9ec80d34698f210228ca80290b749d7f340265448a7171c358a200ae05d03ee126b1d28302e86b37f01cd324f70af8efbc8475e869f5103858ee8254df6e6fef8c0d3d4a99631936843f61b24ac9c55eac46160b9d98ebf70eb8a6841daa6fe033ece10ab6d6b42feb45bcfe87855fcc3d1c1bc1dabba249b30e0fca000b1b31b077a72e64d3b5129edf7965c5ed269290e0835cd274c233bed84c91932b4089bd79c1aa5f6b562e286313d076eaa486ac8a030af3a67199279caccf15d93aadb5110f4bc2740938ccc8713038580de6eb6a3200ecd88d52b1e6cc03478d413cfd5c475d35af12cbabf1221295fbaa33396eba7fc9ed88c6c3f960778d02f78370b8bc7e873ace2d18593793d6654859163bff20897bd303d2ced601b487760a0df1385d1c75552be98b344eba32f6c4734d4a1001490528f66b44cf986d3212cd621ff8403c2a930929c1be2bedbbae6f8cd0ad3f52257141aed08e920a364f9f424647df122fc1e156f7836674af37b93101a1baee28a0821bf5592fa1e6c8260040d7a42d0e0ea8106af22efdd7a3093b5abe8e8893f69802568914a1348628d69bd397b864283ac786c80554b2aceb7209077cd932ca10b7bba7a99ee586b718d99943a0e52fa3c7386fb689a76050f636712f82996554fd07dff0d6062aeb6e18e883a4845175bceffbc2efe780dca4aafc8a0e698e9b508b403bf555ee3c9164f0b8250ffc9dc6a6aff2d0a1179f12f3810a482be568c4f3a4ab0a7ab36831a1ea0ec4898b759f7e29ce9a84451d1fb71ef483e899e3c5fadcec8746da9434279ba0f3155c54f88448435210916b2f6c15c7f5e030c0faeff62ab061a641cb2ddd052f3da5042f2560b23de4ead40344c60225d12a7d2b686c9026f56d859bcd8714ac554abf16e064c4ad795ee29e9a918786cfd4de0d2ec59495de8e2903e93c0d900d91a69a45c70928b3b65da9283d5c104cd9258f306a01fca01e792b5bd2d16244cf8a69f5dfe23d66bc800ec44282abf21ad2098d5f2377b0345614622f626e7be61d26006955c05be2b59435db319b1facfee44c2661d003e8334dac93524d4e814240b7c950decdbc3e3603bcae1f8c5c9ca9605cf7582736cf43652be7f8a0af4e05e6d75907ab9a73f8d432836af7769e9f169b0f09bfca60fbb91513b6b2cf8498a1973df0d220df26a3495e1c007f271972dbaa0d39d8a4e2c5d489f4effc9e12d8235e400a4e6fb7138b138c477740da471eda2ecbdf09275bdfde1291311686d9165b41c7a237a6e6ab0b3a1d1cad63959574b1eddfd93043949f0ec23bd5c5dc6feb7a745968125e19ad4891b02a0d1933e91c6ed72f0159e31a595faeac98a237c1cf5b21903b771117324da04aba881c2e5deade231a6725b52828f5db0e316c9e59a2ef65367654070a22bf6d8fac0e25bf86c8c0e3ffee96fee23e9c79ac1a75dc895cce14a21fcb5bb9bf71f0bc34ee361d84dced212d7586ea9e379fb2256bca51efa24a1e401018bd3a244229760231b6e01c337c439676ce4d04e564ad673eec39a4c033ff35661bc8c698fc9c80af8d8b390dbddf62f8f7e0e4061f1e4b978e6cdcca755192a2ac2910f55f539b894396dbbf427d8e35e264fd50ec3fecd971efe4ba86270ce592eca41966ec8efb5caf111f55bb70fbdf0e99b0217a0e4399dd9b4c7b0d000e0b7c707f4f5abe87824fbd3bb8ee5466440367ede854f3445e42e11d66789c91c60f38c69b737f96c6672265b193086cd5836bcc22dadf3f2c2b20f15f496317f4c35325093e16a187c42071c76afc493aa6160248e6b95537587ec8ec8053ca2609b9360518aabd2bf7d647ea04ecbcbadfa5fbe0958545473381d3169ba7b398738cf97470013b903d2cdc75458c1100878b6c284765ede688f0ad1c327a3cd4a4c3d1a0da8b0af49d3e3a0f00fcec0a6f289a4fe7ffc1c965e7d98403cf8e31426963afd00907439e157f53e883682713b520aae9cdc5446db589e27067f9255a1ed9a1248711e0c8915e89ad9344e196c269ce374bfd30f637b249ef3f1cc324b2eb2ce752f10807404b3c1ab3b1d1f540b0ead758d527fb7f6a925e14ef94dd6614262d22235645cc3698b0c8d418b6bf812cf05e53aa9e1c3e3555c468909a7fee900fbe49e4b02d6679d4fb3fb14cbeb53b9e74f4ed7b1c3f3c843068922c19e8311aa75e87d2288279588435648bd914829f1f60ccc604d7948a39684dbd44270ad059c52823e44722435097d36e132b7593cb077a6fc8c22f4478ad5d98df4ddd2c6c3828d30d88e7ebd87876532644dfc0890d38f37f193b92e2b1a77912ec760bc7060dce8668760561689a1b846ce4eb27c2ed834eac508b8e72e81dd04be2781837e4d55a4eaec91e23e54ca5eac9313a31a1bac68e214d38f9d1835cd64732d4ed2b82e7abf59c4472cadbce45814a10988ac34dc0dc047b24a1032a47dbcd7fd744b49b6c2f32aad3cd46f8d93d6875508a1a37d1f53a4285d54a7529c4b5eca9051a5f32085891897563e3a07e9f6219d9758ee28a67fe84f555c361efb629d8d317235b28d4bc67b7cdee92ba8e56df2170f99e7142aa81ffaba1d3f5c4031643cac41848266cce2b5d344c0544959ab815b3ac187fe51f5982f6ccddd791b90f1e130680e98d58addc0292ecff51c4e6dd3cb0b2a8f1c7ad73682d5a1448ec9471bad748d1b059dc1139a4412c20bd441f1ed1b71af6d49ad6ec2eec8fc52e78464755fa44c438afa82990af66f2a451412f333c3e1a4362d3195f1412a9560ad10c1583d4e6b6d432cb68f5635c854c8b8fcddab8ff964f82933d7f5bd5059a78bc8a1b6cd95221b2b79e2d40bd0df738afc4f9f964bcb6fa8a3a43a40324b070b175d234d10de7f11b6e2a2656bbb08ca72965f2b6477393dca8d22ecd7ccd30dec46a892f0c8980250d5b188387e559676f7a89ad9c79b43555a0686db21b8aac89e0dfbac885bd2349e39569bb856f06e252ff54a21b99cb466af07692936ee13d429bde79160a6331250760ec7cd9c58c62ae4227bc089d589d83d4a0273a72d700326c66005da7e1b7e779008857d4e02966de28a815abe7e02d7d85bb587e0a49594b50adcc7c5cc34a15522dd3f0bd92aa36d750e1f7d7b58b432a66ce29343116251cb246fa92839d92890ea064e1cdb6b89bc250bb11e5a4a9f29573beb224558ed41862d19652e56fe3c5b58a0fcded3fd96ea2710afeb84ceda12784e6cccc6f5c80d89a9a96425f30030dff237fe8913e15426a0a0303b0e32e9155274f7f64dafba0d2a916c2a61b79197e66b52d960d61b0b4bb323bed9dab06fde97e27ef638c3595742c716dbc0e4693825be787c9a2bfc52edb6c1646269bd7f1b9eb8d24c83982db85c7c8e43534db87a78a09121e2047324109c43f7c86bbf0e4d632322b34d55e329c2287e1052367dfc7bf6951b71d6ed53de82306e0f165b5982d0146e83e1b3ed6dbcc4ec70e7dac33771acf5bfdc562d5b2e62c86b90168a493b903bf0e9781858f9c6eab9a995320292bd9564fe7dcc522d18744a02fb6d89363309cdad689fc660bf7240f833eed5f2c9d74275033147adc3f4e9e6b7f295842ca5c759817d9dbcf2b242227a97dbe585f92e3c05b86e006a58060b6641d3612b07a2f795d86acd5aed5abc0d92d4bd55784a2671f3b90c9f5236ff95361fdb10b2d6d0f087c58459627e19846bfdc395cd6b8169c10aec49b70820536fe55b83239b1caab560291891f3c536ebf980c76362acc89c0a6248d456e3807791175196443d8438c41a82ec16e900c492037926f71fe119a3b2e5aa378833b7c7c0c695fe75358572352d577429978c070b636c5a6dac7d4b18c08946da5025258b426363db9ab50eb4318ce1f27a9844a74edb98d3c4fb8602523a2653c7b8b286488db34bf7dbe3a81ad25a3d98e9195c290f2f4d27d774353139a621c0aeeb8da500a44c9491f7cf905b0ed26b376808f2e67f4b2b9179d952583f524491c284c0a4411d0803a58fe20b47b4cfd0753b18a89cb6cf01b889d9583cba09cec12fa5ee096eb9e8be9104815817125a69ac5684737510209ac21349fe736d54c9d247d78d40b6732123c51fc1ed9062399c8411ff23e8342834ed256e09d431e2fd28ed29afc39f66fa08c9d1a0063a314ac5bf73188446301442261450a55f19db732736a129882d0a966cc2762143f2f67cbb15d0e459c1b0f4efcc9fe401cd57ac486edee4bb4baa0cf93cb48644f8d3d2df697d30bbf43d359642ca8810eb9fed5ab72439c2489fe1557710a15069d4601bbd78403bae98527845a0cbe923c445fcdd3e09bb059f8f5422fa4faa41550952d92d32f519bb0bec0119754885b31b720d340c54c31312af8acc3192af3acc4dc1ed3d1eb21f2282b23226237a180497d011a1378139a0322863af03cd4917de25618174de4e61837b90e884b39956d1ad61f6665e2b908df7986919427b9bdd7887f62b824cec9d30c6b35edf40897fb6cd200bed262b2ba692b3f4bad4573772060a42fc7eea04dd6a59ec57097ed09e08a64b409a4bd723d674e2c00403bacedf4409d6231903b73ff8636f855a47457b54690938407994dec6554b834535f5791e102d81e89cb52cced902d5e0d3689eb52e025fa34912ca704eceec6f291db1f2a292823c4fb442856afd49f8f721e321f47dfd54767d0a0d73bd745352e181294e398512920adccb7eccd21acda1b34a56a9a6e68496109c964e00b59392697e54cd4adfae0f2745da7b4730dbab9b97ab8b4d0fd52cf379b3c9555b0b92363cef2de0d877240f8858869c19a9330b234a6fc9b0a7f0757fa5a3fa81eba54a010f5a1908ced01e20a286161799a8c0a1e47d5dbf660cb58ca725d63a3c48907f0e0792b916712447b568af2dd6e7a856bc4e252f15874e13db33bb8ded6408ba4a129ed0e4c797dc11735527d01d0aed373051808590b7889fbc47d445bfff9b0b63132c8579a0beb980a6e25c6c4d79ad8eff55e688cd7d70916739835829337c8ec5c26a318201ac1c801edf60bf1d81d2a27912e04b967dfcfa9b48a11e36f173fdaa30e3a12e2655e3e751822df89453460570e2135f8bd13a4048cb95e5a20c81d06180b727b7f113cc31bb992e9548e323cdf76e3ed2ed5d5f3dcd2b30a1920286ba691f84e1bf456436dad3b876eec3dbd4698b661790a50a144009e213136f49c7a70989636d95dd03608826f134395233d4e7c626e2a864b1ca59e1587e361ab6ee9a09321cba0775b2021de835b0258e5e0a2746a0951fdebe269b08c3d201416e9fd090dd0c4f59f5213eedcaa5bc770d47b4d64def27d833992ac3b3dff9535fdd368066210c15545c4731ab8357d920d7f36de0595642f92aef68c87f87bfc02c5d78af932e062ce57155b962b94183ca546b3863b1c7f5281d199e891277adaaf96822257bdbe9cd256a7c9e1f6224a1b1344f72b2cd3dc4ed0c8b79309953b773a2a18581f80f4024cb8e32039be75104f4a8034caceb8987709750a10885ff293cf64bb0a313cd5a6f7af8d6b10a3c464becaf9949f6f290996da61918ef6c5584ad2eba103dffc7c8a853df31ac5e7e2aa354d24622fbc1538dc9ea431e2e9e71ffcfe570e18dfffb792cef9cee71e3f97dce878b33deffb33ccc053ad13d6e3cbfcff97071c6fbff7c764ba97cdcb8f1fc3ee7c32ee08375de783f9ff271176860d2ff7339cc0de4fac69b484bef619a3bd568e69de201b5cd40635cfe8d52ac51d44515952845f5ae2e7ad1892efad18bfe589de8a28fbee8a219ac2efae8452f9a41effad7bb363e87328db1f13486d627aa49eb969d3b1dbdb842e4fe68f6615998462d109ca816243ba6a252aa4ba542512c1505555d57556a75ad5629ab7daf1f706765208e3264a97565f4a03da4b0f1d503430150becb28d62cea38eaf8a88498015c03254998019aba999e79dcfc3a8cac065dff63693c5a1f9df3a800c5f0e69a2634b3c1ff3487b3939c84a62fa38942fdf81ad7a8c144c59d15a80471ece2fccde7da61b97b1b9d41004731cef6ba138a246bbcb1dc96bec83d0407a18acbc5b4a3a1c9e866236134be7eadf588af550acd0e1b658891fa235417d4994c1c85c287c8a9f389579de3d79d167205a08c8d56ae31e26b879ad42ea005b5450447c71a15ae442c11e6a10dc36aa3740bf6883268d99ac44f29333a4f4e9ad78382f1e34e9c12fc9060b2faa22b7b902ec60ee75b740a7272a35ab87f4c12b328dedfbedea32ea1beca1feddc2783b03582a7bc8e81a504869245da847608c55b00842538d13443a6e92eaa2b0cb01721ea50ac4c7e2c8abea09f85985aa802cab0bb2f29797dc69d9cb9e68721a98c480722af1609f0bd6330a6e820245aee781cda85ed5d775755ba207f3c461b57f78386e4e08dc440c856e6b831edc639a180e212d76a7b7e19a870c09c4102e1f078b11c0bf2ff2744f424030ac89f147a39a5837674d9d2206f9270438700420ea0554cfdec8837cb422660500bf39e7083086f3c5be917ecddb3d589eacaa8508eb51a03ec98b2d60a900799a03d82dff021560e3af59f95335f7c355d06f35634bb0a3f0866698d6544246ef65c71465d72b6d26a991b6eb6ee8005a59f0a59a9e5258c9bce2ecb99332c690580818d698a5f0acce6b6387d077d47c61c40e2608d97601000094079c11c14685409a1664734d67de403438ab848e69bd3f2e956973cf03cd639b482e99f7f8f33493a0d205ec8fda57538949222aacda8bc9f211efab8916af1c236afed673ad9a203c20aaabe09f9bfc1f486691c28d7841e027452156333e1517cd77af5428a5f6b26e29696eaf80b53bea8ae7662db9f8e996e3a03d8a7dab7a4c212a872a9e878f1105d0ac26b1dc011ad64040f015f132a6c4c19774d834b1e994a98bf82862ad3c06d5dcd5a2f77fd157f4e088892c4da050dabf24b7cf20981c2f94562c6772cda5807039e3c1924f8b3b8fc890c416ecfa66ec81ad4cf1f1e07039930aa4fe705674340d730b59d716f9094f5c60ad0765c956aec628f1921c147af0da2e647ca50de7f9251fd6690c2a42cc27fc1fbdddadc421ddbab4bb18439a007c754198c244546484616b3569d29c721dc97bf05fac189af31017db98bf5141e1a49c71689a0ad847301eb7f24112f341534ebb4e7df1b8656fe903fb7a49cd9115461c4ecf059bf6ab3801185a6d026f49670621c495137ae72b23a67bf0ee441d501b46eed1b9173c525e14d53f702e4964454539bb4619797589d8b569c931b010dff617b603937ee522c0d5221676d818d3858e7df204a6808c2ea3c575e6d98f9455ac2fb70f4f0209d5a3cc06cab016ee5c7f1af3ac51b4b648c56036c7730feb725f962402709399e47193a25ce74b21120d5057a0a7c22568b2e5db2280189eb239d466bfe2b50adbc4941461ac576112e2e450a46a72dca42b18f8bb7da17ded027aed0716607b2cfafd7f776ca210118279567f0b988fc949d188073de2c758b2dd7550403ac25068e3e6d2b67ab4807815b909b334f9b5348f8b686e6ecb87b75c993ed4f0b4c3405dec962ba094f7edf9579782be0e47793c441f152b133f8d97fcdab07c41f2f3e6be1ca645b0de893c189480ed1794d4bfc6cad25ea8359d3d0772b7e3106598ccb97f65f170873fe6692e42d94da4455f4c5deaa035ef2ac0ba20c1d1c1849692eff7ace9c2b890a1ebb12f7b84499b7dd3a3f03c3c93baf5f63dfd8b0f2895b60350810918892868210b9f019aa3994694e343b39afa1efa613732ffb5698eb269e5c97e664745708ab70146cb42480ccb7e047c99ef4a72b3525c4bfa3ba6cc846668074b87c1e8a00a4fe31fcde032ba36f0fe855955505bbddf3577880bd92862a8c2c812c7d359f4ea5df8323e09df5d29dec4b044ab05c3c6cacd0118d304e39c01509f2fec5a2c11253e6c2d82dc1cc4ee6283d985b6b84b9faa854a4906e66e59c0878cadbc9216f23d926660ddc99567993bf7f62cfcd7c836a796ea9a47439d9dbfbeb4f5df2ffa30541010a01d863e15734f3555d3132de85de743e049a53731bf6dff78f1c47913ef52fe15f997c3099274b5de4536a9e27d0df35bae4f342ccc4a01c19ba5fa3098f878dffed530e16e29218f6dfd4d490364e8e113e00f82ad09d0fce22dba092d7d1c07921bd938b3f8767e8bc5ee19a91a4d09e50a4adc7e90769a9adea57785a2c48bba8d28ed514adf753b067196be2fff8520da718b7bd97099bb068b39a314d5fc56fb86b24e1c3cc052ff270d209d9870b2a7c9704f1e426a75a1362c48db2b0af6d0b8be96d0f7d4c8be885fd56a9417508cd6410988a184ce842cb0e00fe8571e679dd07f7805bf84c2250a63400a3b39b560f20f485fa234200687f0041dbd27d0e1c6b38be4b92cd61b99fdf0c49bd7cc8fc250048b588b22d2786e171221526076d5498cb24549336025650888be469ef860aea6480b34502e7a5655c6e5061f6a30b955bde268508d8b009bc4f516daa52de35b9be0cb2b9e2e2f2303add48844ed4440776c50c399997940347a112868a7abcfd7021f6afdb6a075391b9842e785d79bd8daeec8cbd03322712263a42f68174ae8b02c6b7d865a269512045ac91f6226bdb27b61e1cbe850b39812eb3288404676e44ec4ed5854082eaf4059114ee989f780e8167ec2239d15c75f660787ec66fbd731604f9910db61d5d9d78c603a8add038062b55e10cc2205e169b3a5dc8775f0f051e598b41f3fcb40d8d456d2b8996091a4f629071caddb72f88d934d4fd2631ef1dbef79709ec4f22f84a28210b0959eb6ac74067834765074b066303924f742b034cae2a34089cd717bb3bc0ba2a0698b05fc0e30f82a18807659223346eb7d79107fdf2d07144848f8a46ad0a42f0664952dc0c008fa68f235bac8db44d9517a5ca8916d75099f0170e532b3c9e5ddd55e284285fd0a6a50ca736672f84307aaeab5c54ce84893cb483867d91cdde5beea9a9ea7a7c532a30feed2fd41d6c1db6f68ddc938bf59f19e3521926a66b631bb6fc9610c5575d86932f2bebe43a4495f429f3486f0d21123a244a5a9b14c26c51e1bf1542b5a02047fa64ef71dc66d86173e793e143ccf4eb5c32eaf1e1d2607931068740ed724ce1b64440417e11da85effecbb9761174b502500d4059817519ee3cfcc025d2cee5eeb32b1f8a5bf3a3eb0280ff62703723e54d28d0acf4e992e12779b899889b4380339b52a06f770dabce2f9fd5ed9ca8f6439b051300f427fa20e997101b5e32612bcf98c46bc8b7018c100d92cbea5859bc20d1a85d60922434aa9135aad73369e1f1a1882b8cca662418771e285d55b3e73add5649d544b38282282902517738070730665e4c3aca11c7ff212dd60b16f4be7ec2da9337a8b6d9bd96c2700f734096422726765672530912d1236d9c68763cfaddea4b89436b6b434e4178079fefe087241149ff0e5b7ac437a459b64d1fee880d4dd190bb666153697e2b025311f2b96756896a147045cfdc017e4824eff4b59021c6c653fdc3ecc2252db969db1b70db043c47c3391952410bf78b7b32395cfedfa9e8b9c316b4d72055ddb5efdee16b7d37e1c89741f7cfda26658b79845dbe3ed31e268f619cfb538499f6b3ed6ff3b341b0f8572ab1fe1f12402b9da065ad294b7afd339887eeb863825b8ab9f086e787861de99004cb0cb4937ef9646b94487f2012a68af5a173075a022480d50a4105f430f4a59e6787ab87a8f5815da9f2c4e441f7c288e03b467e367b3796abe45b11cecbc0013c4592ded0e62309737eed16912f28dfdd1b5026794b6895455c9a5bf412e0e79132a87e1c972036b62a168b2fdffc77cf17336f4550eec1c5f4ac3a2779da10a1bd0e1fdd56db1eaf8216024e4820d5b9a1c35983a9c43840f65dfa08eb8fe0c70539f6f8849a7b9c74ccafcf46a94f14a292365a1ed3f22ffc8f65794b622d4094f6dd296d4850cd9592c8f41b3907dae8d97c0ae9c749ef40d167da4a8707399af32ba54f5faf0734f3758d01ec812d670582d8b8bdd46eb90eda8cab308c68fdd3e702630893c3334127cf5c7ef5f148e4c1166fdbcb0b33ad793fe01df26c7f1c13ba1b264e0e4a807874284a1721e7000447d6b71672f72d2d7f5e2fa9d47dc06c9fdd2988384b2308e7feecf2af7c24200241ff6c9f29c2ad357f66e810d41c4a37c4b1f6e36429678c23f0d7656e4a412c38ff0f207fbe6262a1924b94913ecd643c3f72599193d3bf938143678565e8ee91107644cf8be36e26b056a637d484cdb067b59d93ae9428faf85219c6f4afa19e5e089192f22b4d316e8fa0a72768f3b3b84f0e0bdffaf187bc61cdb26ca201c5ce4c1952c268884d04f070e8d2c399dd66219bf3b258a3410df45b5d1b7464f038454334fb6e18a9878fe60e6d9aff54a1dc0a03a3047af4311dfd90ab7a4f884696297a53389e63f2f833311271768f693aaf932cabfd381f82bc8744575137290974db74c29537b66fd326af08cbe22a13dbda6f133122b76554c69e199995a1e47846cb589991d932546ecf888c9559323c43cbad8cc8d8322bb36788dcca28cab057130c6ede2d1348ed038041005ce5cc4606deeb3ec28e1e9fb988e26a71f3b7d3106fc709971ae26dae78131f0c6ba02f64bc4c92c9e59260e51bad772bffd1b24dd6de477c1d11266d8abf59f1452c38b6195d4878b25c2609563ea646214c9ab53f5a55ef1871479641a3d08cbb8afb205d7267100a0a4de5982c7a03f13a4e90d4104f37a8d8f2d0c4811f8c15c2f4a4339ebfb82eeb09c6abd44210c798b9ced5e1a2c7a6f0822ac3da7b452493663a5fa4e4d656fafa509ad44e23b5762c6023c20ca7fbb2aa0c37798f9d598d0110dddc4094dc0e7faa0e02a26663617f17ab1d6860d2530731851cd6ed20e15243accd95f73cf3d0add3889dad4ececd422038d6845e4830b9b08b879b3d693eb51d6667e8067bb3abf117ab0904ed0310820dc5b507b2e1dcff3869ce483fdeeb0976747e34e1cf4c686e4844af2693dc7d637d2a7d6265b02dae9ada2c799b1023323ba364accc905b992bc76546de9219b99db9e45666c85b9995e332476ec98cbc9d59722b73c8adccca9c80f45562279f45dc75a928fa4a5cc4caa7f5cfdca2e8957811eb2a5334f6d6ea55a157c48baceb4c51b1bf6fa47d477fcd2d8a5e8917b1a6322b336ffa2ceb4a6691d8f45b6937d257d04562f78d653ae59e85fbc0b883c969a21529d416754cb1aa46ca928039f9c995f9483feed6700cf85d4d5254f67e2dfd69336f43a18e51d6b1d596fb01ee8119991fbb2d5c9e648504641791756153ab309aedf25069131ad941bc2ed89435a2fba903e8fbca6376b82e2e2293cc407c5dd8947844635622b871d21e07dee240ae7010db600a5caf2fe026c86bb928202a1cd264c0ec007aa0d8fcd8aad4c1164120d4ad9f4d85fa35550fe5ea427993bcbc0857076094f93d87243d24bd6a93775cab59a43967b6323a85de72aaef3081e9ddf9b964c2f2b25bf06202eb0febe6c356a532b0881670115e8af7cee54706eb5d143ee0faea2ae97e81cea9ab8e6471406a269a65266a13a5a30c62cdaee9b2b99930f47f730856e6d4ef60b5efb29a3f0e43c186c3c7286b25dfcd326225210286fa146f249cb5c5869c1f8830333b51e84a79913f665c8be66913e0458325e52dde8650b79c2a218043662d3b0690750f601280a5dde71d24a09400cd82e96fac0cfc147d4db9fbfd77ff62afdfa706c4c94488254eae581ee0c6d5ab71c122730cc71a25b5b2ee5d8fdf3efb7a8717849c09de1899170d99f05f1ad887cf76b59df77188b6bda7e0c2577dc77f944dee3dfecf93b3aca7bde9d03a315cb1f534d1446b87a2b5b4a345150957aa45e0a78dd946ba0beba4bb87fe31181520dffff7964e10fe5f22e4c726803953d178d4844c94f029c4ace4a0ff43b2c49baf156615c32dba2b4a21ebb91cc546dac8176734185ec865fe6c376cb4886e423e286813525e3f343986df6667bc729a08cbe170cf4dc650e45d7033d5751e045405a83c196fe93182bffba654aa8fc467cdc87ed88bb4539836be6228e35f8fd202488be2b64f5c17d6c2b63584cbee2162448f32f062cd62ab8cab3100ab1653140a0cc7aae7971ffcbcc20fb666095d5ae3256273725da502c4d2e45d5086c797356a607fb388b033c35aaab3a297897e89534d2247a6120dc5d9c3efd7a37e6788339b02d6b50d99240248aef5a205aa46d3d4e262ce1fe37b144031ee35a736f38a0454844e94befcf2e555baa07e17d15aa2c1810ab7e1836127222204f159a08dc8d46b871dc2685a20e2edd9cbc84ba98bf86fc98fbd4eb43f0c02af6f26f63341e408c7fff291055852c780494ef6277771a326358072b9ac8570796e7f8742054c3ab1f9b970dfab64728a76c7b75ff4bbf735d63ffc1951c1e1ba4524f916673829fa62a7fc65f3aeda2d249a025a3efed6fdd6a8fb8db3ffbff6c6558cbb1af530a0c103be275503b3aa6d2d86dce2ceda514a8f5b802a7192a6fb1bfd1a737e3ef41fedaf86cd84a6d9a0200cd3d0a033be72635ae85def5a7171cb61d3e9da78370a9e5e9852c9cf19975d8922c33d8649333d08703ece32a0910db5feae5f275494425f46e889af24688c9cd2c3f2759cd410bc81d7273ccdf5ccc015adc2ed9f20b58faf0a336fbe5de0c5e064861be09f3758d15ff2e94015261130010421bf8c911b818e2d8444e4418f96f7e7470eff917fdb04d3a8bb9c1e4c37b9e78042b11eab21ecbb56207593bd6eaed1cdba531120c2bb0267878cf1bb044109bbd970d5d03229f7bd2727a802887d0faaa4dcd35d6a26e6e50b2465d6b27e0b1c58f94e98f0f4bebc8d5326dbc2565d160e08a46680654b8f413502df019fcfc7e57ed89520ffedc7958f601dbbf1f1a215a350c4a3a940a435bb0b7bb7fcf8c6ea6ea67b3b6ec4a7bb76da9b0ab54fb3543cc67e62d31cdc615bfd21c43c11efb0367dcf333f575fb100763a77ed0775b12664ca670f87100916ebcc3ef608c851054e2b36d0a0a6c0fc508125e952d6a558eba51b676f4c32884ce5177807247fac65d610de316e335145986dc1cb4fbc5a0c573e66b93e83a4e44c302f842544ab4fa747548aceed2cdff62ad74a02b5b4cb25ee33321dcd33ffc9f186e34fbd47ab868a9ef2cee4df7a392ed7b274c3bf6165fb469b2774c64f130b3d5fb0a4f1660ed8b79b1b1bce740b7f10921c9c486b852e6ab506330538b9b47d89fe07a21b6e4272c9a5164b381f4632970a870b9b8cef72b0fc5a4039385afbb874447319cf597702b6bf6c9c97337915b04d6ad86f8d5cf3ab4bcfb917d18b43ed0eb04b9b1d3da8089e28128e7ffe8951cef6e5f6eb4176b2c9340bd33d950065feb0584d96d9d2e2b7eb54de6ab20a0615ec9d33e4700a802f9afa9feb435a156839d71c1399d5f0455af705c456aab16a06d4d56d73121180126e849bf972cebdfea7ccf375c5c39fee7ae5722196e1a3cba7da59d07939a19ec469bf01ac0077002bda54deabc75aa32770b7dcfdf1a53c2d3ba7ea5564c432e04f8bb6631ebbe737ee1561e261bbd0a4ecc7144fcf9cdfa3e0ecf31230845258f3fd0b0269b4e8502872e07d49894f0c09de2d3695011b399a5f2aba40a38ecad04def03ebd9bc001c97ce2748a9fe3902d0c2c679a858e790dbc4a29e3c5300c340fc72ee8739f3a35dd8f8cd442c73920cf2a8c1c51a00397b07aeb034e2077a04dafd8a16b7a87d3996135a4e2dc67aa1c69ddf3364999d37a0aa590e02b215605472f8a4a8daca077dffd013d57a105ac9e82a9bab418a277eac3334bc8c678599d2541887b519f46a1416e62aae10a190628e787458614d12f3eb95d121d3758838a97f9d9eb0a2d1154f08e54ee2a017821dd46c75c63e2c179ab65bf8349e08f225f5bddfb0d124149c5c731c067ccee94873b226386ddb4b2b3f888b9395bdd25847f160266d6378627b73c8884e3b6abf6d3b2ad1d5acff2173820616de720d1f466ddffce3642adaf78475e7278a4fccba22966795c820b0b76855093a0c6db541fe363ca61f56ce4dd3d50c863ec42f7a02d09dba40cb4b40bd29dcd1473257ceec75b984568ab358ae2c0c198eb50a294a3b0d38716cbdf7807b0a86a97bded2cd9bb2318703e9f69406aafdb359b216d7bc1a7f0030b9d4eaba89cd6f5c33539a6d00800c561fa774a4eba0f643d6e7102e710601c6252fdc8f95a6ef43b2a3576b797be80ddbf62523cd3d5aacf8a027cd11b0bec5f205b71d586f62cc0cb86dab54d24da3112c6c9c60bd2480da484b8acd2f4d8caefffc039c5ba6532d9f5acfd3322abef8e812cd385bfbb4a5efe23421a76909bffdb9b7cb5020f38d4a09a40aaf46ffd6bcdff18631f0dec9a8299643adb3681122d7ffe38bfb087a0603ba37ede991f8b8b6df4cb06f3703394fd3f30cd0f3af15572047c3fd57aa29a76347a1cf9d3889f44cf4b3560f682215e8db02dfe2d984dc56a54a5a18f145793490f83b2b41212200cd39fbb05bd62d31bcc7037389deec24b466aff038ac3dcce5e35bc28d14c393949df53f8e893d0f71da9c709bf26211b973c74934a24f23c863f99c84a2e565fc0a94fe0a95aadcbbffcb389c98197be0bc724537fa95d28e58c0657850efb81ef7994db800c349cf1f5fb9a14a4472d4b2b466f2aa9a8d773a44a00ff2bc1e71200ce4fe2a2c823fdc03359866a69dfd5db15ae5e9f9b835c676dcacf6fdaa86da5d891ef66de7faeef6f4d3a63628bf97ee8a0ca5e543f7504e2c19c75a5f6b414f6c4a132b0281dd6122db9f7cdd097e2c30d8613fa6a0c22a7b1dd0b07d0318ca464e02165eee3dbcd6d0b096aa9787611e55a60fd151c53ee54cabebb09ea04fa702aad10e7fcc03a4229f0a7e31884d2e4f425ad57db5e5ea993de5d46f1a6a00810e5c7715bdc60436d41060de8b860efaaff2becf87596ff5a027d37765b02178511d7cd065d96a1e6c770a5492e146ea604966979c6be59a1538eaa924fffb60ba4024a35995ad5fefd36c7e34e37e97be407d883de961e54128663033f43613b9166d9b2d9444dfe6eaa20847477161d9a00a4aa360db8bb536929b5613d94d721f9fdc6923d90e23ccb0a1d7c14fefb0ff7699dd13e79f72648e306c6435d455162b5b0feb4a0713032c4937e50adc2f2e698a7275b60cfd39875ec2451590c72c345ec1bcb7b9cb27c70135af2416b2f03f22f0d8435791f23c1e6206e884284d911f374ab35f33c07b414a134e291f4d811ea6222bb7274d3984bae9f1cd1c906fbf6991966a8ee19a027693d9bfe28962b040b24348c897714c6f8d74ec569a352b9725cc376bb2c1c4f5b713101f6399cd95e81504b5fd32f182d64734ac8bec34d831b3a754cf53895c0af1657f44ece2e264bd3f61796a10c0465ffcc6cd6e458a26344a72a25e262137ba40a1b7f3cb4c0f91874456215f76b3a7dc9808dc612e3ee6be37f1744d3549a49565ac1dd11a85d18e3a44ed910267241d3486db0d997f756ddcae0c1adacbb0cdac568bac3ba961c209dd294f94a443ccc44a5470acabad2122410ca829a618ba2e62af10a3d96c6ceb5f6f86ecb337ab9e873ae62ff324603e1869ed68d51cd9417ef0937a6c5d574adc0d99ac932b09a4954bf957322df04d34452a21f37d4667e9fe9d0a91d69aece7f2941d6020c13080b88f01843104d10a39b330aa70368879eea0821ac825b82c39b14e8b0d2112f3ebd612b2611bd43977dd673e11158358d94924054d6b699bef08be564ac7fca2aaf643ed6e7a9fb725437be489429f15d40aa65da21a997cfbca8b353f3cf464d5a6e2c0d150ab948240a4d2b7325f7154eb292f5524c1f4506e7ba5cb2be78daf94a1242274d04274542739a0ac85afccccabbb9812a275231201885a4b79a747bbafca7ce90592795cf03e509c99ba646b6b3a4878de876fd6cf6cb63f239f2ce9000158d5bc09a82cac0bf186e7503610a05e928620636cd55e764d7b745517f270f1681bf114941169c729afa8347849da61c3ea5dd7f252129a041448dc923de7bf66111fc5402764dc7a5616b498a9d04c94129fa0584d309cd0a8c5cf1c8ca5c95f69a828c2e755c3c2890eeb6a47dd4c76d7230351c296dca0f312f7120762d2eccadebee5f9349c3900a875f30be402b32c379eb5d708e2095253afe7253869615cfa55907d9afdca74ec0df1869e209e5e71762f581193cf09c569f6c88258e7a22b7af4d2363956608cacb86687fbf7a65f6b49baea0eaccf1fad7ebff0ed71d164baceb39688875feac551358d34d15d5c664ff01b6f794d2efbf4cbb9b8c14fea06e1fea946a6c7ba0024c01db4a77e8fa0712353f3658f68c624f84fd3436faab0a6f8f8260dc6f569967d452fc59641c4839040e8a65a7d02f373a0492ed58c2cadf14981099d01f0e5f453a9db328f3990e3f4d3476361724cecfd58f3f5f872797030e56cde61be6c6306fb7afa555c9cdcc117fcba785cf5ca5c791ea6b4a2cbe84d8b09f64b2bb492c11d97d2f00c0640b06addd0dc9a2b79838fb3960bad03356f2b5bb106887e318b752bec05fab4580b9a9e7fe2d09c536f6e6cd639dd1e9bcd74d63b3043ba7380247517366cd0e43ca4e66495643d3c2e66bc7e5d1538d9bc4d3163546054769004d59733dc1460ebb8aa6ecf1ba1dc97316f230104111d998a7b0d0308736bde2d5e4674f52f3cdddb769164a463e3a1c2b4b51426c78ac18bb3e16fd4c13b9945995b67872d591415ca8320f9de3211174ba92973eb727768bab85ef8a264e25b512de054444ceaa268cfa92dc51e58e656b1df67355ac35fde3f7be49d0fe7e31f07d15c722becd5d64bf72a8fbb2a764d51cc62e7a1c7712b700ffa9082006899b36406c4db31bd96af3aefc903495e63a15974557d40702dadaa4ffa993ea948360aafb4a569dd05e20f52015040c17b74dc3a174ecdbaa8310ec03be770d464d41c87906b56ae759888ebd83c689796fb13ad426d4add7e64c26584b27124a9b6e1475ff822bc34e72ec8e2a521e3095b6c9d7b07ced6881f29835d6f410b6d46c7857460fb1267a4003da8a0f09d1d2bef09a783abecd8331dc2f2ca0350303457e6ab352fd4cc652694e34be9fb1dc375e26f573447a7943c2675927a09b2f0c4d11fa965aef2f086bc5c63a2141f9e1295334b6f13ccfa9f930be51e29f1d479608ae5805d0d00571cd9b4146e153dcca0d68bc27e9277d5699858f429779d41a34c80787895507fcaf08080896cd612d4effc13f44c2395e05637cd2a5a6eeefc755a8b92ac4a8a16624a45b083356eb256007190bfd83c1f6e1798577513e75ebba5a7356545f45f2e699e9c4f39da6dde31230b5ed8be2d7f6e6aa14cde229c89528c07a60db1879a03509b9f98782222a33d357a3b9f53c026344b11fe3dd8640d9bb04cbce6efdf4d104f9d6f3a8ca420009ebae6d65c8d57eae0cd4771f2124cd31a2828730f81eaf4115f013e9516511a9c4bd3accb0ed182ef91a878d2ed1d7fa630ea733734906473e55732b560cfb7ebc5386402d4a011c24106c992303bd6eb3156a3bed738f9032700ef1247d60254fd98cb6aa1f5a2011d9f9d90d91938244df814d0d0856a5bd4cb312f62c1959104a13b3777a5eccb7b2200af4cee0e85d26821655b330aef71902ae930c63d72ac151dd84de6f7b390fa40150ba15126090e3be4c711185cac9f36f4ac1a1cf22690d7b75522184e6faf8649af291aba6d199f4997c56ec45c5c5d67107a8e5ffafb1a612c26b22422c8da1d08cf454634c181c5053d9b5c2b6343fc56aded12ce067c9e85d46df2bdf3d0a900e999124b65d0437e113e873a847d9cec9ba7138aa92f9e26bead440e75b8ace0f94abc28092940d37881de3e9d863f58d16bb59d1e8ac953bef3565439e055dccf7638dcdb31994ba53d13c1736a14250c8432610b6ccbc6e8d74ccad1b17ab390ec2d978f5447a301d7150cf4355d54733dd272553ba038a041b558ba902134e12fd7dcf8b0b254400ac37d01bc48f7f85f8294928670ee04fb9350b171109b8e9e7c647d9561ab60d7401ea9cdfdc28d8c3b95ab6e603303c7711af62be57896f2be4bdaec58452a98b44abf14ea3f9e5e75d66b6cbdac44ef733796db8b57372e5bfe14f414337a337f1e553489c01cf5828e90a41e42deec0252aa400d15c5a045ca20aae02403208ae3fb9f89f62f0d4ac7792208aaeb4390abff3442a212c6f433f2891229d8cf50a8dbf5950cc53d4a20753074992ea7240f50b0fc68e724807e40b2c6adacff626fc22816a0b2609187ca18db7c46151096984c1f777f486ed2a45a49dc748b72dc13c538f7694a76246cfa70e68144aac4ba1f204c809b3e58b73e2822b10ff1001f665086520a3cc97a25e7ed7fd349d80626c634b9cb2f51de4985b12f3103de65a62cb349b5d221b6daf37aa1ea4215f229ed3631a689e2136cbb0e61c96019333432449aa35c78e2a3f7804b501b561075cdb6a60977214ef5551af9690f072099340a3317604e7ca8549bc68b7b243857989ef2e650458ad6490f9684de62b816bf8551bc466751dacb3953f429ff5b198a544a10376f57fb0771383513995fa67816d0c6ac58101f8f9cc5f8d6b8607e7a266bc6a4f68419fc8142a98eaabcd52bf6b68035071043040aa542b336e67589c6ab67affd753fd2f79349a6df27e6590dd804436720c1f9fa0875c0fb2bb67811a0433b65ac1767df94cf340a3aee267ff418e5b82ea8b36b1c2745b0ece32d76d7297b4c9461e7697bd9cb987514214e2c3ce2c8eb2e12888830eff45e80347a0c054142b6ee49c8c81432643c74ee17e14b5dcd0d4ca3d8a0b3b14e5a52a4bcc97b201c9a9263665cb8a28d09fdc4cbd1bb7ff1b73ecc1aa54e20d29b4d9e0e3188e79de9d6353025975d9cf4908ff5a3187cc795a11f67e93040dcd6f35e0c3566e51ae9fd814f1a130447ef6320800329fc2d77fbf96a493fcf1a2774fb44b85f3e0618e301c6d6bf4475c91a9de6885ece69d8853afed6e5376da4bb0ac97ba292f329e28727940e23588a50a7851630896ada8b986806b7ebda8f445206834a2914136c20d2d48a53091c35e2956d5b1c5feed0e4584ce3124a9d4c1613258bec0471235b0e27aaad7a3c20759c584877bb7835484edd45e016dba66d770e42a5928c9d0720b7835290fddc6a44b239f4e4fbd0b746071748a00199882b286cdae4212032f02c28a3ad8428e282f4e21916425d42aa7c1cd53ab378027bd3ade5f161148b869236f1b080dd27b3791cfdb48fd0a98780647d399b440c99d9a6f291391e61d3a94e33ffb0486dac91939016fa36ae11e5feb1a439ddcbf51a6eb795097a5b131dc30a706c1aff987de45923142851727e29b1973da7e06882545af35a695c6f506c3cc1b10b5e94b90a8824a60bc0ad81411aef189e32b20ccb09646bce97d2dbd623d8e41c40305f362066ad5df5e4a8cf000d6549d2c5deb1f3700195f39b9d10e2d46e051d9b68f81e51b375f64ebdc0d9483d77b48b6b2611e432c0d534c5485894b845e40895a53d0d4698a406e64524c6061f98b22fc1cdc9d7ece7347695bf3f8a3c3286f062c46d3d16868b7f4456688e5dd37d369ce9250aa119934ba79e6b6e28a148a12bac41074ca54fc08155121d0a0a427b8b436b3f62d1d7f0931c09599f44b38c2153444cf638616c2ba9669b9ba6253dc33892089f812faaf60d0d959d61b1bad73d9e3886752753bac945d9438ed2e49bde1c873e77964b7755c67188fccb983b72458aaedd637ce88db3d70216ec9c269f98347c9e00dc81909a89f64b411bd481dc46bf2069b387c4cdf9c54b0a0431be41d6ea651cef926a96b47ed19091899141162904a6d27939ca107db1e33d7c339c27045a4b73aa561050e94ad2018046bf8572c0cb17fd296259e065a8e98208871ee0d5bc7c2025565c4de787ccfabe5ceff83c3df428b416c0d987353fa3aea4bcb7fe12fce4de71a3a2b7ef4014cffeffbf7f238434b237217bcbbd03340aa70a850aff7e6056dd56bd8caa2523d39d48f734925c820d55c94d4413b42ae48e15412522bdfa329d4aa5525d4767150f4fcfaacb5df70e7faeeef274ff5c376ce06aa8554a1bea8f76f1e8ae7accf5abbb02d2aaf82703cd20860d82bf9f0c67b84031aa1e79d407c13fbab0f1db8bc834d2f89161c26adfcf76677c21fb76b5f842f66c9ec75e2a9bd5ae66216173fc8fee39ccb2a1ce3ca0d3d191d7a30169a491c66cf188c7af4185fd58344db46e1b2c563ee22b1abd9cbd139f456e6705db4188c97db8c119a8c28ddcb74c3086a845fb08813b7d893f28e60b38d5dd2b29ecdf46af28e51d06a48b1cd741719c50ccd223de28475c6448bd40dad5467cc908c83066049353184d32740aa3957dcb5a5eca4a4aedba6293ba3944751aa7543f86818aea472e33f6e76fbab0d9677c219e5e2dbe10717ff5f3c929766957c71cb1c4acead22a802ef4e78c327c31bbd2ab21e620acfc62cc923d1b26d6e20b31e2c885a3b77ab1f45bbea1fcc567f28faf8f5ada4571e442857dc492a52394cc1256fe8b5031490530069824b560aa39b241c46cbd3a030b6db242b364790a95250ef4db5bb3155455dfeef6edf35bbc0a171519290922c4833bc23c85815178e6db2796b96a2acbcb6d0f8a57e125aa47158e5fd29a78e63f5e110c48f7195cc4bae7bd93ac5aafbae458f153f5a0edaaed41f0f5fde8e0bd6bcdd6c4aa6bbfddd5696ef4eac8a526c90617452c4c5cb02445261abbea1b2c462f1b5fe442f3f89917c1806c577d7b110c88cc69705194f90c96c145316a46858bc214c5a7ed698b52c530aa3845b5d0160ef4fd568683e8bb15541f5f815a0a0859ca30a3e9e8e8b53acd6140ecb973dc5707c2652f4a02c29d061735871b0b13f7af9338262c3229cc944c0ad353ac6be3d6b83717ca1d6d0bb349d53f9964f37e110c0877fb2218909a732f924f6ac08be62b5c0403b2ba0d2eb2f9ea1617c180d8af70910deea7a2aec14fe26be6cd4526bbd18b72c912b732fc03a9eec81bbda816b923b9c717f799dbc380ac660e44e633b808365f242fc30588cc2d2e924c7285e5c422b77f9269c34b5e9fc4b244855b40bc7b6ffdd89e037c6d583e489b2a22094924f17474f4924549fd529dc9f60eb7e625972cafb38485afa8a8272905941964910518155ec264c3479e1818175044b1c4e1d6c43c5aad1fadd68f242096bbc2e1992477e42791b00b4072cad04bfe2696edf1b5c92919c6c32d20db396d4aee48d90a8a2fd5e36b322565095f1d6e01515d4a4d4c965785c9b235f1946ad77ccaf2f54e2e32a78a852fd52bd218cdae31069cc2fb35c6186bf748254c3965ed96736e15ce39e7cc5207ac1cfb7baeb24e56955666584a7929fb08157f2d359c6956d3b4396996b1b2c8659996cd3981b438ade020ecc9a60eba5d369b1c8cddabc69d8db418c370626d863122bccc181135c85c404416a9a945d3683665f3e0f899a15a960f50f284d225a58cdd6f2e73ce3935add3346df50e673068b8d51d464d7bd7d596866bcd28d568d775d70173875bde8774979e76bf6e28ab5eef07c774b7b64b536d359b61d878b2f25687094b23d52acb65a3d33db407d267946a597b714512cc410dace4f9bee228cf37d29cd789923b47b2150d5b9d60fba8979abaa78594a4d45498ba0ac7d5cbc0c62c77941452b752436991e31b899e46a5252a90e6c8d4b4cf0391c9012142434a8aba87e2fea2a3a0d76a30ed9a1f236be91e988f586580a93c51197e87d9474454c9306418a37284cc452018f5754d67d3d9475a44491fa9d47d34e79c535289aa2db777945c9a87e2e923168f75d5ea649f68ceb0f2312acc54139832aa7c213586982c6a7182da6e94227ee91e0d6fe112bb3ccd48a516eb85f26ca119c6a8486508b3d9e16bf7f4c4b3b229055d500795224017cc9fa4bf3c52b8ec50e793504ed0cb61c38b8d35d2b05fcd375358a81613cb68573c81ad73aaa60a472b5ab42b469dc06eb7d1c48a39ea327aaa7bc64824f99ec68dd49d1b0aba105f630c7b24d5f336b0b0b18907c78fd478baf81a9ba21274610a964bbb4dce6564cab00d2c6ccc5fd4d23c4013c70f0db225942a52a86923669fd3ddddddddddddddf3e644a438e7eceeeeeeeeeeeeeeeeee6ea6db74cf1c22af3ab771b393599665d9e765be49299375f29eec54aa03494eb56973ce4ef6cc66c339659fc1c90f11868a960c634344e5efc7cbd1b5cb86170bf3d74812a86df77477675966030b0bbb491463c38a9ab5ad716eabb845015ad9e2215141a2c2715e8e27e9136b7d7a7a8a5312e231da957161586168c8a03c986b0e214d0da661b166ac058acde47577b78d2f361e478a8d3da68f5a7df88279aae8bd5d3176314e25718da48d396aa5a58c03fa9e57af99b6c27dd4384e715ee7b1b2878dc4fc7df37278f105730c139f7614a0e1f3c07611c95b62f25e9f799cd7d5faa967f657acf4a9795669e08e8d633e450365ebe9e52f92fd93bf2c8679c7d1bc1cbd6ae8ddebbc43a8759c4ad3ee5dfbeab4d677ddb9bbf26a95d9b6775e8eadf33c8fbb102b7b5779393c8edbb6acaa75753a94b531de3cf434a3accd6d3bb71d48aa6e6bb1ac76dd06b6b526ae592be038ed46eba5dc4c4da5997296ad652df9ec9a7c96e77be22edbe4b63640b2af8d65b15cadd358420da6c04e29e5c4518aecf4c52e191ec1c6179e3c79a6504ebbb0b4ab29474a6a4656b4316a8f1d334f513c8231c431f3f38b165f80998f5179cedb54b1b12956e99ed6ccd686c59461673f6f65cb90ecddb72c36f372789ff910ed146b9f3997dddacf44ab034ae52fbb8c54b6d728cb5c21289557dd63d7a9344dd354349f349226e3a1331cc78fa6656256cd29c169b0cb0cda21fc15cbba4ef7d44a29a5d70133c5add55734c6d585b13ed6aaa3e1213c328821b8c01b641813a20c21c064189bf245fe7e3819d84c19b6165adc70b1f7d1b54bdefb212b17fb592e0757b199b0d5231b93e1fb08c6d0f2882ccbb2aab5fd2ab3b8b53a8cab5eadbc0bb156329c54adaa0f995f9dd2ab3aa3dc6932efebc91c48aa64306c4de3e46ab5ba0e9857ab5399d71be5be5f3794bbab54f7aecc85b7b6cbbbdca1d719650e6f4cc417342b9f5153d60e24eb85d86a5a205141a2d24f52587982024b549d5341e8825d55376659d45d628dd68661c32d7998a967abdc91d7a43452cada547d3ebb9f518e960e98256e711f226f3397e56d6c88a73c86bb9013427c619e6a538b8c822ec429052b4f546cc9f0690aa50c9fa440c3c6173be171a4587849ff93214fbb8ae22bc387b5616868a307cbd2aee19cee8119a85df041c840c1ca0c634ea600214f9e3a854a8e39c6a4186fd383fce544e54f27274765c94296f2564a14b23c2b882cb2fc9bb28c2d4d65c963003155ead5426d100c2c5ab62d7890bf9cdcfdda3d1d8b1283dc31293f8cc9fd8ef30632cf39e79c2e252d60cd90809243589a614c4907f9ab3c614081ea34ec53d6a1e414532a220b27d5184f968cf0431a4b3f50120305441a524f49af264c514479f5000503a527284b3c791d2da97870fcccd05bcb4ca1645719c69c383981a5c930d68409920b6b338c351982f4c2ca64186bd283a52656d8c83086d4a53e81b6d65937fe2894104218b886ce48a8121c82182add0373930a59c2d81155b23cd542b920e9b6a9eef9346d4cf7cc25c4a849491fadd62417b28c52e2944bd58f5cfee609c600bb68b55acb62fd2e170f4f36a2fd6423571961a7a87e644382e4f29a549cf28a535ea7dc1b30aad11364d8c089266c90851464002102290c21927c10c41390bcbb8f73d5cbe1c37a3e8c6cb0c1c78d59f37a6c47825b3db62339123cc4066e7a37d03039a75d12ca6d0189501ea73c4e89506ef4ba09c33e7ff42893ea9eae8847231ebda038c4a3141f1e8d38f482e2934729585b8a465c8d29ca1877c85a52bb705e609744a5c72286d0a6e4c3b48be60afbd123198fe4bb1b95868812e5f0158bb8ada0b8f408e5114a5c3a7c7538d8424b5621431c6ce194abe4ee1c9312e77531ca8d501e976e543a85de863330ed925b269581d9303dda22746526c8dbccddf69edbb65d6ed84897497d4ca49703c993c88e3303d33d48f0679449754f26d52ecdcb31cf6919d4e4aa3b506752dd3374f90c0c92432f07450a72352bed921fba2def317b9fb7e561ad69c31a16312c4d4282e90d14ec91a3095dd8ceadbadaae7e514c7a5cc24551e971a92802f1180517452887f2a318c49744251ce02b064171e847a5c728373e2edd7e84f223076aae5bf270d05e5fd84f6bd29a600c4992244972247d6294cb774b92c5fa6c2ef222458e907b5c87cf9b69d12e398f1c39f223dbd0912343478ee0cf68fbbc31cacda062140c24772427c5363da25dbb3cfc11c14236997b875d98a75df2e7de0daa0cc45b4111497a4062d25b41fd18e5310a5e129dbc0f5f403242b9f01595bead870ef7db2972bf2dc93512e58ddccf956310b728bee20fe7c1f1f37a9c5bf11733cef150679c1ef61413c9fe512a06ca6dd012e53e2e5fc528bd47131395a2d234a54a4939ebf2f4c80497a7484597a7494b2e4f95985c9e1eb93cd5127479ea6474790ab53a225a72ea9e4f0297af50f4f2c71f70c3791c02df71d80c687dc3d20c9897af34d741c4695e8310a7798e204e731a986e730714f19abf7078bec08130f00650b9cd1940c46bbe801d3e83052ec394db3c06215e73059c02ff39acc07da4dce63d576210af390c418e43872760e80840f20324394f3cfa0bb1871b2036b90b447ea3c80b60e40450f21d12dc5582b7c07d00dd05e05d07c85988c0710ebff5df1e00d501700e7a13c09f519ec08f5c228ae4ae2e112d7289e8bc44b4bb44945e22ba5d223a8454c408f017842402fc61006975c40448459056abe3af0869288911471e997008f077014c54830e13c21f0e464c264b8e1871e4302441461c96e449f0878311414730113d62820761a28a03fe828e014c547128c2df059e04137543f84bf22398a81b3aecc84d80bf101c03451c16843fa1e35004f60187c3827e01fc0dbde8b024f83b72132029f21526aa48ab2448921c8664045f89000903875d20c99920f992135922020f2972222b23fc6d4bb308febe77dd8960226bc3611638fee2d112112343ac1ea96010181d26047f3f8630129bc41ef04787581d56c4e8468638ccc88de0efc7e7103b50233b60a26a74d80ffcd980896a3cc2df0e3782893a22f833f2151291c35646f803c17f201df6e33ff027e43620fd38cc06228f478719c1dfea46453efc596087c33afccdeeb069a48891c38a7c07fc7598c80e396c5ae0b01d8c3c3629f2d8c3bf734a42600fe0af024a3e3822fc6da74af403f78189ac8ffbc05f05de29f938cc031cfe883e950edbf0c779d7c97c9c823ba0e4300ee0ef06275e09f0b791007fd4c93cac53f21b9cdc70cf09050e2301f5488089aa92c32ad13d4cd4c138fc799f98a883cd2bc1df0d4befc06137fc06fcf958bae1301f44f8e3aee4300f7ff344e7c007f0e7014c54497058ddee7598a8f30eeb4e02fc550013d90f1c568157007f14c044b6028751e0f8f35e82c328feba93e01e78855283c0b547c5449d04f057a16c1bc09f06aec37bf4386c03114a555d22ba1d461fa5e00ce02f48141ef00781285b1455147ad826814781c0a304398c071a011e305195c0611508ace22f02a798a8835109e00f0219380c028700fe7a2841e0b01e40f0570f845e02e741f50d13d17c25e9af086c0013550d1c5673780430510753e12f02df3051a73a6cbb06f0a70326b2790387e9701df0170413d97c2542c13ee8705890233df90b9603fe54cfe1b008e06f7b04ae8103c9d824f6108f8c982c2932410948a08428c9bd39925be343d7c68f5c156ee4debcc8ad7122d7c65757857bf7e6ddad71eedaf8bc2a5c756fbedd1aafd7c6e955e123b83417c1ad7908aecd852eeb432ecdbf5b73105c9b0bb9ac7fe0d2dc03b7e61db836e7c0657d0397e61ab835cfc0b5390f97750c5c1d7e811be416b83a7c871be415b83a50e006c1b05d2b7c02579583ee86a55df212b81a941b8831420672e5113d3c292147e0522f495ec420e770b51ff480451919870bdbd5fa0f28bf21ca2110956ec3bd12a1e0a2f88a50eee35e89517051bf2294f7b857a2122e92af0805236d581a06f97802dcba537ec0fd6819599ec7fdea962cbfe37eb58c2cafe3d6703f3a4696cf71bf9a25cbd370bf3a469677c0fda8952cffbaf97e744b9607ba0db81f9522cb33e07e144c965fc0fd68982c3fc3fde8549697e17e744c968f415e01f7ab58b2fccffd2a972cef73bf2a4596efb95f0593e561b85f0d93e571dcaf4e65f904dcaf8ec9f208b81fa592e50f703fca94e579ee47ab64f917ee47bb6479035c17ee47bf64f91bf7a35a64f902dc8f46657902dc8f7e91e577ee5791b2bceb7e3529cbb770bfaa94e50770bf4a25cb0be0eadcaf56c9f22cdcaf76c9f2f8defbd52f59fef7ab5a64f900dcaf467df58b6fbbdfb625cbb7eeb765c9f2385bd266a3c60d952c6f5325cbd7582932af3a678d2895d161ef57f42dc9347f147f49a6ff8830c9f4f053529473a55566d51d524449ce5e6fe0a6cc50e76c3b92dfe437a6ee911b95cdcaa694b7a5adcad6b4e958b17d9461fe28bdb407487d802ef90d882caf8a92e5b92959be2322cb7b4764f955125942988fa00bf2877c10a01ddaa55cda251f81b8f428e9d2a41f2e5d7a7269930f17ca9d1a5a902e7c452717beb0ab460cecbc3747b07449fa08a9202625c609433801092f79ca244f8fe46992acd1148ffa8627513bcfcf5d5558d84733b2da25e597404d9b96250363d0692be02b0eccd21ca8559799f976b96d53c97ce62b28d8e778247de809c21031d5a506506c79658f49d9896457927dbb42786035617968571c0282558289b42bfb0d14ec4a4bdc02c57c10caa7b56557227d5a1bfe812466e7e6b26ee33020357ef39b9bb30ee4e62c5c04db5e04e4e63670d10de6913bd96be09b7ff60673ffa0930df4db634624e599d3cc5ca6b66be635666574cc76cd5c06d776cde0af66060b3950e364b130ab6eb3cd2b9775f00bf71a3d20d2dd4f4e2f0797c342176c2e3d1ef41baeedb239977542846c9ff99c79d73daacfcce04fc826cf9c87992ba48b9df907a53880856c5bedb17de63277c8f69973dbfd62a6f9cca5c1ad1e32575d470d16b2c934f8db9e24aa6e9465bef1208385acb408a15c6ddff054d5d894bd86165b2306b6555348a89259c8b08b18593227e3d2321e84fc0892dd9c1eec10a12ee3568f6c887cc443e8abea9fd050c542dd90a8aaf1521ed98de4ec10baf0d56b30ff00568b32c4478f3b9c5106d5b36b5186eed96b9401c68a98ca05c83096a484ccc56e45856daf87ccb7e32f6eb7b15cd878557cf722328dad1621a66edbb66df1daa3a323a07669019906639e7dc3a5e54c1a7931eb614786385ed878a19f0c21b43042419b2ccbec0e383fb0f1423a39cb325757cd9810a708363ebbd12ec8d2c4b881858d2de574b59114b00b116097b90367093636107c583e600cf1164117e287e346fbecd03bf1676a0c3165089982833a36f130f6e438d9afe224c17e3c2a968e4b4a95ea33436f5361a12ed7eaaa3c76e6336f40da273afdb44f4c923b5bd28eeed10ea1b20d0579fbe7234364822f6cff60e8bc1b3c38b68d6edbf69c262096ad37d595b96ddbb66d2a8c469442a5faf6c8a56eb54a93963a43358a0365bb1b6f9fb933db36a7996ddb66be6ddbb66db14bf7386d334e799be9db2bf3b4e2c971b2394e424cd8b66ddb54dbf62a7d74363c24426d4300c118884017220e9e191f56cfac3337e6ae3f15b390607f64a712faf971655c973b3c31af5c3f97a7f12eacd20708278cfd205417c475a37be8e5796018f91f1a80ba0e0bfd64d5a5d78309194078e2892c04c3749c2a42294fc33b405a85833cb6bbce0d257247fb745c3e407247cbe162bb03c9a981fde017597b4e131662a16272b786afcc1fd24763e538592d09470cfb03489088a54a6cfa84926abfb10e2b27c7c9368e181beb8df6812fed56bb5315429d0ea094526614665986634626f1679465d639cb704017a0f6c39c734ef9020eeae8d03eb32cc70c1c20d8f839a7f402e29821f194cf5a714806a7300f26b79061ec8a14f94a96ecca307605296359ba5246e6649759994db24a670d632a19f752bbe8b56fe6a1ce116bf4d2e634ff6a8dcd85bda3e16f6856e95373096f5f73692eec1dfb694373858766a69d777598b0150fc94cbb43ac63481cd2e12f0ec57bff8664d492e50d0fe9d3d38cc39f51e321f15996de0d598e38d35452a75dae8ec571934e218d953f21791ea8a98645c0ca130f899f18baa08cfc0c632d98ca1c9cf15afcbce7ddd04e79664a3f63dc92239e197d2749a19f5e0e9ad452b4a5a804a544199c2ebc81cb397b4ce2c1658a67d870a060bf5aabb5ae7cb1145c44e66cda19703c882d673671a660b32c4e4a6bbb6c3661171c1fd888d3030b315d7d4a72146c7c7603889386fdec8ea91ffc0d65a19c11c919fee617cbd350d557227d6a9d92d2877623c7fbd5fc59ab75774fbcbdb68ffdf6b9695acddeb8bd1e04d882892d72967d66a31c27ab644a0c9c4ac3c643b8a35d8d33a589319fa0d30f9412ae1b5252cd5b792bafea0049151ccae88553db20ec66cf1961b6fab4f959c5ac0b29211c62e5b76bbaf2cc34ed4709a59f4dbe21d410f7c025c9f210edf450e61e8b83abaeebbaaefb78726d97eaab5985bfa10c487a591e927dd6c3e6b2ee35a77b56de6770b2b0aabb6ef008fd64fb63af6d57d75de676acd5b56957b71d489ebbf6ab51eb5aa6a7145265c4a37804052525c5c31829a8a2306470441a49a814179cea161119ca738ae02773f2274f9d1cb95a71c0b0dd659ad53d5346f5d5fd5c1f4fce5cdf8e9c711b16d2e951c485094500236757dd99b70bf30f949a3bd07982ed73f583533ae4e7bb648b13041ba48cfccd483921d8a50793207ec0c1127276675fbb22805339c350dd0507dbf5e5885eecbc0d94b7e99e8c005b30c14566f550ccf88b096562f698e30907f1673394f23866d896d734ad71ccb02d6bf7c0980358348312bc607931814d1042134214e500f16262f3e425316c18be2e3f99f2a2e9b5c51831985e9cece42d8253884213985e4c56635eb061f8410a275c5e7d5b605e4c3a4622b65a5944b073ab5956a350020a28f86283994d289480a5524a9370861356c03c916d0c906286d4ab6ef311421784640792401d855839be68bbbcd18b8b77bb78e2eff17e3c2d20f575bb2c0824e7b55b8449763f568d512382cd5eb1e62a3bde9392542e87b2ee06b93fa06081b053b35e8588b75db2566be9b394d7ee6794b5225cf775644519d6430f1a6578873a572c85b85f8301929a94d066996581fda5bb6b77d2d2141803cccdd47d236bf07eb3239c3322fd905236847ae149002bdc641c2e40197ec017a00f4f873fa19f0ccfc15ba7b0f014d776d1a41b335c037c7cd4208c494a12dfd621acb535b3cb2359ac189beb2e6b7166b16506b3dfeb44b1f03d46d6ee9a71c29edaaac543fb98e47825e931f6d04181ed56d43e2376e599fb77681a99b9af400f07f87212d378a90ed437ba07e21bedead76aa19a3e1e5f57bbe0b39d08bde0f0d235e2e9f6f9abbfc3078c417e5d2c0c96dc1962113f9d8804c7c20f2c4091130766e575260cd917968a326c4e86b11f5810c40f50aa581b19c69e94a1048612969561ec494c36b13619c69ec840f3c1de64187b9282d813a57905d7e7e0bbe6ee98f5b5b97eb1353929258f186390983ffc020b9db2ec664935ab55c2f8aca79452ca4ccac6081b0f7fa2226bcea94d8929a534ab734ecf075cec18a3ecdb354a29254b4a196396318946ddf38a58a39c59a6d5ad9350236dfb4929a594d9eca694534ad991954969a59475ab40646764676467646764676467685a46a59c4533d3b42a55098fba6548905243439368b49452434393684c293534348946a6695946b32c42d73cccb2baa9388d522476883c1e5b96e7b82d664b70ad6d3f763cf110a4f32a8fcb05f4f343b384532c4d6665b39537d3c1ee99dd03a1cb04d9ac81dd036f58d26713b225d1711e77a3da3a2e1e694d87a015ee441f20a845ce6accb8229f9420227fd0a9d150e20914bb6518638114e614abca30c602273061678631162c61bec0d20c632c0803c5022d82e05285104c523cd132a545e9e5849623acbcb448dd0c633f8051e39c45b0e08903e4fe4cedeebe226515ed0a8e90e5656cbb008accaa5e2fb25c410e9ac6c8f29ee5b064512396fb064d494d5ce4e827414c16666001a607afcfe6dec1142d5d4c456972c619afeece5c905b0919e4eeee6e191fe279e27fe277c40791f13c401534c9f2539e33620113130ca858f124a90b6845171c9cb1120a23c4754315bdc8f2f2158d197421a54b96288ea6cc644146183fd83284a51cb4800c1baaa5a089fc4296cf8460bfda71d1e5bb81822c727f36122dc88d041ab9abec2077122dc89d8418399ae7014e600216259290821241642f00030851c2f89005133f3a3a6ac2b2e245ee9adcdddd2e96aba7aa499e6f2fc76c142465f91a44b871441104106b08c1419dcf4265ed3447d76aae3d4ef55127f5929499d25c3fd2766dd32c647a09907fa44f8e4ed63e318be66618c725f85a612c3338362991372ac5a5c824e447dbbe1f7be7655cd9257da0e69af9ea3fac9a4b73abdcd166308be2cf955d5962960c162277a2162d7149ee683682b09f87afa8256e11b2e12e4c55e1203bac6e54ea1ded1d95da45a976a08e42a296242956dfd20c585da3306b3b72a36f6d5bd4227d2017505d66d6608c09296b49593b94e28b4f5fd4226b9af6da2a15d23d5f4d0a1395ba67fe90b57391f698995ec7cc14a86b9c58f9af5aa82e0a0775be1a4d7772784e76937694d2ee1bad45620daa73435474695e9d76c9b96d4259f5afbede21dbb96f9baac3c7ae2f78442837467954ba71e9dccf0f0fb7dd1f2e76fbc79371d4f0257a39f4e3d2a397438c4a8f50ce492f07c4c96263561d6e3db4dfa288e4e41645278f4a0ab030c62445861966e96efbbc5789fced92dcf62ec8230582d5b6edaaf358248f4c5fe4ed3cb6dc7ddefaee6660a040894ab705242a19818b3426a51bbde661cf6c6f21a15bbae7d3900487ed9ada275453ce32a816e42ccbbecc24bcc428be3855aa755e8e7eab07b6cb30f6858cfcf1b4b4f85284cc45149e9f9fa9ca430553575b3bcb032c7227f6458b94195b5e744089913b2d1e589b61ec4b53b65f98248df212042f51f9bb531338892774218f91633ad892e58d504ad9734a1cfb32c6684612c476c014cbc20a7c8a94fac08b0ff2079d5a50b6338c79e1c19cd3cb0e62145ea072bf7ab9227f3c50320b2cb0f0a284c5115e624d9ebc5001c4134e86312f5672cd30e6a54aac4b9727a6580bb6587f787064b1273139cb5e6db21f1e2b2c14d33b30d72ba67a07e6af569a617194b32c8645949c65599665380716f2fc3c85913bdb13ec09cb0db21d34c49a7cd0a92276c40f55c482d0410ea0ac0842ac49942a7280841c484da1c579961556ba3861c51649544c6a23c398155458b1c50635a8415627955a8565ed9da69d876a197e14559561ac8b124e8d050ec6a8028d2e4d4ea0e85205098a2e473881a28b934c338ce160cc0c749af0c3184f3c30b238cfcaa9a2ca0db06c7182d6a1c10e9ee8d0c0a90a2f3a3498553c51459679050775bad5385a7b576d4e9dc1f60efc07bb64cd266bdf0ddb3bfded563a6fc094e116194285c1c1ce7072b097d05962099d257e725887507842cb11134620414514105e5270c5115338b8624c13a270b788b181a1a2e2098c8bad16d80f46b5c0c21b65a31cb1944d734ea618bbe1e315519359d30014bba8403ba0c822cf39e79c73eef084329030c40b5c500427464c527c884aa2c90c9ce8010a19785038ad6490cd09850af25ce509052ccfa99dc105f7c17f5f3f6a9a939665d94fc62377ee275d524ac9923bf07e33cb2c3755199d31524a29de0135c55377192b8da82e59beb0e2451832368044185b18d182263c0105c50f128a13dcc4405e9e76416b93616c8a22642ec3d814512d84d60aec07a3c4481f16deef29e9a3239706f016c0fbcdc5d57ae7bc5778bbde2ddc377ebfb5489fbf3f18f5c1a80f467d30ea3df3a679d7bc6dde8f4fac9bcb7c75ef7d22d24785f795481f1ce814750370d705c0b9d8ad70e3cb7557f80a78c900306ee10ae005f80f5f2bdc03f50ae75ab83636b7c14b726e6e6a5a2c16cd8d2fe8e5b862a3e6ba6e735b38f47280af16ae875b412ddcbb8797ccbc05dc0aaa5180d770dd156e05b9dec25bc04bec5db8158473d75d78c9ce71646e7c71b193b9a2428e1f3207ea1d16cec20b708b6041510933c0e2e84580efbc8889eb2d9c003b9889abb3e4f8254c5ac0473ad7c132801ba704705be7b6bab782feeb04fde63ab8a57a2be835ae839b85dbeaf08ffb56d0f159c02d0effb0f156d0596701b754f8870a6f051de72ce0a4257c2394dc89bff7374645a71bb9c89df8156ed42277e2736ec42277e25b57ca258666382a5cd6552277e26d5c227227bec675c99df89b789b2b44eec4d75c1e686e107b77c05badf4e1f961120023ae55547015c61039192c34d00b52446fb5198f46ebe86968d432736f6c3cc7951a331acd3dface7be7ad30a5f1365ca3c448853122ef75d47b905610cd6b5e839768a7397c4d9bd7ccdce6d00ba2bde6416c6e6bdec648ff48cc458c140922f3fa20aaaf9ee3caf6224145ddb9cb3ca8c8bbbd6a2688769aff40a2a7e14e4f835bd96de099dbcaf08f1af8061fd95c28776aa0dc91cd74bb49ee18297224e6224572802ffa1ce08be64582b48254dd55872ffa20ad209925de650e5f34d701671ed405f16862fccc6d35a7bacca317d45df5f6827897b9bc31432f0877d5a117c4e296c12df9d5817a07943bf7c78659d8456fabf10f1eb9c384c668768501073b0b2c8a2a99bef03421a487933e52981940c390090b333c0554c19473d2d02e1873810c8e300332aeb86209d0074f3f905a02154230230b15797e4611cb53853c9dc873ce39e79c72ce4315e439a36822cf9a3cb5e439a764a24686312e50525cec2f3ef505ffa3a1d7299053ca9c765521a5759a90920b0db294b7699d26f08e56125cb0e48f9535972a5c8cc81fcfece934856d0c6e4a7be10528b45430852d1b83db21a59cd262353823663068311175727c0603a52a528cf04206637c98c94288219cac50d181185c8eb2cd30f684982970b07b5e36c3c30ed4e00b2e615cea47cc2a0bd95b2998da9c18a8ca1349c81f84fa0135e77ce20879ced9c49c0678228cdc3d6fc49e90929a545c88a3718858189b4198fc75b90f24755a039127939c2c529423ac3f6294e587c8d767177759dbfe75d6b216bf188b1465a73428a39f80caa7923b4603a5dc2df3177fc428cfabee10af86f8792e4bb2dbe156e310f97aeae5985dbb6cf7689aa6f1c8ae0d918f9e7c7687ccd71abdcaa32921493694fd506b924c4707883975228e8e0bacf6292ff4935b27b0f4b066287dea2b49cc114f2c829face121f399c45038986bf77c465c7735c7bc1d1d1d1df580a34b8e5fa0b630217fcf71cb97fcddc831ce2065048363e2841062602529064d482c48217b627e3a4900f211a31db49086b21f1d1d0d653f55661e3456ae18e2a7a59410a9bbbb5be670610298acd3ea213b7a01b725aa51aa010541094e7ee8224c131bc01c64b18411a22863ca1365bca0d260664db04ea946ab642bf024183f4f2c3d5ccaf4b3169129fdbbc70099d29f27b5ebc11336d6739cb8028866dd092aa038c1e5c9e6353104575960e5c3e028cf64187b8152865e76a06e4da11ad5c91fd5d16c9029a53fd00e4a23a5943a7951ade5c3d4789ea373a325c40ed65d309022dbc830e604152796584670f2d035676abbde99ccb2a8a39896a6180cc46453f2644c482925c4577472fc4b44c8f027e402eac9349766119329890cc20c8939e78467705fcc38606cfc8cc8e3160f281461845195379abbe5cc34daf512248e116470866057edc96e72994adb6867e525b6dd57f3b4d5ce3c73d7aece3343d8c38176d5ae3531ce181b6f94815a6584aab287f1d5dbed7a5555b56dda466556f233944efad5edb4cbd15e9baad2be69384aadaa549f5fedb255e18f15256ca355cf2948e17041c30e1f3f5813a7093176572dece772b91a0a1cecc69f900bee64736a63b2cc222695b9348b984b93b63684d81252c4b034e174317b296b2954a9935a4a2ff5520c36462c8b148e192be020ec9953b60c0d8dc40ce35067d8d313c2ec45f9c3183bb42bc39f109c8253b2063f3c5c8c31c61861d4141493b376653309cd43ba861f40c5b2347555ad569bb5aa5573b077a8a77a37a50bb6e038c14aac092d624d7489313115264c548c89a730b125a4e69c13c709b12c4bb126c0c498e05254347370ec6088ee80a303fb559beef984fa16e0e1a819524a19a10bb028e3982171cc803d734a1c33a49492a33be828414827cf6b91ab1d19f3b3931312b1634c893f4a299d7348e679c9b2cd496559961dbac0c3c918ca62526a9aa6491c29e048218a997076b5a5bc9b9c4d4eb4accc612353a8bb17bb08a81f9e9f1f1d9f1aff866c6aacc59f90cc030732bccdf57169e89d1bdc3439edb23256e6b258b2a6a7d38f9d517d9bb9394e96fb767b3b1a69a45fd148efd1777175a58dbd044a29cda22553232c5704304ca6b707621e38204488488635fe0d65a8a4281fde9cc31f101fdf8f0cef923e3718de2b355e6373739ceca662ddc66feed5bc5df47d9a9a9bf3e3ea1d7a1b97e6f3489f9b7b35de3cec1004080b8886da3bf4377747efd088a1ac1f8efc09fdd87655dc41a79aced2c8b22c8bcab21f340821945a96e1b8e1e3e7a7369d61e3a1fae908b00b8e0cb54085014503ee1b9219e2affec3113fe2168fadc523bedf117fd9bf3e8fedb9fb868dcc2cf493b71b65ae7adeaba7ea2ea769dd079db69be5d93bdac5cd4943bba0a63da3e3a8040dd6b4494c328566440000000000b314003020100c8984028150341ce979367d14800b8ca84c664e188a9320885190310619638c01840043800cc00811611404c984e5e082c72fba51dc0ed75f04b2e1eef58b6bd2204ffa45e248a59f96226b89cc3588bdf32370a12fdcdfa20fcdc839c717fc2dae0d9a925bddafdac001ea2072670905fafd981bb472fcb3f174fd96dc450046ee9e782939bd57e7f79ca243f3dccece0d042290c897d888a9d431f3c14b557087c3c1a887828719bea6d4cd7ab4c0539c69bccc24e2c863c1d9203f25aac5574506248648db80b8dd1cb462d8b88cdb31c0eaf528c0857844ced5a482e356e996479281017fb285e06cbbc98e6d039bf44a88aa262c07872166b67cfcb2e442af6c08a426921b7c2489c797ad8dc0a6ed25c6c1a668e960b2b0368b27de93d3b55b599a8d235cbc410d8e80c9cbbceae1b791783627a20fc04693ce5d829a739af847c489ea5a89ddda4fdfde2312726abef050de401a89203023843d4556621fe567ab13e73a1bd1f91a490db3dbaf157c9e01f9d4de6e5a46bd6b32255b7edd349311a33ce5f34697b0b31b6c254828355ae25d00b12c3438052ad2d51d27e1a432c9bb72e4b07b314497a86837bc571e0982056f9bbc3a3443b532a353f571e2617d63546ab13216a5730e407682c95e431ec81a9ab9a3248f6b040752a0130a21323eb617bdc3b742e845989bad37e8b4a48011b47d6f04187acccd7d19bd40f1a1c3512f27e91275d45c200cc59197fd55c62b7d51404c354e006496a16cb54e4a4aab925dde913f174cc56fad39bbb6ee52dd342494c57d6c6f4040389e4af20eaf91a568edcbed364fd78a098b0791e7ecca176cc6e5d58a7eade2574ae43df47ab7386de7ac22eb58bd433c1be60b92a0a1e7e04456a090a9bb6dd46e1dd1b8b018130d0d9d80658c0f81f4e6e841d9e2444107caed713c25589c09819234bc4b114980bd28f3af284f4eabbb30f3bd57bdf8fb541ce1f25b268d06b8723c0109c70ad23e60f762b56379d127e6106e305f29d2afdc83932aa53bff3756323880efacfba6d42776359726e5b443612fd69a1a99808bdc94c2691a24e128913bc0080b3d6d4fa9910c7190298d0ceca41fcea656d7dbe7d193f6f2c061e31a5838c0439b13034af4f93754c6c0437ae81353be42882f64023e7797e05ab4a07a507581c3a3092ec2c95c2780661f651135ca12004a67dd6580ad77fa723251aff1ef86a00e45b93c3275d8eb36adae5e54128f4b213ec7821703504b8f09942fe0d13a04064982a8dac8a333f699429c20fc9b42b5223d20adcebf5319c249bc6caeb5cb3ff4f3178e7d45802c4c2809234f5a7b200a138947fa6f53def1abadad3375ff8294baaab61df1ace9d9cbdc128bcfba01c1fca15f2a8a5919f18709c3fefe8ffba04b2cb63443dfe10d86caf3b638668fb130a46fd1185e97a9b4885814c1e37b29cb89d73efb2fdd6464a5128cdf9532c541a6d270607535e4a763b5c21440e90be73ae85e005d5c997b4d3f2dac4d807807e0d3ca561ba3981ce67450206a814ba880f2ea9a9b8c7842791cbe246b22e6d9e0bafd6af8ee52c039cef40a0f0eaba95990266c02720a57c66dda6c6219453f3f895b7518a8505ae6410de5dfd2ddc4cedb0ab122b3969a7b7f574d338e7ff0902a2920e11a68e98ecf6ea9d0484d29f5b10b2465bcd7435bac14c203d8cd01c922772e25dd21cc993c64dc7d0179024dd61d1e048f0ee9b5a997fc42267b02f9055f9ac6a407b756febb8ec3b9708552072335b4ae97e217c56de22a360b1c879a8df682bd132d962e076d10e5a4e9131f9a7d86b395212b13cabba3217e0e04c753335803da75420cb9d74d3186e9975fd04889fc6d0e196516ad631778dee8c3ee92589f9ed91c13a0c085bddd6b531931c6fa4bf46a31c23de4578c01cc05ef8d924e454a0948126d57a534a19a89ba967e7b3cf901e0eece4af3bb085f06061e20683f47d11cbcc07c5a1a50aa70d75923d136dcd0d438e40353b9460312277f17b7924081f31c1acad44a4d58e1c7f01c4aefa27b87287e6e827633d8a7037e04149c19f88a87358b24ddadaa2e83b1b03c93ed8e3803fb701667dcdcb4e511268e2537794c7ae1b1ca15f59de3cc2679296e48977181c290e5e3dd0a63c815f02fd34bd5aab0774e07a19774c5c5010b478b7d98192781161d726aee269d8ef08c4e39a6436239759ae36394be79f3d9bb0aa3bdfbadca10168b8e6dd931a9353ac8bbd3ee2df29569d5d97a591b5ab6f1704d65c62b2e7b4da49d73c1e085360d7663b29fde1af5677053d1cca267a78dae1c1fb36d8d0312a580891e6f1bdefed3f2ac2606c77f023f1ddb7a89d9ff5d0e4109278698774ec92d24b9ce7a0555e3638824400ea9005f02b9d8bbf3c0641246e1f452b030dd8175b961d6320c4a704f3d3e68f625c79957d6a5a9055dbde9ade202fc7f59ddf2e05247afe0e9d79d58b495f3e014324683f56a36854c389d154f8a9b18ecb36157dc480491168d566ec902c1c9d150a22db9847ea380c242c5a1ac79d1c38bcbd1c4b811ceaebf86b050c4fc7963fb154b9a8458f427140ccbab342d57b06d62ea5f3db8d5a3756141acf7eec2e3f9a0aa80fffa178561b69aa22221f59685a719774e3a6853150796d6aa9118c26024885936acde4f9c136f1f90c174c483bb52bd2d47dddc05993d1e0ffed862cff119644ea216b241115ddebbef2f247cdc0bfc3ee4eca2a2760c4e2f8a8b9520b3aebe7a460fd73869dc059f553c0846b9054e6ed82e170a10e40869b31cbeba6f385853204cdcb2f3ac7ece43525d141e08fa851917e999c38943c369fb8a7d3d0793134037da33eedfe9a2313f4880534189d07caaa5c7158a45ba4591bac1c22d1e763223e8fe44c054ec698e1b1a1c55a7d5db959eb45b147aaee52f1da0a5010091fab3b98a79de3ce78561a89e7448d65249cfd11b70f3a66e5894fdfcbe1e87d20e1f9d12a5e7d6893b23452b631b9d72f69ce2c42ef58e8f15922d1f714291498d2610eb20b09a7e531d74483ee5cc230141772d9ecc1cf25412f3b6bd5f14d4bcf8c610ae0fcc13820a4af144b6ee7fd0d287d36d5e15718e0735daa04d2c0ac01264a35c173f584a9b1f8683aefbdf74f9a654526ccf5edf5d1996ea0682155ada521e67a167658a91dfd52e31011326e44836166297c5280790b99baee40810b3d3878c1d00b9183999b5190fe0113f05facac57a3cc29e44067a7b9845020894144b34986ee50d19121545a31a57849c00373b58a41e7fc5c390a06bc5e4a0ce6776b456e25485d90f55f0d007115acb55abff8293a26759a8ef5e7e575a9cd0feea1810872a4f5cedee66411c5f7ad72201392ea7edc94fd61b495e237cf8faec70291f547cff0562086fe057a09e4e7ea33905832ad27fa5e70c1fe8a0c60f98524eccc193d3380307fdf06a9c54d0cbb304c1d79f60058477f0a569ef2a53a47db0eaa52726316d81adcd76974737e8d0981b50a615b7ea80f24a4ec4410f501ff8b0b7351cf3fe71c3da95849683a8050d7d63e6e048752a1d218f51850688674d4637dd7b9de279ccadadb8890beb724f839a7fdb706cf4ebecc095da3e0e6dab652d07a557b2b27c6c7993dfa2210e6ac70fb3ca3850b7cad9ffc6b86e8c4c9d418f9594f32be71e42d4a4e9a781def47d6585c6a9699bd554b5d7a5579970b9f9af00d0a89bb10da573601c9908bea697a2b0cd67ecb55a475252341d78d09b8ed655c256a7b18c3281dbd5cf9b466208b5511c8e4796cd776d5b396f93bb8ae3ed57722413e337d2112d7cbc133ebeda8eafbead9e0b70a9d7906c1992489952a1b2934cf980939386469ed16a281b832bfd221e4152cbf659e5475a2fffb5af13f91b98ded88a451222a24d7cfabb2acd575f751278b8a5cd20e58464ef659530b89f907e447aa58196312a1e3fc46b0d032a4756e3e39056fe3d8f1d762588225b259f942d1077fdf48ac9f4de40a576fc86231948be90771d5cbf45a63f7281a127eed178618f8f414446e4aae52da8824e149fdce25311c12fd2f52ae5b9ffd0902dd6f94e86f5113801b121f28c8961df0f88e6f6c0f1c4b6aac11b99e797663a692902862c777e468a3b2ef2b87e2f92fcf05e946c53d007717076bf20b700fb97934b7427e69bd988add6a121899876a94dc163dceaee1dea24975eceded68a122e17f64368ff6653859e9140dbbca2d4e5b082de6615de064d2a4e2b4f1305dcc63b375846cce3f7764ce067c8544fb45b808e9870e4c26a1a6a6bab9541d4647890a111db528aa2a0fe4cea0fc19eca4932b5fac0bf0250dfa55ef8b4f44173a951f62d361ee9054c8d027aef1f35644ab0bdad36b699b0fa42dbda257467371b6d896acaa68b8f09819bf9cb457a042e0f04ae0311fd884ad72f6897f8bc54cbde5f5a855df40cea8c2a9a08f4b4148e9b862565195c33bd88e500bf4e80673e158d4d1f1e37549fa63a2ebf92d26a6607f55f98c8b30fbd912473910ca336af7f1e0707afc6d56d0c2833b5578436e12f5f65dab438863e03a1515bd90b24d371eef6b3efa3356131d4cfc32eabb44272a0c4575dd0cca71e0ebf00cd1e4d58a1af90362e176e3009ee1a89b353cf44abe6580319dd3a90feb01f35c4c4323004b1c5122f0b3e9bfa621be385074f8562f34ec68d4abe89773869987b62740dbbb6aa5040d7a227de4ac1835dc6f5c26ae8f0cd893f48ec2de140dc7e1166ef094b2af80422dd0a94980f1acada124a4c731c360baa6fb2d1d0ec7ed5722126102db8b9b337b488f9a8fdf00e4e203c5b24c8edc8271b270b5ae0e90d155420ecb1a26b79fc51f44293ea0a448796caf32b45a1d7cbb0032a928827ad285c80102dc38193a25686e72a0d4e99c832b2bc19fdb0feb2f0de6ddb7374a2d9bb0de126a57269c4195e53ce4b35492f72015f79a1870bcf809ef4497478b2796470c8b0291877a28686a933e64b3d0ba3f26966a7f5b455fce90992e62365e285177971da56907c461078a0d771edc3c94f9253ba02418e15cfe0da8af103af040128dbfd15f26b0bc52495f0e4024d4e5b0406b3c04d1de186b55d4076f9b198536a4bf033dff2fe17693a340260dd9683b72644479db1654f94841d12f55a56cab26c5fcd03e0468ee7b1b0a092f3b487a2a6347fb462a17acb6b0b6d826d57b4f7ee4771d37c62243f39e3ede84a33df37276cebb99dd15d9f8f952bad842ca64bf0cc18e2bbd21c7850c1a5c0b7170db927c5d19312371fcf125930eef18cb937ce1cbd76fab3487f8e88703dfae27ef6a5d833cd20867cbce5dfabc021d7dd51bc936c91cdb42ee08955319dea3047ddca54af3eb5763f67a81cd3dba2101bd75ed34982f566c48818eafa676ab1a29d4668d5a308e2835c7c537dc6c80898bd02a3acff1d3aa75813c74ba9b31c22926b573597bd51054e0c92c6502b27a08d2d9493b9f0eb05744cce25563074729b14d404158318d92e42acd28feb22c4ed29f3f691836a5a223a568286502f382f92331f341c26ec783cd18786daab8536f240d700404a4f795469857cf538a78a57719b9b6ae0383c179871974b8bc1e5572f0ba32caad7745b41f54c103dd382b2bf793ebca37e184e03123e0a8f31c900c822e7fc5fb580438c07b0234e2754922328b2d1dd41b14c92005726144f9ecce4aee2588d1e6d334484d4acf1920609eda57c65d8a1a394e67b159cbe02937e9179dd7103352cc97818452f1139765dd7049d0d2fc4c006650d04b62be4f4881ae695b1ded8148923a2a746b8857d052ece683b611858f0948632294dac29a98b3d4a6b638dd25aec5142e7d81d56620fc79e6fbd1d5a15e97de15c6f8cfbdb3cfc89fe134b4f51e88bbab0549ac9c0eae48e154a5358d7f4d4b83cc883fe2a49f78149d6ddb9525742f51b7a17c90dd77b72757a222ea768298d003153670b69766b61ba618c9e41a0ee62d1ba6426da91b67a123682493797be1176778cf07b2a96d1175deb2221060c0c2431d7bece66f3b1763b286ad85f7e3593c5a425c122326f552c11db4151e9b0fd26b094b029cbf34cc40d00c9dd16184155c09ccf348bd130541ab2f241312e1f907d9a03206c5249f792c527124fa3b7c95fd4b1edb44d85c66d86061ca3ec3cf919ea3dd112c00d9ad44ecff58261244c678888fb3bc6a75d68b0ffaef3bb77c08d6622b252f1948b5a5e51fc835ae4bc47aa22d4961ad8c680b2e92a37217c8e13b0947b224e2da4fc3e1133ad81848f1461f2759f74741d236051844d744b3844124d07244454911b0e5394b9e160131184d0d88f76cc61fbf4663969387d9a45159d9e16f028bf8ab6874251962164de5bebfe64ba12a13119cd33e96c2c9682c811cfd93fb4275406617a5b635d1bbb36bd6969d5741d63fbb316a7eaa7a618eaf6c74e58e5fe19ed276b3d133f847ebf8415c6f562203fa83a1be48b22a8888c138e9888f0d06df437e73d38c7e7ef50696461565f7e08517b8fda042bc7464d2c6c3f2ed897ac5a2bb085aff4379665ae8843c49f8f82d60bce9ca8a67a1cde6110096afd174d6b64d4c1ff6f698fc3c2a69258351187f0832eee241c2dc65bc20ba62345ff21192a98b2fd7c39038638e1537ce0590d8f6783d15cb5b27338185d1adf393200c33c9519700f2dbff891aa8dec05bb12891d0be12d8f20251e825b08ad3ad16181d60706e1b7160acef6affc9c78bed65f1a14bf4590bbb5027cf78508f74c1d149cfc3e01d29ee3d09a3108dfce779e1431d7a1d071fb22880612c400f15175f2ac212dde21e1f07e10cf1d88194a7c65eb875a04a8c0e80002c83fc05648396667cbbb4333c5efab0993c07d5b346ed84d31da4146a233855a0f761b77e5c259b7c6e6d18cc135c56ccf231a0c5a010ff9ef87e610572dde443d7b593e7261017fd42a9665abc5a8f44cd74e50eb200d16708a808af0298b65c3971a607a6a406c87015bf4e24bb32121d32f0df0bf5157c041bb87afe12a122d9008d4d4fe6b62f05bb4801d3a14c9fad0788c755290dc3e17cd5413e48b6fe798700a6b2bc091b50253c2b0b150a253ec059a9e03afac439eecf5a7971b34da0ac6a082fed9d0fbc0dd4d3a26d0fb6801a3e9226046102157fc21f98fe7f0690ea1d602fa3b0f19d58d22829d3d2196a38d384d9c6bcb85ab38aecfd51104b961939b9b049a048fb45fd85fb8381f03c149b6e8aaa47efc1de3af777755a49dbd35123618e571eb29574866d67a260f9fadc1f405464a07fa7046627c2efc95c43910196b0c8c86ea4823115f29007cd1848f983d2c298dd367f00e073590511d7ee3335076d766b8d7890d94b09b3e9c5a397a5184df762eb1de84c1636401628fd9b03bc6a9f631dc7fd74198428c45f7eef3910e73c1cfa8976672313b12bcd8c908ac7f3f59453bcc358845848110f2eb761eef246cbd564a6315c0d03a658b3e1cf560b9d21ca57c6026a08a49d453384f3b6bf466a9d7e2a59544466e32ad91693cca01f264e4d309d29373dde6a438cf98d431429cca39b91f9c4ff4590fd82e446a15ce037dea90b0232a86f09105f12d28a704bee4177d67be6a5bad16a95bdbf4ac3f12ca2de50ca0e1f93dc7561b9da9973315ce2216f7ba1f1796f0c22cebeab27bb4e74121e94b3080a52a0f6e715558edf38cdb471f1958a6663fee50ec1766abdba05f3b3c01a2a02384c097918aed7080dbca96275bf3b5dcf973428f2d5b768756b9ce7a090e3ea1c0dacc0dcd09a7c52d102c1a6858361d23c891eac9eaac043ee5ad070501910c7cf585f0ad98f2c345038de2f6325855648d7b2614a2ef347889955d16ca0360de3ce1e921031a74c9e320c24e087d2bc8bba84a7c5c5729719a02724cc8dbf20a6bd077368dbf8c135a07e71e668def57f1da9c58e29238da20fe20464532407fa290addfb4db6120b01d2b82f6c203fc18906343af002b2881879016c42a8d88aaa615c2895d651b3454377846138d4f98514d44dd4e6a2a8d7f15eeeced2c0aceabb4e7bf7dc625537404af2b13d9b125ec362b33519c5353adf4f6edfaef302db1e36d7cb22bc7433e1c3de420417949fafeaf19a70a18730e99f3bb12ba92c10129ae1b81852eb2d21c5ca3c15dad6aa4dce67efe942c312f915fbce0c74b01eacd60b68c37141259ec2c4b1dc61a4134f2de5cfeede88b7625b285ee85ff880c71b8eaa704a094e947de9af283abfc150b020ac8b21072c7eda76055a303f9bc02e9a20ba6e915b02b602d9478cf236676038cce40981424adf5797fa07549b079af15f4a12e05f53048f0c0c51218c7ebfe06c71f6d7905455a4ccdf75c21747bff838fc5087a17a8181437a95614e1f2c276628b4e938d93ef0399730c1fba378d52a6a0b7c74683501017ca93e449e242ff8782100cb69f0fd5942f7dc88c6bbf3f7cf781bcd6288dab8804d2ee9e60edde7b5eb4929b932ae812bad6c549591c1cf8dc01bb70c33bdbc6fa721c3420e7426459502136c1fecf02f5c5c12ec33d8618ea924045e7ef2abc0c685d4b0085d90008fc7e1dbd9ccbba3da04dd6d87b5576aafc46f513550503a82d994479e4597676f7b70ca8c864beb93077c42933091fb41ae705ba6e2f97e34bfdc7173030457f60902036157c3fb96f3d05f5d5e9999dba1a7d82051874744be37f4cb9b3363cca742b2daeaeae58d79b5e43dac923b83e1056ab864fab27ef86e8314c13141c79f7db0abb8b9438505e25dd58f3fa43709dd70f2afc67a17e28a8b72450e847994e0e570f451bcc413a59bb986a2eb72db093cdc3710db8606dc995c16b3358771bcef47111f21dfd87b86b0d40e4146cfc5d7963eeab0bded37238e3401e89877cdf6a1ef0c90acee04f41a69c460409074203e49407357b291b91e3415b3763b592166b6cac111af11f2dbd2762cfe4a3c9dfa65f73e3ce9b73d5db3e4a4a4d7acd0831996f93d95e7587a4c9fa9a900456801aad1201ceb87e0d5a74072d725d0791c40856b528bf7b84f0494a835ef44a225afd3fe589c405e56a551dce5d42029937797ba2787bca5ced9c1c8335e30decbc5e5c7cc54af05a7c1e29fa91723ae9d1b28fbfb946a2242692e08558c24653845c0d04bc07d8973ae49022804118bd6682bc27d62e4e670c2df76d96d755e2e6c33330c25e8de86d561cce75b28415d423234e957f249597c24c33eeb7afdcdccc53d3462ca7ad354698da23073b299cb1ded53c10fbd3ed569687344237f710743d407fb2fb28181cd84c93c42b379799bda636233eaa75a99bf15bb3f8ff29359bd084034ec5546b03030a1b60d673b319292e5ca5c141c393c1d640ca1bc840425afb4b233c164828275989b9d8d1f2eb2869b5abf603af3bae98f3473512798d0feaa55e9c51a8d9e7030bc088a0c865e0f3c6357e11169bf1dfe4be4b4a067845103dd85e1e17e753dab1772b03e2e2dc101a97892bb348c3b811e053b7269e51822727fcc61312b7be8ccef1ed170b618a26e6265f2f62b7f5e4599036c8899b83452652ae80e48b2df2b8f3b3d53320b36edaa9bf8b5a1605cb46c3a9152d43a9fad5c09a5399a9fe07cf44ff87bf8942d8e25448f18380078e607912df4309f995f05770c0fd3ec44c795da2c0b6abcd1d4ab44b905e2cca4f951b81240b95845a0c908a0f235c130c7706692ac59cfd654bced501bfe22d403abf62e68371913d8462b2b15871219b10925c9c5787f6f02a470bca7246aa0517fd1a356f7cb103d30a05fe82e4e7a0b3cc8cfa34feae3a90f9437b101582955b3b9ec5e12f1f422f0f8056941e086486c9553350d8a6606f6c522ae820e9ba401bd8bf35652d39bcfdd9d4cb00d3f5874ef9adad3242e0e13297177a2110e7e2bc0e0b3ce98c91c18d72121af9ab2a409e3690a8db7e86d5e8f712f2f7baa51516b997d20b2dd9373c1a12f94030dd56176fe334d84f783bdbb332751c8cc24d78a7d17db2f1dfbdd1f900945d01af7a4bba11f652fcb24cc16acd87965a71b3746b2ca5d609ac7ad86481756aa3f6ac9bc5055b411262504882eb0d77277e1e494805c3b02122ead8463c48a66288d4b66419511c370e1f88bd3cbc2d4fc080b036c4444e7be10c5dd80e34d621190b196055a9cae8c85bd01d2f5a895b492b12f338ce384ff0ca4f81300fa241a91aa550c68143ef29dd14333cbfe84b2c82755c81145134c7d59036c0f3c021be4283855170e6936518fa00a6831391f7662487382151bad8f9ea10568300a8628ad8093dfda6a9a99704888e4b6b0843fe00291c15002bdf4dd7f5897c91a55b86e4ae08a43361b808a0ad54e9539fa8aa2be1684c54c4b969adafcb66e93d3e4cdaa1c9bacf2493b34816c5316530f294eb3062789b48bb04caa20f64d84d73387527ebcc13e7de36a4ec5b5f865bfab11fc45e0e721db46950c0a20e1522e565fe0167ece433660fc70a0cade2c4e7f077a1df8a3dbc8ff34c5fea3e769fd08d7755a8e2b0545ed87f000b4df62986e2719f10a356043165576864bf89c1aa3a57b6186f3c2720eeb0545995ca0ca71aec5c46568cd9c4921750ce597ea499faaee87ef9b230cfe04e4d263ac376133e397b5d74cc17cb0e960f8afc87ae5dff690883c127658e62a302458f2c4eb86a8a4e17c03bd55defb4a862aac73cec04f7bab11fbc4b5be379e2d7b1d5038e4f46ba0fdcfc6de4687290f1321950a912e031d0e9bef04f31162df74d777e3c67b9d96c9ebf451d47d01627a2f06c2ded6e4a96c051c42af522e3cbee23dedbdd502c55d890393789ac1a175601e77d9ff9b2f49fb4ea9eea4e7ab6d1608a2cde758ddf5b7063ad1b1d9215e36675330e12818932f99b5e2ef7034e077464ffacc93dea86bc896ef26a7e702d88a3a778a3e4762f45d66616c0d37b8c3d832b5a6eadcb8c6a9f39551487599da8db2d17255045b791f743153e97a56bc2c7ca72997f9bf0d3957fd7a03de73e499e5d2b1cc28a651ee4bba789b9142c232bc542361f8b477c7a7060af914103f24c391fa3544d16a7bf36aa144741c70862144adc4d432b2fa57c66db1883cc1480426fc49442934b7d4d54d0c67f203d924bdb119b0f38e646c47dc53a983da0a83328400291ebaef9b95e01e944b65ab789d35e25064100322c6891fc327f1b60ae52d5645cea676cc6bd25b65445f64e52c9a55d70ea7c3a2ac179436a1bccec0159a7feb61cee3f071cce22092c0d6225807f4b84a518222bd608095c22d8ff8608779ed29f2167ce2851d104730ce0c7efa9e48b3f5210d939fb5024cc1386c8c452f016f40be1005d9946356df0c2d10997b98bd508e5e1c6e50e8e0504a9f55156b4ddee4a97dc0b6c4fabf4232956d4c8302f5b8c552d5eb763707ed4929cc19757ea8b203f5d03f5b74f2619be1b44bd6ef00dc860e2225730993d0cb764d17a6fa007f73068120a8c6b9ea7e02a82988b7fe3c9a889722f1d41496d9feb7357bc710bd80c08cc2bc3309d2ca77e0944eef83c61039e2babe7d3c943ff762fc12d03436f091410feeb0804502634115c42f9aca870380b9f39d64eb0d014d77c57bc267a3ecff7ddfb377ccc9d6b6ed35174868037540ef42e002d92902e360d802e20160d90c3e4cee172a5c31fb45b1d899ec4a9a3b29d5d580df02cece02e7cc7d41247b6f45b175e684c5d2e504949d8eb5224ea0caff0da673c68c7dc58e664fce2b1690f5a1062611f4e750a1c7c586a4ac36373565359650d41acb147f4e25c7feb7854e19456bd6144d63042abeb0792ef69720cb0af3a0e819fb02b8330d084a6f81a9214b5ab0975067543512305f8fd777e1f7fbd723a7930cebd327ecb6812623ed3393e856b282fbe417e70fede4a767bffc67b649202162069b53acadca754a8bc0e8ea8609d844657dee5521903a4c0f95f8b8b1445d33b77b420f44486aae8e466c34455347b506d24790ccc93ddf608ea154021d51f4500ef8dfee95c8bbe2ed8761097a4dd8234baed70e80d37b874dfe23b1130e844feca473fdb802b9272c011f4273987028db65c6f301cdcdba47ce990ee1b0bf358ccf268377557a77d339cac1372b7410f670435d15ad79b9ebb97a00e787c4043bf2c083efec6202fed3cae52c6a76c2bd7497e798f58cbe1d5b6525d086f08cbb5acaae4997bde2871f399ac4f67b353db2ec1c60ff5db36c68ab16a61cb9ee9c23f636cca0a9c5da4a48c30d2b111be7def08e5d4c878b1c9b642600bd52fb3f481f543bf9c29302af77118d56ec7a07b133de06b751b8358edee93e9af4f2adacf863226219c437ffbfb09b786e043adb2c4bd8735000ae5ed6958a6f650ea76e9865cde90e9f07953f2e3747820ec0fdcbd4b1ad61f97459377c7112715085ed28c9296ec6111a260d71c9e0f9ed0d3f95d3a8c8d4654886d25e1c9b4b366fb015bd1e2fb971086f5badfe36ee96813c2fc2207dc20585ae5d0274c87e586edfa08e12c6e777f046da34301354b902f318d7df33566be7207bf882a317e9edffa32d6a3763ee4779c7594d1ba0b7a61c49b8d2ad6eb857910f4a787e9733319210e8918e0fdb647860e62c659b970cd24cb292b9752ca1e04271fd5beb9ac21753b3c0c90b74f8aa21445519d46ea044b1dbd8d435b4e37b707f45c0ae4dee1fb214c629897b79bf1a25fb613403b44bb9c70710d975997a0c9b34e81cc523e13110f665fd2080d1e0093cd0b64c5876cd75c866df24f5fcb14065b1171e9df13c9eca23fbc521fd2677ac3784066d1818bf381fee7b3d408e973a2ed55e5782fc3cc7335b40961aae7c9685a70a15b472d43218889657719d240897cc272fab80de01bde1c50f780ff46363de80367aa409aa58c6721ea9b8c10ee842a289ebdd2703e5e4374d67d85e3fe8c77d63e19db46b58040afef8c3ddf16a8fa5885f0d1cbd4ec2264025bcfccc9fad4929f43ab73f3b472cf12ff99d851ab2018f9a0c95ef78698567a93f5898e8b5e89b8579380f08adad81173b1101046b191260e98ef0c58dac0a4c2712017d88e2347d561b784dc6b48af76e28e00743274d9e6f0cb26bed025b67ac6444ae4b997c21870092218e90d907c298453086cdcd84e82f58f59b52e55a99f2e210b2a8a34a8905dcd1a51f022621fb6c2cd6b1874aecf0f55b90c7f4fa79cb27ddb7f776e6abadc54bd22356c1ff89fe8afd7bfa69ba15c7c1ea0dbc6b2cbc028c59629c13b5047bfd6612f97dd7644e1350463cac72f26b1e348d29ecd8e24cbb9c86a9837d6f903832459625e429e1aff96c53d2c85767868fb8e3a92363d2920199250cf8cc8b3ff70c47f14a12a1fbea881026f8540374616a42f8381a42041e925048358a85b47922f6faf75673dc7d0fa1f88f86c7c272836919a3526196a7cc166e74259b244a51ca9c691eab3a463a6a8e3d629ce909ceb6931aff593d91d454323cb97496ef5887d6ca67ff7b40ff607bcf3239ad66f51f3ba86291f13ce8930abef1f7e9fee2eb2b52d4045d3dbf933e6ae75850bd0bc500520eb73bcfa137aae45fd6c452cea89f17debdaa2ed7ae245d1761fa43bef63dc840cf6a6ee6af244cc79b79da162dc6dcf1b4e01e7c99ace15ecde66ef9b8342dd56b4d2b0891407e9f743e981ccd9238cede013aa1e60e8af23df19f4b0b9715a95de85e373371c1fb6be12106649a4bb0960b7dc57169ea28cd8b00f32bb2f7063795a37e7d4a8d782466cc19d3d671e694f8f961b81f7162a7c214390b47bb338052cc72a8b2bf2ea88438040456be0c59728c3f44973b56fb0bff1d22c9bdef680ef735f2395d3443ead98a88d7490eae54a27493cd41749994f629ec6715380555dd0f87aff3ae13c108eb5ebb9fcdbdb1e6f6569ac7773ea0740f510747118b4d29dea145d94bf80c0115294488c89f17afdf36edff5f28de30668948a294d30b6f9a56c59373588ebc7691e51e9c43b059b547b4ebce5ac05c4a94bc3ba1bd012918251342e38d1fb3a48438288e859a1a2bc411f1017e94a0051eafd8816ccafcd3a64328843750d9bd02e85750d037c44157cc9b8ffcf4a9387af0d2c4a163764e26af523f1cb2110987f448bd654bdfdd11daddb1fa793bb82c494bf509755484011d91f8ffa636df01f0c515e40e612152f61a0de6e980513c6f37d1434b289b344ffec999a85c28884619116734f0a026fed2411200372303a13aed848fcee3208651485713ee3bdee9ad6bf3df6844724558a1364b965f22462b46a864b608774e6ad6e719c7266e73add2db8fe1a7353bc800e96428937c6bb2e87a9c755775fc6f8674e6679d38fe9302035dd0679482ec7275d45688921912f6456fb88892f4b4b55ec6c68e72d26ef6467021bfa92d9c5e7a4dcc7cfec5c7e4174db15c435775e3cb5dd92aa5f6c88fcbf20441799b29f69e80a67afab3b11423494c89687991accd0536c0650e9cf6bd2a5dbf745842e1d442acc858d062853843b8e6b23eeaafbabf4456bcdf3b4a776d74065bb8ae11509168d41e506e24846638081624286af186125e150f726add2f0e1e718fc15ceeac2f43a8d822e861f523ba050563b73f4c8265dd3e3c3b0092a53d04503f461a296f1baed33299249ba4cc339c5d3a1f0951992a3f04002171904a6a3e5ab4deb73bcdacf6250852367a913519d517b9f72ebe1fd9df4cba9ecdf86b71d62d3ee4be37cc0e00984b99d721159ab98ad27a038491f30003577ec413c0a73a8d7b1c6f2515f8c282ffa9345288f35ba3af010f7d1e4a4e74d9c4f8dd121422485a7d0d78388f72e585b5980ce0cc3555f88c2e192e5d01ef887e604ea1714aa8ff8822da6e370c24bc350f8280d12bcd12431571034697d6de84cd21931e43a17dc72bf80f71d52dcf0ea4c438b344a2cd0261dba55710caf064d390a1c334d963f894edb8c96e773ca2880cf889e75aeb452bf818441e575aa8a1702bf06c2b23fccc8f603e25f30d65330dc2805516e918ed938fd91174b2ba269132a72abff2372f39c1b300c8108ec4e1c5ea6eb1fc968cb8ed5c954c2031fe7d07dc55cae8ab7ab96c3b64b5ae77fe1b9e190006b8a85eef1e2a542337290c9b57693465828f49968cae40a9ae52a5bf857719ac460e7810cb23f27a01cc198f91194f7a03d6be126fe9fc9fe2311bc09ade223fa5f34e6c05cccb8bef8a47f018fdc47d0cf10f9218b67bd2f50d0ea802323161d924c456ebcb2aa175bb6057ab2c0b379a745c62fa97cb2f82e239db647aee6ebf15f8ea54d3fed0d7d2f6f9b4c8cdd0aabc2d4fe14ff05b0ab82c380c4915888c1b04a5b70ed101b2132123bbfeff1f672d5e0a904fb9791e066df7caa12a8836dfe6181bdbd1146ee0710461bb73fcd70ad11527a1f451d6cefea005520836d7ee6073c92067b85136b822dfdc5cab79005f66abd5fad05844855ad4c31154bf49d072996cd754960aaf1ad35ecd6e30bbf78979c167f80ea1dacbc6ac0cce8c75bd6b37d81603fdfcaa2ef3c70a1cd33d117b3aeb3f34d092c6bfdd0bc8ecd6e85925a146563895fc8661a04c926a1be9040b60d241d7a4d0cca087e1d86c49158064f56d6011df52f22a4c754dd0758296081a64cbdecce5e2020e1c248a242526b168bc2a4907c8467a24a1e9963dd9be9e9998d30905acf6f6f8228c8f5ccff789114b0ce042a1744407b232d7bd1ef751d04c77397f32a0602be827eb8d5617e1ee8ccf2570549ac1c90970689c64e2909ea3dad9a14d455f01d6fa456e5dfc488e52cb820aee7f77d3d85970527fdd51a4d6f598d666f6bf6f6a6f3b1b304b8c239b2e7db91a7fd5b3d4c467beed33d88231905539a5fabf8800496b611b01b3cd056eefdb7fb030db4ca073a70ef1e840ee201298a68a43bd0a037a26e7801be97dca2d005ca6305563374a791b4d2051e5a26cef661ca9d44e45ec3b77bb339bc8e62e773de04f20a91bcafc0ba9cdecdf2ad0c228fd4424facc7e03e8e7ddd2cf338f54e8d50052314630c65e4fbdd9c7ea00bb7c38d3659817fb4e69610c78c6bab95bff7b0df156b13323e3d59021b01efc4004917405c3f8efbae24c243c659db13c82939073dc13e3d02f8b63f46df6399faa0a0d5aa2f0c7ee008693a9609d9b67013e1570229ec9607607a317fe0fc9c29f3ec86df646698cef605a6dda87e5160605c0d0d59f99475676344425adbb239be692ec56d041e236802c7c03cb27f01106d7252d02184d1edf0171f26f6d7ea570fba82c53259fdb496016235c044b4979a68d42fc498f35d0a1582eba80bca54d17373a82449d2d7e9aec48456e1a136f6e57d56e044f043b81639f24ca91c2fcad474e5a8fb666348ee249dc2e14d76aa7fb1858a5ca13ff95965d416fb51d7a97ee39b84663fdfc0538693ca40e02d63451c62224e5224d3368904e21da88589cbb596390fc28b63a2d1fe25714bd536df66dc29698475ac25a25eecbe5f561a2f16c58a7005cd0adde66507bcd121b917feaa221b121e54b7e8fc5f021814a3c242e83308a1089c807519b50034e2465709c7d3e391d4c28eb817b253718476ac9400064035068dd2161354d81c8ed4126bd6b3648d2031150eba53fbccb9d12525204c4356aeacb8b37f5f821da61654043f65f6625f05c62d3c5e7f3ad28a89d59ddf0b522d3ed69afe28c16067c5604559da43b929b7dcb358f8c60ca4a48a0a4df0b9509953b837b042fc1f23950629cfa1fa4768eaaeea0289d5bd0b578a1e05934305a46cbab50ed33b9dd951595e954795ef26cd126518135d8344f5d4e03c42fcec11fa0b635318fd683455649337f31195088d2bda067184df3c6af9c0b0388adab39687c636598e497829c76860bd1e4f1dab0a182f153e49f6f606883f1c941d89dae7d9e3d190b1a0c71955d3d1be8f5931a8d30a6956d1c41db0ac954d170cb92da37180cfcc83714f0f2c0667ceeaf9acc86cf428a5d79afdbcacb33333317ea8b6cf83d3ec8c89583face5c4dbc2a6a627ff075ebb79e97c64b1842f46376e0a643118abc5b8b1a4b1091f5ec9f049bbaa7db516f9c28bc310e1b7a1ea06f45e776d2bcca9f5a6dc6244ccc87f6e64a68e483b36c420d381ad714873200d4857fd8aa066446bbadb7978a02268e57dc58906d52b0f75f712083f654c63d59907f039fd586594b986021bade402f9926ca22d972d4e1a00032d6035484dc8ab43e2ef1642dd0d50c488cb681cdb142d549a19cd5364a22b65b34ffab7c79a08973f51e0fa7a70b3b305a42a378ba787477c51ae9692f6004c38cde82b455df4cb00b640a8fc594dfbd1cb8bca4c5a6aeb6004fd0230bb461476371e37798c69f6b8177af6cb72089a688e13fa7342f4074ef352c6ab7f25b11e0c2e639d37fa0f54c21eed6b08e850dba6b14d9d1514ce9ab24c86bab806c3005edf9c9dfbf61c4b0836354e64061ebaab77eae4e54ea2ecf7c6c7db2d2adae8b32edc924df9c68eb89bcb5611b505fcedb2632c4d64f7882291b8ac7dcea1153384fb25ce7856e1ed3657097d0db6ae75fd040a834c54410f3b82ce33404bde516075d29d16e71a489aefd7bfe0b4f852a0ff25700193c0abbacff81e8ef032da1840b5a241eecf2bbd4a1fc4b140be80aa1bd1f9e5623cebc49880ec39a92a2cc482e102c43d2b6b4848cf7e5dfec268be1168f5226154258a7e5df6c770e9aa7eeee5cb67d62f40fb13d09e0f90e45b88f71ac8a44508a0801dffc291ccd0599a0834ae73207cb268e37e0c1ce2162e98837184b0187ff4faa3a91001eabb40b2e976c053f3e4e18a57debafabe399a2d38b33088b78348764f04cf2f78441a3cad727f3a6095c12820b92defae221542f03300c44323a6a4fe028916e13be826303dc791d6f47c96df312f58970fe826bf68bf2610b8d028daaa9fede3826110c1fcfe43f2db3d14e344f8d96a8a4904dfa58662d012909b8727ee0b211d26b915f4f359155aa9b38c00031932bbabc7aeb9332dd835a014b4860e2739b401aaa82a7cda25e776a0947a64f9035e037ede558eaf8f666988dbd96520ab74211de5a9f9620980ad5135d60545825ad892289cb7e108db9f1a0803902553e83155c52dac98514c856a1461e5404328350aca295d618b458d32dfb047c2e0392b19258d9647619a34ea4f62e046d1a881183936b980312b95fa82be41f91770c9d97b17dc22a40ca547fb9d8010fd462983375d6861e9f72e5b478a7fb44591c7634ba48dd327c4827a45e2e865cade137abdd12f7134e4df3198d22e658684cb4773ce615f56f0086b86b805fde2c40bf366f4ab2a6e1e01d492ce6088fa718b070d3c4ba158f069e464a1ae08ef7b7be11066cb6bcbb56797e8df3ccebba5512104bb7071b78b6a4ca9492e1ce320752af503aca757562bc39c410cd244eea792f4cecf50349e2f35b32a331c6319a937787f308290081b82a94f2cccf317cb28289af2add751a9bb2319c19e3fbab20a5432d702390f2546aa30b2aa494e24713d8ab617b25cc2c02654defb322bf5320f86ec07370d043cddef03939eac4695d10b40fca372242f383ad44640b041863abdfca79e783142c8998f0c970cb65432952eec2585ae2c2cdc2d375266224ff6d71b9cb937d80284d5bf06d0a1b8705a09f38aa0fb4ea11f7f830ed3654f79175dab04f17ab9eb4ba9b097627259f0a0531f145bdd063d88364317e8dd253dda2bad4f3b319273964c04970e90d10c63f7292e9344bd84a1c0e24b786b6a0b88c55a68bd0b55f0a799de522881f8ffe42b6be09e4d0a89a9acd5a8731fd7c10331ba9d2b862522caa85fecf082652f9cf1771f180ee3835a3c48f73e36a874fdea4df4863f69889ec72aea00aeac17b7842258020a82b709af1f26157e904531723ea16286c1c02d0f0774a43b95bfac55ef278d33fd9a681f16fcfc0931611dcea19957be43b282bef4e9ac5b1f65c8aaa6075184a4920899bdbc21c46ca79dd08cc0b44d7407485187e01b9a11ae30f40818860ef23a56f1f1a5de5f094aff909e4f1a8017a594007f9e522023c00f4cc0d69200d1a87999470b6ea3a0279f81f01b99383482998ac5172ba9ccaf22fff2ecd4defecad13c1e4da35d58c9535d582f9199c860964ebb2238a96fa0ae2c80ec008ad8fe8b330feadae30ed387425930516b39bc3514279d981723155cab82bdccfb8c0fa24d69038200b593b0022e47b2af63b5f4a62dc1c38aceceab77d6d303eaedcd6f92c9f85ed188eb4d94b7dbc5b65e557a9399e13ef4c152797ff4944b54cc8cc67e52cee151ae5f54d4114a4b047aa1d3b3f0c0c0e36d764c21b6775a20288f927f7b9014efbbba497711de435e4f781f4c80a0e6cbc322022050d62d9f6d1a0ed43bf3b631da3e4c7a68222c077776183817d0c3db4409a20dcdde8bc6dd389d997508f92d0f0e8b3ed85fef0b98bc701d1f418313d57273134a74d272e332a51764f4325238f68eef0e3fdef00fc569b0e2caec61e27abb05bcf5d1cc98c8f65e725559651dc4744ab3d5b3c9e885a053d8a64eaf2887f90ead585ee4b2e4eff819cf216d357c4e78759208eab6f88f8525e567d370f2fecff104dad5ed74082db49a338600d942de553886284dcc5013383ac67975e8e4ea331b49be4ecb450eecddecfe773509741449c326615296d03b262c7cd2ceb91284baf4ab451e42051e647f455c582420893cc8d69fcd536052d0a753748daf49b4e6914abc213cdf2615c803c521679411e7a6af3eb512e8a286d931b53aaac6e92924aa884e3a5782fc326b1426401a4288d29c525a6c461c00e542a0846e21071a18e402b5b484c5cbdc01aa0cb11a6ae59a4b096f0101223391ecf37deb10d146f40884d0f5c2257d4ef7c6ac077691b1332053aff87123a03ef7e3ac74139c667dba4bb478f497af33acba0c1961e8fa84c901ff57186c54e43cfd50ee9e24b1f2021877f11219e4e58593388812c7fba640b02acef26c4a25e5692f79d205d5c80cbac4d2e6f76ea242e10bc218c15db9031d8256d42ce8ac33d233c095505e7ca967b3211ab01b770c4c8049ea0d0500bb620c9cf77dc8eac201029db6e0b8284bf825e0388f4c67055613f2bbe44e18662104647d4b5cfc4384e227acb5c94a87800aca14c9ff016898b209fa7fcb0031dac612bf13b4d3b96dd34b8f884419ca5aafe163a714fea19737d02bacd0650ff70865a21c9404aaff53a1a2de406c1675cb8604fc0fe6f30e2f9182e427106865aeb238482a4e0a456a2f2560cba93880869dbcb9fc3582ce65415859ba6a8f4c8f81e0eb0f68e94f1ca3a1db5038767a661ef80f2e5854548fa7c476bc0e0516f8acc64831ac25aa3502a1e423f1b7f56862578b2218f529fa20363b0667a224991e2ffe07dae7370f4c28c7c77d3b19c800264c7a86f7ed5a131e94face0a9133477e8345c231122420f16491497380046fcb4a2dca9cf8a686b8bcc3f54411503fa537fccb3f1f6f193f37e73fca6b38d46f0d77bfe1648a790fd31de43ed5752cc309e914764f09303960c5a28d49f016a594412610a934b01720fe6afe195a22fb328007ec6548103e82325a90370ce41534bf7f23fc8c92636935c302d0ba57f777aaa7783319cba3889021f73f753f9c634651e2df2f296833f92376f9eea4cc2002bf2f76c2dc7dea269971f7297128928f70728133fb4abedf1772a543917649ee818459a12b1d0200dd9b2a32a93f5e515c6528f471d8e154f113f07d7f77a3fee69369f2737106ce4ae6403d2c14e043cc7736dca2def021adcac789843dd0e377be0d448cb7b04eee4ad96c734ca3ee3f090237bcc6f45fb28119a2f136163414266748bb4ea3b0c4b119136cedf40aadeeca19a4093ae840cf488bf2e92300ec9070c0f1f81d8eddbd012225614e76a91df480477404614a09bb0ea7e7ba425b8f4071525711517baaa228edcc73c8d473faaadfcc879779b090948df4d698e6910622c95c5411a4b397e43a057aca752556766052ac5e719eb2f2a511639ae0aea21f08d34681402874348bee7a14266a811d9b3001ed610a8f05d0e04b006dcd66ae440750f258b913f2f4099b02de6837304e463c9b5809323778f2fc6f0058f06744f945f3010a724c92a6254bbf24cd4a931c9fdf2a09c29afa328817290ba422b75dd750f941d7102661c403f805ddb2f77dfcc74ee46bfbdc01aad3175ac2a8d3f7bc04e7df1804bd53b9f617d871b9c0eb13422fcd82b008938d1a5b7b9e5cc13e66089cdaecc881086073c114421b7d58ffd9d5b5d3ef47dc1c46db1b5fd2d57d43a87fea22a9d469b6ddedb6f3a87415a093cd8d5b409e3c506b3bce36befb7583355dae977201c178d8f1547862a5c2382ac2b1fbb0e1d08af49d995d40d0778a0061981bb4a62d04f65a469d38e43b5989f0811219a7584c24622ada3d49bb0d883e08822aad2ec27c00a916f3bb82b245adb04facdc6337ad1802313d71f7be0b048f3e0dc1f9d7fb807c7ee0b0180f6c74b0b8ee396d82c5033e08567d3fd666ba692e2c47c7ad1b08d54c6ac71f64d3ada547682f17de4e4cc0692c1a0f085664e92ca1af35b0727d5a15883cbc271f2f741b693683e983054a7ea83312f766fd310eb267058cd5faf646aafc88306984f74139b960c9d0caf95f24d22a1642996210b9320f49f025a1f2e66cff7f7291b284ba1a3b2f0412a571d6979dd94db0e0422ba9fcf7a2e861f733fc8501696172ca719483bbb9f8db8989f67850348f6149d19e00af6f155b9e24b6c8dc7b6169fcb55c3a2e5b336c44eb80a0bbe9c04a111441ab5086e49fe4cec36b1ba0d00a6d1438012d60efe88a5845dbfe16205c5a3e847e9b742c9bce60a691577179b12aaad39468df7ded39b6e9e3df7748e54565991ae1a7f5d743ab0b69f0509801b4db032cfc97b8db70aa175b3138692a6ffeabd138d96d66a832a2f4b6d317d15702dd19cc30cc8e326d902ae5291c92394429cb4e29176e5c562a6a97b25bf4e2e0ca47cb980099a6645e36c21716576fe588658ffd949ffd824607ba91acd28db5408207d16b732a33cd3b3970d14c40732a2670d29e0c495fc8de0c178030004ea0642821b92275ccb2828193b2ac8b7e4559f0284e2344f10fd6784732b0c9116bcec5218f0495c424d9bbf28418a292b551dc89040916ab431681095d5856b1404ada9437c09cf2e26ea56b90197593ce342405fa97cd546c555c0797ce68e82a0c9bbd2ebaf82a84d5429b76584c9e307e921b601bb5a8cddbe7bcc714c4b43d19f7d31a909eadb070bb5a1865bcc0cc25ff769a17ec33c7d69d4ce22853b1d865fd1cad529ee2f07dabc8b8b290264016fe9ce268cdf01568d9fab4ce636903adfcbe146510bd54c720a3fbf863165f1b04c4f76bddef7414b2e53d2c6da04acb36c16c34258d61463fa665626b754bb520d38e2b93055acb7e9d5b173074ed8516b93abc62ff5ab482add38f2d9d9c6c77d0419a9baf587b8fc35ec41ab5e1916472e43934fcb76ead250224db852c956b353cdbc874048bd675d6fe8ef3631c238882043ea86b9013ea8bec238a832de2cf5bf80269a5e1167738f774a65bf18dfe9dc3602f706a8d10c81f29ca6b051d2d7ae905217a92b0248f29cad8903370eb5a74e7ebdf4b61ff8c12b924973bf5088d01471cb10bc97024301b148171d9d289f253622e8320525ed53ce68ee238ba9d0fd42a68f7900afa559286e465758832dafc8f311cf66db0a53bb280e6527bdca06bbe4042272e4006f6c3d741e62c6338120ca306345cd1d8bfc57ed93fb8ca0234430256004a2ad0bb7e791966e2d69d754a77f83592e1b8bbb4d3209da15800844fcdd8cefe0eee4659bd6c87304b8edaaa024a4a994f6722189c5c0ecc96e9f853255857cd7bbbc9218488aa4b79e75f9fe0806a32919e6fac13d5e13c7418d086f36f72d3e743b8154ea5b3992e8b873ae211fc63a82fd646746fe61ce919f8cf76a7c3ad6581f5c68d695f3642aeba61dbd65bdfaf8d98dab20c6e512116d16589ec19a4ce0860d8e3715b755a62600c3b92ba025c338316faa7b07cadc7b3f1fc6898a3a98159689d91f4c2d06479305df41cd7883617048512ad6c9f9c9222cff7a7a078d9106096da5fa3aff8be30164eb590983df3ac10cbba9f7413f0e845b1b96d93334398a0e4e8fa4ae76ae68dccf8ac79ede8d2927bd1202022986d253cb07ed2b5262b231ab983d319472b2cb6e0e7ce7d070899866e9ebf38b49724f5bd2218239177834dbc90ae4a9faffa54bad294c350767f52022c67611880f6ee766a4b37289349aa5a0914a234cd9285a4fb9ed2ecc76f2ad982b30c1f0687664064503950e44c0aff33934ae4c631b81351da266f441b096db5bf56be7d24c014bd97825f63d2996570cf8da5e8e3a401b00d3b9a9b84c2fa2d217ad00c7d82adf004e92f4bdb6c868acbfc5e6d462352c3ed9a34647abf734198d9144b0e4ff03d34f9085cc25c2cf50df92b4b0a78e34d6cbd4770a8878110f0c1cbfc8dec95c47f96ecb5622fefd95f4a73d3932f104b6762320ad1d94b9fc67ab0b92d77149e6037524b1b07547dfa39068342ad966107ec3235d925f0d35f1cb47fc595582da69f14d1266710e94a75748c2a19bc6b5d9d1eb3741ebb7e239e055c7f50babe7000be802be68873c6716e697b45a6fe29038e34aaee9371a02fab7184ddd25a45f32b54640f49822ac09769a24c33c56ad6c340227b9f0090750c7bcdbbad1804052933d07d913b0521ccb806224f25f8822a29dfa7a616cbb67b777165749e96735b0ead28a472ca703317d77c98af2287ae1e0edbc404f6a406acf376d594bf027cf0b12d4ec72dcefba24f4d2d329533b685e5b4319499aee49d2bcd106a6389e5958604a5e95c84c8c10aca89609fb802aac68db9e83670248bfa62c2f228bd1ad6514597568ece0bcc036924a2922aa6592d254ffc38fa0771f9a1a4364b20968e6a472c0ee2d542484bb72dacddbd23d9618da60349951e5d336819bc1c72a102d6c7e50585d6b026351b34fced45b8770953dccc673d965f124809563d5ba47c850754e315f0106f6819204b6b42ff403ed0dce73ac558827fea27fe8556fb3e62392d662e0be7b58f5686922150c110f7d4c258f1bc51a2eb9bf2f98217d13d6cef97d9f81af97231638e9bd761107c46cdd21da170652e814f449b710b72f3826a07e2139151950d74a5d28eaeae472af6e7930593c86e74474e8f4b494436be7414253b4a37574aa395201cd30a4744530d349c7ebfef888fb37cf8625849010fea47f02a5e25b27917dd8857d7a72c2e4229b63e459df529a58adf79bcb7fc2926fd114ec867fd54c37fa0534429233b1a4dd27ec8045a1e6e3f450415d21f486b3e81388189596dd941ab65d7276c3ddbac9923e3288aa9a8fd83b52e3eadf78185c18be13c9e99c11fb31a90ce7b6edb8c2f82a354286b0b7a80bb17de76c20a906a31668627146c71de0810137746641aa5f41eb0ff77f482f6b8735ad6b9630683f1ab83670188155288764ab06008d1ab2a9b2254afcbd44065ea5c1cc7a49e7246e3016c0a8636976f948adc4cab1152fd33a6c1509f95d4ab40df309547eac07a21a4d8ea30d21365ecbef0e2c0b2157dd5b2a7e7147aa8ed639f5f4e95ccb615ac280690afe2fa2e1f4c85b86ed4126e5eaf30bcfe62bfce1e3c61361ee5f1c3d2326e4da567f2e5f0bcb4c0dc41f5618cb921b80e36d9c9421ca3b71150d3e97270bb000660c39c11b1c3745fe80c2d82c180007bbe432a25a2a1ad63484ca2be268ab5d1cfde4d8d8b58d25374162a692ffc04d92e8da718448afed9edb030d89a308b97d759d4d0092701d3f260fded1eb2fd02bfb15020337fb91d78573a004c44e499654344ad3a2490fe20d88cc18b1534f76dee2b611861238692b20711035c67086416b173dd395cf93e23b42f3dbefffcc74e8326250ca334caef1367c4adca2c74c8cd6e32d597dffa8ce2d2efe958e8ceac93a20ae28041dde3b46374900745c51ec2891361d1a75612ea358b14ec7ab812169de990603011162961e18110894fe8e3e90113afab59c37b639ec7647f6bdd2c1710a0f00349411d52c2ce8369f00692c11287e81c7d9c3584bfaf8c9889623586f58247a7308994b9b1210152b885082ab18cd5c599432eac07c91a3e7b68479130dcd98efd2e7d56cf380dafb3380f065df0ad344027b5470c9d4ac777238833acd136cb0e7b563ae9a24e5473e91a908b4204edfaea3d8b27a01832a8348a4f275c04f29f41595ddabd3d8c10bd1a572ffd04ba0cca1b79cc3ad54abdefb002df41f4cfc6315fdca7724c6bd35843fee71f7e921ec26fb9132e8724eb70b2c8434bf298ae09cb230490511c419ce68a038a6469876bff7bad90ad78d3d971e68362eeae3612675620c73c0c7a5c47e33042725bf9d104dbe6d25d21e3fb3a46867c97923e83683d68919910bf7bdbacc9ddc021d0104d3798168a17318180711141698ca62843d0653ecf000e09e8834a151abd12921c1c4cffcbd7a8131081a53035f2b4a2add7e489f85c6cae7be6de657212503900b893a5b1a60e1d837cd2822c88e537d93f242795c4e6f2f8d585daa773a4ec5d40d0eea404300510b97caac9c57c7b8571f1efc5bd5649c03ee0e28106d638061cbd8f248d68adf5631eb98b6683b3150952de222b16ab8f3d48558234ca1ea8e7d15d29d0c6d63463382d289a04325a340aa7701e5b61cec3fc3c054fd6d3de8dc94db1e23622546da620d45bacbba021d31578743cc79036fbb23501a990eaa066df8b2cb832d6bfab59e8ad1cbb1519728366364c2d92a86353ab541ab0b797cd71cfa2162c4fa6a7bef4dd4c8fd844b0755671a5853afb4aa5698b8a1603ee7adbf40cc8d35c51926b4fbcc024f6bac51c28f7cf365add8e7d6e77f693422a1dc6ab78d80d191cdebe6b4bd94c35b2876b94f28c81f5fe7a7ce85860addf9f1ec6c5d7586a0b5ba3a4b14b0156fbf98467c8e18bb7b76092b7a7e36749eb39fca7ae89c02edd5b99d09cae6a5a65e0e8b571e93e126648b1094dccd2495ff5773ec0f1494bdcc3b1ba14bf7d50ed207e0b2477747999e3501125511d1afc14d7f4ceaf828c919cd4e92d3953e08f4daa4b28c7a757d018907b46ff2199aeac3dd1b5931c017dc1fa461116a89edab97ffef88049074e3fdbda01520f560287ab377b4461d850a76a9f69f178324cd10f0f8abcfb52477404f537047f7aa1d6e3ae1e5dbd4e9786a3b765e3398e716c60b158fa31b169eecc0318d7cf5df8e553fa201a95bf624f4bcc11aee4200848f29cd63d5c39096e5df18b9997c0882313988c684dd35a0614ee25a92030d8fcac77bcdced84a81856f55ed66b16f9a85707bd823989f2412a7f421ebf89f8de37939568b83b26ce657c110839c1efba2cd9742d2c7bed6eddc9e67a80b059df7f8c1edbb3f8338d67c70a62295d65d35b62dc97ca84f00681288bc7b08808f5ac0a27ec762b2c0a635a08490e58d7f982ea742d16608576c7f4627c142527a868b0cc72e6908b1407d54a0a624af9fc239a1976e53c58e7419408f38f7dd3d6f2b615e160656e7634bef8ff74d32c3de48f3e1631d8e80725f11001c5f6bdc01e9303f4fe06679e8eb1384ec9c23c739aed62d64c222db45201f8a8e6f13b099a5a78b222c2355e2cff188f09c3b50539065a1ec2358023804bf49ec43b3e32dc174100b2e49d80d1adac5ac19cb2569a5c0d75952fe4b521aa943361218c31ce95b5ef80021b1fc5b4254281073d955038ec8b1a88634cbb70d7da271992849c45517bebf8d32f368e3aa8f3b0963485149457b82995ea721bb425a7be6cba5fdbdcf1c80e1bdb9e9745f73e1481b8e734e80470d6f38f0575adb9427d2e28e8ad3b2546e8f877b35b9a103647ef8e14f651dd8748f0ba8c9c0a6e4c1ebe39b2628a0b7879caa68c9a3acf116ba2b889bfb96e4143e08d82596222ab4a51a7837b100377252f1ffacba80d3e005144b6e5bb7899882babc681eef03fcea3c755c94a2ac929a4bf2d9076d1585b807247d9f62d3dfd5873b896cb29ca77b2c0cd7f3e142a2acc970cc5f956f68943e57412a3b6332331723ae6374a7a546a4b5de9c1e3d52c67ff57bf2b34a2c718bd715b2fac87439d335b5b209a35fb196259c1adbf988af8fa27decf9122b1ab1397ed05568318cea9d7f4ff5e5fb167837dd976bb58ddd42eb95efb741ef334cdbabc1d867663a0acb7aae1fe98c52b1bcd15ebff9f0558ccd6f0c511af6261bea7644e6ec6a57e6dfcf5940fac6303a4e66d79b4c15bc7c6c281cba21694d4331f9aa6606027e428329476a7a0703d98656df3b126cbd5690365d6292f6a34bbf904963108c2db3d9e62ebc90b66f3211648424f3976be107848367d00611b19c57c519d9f87adc9099c4580a7d5501f4b69a18c99c3d36017fdde37eaec1002853ae7776dcb4c491adac9fa0835db77afa1c0d99cd7b007fe7e4fd6560cd71f18c2a0e1e7df23cfe2b8495ee9919c0eb9a48c944a6137c699cfbcfc8e451c350cfc46b9580d5e3acb45c350a15a7304bc7df238aea1871096cf72ebfd5660dbf0f670c90ed0e6d5140b722a8401a69d6a9f0d026539dff2a024a8b947f5436fd4510c35f3a8472a7602119c709dd47ab3a4e68d85802daeb3b6df69558a1a9952cdf9af32d7f246f103a643911150d6fb68dd31502ab6c820fa03018666da6f96b610be0826125bba00a09b848617f0819f70afe2df30bdb9504c1149f6a95527835513d782ca9a45abda59d416313186f4bb271674962c8d8d1ed579f2de5d5d06e02e6c0954af16c9333663336eea7997062387cf593aad177630fb2afec88c6958346ef0b50f15c184575d87cc3a0a849bb8c5dddd99075dd461ff64899823ba38338363d5d1a66c8a93a4339ae6b0f759049f35a6880d0c9391cf1d821060ca71f450226daed0547bc6c2fc527ee4da82e51f334692c8db304811d54e6c3be7f3c36f10bbf09f288c74c189d84190df437616f7c83911f829af581ee218855639803fe7f177a1772335b3280932774b94c2a42ff941a8328f3964a7e60721003094d2cd75b4e4c4e3677cb7d6566abe5b41c1ff7fcb996b78b4eb4a1e79ae55eb96d35a90cf3792e726ac78c7a19162959aa54ea78ac1331b8f8a4c2980f2ccd9a93919ec3c1297cbedd69cbbcc58a44dacd9ee52f3297f1ae1e81e91a649117cbb4268ec9571f1ca72e444300913f8394f54fe0682581fa66425c0221b8eaeca17da9ab360adce217eb054a8bc8c52849056f0bbe04f398197c055099cb9405fa063b395f3b58ac03fd11e08194a13624bdc16b909fcad1097ee3c1374ebabadd619d57081dd53988c4ba1bb23388a140830e69dd1141a2a0d7bece08a69c9fdd6d91e63433b7187c0992572a6e65681f5a6f0e35ddd2e53d8da92300707528fd0a81e865552133d47cb5918a8318d9f768d8e281ce37a1871d43e6d97840d4a5fda6c2a9eacf28c234b4d2a47e52452be1c0ceecbe58cbd5495de502799987b04ad6325178d69e2f21e375047d4f3e89b3b2a9fe442037bb49f8c2bcd99045d06ea1bdfd2756d883dd8c2321a498692377944cc44d6f73476641c6659d0b3686e6301ea9cbc4af8a39a0b83d32e890b36400edabaaf5225a54982ac248156f76e0226e7bdab4931e44d66ac55c4fca689c1a2f5bdda2f5a3c95f64f70a40df501e1a4c3db1c366df1edc5f3b30b2e01c8254824875b2dea4e5f5a2116be4561964fa15ad2e612fa721a111085cc97f14e8441834d881e6d63576c4d2a300f42767f3bce9c0f97192e22175f2c50d1cb487c48b0f7c0f1eed092681e5dd3655fb0fcc08f985f600bd224aa474701f661c3d08c343a11d1bbb49075ebc05b0b1f39b49951538fbb4f0012ad0e233967b249c666d0e98e9f36aacbe02d4cab468296ae443b1d7b6e8188c615ba73aa55abd491cd1b5daad8dfaac4703176382add0b2e180e9ca31f179dc8d81a33a35be78de7738af95590fbe689765828aec0498b2a493a0ffc87b2062e3978f09919bd5996fcff3b0e61af6a84898846062b9c233588717027da11a594f321e31810112fe5907417e26b0400b5281ffb697fa086c1ca9761008f6a3b15623b19058751ca27b02e39a084726ec081cc8cc206977ecb6919aaeb7a85ec5d1c2beb38ddcb016a2ffec2f46a7797632f4a2748660060bb932ee1205b5d649152c1325672cf20b2e8902363b414827418727022093ca0b961763daa721bb2c1d65a68c5b3901a3f618651ee048926ad47000b0f67f326c1139f1a61dfba226d7ab07d99532ac1416703fd246c75539349c154e04d247423586573388831096ce85e5be3235d0ced9d85fba66f89937fcaff09f16d32073a5710d8416b2ecec33c9caca5f2bb0f428a28290677ecbb22a72243484a9e0aa32266213ceb37745234ce9995d9be16829e6f9ffbb60314ebc32a8df71967d1a93a87469934de5729415146707a0ce9fc7a5f27de95ad9078e146bbed3e47a543042a32e3b0823a29e93007037a5f2e3b11404dab71bd73e2a5920b66404fb63c3fc60a02e8b3d55504c5827160b3196e8030072b0264f0035e67c9cb73d05284b25fcd4ff0303230dab78ac7205f7272e885636f5b2c211f9ecbbe5c07b74f48edc2c991025048abef55224e1347432c87e3d8ebbd660beeede4ea86a629213f7885e3027c3bf61feeefe06add8b3c231a1642c866bb656de4c59b26418cb0b8f5b7891402057872214e84e714508089c1d68dd3ee8c7e100bc1c129e0d2d74d40d440eb04bc4a139d782ca2d02feee8b0b7c4c6f16bc747db9372e803c04a1415cc11e360ffff7289b77ec5b8edffa4a2e9c6d4403d9010d20ac02ae53925f902d510ed9823059709761e07b8f1cc68393012d3063cbd71457099f83e85009be33687aea320fee9f28a70d39466d0bcc3c51c5625b9efe61358787335af999b08a3d83bac987ede596d77ed48dc385e68a6bf01f50d42ab9504b73843489ca2af418a569105f7150625182d7c96e39aea50034c9c56b33404245ba5ffbee1a56f02a1dfd94be716498e9fd3cb6dbe946a3407d60ecafae170dbcb5e1f5834ca4e748b95d3857a810aa577d6657b3fd53c0dac2b81272f43afed03acb66f1078489b2092486d526b7ca1791c0ea6b43421f0ea81812eb2ba6a2dd6a4052a92e7108ef77ff4fb0cba4e7b43b089583d6af548d59d02938fa8d2a2373acf8c4131ab401bcb51caba234ad42716a198df1a8200e72a56cd6d238510099d75b13e84fb09ed4ec56517580cd873b12ab794f5fc1065e155c1b80968fb676bc11ca22dc0017ba83a00150f968fa5dff84224b98550771b8fbbd4f0cc29de860ee9ae16107611799ac20a427fffc32964deb259fcc32fc3e03456be41549f8b08849a07b6775d67c20b0e3863845bb4b24a11924f23082fb167126894d0d4bd373066987ecd695d2d2872228c4197f3cc2cab8ab5a6b00d28a042ccdc39e921aa9179007bd652414ed19d6112d81ee01baa48644af5164bdd4b16f0dd9b275ac797b64b599c926e03996db69723286cb6602c85639beafc173a574e56ca9024510ec9238f79d203fb5b362d504d2df75ab391cf0ec819ca0e092f474f9d4ef6a6158bb4a077f32812f7e27539f37bd4e46a9427c35d058d7d4323afe80c591b8157d7906bcd93f192d96a83e4e5401d368a63dbb326913c2cf4dc25a859688d7534f5ea303f84396b4c513c01d1765ae33be618a74cebe09c0d1066741c8811b948b7d66c59e1c71f667142732ccaba0e6259424d021b98d485e7df214e6581882fcf24e37846a9a2bc11825f81293b8bdd0df31e9f10b5f601ff881761cce759981126f3ebc6b9b87edc926c9ca4d7ce848f90213ad5214c335ca4bf87ac615ca9322ae57de7a0d7dbe13576c47d13b6af3b653fbddb1d7ef48e12300b2ce5a53791f938c691f159e9f13ce1940db1ff3ce22b0fc602a0b79c8cb498926edea8c7c0542648b78d428bde73530c13cecd404555cf6f47be0c466c61c2c4206f496c13096c0090079f8c9945964b5e6a3bc571c9491523b4dd8a06df86f0d9b58798518c4596de3c6e6056cb36392ce3c6b21d5293c9637944d2bf390c24d6c05846dde5cc97089a0ace0d852a12af4119146cf8165b940000dae0b0ef1ad85d0772f06e96e079ca1d4fefdc1b7c0ba79b37321f9fb4cd11ce138a73c242078ced2263cb09f4c9f053063a9e8392a35172b75c98f50d0d238e63803a20ecb8bcb16e75b3d380cdeaa07f70d2a989c165d6e998d1a78f0e32d4109111f117f81e75d2187a52af4945fc336fa32da47c01db6bb05616e13db54e3744a7c705145593fbad45aaae6a34a25c04ba3c8373dd8a3a0e18efd504b88aeddfdd9bff8be7d6831856bf4a3798b8e15e4c869b67d568f4e79681f61f3372284aee8f90e6399d2eeb03c219eed1321c698b20d8019e542f213823463e5f326ac0f92abea8414ad1de5f126114166ff2f6c27fb10fab90be16ddd0ef6b98fef8e1444e43298843acc736f5c2e31e64e7ce0492178a38b29ccc4441c1986e6f3adc2b4dc9fba688fe484890a077f202526a3cef896ee1c396ca458ef7940282661e4e259b754c5a1a846e4330ace0a0cf123a632eb45a88d96bc6c0a136617ab984c9f793aeee0df0f5c497987f7e039782ca6e9c050b822213f662e3753e820254a2d82346650495148aa2f618119899a6f8a707bc98f06a665253a58f218ea10682d847a8f9b8e066745c7f3d56b4c20afe6901994bda85055a3d6a0bb5984d1bcef3327ba490eca98335b0b5dcfb86d3b4a0476ac15ea74338cdb2cae3e4f368f8d7f2799af82eba6f4809a5bae1d63b3107a25604f1cef51ee87fc6ac86857561e72dcbbf4370b67a258d6f5f43d72a23acff584a5737b8c176bb69c151fc38675f1096d7f4a4ed6a6e71b7b13e74a2d89bc2f76b69a3cb8938611823a8de927063614be2467cee9420ff73997a2f320084f39117a9b8b1c198ffc23fbaa6d8aaa87039d54a05c7852adbc89d065bc5f95e8b9d8f27dd2c072a29f6d22ae8dd5682dc293301a9934efccef3416afb65054b68788e280310d0baa3cc2950b9141584659ade43f81f6618a00f88c3993b5fda9cb9b86203a96915a503eec3213ab5b02eb4d8beccc7fd412d375e8112e462d576e78134776622d907b53c79132c25144b6d9797ce47666e6a39f1ce7d9273fbb59b57c24283f3b1d24ea4474e3e4d1ff7fb6db3542a51303d410864276b2086588db25862680bf94304ad1e6fa1a8c34c0a773301e95c31fd3fb808fa9ac4d845b49368af0645e286efcecb3973c5f217e6c1c18931741a229c518d85c4339032419c7e587d0b9a58a958c61b9ba348fa8cf67aafc0aa07e3785929fe09aa7edbb8edec92c9355662845c05ff9fa00083c1076cc3021af96d655c3050ba9236136702e776a51917cdff2cbfd60533a385bf00f9d25567a06636655dd53d2202ec88603b83f66100764ff6d6064b70485307bdae61ff48e6cedd0a962c8de42ae600c879634975b5f2eefe7dfcdd1a114924b2bb7bd30e5806e30567061e4dd7f1b82f9bdb73f7fa6fb8e3e1e211f7728793df6f586b7fe5711fbd9a971eeb673c15dc31adadf318f72e468b7760e34e6d292dd3fefee65b04eefbd457be7bcca7748c6e6daec53bb86f7f468c9f37d959c396a4de4a9b1a0f4a9bac3f9fa9fabcc9b65f3b1efeb294fe9c763ddc76dd1571ef5ab89f1d0fe74c38f9fed5aec56fd81a1365aa88328ae042e229b0b4b2ac28627232ad38ba44b8708857b5e18ca9863d379c3105714405c3ff0df5e73268e76e18850294bf9b9c1976fc1ba6a21d1f27287b8c45e6efc8070001ed480f6867ce3967cbbfee48afe5ba0734213edcc1b27ef49736f3ab3701b8335d516439e7a44f02d520a0b1e1913309492e4f5b5631b4a584b89af043e4b5a2ee014da80f77b07375077b2701b823d43d00e83df93d20d00ef5807660e781904e24c13fbe2b8a1c3ffe8e94cd27616a10d0d8fefe83eb05d70a332e5e6e9083cb15332e5b220e4a65c494428b2db6d8628829d6b2f8f325a42b19b578b52ba38cd6b37fe7cfb78f374c3fdf546ff6ef9c57267fc20ac365c16a68e60a60c3d9961ab6085171c190e382e1c955827c83c3723d4cab35e44bbfe3fe72dff5707fb5fb98f3babf9e0fee3bfdc9ec6fcfc92ce7c9fcf163a9bd73b962ea41ca53e91447f697b56829daf1572e19adff659eaea73ed59f4cb266679f7a3e64f4ab8c7ef56455eeaeae38af5bb86870cde0b2e1052d35a8108316188cd029a316145c4ef9022c4bd4b6d6563a65d432574c166cb5d6662972b3b4c0d960096a5bd296a4c84b51524b4470331bceb250d9b2400d4b142fb84660abb535898a09663d2871431849643060d27484051dbc30c10daba51fb6b535b076490516ced292220a0ba1a538014c0aa11a2f345662cc64b0cca0c3a283bc91e392e16a2e12643992c5c815430e970c4e9260fb83ed1b95bea8108612161bc2502ae248184a514c28d960d71a87400213c92a30a90d674a3f288145c8d9174e2ba150bac2a4c4c4d221a80e92b3c164b83fd6bd50346d9b0d674a28400146d29c5b7e7f230270a2cedc4d1828f5c77df12995b9deec7773d5afbb7f7743ceefbc7fa76ef998adaa7d7f74536ec7b734b88ed11554fdfda34bf7a8a8f9cd9fdf9d2d2ea82492a90d8864bce1ac4a10ad2fad2f95f2207af8b227becc015a441ceeee32be972e5dba44ec3aec40420e49a4bdda76376dc88f9c229298e455daab59ed834b3e74e41491447babfb9193acd252ebf9d19453ba53199d3e158ffe31c6a97db6aae4f810ce0be76b4bbd6121a39452c21833325db6b060811042285d0784417ea385104238e174296df0429d381de13d743e43f47280a22f335002840c4f5400115d216252e10a1510cd766c1514a8e813a7d91355f677a9443d8174f30413cb05d3c27ab8357d4371c0b00319ce9cd8b2bf0b67554410a3921d21ec3b88d13d7243e2f6893bc97da2c9feeeec0926b0b5949d6653a02e9c4b24d94aabc7727d6b4bbe1bcea620a1624a0aea86b32936ecef2649065a5dce188609e49c22af369c3561854e13526cf0d2040d6cf022b3e1ac091e36cd86b32666d0e271ca2cb2bfd42f9f63c558abcaa4d45d4f0d63cc5f6a1e70e726a7a627a7a628288f51ca39a99c93d25aed9df7cae897d66aedbd9abd57d3b60d4ba96d1bc61cd749cc715d974aa97a70292729283bbeea48e564c7cf39891d3f064966cac8c8e83241c458fc2882a1288288827824aea0b4a4b46549a989a98a1739136fe245cec49db892a82817f2a0281781af50822711a72401957a608f51ca39a94729e7a4b44e5aabb5f76adbdc36197db357d3b60d63ae9b5d27a3771be6b8ae4ba5545d4aa5ca3926466666ceccc8e8333233ab150d4d8c1835acc962c9e8ac18194e7adff398e1e1fb579cf4668d58cdaca991d16b6eaae543d33437d5f2b125538cc5478236aec81f6b22411d343b3e4552802f2d29ae4008e18c2d2c170bd5fc462beba4746e2cb1f594e7fe62bcf594bd95a52545eb4aeb4a0b0b8410c6e08027adf66a7769164d5aedb54b93565be5d0a4954e3a9da6f43e471263cb8a9452ca07ba7e9fb4985a55b4b0b4b2b4a46859d1b2a285854ad31350489372698204474db8e0c549132d3421f44546e98189246de0adb5d65a2d0f49dc5c6badb5d65aebcfaaaf142669032fd00e457c41054c0ac0002208294ebb56295cec1ac34402163ca1c1130d4676280deefc199b6ea55483f0d2a4212de98876bdc9da4a9288367d0e6a8a2eac7c01420524aed8a13cd410d2d9653ae1cbe1b8d19f5d6975edaa633576d5df8dc35a6bfd9bbb43feee8eed1927f73ce27395db80760d82b3353dbbf80dfad7bb4a85c0316d7b98f6d3835b274a874e8f1e06218490d28061ec72e4d4e465697a38d36936cd2ed3693a41f16146251f497d64143ef810638c51fa4c28b4afb4fa9e9e4ce6edd2dafaf948cd930921223db879f873f36a0fbbabf9f51df3e5cf4d3dd98c4fb3ae2036ffee3a57b044adb85690ef47cd7a416e7950cb77dcee8ab15e9790fd6947d8f4ab4f5e419e39fce59ae4ef66c7188ceefe3f64d80e5a45e66ceaad622cbaabc9bd39b3befacd2c4d7ffff1eb9c51763f6476302286b9a59e3bae25b22bc6a2ab498645eae527b5947238b569f9bb577dc7a37aaccaaa4cb3865b45531d87372d461a3dfaa85c162143c6cfd4cf78f13bd7753513ea50bdeb2f08acc6ab79cdca78d8b90cf90386a1de2ac628d06fd5dcf3bb7be63d5f46c6d33ceba7fe54cfbd7bdff3b01eb364b06478cd5f19da47ee9abfdd0f58e3c1cdaad1378647e3ad643cd5a7ba57a552f369aaeb3a0fceeddd8efaf483c0e6741de4872b882ca6889ae535898944bec1c99996c7a90961c28409336d722c229b7fe786b7adc776086cefeaeb448a2bc6dbb6c37e1501b665764e2e893c3fcb18b8c063c870e625694bea4df1405e1bd307d40175f83eda55feea6b7dfaeec9ea5f9deb2ac25e906ced6fcaf1f656e6abe549fde67d9267e621b4b1ad3cecc5fce6e5b7da676fc6fb524f5f8627d583b5036dacbffbd74b798082ef7c402bed53af13579e0fedafc695bb1d0f09f5e5c3ee7ff263f24befebba1df4763df2efd7ae47fbabbb9efb38f59887fdedbbae47aede7a9f7cbad2ad1ff8538f3ff59a26b58c0728f88efc99a7e97aea7ff261495680b0009f7dfa34d853fd8cf7c9e80f68fb788c274bbdefecc9bad7549ac6bbd2667eaaf372626c3eed7a2a27b9fb1cd441c20c1f206cd7d5f30df78a660605e5a0b80342090af28608814e4141db4766e3973edcc63d236c3b444803768436b4f7a97b1bb2bd4fed01c1134263dbdf3c210dd80e6d6856435843d3df7d2abb2f1fcb743d746638ef76dc9752e270d0c67cdc4168e34bdd401b53b7a4de11779c891d942a29923d53d349c6e2b775ee97524a29a5fe82e068ef3a1e114785bb3a711d4fc51d8febc93dcbb35fbd58d37ad78cd743c8c1c76ec796c29e237376d5df0d8c5318632c37c99229f9a97fc72c2d4bfd2683468f0cfdc5bd3d0dfdc59de2407f37965efa8b5999a1bf8fe2d255d75af56f5fbdd95e65a90f57fd01fdd46fda7246ed2fbe4f94c927b2aba7dea73fd6f3697fd14a964f7c6bf5379d6e6c3c19311e04e7665f5d3f4e2fc5ac7c1496117088046c5b806debc7b7ee15474d04363dbb68acbf19afe4bebe7b28550fe5eaa1a4f13e46047cc8af3db2c93ba8ef95e36aeb535d4f8cf7f477e3f5175b3d0dfdbdea39d02fedd2fe51beebbf9b2dffdb74adb1ca9761296d8cfa34f557f555f5bbaa5dda22f16617bfa1c499384eae32bedf78eea3275f47caf032cbb35ff3ddd89f2b59b9929a23e7e6d4dfff6e6cfa50e6bde37173e8cb5cfddd886dfa8bfdb372647ec66b6dcf3ddcfe9fcbf8d532edf1ede21d5497aeab3f7eecd8cec45404b08c8c6e6d5fdffe08f4c68d58ec9fc5caf86b109c9dfa2f08ce0cd892fb9e3dd8f148bdeceaee6dd7c3ed94df50b149f2203675fd05c1d9f855faa6f0776f6717ef004e27ce953893d9c56f54faf2677283a52bb620d9371bce6ee0b4af98620512d4e6f6fcfb47f6c5e2088b159aaaecd886b3a6a2ddc4b4f1f667aa320fff7a318f394e75b99adffeca1cacdff43737ff6e461c7edf8b98787c763c53c3ebe1c7f8ead4cffbdbf5edfea6e5f489294f969fc8bef05ed79197a627f55abc83ed5dd67d9ef9abbfb8f3cfe82feece99b6cfd068ffedbb7e6ff7f92fe5f2be16e887c89d9f094ffbb3ef1365f7896cf7e6f452f3534d42e4fe5c27ceaee78bfbae526f1fffc7fdb6e9cf99b64efbc4ddfda6bfac7de2f6cd6edb36733ff71b81ac5d8beb567eece3bef7dcf7ede7fb9277e03f75ca63fca6ea78cc772df34f7d6af32f86f6d9eeac09ab0d91829844611aaf16a21042881c5c8821498712c85ea872e5082c5348e0829df970ca9e48275409409524249bdb102968861610c9321b22051569810bd364c34f6d380bf3b4fdb9305b64369c8549daee02d2094d90828eeaab0549a5a42b98220c2560c0c5972f98804e273862c50550280c21821d49654b295f46e8136192a04e8451e26e380b03e50a2b071340312ba201142cc0a440091500f104153498618728db44982539e0249d0861d5f0fe58378a9730270833c405175cc0b8f089453e92330c0b2f6096cb2ae79c609658295dd4a730459e9264e912c653942cbb36c1e18b824416444091c2858a0a442d8183941734a1c3951c6e122b4741e2258c2d515974a1922507a31910506258428b18c880082b31080306051a94899c2eaecb8b8c816902660660906ef0e20ba80c25ec6088cfe9332337a59452dee8c383827c4c2a250b538421e0d107a8e0a88862020610515a6eb8c86c388b4a8a72620486915e38adfcc20b2b806e98359152c410568c60850a86925d691235e872022868a0024b9213765c527cd104c6095f8081c5ceff58186e1846ef87080887717cfc9a06927aa97fbccb59dad8b70fd361fea663cdc7f81f229aff2102b272fff940fce704c27aa97fe4b3b407fa8708488c77fd73236decc7f81a1d43ffe8481bfbaeedd344fdf3d2c6fe0a77de0f1110d734ed43ef9ad33f23488c75d43f580fc577fd13ff8708887fd43fae7f409036f6b9ffe962be89495a9a79b863651eee6cd7fb21028277f0ab3ec6cb9e09444038fbdb9b8004962457acbd48dad887e9902bfdfaf4e1cee745db721edcf1c28917491bc308632a49cb83fa14f01dba0361560524a3e5c155c545c54ace14186c8a947e052ae5e4586ba190b6b5394edc2f517bc686b32e86b6b6e1ac0b27530557a082e8820817145f92b6853df10509f6c417215878824e19af7cf1b2551bcebe2c3d39cd9e989e96f286b3a7a40f7ad05ec6df1ee77397da58ae87c562a8a6c9a8c538650cab3c5b774777f61cdad8baee71d7d1edb76d9b3b7a909b5b93bb4bc5dd79d3722acf79c8aa25f993afedb8c5b72fe3c168a375dc479f19a3e6b9624c4e6e89f6d8e3767fc6fbf3be8636d8b6869b778bf2f6be61edd221d37cb7edbdc9de38c980c880f890ab6fad6d4940beea270077848c746f24760fb4f1f6f5bee6457bf399b5deb9c5b90547fc61fdc136fefaab8823751fcedcbb2fa75d4af2178bd590799a433f879389f1663cee5529efaff7e1977f39fde1afd883fbdac88507ea8ffb2f480eee9c3654809006840903666b0f73f60734e49a1621677f3d76a765dccbac7f9cb61cd8eedf085f09db7f70b6bfb08b507f177f77771a721edcaefdf9d02d6b4c2c2e3f56e99e1b461cf3a1b6dd774d6d95da5b0ffff5be20accd8323dde49e9101dc4b2fee197158cefa7625914edd7e302113148efbf25be1021fdcade3a9ae753f4c0892b3edf4a1cb82a7a32d9fce8f0f8bb6fcd60f8964cb7f1adaf669569eccda97f918afb50368c7606aebc493931d0fc490d3913e708d57f32caf35e166bd773cad777dc74d6f7b3dec7850707d0abe836dcbfb30c62c6f7e8d37e3a7acfb39e3b117e3a797f1d7d7ba1ed963bfeb9979cd6bcd78d6c32d437f405bc6cfc7dee7dce3ae47fe877fda9fba3543ef00da31dffac1fa9967fdcccfac5ef3646478f65dd3db585e0cc6fa4b3dcda7faedb7a93ffb9bb7f2be191280f6f632def5723cd9a7e46f18b6f0db8f8f31ee2e87bbe7eefbd4cd0de13afcdcc51ac21a9784fbd8d376d8978f7fd88d8336e86b9eccbed433c6e8cf9b12d4c44d082c4b71dbad46e886ef818b05195e0c602984477e15a281cd830d7f7a9e3bd01662c606ba61fbef80526c7719b18593ed0fdf04225d0f383b9e8f3e9c0fa9fe7e5a3be04f2de4677f5227c64e480942454e08da10c6e0cbb99bcc8d55f273f02a729d4e84da76ef388e62777777f7526fddddbfc6cd8ebb5d6720323c227380206d2293eb08254aeecd99c5fa8fc5f27d9f816abe6ddbf6ae6407a1faf8ce8a31bc79f735cf67eefa1c041263b1c7e72bc4e4bcaf4b890cbbb8e9801d86ec1f83fd06241b804219ceb660b2c50e5bc8b085d07668012d9ef6c72a624b2db66cd896317a5cd437bb5a90bfeb7af94213d6b62c97b5d9c5247fac6d592e102c0742f00e7cdb1fe17d4ab01e149968b1c386b32c8ab601369c3981d939e2983f699d33c6ce3544aeef22f200c8072070208488a304396e38733ae245933a93bbc7189dc9995c31c845d369fa0745c060e43d81411823086ca9a2871faa70010a6408810b2f4b2c04cdc08a11482900b16d75c108295d3c0924a303641b4fb8d000a17028b8d027538ca015558c06f0a48809232b44dc4088212301689c2746d800264de12c403037406d89c193e010eec4f5041e2d6104841750bc781118850d59182919b14e60d4001c374f16f0c47b805135b8e04dd08b1a00e0c9911116231a4f3c0b124610aac9c88ad1569f80b131ebb2430c4132b8b08396285131588103123720a95045ae2dcc9c8c3092112c2a0b4718e0890c46d0e90ba3023c71c2a5d83c8159a430032d68708153d0a0c208420821740821841042081d3edc915530847139e2b473522aa594524a6b75e4d49e94328c311042f8f940fe08da63d8ddebd2be663dc8ea12f28f104402e2b4fda5d4cef437d238034bfee051fed603e03f4fea1171c0add23fe3bd4fc14e46ce0b89fcdd28e0062787c6cbf7a5e804ea8879398097ef4c3287005e7e0c923902f012663f7e3c8a4a62932d9372b6ebbf882448ceb69afd9713390476cbe8c797af29991571d4fce74141fb7e842dc91ef4af28f9f3244faad51b32b71afd5ded63b76bbae9cc78235819ef272826ab3c2ff21cc9971c2a6a0002f06e7a80e02b481b4712441207decbd5f266c8a852855b6d27b9a10b518ec0627b92d74aa9de3394327dd6cff80f267d2073c8e05ebe0fd4b1bd7cf9b086d0a3ea2039b7fe4b89fcdd740a7027ed4c9de74d31e625e49f18138236fc295494e7f90a2c8fc729a531c61863acb6d21262cc9b5e4be4e84376cc403451f5e4fe401df507da807f018a028611070fb82d2b0704a803d35caf0702b4e13f3d9d9ce94940628f98a347b4a14468f4297c04a8e3e7064ed91f3c82f30232c76bc6c37ffcf2722a12f7d77a32fba9aff7bf1ea9988751e6ced0d43c94393878964af51c7830dab0f4cbbb2b8f255dfb7e8cfe60fb7ed3fb523a48cebecf751ea7b1cbfb566cbb9921c3650e57b489af23f2b51732edea8510635e13ad9109218410ce2a49104208218455a09c42f0b1d2871b6d7d3991a1a0f6c77a31913f1ff2a188438bbadaf5864ca812a0e400c3cdab2d0ec528395b46bf3e7c4dd3e64babf2bc2f67579c3df3b5d6aafa5a3fa6faf9f5efcfe0c7b0d3b4a9faec7d9af6a15b7b556c7a2afd31a67dca9b2c588c692fe3dd68a37d8c57636b5bced6f47d1da9a9869288045245c9947a8c71d77d776f9aa6a29ddb2b89fc3738390ad031f532c72ada7054af8e96c095524a29a5946af4ee40a60d5b92edbf92a2f69b46378f297a2100580008702f8401c1376a006402b0b81c63f49e524a9358a873fc56d597255f30e48f56d04afda927abac54097f16229af4f58c716a1a59be0330844df8f50544e620db1722a2f529f07a05915df98577f86eb5f2b651bf4890bf9c57ac1fe2fbfe7d797512ed7522dc51cec84244f4358dd2abd1fa945e7a2d172c039b90e386484253a48c2a77fad9f58f1ae3cbafdd8f0ce8eded78ad8421be96642c62ad39c65e3c64eafa38fd75e2742f98551383de0b5dd36421225644c04a49ae818412caef63b19b1a3832c85f2c56e3062767958f588077f89ec9f2695e3ebc7cf08730149836442ac2b47136442af2c3869d8fea5a26eb4408830dc0311968c3879e15a51a1e28e55ce006476ad91fb7e157ed8a36f1238be5633ead1171c45617d91fba4bb924a1c855ccafa1fc6a4176393f471c52ca6d458bef39e79cafa2cf77a7763c75bafc0885b32ac38735d571194ebc6521a2289f01f17378d45a764f00be194e0c6175de18ab3fe58b87fcddcbe5d510dff33fce286da62f4424bf7a8c462e7797e47a82646df931f6ea21c7e2d3e99a660703eff03d63b0cc70220941d91049a8c926c08648424294ee88bb7eab570d99ce9802d4bb078f5410dab0e399ee412414a036eca2d5310b11c9b79f3d09ea8038e6d7a7fba3b0e714c6300b11b94ee177fc6102acbbb5d13a8c94661971c010de181f3724c5908a30d9be5f33e4ef5f32e4ef735c8aed0fab01a58c1201593e844230943a3e442ab2c39e310624fd0238035888c82177a3c783db514b4aa9fbaba8a9aa729c3f63acfb21bfbeec7ccc29a7fb0c43d8f7b786fc5d11308cb6d229e30819229d00658bfb4a4146e981f7bffe2c7720779f412d2d3041030a96f010f50355021ae252e54a11487c1982c10e7c18c24b28e72514a79c53169174548319a4204d61238b0a4b8ab0e284530b866a0d5c2c41112338278c2227ecf99c14019914a8942d77353d0a51d5480000f314002020100a0744028148301a89cbdc3b14800a88aa426648994863491083300662100310210010400c21c60004908188f000048e3cc2f7d1d4fa0b0d44ff115683c72175d0a3f5beb99bd01ca42be257215f88393f8b18a4c4f36d3ba4c7030c7ae8d01edf1dd8df115a1f1d1d74cc732f6dfd17b09d5d3c846647a062d1e0130cda40b3eee3001ee1baa123f7859647cf04e58067c8fbe85782471e7b79d4e3a9b73c00aa87b6fe06ec2cf78e90b4e862a0239efbecd0c3d38d3bf7dba19fa73bcf3d3cf478ba6fe79e3b74e9d0f4c36f47907df4559f401edd78d2788cc5a39b279dc7d8eee8c24e1a8f1b8b67a80b7db882209468d07efbf3fc581f6de50fdc516e3b42d2d05bfc85c745f3d9536b070d0f313cbabf939e56fc1797a7baed0887860662c290239a9604412bd119cd07633f7a89cfee7886c642ffe1570d0f75a1a1b99840354774e58f773b42c546ff00d67ca116d22b53424ae25cf83c7343f773f2715cc1fa0931c0beca04faa0598ca5adbbef68cb7b4cd0993ea893b44a142ed36f49215acb94ed10537d00566c267e8192a341a630e8014d098f773cc28d818edf17ba0e9d0b524e8fee13ff1d41fb68567e0279b8f0b0b4f450c4ce0df9357ca08478c8af981334c26ba0c621f4284bf8480d1655408bdc265b95edab31fbda4177c67504cb0659b6de21818584fa601ad70df91815f93ac04fc6485b160d6e5e1738d5007506bc3200dbc1e27f67c5c8b1a5d196c4fb13057aaa686a08f17a11e2fb3a7eeb38241130991b89585a0a11a21b56aadbf850c85122c37ec08850d34d6e08145978ffc54ff16a2c115e4f90e13d7d2c1ac8d0a8ffaf3d7cf88753488529a3d25ef7c0adc06b6139cf50357a2a2a3186f2035047ad94aea771ecfa7320ee8f33ffe35e3a0c11384ffa8f926c387469a3286b89e6a2a27aa51ff1cc0b9b3db514fb0ccab66d596452b34b47fae70f853fa0613b5408212730aa527c3bea5275808f4ab5a5a708d1640169c729a072ae000c000fda9252ab1e0d3f394e2223ef0dab90f3da583c4e33aa3337679425c9e03a22611e3d346fe164278e6b2f20f24223b468bd429239fc17906473f80924da2fc3265e705b597b0d847c93b0b2ae96b99836bea0218b0a63bd1f1b7f049ea5ff112480c226b19191f5c44916077856819a88eed314e668243a80d943e889e4dd0fcc30020c004b5b13571685befa4eeeddbd582b63dff4747f146a68c601bf1b482c1d6d9998275a4813afc8f797ed444add3838cf500beb974164e0973375023b8afb7b4639194c48357b0bcddb2ec2ba62951b33abf38626438c33c174bb3ee4b73b53cb64510949ca7ea8e9701d36125f46d176e0b4de2dc4a11cae1dd3ae206285645aed49add64d98b577b9d3067bed63efbae7fdb6a6538e88d4905c9f16db3d2c73535b6f01b4d32958a65f364ff56db21daeb95c70c79f0faf31e2d46a90df24630691dd788ac0702eb36d156e0226a754ee2b26613b85ed0f99c4ca240c5115e1fd87987bb13577aba8cf817fe8038fea81082516b364a3eaf1c778c8bac391eb4017535ad00547cccbeb170f729e3721b497d5e5e65c7598454731d3b3397002ad5485b8daa57896e0c7833201f6fbe6cb4cbdede3111ee0607f656c76e67afc9a9e5cdcb601ad8f81785decd3bcbe0be7b2299b942f2144aa2559ab1f2e405568861661d911b072b3d64503836d215ade9802ebda008976ab57ae21796a15e22ac1c6939560585d359ab79c2ecec593f42372b96a87425837c3c7fb7f015c966ce66a92266ca468c1576032494aabd2cfa18cc0a047db614ea77be6f1ba6b6c2b703c4e94e865e066d8af0d37aa95933924520834413860a9d44f349ad4fc495e4f20652d9b9f224675247d2d2dd552ccdf9d05ecd017ac8e0b67885ee8578c06909d642aa60c21c679039251f779a365edb77f06f0b2204a0927576f8fe80db55d0ef91983e70118b0efbb381a53a06791e0bde38e9d7e474e8d135ff4b89ce91266856b880c365b281754c6d1d31a3cbf8b6afb16e8a5fd479bba8bb1a08291e38f09a1357c9f26d65af3c72d909b28feda2c67a5ec79aa020681aa38331a5ac2925e2f18a8e20b6bdd1f4dcfb57fada480e2484d28e1a5ffd0037501d7856e6accd9a651b29653344e74ee954675b230b18297498999738d10341cde42754c3c32e98a1a2d5a0c2cba0ecc66a3bca4fcfd7934520241df372ffee299096b20f40a29b554a59f30de0ad5cb0ade21b60adc3e41e9806549c132136fd847ac6f32b1e69b2f03742be672d32f3158e61072de6a489d1c08fd5a40c7c39fb4094beb65dddb4ec29f79a9ea02470456bb8a4a61982a01de5e88482b81b1d941fe7ae99a8a324c31af8c1bf5642dbcf07d9b2568eab8bdd27fd05225c1ab2bfff1a8257f13e64a457aee0830fbab1c1991513d91d5188f96419e9fc26ac98c65cc8c4ce81841eea1d9e848989a81131d8760c7ef31c0096d071773848b68650867ab2bbb60c7ffb86ad014dd85f2e0230fe3055f05868f684700a0b8918b8a098c0c0be554e2f2644a9a74d34533bbb4c9c95a0c8945db1cb99890197a436297127ea5957dfda106893a53c7480519e64b764b2b97049b356060888fa595572681a2522630afb30ee9a54c7647f5d83fa450411f7dd951c971270a798061acef483cc414352c2f7931f1c32a70b4bdac3daabfb373fca23a8d450f2064840e8f3c29c28b44480cf079a77fc89d13490b97f13ee752b1c789423f207ec95c4bdfca86de81dde1ba0dcd2336b76d81862ec6c1517ac784c9e3991a16094226b7cc8507bf29a991e953b0f00051c2860e15c52bbe00ba8114c72dcfbad359e4e116ef11e884753f82cf64ed79e89aa88b862e6ac430cab2bb33a76b520a0a81806d82218c119d818609e88b8ebbcc9afae706052c48af878b0d7ec7820feb619546da0e0325f6b0264b46e0908d2d9f806ba2716be264a96b12b0366973be8e2d7b9d61d8d5647a7c415e0fd6e416050b5188ec23025f25a6af20d3b3b007a90811dc92aa49e0e9cabe0ac377261fe67f73e8c63f8d5b5202bf60d3a50a324734d9a0d98586a6a4a26cc915dd52b5e39df1d0b1b28bec1336029c3414bd4aa7617d6b50c496ef25a464be1ac8ca97d8ee4fc142fa4d78b42b113420e060b6a154b19c2638861971902fbd632c04554ec86c8311c5622cbcbc9f7603b534d54daece164c5feb45d1fa22d3e63ee2eefb2cccc1485908b13543aa3184abf5cfc26977fafdbf1bb18d80577fd494a94aae0357f99704e2a747a3f3a4b817365885666a8fa41b644631413535d8dc1ad08efa86c9984c07cd927f8b9d20d0a3c035b45a69e3b58781b1129ad93b5258984e72686ac93e3a9e5f1bad933dcee160ce5c1b52b2009640b27628e22059097b9d197a769d86c0aa676046fb6f26a3ea81234e106105fe83667e0d4e8b08d669c425efe44c32ce31e402b7153d34c96e7e0d69523d5149eb78181bc9746511646a27e83b5e205d47231f49ce7e59c4179ddf6ff62a487f51a8ff6f6628505f0dc6d9b027ae8e85344b5e4a19cc30573903703d8dfba1846e590c207dcbac44a3d0d5d08dab5bd469c818a80de17ccf1fe4a4566a0d40a082a2cac85c95f88d4feb73d0c1135b60f0761f4be62202853125391adeda32ae01e467575794342d34c2e4588b5eaa5f360f534b76a7eb0e9a4e762101d82baaabc1e46daf88dc6a90fd84c05ede2d9b3863ec5c83314f126c5e2da2863e6e08496b41eecbf39535ed90647fddeca06a6988a94e7b4e1140a7e4dc2457e86fff307fa1fc1586a720ce86bebfcab93653a56cc64c9a049b1dc6b4246612fb52872bb87a66fcb5c2b68cd5e067f556781a7aad460bd871f363b366cf596a593b34a5f1879fbcdcb040b8b3a49787ad49b473fab9a553b2df9cc744ee2ff9c7c006d1d8bec3238ec3059bbfe2a855568461eea8c3651d86b87cbaba5ab4fdcd74096e04461624e6055ab8985695e9cc4124c31ef43e59cbc29f9cced382e5b54ef18f83514758f99113b097e19a0a5976c2a5781ad3c9e58b5b91445952cb4fa8fdf274facdacee6c57f98d51bd094e20e1433d023d958a1d2ba546298c67b846cdeb59dc2061e000f6342936da5a208df82e5475f9847b1b2ff1238ba3e2762f0c1581c3f34fa9fbdc0b389a1af47171f04500804529c34f37e6d2a2612804ad1dd0a9984fc13a625526ea060963625f32aa9cda8c3dd26ade01ced4975bf24cab9c66f92f0c91dd8036ed6a8336b2365a515ba18b706cd636a124d872a9e13c7af52de542a384072fab11e21e1d9cfc21daa6abe160357fae5cb02f9b2fe3caa8f61fc8ed2dca007e8f7bfec740a8c71bc8ccd4099e92f7a07cb2068af23913a4cc25e598d0070d00a9b5d3bb87d23b7154ddf23fdbd642e62bb4b1b9dc48da9593b36bee44264e1cfe6d063446636f365252a753ba18a0ad779b81654b63e72bcaca77adf8713ecc277cbef959ff0d47ee6ee4a244a34be0aedf5cfa8119b788ce9f46cdbf2e34eba0146dcd8431f5beac4581bb8eca1d04c02a9f0497d01755695d4b17f6a2179c693d16ba5dad67bc0679136b85ebf437d19bc95fc5d4a23b433576a14b8030c0911f48c8738bc1e5090cee2730c616d4f4eafc5e38cf3cedc05b1cdb9427fd30d25b13f9d08626b15f03919a06052ccb819c128191e8ad560132f604a1a8c27289cb51650eb1ad062944a0b17aa9536eb059284bd2594974a61268478139bd0d9dd6a29ec05d94d4b72d1b9ef48ccea8e25e380d24c0cfad602686c988c2d297cfdb3523619086a81aa56dd8bcd8d4f7d27c3c9f2a9981fdd4094d230738c2708c618be4a9128eaa84de8af7b1e348b8fe8132acaaa2a106189be7aae77e535e74a6898a9b341da00cd05f21534ebaf63e59f4a7248f3fd276580f93a15f999f6db9a4d29f93515a2c52b948d74ed25038bd93b8eb3863784f8a77131a8f5338882c1fb4f158ecd21ad66bebce992e381b0b0fddad2d52b3750b9e040f5cd69e9c29826f6133519338280af6d9c8e0494783e78fcec8325e08ca5d6761ea2ff1791be83380d052c0155ce0dd9773c1d88308a4193fffcf6cc649275a9736eacd9c4bcb566fe0a123d80d6d8ad1b328413b22955a79216e7f1741aed3c3c0614e642547089035fc21c644565a4a95190bf64972016a64876c6920bedbd0504f7d4bd793042ddaa9af9b356e304c2547090cd880159a296018dd1500a6b010bac2c0828719b2350532005c1ec3906b7dcfda4ed85b74acb7970650c894d02107a044ceb259cdd43100e23cfe1522492f339289662a6e3c56c4a9a28f5ecf8078d27be35626f942f7509a3525930484ec4987bc72ecf3867d2fff1d42868fa001b790d565d279b63cd186a03df5689b2ad2da36d790b1f3d8693e0aca3a0376eccf70d0c1baa06ffef77362c2e031ee0cb74231be13061be959ea7e7b7a44aa3cb2d791f1640e2b7d880ca87dc48db4a317268260e610e26f1c88a77e576d2ff482cc36e36d1f6027cff0f29730f7b359b09bf5a95aa4c7028b9a573affb853bf5d7e9910ffc7e1b06400d82f0592b0ad6683f3566dae670b86f1f364cb19e586a8a54b42aa4b407c0f905c8ba1452616ac61b10b8a61e3f4a63f098e1365d3d7d11030b961fcab3892324d25163742a3cc72723579aee81787a14ff38cd5cf9755eb2a00639f095914601548b2d274899c2b8194254d349f18c0b4df22bfca1e9f46907672e8baa32df2aa77d7649d22696fb0b2483f487a024a63743064286e89902c3fe390f7893638801e487b70731113157725a2f69ba5e1675395f079e898c2d4d047624b193ed3d696b4273907a79dee9977e73b7e809e44fc81f7e39b0b4736de884117a77215ee4ecb67d10296b4cf34d429fb59e8e1b823894a3af637dca079ee7c6a4fc821b2f633bd75235887888e49a92d6b91ea447481dfb754d5065424c3c80062d9a9815d2d5182416b3f71fa1c7640e23a7bbee2c96ce63623e17c4b67fb7520a9a1a23c91782c1ae4a8a1540816de3f5e9f88d6e89c91c4cdd0e0b5fe107313d32599e3671b52089ebb7e90babe5483894bc4215b8039595e36af80ee972483873787a6c428aa507e860ff2d72c1eb882eb5015d2bc62e4714f09003744135040b6e183660b3f90af21823805dd1abc28f62c09b737b827ad74c13f51b776bf1d310bf2478201eb06e937ec997d92c550e7b0d85e26776ca638155d933d1cf1c6c937f27fec05293b5594a0d2f7ba57ae6cc8893148ed7bb020e7403e93d22a9d36d04c123abb849436f5d68bb67046a116feea5e62d0831ea71f6d3665259aebfa0c275417bba6522a64dfcfc4337f5f64663ffa6711e1634ae613c29d9f3fc2eb8f772712b4ceba50c1abb16f7ea126452bc4e8826181a5f912046326d6104ad82c7542387a0d0d3d802124fefd656d0ca478594f26d980e74227004335a1e7afcea5d00883b679e395743c78483f8ab8ef540063e161f91a6ad29445da9cba2ae2c5cb0a3d1c73e848cef126de811186988471ebb8c226a60b98fe8a797e442689d46da80b9c5fe691286f0d57f394f584a9d628d5890a63f5ba52105e9d6c63cdf1cd6f64fbd9dcd41fb67de4b4fc2a8cb3a9c48df3647034b92e1d9229ef884e30c4f5b5a99937d5732ec35d3b809c08bcf45925c3ef316dec3ae2711deac9e2f8fed1926ae3616772042eb5b3405b145740d95528f771c479fb60fec5f1b35f993dfb8f98bdf42dd812225da418147d989cd3b3f786de6f1912a38f3be1cc1bfcea1ecaafe2c8e14ccfb7048b200fa2991a9454fedfbdf9f22b9cbd57618866a4ee73c9938a8d694b72c518e31714e8b91add0f7c70ff9276f3e18327532e6da87d303cdd54934576627149e25f1612e5551c218de9a4e491086cef559b0a7b8e7e4998bb25fbfaa7b008460f012d22f33688281b614813da54195f5420a3b068d8dd27d4465c855750629b58a3190f8c433ed9a9c290ac2d113736a8e43c5b5a5e26878abcd470b7aa7f5ef5f9cb8b1fadb1b041bd836d0254bda4799ff9d3e4afc7145d92533429604854f4851b8b0fba419ecaa49a20f84628a47a69fda11fa542de6991cdcce679c6e39ecf420969e97ef1c7543f7e081d27a798c5b339f63840f83755d2e5e063c2fdac6ed23256b8592cc0500ef6182cfc76c3364b0725e3040b96198dfdf0a6a0bfa940e41234e1f3bc8c1cc172785c4ae421b0c572a184a2b219cd2778aebfc6b36d5ab1b8ee3b938e28b500723084e886e36e1de32949b7dd2835ada08301e3bb7b1aeb90928ba5719024d0e2134dee07f4bfc86e938405e32d0ac1d0a3131649ea8b6726f81313a35cc2683398c6219831b4d4b936a1dafaa489b6fe42fecf2df04d5c1e3d9bdbc7e72a58875525e0ad36566b4f5a53940eb75f58f97d1fb91cef2f30ab9da7864acd2a78bc74154e6f2e51405290f86e2462bd0799b21681dec20892cd5f8e45aa334f79485bbb24500fa3628c900bc6cdff987c60a1f1fe834db50cd9d196b3f462ef8534686c1ba0c730753a8d1c7852081875f4fcfa5e2e297daa3de7cb758ecec791411d3d2611051b904c82f8e4c12c2e0fe86390cb058f941849f88f918b32c3285acabda46074b42dfb3b76cf716d8ce596998b0c4324e33c917d29859db15a7a9e2b9f97888f3bc5d424f211aacafc2a2485a196d7b00343569f738b95fad94defb4509ad43c0c2c4e4e269963e5a8cd597374581a6bbb71a9c13ea6a12f8df037ed2a0d826e78245da4875778f9793182322998e2f4135b097fe4eaa4bbb0a1ac4b93b8bd336fc965dff32a187cfcbd4b3aff9bfde1958a87fcb6cc976d968aa7cf3186931c7541e4073e61ded7123b47842767754d624597216419d878d264cb76e9dd393b2d8b030e7ff88fddd053c71e2053ee1188e816cafdfd26cb4e880eac8d7c207881ca7afeb078f1d6446ee1e4f657ea64a38658ee90e8c6ac497d1eac9b9450115d2ddd7c6d946377fda516963ddfd323aaf2f36a556b5fc4508a452c6bf5eaa663e48d69c50cd793bdf20604d06410bacff4c4b5742b5219d57348d4fd8c50328f5fb6c2a002f73eeb486bdf85bf5a880facd79dd5f2ec6a48ab52a03a6d2ad33a57f2678691c8c5c9ca0e27f54c41a698dc958c8763bc574e641e3406c53d3ccabea6c917de33ef4d009e408b9ff5b4cbcec7873806589b4a34a8214d2c3897dfce1d83b5e9b3dce07ebb86bbcddb71679a1aa0c2d399272288e215eedf373ce6c4e7620f8e5571ad46779268207c84ac2f1c2ad5bc8c870191a8e7edce2fe88b3dc50e32fc4840d7eef005bd2e6174807882d8386369306e07181c7abb9c7ea2feeda97100a936b2c5a7b52aff2d18f5ef1dcc581e9a01bad9024cd01c5f5fea6b9671f40516562f45290576b544c81b817d26b2a7b219e1a74554e30c00fc346447f5b0b4b0710bffce546210a798188b58bec2e1af88e2991e8d4ca92f1601da6cef123bf4672f8a3dbe172b278aead6acad7150d0ee7e1bd0b67b733c457092daa91f22229dc9b1387e1a8e3a6d55977367d77f9690b12bcf69d2bd07c3b2a1460c1fef31b6f48455a896ffc4b5e3f40971f7d7ca505978825c48179ce0e09e83a4903649ee459ffd62a1544c7ffd662e24405ad95682dd6ed3f504ab022f268a91261894eac4e7eef1231ad03d5fea03e549cec87842ff2c4bf4aea2632ff8db4a0b7740c5ae2faaa7497963f93da8dd8876d39c0ce56a6396504473c62110cc8d3d619ecfe0238be06f6b2d89645dc26ceb0b4cde363f23291fabfb76a3938784197c3185144877659b88fb61f118eacab84afb12a62b88efb97c37b98ce5752722c79d202b4f771e955d69dcbb245ed38664b6a46d0667c274a112d523ad13f56c87755b761341b805deb3eb055a360f44f93f82791478b94d2831ed8d6502623e7baced099baa5195af74443ea4891adb88892f76b975f2194408958980003e41a64f7fe33601b5a13db05314a6f49ab4160d63ee0701d8357d75f820d0f5d6943bf0b359b872cc103f31f5b118647b4fbeef901fafa3c69ccd2d701d59e1a6b2df23ac7ef4ec16334d4deb40b85af62f5f6e94517b5679c1673203fd165c31a822bc0bd3fd840906f7d7acb799338915dca0821effdc687fcf37ba74a675779c7fe18da83639423e2630c2dbf0cb3b23cc58a64172e4701c9058cb798cd19400a78a69d1024d68a9ee48b7b4df82632dce2e53f72a79940577cdac1688d3eead78bd1b628f5d7e2138e7fe23915494d6f4f603cf42ad58680b46bf57c91f5b5d09d70d692ab28d68698dbd8614e1e8cd42ac6323c7bbf1dea4fc7d66e0f43509b2e348f78b2110f56e70969f1c17675580feb7aa1a667f813d3b0d8a0dcf9411ff0fa2a510cf9f44fb936f32e6336ef6a7a1cfb556708819ffd477d5f09b760337777bc3896f18657a3b4088545935bd81c4948ddcd175a9bc708dca8f189a2f5a82ad5e7e585c1a34922389ce0116d49b3ebd2dc8f2013e8519a105dde3fd14359d820285179ef5dc85a9f38b4ed2e6460b963dbede6c5c859ce661bae2c9894da20093d4192746bc003bcf40ef38ad2510c74cc1bdd254f22393c3a158b5cc94cac80204e62b8225145e481a133898061decc87810a01826c7a4185ed1d764be726de16fd8045012993f8bcacdd281e3713ddfb099483a39c18c8272188ab281f0b3d307ee0a60990f0033865601318abdbec0928eb08fb845a1e4d4a45df9b6779e8e6f3a61658a59095a9a44e967f2c909eb43a74a186cd5825cc8f6c2caa357d0829e0005424d6510ff08da1a1826c7ad5a700b0bd38e270856f927414b1639472a008512f8c49bc93cd51a9677c217dbe14fa71edf3e6d8193e0444b421299d4c132fef1d23dae8756c3964ab76279a8f0d7faa74f5b5e44aeadd69978c41c794e36d36f2b9caa625d01ea852cfd1c470c0578eb240fbc400be1edf41e2a24d3081d98768515e323dc410958a78f67968c84a4d30f49c2d5eccd09a5c6b285da2b94ef6e7052eb3f88bedb2f387afb20ce93240c5fe0aecb4422ee41a85cbc280161db6798a084381c5188df519fc58f3c203084bd70cd3962451f749fb3212f24c639b0ae2facb3963976a906040cbcfa0b6f4e227a25cf177dd4c349b5c7e1c16ffafaced60cb88590a2a026c1ef66bbc21e091fa0bf67046e34009dee66658c0150234fdeb714cc99cf9574d0c987a1a3ce8bef7b07cb99ea616085070171aca45256472e2483d115b971075fb7a09b166ca4e73144b5a642b25cfbf9e63eadb6968ce26fd2ab2ace3f6f025c3975239267a3691d0d836ccc0d23c80d48aefee0477ddddd733745bd74f0a2cb536f3c9c5af5a9520e3d021ed6f0d7774cf688da0cb80fb81c5eddd3aee481dc44b7c1351624e5377110efd02d89dcebe67c830822ce8d41331482adac695d4b4aebc2beff143a216292861fa94582b88d3a159eba3cecc4b0cac90ba0e9e81398c6b946e5de972e426c399477f552456379d284920d61d28503ca58865e679f07421de5b12ff4f3b14afdcace07c10a8533cc359400409218d9e88a844d9a4d96297148cc11e0180010c97fb260ddd66bf8bf1499bbbb9b8e3a2f5f95180cb2922ee0975c30c05d1020b931868ad5044afa0625055480ef8cdda4d286c6f2c77094b27c71dfc5873c602e10200bd836ecab99404bcf88e7ab04ee99b74b6691dcb3abbbf22968e38f51e28c6bfa8494d9490c6fc72c36e508d88eb5a1a56a8d8120f1b8f0b5162670bff268ef6379352cfdbbcd20860a66af7b85958b1c5885ce1e72568db7582fecc12d208738c9ec2166494b0c8d62c03f6f3228c62ed06f3ba59d5f9a0a541b1fa1bcde40e4d117694cd2562d98733149b5c73d8e57060d20a086525339352ea0dde285fc0064e8a67a188b152c53459ef3ec140237dc2fdce9977fae9865d226567d10934fb96eb08c60d8b1b9277418197fa935afc033287d7f9495485fd14773e43d50e208d3318f37ef5a6ae26a9d4d23461a3133c347e5656679681f7847a710ae34009a349f09f7982549ebde5dcf534e1cc77da3a87607a086deab48986bcc88b5e39709f9e5199b7ae86e67b8260a4e0a12766dcdd682f5dc24f11903f2e2631d51fe3a6f3c25541ff2b59012da1ce3650780562a68f8f8fd23f60c980da1404f4bcc5e1e879e5f679f708d45977d0a304288921a77c88f6df2627efccbe7ef67dfb284bb28899c6e0ffadbf1aa765b20adfb1f1d12f4f62aa415541b2211a7c56bc5a83e108e9f3825f60ed017a09eee907c2ad0754780fee2c45f601f8144693b20f0227e7990e12e54e14119a1e4473059146473034311ca859f5725517661724c0560a0aef18aa9ea3d8fe1d14c4beea19f136cb07a59192f2e542469688da5b04eb3063446cf0aa8d91bee4668f97c96b7e75ae1c63faf952062a5e787cbb53e42597c2f9af6463ed0c701488fb9f242e375245877b480901caa47ceb274bf5665af647541ecf8e913c9f98f749c884064b3cac5f0a881c2fdcda0a69c33f415014822db7145f53eeca33e5d91b82a8a39d252f85c4931e6dfebba273f513bb1a82d8c5c26f3b168b1daa20e13b3355b72159877f000c650f4a1843840942e1980461be426d2182cfb8946f18261b428628e9a667dd19ecc0d410d11cbee2f5e2078daf31682b7976d42aebbadfd25b8a77345723574971e8a3a38ea545f07d8b5949e7e3f2fd4f02c64603c6b2b6c0322f0549a52d6e2d9445a12e19635967bd425ea970b43fcaa643da71327441e4719d23c25ea1bafa105fd24b8a983870e3e0cb4a925dc3e6f30b14de6aa3b09dda68bc08aa5ac799d39b0c71b9097ffc17b2612da7f79c57a4170bc99464919f567327fabc6c4bcff103b844d64e173e8086d1f7793accfb4cbd7fb908a77768befbbbf34a7e71b27ef28dff9c05736f72e878a9579cae1bfe5bca937feef5445bcc5fb8d07ca504d2b8f5ae3bf17f01bb20ecb17019e55af02e183ef4a9406429af8ec16cd13d97bb13524272d9898c5d12d72bf0d8e4311da0217418044334e2470dc6f37223044ff3435474a669fb58915f936b2dc163590c9f9b9693ea90451f7cf36f2930d499a5dcf3f0a1196a7f5dacee85a9c217dc80acd3d2c8b9cf1ba6ab217ec52bec086773449ca4c57e08b6200e5a2734845b0ad249f0f98ea891a3ef2ed3e09b8681309bc1ca6c813e0820996338f13387787626e1ecb18769d6c5aca43193ef70aa9a8e5c28c3d4a758914292411cdacddfa89c395c9eecf83165bb186c190927c20745b02b3fc95a068ca39a50731609c48d7df252307d1909965e751d3d1e8fa4fa28edf73fe69d7d9d7567f1bd38c8d1bbb87c3a47d29c9cab7a40f33dc0f93e2d22c14b41e1f5a1f3dabf817518bf24a2d8fc276ff8e1b38a45efe0b3075495bbe016de62890776eea0981a9e8e203650edf1e18b2d710e394ffe06d9944d64fb07fdd49a1eac75e284ad9c1f7df8e8dfaff61d7125501b77759ed2b395bcee915374ef4ca407f40f79ec38e42649874b294c5e57f7ed05f38bf6090eaf41ca30688f666bf291d2bc6c308564768f4d28a0bdfa75ae26dd7f27dbbd817dbd9401080bcde2ecc0aebb63d2b4105b67ba088bb531fdcc3bc173b9de1228cc9c9fbd0d9fe86789c3267b08948d45ddb7ae69e301c9302be5473abb72d7eccbacdab09f800e308f363ee9441189742a08eb511e6f9ece502f3a19625502a2a10831398a43106f45f98d1f0116fc2c227f0e513e7b9c0a4e3fbc8f674864fee3895e487951ccbfcb2b3609936db6bfbb3a1c949804074f5e4bd8f4c3a440e8f0f825e52ea6497b2aa8e3b854c1bd180f795dcc762c93f84912525fa8932c27744d790b62414a4802e4022adb14367a16d57c588035ac5bee11bc1e535c6bc4ebabe7a5630163bc053af99e5559f04181ac1114dd1b42942a22255b95ccf4be609bf802c6ca4225cfa05456d82c227ae93a6191f27946a55dc4dab6c51eb331c0ac7851d83785e086761c34c30eda0fbc15e0a95c31cda48de8db24fb72426f9e96f8b69ec1851c713bd82621e70812e6328118f0cc3e225f09f5f5384f445ba676f82b7febca0d13db1bfc940b41e06da1607647789be106428138484b9335543cdb069dc0f1f381c35868d822056b3cae5592686ad7f512be63af3bd17a0e0693e8615e6b5904df6c3249616714549a613faafa5c000fc985ea76218796858244b2bf086ca7ec667cd26205f3622abbafe14d8a455df089ecfc9d5283b5a537ad4840e651398dc1c802864adf2acc03af2793839bbc4cc0c7af1358181936feee0c075213f3f9377bc60231e987845cc248be07b0e61cc21c1d9f9270af126ba633f1843dd78da745667f80ef84493e2ad30b0f93cb98aae60dc27ae728c5b8dc9f795a2b57e742030c7d054894e4b6e30fa5c11d73352ce2356007332b1ca98acec142b42c16aa96175e445c4c3aa8dcc582d87ec6d8ef9da9df5d34cad3d27a5629d1a90e124a30f53e3731784229f5f0678844376d6a8d60c3206ef7881d0f5002997653d202272dfdff31b2dc0ec33cb687e5d098af85c49dadbfd62fddb4f8d605d7a8778cd1f3457e657e66f14afbba7dd23d3f036d726b613c50b5b0dab372f7dbd4dc202a5e1ec1ff3f988d2116353fd6abf550bdc572f2912cc464c7f6e3057e3f604877028632366d0277657d1fc98ee59d2ef7e0b8eaa8577638e4acd82505b0be2ba03ce5fe770e41090c172c93342913d97c8e7acb3cd6f8e3db71409daa4ca15de4c26c73748f434b2d420a35dc9b9dc3d0f004821a2a97e891de222a17b09fc704e5623cc6f2da821c9e20d68691ae5d7928654059f9e82c6a0cbbe60f4f21ef200166d47459b09ce4d1a0bff42e9496fc61a1fbb4a5918ba2309906d4ec6cc8b7c7918757aa665ba07402ab242c042bb625dd40730b1c7abeeedd9fe95520a1e4f730224e59ddb075a0d23c8219fc9ebcb6744dc45d10593269297c758e72607dd0430a24b6b361d8616e4301c5a010f13196815d0f5103040adbcee38f8f7ff902f7d5cdc0560fa9b0466f48d2c78f382adaff62b045ae4643184c31421a10281cb3f70ad080eb744f94389d0bb6495d5d12a75d38c9a1084c43b6cc52900fb47ae0793e027c3157c68889806454c071c03a7db48f8f875f8f1e693600020cd338ad1750aa8da76e563a2eb3424e4658b7ac70fea9f68f1795ce919be2d2de8d40201d08951f678ca466e9fcd7a8e0ee621c6d6d94d3a4dbd53845651ad4020938d7a58189265678831c03856568ea63d9e1ffba4ee8e22c2d4907f234c6b50529b4746d9dccb4496fc2a96d0aaea26c3c3ef555957eb5ae1f366039999de43932e8b780c488f314840813c12bf9c2490d271d9fa91bddaa964c98bf46b19db5ff66763d3a00df51ce6c9184fef20241e79e5e11d9422adba0a4bc0bbe908bc60a7044f3db8989bd92ee8159c6ff0273ccc9746ce327561a81f80afbfc671dfed3e869a6b74391116038306fd47209a33092c9b6c01d3688e29a3118ae3b098b6d70c474499bf13d98bf5f017fead9a2df0c38e4018d7ea65d083af594f114ca3a93a03d7c85fd8d52b4e188454c951de5eef21dbe3b490fb8502ec54d3ddc85c8903833265ae1b8f3c828a420bb0bf15be5686420604183ec6c5afd8f13d6a54d2887da3c02942077a9bbbcca736df39d68f9897a070eb82305d36544a01c351f923c298109a396720f7f8da5d942c92cbd37484779377fd3cee8f45cbd9bcad3e9bf6ea40e4dee279803693abdf180050b70299bb2d886a0f8c28bcadde824063b82a0a0da7201cd77b314fd5b7cc47e716c43865e9cc79c0cf45a7fa250dbfeca8eb519be256498b20cc58ef586a5d8dcd3968f16c67e15a3ee46287ae3ab868d91e3c9e0e470336c2c17bcc475849e68c6c1de60b01bdc899b453b2a9151edc6aee7789eb466d13d9017dda13cf0a45ac93b9897a99b9084838107e439f62e3842ea7304fe0e16f1dd81be40e617a53ffe8ecc644d6ab1d2a34eaaf0cc6a55a0328f5763fa0c1d9304aa77a120609dcf2d23acd76e7be3ccd52cf717d4ef3c16632f7cf41a82d953d7d30747a12f78e2534f6235b54d1d705aa238d47caa7a95618424c945b374907a869154b86cb80c7c6f7622bdd2743e6c8578199150022fafa9b0307239c893cd8f18fb91037dd9d56538c98a68e93f1ae829e164406c843509aa18701a4a639f1a50f1bc8c324d140ad1a408a68a93a617bb3c8706fcaa07bd3042271da6a1a4c225800f2754107853fe80a99b1f5b527d07be32b30b6a28d8ab5b955b5cb93ad99ced9ba2017485abb545004c0040b3e3b346a5bac82c5b3f374b359be9556d65f7c39d9e9a79ad598eb570edd11d2984d24c72afd93912c2fbeca05e63fb12bf1a54e8c78c3fd177a0a0fb8f6e338f3ad855aea825b794ab98063e358d3a997eafc06fd989020c8d824d42377a9e36be8c37237160608e22560df5ecaebe58a542f6b50613a06b16588c788bcc9dfd00384d06b258ccac9aa4806b257fe93122c2a7635838624966c6e6f94b4d7c477c272c0b6aa6dbe78b924e7e07ecae317ad7feb0fbb354749347484aa33437664ffaa7658ede007d6aa7b3cc78b6893118e8c164e02eb74c2cbd7d2cbafaf923c5e0c2b5b3fce39dc29e1db663f96be56f78761f70115f5a1fe53b5c06d09674dfa9a0a9f05722b759ad4b6b0dd6eae02f67fc068d295ad026569a35ce1e8001de7aff71a6530c489b3605e218cb6e2e633a6fc6c0c5742db6d953876bcc2c17e27dea21ac98f3789c9fc0f49f06a93daaa4a44da8dcbe2fcb35cb1d20b624810ea4a04f3eb026d91e5729eaf55986df23f7db5e8084856efd751c30a18052a725a908e037454e6534dc0a832fc58aff43151caf6edda1ea61a8b9f1888bb742567a88153302575d6ff208e0efc04e34444561459df0db22dd503b1772d518fb11a84adfa8ecee0f00911077e96296a5269d45709f1e10d7634817f99cd506280fafba5c0c130d876e3173dc0524953669c15817e5e6261dc69791e4108c7557891162e5d051311a3d54c397987e6920bc569dae77d0b6043e1cbb64b5391d59ae509eb893c0d68e5dbf230f2108009e182b6e076cf950dc40d5f92e3a79cacdb638d71b1b730c1e3c410cc029ad85b96c9653176294945c72f2a689c18cc15e84e8cedd5e1b8916ef0c793bec1ad52acf144fb35bafbfc843efff85e876e09f7ce42f70c20d3b7bf110420f058cb4afc422b36d42994de0a6e4955735e4d7c18c57123d8fb2113b86ec11bae3ab2cb7432d512f04f9319572bb56a54b4d5101124d91be35f7497cbd90baea6c958f0d852fafe669ab7d4aa0e033676aa0f6808c846d20220095c9f965856b5488bc3c5a7a0f329fed023a3894b2129b36927a4ddc0adc738567427f07b38f832f16a39f8842e8902da790c671fc3ff2a560ebf77c95d71e95dc46f98b27425e209e13cb32ca0d85e825aaf30d73a7d93aaa9ec6f3d727b3d885968b6f7f8e3dd87aaceb58911290e853d94e4c36017a61ddf0ce66dd3f061fbf55c1399e99a0b20704ccaa7d9945b28d53b4c508082b16e7d31c6f926efd12d5ed4107976f72f0c3db10eb867e9b56eefc3d6cd4e90df3fd4fa4c291a0434430ecc9ae58f36f1d6fa5bfb4c2e897a2949a02b78a28208388b7c9b8d3bb7be83bba019de57b014bae06c1aad8de2a6d2451775738873a82d9e802fb9410a43b8873520943d0acec2cdda4e3743ddd65c32b9bf726d22282d09a6bccdd93d23b398814f3480d3647e63997664050834429f38614cc63cf880decb112390ba8277179990954c8cb3e2ecd8e8df0268d0ff6e626c9da315592dabb19628702e53bbef53d85a1dbfc7e4a124f568e2a43b74109d36d4a618f52b27508e76af9501bfe959f9a312c7e7428ec352820c484abdaac8f2f1b0706a702bcd227e6cbf650f61e42a3b099702141c7631ee68c1ea40f4b3911acb8bc272d60c3fe5cff1768397bd0f5a4f629f3d20b30f547a37073a372dfb254253b9b37701ba9314bdb9999a7b74c6b2f2b2df3ea9e7c46b180c02822907116c91a71159c8495d4b9fece324120efcc2e01a316d041726ef8b0a853b2bc2abf455814ad7deb928e48dc33fb58c881b07d2361f9d7a7d239b7b2f363ccbdf6114b08b072e3767887dcb35edb2cab34610c17a2bf62475fbab9213a81a80bfd98a5cb0585bd39197bb8a6cb5f503647c43a6b67afeb4c5c0aea10bfc2eab7004d0eb99859ed89e48d4b7b31963e00384dfdf4544ab23fe78af41a0311179c02fa2c99f6035b04dd5e0f33e9326c8fc810c273dd3df7d66db013457fd4cdc0093a3ec50dc744b9e0f1735fd1b5a8b0acacf84c801078426697c9bffda72e060b10b0aa5a5c13704824feaa892b4d7c85ad308081fe9a8a7848c92af8073b558ecf993554073d8265ffd9bd40ee6c839e0c0b75aef5660845f3c22a4f7626cc5485f0e03291e4705b38005e85081e639ec6d94460b6cfcfb95b53c8db538de3f0677092483210d17a45c416b625f17b7f32b079486e231d26243d8990aa5ad22ba1e8322dd78f331e2b3f2cb690043342e8c5e2ce4e13ec6f336d443ae839035ad5d54e953320e3c633848cd57c7825dedaa6506725f58ab460580e0151970d088b059c077289d6e04e875d1fd9e32acec0d6a251f73cab315ab4af25f711ddddc949dfe73c44ad992e6d13423e76cc963235e568597cb094310e44ac92425500174899111b7810fc1cec6646e1a3b973f241a0f71435284cf9c721c381b3d72c7fffa070a5296203f9a172c66f644b501822de0b531a7f7420459833f2983213ec2491451af56a4e468488e68d665620b1e58dd0176ac146d072cec1841c528f9ca2bdd03cd531a0f0532dae4166965ec1fd6e1702f9e6f53d7fba7ed01f9e11e7c7e38fb7ddfde4b4a8bd4c1d633580b77a9079ebd89fe0ee0f57d22a5929dc7c221807ea895844abd9ac3c319a7bb5c1cdda0c290ece1738f40df37d1da43f44e6d3f386f077f9ce1daf8e479f256bc8aac742a1e11d8ed0e2992a4120e0f52b47bdf6c3ccd8c2df13b9a28cab2bb3b2d6d1cab77b00a69600a28f79d4054e896922dd23e8225e7ca35c5a2aebd702f3e2dde122055f739687d14857d23706c0000cc4970c111001713fa0c868208daa119a500d498ba5a12c06869d8179c49d29251839025c78a072d71c193c44b31f50421198525e0a5dd30474404e88f5ce4c421ee9ce3d8e89d05af6a6307c2776dfb407bd53bc74304ce2716a8425ade5a11d2eed58bde4085260f1a4ac58561338f1dbe4b25f1c24d3e50a1f9727e942bfa29f249967b43450a06e19f2a7b8a5b60aeb8c41b59acbca7975e492b2e307d0747be2c1e42dd7258c4266838700569bca55015ac007aba2faa556b52b89462dad1a7ae04540621c738c01bc0f4b9f06edb0753dd0ddea6d3eb4ce8b2d05d3a89fd6abcbbb13be45ccbe612cf9aa8bef8bcaf7b20cbd976e030309409fb18988b6f9e8e18ad1ca163075327a5369f76f528eb73903b9e73ff7866f1712cdeb71fc281439c27955276105efcfd9e7b55a2ca42a94379749c9406d4bccf21f40bf32469338e3f6ef567f7ec9c6ce1de843d952ae31f38d8dc1717c3cbbb5754d608c422c41feea3becbf7d15fc389ae3d27382d1057edf4e3f35d9d900411dbdb516829c8993e6e2379acfe8bbd2519abceb7c2bb740095123e28c5dfd9f55f799dbb16093650dfc8eed3ffde13f9d5255887c2d06c5ad1b4e13bdeac1eae2bc009b6ddbeac04a065bd7775778374e9054c4c5dfe8c9385f2c90caa8da3cb44a4bf95610436dfc5a71148155f54b0ac0a80857177d9387f23a63f89a66bce8d50725d0b7dfca065885862e2c4228da3bcf3419a9127eca430ca5a92bb1d1a0daea54602372ba854d76240614409dcdc0a6d57575f8f10cdf2f105d5f57415eaeabbdaacd9021e589a40a1968c63ab949cab9575c371b1b1a86aa439ad3e031fca3f3d0e86851b8036ceab22534b8ae209f328cab870bf1e2c15a081d8ce429f6cc31e24e32cd4125cdf2b1095decc49765ccaa322b3407f5b098687ae7a116a94e8f8d2b8c106b22de831c085597c7baf73df7f130bdde29d80a76c703c3a8a086aeb3b68167e887d9966bff8292f680cf11b913c1033f0fde7f226cd3917320b54c04ae645ac0707e8417c6f6f060294d18f38166beb3c8ae292a2abecc03c454116ace44d715c5cb22e338f5717c8bf2dc58d4aed098c45b933695e57802594470d6165613835dc00d165410095277b002eb6a09de43d3f6fabbfbe8f945545176f69d4513a31a461056a71eea216668492e7a74296320b74f862d9c11a77250dc75898c12240a57d4a1fbfa0768cc1597416fb46076e7fa32b5bf0f64261f1a70ef768e133908c1bddced52f5d4841af0a1801ddb5231a3640faebd355c93ec19f9a390c66080e29a3c12f78ec683bd14fe2ac942190f1031c2b29b4155522392da43e0128cdb5e87763ac468dfaf1ba61d76de42a8103f56d5607bde916658f948439bf06923047579936c488b19358a4c41e34b31a7439715c0805996dc7fe6b853129ea79ff8dd0144a526516ecb8a500ea59143e06d7cfcc479f7d4cac4b6038edad8fee233a3be2b73c744f3418d07f9b6f2d2d58cc6681c93eb5ce98406dfb6037afee951c28a0dd7f0bb6e32ce5a7007e4b0db8db373c7d7d77c1f9d7310edb6d58bbb16f10edbfccd685a2fd95c4e74a2c7527e8f82fc2960c3033bf00c5acd23b5141261ac85a7e44278be3d7c9ab6ca444640c814a0ad6177211a2b6c37bf1584a7343b83b57bc1b023169fdd303f39e192624e29df858892c7bbe002774465fc29da39c7fef93a12031e289c96dba9b93e7d1e564dfb6102a5bb5463e48dc2ff6d3356fcf0432a85cece7dff004a398c8bdda64484010f28943538cca2f5d9f811bde42cee45cdec9f272043a9b0a1682d8209595ce5a98d1b1f17309d9fad19951fcc81edd15406b2b87e84279e0dbe0c872ea1e07e7c0c31dcf387ebc29077ebcc6f05182e8e3eca51a29471960f4857bfbec70d1bdbfee797d16b07fa9d6d8e70fe0f118a1f0a51f20acd2447a12f2866d237fbd31aeb75f4e05c009b57cb1e1476e347afc5341afce4a705c17b2bb4b6328351d68995115441c8a5e1c0c0772baf46f87dd5209944955d02b9347bd0ae434b58354a3180983858c89b49e213d380457c8f9c611ca32a983245917b0a9b158c5c57b2a697a47edd029d4cd3aa05738c479f13e0a5c9e97f1c05a13f1c990071f0c58d4ee73ae3bef2e1343395a16a8d5b6993b45cbe212fdc90829ec2022eb93c06627b4ade694c24d2ba4d085d075868e05522fb530e6bb5561aebb0f2d8e84d6c1e206f4bfd68615611e15f90a3e4c68f3a60640aa442f1a89f453ad1fb005d19bff46a79c3f2b8231b4579b30dc6703156e882b0fb86bb41135caaffec044b19810c5faf76f88a2dc8d73009829e297094c1f8d08afef265cf8967e6d5a44c532221251ac85d25c1187d40a4de42cc256c7b33bb7dc505c0e578ce587782d919e20343f6ee3c1a82fd76706691556dfb22dbb0615d33df48509cc178394d5ab7078de425e72a7880c7856c8b38f9cad67fc66906afdc5e1ccd8bd157c024812022494a5d4409262a755c86b0ce2ae00f1689037dfc6f18ca2bcb88ad513ad16c9589e6095ae04465c7682c94fb31c29a97bf76364414412d572201ef4ed06d5107298ff8216c675a7a49d354bbe5187a715fe6aa97ccba447fe3e701acfddafb4d857e9eeb3376928c85008aa4e3f94f3b47839809d3084965882136aaf9bbf255f5d1655043ca0aef9712d66e14b96ed20bd584f824b56a0d8c1cae776cc6dc7143c6ab08b799d790ba70d72b140d448898cd1470d174cf19d5a358f71668556b2cc9d035af254bc76601f4640cc5ce6dbf46d055a275bc1d8e142d060cb01bb604fb53336f9048dfd07e068a9b284b4dbf99703be45bc5843b01493b5f6b5becd40f8dd1d01e62563007289cbf1e360eb6dd5759796315636c80f01f260cb75840df205d4aafc610433302b8c9f68193e6ea0961788479cc9fc0ae4544265ff9b97ef6343b7f6c475d25a50ff3ab88dcab5f341757525aaecd819ff904b1ede909e1ea5e5171f082ac1232dab15b951d76f2437fec22bde938a7ff87c6dd5283570833369afd23ac1db2d9fb82854a3b39d68249ad31a3187959b38b00d9aea99f2f7ed72f156b250e983f20bfa3099f0d8ea02859fd9a2324c7a900b4bf8882c399c1bff97c62c0ae8732c9f50df07f3f85ff3b6437b772e6f53e463f59f4ead2a4b96ae9d9bcd7f26c0a69146ea60677caf4bec3787b333221ab0ff2b1ebc42ecea9cf81093e82ed8e533993af694b6d1268619a6cbbdc9a606aece542d62967a3cb2d2a368f5167ddf891228140d5578dd34483226df780742a5316df9ac5a1af7616e6b76725872a42c58466d903e5a574cd9677ea1c55676a2ff73e56ed30b394e351701cf2bfc8cfd6871da43712dd03545cadc66177a946a2d329e57f819fbd1e2b4873095cf1437f448e83839345369ab25c565ca8d5f91f2e0634a5adde8285245e81a0a8b83e5233390c20eb9cb46db35e0265ab70052147a79be0381c32d91a004c8de615dd8cf07e53a9c3ae21886a4b858ad7f9fb78d1a1ffd5d7e3dda093da19fbaebede4e5f48f3d2a8ee4a4dc6b7d404adec7f8d3e0d516628f11c320317aa3725028ea00119b90404761df91de2bfe3291756878142388c00f5395900cdf2485dec01a4c264ba0286edd536adfc872f8b54176d3e8161b32318f3cfc59ec5947840b85b32f4fe82e48da888642e223004b885863178a58f08450f51117245ee3ea658a0f9cda872451c4195af464172d0dd1bffec52afd588852d64c76d5ec26b08b88c21d3d404d01d584bf31d29f9bc4892904d23300768b7a575b689598b09415e9a1a723deee58d9a8627d4a29e939e25d3c1d5adf6611e79ba0fca487e8c17bdab66c7bfddd6cfab951ea5f78d08122108fa888730c597ae0a9fabeacd79f69931625bd18c5b7a71bd343de7d926f241e990202afc1141c3596e0c4a4021078ab716b9e12c762245a391cdd0950d8c0e7d4a3a49a5da313da8b1857931a9f4d73b38c1f32fa6a7a921946878bb0cdfd82df33ada9cdcbd690cce6eed2b08391bb4a118dc3ca89dcda5429185a452fb49565a154aa434d68afacbc89730cd43afdf93db2b43dd2757b8bfe3d9f01bbfd9d251dac0bb01c9709ac465b39302d70bc49fb801581213011078b347cb2dc8e1fdc82974648085181896e55688ec36546e179e7667ec455cf6fcfa0ba3ac97b1ecec15fa238f8e8fc733093b8792bcd6d1bcb024001419d3be8cf6da03a9c7d4f73f2555d2abf314c571c15f0420d4830caf4e2c2b165fbb8923781cc74e043d532c9329df993ebad4656025af4b074581b6c5a8d1418c9b832ec9e7102fc1afe95e47f5ef01b3d511314400d36ee342a2c0455d27fd8aa68b6bfa48ab84c4840a2ade6523e37e864f5e90f95429d1a3ff8723fd8a4e23dcd6a6cbc010a4739495a30cca4d51caa98a245777792e2cdbf54122a5c2f38acbe19def5e2ffa64c7433cf9589207f0ca5053334811862462c53c3ed741dcfd75907a6290ca2406a41953422f6024e36a0b6e1a49350dd8cda99247a695323a1255b4a199d049d0402042d8bb3f646b1aaebd704cb7541e5ca806a4d2cb57346ee8d2177a8c2c40f8b8a9cab2a2d12bb964b89db04e7fe503be1acc52ab633babeb04aa0727b40b9654b3f38f634facdb1e7908f143e2d5b8a9d2e2cbf235260d0fd20817b73e1d47a6b86e2478765dace711c4714637d7c72e7dc65e830f8e0442f88883a3c53c693e65efe58a6e697af6f48106817474eaf0574d98814d0db5a51e7c7c49ba0332277c22c45d4ce1db933a5c57c3ab7387860f61c0f6179225f7c2fbe0b5e7c17bc684da66d99dcdf279147fd32be9c637fd9a599f758965c2537af7cd79a9144cb1a334dd70e3149ecf867cd51db96c94349b28c7e9dd1b526dd3a8f646f944a73cc9360f767523df5de19d4bec777ebb1300e10c81acc7850fb2e62d077ddcc1ef71e32eb7bc503f6de7beffd7b1b1aebf08cd750dce1bcd56e0d697578c625626dcc902ffb8a85e9391e623114ecf09f993c773992e4eb51eb53bf9b2d9f65f57b72614ccc8c18234927cea020171a610ae18c28ef7cc8a0399f3188884f5059d05650c8c61aa579753131533f6b100c136a908b12691009b44dc2c2796b896da9b05241d30c369928834441a41bb3be3b12733e663bbcb5e7f827a937a2d7731c34a58360a03dc7412e82888274d6bb322e0ea699c138c8e3a054d771b089e7d2731c2442833ae69594d7730c74a7f61c03cd75a0b40d64a6a628efec8d4275388cc440421f23147a8e81b45cba1f1e2901a0e1e99cc6953b4b72dc5b1c3cc812d2e64197c53b63b14e10b74e8efdd15390753897b9572cef39fe012b23dd272c9ccb3c5c202651d5d19ee39facdeeb39fe99d1e199b10e83d096d09c081626bfda7987c96f8e81843dc74038805ac440443dc7403a1d3eadf41cff2ce93dc73f713ded39fe11c20172470369de4f011696897bee7c324bfa866362348a0e9f3a52dd3349a4a323826dd1f39378eaf90d91b70c01e29e2a29b2e7b8476881aded3ef97193b848dcb91aa22215763086482a4ca21b1fb3620915646e432a26896f5192e407b554d7dcb89704ac183bf2e2c66d163d194a12221a0ce206c337bd1483488548455c71800a44c4060c8b44751d2e6098b34419a2b394312baa488328274a8e141286439aaaccac10b186cca1b02466c49621cf9c9c3ec3419423ea280b86d90b0148a80c11d9b88a765c693a39416431664449eb32858a7044010c0130d4535cc41fbac561f94cfb107315228d1fe21df13734c030ff100b427c71716680cc2b4cc6125d9190247046b27cf8c0d1197b3283c24a1812ef8899c9513bd43984c45c2403c976fa8436c1e534858add9118475ea88aa210f9f8fcc8c203c40c86652266942b6d3b6de411b62e2b0518ea2079ce89588358a7414eeb0d5b1033189a55d16499c70d8d166844a51b42c2b220808699550edc5693d351e7265018059a215b9812a2661ab32232601897df70881a8a989ec1eb7a726726264493b222a69beb41474544ec6161fec41760360c77606527e3108888441c720e9b8831c31e64c47c45cb509b73537234a5032987d2508ea52d126b503bcc13714e09a2ce0e43429441e40d7510350cbfaa885a0a18516698544464b2467c2ab985a11249b2eca8413e39df21e262fa8c43b84fe7614df21134a24b053701f05a7e88dd75fadaacebfafb39b067fbecfdc21f36dab7fede5ad39275cb9ffc0605fad7bdfef6d11be014c0bbc5b671d969daf37c13adec6ba3be0bdf3f7ac3faa6b6f0dac20befae065f2ebc30abf5eba2becbc31f7c21b8982f8ccb7e614d43a1c2de3ddbc7e4bc5cbfa5e5d7b5e6027ff50210d6eb57780b2ffacb5fb799ae35b0465711d4dfeb4b81b7764839d005b881aa00563f4c93f6adb74fcdfe962f81fa4d60f92c307d0ee3463f25d5b2e4ebbabe7ad52dbafc73d4e07b7bbfbe6e73be797e4ffd5eef85e1a93434e3faee1fbdc1fcf0c197feb9bef0739af149985d5ff8838ffffe315ffd344ddf5c3ba4419a0d38499a65159ca4b983906a0ab0f039e3aec3e707d2dcf567b15a935da5eb20782781c2dab2d5493057ddd5b1af24985dff08baad93a0f6b28611344e07e180ae49ad5fefa934ef4c4743c3adb4321b8d1ccf0a1e8fd20b8d1c4f108d5c142c26148d9c1a5ce79c46eee4b13dc751773c1d4b7a8eec44b5f194e4b8b7387810d5a315127738975545e9207d3dc7513146b7360f659cf397430bc443548a210f1728ab8087b2289f320f17104e692bb9844e48a04222433c6199cfa9c59a3dc742b10ee72d618e20e1539010a94768b423443142f8c3232ca1c3fb9e63a82450695e234c055214a09fbefa6bf6ed9a9c31e83f63627817c4c46c9f6f678039fff2e10f6a379ff52961f99b6f636e760c4b3391b9add3773c438a04be1ec2a7ff46eb11e872db06389035f030be23a9a46d0320f0e2d0810f3b836f032fd819c8ae37f0f51c3bbdf5b1e7d889adc3be6e234887657e46c85c212fb704d695a95f91182390da2015634e3f434e3b2d132b2e929d2b9624881b4eda2fae870e583b350cabfadd4141510a5bd1fe680aba5d4d3c27b03c4171b996b441b816c51035b31f93d805d29262e5240a8ce997c5a88d21d4c644e2878409a76592e21669e2f6c8fd8810699dce5c1d623f351d5870fcd0487222e1a2b542d4d65832e19a2d99e0c238c1089dd4912845720069798cb53b5dae89abba1a654f3fba17ad8b143d4a27dc24259dd6a74a2b57f74343e2b66873b7d07878d47db556592d19159a0cd72a69a7482909282a6944abe48a4bbc738d94fca6bc9d091152d67e85b96b4477848db688f06ec91dc2420752d00ea49ed62d4b2b14e58889cb1487a3f6bbe2c37ddbe106d96ae31b25ccf845696aa15ab86743bfb61725805e9480634adbc249fb6644b8e6aaf8e1d228fea070b568395a2229d70d86d7d12f0d851b3cf2097294d3a651c979a234d784cd250bd20e91b543bc7e52b0dc19536e5a8c9f1dd24f898a1d2e7ec65cecb45981b2738b92b83a6e3f21693fb61e6d1c584b1cba2faa7e49a08e94d8563405795af0b4439687a515b23c285a4be88ce07218a9b54e8ccea88c8a6e9051970f160b2a13a0502cc9302a0e21199930c128a7cdaae264b74289fb0427a54675e68215537411c1aa42d5aa41d92dfd9618b54b86da221626dc2916396e8d2a6dd1ee85922c38156aae8db3f644b12dd16505cb07d5ef042897c8d211a31e43ed931526da292b7272aafcaad8b93c94b42be05a1a6a6e67bfb5e28f4a57162c2caa360a0ac8921bc3c82531f41b526442ac28a75daa6264e7e250b206f77ba2162f6cbed869d288b5a6c45a745ae31e3bcf3206b9c32d1e10bd3206b99be490ada0e710744d9a65046e74055d6b2922d6dfd87bff8d103bc456fbabbd3f8ae53132e697a4a94d93b763649c278fc7db33573b58b2a50d3a1c9ff44b64572a8255bd58245969376c7cf51467957550a5fbc9d3cfd3e887d8308c2ed70e687efd31585e7ede6798fcfcd1fc254c7e4398d279e8cbfb0f3e18f47d14f853e8e737ff83dacfb2e43c13067d43283bfae8ab6e19defbd27499120bfb7af9b04c2f358e2cbda5bd7afa69fc527de10b780a28cb6779aaaaaaaaaaaacfd55c3ef93d34ab2d5fbe3e81320798012a806603b2c333b1b04c2f5720ef334d2f5fbaca398abe323ccd634a74a739ef17ce362479e6d089731075def39ebf5e432831c0e6f8aa88c7ea0d23e89e9eea59ea0cef5bb136fccb0ff8979fd797c19e23cad3269b3598ec3e41b8e965ca5379c0b2b32e39c3b9c2f0def3e49feef583bc2502e75c04fee70b932609bbf311f828027f7596313f28bb1e37d9033162305fbd7678192c597e5acb38ea37cb711ccdcf401022faf824f91ee41f7f670ef9b5199f835cbe7e196cdea699df53cfccbc90dd2406a43efbae4b3390e4b837640de49f3a67d0652647f2dd407263896fb4e839bee1135b158971e0c437dacae21b5bf10de16b02d6489ab70d9caa293d3d3fbfe4aeaaaafe55457f4c4b933bb1e3c7bcb0e837b1e4c7c870185710b25e3dd020e40e33be4d4a6ebd7bfcd35293bbc7e3aaaa98860fd558275f7d894962cf379ff7e45ac3b7de3df453bd76a03b274f1358cec4e9ce3096655996cfcbe7af350fb629df112e4d8be80cfa9327089d6585a9e13d4fbff93a040f9881e4e7b5348b6a9cfa769eb9f72910f6ad23b007acc9bd3701f27b2f9cbe7ed3fcdebb0251557f7ad379c00fbe7e8e40127893ea4dc5c24aa4c6952de9ee51d53858abec6f5455e3760694ec80921bc83e00f6bbeee7a87ebe9feb5f8136165e44dfb9c2debac2fa6f7a037f0def0bbf5f78770b7fe18577efc5754da197f2adf7defcb5e9bd85df288aaa741d36d1fd22ba46471455dbf406f45775cee42389aa6fa81ad7cde7fce57c1cf938f2de6b8352e09ceb6de155dfd00df3f2e6f3117db50d5d5738c456e33a7fb665adb1b07ecf0210d6dce5c238ea5d01dfe8bad6c0ba5730c6ea1bbff0c2ec079f8577f7a82b9106ee17e0ae1ab3893e5f6bf6b36f9a5f01a83e8771a74f0108fbfa389a2da96ed15aafafcdf9e8b7bce9f151f5f7f77e6ff55d7bdf5bd196e71ad8f2c2f0defc95a82cb394faa637a0d94ab6026f9fbebefccd5739da7bcb57d757553f8fe6ef1e558ddb52bb6aab6f635b05754c524f35e2fa4ccf718daa2e55d40dd0734cc327ababfdc2ef8fa974e2a9b178aa455ce32e9e12e6d534cdf28136db4c4db334cbcdbf0cb1e1b307fc3f6bd0e3970f1e732e54e2cd7572a1f1e291c757da439f497b2976c9a21aadce218955f238c1855735fd58824446634a054cd4ac8694d8ccaa28e999e958c7f0a6a6183bac0ca57561155fa4a042b723ab4a6b68cd548a9c57648e9ca91cbf4ca026b191aeaca7b5237d8428ad2c89458e5a4bd9076e04dd9ec4a68a5f79adea4d8a8fab3b212051bc4759e2449dc822369ade7abc60aa235a803463ab8813ae1c2f8a3a3c387f393fcd93ebd429cf789f50a5d4a8d5641cfbcae0abe8c3c9c2c0c488611a8995a7a0135a4942d46eb270aec08dbd610589b51d91347195e476b5e655c716c6226b0995af172306608e11f9598243e182c7d556961b512cbe60e165e4c6a34cd536e2b129e8192f51a56696689ddb884dac7ee83891c5e7890a39a4bbe016db9262d558346b293611e9d06aa030a363c126032bed8516892cbb18c5c57609843b3e842aceacd048e83041edeb4456115c5b9a4fd02d42534d5e486f32620463212b1c764b9c88647001d811a6c592f6d2198b2d593a3ac12596839382a43a262f82245db9e045bc3026e3de392dc6d2a2c9158a232b3596e08aa676b4b9e18cd57831c16252588ec5187fbe9c8c6257b8970813b870a09a846b6556544861eba993d3515cbbc238605bbb6212a6e3d695721dfdfc3832f37133b9d0aab48cb4883049baf19286a4e8899914a21131af37755c581145c44c861494222513a633174c364c9850445ab7c0389998d4a8e5c31c4d720e03543c41e69446e004794d59d6c6d68064e15154d223ea201d613684a4866cc14941eca0ea5ec0e82ab6a5da498fbd28f5d10a21a3861457a0a8823198d024c0d404ad8450180baacec5accc219cd5500a214674f08c2511b6a12d4d3951452ca873b212594c4a2eb6459a58613c9f244bb2be9792730998a1d9886b22c3eae80443537471d55a89afb1a073aa3ce1558a8b43efd2af2529c198c99f3d70a51c4f2067d0b6de926487cd715c96e378abe73fa1f4ab12e0d90c8bc17e58a12ffc8186039283ec8623e80995132d90da8a50c938130a5a9de93c608ca1fa38c6547d1cadfa388e5f8487a5750b3dc7718a38b893e687ff6376d894becf4de4fb08929460f8d822c8c0b4f145058512262b310f381cb32ab3f530518242d20587646c2cf717988f4e925315287c9d606489c556929ea4243d37c6a0049b940006838432a9c08c54302095830724598e64954eba743206f3e92459b7d27c1189bfe4d6bde5c5c36b2b8dfb1af34a1bcd0b7c536724694eddc0b05a11c40e4812d10eafe18d8a9f1e3dc05cf800aa32f61c7b5d85d1c43431e91bc9feab2c3170c36e2e0dc8db96db8dd30f2b4225a41c4e4fb87a502e2117b3c6859e632f26afa2343f5c7e9185e17fd3790bcc07fccfe7e78ba0c39953980ef6d96b40e82c79ab1983e6baeb16f41c77057b4dee361f78af08f89f6387935c3b9cfccdec96d1a9091c41670c66c660fe94aebbeeb18eb99e3b7f9897fc2d5f72eda59a31942610bee13a4b2fa19bbf71c86e9a59c3ee2630670c67d690bb79660ce60bd3df0e768729cbb783b167df0d4f9b4634343f769e3434d23fb7b9b7cd56cb2f965b6cde0fc69a9f35980f4204fbe2b3206b389ffc5fd6c09f243fe520b4f90ee830fc73b7319f9b9fb3f4bc924fb1565b4c4c924b53aa8f7c0c903ea804ec985152e6cce000800023170000200c08884402490ea42098d2f10114800760b03e523e24100d26713018c43008c0300cc3000002300000310804311045b58e744439ce242a0f25dcc619fce67614d8af9f282bf67c298af78d73d8040a34ab35d6f8027b64510a9bae985fa405052815ec44fe6a8f7f00785b06943bd048a2c2a32f6f202cbbb55e8f46eba6695c0613f87b4a529796667f9063b10378ee931a5c5241fd26e9632e82a89ab8f9fbbf2bf83e0a88c70df2c41781b74e1c30c16d540de8d053a657d9b8522f4d7e7519ae30dcdd15fe45b740772ad54bcd019e4f32db41f78a33270ac4d38e00a9f069fc5b75f0f49d21de71191dd8b4a76fdaa4ff3486999a3f21314d0b233482cfbd1e9310a4409d67cbad64e158c7876688fef863dfe26d5e63636b56f3f32d20120f5a55e4f6dc48560d2acfdc818da736886b21d604c27f7b9a8bcefb235986b302c75ddf2d441b04c0c0b99ebf0967748fda8247d0f2bcd1e4262d7274e9c98a548ec6cc2c3ae706ab723f5424e6a6cad30d2d95c16e9db4005b2c58f1db41b61cb25b87675dcd6ab80329d2bdc5f15843494a054abb76104210155483e3c3946b31138a9227eb0b0de437ed6f3c24777ea32dccccadb5a6f6ebb53a8bc473c9ab433e475a2a829f06c2dad1dae6e101009907f15c4138fd0da53243badc24361b168ac9a94eacb972ef849c469aa32a0fd28704a3d053b9e214094061507178fa3b550d89411fb8633f21cf71cb5ab37874138d23a217d37736708c1a341b28ea59e85437168fabf7278ac4dc0cb5510cb6954f2adf796dad9ee1deb786c74d92733cb8a84bab5581ff9202df0754694f2be18708667190c03dc7d8c2f3696b30e4cec5ed590ec962e09ea5f3f812d240e3786f589b3ccddcf3ac8033332a1d647a0964dcfb1aaaa947d72b247dbda3fc6bfa291e50290e9efc334836becada35c6a4113e36d6ad57f8c68ea1f2905410968e98e917ed5cb8c297f7781a7b5de29a5a4560ae7f7c24733987e51823a82fa471c1575f2ae9c76a0b54fafc3fc0a26529db006e3fe978966dd8af4731c1431fc518e8eca3532ffe96f803b03f0b0fbd9d1c91bdba2f7f4cd3344987644b5e3d8e0e4fa07c65661ad9d8d926816e7889ef8ffb8bb7b1e71051fe8f8cbc25606fe519632c6542f2768cfa1bf71f6b5e127679ee846068ca3fed3e148704c5ffd6fd014b68b9876e7ff3a1b412d89101c82879c7e4a3d162e7b6c0e0e29d6a3718c849e1a2729d0799b05078bc3854e369520849f543774b09c69852b524f79c40c2ca2d1d749fce8945827cf67a60894c54acb9fdd82212958ae41d8ab37244a874b4df152ab52de08cd0cf5f73ca3a9f833c0ee42ae87ff035c2132307eab3f298fa36f5d865aa8a9b598daf75135fb589f5442b3e172a0fcacaf379155051819b0f225b4f90e37b133afbddd853a8cad3a9014d600204dc6d12bf56a3924a163ef4c3328561da0d33de20badc9efc09c6579f25fb946529cce808581ef6eb33682631bcc0e9b938095036f6ae8cb0ac0dddb19cd47b916e3ff218b7d6ec162b026874d69184ebc1762426b1ef33c0e80235ff2447819e0a72cb14d0382cc006dbbaaab85f7a0bb29698c9a4805f894a9e1a81767ec7b39491666f62db4f6cc4527df4cdf037309c70cf54b074d5a56f3439bd05aad23cdd684b2b1294589592a3f4852b6b28238c6f828514da99d9a889845ecfe8623a013b0567445a036c05ca0051bfb7aa27502132325d61bba92f39e626867ad5919f062c7ba6848017080d176dd130b77686a8a9a1e4a4c592d70d391389598f929b94b91fc37b2438211c03eaf51b86ffccacc5c894cb77d4ed27beb1a953f878bee5fc0f1b3fd60f1f33ca7179cc324acda1896154e78219c5c3de4cd055b89fc6f0047ef5ed6c4a986836e0fe90738e1862c08b3090c954a5258c550af525e5d826c859ec05b32d9551529087fcb6c653ee10da944fd8503a9eb2c87d30369bd117618d4de429fd61f8800947e2c01b7cc30d028ade122fb80d9898e856b80f6ef00f371ddcfa9ef676d459d6a0267b742b547c9daad51a14e4b851cda39d2e97d466a956be3d4bc0e3c1aab11ff718fb7026cee44088477a49d06d2b5c231d5619a922a040e1fe1a5f15e0caff85618d62b9828433f068ceb0203f443ae5d76d5ac5544cad4eb85ddcea922325839332ed6b560126e5c71b9940f5d6119d828c32001563946da069efcce414e4eabc8be4bd2eeb0e2693631c33a07098a00dd160479e9718d11accb47495f3339338dab8841d4fab155a5f90e3c4c8238da06eaad2e75b1bd424562630c144abb506d1dd2e4454a08f8f57cf2eedb0166e3a0fd48fac7a3ab1dd21a394c42a593de191a2f7fe36ce7a2fa5423525f126d5e697bd71fda4e95d0a57c8c4f5b7ed9d5edb1303d2483d4cb8146dcd9b3dc00248bbd45b208a0237f001243ff541dc35f9cbff45ab7f4adcf4804ab2eda037ed09bfffbb6e18ad74e3c45d136e60d0649361a692eee619b5e8973f40866072f8f5798a68da7df833eb0cfb3dd704ada48f4077ae4ce6dd54d93c483b041fad6986ee87014665c3a2ac5fa5b69e908944c52cff82a2bce691e8b646e8449af3cc60b46bb6c25a6bbcbdbfe141f89eecc11df6525a1f7a392bae3bc0a8cd8f7644df9e6946f568360213b18886d08c10a09d91c2168d31289f0ea72a47051b12ef422516fa488876985acc184cd24d3428781e500344687177ad1b0533238279f681fda9f6f75db7eab7ba98fd1353ed02c892eb9062dec00f9bcf2f8acf02f4223b388d41f27807ec605a0809f0f564d2ed9795eedd238095293066512dd3af40c4c3021e61863afc9d7ccb462ebe69c60d1a37a8b54a818c54a0937cdbb8b6ba465e048010efbb1eced4fe7e4f6828630c9e8dd08f34104396c2932c1ea20ad32b855d681e3e030625dd93cca625605025deab9395c50518bb8d46948b5bd8c4b7170b559cf759ebe6e46c67295c29feff2d4baaf380798a523c2e2661798fb4fd05744da30153e3b899b2a9d18c5b15cde0864fc698b1f1aba7d79ff90ceebf802fafece500f56d368f74f0ccd06728b368007480f836371367b1ab5b779426d52f51b97078c4d0b28310917dc49697129c33d7ca2e1a188632db1088aa52f15f64c036e0fce7f708b8759afd2b67d7d33400c943dbb818f01a3895061bd21053208716aa135a25ab420f5b32d7d07554373d33a3902c2d1934a3f7533057fd8432a926d004db475c66263258fcdd971e18f442ae494cfa127a119ed129a7b951dd47c544e6ce12a9a2b8457991a5d12a353aabfb7015a3ce89dc988e11134f9984c06e569109a60c4f6dc486ecb9d9a80073439baa508f9eae69c16d7356c9a30c909f7871b967e963f5ca838159a797c6472fd0ded43311e04ce337f638c210b686514f10e14cda61f41379458d0280b255cee443b4ca9f64f8237afed5483e2ac40b8494787e1436a10036c86bbfb4d559415b2164c8c3d92a634f48315fa56374135b6fc847ae0278c73c5acf58b328e04603894994c79a0c0f69540f151671e27f910b1977f7c97f3f4ad8a73e17249d40d9407aae41634d2714259244811726881cbc827e409503915979eba3244a4cb1d8aad35b2c9e7b5fcfe77ffba767048b3d4ac84ff842831ea7bdb01e29509ac87d487f663502c4e0461d05bae669718921eb1c849020fba970c250cd48a4208f4d611bd74253e2c4be2cef9741a221d74e280f1d01df5bc887ca9164382dc8604b59afcb752ac3d9b3af69162e53419b42706ab9a7c13c43c9a7d907e06a8050eb5be82f0d94748b711091828f4814bf97e6543624b6cbfa9723736d2a1b521958a9b6d990540d9c1f7d8d3024482165ebe05572aabf7c37890a5bbf0921b15c151844b264f374558d3c88310b20197a3c57e303a116a4b61501025552293659058b4620cd7833a7238517eca5fa7be6047446b6fa20023a4f8c3fc4adaf7816b6fb1c6473cd8f3f865a27f4f19151e1380833013a7ef148e128ef68ae2ffb8a8781b5b75dfd36aa15c311a6446db2331a0bf31186275409196eedb3c180edfaa60be6a1634cba7766309959d12fdd1ab9b61b4c0a5e9347d2d14ab8fa2b27ca5b1a35a93738822a09bbd33f2a2e0e8925469a60e97b2178bc3ed35cb47f2b89b2e0f3fe951dc34873a6fbe8163f5efc918147db11936cd4c8a75056eb0a41e350a838eb21f60bee0c38c3cded37f5cbc6e259a0c711c937d787ef26cf204824e35da7a2396b7c5d01c0524a99a705ab98f3cc524b6e342504b490833942e6adbe77e284a651c2be31748513c6767d561d65a2be837b3a0adb245c915f9ed2a94a0ef2dc8ee37855624156239bb98c42ec302a8874fb1c139c8f09a5ed543011696e37702c0d744dec5731709a1446f58cba82b83c17f471b1c7e104c37ea0b7dff70d16264c6db941eb868c9ba50b30e6d53d7b21101d8212fff7b9d044350f647f32eff974c9d47ab2c27092b2ba29d8a606f03b3085f01504a102d88073325b0a175c70d7360611d476e0137530bb00f962a88dee768cf864ea6fbced97996d77c6e215fa585c2d4827d7d1a763be6171168d8022412cb777cf67d8bb2d31b7789ccf51809b28ce6ca955d0ced822d91ea9cf299275c367239d86ec084c95358261254119e82eb92da0a83754f10c95cf23df5a0f3f550876d97163d72423f9a223fe3ce17e2a057c5ccf78fbdb6ae3069b017c68be5b419cd16cdf4d1cd2f117555067709b346d8894fe68cb864cb68e303ec84d912bee272b09f2d3eb308f01c1a1b7de9a986b1cbc554d195cf57847386de76f5152b03fce55e41a93d1036b8dca014b79dd69c08f56ddbe7f1d9dce716bbe6662ded2af437147db5d250acdaf2f5dff074cfaf6d009641ca5bd0ba94f92cf916d4380ec2e3de787181b64bcfc8bfcb1697817e7383a3c417e95771668ae0057360dc177f5ab0abf79a8670d6f6381f4904b57ffc114b9927eb4db77a0285944d443cdc317969ad8b4ddd48e5e325e45d3d7868963c396acec7d0ca44a4dbfd4e9ebf568f1efb2e289648b62a2d508a91d5d1bb9b2bd4eab54d60ba1af3d9228419922fbdff3338634d1e46f09443e98a0e6f9875edfe7000b9c9a3c6a07b0c1c80d5df78caf54af8d49bca8188604d7bc13a2495628d434934b93ee5c355414880b7fa79ab540e2d1ab0dca2d37fe2e1474961014927b34e1965c257f1eee97f05ff199e8860bc4dfd6d804cca02e466b777e5fa0a8d02348b00764db6f9cd389494e21bdc132380aded1d1d39ed040c9fe7eb10787db543616f48075f2a2f32e801e08a974ebf73d019aa53b63388543d07764980b67232aab012f7dfd01b11024d572607fd7667a0742f4db4e024a2d3add1b4f900401e4cb093ec4c6f5114820c0132285fe2759eafdc030dca5ddee81cd5b5fd7f84ad568d5f4db1c1743c5f2f29436ebb1d120005ee712bf6219f11741dcbe4db21288791708a45a615b32ee96eff5b5907b708dadb56dea873827de83b5300ef6c9301b1a44459a037dd3757d4b87bc247490a9c4dceca23348ac9c5a33da2ab3cf2753da351cc22f20d01ee5fa0aeaee4473075481a6a16df3964bdd29e27e488fe44a437fad51216032e948248b4ca2f6fb23bb6ce9fbb469f383088c17d609298970fa3ee7afee91b2f6a7e1885ef4168fe13ea847e18e875d236c246d1a6a92c390edc7a1ab02bec37c4c3015dc31e7d4001ae9fe23fde312584e7a5fd329c43ec0e6a5b1fe8ad0575c6eff25bcf3098aabad6045202c63dee08ec463df8b084c4280fe40f5109c73ec206ce59adae65df66137121d1703c64233ca3d19e651f38a9dd5256e18d5e871a02b32797c5a124bf712f1ede92234e47155b8076b20859152986e5f3dd1e6a1ab09f420208d382a2683393400249f5566550c1740e34bcd9a5ab0827677f2344685c1a80ce02f25de1881d7450325a1c515a9ca125347a6314c776c25e8558870ea5e7fa7aa175bc7b32f41702f64f5488ef6e77a410fc9c46a355300edbd2ba0e12f55c36a1632c4077fcaae29ae00d71284243daf3bfdd0e4d096161b53c1a19eb34b18931aa44defd76bda38e03aa194fe0cd062bc909d0074e5ad10db381933c8e0867f4096cbb3bef505e2090bbfd7bd4fb5974e6356c3e81f80324db4d00b1c77cecaefdd934b8ad2616946fd7887d2925967532bbd1d619ce4e87b5f1621874edd340bdf3b0fe2540f81020e4f69b3a9f4b5b291be80549e0d5ebf73f51dda23e95194e9bdfc2b762622310d3ccdc9b225df1a544249a8c324c17242a8e4172813527a5bba1f3cb8ea176f475ab2519c6d1546156455f5b76e901220e71a83d81db09b078bf43bb55bf65babe01dfc97ab29bdd50e6c358a6507a4bd2fde6e6b15ed579cf89e8861c1fcd96ef5d383b62de386dee9d21841500885da8e5afcb0db12b08cd41aa09d5fbffcc7dbf251ed76ee9c8322729065df4afbcd75eca718acad8d69d969d2f8fe6ab1d363a711d82db990ce0739739d607ed32a608ab5237f9a453ee7d842effb8ed81fe278361048350d91609661d95b5e3cd6db84f2026cd9c98a55d093235a4b8a98b2367e7d8ab5720b1342fef5b961c3cd8392138c9f4484a10eb9bb41b305e65a16fca12f2b1a2de40e64af906f42464a695123277d04ebef96df6c92ed0f936fcb55378be208fbb4d0491300f1e9e37673f2596e2d68641cb149878e0c4d30955d0c749606e162d46d0c5d54806b2eed9b6371a24434bc4e1099584e0cb138f3f00c547e4e603d5f87a28606134694974ff62bd30e1d5ead21d3dd77d68552f24fa50ead95164ba45bb25db38b89387a7f289d44a2c4556e4ebd6b5aa70898b207a069fca3f6e36839e3f7b16861716f2c1104242fe613ce9d1dc2ce5f8c8ed3fb4c5b302c8e62e1a1358457da8a9f88f1810f153a9e3d1855d9a561729ea4fcabe01bd40396ec64d8ba45622543e823b63883a01455b308b2f446ef5969454bdfc24c7906b8c4fd6f09113adbf27725f0ef67cb7e4b6f62e76af81e8ac94201f5141b7c89619d2eb335404e52f0ac0a0fc5172dc104285410bb11dfbe6bf00bea950ebe594c79aadc68fb84999bbcb05ace1f4d1368814c104e686efe68952f60d9b03233df308604cb398b914f630992ee0903342a001e6068938f4a45ea724c914cefa09522c856147d8cb1fc7983fd958c850d29f652802f1293e61fa76842665addfe098eea52fc616668fd923ebd402711ea6b1750079d3601a252f9ca7a1bc59063e5f60c9c5a4e933282ddc6aca4c2df0e8bd94499089e483d98dbcb12a8531e297ca5c52f7eac7d2095714aef9b2185d3c363f909d40b9168d126983476f768ffc64f0b147aaf0908e8132b93d1430dcc32c6d70f0934564c65cd5dd1065e1cc5f59e0225919ff6f38c7b638f9037401b57283275231a5ac1b8da850f8f819f08ef656fcb895e7b6fbcf12b17f08c6880d7aa3ba6dda7c6ac57467d858677446259c6d331270de9de0615082614d07589ae1c894ed1a5f05e598122418b5e1248115df06c11f705de7925fc9adf093afe1783f3ad8495f18260149bb917229cbaff7fd2fbe830e132e20f148b34aaa82fc1309055a8c6096f9184e0f7bd4675987c5a9285f221a7b9a2dc25315735d40237e088c7a851f911a9ad02bc316e84be525128d97b41f9c22a55a3c67aebe9b7dbc89281b93c4649035bf0ac0f7ff183ce51e910796ee249fe5b3e45df79d78d44f41c988375aec87f0f78d70a29a810aef0999355972f856283c36e44b0e593ae1f03cb9d2b5db58ac6e234c7a3cbf03b0623055582656af994cb34c2538c6ea32308cfee2a187cb4f8315474a7f4f9e83612db363a5200a6079cf787608e478282364f44e57525cbc0631e74e3b66007b0aec5fb19fd12d2ae9018745d44d567928836bdd6a6b156cbbd211837c7d223a3b24b463e89f4a9cd16daf16a6867f65bebb1982fa44fabef48137122caf7ead10a6f78e37075dc919c5db0b09118d20e79b6ace013868ee47062574b5610566dd6484b2450d399c2419609702908f5094c55fb6743ad5f4d416ad01e413afd79ddc65a98c6d3c9ab0222c5bb8b9fe36e89a19b118710746d76f2d590a1c1234ce9a2d5d54ce713a0e33c62526d7f70162856d6baa5d9da8fd90fb2ab5912c843e2148f0694001a33b763ec499aa48c0617ccb6299a8bfa40f0081f54f625aced8235948421bb1a54a3bcaaca73c2838456ac3b31ab4b2f4a599b1f2e6bcb1c4991a2d6a2fa9674d04f93ec18ca64563e60d148126a76470380c9a4fb1d218d520bbb817882a96b1caa1721a7d1a75dc2c66cc7e81386daf645dbadc615885acf638090dfc38340ff54527c422cd6bece854ba02398f5529d81d5ab8e14a12f3244de6725449f75380c906ccee38132c432a72d1d179d543b16559a06c60b78a7948e834f1c451e741c0853ed458f435079cb520872809b553ed763b4d139fcb147dcfc20a3dea6fd1e90b920f9ebe2ee505e8c06f71b5d1c85e99b398b0e6a505e9ffb22db70a2971916ca3e8a02018b78e7e0f2f56011dbc0050fa18f341ef4a9b933a6bd3c428c494a0942b7121448d45c803689a3fe7dacd8d9ba6018716db4d459d0341621480ea3a0d69f67361f9e62cb60823cf3c1fc89adffaa00405d537efc62dfa8b1b19f8d273caba381f807c06a792ea647fc9c2827e07f90e9090604a5ae1c151bfbf3ced9183bc9ee3d944612ebb0f26170f84aa3115d433943c0909c2fe6ede17daf525658d9004c883d90d3a62382a459601cf931d698de672b0e69f4a455e616cc37622a8d6456d2a00778eb88928f4b64509c9d22182a707a6986bc9c8cbeb1e64cb32e2e4f110c89b53dfc385fd2eac05bef10ea8f4d6d20fa4b0c7aad4c5b9fd8a48f6dc1998089c0352014e1a4acb0c707192cec71e2fd0b4b1143bf1a5f9a41ab164a16f092552afef2f6dc999788a2bbaa61cde764eb46e573e16377a79c9d772d827731d1a704e068d8b65654fb1c1bdc73acaa9aa642dfba3d9271df8eccc14f44364fcccc0fb6daafcb355e1ccfcc5c9df7a94941912ba60e73642eac97f06769a4d0126baf0a1f25315583104ae1643d5eec5c2c35a313f2a9add4c02f215b0220e5d8397b6a972dd915c702f335c299348c82bd9ae8519abd980ac7f0654d908d70812c76920756eba2fc4b687eeeab80fa0f839cd016c0f75c2fb25ca8e0bf33824db4c8b69eae9f15ba65893d00d546213b4a7067e985518325f4e8fc6c2daa30ff8fd40919e24f939631bd8ff1e6212b3b0dbd81e15efd9c2ed380d38693aa1bb06e978f620fceaf8b42c8b4a83189579d3f1c65c10a13e3472a722278c2df9733cfc5bebfa14fa2b35326fa166861d1552d1fa2f73effee36ca34f756bbfaf701a8d45c53bce81089cd0650a124cf4736b53b3e8ed1d352b8a63214f2a984c18020853eaa2855d083ac8bf81898341bc616d00f58c22faa807e08276bf8d005689849e8b0f751a4c0953c5121667a0fcfe54695125f8b54aefc1f29a08a955e0c615041c7dc8d1d0ca03e1220f2c3b24ee3b517db64d3db505ff4d1a654673ed8540b52a01657fee3b0700a24e311b43bb0172cb4730588fe3826f4a876720bf7cf5a65a3cd4b6fadb128fa3b07c43f2c6348b344301234857d6a9a77ad8e4e6aca2ed7f6470a0703a68341705fead2b3dd78347220ed50b1a0796d07ef490d6da0e72fbd0cacdd0b00f4c7147c66c4278c5bfd843b9ee973e1e10fc595ff344cf0006c1cda2260a0520ecab370f14fe1447f58866138ea0bbdc6d29add7ec1d95c2d0a41696592ded505a285775ba5d066d8b7546a812e51bf29e7f66acd6eec8ffeea264a06927a79451d531caee1810bb0b318d052d00ecbce87b90877581ef1e0c90ac6666e9c6b31f05fca651a1eb2022f3fa46694cca8106676581e6c117d1ccec6c0421e115423059f0d12f001de3b72cf3418b0f1eb1753d01d985fcfa049c360e888da85a9ddc081b4a74cbfdc053ba7463134f4cc1159c19e36d670ba0bfdc9bf3353b628df9463774d0d7d22dcfc3edb3fe11c9d6762cb26957017ba4de2217d01d112ae74ca69a14654780457c9813403ff3bf42d9cc03ae96cc1748cb70149cb2830bf9ccaaba690b3b61c33efefd53272d9e56cf4201072701efdb93b205ce3b0208237d6b0c3af2959e6724a4adc18dc2eb9c268d70bd94c4095600952f549e1304a337a7f6b06c37735c967dfd9f76aa0f951d075aa8861a78a0551dfcf4de8c9344c0bc44b164779061a3e0905c7a5f380b69674466af1e6551e231d1c50fed07b1beb404179ca2d52c583f79ece8b20cda08455239d289b2422eb8bcc494f740373f68073ba0e1cf6989c8472ba5eac03da65ad13252db15247438ca509c6568839268bb9d127ee1fe1380a2ea44c6105b4cd550e78d89ee7e870a9ab25f537adb6af312cbd6407fb9f43f69f9a4995394770087181f8ba6674700e3d5f17814615ea778ee17782ed4c69a9061414e6a64af15dd8657025d8359813a6def6bbe79d3d5dd0657b05bc50d81a4d516d08016ad2d370faba06404633229ca97a42853a9fd23beb88e5523525ebda2ea6c9179f7f883c1582f32efadce56d5c26bbff3c971089ce588fc7ac0bb2d66839adc98027e18a2b7e1512fa4e1c5853821f4803af2ecd116b2d1715214eeb69bf40af7cc2a191070292a248dd49ec87100fc08b36c9a996627cfb4143cdb06b6eda9ed860d998e37ce3278e398e7faba6eaf01cd0051dc33aad330cd471cd1b222cb0ae833376b1259f95e11d09e0af9bb2c13ac7c7fa696c17297728cb492f4c3901d384d81d0186e057178518dcd82ddd3f12c03d42b0505e97fbb16e8dd8c92eee52dca08509e94b9043e7b0cdc1996322738ccd3933a46a860b6d84ba2b762ddf00d54cad3086a8867142043827fc0e625dbb41e6218fa8095fc2c155470a2934280904fd271b0d2ae2d25f345158a7a640947c0752183489eab441bb49caa9134808d94d708c01815aa9c88863b0e78af2195ce4d06834cab7c823cb4d81ebca97d13522461fcaaa52cc4c7c9427ab0354536c0355ae44de7bfd7370857bf4dfcd5b41d21e581a04b3945178576ec2845a5ff36b35fa69598b85a40617c39483f8922f1ccc93a32b904aaeab48d31270b0c3ff184c73b1f0b16142ee375b88c2194654b1fb798147aeb2c7e30902e74d2e3854cca03e9296fe2dfb87d65a77e4a358161ccdc9408ef686af75b678e07a43f45ca8ff8fff9980c87a8473dd5c860f4458f2e24e4e0838bb4063e4e3222b80b4b0326f52c169939185814a2a2045fa558238993e58bac20ae055c0f1838e99fa2a3a60c7e93aec3ca0f8a36fe39659e9fb9069bda4e5880c2b2fc357fcedfd57f31bf58af902063202f01f6b31c2ed874d57943d9165c0b5677b72cd995eeb216b46e62aa99147bf3506bee8bd3592fab7a9dad751341d8a3de9d8b258bafb321ac648e092b4116068ed851109041d66e6f66a8f66adb3e2ae5aab7f4e6943610f55ba17984412803662fc4e4c19865aff0b19e9a13557d899b4324eb30e9a072a60f70bbf89881ea3370b46d9251c295d8d5c1fb7c186edb8008b6ebbc80c1db738efa223b66dc5a63460c470ea247e4ba22e1e21fafd0db8f9982b50782b5a3d960a293c0da395d0404baf0f3e26673100bb1a26c7166b1671d70ef404a17fb11db6ff66dc22a6d38836632f72ff09d105ce866bb54f3c58fcdad747d3d9908d9f948953de318b4f4c7d1870313f32632064bc4abc065bda9e1bdc9907493efad7af3f62dfce52b22a5f018d9aff89ea63fbd1c1aff3aa7236c00141ffd344663850f768c740c75eaa673f36b4b9cfa74013f83d051a0b0eaddd6f14c834b558b02816239e0ec05743f18942c9252cdecc228a903309681c4a2816a819b8293f1dca69a3b31afd5f24464ec3cd4700f85613b91c1777679d2666892d4053c44a16aa078437074fac100eb5311d8971fb3d22382aa23ed24dd47ae5d4deef273a9715562c5d4de90a7bd213cdaaa13fa8558e4eb8cc5180e16421f731019ca28ee850f82c1f372922536a58f9cf0cca5d014081317846e976f3eb3f7bdc3a161bfff81ca11db9e82145acc5bb8ecbbc4bd1e0cb5136ddf8ce69cd1324352ee88a2e25e1731aa3c561fad32a8c6d307109f5043668dc1602ad70531c9a0030d3cbd00ade68f22fa1b0470a6d71662b7888819934a671213cbf1a4f32d275fbd85656b346a3875d2c981719abf765d043df6ae3ebb6045174991543a4a866c19f78e8785eee140e8f3046e85e90347984ffd1cf7fa10f3a0468da815f9e413bb4da416f17d1690501b9a01f6074e73dbd7d65e411b4807efb0747a0513300838be6ff3cee0875d1bbfd82aed05cefc9d3cd63bde38367b7b31e4ccad098de53a15ce9ea0fc3fd62c0ff7884d1894eed0b5547f720828793c7aa1df3f30cd2a3c72e083f8546d075593f0fd97172fe1ac6c8d96f4fdab9f80f02c4e2daa9965406da984f07edd004d19b661050079ddd17faa223fc854fd0943edb7984244607fc852ae83290e641cce36a27f70e8c6b86bc3bf84da3e6cf8fb41970bf3cc9e5a275138273a1a57b210f5a415e90045de9dd79b008cf32dc68f619f22c77ea6f6435b1bc37b4ae4ff7392207e4dd0041f00c75a2b72608c48deefa0f9eeea685e3e69f548dc6f5e0c93350177acbabdbb96b87ce1df70e0e4c1fe8d1d13c2250bd016da97c32a85c059c25fd204a9b01853c3e1e1d9eba1d179e3ccf311e0e9eb0de11d28feefa1eef1437cf9015fd02102431ba125a77c6daf18e1d4157f40b008188e8a5bed03d7a022c7850ef40bdb39cb683453b7aa74fa03e422596e395146ad26e0f603b42efe836f8e1812ecf90052df093f394188f405d746ebfd00add83c877a09b67a8053de8cb3c62ec70ef5829f781b50e2332816c8f8a3d2ffaf3eee07247881e1d07853425b8b663633bc277d1a0198638e8e705e15034281cad1d413eb4f440c8116803bd90045d11dac233248afe7a613bd70f3992608b2b5aac2e7ec3c7c7f0de18b0f098a82491de43130e9d6684f881c1f1e5d5844b18aaa1a312045da0cd1fcf738df641105e403fc50bddd009c0943c438922dc0a28eb168d93fa9b9a275874d0697f2104f426188767900efa1ee4820758d2d1e5900eea62809d793e3fed0871d09bd0b8475e0ab3f92f5665b2bdd7834a413668bfb79336bef22876ddf462cba6156314824fce93a2219c53ed3be1a74154ff71963d93f410a806130a961bdfd265776803fa8e2fce83686e74e31bd2eecf9303c3470984b702cafddd675d40902a6e0eb14dadcd3a4a0836294d2900b869f548830aa109798f0eb8e2e9b0df32ce5ddc279dda49f6e5735aef7396cd9521b92753d81b0cdac748ee03054f48b0715e4153d72fa2b0d57bc91ac06f6b2bfed76c77f7ca2da54c49ca7706550659062464d7769a66eddbcde3d16f395b6bb55db1b79a93dbbcfe1ed9dfe732da7d5fe7f52021bbdeab99ed7befb53a0ffb1eceb69db0e5fade017ae54aae313ce8cf5f795d873d1ccd9bd8b3313c369a6d287e4085faa336e90c8e23cd7e079ff8b250e43ec35f6345af70db8b3568ce39e7d47c28a594767f77777b97819867c8dd6bf6aab5da227bc5db5314662038c5875feb32cf0159f63867d9778f7367bfb7a0dc3835b61c7bbf862894d98775e5c61cd5aae0fc399fd5e5a29452fa802cc360dddd3ee6daeeed70074b07cb6a77f88e1d60f961b0fce84f5f7df7539c1ab986d585532377789388e57e8eebae4965504a8a514a4db13248624c55938650e08bb895b9b11153f5d18afa1ad6d0c857eb56da9e268991fad3b7f0f228ef46912fdb27f5804962ceccf40a2689a9ea379960aafa39dbd2f2f3c6dc131873c398114e8f7a124e8ffafba83005216e4802ea53610a2f8ffa14527ffa1f20c06c4fbd1de0ebe3def4d45bddecdff2ddc3f8c0908ee3a5e545b72c6fca31e5cc9b1b8a388f7e8e2c10a41e538e4b687d72ff0bfd54766b448b8bb28022cceb23c54ca023932927c3240153c26ca5e8c3bab25b57ce2c10b6a76de8448178ce647f02b3ec7198c327da18cafdfed9a44c38d144f69fa10feb00ca84134cd888712de06ad7618e0f7765fbf506d7b4b47ae68dd7a07993fdcc22cf8749bdf8f905f5f325b463cab6dc506d5a785a7502371de646c39ce96fb961da6c3ab385a76db6b1553acc1bfcfd5b0ef346fbfe0d8779b37dff4664de70dfbfddb0d9306fbcefdf6a9837a3277dff46c3bcf9be493c5b0ae6cdfdfe6d8679b3336f58be7fd3d96498372edfbfc5306f4adfbf8df3c6441790f320a4b65101393520a45e3c6dad66402a0c12c4850721f52ed480f0f227ef4c30c1039f0752f9be091ec099a565f4794fe2711c241ecf46f5410b03ad14d04e9934fd2da0ed62d2f4b38056c87a3169fa2f68bfb0604c9a7e126887401b8349d3ef81368c49d3df81560c4b65d2f46fa095c1a4e9d7403b86ad3269629d80fe17704e0388a714382902c4524681168c39d37f026d953963abcc6f48b330c741e7126a611958235b98e3d8c639d38ff1f7d5ff3cb3585fdcc6dc1e4ec6e3e6098eb93b0b47e4a4e90f71f844124f6e162acd32644424f11011b2d312448895dc1e8485e8278b1f18c9fd241e1211520bc794b390d2f7a0a627d36f29f5f605376f88db986be6cae119459f87f5359f79e35f6bad1fcef0352b27d76d4cc2f5730df6f0ef54aa71d6ad69feed3f2706977c1ccd3f32f5767478a388f823f7875ff84d1a6fe5d2fd3c6a0882edad58f067dfc2f6dabb173302feec49c0d916622dc4eeadbeeaf1a0210d9b54ca628e1c7635ea8149c06116e6f099ebade8cfcf3c1e34ac99b7e266ce3c9c52ee00bd42afd4d4681ee8c447bd157580967da3789bbd8dea77805ee900bd72690d633e90e7a4b99255a83f6c675d703fbd95fd5615d79fb37aad2b1ef57bd2b7308a19e17bd293f085248cbcd5eae68a73ef2a84993ddc28feec29a59452da5e044cb9e6d49ceeee766f9565ce7ddcc7dd3d734343d57a2b9bb9e76c67c1e6691e6bafb7aaf75ecfc4599469e68599035da079abed47e6de9d0b4be04834733c3afa9cedc953955527e0d4c8f7716a641bae6adcb006d5a07ced955cc339692678b30af507d7ddc8d5e72ad823fb3eeaf5b86fbf9270431b629f995f417a259362563377f8038f3af7b79fb0da3247a25772e7068974939d2639452a2658f4c0992b634c827079beca225ac632e5004f39d2929515f5102cd3ef96944b5e997e5797f82c398297f4d87a6dc081497cf43b1788f27c3511ca22cdb34950a54d5e59c44d9264da2488ec79be9810e5f9622294f37c3191926d9eaf263d64fa1554a189914ac5e0402484ecec20442708298ed061228d34725822288a1aa46105948efef002c2babc0996248d058502e31f3a3caca08225800c11c317347832650c28aa08038830ea18590c5de9f9220630bc505284098a0d74c04189289424718396d4408a620a8cc20a5000913230438b297e90528511b2c70a2876a608a34e3106c6e20230301922080eaf1f220e00212a9be8c901069d222d74afa051b41919d0eb5651a4de90b32928184ef480e4ca0daa84310404a2b88185317800aa82c67db2049dc28c0ce8febc13514880489019148172460fcc89cdf013d9921748730a8b071ba05145164f6e7832040d47bcc089922a5d347955a08519ce9882061e18a08143162c2852b46eb02208da03ea42d1f83505a9cc96984008236e32f33ae748176b24f9439224498ee3ce388ee358001a964c63311a6bd245fc39253992cc68ec7a9d73dae8e2ad6e24f943922449d67405e8c02a5fd675abd56a85b5d65a2b8dd1588a48a43476696bb32ddbb22dafd65825e26a4cab315c63598ddd1a3380010e7000047cd02180fb20013609b0b1f1a6367814c3439b212977e95d9665b7f08bdf6de55665b137ab8562d7e1502c95425146e6462bb707d9b6b22e1d8785122404a3426445f370bc6c435b22f9c4cb2a59dac8cbb7c440ce7bf184882fe3490f4f8ca0c1939d27313ca96109202c80963c59a18313a0314550163b2c17546103204c0801440f615401aa814c8f0d9878a1839124342071040d256090618b34ca18630a2019401902c26209d014d00440245802201fa0d7df808a132f524ea2380972d2c449154e7e80584038008d93e2e0d56c4a8970eebe2a95ba9bee1f893e9d9ed9efc3584ba57c06df52a9eb2c0f6bddbfcfd62fc1dfae3c1efd93aea6671e0ef66cdd56c0cd1ba2df9b651c977119178ad7dbc181b04fc4f994a37c5c28ba2b679fc5685f027eee35fcdce370b6cad4db7773ce3967d12b674f29a594f6abbbbbddf2b87b1dca59f6b556eb93b3ecadbd62cde14250880341a191e73dce5e289e90bdd1e33c0ac513483f7af778906e50ce7e94715e9785e2edc959e64139135328b30f7751cce970b0a23e99de4ae348a5827c4276524e24e546e62c391f9f69cc51c1bd5a65026f13178939d3cf51316dae1153d5afb6b9ae5635316f98b84bdc24b70557899bc4f5b948cc1b1fc7c1953ec3827bc445728db845dc23d755723ea6eb32bd78ca976c06984aaeccddb4bb67df5109f496177115f80e6ec457e03c780fdee33ef80f0e840791812ec4057d0827020c5272a10604777502b27c02bd0713e8445c27c27bbc65897aa6df4a904fc8ce2562e4257aeb943db43110069f785de275e5e660180538a41152a9da755e2ab5b7c21eaedf5c71249c2a429016b0cfd027eda85d4702bdd07ad5937aabaf55dad4687bb537d346d686313cb414724de2a35842eed24128df7d2be2a2ee7e40368b865eeeeecd33f4aab5eeb0d6de4b73863c730741295ff622ae1ec30367fa2764fa157b2b0fc773268dea041c5310051b0a1531c6189f3c09077e4169c929ed289dad65fb5e2f2e95acfd3e8cab579bbad783c0bdd45efb947299e7ef853073097ebd15487376417ac53e478a4076ac51edde1b4e89f12f21bc51e4eb38126dafd6ebb8db42f7dce8bd2761e4755c96655976df3fbb21c59fd11ceff5ea6e7777afb4d66a7dacbd3427e766e20c0ae2e2f3b7dabb7be8bfbdb699f27d1c93c9946fd84560176559966515ea0fadbb24b1b26d4e793ecd569a68cef90dd43866e9c1fd50dc51e9d3f66a6f86b58debbc11e963697129994ea8d40b8cb8c3863193c6be833136949934b406079386be6763d2380efbd333fd4a30d0074528f753c9fda2aaade458ab88ba28b460ec136dac29ed5816031086afe6f972d2027b7052822ac2049c2081b5f081397c357c4d8cb0508a308126675430745cad25430d4baca431c4113b1120b2e20ac20516418840a0e2892d70916931c9428e1c3f7ed842280b143029d3201930d4c31042c46022c4188e04a7458e1d72ec80491d216c61c6c7c597952f264c86706500974530d03296dd8b6df5267584c044071b3011a856be181f57f435f898ec64b1264a5f298aa458210c0202f94816beace8a97ce22cc11f3e31059ee02b31c618e354cdb670854f9ca50813a079be4a9f1c93e7ab7c52be76e6a4b4316eafad025ba96fa057b046deb42cd370b6d5aae1ac3eceeca9e68dd25bdd5dd9ebdfd085efcef7b733ac8e8d38e59e3667de542d893cbffad07973a7053283409ab5332c10076b640d1cc55e8e6354e433fd4dca79e51ec546316b2dce5c8a9c91bbf6647154f41ac57cc6a5e5328ae5fed34fe368a09e39916de36dc50a1111152a424259748935944c459758974597980b914b51db587fecacda9db27bcea4a19b929e69d5a6a41cc548acb6116d993b465434b2426de9a798100746f1557f57c6797aeeca3a3a035c7dfa98a31e8e8fa0d43cfb8bc3eaa2de3eeb917a6482d66e231d838be131dffe6aaefcedffa0b4dbbbae553c6a4f770fa7d656d518fbfe3f329772d734dbd65a6b1b631e2b0b021bd9be374e7ffed55bd5b7d586e0a4b1deeac68c90fdfd16b4105f6f657fe4cc5bd539b1b66d1ba7699b9390fdfd1e59982387cf689be552292ed575cbc74c64fa21b48d8ef9a3a4ba689624d3d791e386071f2860fec0867c57895cea4fbd4ae686071fbc82c6d14fe0d36415c282988501c97d21c8489ead4cffcb82c6202199fe87837232fdec092e1cb32ccbb2ac9492d1aaadb6daaae1b0c837b387b80ad3d36c4b21cb8b1e84077cc831323538b0f1fe41a6a6176bc20e1aa0e3047e58e3383a08dd27749f5703a68d53816d8422fe3808c5af4628a6b24c287e4c28aa724fa2dc20e858cc99fe079d8b39d3ef3e5e3a15d3c69d4c1577026f7627d3e6f4fd8ec5b4d962da9c3e26866634c666b0662f9d7ad009f4ece509ecec659f409a1d8b89830b06cc99803911209a3255c09c061051997e4b368a791d7d3a8159061f9c1e13ce4963fa17d3bf3c0a65ba269429343d47bb10e66bbe5e1a0af4b255fd30a003b52ae805bcad21dfe9b72ff5bbe47048f72f604b0e8778ff02b2f8bc801fcd790149391cf27dff028e7238e433bde825ea714685e20919057a39059ec2920b28ba90e85f88b306a5585d1566474bda98785be535e2c369138144c7dde5802602890c1cf4e7026dda4ea9d3a61d7812bfa691ec0ead5651fa22ee42dbe3a3b0c7a7ed0ed3c6b660aafadff6f8b4ed71fb770be7a4d170761f83fed687adb6524b719e9e25b7ae3604c113501951e10d70f386886255139971bebf8573def8b02e4eebe1a379db2acd26cdaeb1689a89cc224b072c7c1c709785f289d6e7adb7c244cc20b748c3516bd2b894adec52621f7765dba3168a858647924abf2d9bcbb66ddbb66d5fcf47a7b7fa58469d4b0bca4996b00bb790660f8252fa2e447b1a4e327f8ec3499fe9c75f2af5efa117b975a1b2f64e3ae9a493dd4d1665f17a51ce5e0bb52170ca276e37366f2c4e96b5106f2d8d4aeecf482d74a3e2fea2b2e3811b37421f6abd912347b8028c73843cfc284113640c5185c70c2592dcd81ca3ca5018458e3c3144191a70a24495224a219a2041848e049c8c3c24e14313d70ba018a30626650811d9d00475620c1ecc8081092086960061fecc001160ebdaea58b490c51aa738eecfee2ccc51f97b962705fd43236eb40d03ee0c7d5a6b775bdbb6ad0e6fb0ceda354e08015370459596396ddc06c9745a16f5acc7739a85a9f2171dc8b46956abdca9539eec74cc4ea97dfa5d8635b2d5b1a385c16039ad722d3b0bd3268361aabc6db29c1cc79161fc7da9947fd639f82d58dfe6c0e040a68a666336666336bed5191bbbfbc3bcd1ddbf53113d9594d0b7f987387c2c2c569e2845e513eaf65615b308f58c3f142cf45149bdca492369ca376481b5ca1f8c7dfef5483d3222e74df6fe309e93e3c530fd3ba1f6c67963dfbf83b5cd7df75c5ff476b25b79a214954fa8fdf105bb04ca140848f4d5e0807acbf7c2116740116102574479614144b432aa9c4da87744430f4db095fac440ee1e0213815ead940108f28a2457087185122ab8b22c75abe5d242b27c301248832edbc6cbf381eca4b554cab56fa76ee6eda8b65a7ba9dbc7de0eb71dce259c3fdad58c82a1904f2cdddb365c9e6db359ecee5a9d3775d26855ebb0874333ee320f87e6ead2d5b6a9797e0ad887202dd2851c562002aac0061f78c248c10c3b695c21c31543826879beae50c19269315943aed002cf8e1430d830a9502165053132ae542942090b2bc9d1e816549c913d81650ef27c3d893d71411057d26e75ccc94a473b61f7882f3ce29b140c8ff8260dbbb454b87943bc9476f56aabb5ddaee465814a2cd622220c8ad54a11aed5deac1a69d5d78f9297068a15a8cc325cb5cd568ee3a85889541e8ee3baea8d6c250d095119228a8d642c7f2ca20bc9fd2d39ad722999aac9e44d4d1c925625711fd17fc856b5b5ded46eafa31d3656f9c4daf56a9c476a29bdc48025b08aaa8184a894b3a683a8692435497e5a94a87158c04a0769213bf3698cfe340e3a52251408ca284425cfa724dd691c94242911921a216910241232090e1af3997e4ce5234acd399f8e16689bfb501e28a5e49b3f1efc8d944c7fd038bab575c9d58c5dd7755d375fc4e297539f9b7a75712c1f69e439a799c81f9224c9d2b8338ee3e8725b5c2e242e97cbc5620561b1582c0f38b0006cc2c8b1ebbaaeeb6aca52aea9e11ca691469e9734ec9c0bf9433ac99164cbb833fac88d63b7b95c485c2e97cb4513801b0eba643a8ee338921cc7711c6701117f13a6f9884923af73169c69e40f49921ac98de3ce388ee3e8420e7398c31ce630020c60c6c1964c499224494dd3344d1bc7710c517e6c8862440c527462845ca2fca30545b8b022ca0f34c4700405747aae883124a84a15f7c68d2e88c42000181a3a018095000015cc814dd1015ba2d3411a43c2325e00c110f2514c6003e8050eac70a1063944e60818628aecc04c19a2f33245482a742944435042e3a9823c302ab238c92684948eb814195b603a4358602510f2a5f10289c804a32829f0a498a14342068e8b1e146c5cb0308366c6097014305090458962822b65c90c568a0b84d42836d4e05156e0e9eab5c28006b9d62f75adb5c24006b9d65a2f0c5e5d082165c80c12f45350dc5d519c52dad4dddd9d7694b0e5c3bae843c911b66eb4918ffecc4de983004a4e26409eaf2d822acd5028f37d572b8bf37d5817bd42c515ea00e5b585909716565e5ab84a187dc78d40ef399044bfd3a295bb478d5ab4b2e0c9ee3d89e5497fbd08743f0a57f44a1e3df7bd078a2cdfcb7b5ff771dd8f46a41896ef42316645afe44f8c610971e895fc85a2884299bb9f198532937ec4f2f2def7a48f05f4615d3eac8b738dbee3465c472291482452a843d7bdb678bdb620d2bdb2888d40b1bbf1c3377a96d1bb8ffb9fa6516fd575e0f7defdd77538de8bd6e5b2aed26551b4cb829b37c41a636eead552b737abd6e58324898feb877475f56658b397523a29ab569b616de32ac77953ee9e5ad9a944b1326d7b019524d6ba8c524a27a533a3746ae30e91dcdff1784672ffa845aa249237258de4eb47c98b3401994a7265ca36cbde546422325931159962f31484658ad1568f91207a5a485cad56f5d3e7ba3b059d804e504e41a7b29e844eb01a9e58394184e4b07646963fed76af55fb3adc69a80e1f7149c9f31d366fb89f948718f236bfc979a3fd9c416cde609d22793e6dcd1761dedc9f314ec09001b3c30bd04b0b2916a0c0c87ce475ef348c7122f75f77872123f7db8d0b47db7bdb775bc8916076c8fd9a36f23a8d7b01cafdd57b698166cfb2ec3b6ecb3cc582dcdff7de7b2f0a8c6c4b3094abcb16499224498ee3388e63ee2fc14ab012ac042bc14ab08fa5a5c5c5a5849f2b994ef574f2a6277c65eabc55c6e58996325a8cb03c6171c1725cb762c8fd75c3b5d6ea2e4fb49491fb6f8b916679c2e2c25776cbe543be5a2449922499fbbff22bbff22bbff22ba7c9d4cdd34475f3663a69ce4048458cba18ed782fe8af9bd771f50392fb5d4ba59e241591fb1bbb87de39e71b0e3d1c7591fb3b6ef3d18ef7026f8c1535ab73785aa69829668a9962a6982996fbbdd11bbdd11bbdd11b3b188e0c6e07204a83dcaf39253b2772ff876bad55e3c8c8fd246e87dc4f3720bbb5c85719041b6295ad56abd56a6dadadb5a55e32136d056c04de9c8e556392fb471917e2505b21f7bf682136223766d1d1e5c33a95a7f2549eca53796261166661166661968dec48ee3bc575723fcd702a4f5876e4e2b0d65ac33be50ec58a282b87c562b158f7de7b6ba07c50485049503e2817ea0745a25059ca942b039381c9c0646032b00fc51a1958ee1a5a292e94cb7160f27ba5ca9f2897cbe572b9381b2e33da5066ec40864fb4ac31f77477cb72cb72cbcab646088a8a7c62ea48121d2586f81ef67df119f115f105e504951926cf57500c8260d54561eda337596396b63ae0f9c45976c0d3014f0d703cac357cd9dfb7efe1cee74f75b8bf0d6b78299da1a6c6efe65e0fbf94faaadf37d2083972b8bd36ab3972d4cceb1eedf573b56badb576d894aec04983b5158769a5f51b6195edd8bc1ed3376fb5a33ed775d7755d4727c6de0a4f9a6dd20d6f379c1a1534a661bc7ba9a9585f2b4aacec304f3f853a357eca43f6dfb8ce1b913e960c7c792ec5b550b933f08587fbd14026b3fce4dca293fd4d3a30a3175ba664ff96292fa4773992fa585eb41a8e799c6360c20c83a7fc92429d7c9c34a69672d2b8cbc69a34218ff6a58729b9b480e2c624fbb37ca419b4131ec3565d93c6965cab9c371873adec5ceb01b6c4cab3831f2f748339ac49ef763d02137ddc5e6c927bdaf2feda699a256d6d3e6652327d51068479b95d83291f4194054fd9e270d2b465f560c3b2e68df796861e585d3402f543f7d25a2023d7a471564962a5e0134be556ce1b0fb4301ed892616230ad49e3a2a915ea7c224cac95fd6db4e68dfded2d4c2c7bc994491b4c4c842992fd4be5c632d988d51c6e72e20f988f4dc6688b24ce7282329e034a3562607a248a80039897948f44146ca45027531d8923783b125300593ed2c8ebee482441988d441532d7418847f4eb1255c6690ccc1bc6fdc56bcaadcf905ad6bc31e549039ad1a8b48dd616b184666a00004002a316000028140e0a44424112c3611846db0114000b677c4660523616ca63a1509223410863208e3100106208300410638c82aa0c085856f6f56f32877e5807ef60d9e0e62774ac17c192991d2cc7adbd0c8652d0503108b000d9bc15f26d2a477ab8c7e657d0c32a1037ca0c1aff57883dd375be1b9d66c26770bfec828ce1e07bce5098e55ca57ead6ce02d9a8843eefb69e382006ccb90499a9f8db145c1addec44edcdb1274f2e6676368d170ab35b11bf7d902f4263501b05989f8c5cfeb3e714596c7bd65e6b498b4d1fc8ab4e772960c59e2c8b592bb2219de8035f4bf28c0fd9ae0d9a1573c24a0ccec652dac16f9f7678cc3be8bc25ded127471bf2d4127635e36061705bf3a13bb7173cb90c9989f8df11601bf7a4becc0cd2d4126bfbc190c6a1178ab5f62076eb405c824a05ef1589ab0e0fddd24c8296569e1e5009c27be76e9867ade3e93a51e2698635b8ac0f8c26657ac9bc1c47d70aff4706a297fbeb9778fddf68071b9873afe2f07115728bb4372147b6ea52c00af22335e2ddfa928c46994d220880014fee57482edcd7b4017488adf740a1f75a83acde08494b800091df3583b49c676f89c470c0414c303a6f64b62c6804846f219ff0208f4f1c3fca4a9db354c3200a1557a7820971d174258a0ae7b01341ede6669c19baa83f2b0968f0bc7f69a72cca3dd185a3117b55ffd5d56b10a940dbb238b5514c553529c880b99ab487d7d6a876307e99258eb66cbdca6c1cde9b849b9746c53f8e307792c2014e2cec9110cd42ab40a3532ba331ae5bc80a72c54319912c19655d82d4840067d4e73dd33b424bd5075976053c9a5b4f392efc8f60d4244912647b7e08a68261cb60b248d4dbdbdac9d44d1bf278ec289911d82387b76dad0d836c3612b4a99295ed78c44f85a415830d7734a3295830cc2f50f5acbeb1d0883c05e9455d4f82c13f64362316b827ecb7b98a2ae46c57a2f645022cc6a6286c01b410fa09f5ff29aa1b5431d8dbc9c94ffaec36c3aaa7cc10afd5c4ff1b006135080d9f9ae3ded91ac90b1058584c39689029392c7a742b6eaf7e7fc80610077ce7f0a59ccb2fef2881fc4d91650ab69330b9ea1f52c0c85c316f8553d6274c83b3445c762960e95ff955b77ddf4ae54d965fc2a1daa2b27f67b0ba1b24ec4b68a0825783a69fdbe40afb52547f3740d7438ee3e99011cab29add7b7ef2ba2a3fa4e5e4f1a64fa021d15d55bb6fdaf1db4f31c55a48a4e782ecd076a967b443277c3d6d2dc3a75aa0b52d019d21d563ded743f8f768a6b98a31aa87b277cc653e1c8946e4c7b2d6e0fb134cfaec9543d5cecb6fc743203db6e269da273be6830bb59601d1c6f0d17bfd89ec3972d1581eb84d4f1876e6dea1ae6aae0613148a39ccebebc09e8cf902637ea6b216f61d1c34c92221527bd7d82dbd07d044fc87b97fab15e39fd1e7ff4b764c13aed3a99abc738d1af90439f91ee948b346ce74ee8f1389230cf0223283dc61be7618e434398bcfb2524cac7e1daaf26403c3a73253649e8bff4da3fd2880d5585199b9f03738476cbab356d23bc7de63bee1cfd42c747e0ae43cd20e6131061f8cf66f2384bf2670144cf0cc96b4d4fcc714e8921dcc89223b4ee18b36ce93b6c807b328cdcddca8a6d6e435f23995aaa8e606f89b4fc5498b68bfe1809bda4e8c056688d7c0077749ffe5e48030e1aa966f4530a39c8ed90e95428bbf3782a56f4b63b093f5b4ba4a7beceaca0ae5788950eea201a10fbbd00251008b23bd2692028c8eaf3038d462e91ad96f72209b95d2a2d371d5e9affe3797344954474694134d777943f37510db9e8317da12641299bbde14cf11c4d16daee1938c98cc200c566dfd92546179b36e6957bc59cb3c45c54b07e5e94612f0ef3b974013af03c58bc5de6acbe31e1c46f3245994437c892db6e2c71eeb336b9f0fc9482fc0d0e3e5a38f9171a059cce1098b21936246b652b29f0137a4027aa213249e50e9bc2571ab3dbd88892871a5e9f6dd8156d74813de1db0095f1a486bad5a2d6e9bcd03c431aaa9f944862459282280a30866d25a6617073401393b4a2f16d231768bd3ee29d3eeb80cff333c3812c2b9833e9e1938062e8cd2b1155fca318f841754dc82787a85d4839dd63dd29d877ae6d0ac328f30325fde68d49c50ea0170929c8e5ac426732559d7126539829506d926d5d97a2b0753329902b5742b58be4be64afb8505e5c6a72d00a58eb7a9fe819d6aceffac632f54771a05f37928dabe78e4d4eee4635c83b0880ac2cd7096a0b834037e39aefd1c9a58197eb771164df4f83dafe4a0c5a6546f07f00c2208f5fc63cb72e67098905e656c29fb91542f66ffe6150fddf3407e302fecebdcb357d1fe4d39a1282845725cdffbe32f59629b5faa0d0e2f461e1de2248aedee006a2e3f292b851e75a33f15942e888f72436acdc536483b68b27c778497a01c517c7c45958ac0111ffc6a9bfe02f04ba96200074c56e9ca9f487fa078d6248155b1d7fa85125db631d29bd73d26de04c0643afd2edb95d1583f519ae4962985e7c40f767b25ea378940c2516a9458fd83bd300bdbf761689e82a67702b310368dacfb76c8d93087d9bb6665f8461363e405734ed55d5cca91f6440976927db3938da752996890646a31b3cb32474ca4ec6dc753ea700dbccd0ebcb7a2c38301b130c988175ffcb15f6629ae88ffc91f2b9147b9650b0db06100ad82925ae1e090b13ea593ef5908b4c206d667b409deea090b6fe44514d45c4b0a33ca1c59d3030baf10c3f9329e8cc17ad6dcdb1486b148fb06508f056334670cea43b5c05c3bba7e48ccfcf7c50f85356a42081c232ab074af612416f21649a8a316c64aba2f02d4510bbe53abe12c4b482755f7ab7ee4a868e840f9f4549c5d5ecf4e8d913a7a78d0a997757b23cf25f39bab148ed4e1cdb7bf327e8849d411263deb910b28bf89c0053678619ca0866cb09a706d125c41577f78d0dc1aa13f42acef90ac69e10cb49a24a20fbbb485edd538fbe19cc65a3f9342d083af21c0f6891e374aaf6f0d043d17b9a047be8c391bd24d78719730810517a33c45295089c9b7e60fc43a01800a219be52cec7fe2f7f22d66514c2ebec4f4fc0d4b71bbc8377857e0756e0f41f5a93e0bb8dc02662a73f48f55acc063ae11da478122023030410f31c0ea30ea5686b5c0de22fffb27c871bb0a99241494d25117bb16571d110bc9e972bdf75c6a959aa25dd04a62f316b30868a81eeee1751e6ba94f4b47294207b79afb900dd58582103cee15d809880058034fce23fd65341cb0c5c9051d3d0beb2bdd360acfba20519920f6b3f3b41feb54587bd0a5af58c56b7f6ac1816077f09a67a4d7762882689def642201d9f75dc2cc79675adbf317c6ba11f8234970f7a367b69608d565bb5a9c93563bdc21b43503f8095f56c59275c59a1f25e1149910921ad6437cd1d6ae965bc4d774b3aac332593023b136b57757917c6e69ca0f0171cad6957eb5bc28d200377ddb7c1ea813f353bd9fe72dd74813ee7510d622b472e5c877948dc55248d22122d2a0964cf25e1ea2e70501b2826cd6f87ec9286272aa218ed2379837c2e7baa36d777558789be55484e02534024984573f661c707ee1462304b9f39c1e28327fe8abdb108e9eab303d322556f7d66db3ce6853e3ccb721a4f30bfbeefc385900db5371de8c5442576d89b628894970d7a4b84e53c05053acdeb372ccf2a1f9e8c2717c6d308b16e0168a769be02f518ca5d957e15ea57f744ff36991a32d2befd6d61589a19397ffe091a34ce25c19da1292be7e99fc429b3ecd968f112b42030ded409b773844bf92716c6253606ff44523a815f55132e28144870a20ee9be63fe0923b019af13f92906d409e767c0232edad073b59bb75d1cfa44e10ae8d22a4d245a30fd47b4d6d66c2cdca23bb70b50011c0a4869862a1e51dc26b6f246331638ba446ab88c660648ab7810c11cf0ece88684b8e55feb860d0b65b6185611610411dca31a4d4c67cc96a09402eb17e1af19a0de968bbeeea4a9a92cc4d9a5a5340926e0099228a5611ce20b3799bf4e75694e641f3a73dfeac44571cc2f70cb8533aa1014306493d893e0dbb356e6b9a10a6bbdcf6d54230de7a7e031dab5fff5d3467b1002a384697947414b9a30b5404dc445461176a3b257cd93798c050a045ef0515d35cd680fce7d2ea870e064f60c3c5b3700b73d1d6ac2b3b712cd7b7de623ec68ced5a3510f51fbac60e81c14a078504fe0fd98a8a945cfb881adf654b75a007547d0e7396289bf7c830f3339a1ea3e41402c5edc70a70c05fa193f1cfdf6beb00c14c508f8ba0bfb06a58620fc38040c50a198ebbb9caf5d55b677994e532129ba042c163c32001ce6dbebed0e6ad4898a7ca22e5f2e597352bf7f0b6da9a6d84e0b19d0fc8232bfa37bf97594c0d702482e2f68769c5f2c7af8a5749e88d4485bf3668324714a081d6d44707f1185a1a29d567c8193434c6c4625c26afcf5c08c48fa310945338332ab23a0958cfc762266bad9848e141f4bd02892fe9c88e911bb3f6880cb0fe98b2b45348e79b07e08b481bd30ec586b38039996d241851fb80efe6c2b835f4a4a8ed854b23bde60ed96b3e6d7af5d6c6b1dfc5ab7649bb5bd4c3c592d21a22f84559c24968ab1542abaae313820ec60fe1b69d1c2ed62458525c05ef690b53403c40c131dfe40ba00edcaafad23bef84bb5e5c38c62ea20a22980df0047013ca911a3c3d24c9226d8ee7dc98325f02c44a168de7261a9faad698824fec1e7b6e75fc031de5ad0ac29fe7681279338fd59c2f6e4b573e2b42c7e2cc799692976aa23d89b894c122b3e4599ca1dc8bcbb6cb4091d5449d6e41ab2e6cfdcec64cb5fcc6b9decacd9f5eab71331f23894c3f033f3cc19a2b155a758caf02074f4c08621922eecbde73de79743d7fcd413c61a4f65ce1a869e45af783a472d0797ea0e5c19fcd8f4ca87b3878d18a625e16fa2642c3db13423ca86ada0b539a7d0fadb592a61e22216c50b870c2950da25a9c1e7c2cacba6f6114e939a4ba728bb3e0cfdca6f551ba35f1176e321870d14405633ca7952323d06457b909a4e9d37615cc824d64450020f22153ba27d6edf202413355a5f198c0465aaf928a37ba6741f25db58a51ce9b926f286895650e3b4d4587e8b0f667f3b1af6a8d08f87e28e32404659cfa4fd1f902ad78048d445c58a2d2afe94fe922a0a8caae8557b01462e9b34c43476214e1dc8085db0a7e9ef7c7c764bb53ff222cc7572a00754a8cf1d278794f9ce75e2999e527cb8112f158ebf75446632fc02c2b9dcb176ee076382df7077e987805ade898d41b6ca4330a38a0e51c494d1a4a45f4fb74d7da0eae418c3b1f7f91239b8484c33263a087209e47a09a98f9c05ae8ae6cc1d07defdd1faff9a3f26e8394cd30315e25a868c189031bd2c4db8d8a0306793ca84fcb21666a20b9ff9b1cb456a831927a2efdd70f42020491e72ba8ee6f7c9f0244f38ec9c93133e7fa960b5018080b14fd35da857ee3fbeab7aba82f313d59644eb3110ff216fcc772f74c9cdd11c539dd9129215c9f6a57737f3e36eded0dde16a330e06a66ca33d72b73f191d1de0de24e8a140d259225a76a1b22594cd18051a9775008680b55471aa308870114b499c395804410fa0cf59a24a801b44b7988d1162a26823d6ccc04a09f3b12e0bfcfb206d675ef74a80120b60bf82b4a1886244c9a18bd266d480b08774effb73b623182b7a8619b94641d9d5d5de4fd5d6c2fbf2599a5ebef4641c7a89b53e00a04432486be21e85e85a4944a4a09aec530e6e69f46234ffc4d66a0903d9a2be6e2597b318e6ab4dd01a7e7766ff2321d1b80ebb3a09c34c23bd3b0216d0d1d20c33f4f22941e94b0ebf0e87879692002302469d3a27ca048241323cd2dbd8c1704f39a4e81bff66b76e3980ae0d51733fb67c90982f00a4d0924a4b36fd40e28bb31f0248568a2502ae4617c57231aec0ee16e71887902cbc66aef9fdb3796974ad71563fe7e3f495440c9151c229934919fa660970017e8d2e1d9089de103ada4a8440f0cd9118f3c4d6de2ec91e0e8628852c04783444359d3392ac217042b9406ad8ad13d095dd34e135d178a8053f76201bd3d95589bdabec3b729be8abc9767ef6244649db716645a2864aab82d4b7c08aa1f0dddc4ecbf3ae037d5c6b1b439dd50d40b72767ca8434b60e6224df11cece4e2ccfa73b38a4ca127c1a4fde8120c0c2f4912d5884003e3b3373def5f7acef08cd918489cb1f1b94cb7122beafff8b5c74297c99cbba4fdd2cff66ad1573d81485da36ac1751c677f8a3ac664336ff15a23e045b44abaf6cfa6d1d329809ad958cac97f35f567938b52a96b729a5a21af3f49eb9adb6c2df7962dbed9abd45b1b93252ebf23c63be076ed99bcf7e90023399e4dfac040e503ce68832188de863552eea2abb529e80941b00639eda993fb11d417711202cd44a3f13a4c57297f8a1b42af2338ddc304733ba06159d798a2116a4349b8f8fc002558cfb32f1bd5f65ed11419218323359096072c20a61688faf7b5f8c986e502885122c99216028651f4644d2d4432827b96ce2cd2b5f4af6811b8c67fea37ae02ada29b992e70873293aff1c7d2bb2bf87ab8b2d528a8dca22bf9e880cc705bb5bd2e7aeaedc9ff018ecc2f16838b0ff579c0127590515142bd670c70abc05e22a8ccac667d65e06fe54bfbb6421117b2a6e238d237cbb524a025097c55c0338d75b5d6a8e0925f75cdf01b422e20154d98d48c3e1084430d9d414ab1f361b6a235a4b800197a173319c35a18f39c3cf633888550f796eb554615c0ff7d9b681d59c325c2d02a8d80c7c10cd0f460be5d3fa3a66fc232a4baeb04d528277d637796f19d9f2e7348b5646c80181bca64ac66723ffbd9deebeed517090b92ca07f78bda486185ad16ea0e2766393ba1b375e146f04f7f53f9a7be0e1f720beb609ef2f886d755176259522774a6badaba49c73f650ae4651129948ef69e58b00b2a2e23f31e0d196dece81814f1b69087b9dae73dbc8219cbb9f3d343db6ff328587b21ccf931f0ade1c8032aa16e4d8b8b81e6996d48b35e8f82a99bd49d62b63a162b18c5af0dd8cb291fcb71380b6131684073fc7a753fd59f15c75301d5bf28838471ece82676cfd1b0899235bf4c73ab1e5b062f89e714ade45257b5373a47624560b34ad2dbebe636db699d7efd2777ea5361fe22215ce9369a0cb983f16c094c18d61083d1290af23a2de9e10fd3d5a9ac66f71e7bcd590256e4f53c86690183100a7311c953ab79a2189764ba449569f66400a76e6a00abf813790bd2150be666077456083c5765f77b711f07fab13c0172bcc0704467a4bf27d80d9dcab16af9a4ce902993d6b237372b0ec0dc356ee9f8deca8e196bfa87cb59abb84caed867b7142739fe37bd6d802393529b18c6a4fb6dfdf9170e92ea366169a6cf3bf9a0d846cbcbe5d7a88cf9bba00466d0f02df5efcbf9d3f4a9ae0a29fa71741551c80e064b1a882c86cd77c980a71357d6b3d1934399342424d7d963cf9ea362da2a5ab9ddd7d46993c583b04f6f582bdcf80dcddda235f16f5a3b5475bddaceb839d0066bd89cf7c5cad72f5004365b19c8157b480085f4c3f8a5d907f9c1dd64ef18df6dd4a11bad4d7110b0bb7d929ed2f066ba61b04d116973ca802be0169c54d614bb08a90186f9fa6d21c38cd83911080a34ecaa73b51c95bd1c68fc27d0f47a3909a75af387f129fa610358fbba2dafda621cfe44eac71c6a87d8813594c3be445e1c3deb9453d051d275cf41175bd9281c8f7e538e3050a4c91613dd1d09414a8b922599c197a6d69e18712ea7898fc34cdfe25772f5620483229d5abba28be64f7b44a45f8ed5db9494392a42a75f7f1137607ececff312bcdedc4de34b140ed1fb1c03d70de2b040f4b1aa8b36a911414a6d989cc9c64fabf9759138be581bd6b6989097146fe498c3b4d22df57f548445134963c4eb77eefa5ca181cb85282dcfd2ebdf38d95f70fa8dd49a704cc63cde4ea2997b1d3b7b6ada7a4442c447a094110001c96b7c381d3261cf48b2e14dda63b760a80d8c0a0919b89dd7054b4bc343acd9f16a6d8b7d7682d5461074a963e6ef21ce26f9de65e0b34646c8938b93d11110b42bbfd1a386a9bb5f2af494c85d0369360b220d333eff12dcb898c609b11942b2887b9080c024b10ac3b0ccaa85dcdc46ca9f62d3b0cf13ab376351ca3a99a9789fe4d6e87a93a6e2540e8ca0a0c62d26128d856ed885a0b400f73bbe96c7d10394e02504aa26002a660fa41e00a25b5ee7bb3586135de43af3f660def145970319a20e637762caa29041d617afc5ca3d2fb20cc92fe76294eaa1c11c2976005a69fb3e186f6b3dba931b34c516b7b45e1be180ff59d119433c0bf3f3e8acbddac6fa797b18233b65f9196cb13d0e77140a57dc9d67ed6466350ca1fc0b4bbe279be13612e58e6f25bf3608e7cdd5035a980bfa69f65c7e2417a051223cf524f3b2e5da63e72abd4443735e284e11971041798e03a1b10ec42c972034aa6e9b8322e4ea2ab52f32406ec91173948000beede7903aef7ac6dc7568e17e07ab5ccbd2c467a6b2b58a484aa636553a26972a09d37ff1af8fd6e044c8888721ff415ba15550e5c4cf6a7fbf193a7c09db78f373050ce8baa578c2f6079a78d24b452aa9ad30cf9b00f2b28780e65674a720cbc77b0272a39512528e0fa44131faa467310c92089ec04dfcdefc9e3888a755e936aa18f9a5959ac7d60aa56442368d059b85d6b576fd04ea22624904987ea4f9ce19bc7069cc8ecb837000e34e690a80c515d4fee6ddec881926db40c04a48bb2ff0f060848f47d7f4d7cbfb777c0caa13168bd1c6e7e8aafd6d38730a1aaac85bcf68d1f484a4f0a31446a952d5b28847b88f9c75d4f3d504c879f6a01b2bd73011f456e3d71f43d92dc5bb1ddc066c198a277bc1c34d6ebdca54be806eb4ba838d894aa7105ae252cef3757c6a8954929b5964da9def4b23e966342ebff4844d897cc8ce4400e737c80aa014cec0d3372afcdde3618981336869a1dda95873978392ae7b865030ecf9054bfbe9dba0a236481e14fd4e9967f064fedba1b12a3c542b9ce6f93d03fe708459df449826df5cde27e163169b7cc9ed5f3a72ca8f21b51077f3323c20401f7facbe5a5240074872e828c37b1810d3e86ed9517893f718a534c5fe9430fc3e0e4f144afec301e710b60b57e798bd345eba0eddb59134fea0a58c39710b5e5d31e9189796ad762975a15d8db5ff02d813118c7fd9e2a05f4fc73e9f744e79101ce6bb15b28780b5782a301ae218820e08225b5aa41e7bcb677c677f7d04169a7e0edc8e385701987e9095947d3fb2ce6fded9ae097d1ee3b1bfe09fc412519692b5aed7e63645defa6c5f58edd65dcba8b242f14d757eee0f2873daa87ce1b710052c476a7aaffad6b031915cf73532e13eb6046f2bedd1ac5e45eaf64bd29d0e8d8b532c87eef1b8009ae0ecb8d109e7889599dfd2db7f97dde9c70dfe79fd9bc8c90b9a60bb46c7ac6360657d0213c6e140d1459f7c77f475878f8dbe0fdab692151e70e42189c27d51d59860a6c8ff0415f43da9010b11367a7fc4b42aea37affb7e0772316b537a7a081a29c344910b4205f85ea230299b0f01009cde180d9a11f9564e1e7d6abb72d7820e68eef024a0bab71a638491a03ecca8b1ded483b23d55c4558ff7d9f9fdbc2aff4cb7c5d8e1f779ff131e91bd77c024d6f4fdf18f18b0700c2772ce41b6b2aa31a5fdda53b0e5e76f8cafcd544f46e71b0cb9d69d7043b84e9d60f47ecc2beb8fc234eb0f01ab5519d870cc22ec0a0b0469771ac6d8a30619dbd71236bc565d432773992ec7747d28e58d15e3bc5a80299aea500618803c0a3e24fa70d5b09a122fbaa07485dfaa1daef63c69b5eda2c90ad037976b8c0dde1c12ffb2183f5ced07b4f1dd28790f47f9d17b46b73ecc09072deef8f2cf3a26d18d406eae05e722f6e7ca8b52733fd9a7657c822b6349d1d98856761b9a43de15f1a52c7cccfb8361cbfbceba26dd7cca80dbd93320ba9cf46ae112b9ea92d625c92ee79d7642f4daf63c88876708b11a7da971d8c969c39d19620323a9dde3fea921378b43620712b37d7454fad6da2d3855d61c6166c14faacbb857ae526733ce881bc8f0401cf44a4318b7173368fbf36af72d701b1985d17cab71909373c0c0a217f2dec80d4bbafc3184d71924aa0460d34c42d05bce58b29e922c0268f0d5448ab1190b86013744434681cdf8735d37273a6a4bb2660b124118dddfd889c05b3232daeeb131914483884ff127d92c7cc32f2d2cdeac190acc394ecfeb160d4f53cea31f9e5348d496d9f56651073ad6782c94e84273b6ea69d43e39327566e39cfcfac50a74f906f10b89f431806ea48824a7ac63b918f4809648c3ffcad4f3818793e6dfa83bc1931e63d285d07bd1bfa506b6b6038599009201fe1f35296ea8c96f643fb16ee4debdecaacb586edc3ecf8fe864c82025ab45288020cff1493d06dd5f535c957188f73a43209edf61679acccd8201837cd83c62dee9fc60fde98d2e67d88cf6160b3f7fa4d3aab4192d52fb7f001c77146d1bac43650792a014ed59a737a9a6fa0e9fccb9728771a31b7081f7455edff86002e4280c1a0aa6993050a316e3913f2fed649e0b8a4664eff4c3d3960ec1d42be950dc4a0d35190091f3527f41126ac0b323a1c480ac3236ddd777dc8b9cc7702f170bbae5deffa6c42ed6733ad30e13fb386ada6113d7d74a697304f701a71048a7fdf44d256b1363acbdc9237f074cd856175454b0248f7f9273b8fdc2cde552645e9a4281cfafe7accea1cc56abee2baffc9735d1b116803198caef131050037055a68689ada854b3e07fd07c4303b2d15f91f0b2bfcff8050425fb22954af6684944c2f5064144e9a4f0cd5aa2f0635f96384a4e44f37274657e1b1550a2729408ebe28e15c3a42c365072ccffa26f65f1dae3ec803fa01ff85045a8d06b714b15af03809089d6fdbf327ec50fabc6c6e3a72794f769f46531d3ab9561a33a586dc14c5af0602d5761ac8ee32741333109238cbe9889ca15d2bd05849e40cae29f4b7e24382c8eff5fdfdebbb4d57e8dd68ba6284f06dbaa1b947651c1ed164f15e0ea0c65890411ff1d98d2161dbd90f070e61ca605b584b059a832a00d1d70bd884ce80a0d7779554cb83780841088d8fcda2da32175eff55e80119778591ae6ddc2e88a422885c1118e866a4421b7afe2bc3c1304c790292d9db2ce847f72e828a5d4320180344816445db66fec07399ea4b0ccba5c58ddfec8491fef6f90e67a01412bed3fae10a9d7f558d1b908f1a00a1abc6e74a1f2a2bb9c60f8c5aa556a37d17152d4ea2acd3b084c864014586af7359bdd998007dbc2103336f75e970a5629175e475c98e1342719bb179500ce58ac0cf09484bd9cf20274e99432b9de4d9a2acb18a82735a88b94b70f35b7bdabcb22707dc5d49d6e5c47cca0515e67209e48a134ba0bf4bd10318775a0bc3d589b9c13e0393b6a89bdc6ee5bc3099a2b6330b4f0bf3481feba6a92ca978af5cd935a8b6be06b8753e403d48952fc0cbc93dc7385814bf07489fd2c19b178b4f6b66214542636441306412f922dd736e4195f028d4132ab7c6e1cda57d6793555328425807ef222cf96e62df1b31d312af59480d86d78cc4bfb951db0fb5784f25b9edf8a41a46766ff3a0a26b7ecdac00906467ebe0a0137278359f0a19a96756f2cdbac05e4d15efca555ac54b3cb7761dd3ca0573217e2e5cc70168ce975b57380d2d84f18e96453fcaf0f4dd18310505c2351cfefa945106a458b22983bee6a483e127ec9f2f0e0364030c93d59b79f0c89a723e4cd6e8dacfc28b2da4628a6d91ec25d1446e86850a971e938a751e9c23ac9a3eb988ec5a9ac27bd178eebfefa6dfd9fc3661ec39ac9b84b5eb5a276ef0ded40f7dd60a706d3a815879df994d3dfe41d4dcaf896aa350de314ad8760e7eea74c13e380dd47cfbe009b928cf9b77ba9237ee0220cb87bf47b21d4229a70c48c6e8ed67c3372d9223c9ce85eaad2784f80fc6b4a763e26acc3d18735b719ec79f99f8fc6398f315a056e181b2b6cefaec2f246b72b496be0dfdbc21388c8b20a8ca7ba20168707331ccf8c1b718f40705f3ce79683dd9a13b1a64eab2f70a44868bf027489dc82a94a556daf1200b9a064f95f5e0a62bddcb28d1b6753b2b701e58dc422641fa223588903aa6df66efb6d418a00401d75475042ccb15714e39a0e883fb0ff3a9b02dc4c1760cadec77ad923d70f9118261ad23f9b3ccb5d688f0e83d822088e1aa25563561d2d37bb78f540e748894cc08abc9b680c64d522501ee2bc952d5ae8dcc83ac9881fbae13f15a2c4ce476342b8682a314df02b6cb16915d389dfe8deb4d032e2f2401ba195ab4154ba1e2515874dca0472a231b752370ec3eb46615079d75562e457ba51c38b61bcc1566c97efecedd13a1050a67cb2eb746b2b7381f9ee953682404d359edb234e6ca3c50176b819c7de8494d4e0badbd8cc8504e03d231f73a5fafb8d0a727f5411bf26e43c9cd7ce17ef6b6d40fb22cde13b33553622927120ca79f6779c5fd0ee8b22d1d13995929eaba1f97afd3347a03a0e0c71d9d739b706e4355a741811f5cd3bd01f6aa18721b4d8e5b8f1eaeb19187e11a3a1fb8ce311274b3e6a6bc35672909bcd69d504c38095560a77186f390a70d3ff0c21e4157e9522a3254d5cce382d21b12ea02b1130d00d923341f5e7b10115da08976745c19e4c1e87cd097e07b81040e49aa6c87eb8e59027d419599f03e77bdd23fd182896861dc6393facd5727f0febfbd0cfac64ffcb0d991455e78db19eda4e070016c832354952ffbe68a9b0155917673b125b883a31e68556f1a214a39fb701e93096b210d94badc875e19a3a5e5ee3fe98a30aba90e5ae729eaf77c842d9f131b41b1d16469dcdf2b93cd852a8981548a048c5afe2b06f99bbc99ed280f7c49aef34c085f51b35b65aaaaf2384deae994f90dac70edd079ff9ea87b3787b229bb5c0bbe29fb2ce14378b4a066e8c1d3c2cc996cb11e5b1110aa9fba35e76a0f0b6e29a8fd0398cab3100888cf1d5db3271b6450abb257164ab3a756abb0addb24f4ae99c07e924a0d255ba7aa9e5d92124d5c745d20728681cd65e02421f1913cba815cb439d503d0d7de0955c79385f069489403e7a16588a565fbba96567384e8407342d083b392f9ceb0f4ab8f5620bf71240b2043d72e32f5767fc04252e573f1f835c2aa9bd753737bf209bc8354c2604c7066feceb9e8a3e5ee7271175ac004b967c935fc415737bde0676bf41321369ba032e4d1a2241a4b0a95ba127bdcc8a06d005dfdb827c10185b784a5cd55d0a9d5cf3649a2535fe63898d8864475d83733e5c89419db61beaa453ed3e60d05d0ead71841360ba2ad01d9b423b301af7e871b8198b8d60211b10d0db4fa8542db0631a0ade52039fe69a0d5ef10837f3591b3f7f53bac101fb740c396d4d292563c65a4969261e9faabd8744831d705690312f6fb0cd37ec466b2c180f6d334a964e0a5697c3195514a32d521a74493d0a2113064eb4db57d8d054cec2629716198be1dec7ad9af1e528b4898badecf052f9ca427f4cd4307d5b2f9129f2797d08b2569aa0e4de861c66b04facf3dec1e700cea931e6e201cda64902aa85eb46dffc70352c50c1ebd19f9b0235366fdf7c7c4f58bae51f12981994fd4999a49722ab0510556b22cb497d50ca83431a3722a980e74f4f8657611b03aed1a3c5ae6efbffba3d09abc4acda6348b772de4aa200bbfd29f61671fc723730788b7f4be233dbc8314c225eccd79f2531718897b29edd57268b1b9e7009588bfe7546a107796553a916f3fcf92f36eaeb71f70b77b4ed65c4d312a695a954cc9698eb54ead77a32b58c46997830bb440cbc9e848496632c6202aa8bc44adf0ee49abea9027eb7c1d68c78dfb61483a0873bdccc1d6a3acfcc04809a4e908198ac7245915b66b9502532bbad1d8239b3c691ea9da2feea30474beab7839f7d64e4000442dc12b39b35a5d5107417bd2641ac12183728acc8a732f759bcbd00c3f3bd76257741fca5e560ed1b1fc8a3b4bc770189a60b6426c920b749a1c172eb1f5a0fbeb556374e04136d18969d228af6282aa361f18acf78b6596da2c7ec7d50f2d33547b9e4dc1b57b023a30d1b98d57dbc08bfff349caea0d196dac72b37e65501c409980582aad90455c4bdca85311d9b87b28f3c15c32cca5a41c5a2c7584bb5f09977505f6f63073b7c059301462856d06c3bc343777e5f91f94b21098cbcc2e25bc5ff8caa9180b541d508e2da902ca1fb7ca042e3c9cb59fc5d569b5540d50fd6749b1462a081a9b54ea4c6556cd84f1f614a64c745cb4afc2949f76b569427d59e3c06f13c28bfcc1d394b22462bcadfae9d9ffdcd4044fe5d1e428be809c333a271212f30ccf2dda7257da78c7073f4ad1c01886243cdf9ada692f664c6139550a359a5925a60a1e2556ea0f57dfa7b1b490b4946edd71b2d145c65ed43e316a757a5679d32ff4899a862b64d3cd3498b642a1b21ff5d38b43e372edc4504cd46d152d1477a3465021c83f8151018aa605147348a080d84061b9193cb7298b5bef95638f4d816984e4b61dec860077bfb02c63ae642ad85d5a69b238db4f2d4d82235c0d6b669390fbff90b779fb9ac617fa0722e71ee815979c6f00b9a20314a2f76075261a1196fabacc9289877500ad3ca13906f242dd4661b4b533c1e461e8dd536f8c663192c90fa62ba7e8248952a3c94b4f0f4edcc0bfd70774f0d5e610bc5c4b35bf9dab1458b2b21d69aaf186c9d8378e710f85a4e38c3345289e83838a652fde6cd482cf8f93622d1cfe7e9d10bb4a021dd0a3cdabe74f5b9f538928d9e0c27ed6b407116c476091c58063674dd01b5056ecb04ba79d67295c68ed306a078144bada412e66d8d44e8bf76375a1b061f083f1b1a1939ab1a7ae3ae911cce74a2de47804504727f747c4bb9f68d518b423ae22ab5a220ee141ebf7d92ba156a4cb69280df1bf6b5ce3b530c18988b5df771d553a545c25bc1a809c5696d89b426c1e7654503d8c306c432bfa24b63a3ed6b2522f8a2d69e725d10b480795cb53e73abf1f6b791ac445e9db7d1a418b28523046b10593243854f49392358a610a8e3c789b2bd0530dac7a1fd538a5b39bd7b676643021994e1c4317206d55ccfc576413e428ab10e9eb59515640f66fb91c47ec74a316768d8be708a948733604b7d29190ef47651db1f2ecd8967d5f51415f8a6913e3d518a957f82d07e1c0e7ebd38583cc954a76fc59f696eae696d30c4773f0c3664e2cba78e46879cc94f310f2108fdbf9e90b4af6fd8e84b3807211f0069fc76c3432b40327b3b6d0346516e357129b2a0c918bdc2033addd1e5502d322d161d604094b8a76229a181d9f8b0e45a885d12532fd13891803e7910b6406d14b0eb1435ede7a2487dec3fa3950d12bc16a19c82578a6b6ffa807a83facff3c83ce327248fe0ffd905d4883558369340c539805135d63948269b0885a46a94c8288ac354ac53cc88ea414115be453edd4f242b14f233e77151aa69b99021a0451043ce8d5ca00a60d41e5d429b64d224c62d0093ceae491756e85af62f8f0e8b74b482ab4fd440483347c52cfdde58117cfa4f06ecb9a4052dabdb275b129176b013754623092ad5c20ece8e0a25d368a74dc7862d3c294f116522b2c377430d223df416ce41af8e7a7caf0e9c5114c355636843faea1f7e224d3d956de3f4a100dacb7df9243e510ed6e58af1f8aa3916b62b5fff91a71536163df314f831225afa71d9c0e0c361dd2549f8311c21b847c01367ddb4d8c4fbb73d268f30d517dbe1d4f887e74776e24aa238bdef1669b6f17b3d20ce5e4834802da7b82cee604460128634e681e686b92647b160774809a59d24d0ad5b31c6753d3e1d87cb7c0e9a6c672341077fa8b3a2a9d4c51b9c1c71fe947ce87e8a350357f6215d0437bae5b92a06120085280914c50460df3a01c740841cddbd70fbd5256c4c2fb7009425e472eaf6256588696f950e9f3799669e94449e0340b05e3deff72af2517b597dcefcc0082f45280a96cafdffacf8fd0f7d42990f1279aa388c82f89acc53f6f0d502eec520b218bc19f79fbebe70df62d6aafc666efa971b8055d062a779af9da1dbe9139b5e3cfd30c4b2a03899a48038cfc8a7f912ef74388157c17d65b2d39b51f2f510911b306f3f66881bb6a4321b4938968f6220f4a8c289bb766ac28258533b6b8050f6eef25c5854e5e5c165ead523342b28bd9031f242ea6d4cc5984cbd20a8651deb0e836827a6d88a4d8f7820a52da4b304a03dfcbacd088d974b05fc21cd37886c1f7c33f6efe17dc9edca9918616831d88987046419f61de8026ba7f65d9712a221cf4ae14e2f2e26c8aca81f6c4faf771eb8d6a3fc9c91e50d818a29b7e3019b410c3e80541b8b5fd170b7f80a6410fd06dfbe0d0de116f387463194a26bce4226b424160807b6b0621955c105e741628785dc4c926d4031896dd8c2b8084ae564d7272529b5dd7da75ab3e73014e612bf8842ba0f8a033a438214469a84f0fcf7ed4765c4ba86b991a2806ce52079b6876dcc45c753c49a55d8a84404729af5c8b5aca4abbd70e5b0386e325adea17bbc1138ca967a8792c9959bdd9fd6cd70808ed99656e183b6a4c2eca54831e96ae05c543a6142d8f8dd5fb8e2a07d344eeccb25591610e14af0c1185b1b5dac1760509208abed69bd5193ffbd838e58d996275ea27912e32ef7ecd86151d94c2079bf0a70348090fddaf34854d2a2ca66e88f980a5a62f6d69c1ed5133f44dbd2774f018e782aa263ab5c9f4cc9d209543e534ff3671428d22c8bb82a5bd01a9de6bc0b1dfa0daa03a491e3c416783f21d053fce8e0fabd9f76aceee65d5d9e0ebc97e0f12977bdd71d0a85c6183f49a61f6bcebdc4a1d40cfa668267c8b828990f74baefed20b21c026fd352dfce3a5d0e021c039f671cf8267d71fb1737d95bd7bc83ea70dfb4a7268115585f81bc5067327584e93beb34a630b22fced840eb53ec48bca7b6c66ea1a3428cfde71e45946539bcde6c1d7d47f697ee7ce30eeb0d3f9154721a9b35d0c5d2b05dda099d0e32161e7495a91ff6c7e7763908b366b277d1990f2e9999a9982ed7689563104beb771a0ec2a7a6f27a7a6b9c1169e59b73365214ebf6a30d85df1d3466d2b39fead2128032e70753427048f1a350cd89cafcfe22030cb71f532698bffc9370eeafc40b766c9a814f6df66e0332ecc0191f3fcac8343c1aad85aca9e424f1ccbbc713935dc7737ea06726c4078b0ed22e232c568361a35d57e6224bfc03368c5bcf6ebbb3fe26127d4509644b565041ca6db52dee46aac772b6d8b7d3bb60952d63b1975b5fbf807f4f7636788a4ba3550356f064a961fce3f543f7aec7af0bc7f1c45bf889e9f3337e011175cb375e117654f5c5c9ed09a980c7cd3fc359f889fc4db2eff83c5469dcbdf74a5426bb2bc1838cd5f491870b2f098713796ccb70c380070144bd9f13f5a21bb6e8f5ffcc24294b8dbf9b2da6dd2137e4047a226864bcec6d999794a0c271dae7f0a5a4440c7cc0589af8da51a64b2317da3d7565393b09f93d2c2492e60913e0ebfb7639612cd33490bb9527b1ddbb435c70c76015299f870263724adadc6e2d5f29ff81e7241c485d802de04e3352d154428e95432109b81bdde08a55c8ed0d6dacd9e083ef166e742cebb267b32ae7fd20b3bff1bb2c024a9026f4ad50f15448ac52ad569c1dcd71ec0b6de211c54eca950370d542003ee11b2b51b38c1805605a23ce807f72b03d725f2731bf7d9234c6220fd792e83ff6f95d86cdefa01d0a4eb2a54ca902c26cf940e4c89a22c60bb51f549803f247e3bb847714564ce64223d2455619fbdfc1d8326d2abc87ad6e38d2701cfa8ecce16e4d4eefe79a236a7023e8197bb4120669eb34b57312789128eb0c2dddc70531c2d0e1d7de782d8f2367cecedb2ff0a9a66db9e4e8ae491e8bfd27e607233a86f8f961f6d36e2a09bcc95687310f19a873b48703004dd53f377e933520f5d77f29c23255a403142436fefd974ff177e216e6f65841c2404cdbf7f919cce2bbf5dbd068270e85e6fa09bef9b66199f8026967fa7ae08196f364cc483a9b21f02cc87651aa769c7e0b20ed817bb9e8de59b4cb3d5167fbd7474b026622f442fe45431cfebc39c5ba6f5c33ae5dbd7a5ff2c19582c6e17f6fc71cad76d29cd8bbd9f5702fd03df567a296f18428d6c885054a53978cac56a2124ea1a9776111784612beff5841e714fbc21b0ab0fa1055e07b5e3b04730c9ac557432b70b2f39d3610ee34692dac9778eb54b1c9757412f86d14d324d5e7fd8bc21922866d58dffbd868653422da8daeb15468e721610f384851e38d1b1ae5e609d06a29b640695ca7a513e000cf1d0adb1349aad85a95ee59d4343d3461066fc2102cfb230a90ec1f2866bd6901ce640eee009d766ab64d1602a12c3dbc478aecd26f5663894dea6156a6250c7b699faa8e6569f00f379c9f546b9de4a2a324c12424763be42218d27cc54e7a99a6c694dc3083c706f173bf22e702f45c03ddb041b468edb50f079766abe3970eaea0db7a650eae3ebf2cb3ae9b2deab83f371766ca947765187b6890c68adc077123ff664648bd18a74a71e76492143b98f7f37cfa1397a5d3620f7ea99ffda9eea0a198cf27e2cddbb5e846b5c98e71c7fbd3d2ce9095a59ab853a022b9677e46bd59524c16910a5cdf4eedaff0af2f45a74465c34082fcd54f81edb9683cf287d299cadb91fe1d86b5a49a3a26f4b0520d44ce0a42790082d95872ea053e8c1e9a2b67c5277f0e78ecffdc76b0e1ac8425ded9f505f85fb2e407f2f324078f6341ba3777116c54860e5349486400137de44cd09a45cf97c0d874e2a44e780fdf345432a500d17ffb30511c70d60768d0d167a5e8a8990f209d6a9dc5bd4cd39a08500473bfc75b7a68a0351669787866c6547fcbeb2a161cfd522823fad8c26f2ae479e83291305c897b70030de066c87e490c7649d443971b85c8b6fa33074c38dfef203fe9109d9c87dba35f9631335aba0f837a8ed80e55ffab28c9cb5f9209b193f311f327d560c7f288cc476a5a5edc51640fbfe57118adcf9e1e38d4615ea9383a6459c4aac47eb303910caea626bb4bfb10695dbb43169ce5cb7dc5eddcf7058137608baed9d8c1557a1dbad684f2a6ab1bf6209f282ddc377b26ea1704af1103f8397c4803428deaf6b0128fa5c82fbb91a51ca9fc2e89a07eb469e965535003f26929c629fe6d02c2766e7096972e5aaa5073da948a68e6c9f15bb327d3ab5b8a495a10d502ce99b690b8ef873ba014ee04252546474d5f6f17a684e0af13e951656dae8fb5a9de938a4d609503cf6e6f309b5faa9a22eb4bc4cbead44fdf4446d9b56ef8a40b9e5e7098f815c311e28e36c7bfe4100d225fe1a40e992bf05b0452db6d7fcb3d7228864811bdb28b03af71f59d2a98200b3f95aad68321adf32b5fd1b3b37b4fd62a17ad177b3d573f559ce4e85ee219d0f53d4f67b2c92b3f5c0acd6cfacdb37e12dba4fc478d3980c39ff1af67fd2bf1918fbeec8c2164a55a0fa5063e22450223dd445f7fb9030c31cb8507a83c30b8004a431f3334f1c9cba090d8b78400a08c69630b9d71d19ca9637ec645277e05b92c62045ead9121005e997205e3a8a4c2d62b1df7069efa4d9d2d4000551f038010a03b7e5ddb36c115ccf789f1721ad0489eca524dc0e658582e6f4b62aa7781a8d0d6dd63611cdedd47d7e9b88806f0a7de1b722659396d58ad8109f84d42361a72e774263fac4dd483761ae229be8f3b1e30b53deb31d5f3ef657e71eea30e6d18a9efbcf92a16041b7b0c53b04b02be2960c51ade346ae513d5ff5224356518fe2c2aac2e5735ec97d7b22746ec4d952081889555c321034206aca5b1e38779819b07c10614daa90c69cea027de5b1df758f199a2f270bb174fadf9439a401a128bba90e10b1b268ac8e655c92fec5261bc191070e31e4b198fd22f25e5897c26ba8a96274dee3835eefe91fce869b0d749bcf296ea6676fdbfa89d3b6f257c95ced099d1d7345e8d8acaaeee190ce95c052e8dbe160876e19c3d7bea2617bfc9aaf0e57259e86d8ef4b819a641506ee24d471e9e77812549d3fd3fa3b82a16198216d0fd657a0d51087e164423dcc72040d6b8a87f30854572759aa0651e7346444ace2e5744cbaf27b06fce972b4d9580124c5a19e970aa39a062b1d0648e26c25fd1632f3154c9eb64f2f60eaeeae7979f4ba9514a72acc41911a6f6e22199311efbbfec9cb8ddb07421e48b70aebdc62d0ead2ddc433d3be1efb9f6034bfc7526d65f05b15bb45eed7429ae7934c84256c7157a282af08b8310541d02b6f5b5e0e9b8fed2f27755cce515a9225f664b3f989fb6ef402144de8317dc49e5949467a0149d0204e6db2bccb66409a4f6aff607096bca0c7c0246d9a0e6dc72dfda91f9ce28c56f809fa8db819b9fcfdc1dbd8747984e67d3b930ecbc8f5ebd89b2f877859b92f34a89518b41fc12fcde81bb55ff7027d13089feb4d1b8fd9939c047ecb25834b0c95997f6c0d521731bfce1db255b515d0f01c681cdc68a913575114f533a999d71e84f2c8f509e9e49f5a5de3f753bf1b5b24ae2af3b773aaf742ca8d9a20e4b134d7c0b4aa1c67f992fe7af0492337bd6de7e355864a33f060288658282462d83b2d69499606384db6557cee3367e7d0923746569e241cef87c8d291db0449908db2be66a1662699f9f72072e0d4077c3960fddbd082622edb8f25d68a7c026890ea58746e904a52f9c8627918cccfc8da4aff7546183a623926aba7351255a95aa02a7c00ca54f2ef007657ed03a05d25526b53e7db2a61697f28dc4a593a3a71ff6b91d21e4128bd37e030b900d669ebe7d97068f5eb481a0444fbecb89c97f2c20514c9fbd8234e93e494b37d7a065cc2d60f9dba8734c03f3410aa96caf80b119ac2ad45173246e13fa2247dcfd64718fca4620da7f58674de0f23ed43c8dd0a63fdb88dbf43940d1ffd8e50c8c94bc12cf81c0a71d2cc7aa1cff7bd7c70b27cdcea9e1597fab6f59b06038000ae9ff430f6f0df56948aed251c80998e84ab7ce80b3ec087f9582bf6f1b4ca489f626b2bd27e4e5f5aabfd7342b23feb0877bb0eb592c636f3e4b420e48d6b9740f5a1790ec9b8157cd25f4c5420245f7f6980c92d2f59011fe6e7d6ccc76f9d11fc0badca5dc6c7a264ac8daed697a4b36e875299490fc6d0d0ad26d36fa2a9060028600845d511dc6d53fbffff03dc441f3c6525e9eab1d7e1574b4118e2ffadde9eec6b3d9cd8f9491680ef80917ccaadcc19f271b5cf6afde140bbe869ac181df5932376bfe8d701a5aefcc03613e8b39a64fb2f8971aeb3a15e38c413c49de9d4c967885f7885fa87c8bba1e0c215b68c748e2e8a9fd08411f453e9b621a5fc5a2b103cf691b806ebd427d47dd9cf28671fb4648086a6509b7e02e52268d984bcd01070db9e9d6004e495fe0123cec7cbc64a4b15d93f68e214b86d449f8a755ff201fe7004bf42ebbef4051fe6e3acd897ad1523fd8bad7b33c68f2326d6cdd3244cc7b20cdc88612e362ad58321412ab489c30a6be81e3e85faab29dab3712dee17650d83d48783d6e9e310b5268b3a7e8c78e9e15b0826de26d4283d97d23afcb120a91c304604dce9c929dd0d8906cfc13eb4ef499cdd03fac264f5e89924be28cf4e66ef22d4af0ec812bba14a69f033a42b32e34ccd24b6f737b490031a883a815b40d4554d1b722c77ed335935a4da51f93e96f44506b14f7d6897ff502f7e778a3f5291dd188c1e4b69e6f30234b7d6243cb06d996f3ef6ffb547012b7ce6e0577133bd32db273aa81e6ca9948de4fbbfbf5d6209214422bb7b73cb7908ad07db0744447aafc0c5c32b401c9ac314c6fd866f6e90c46a7f7b0d431a0cc377a37ec4fe6ed4875857a7d9300f4f83040476e6f0884bdae2c74f057f8a4d2f004fe6c96c15702c40fbffbf69f1c46834ba69d8d2541acd6e1aa6341ab66978d2481a4ddb341c69b4ad6e198962e927156b391d1c8e345ab671d869340d3ed7244992545c06c66c9c0e2efae32489c319cda6711b67a3d6ba2dc2e7574288354dbbac6229faf558b74068cf859041108892dc100d41d402aa02698249a4a24439d42cb8b05910e9e7cae2950512b260a2e19559b4347ce9331bee4033fd908204585ac27748a29f4b8b235a14a16d1036de6851440b1500d162a561109a2948515191102c6af2a39faba847efab5f110ebce848918e7eae2296deb8080545aa28469b7eae284fa2043181344a9298830d49253a3275b68dc282166c1649f4dea2b0f473455145b1d1620b0da1ec68f1441ad14c3d4068a39d362d877b86308906d2a37dce397dce8ff36514026dacb5d5566b6db5d6da6aadb5d5566b6db5d5e5a455d26a318b659a7d32b3a96d5ca669dbdcb8b96d136f7833e7936ee6fc6e4e3be76bf29a44202fe247f48c21a2934e4be7cf773ae9fc1802980432e1009def0cd04ee7c717a09029438e9a21da87b8500d2be83da9c9d9352bedd03d462927f418a59c93ca4969add662d562589669da96d18d7294d451da751bbdb454da688aad73e2bdc25c59d9260bcb3663d0879ada6af10622a42d860183053d5f65485bbc09a067c53b017a3e0b1022edf6a1b6b56a9bb70d9afe06f2d213c84e0188401b9bbb72659103dfdd8740120414437a008512e8b80f5e00a1882d82b00321d4143825c2c20b2cbe78fd5c5834814593677188c0031ae800a5044588e268064a2ca185173f4c6185a5810404b41793638cb8ef33ebeef9f35c20bd73cfa394b38bf2e5dc71b2f2bb2cfd24bff44eefdf0e153fbdefbebbef86fc2e6b734a4e869b1d76d0aad4ec46390dc3324ddb32ccbe96713c32dd7133742d1b1701e7e46b1fb9aebbdf95ecbb616bcae566b81c27ef6ba42d723ae4bd1bc7a3fbdba5dcc7b81dd24f59e953f27b37e497baff80bef9756f7547ca79c8f5c1f9c620ae33c79c11417b31570ce9e77a325400fd5c4f90d0d70350effbb24ce4d67a73321c74fc8abb9f7763e230eda4dd1174fc6ce58bfa70d0fefed200fffa353fddfdbc1bb1cb6ece8fc4de2547c42edef288a837fd9706f8b05f5f6fecadc67cd43c6d3ccb1522fa8496875cd979607e845c06e2ce8f79c88dbea19610d6a023719b96613626814fa4911a3466c0bcb8c86889c1b2a20223a5743b12b76919662b9df2c993274f82b4e72f20020b235814d1cf8585108dc50e571849e04aabf23e5871042b5c5600599103bddf0f0cac30029fc00a2356e4dcf454f15758c103d12de9e7aa628bcfa28a2bf00aaa90a20a273b58c1f202c217e37b8c304722552441d7182196e0d82a7a1023441549a8688c1033f861562184ac02882031c70baf87012fe0175431a48ad50d7582d6a40a1c788811420aaa5a6b7d2aa82882a243153dcc00dec4c450a184ae3146082a68a06b8c1054bc6015230415ac182124152e2a9ea002a80556085951a45ffee11afe8be14185b70384425ece417b0fc21c6dba8837d1c6bb80514854c167f2c3a4c90f93202097bb478fee72d24aabc5dc6299e699069f70eedbb63957a4db1c9398bcefb633710ca49fe778113792e345fc88b3889e14113de9c268a82789929e244c5c3b700585c021700585c0229005552f68be21e81ea394137a8c52ce49e5a4b4566bb16a312ccb346d831b07491deceedd204c4981a1a2b24280181806c7036a189b639515f026807ebfb2b23966e17840f80eb31bade0c5d00fb48e05663074c4904e90a19d1fbc165a788249122c1327549e22e880a343588a4d19bd27c70b53b8a2e08229b8b85f5c2c6e17f42374a9929e1bab9f6b8a9e15b4483953aca6d0c1a3e8a95d48f1a4d3cf254590948289144a34fc6d4ad1a3e1e3d0826b440b2970a4e8a1871f196890c206f2085813395ea8b5097109119ac4253e5a11222c9153041350e8010a9121a230914316ab25a0800831904428e27d5a1822c7252d0c61b19e1c2f44311485514624006d6fe86bf435f9dc5948f121948108802ae8e73304d0ef4f3a723c5ce2bbe10f25dc7c46463ff919d0d1a30c924c40488f57e3068441ce053214b61c2e84385ccc42dee2c2df8ebc772347f91e2ed5db0a1145f193806d83d95a7ac3c0e4e81da3b78da2476f1690f0835011f81b84a2091a3e057251d641082a975010ed36f47341210485929f1be0216812747e0a308a11f90613e182e2094da04ab85000b9a040421130d238e7fca20b85131b2071628496d44912bd5778b951a6c1dd56bf4c83fb628cf1638cd11d4288a1f6bc69d0cf9320c3fcf99131fa057ce40931f87942912055063fd1d023661a8c3c0105efe4093c7c174618e76e4f6c829840095ac204413bf3094d3413bd5720ca4217fe73f77cf7cb0daf874604f24530bfe4f3691b6554f4cbb226c28f10c29628635fbffcb2036adf50d7faaaf59ae8f208cd038f14e1a3d978789a161c0150caac0524314e0d3f9a0caf1065608fcc2f3b321dffe56547d4314b1db5eba77bf0a6337cb3fdfc1f56d7d7e00d126a915024f2b53a7107e017d883a045635f63a8003948921f83cc51e24c67f8d16818c8b5b1b1c1810609fcf85afeeb87df0d8831ad616b2386ef06ec00101b1d33373519dd560a3192a6bf16a1bd9828a59432bed883fb11da731d5710ab4515c4aa01be06a7e0afa20885909427e4cb08937444b328759bc2624d6059938cea277ab62770c0a9e8e77a2208120cfd5c4fe03c91c3755254722214140463e3515981afb16caf14c478f5d0921dc9c08a5c58f47339f1e284cfe68412339ca0e1044b6ffd5c4ee8508383c277fab99a98a2892656f473393182c9c90f6264b0c04613390080d3f0b500580d9f5aa1e5563623a63577f71314420a64b4b4fc1749c10e35292250d6d42a4524c5f2995aa94d118130b58255fed399ebdd78e2f668f829568a484664a940a15028140a85e250288ee3502af9241229e60d35178395f0f77c69085172d247a95042502b8ae2207c3ec3a154524a148ae3501c7ebadb89327623fd9e4568db7a69fb9a29e7faa03fb57d212d433f1f1b97d67c836fdffa4c85b7c56770a4c5f19d334171e9efcc7ee743b13605fdddf968fb915298f764711f310dfd381ea4d773a1be7d128e21e2be29747c6c672d1a14c38f38d364aba56dde9315b91ddcd7d03d12620e6f7eb25d8fb6afe17db75c42dbc75adae61823aeb528140a8542a150148503559094aabc36df7c628c919ba4f924ca914828154a08095584db366e7b8e442271cf653b72a5e7f286dc97f0e5760ddb1649daf61c973754a1705038281c140ec9ab112ec6182309fb00a2e1ac73ba575b29967db6b96f9f5aa58cf8d0b67fddb6654fda9ed469da6f4eda48d9bbc418b16da8d9db735b969f9f6cdef035dd91a5aeeb3af8250867ed206a855aa170bec6fb5da904bfd47d8ed8d5c73e485dd7ddee6f2d95bad2edfe6697fb9788920a8c0ca3df95f2b6a166d31dddfdcd1b5a140e09a3705038289cce6b141f9b1d2d00fd7c6c84e82fbad0f004fab9bc18baf3c5ff25894422cd9d3d7d201989345324fada961ab30f809afb1c9e22f2a4589292244925eca34ba995f4a5fa2592cc1d88297803d13e600c9d2c7d26ed793f6f1b6af6bc99f452fbf91d293f0ecb06685acb3bc3b2cad71411a8820a951dac3d44aed6f81525a472b5568e43a9b84709e18ad45aabe4380eb5aa1cc7ed1fd27291f4dc6fad6255d6a0d5bff8c5faa54acadcb669b566f987d4180a4765e3bc7e711414e9ff702d462f80b401f473796124c6f81edf3dfa3f1d3b10b54b6e478db652d69a5aa586d4f832f394bf8cffc3b584b2522f861c3d8921e2528de3e1c3f38699d432acaa6c53b4668a55e74cade6a786cc5a6b8a85a558b5d6fab1a5b3779ce588d5105344524462760cca2a7ef4493f57173a5aeb5e0c946f4726fa00fab98e581aca7f785fdf6c7c6ba18f0edca0ed3f1d3918a29e36bbc4a0560fe61fbe512bfb472a1d00fd5c5dbcb45637cae9b0d6becdbb3e76df7ec97e0ae6a64a6bdf759bcba51b63c4ad997e7c0c6b74d7f8c8ecfe81c5f9117ecda84d9331abac484e7520a17a502b15946a4bb131581ee63d73cd1b721c0f0d65512ad4ca67ec43ee61703f83c41964bebaae76a82219f6417a201a5a6b512821b553a9306cf624abb2b2512b5d65cc76ad10c22efbc89ef4b08bb572f52d57dfa28ae8cdd98a77d4f69d8321eaec9dfbce7e871aa237c7c560bbe72c6aa5b97febf2e3bb5798694e554830fb2ebfacc0501fa5f2197ffb28213055bffe46ad50abcbf1207dcd3eea77df71316c5e9f7be7ac3bc7d9df1d10d656aebe739c8e0dd5d3e18a3b22dc151971152544d7a71c86f7638cb7f86918b8d350aaec04fb01418e070ddd0171024de997a42c41ee49289c1ff287dc3fa44b0c1159f73b83adadf41c56ca2fd9d7ef3a2034ddd950f7f5b7775169d5862dbd7d0ccc825fb49d85ddef07a4e9df4e055bbaa270503828150a87a2561d5157d411a1705472aec758e9d1b224852346395278228524da6815851d7ef4a6e7c3944bdb2e5853784da13505d5147ab4a6b7144b5bad91b62c4b99104208490f1b90713cb0f797137e6a9522926249a83df633b0ffc4b32523c60a8ca79536a7946affc37dc007a2e7e56088da52ed37fa5b07a2f6319f8b21b3afcd87bfbda6f366106f02e1ee76fe03e6cfd9a212e6dda2679eadbb33f396785f5d7303901068b86d12e8f95bde2923da07f740f484335ed35216be4d15d19b6e33b20ffb1c8d9f316970f6532c18ff4fc64f1a3fb3e4ec7316723945a4c66bef0fed777fffe561e0cfbc61803f63803f3f453f3504a6e6d33c678c1137c5da381ef369f6419f7b8d8b6173977fb1e55f64817915ed5d9b9f6dd85dcd970f66fecb9ddf4d0dba66391d59ca5503df243d5a6a08869f23d2787a06de1e06bf60fb52abec1565e45b1979db961c23efcb9257f26e51c930f2ae3181b4fc7d4a4911a1354c5d7389f4d92be2b8ab2823bf257b6913a8e429f8c53ee6a3967e974af9c5fefced6fdef0aea2bda7167a575a6e4db5ed1a662b7b129e2a1e9bf6928b61d3db9f228e19e4c9409d200401843e81cbdcb49c22025548ad524460eaa5581abb3b37899fe4d7bba3e5dd4911598181329ca0c1972d0821ac5a832f2d87dcbd7a5ced0cc548a3f70cc929e56f67e98072c21c978e48f7fba145aefc0a75dd3ef4843ba6cdbb21f38c983fbe8ff90581e7a5634f0b0c50a27d0b277a6f375d0e92e782c20f7aafb045134d13e1933506da8de8bdbdec0809c8f0e3d127a574c8ddefa7757f28a594524a29d5b94f5c24eeeaca2d6e6cb40db56733ba0c91eb0f7d4b3a5f04f44b5a4a49596ca8a1a98ba62d9ac6605180d6302c9bd133db15add1972f5b809a865443ae0784510b406bd11dc68c043febc7edc834ccf6dd903e006d01a0adb6269df51382d6b408e1d332920f74e57664da5aa7d894d66ba4532fb4586921a4450e508aa05c01250a284c40390214d76e89c18582022d7cd0220708a5c8a15c11a1440185892340710581d29236070a110c0a0a34ec81564a83f0034694e4073bc555010f94524a29a594564a29a594524a69ae99524a29a594524a29a594524aa9d1ddaf870597e845248578afe06de38996af8253aa4d09df10023fbd7e3cf12c5f3eace15f2f226ce333f14d4cdc17659ecb997037d5f1008fa7e3571cffd8be1a7d8c3797d18f9fcbc087aa4a75a28c7c77511daa4375a80ed5a950e5ee14521d1adac68a89fb8f7f5fd70a5abe30b6311465e43f919636564deea63abee3f219fb183d4291a049680f55e2339ea59fdef3c003e26f2c6bd5f4ba5beb99ffb231f45ca0f6dfdbfebdeedfc3f102e40118e2ef1f1baa5c5afe0b50ecf2b62f405cde77dfbc5b5a6a687fec0548531d2db70d2ab4fc0cef4d439a6d0c999470b7d6f3eaf119ff796918b64a5c4c7ca689cf68405a90cf78868f5249f1b6f285869e14c9ff2e7c26660cf8495ae0063ffd6b47d59efff56ec8370de1ee67f42f2d9f72f14320a18d9424faf13d082549d2c82200ac601c002a78e948f58b2efb845770b61365e2f758d7cd809e549a125fc8dd5209fb9408b54c3ad432e9af8427a7a3f4dafcfb13df9557f91e2b5925f78091a38ce33d55a6d6f51118699822718d862919e538c39b03ba84bbdfb3954987cf73440d6e8fd36125dedc49cba4430dc7109149877073d73191e066cb4ff04d36b8f0e95bd8a2ebc710d16a6559e6b9618aa7cc5ed7b72c4cafa28cd23931f634be9c3d93937bdfb484bb2580859a358bab4acbd304905ba5321ac9d19eb3170ceece5efab7c652f977aecbf2195ac467668ecf58551452552dfb0a91804960f6ca84b2a1ec09f699eab9007f020509d9d4cfaa56ff86acc7b66995422cef2c884da6cad140ac093483fcf49a427e7293136ee619917623cd463bc7a375376c69ab7a58c354e9199fde1ceb5607edc53c17ac26272fd0a0811e1870800c15b08009e8d66c6ac285ff2c8f205c6929fd1b32965f94995f43338170e5473725e1eee78aa624dcfdda3fc61e18f09938df67e44ffa9ea8fa74427be1e11f35f92fdbe079c70c5fd2bd5e730911115d424454972c596297546c895d922d7187900b93129312931293129392968eaf9998b8f3a98b0e7d9fbe5bb01f1da099a3337374b04c27d3f12c555dcbdd97a810a99e0b34db7198ed743dab158b95a3e3ce7674a64e4b8595edb46437d40d6515d6908ed8ebdd68a910f9d0031ef08007f3351796acb0b26cde2318d2f5eb077e5833c77be0e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1c94972b3ec37a8a3de36d4e894d77ea5e56374cf7d8765fc869de39e655391f14e7ae7be6375efdfbdff765f06dea44e46c76d327e0443dbfb0be9b917d21ec190f6df2318d2dc3f3d8221128737f732728c1197bbef32b20f96af61b2ba5cc364adfc9659fe7d0c181ccb4acacfe7f256810123252525a5dbba946e2b954aafe192bbbb9b923cc739dedb7759f61bc77d87638cb85d479a2cbdb777f7cc3fcb7b7b77dc3dd79e37e4f0fdc8fde55c738e5d9b767049bf274b4f96de72f62e6b8895b385cf0e3e37494079d232e520c8e746888f0e5df8e8d0e248da86b5bf3e3af8e8b0f2d1c127078df49b0d50977efb6b4ae26edddfed35eeb50d6fa4ed6a9bfee663cba624eece4f775f2a6d24bc49afe51aba8dbbf79a72e073e373e393834f0e4998923025c102372376c02ffe4a1b415043cf203cbcabef7bbc28f3b3cef79087fb631eef05a984124a28a1c4036a8c31c628a59452ce39e7a494d25aabb54ab849098f31723b8078cdf44c071312a61bb8109ab6e94c8b0fe5f569e3b6611e2f3cbd652f4b4ffa1dee775fb997194a4ffa1ea5dce366add2cfe1f3372e67a6d6cdf2c61ed6c799c535d4e899a7eadd88dfad583a06d1f181c89acca3149a7c4d620d218410c2151ddddddd6b8c31462aa59473ce29df531a4d38b8261c5cf84f3a0c1e7f669f30d03c6d6494eead096b14b4554bbacc29568ad5923fa92129229a8da6d2f173b87673e42745e488b63ac2922eb1cf15b5f2539db3cac7f00f29a70e86346f8812a2e543f98f8b21eb71e9f819cd94e86c47471d13921b38c0c3d3a070e001e0c71bf29438762002d174d740244f629bfd48a7384c22d62c32551107e939d862ed668780da90ab2283bbe7cffd893866abf5d3fa69fde45c1ff6a76d21e133d84e921e252e0ca5cac9f034a29363c467329d18c839849ca82131b8f4e1ccd131e55c08ebc43299a1707e805a3f4d825038194a95a1704818cbf5adcd1baa5a2651e619510b6aecb5fca4104f43adc26cf146c4dd9328e298d69a82b83eb09fdafc6932817c66fbf833680ef94c4dfdc76979d500a9b19c234e25d3e5a7f8daecf119253e635d3ee34f4e93107216d1f04d462e7d95cb6736340571611794def88c0a864d6fa8778a085421ef1a2e94e83d8974fc6934897ce6b9b848a2e3cf229f81b38b1411a802fcc761597e4ec530edb6c1e5e6475799102815edbace526badada45aad7d940a85835a51696bb434cc41e1dcd8c0bf42a87df89dd155adba80281c27d7e404fe23b914f162631f0a151a6aae1e1716673328327ade0de85ab18932f0aff6dba508159d7703bed868f8262e2efcdd1969979c15954a117a6535876ab4b41cc45863ac165a9d9620aca5365365ad2592b216c65aebb4d6da3a638c2922449ade273e73877ce66f91cfc0d725f21923215aad0dd2f44dafbbe78ea6ffb6971e5b617c192a69ad2843ffb6dcdf3528d5d1b4945f58ef066d61d8dfbc6b7479b7b434d58034fd0daf0cbd1bf45f7a22fdf76a68ed63de35b4fbd2a3297d93d1a59f236a78af50a1e967fbbef40b109a529b2722f51083881fe3ac1f638c3145e4218410ca39e7aca9558a488ab50351266b09e1e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8e8c855277890423a57f3357f6ccf204f3a293e94d7a7add65aeeb7df41fb8cfbed7b705beea1e58c59186c86342629dcd9cad9cebb1163c46d99947023e034d8744213a62d260b2eb14194c98a29e29e4e04588185397b9e0b55fbc73cde76ee9e43d014c5dda7d3e9743acd28b4f8fcd0f2f9c1e7872209b83e3e0c01faf8e003f7f16147431f1f74f4de7c7c80818f0f437c7cb8d1f035bac5d0cf27c815d5270813d6270810347c0df309d2a321d5316f10e89b550d1a33605e5c64b4c4605951f111c282c2be9919656f40c38ef4326f0e680df4f053853dfce4cf829f4caf9bfd931c0def14657325dccc350bd767aed6f2be406897cef066e1de96eb01bd191815be993be97c8121bef7139c2f866a23a0cbcaa12aedd176f8e6601ded4f43c4715b51c62f10ef5444fbfbce6a48e6cb8a3ac6e4e4c21ee83d9814545e2e3ab309daebcb96fc07850b75137aa64e6694557ab222baca8a26131d1d1d1d1d59d21e639e2aaf29dce4e4c24e87869659a56789bb57747a567b4547fb5659427ba7d3e4f6b8f4cc2b567a5856a6d70639486185d3284e988345e142adb9bf5136aabf6523ed3cb423d6de2b27d4d3a51df1992c471ccf7dba7cba7cba7cba7cea48d9126554b965d7785dd873af9cb3a5c9bc32f46eb849092fed4f7358563c36406d1212d220148a2e14a3509442314ea148852e7c1e6e12aad1a1bf0e8b82f74ea7ed677834373bbc28b3b7df81f4731565b6d761b9198268d2cf204f667b8d3a7c32cea97a3748cf71ff38131497945f48dffdd39bcbdb415f8c91d5e16edb48bae2ee5f97f76c55aaebab9e0bdc6f35eedbb28ace9fad0cdb66902753dfeb6bb57ec6d51df4eb3659cf85aae163ffcad2377b5516a05428156af53e03e7ab653549627aeb5bcbdd3c391e15e62725c1a71c6a08de7c26be75b719deac131743ad2c0a2796227c49270a07a542e1502682e414a99b8ddac67e93a4f79d71a406649a4bad52443857f153fc169a4d6c439d5ab9c54ddc9a624d4dfb432e06f9fed37d6e704e417b31240e090f1a5ad3b48c5a41586be4ce5c69d0214de651c583be182dc5aaa9f16ef8bfa9f36ef89b6a70778d578de7c2d32a43986ad31117fed441359190fdd6cf0beecec95e306b92bd20c4106a088bf8690294e9b85a96c872901d3173e8cf1d71aab0cc8aa8a64619919f8e88d06b68f72b6deb041acc547e9a5d6b7ec6ca7e6642f4cc587a3e0db42d9d655996a93221ab8883fb89b5ee5627cd8b38e4671fadceb2e7b22d6342b6618ce18dc3b446574a93b099c1b53a475a48ec24e951e262f2d30428e82534f4048563d3026a328226e9519279bcc9a4c90bfc971096791419cd2e1ec4d23e7cffa08c657161a4b17e2e2e9a688f5265d4ca4f723eaca1c1dd956eb5c66ddb76f6b5068a7b3c8acea47337cca986d773a1867695a783bb5fbf3f931477ffbbbbbfbffffc892648ad52ac1b15124d50aa10b87bb490cea0c88892d94a0d49ad7c7010520d41ad7c7830f2e1610a1f1e8082b47a50bd40e760b030545a182a298d39b61ce1ee09f47280902b5606f829de21a31c7e8a4fbbd0934b547302dc4d4d5ccf9b9f705ca00b6472e24a77206924a57cdffe1e63a8bf1de0a7e8ef4f23fac33cfd0b144d78db7d4d4870871ef47a116e96069e9c0e1a30303030d4c5c55a1af235a861dbe378cc3d81b4cf360853350dc6985ecabf362f161634f5c86f327dce1ff331f98698cfda6b02c995170c2e894565a361bc8b4be559582c455872588cf88c8afbc8a95a4840cc2fa59455c2bc5c79f9cc6e6145c867a4cf3c8d3f6aaa15557c5da01be433301fffbeae90f6caa6cfdfc3f439bfa947cc9bde946f307d4cf7fbaea8de8d787fb3b060f00dbaaf2be427df70acf7f55cf08fbf32147198627ccbefa859fec5959667c91206e6b5ba3daeff38180b21a4e14e23c2e004f8499af08bc7e09719f29bfec5738ffca6971e3136606c601b65ecc76013ce58e616fc14b317ce86a24cfc8c314ec70df2537c8cbb4036b87b02c9f87d81b40ca02813df05ba5c97eae202f31728c2bcedad17c8d2a0f13366bcc6e99841a7cad4baf5616ac01a34bed278893707348d949f814b9f713a52defe3e69fb82f764a964e00def192406de3327c80ade334705b35858252cf1be1dd006da2b423afe86e36798dc620b3ac6e7a0d63089454c9268ad2f3f1c8f26c6979c1a9ebfd05e8c163953d0dd0f7deac4d6ceec992e6db7ef7e07ee494f0224fe24d8befbca39f732c3f6ddf7d8becb3db8ea2a99b5f667966518cb5a1cc016ff48000c69f97b736981a8ddfa9af69a8d8f7971bdb85e5c107b8ce5c76bac1891587e20fec7dfe31fdbf8ff987f1722926f35227cf9fd2f16093f4e861b1b1ff39ae909f469f8373d0df8f39300498f98cf4f021bf925bee9ff4d4f8298fc42f30ca6ff7f89b987e95f7a3cfe9cdf54995a37fed67a46608491628d76d2d6da1cd09bf46cc30483cbf2fff861fcab54fe05e825e8e5f522b462b4f272c5485b00038ee3e27f0c730c8bd8f6d8c3241886d918f299fd5e369ef80c66a3c86768bc8cf1365afe5fdb47fb52caf8ff3534f8ff7be0ff7f9c5f94f19c7be4c78ff30df8738cdf2c3f3656ef866c798afff5423ff44ffc6463c80651c4816544ed22c305dbb016371a3852ea8fbd8db846731806fc24b1b7f2b30214836ecaaffc3c17fce5af00451cb8eb72febd193ac43bc99f111fc6bc5b5418db28a3fdd321b497f767e01d354cbeaeebbada653fde33a705ef7b044ba2bfa8442e9566bd746a060000008315000028140c09c422a14896267aa4e80e14800e8994565c4818c9234a0ea330c818680c33c010001000011919198800d97220badb51ee02f487ea97c94e548d6b0e92c984209aec9272548d4c521fab1554f3898236b19bda474d76a7f8b089dd805edf0071a60974a488212722aba524c99d485b7db5974e7c976a6c5fc998a7a0038df07514bce96fb62ccd63d59d8e80cf473d99d259e35fda3a0ead4291d7939d8090d4d3c509eb1e676027ddb0ba176b911074cc02603309a48af970a08a4fe29531bd6de48f93f809c9614b0da9341d702d57beddfd633f57504df6dc4b84ba87c94c0611ce207a28c63c8d5564701a9909698fd9c98c692a46c9a5d16cde03c9af9f0d6c7d7e56c654923de2d43b7e43a7ca03db43c7eb118fc2b8dbecb39fde374e2c1221bc5b84846c41a4a6632888ac4d74d3d670f17b45ebe144818f6b3126b8c02c3ae46c2935ee99f42a32a0c71fcb5651189b59e9159bb232fa52b7574aa8950b7c30b8abe22df6e36accadccb4beec0532f7c744746ed2a20c72bd8ecb08956bd7e1132b823976b0170df0ee83459da6c032e2a273f763de374d2645e4e44d02ad27962f3718ddcf5be97206d17d606ec3de9ebd65e45866ace1c682a6be21b0ea9a6db0bc8c9a9c9178491a4d5d7f06001abe32aac6b4059ad8f21fb798f68c8fe997d0c1546fce4756db652f3f23c87ddb397479dc50b8b8a4437c5489fd0445bda369959463690fa8978be987a45bfb67ea9f99868d0434c34c7da94b7df39e1e5797fe47c88ddc037b7dc332a093171d83c643845a0225fb46e2a15bbb40f7f22fc0bdfd0476bfaf0177f3038381e1c0e0d0606830303c341c1a0e0d0f0c0706430343c3a1c1d0e0c0706078842db82e6b815e759ab1edcad597c18447336cd205beadf004a5950566f2b5e2c4afb080ffece3e8bcc89bf75e32e3e5580bc2e76b8acc567ede14e305d903acc21642c5a603bc1c45c8b7462d6e0c5d2162b6f4c07ad055f96ec2a6068d57e116555a6e32db8d0aaa1210e5a77d00c49f0c0fb412655a19db500be01f8826dc5222e308d211e66252c571287685ac848adb930b89d1c1ac7754620540c6a9d88abb49e5be1d2f2f8417b80dffec06ec88682a619963c703fc6b2741d47e95c21cee64bea5039295595670f0fe2895015210bf1d854e515782021afd08e622afe137a638b36cba125ddf84163a887650b8a570576595893c55e099d1b5119f7650b893babad62be328a7814dcd9bc457a379fef8ae6430a3979337f09778f47bb1ee3814cff2cd2f65db32cec610132cf633e21008926e1055e02a2ec074e6595c2c0881d4c58dbc956c72b7b9db36d8c722fcc8bf8bcd0f8fc22ae89a0cc001224cdccdaa90e7553fc2a09afd9249935ff0eb1dcc37b7d585b1262b3b013c58b5a16c48cfad7b9914acc9ae939db8752ff2526bcb495b04cd2b2c205faee3ce33ca1aa2d84217928e93f13922ef35a7535d6bec9b9e84dc65212ab2de0f06cd0b618cd24d07de277a5f0615b368343c9de78d829012ece7670a3fa26143f9d0732ec3b5e9ff5079e90e909bbb44b3d54787ac6acc4796615d473339c3f94bdd02024b253f9b29040955190248eacc8f9a605ddd022d7682dd5d513eb172e46cebbe6ac3c1ecee1a6c8cea182ec8fc4c06e3008736c16b48a0cc95b68dc312e9485632a2aa8615fd1c7ab5961b0a6520d00463c0d91024906cb315926c2d3f2c9ec1661d1bdedbb62306246dbdb522c40040dbc04a6999250adfa18c62feb105e8341ad8c339465350480821c0bbebd2d30040a82d23dc1b3537ada71132df8395fab828228cba2de5edb64c085e573d44fec0e88afa6669b8484c66976534d4de637768d0e6b2df534c71e68070e94b6ab07199e190054629e1fb1a66fcea4adae191f9970b85cd4e462bf48c83e4846b34e04c32813240154aac7599d6a2a67e9a9f7d539996416b14c44755df422d200bf547794f3bdc0b0b978f38741a7e9921a6084d429e04c650acf74f18138d6711a38478368bd00d29124817cf9c0247a516793c971745db4a3affb4554aa2ccb866290888ef4fa823c846cea847e543a6b7cb3f49c835850d008c254f2e9693e463a99fe7fa018b3e842b5ac767b7d0dcccab02a30809dcba203ec2bba9497b31db8f82cd7f3c4d88267093739d4b087ae68f100e8f866b723e70150f1a813815b9d6de12d99faa431d25c8203f24121075a7b6434a1a84d19d64148922a99042212425973c91596090a31e1a605ca633b78a74184c3d8fd2f369caf96b92143afea49e49923d3fed27bfd4fac28e38a696afa26c55dda5a62eece952a95a8b39c73d07c875c4e326ddadbd1bbbabaf8ca1bd9682389594b18c61c782cab209bdabb26d77ebe6f42b6378adab277a21792e63a0b1639232524bd16caf5d7ecb185cba60e3e7114f650c191566552c13f5d2bab68c41f4c0809538ae5cc6307221e4ec4557b4650cffef18adbac6cf2d63805f2f9ab6ee81aad26529708f35ac82e78ecbb7a2348cdd7e1ea2a896f465791179c9dae432351b0be96c86abf37f3842c807a3865b9e737a8f3ed16075885ab5a2aa89e4640af663013a0bd06c26aba37c681e4b1147014eff21bcf338c06c842c0044b2a8db3a65dca4f37789506b17806f7dabc58b1d917b55aa157376c435169ed3e5e51000b88633c6c4936831ebb248c298f1cb0f13d9fcff9ae076c8e1a5c02433303d64b4f7c52d996efdd8c5734e9a18613ab0d3021077586cd279e58cd70314308435420fbc85d5d972b173fd1294d2dcc9dcc82050ba5d9d025403647e121bd1ea947f02467ec1b612fcc52c5978cfc3f9d8fdad62bd9addbf6db7b1c9c6dfc42eb5701d73623ac0d99b01fa95ebc036aa000c77041056b951c8ab3c1d78099d4a5c5de691504f0fd6ca8c27ca6e20ce95c8af88cc34a82e08365c27553186a444cc7cde03eae04f7ee9df1b74769d467e412892576da0be784cf233769657b047f800b74bf6859d7a8d175e0ddaf41c2aa63c845a7264a8955e1574a69229b029358fd89f275a944b8f0ddd58f6267fa7c877a2efe93094144ad77cd4140bbf437bae8cb92ed2bbac125dfcb4de0b8e9fc5c77bc24521f9f575a8e338551279793e02009ea2cace8fdd3e5100992e1222b5d37c03d79c8f554a563363cd3e76956d1b4495c2215753660b293b316a761a129a73576b78269719279b8e341b6242a3a0736b61e36c36be5d69214802e6e568bcf32e4b7e3d7e6aa4ac6d4ad8e8c03c9c524dbcd149b4d5676aa40f91be627d36a364de295b7c5192e1ca9bd5a1dc29f566e4d85189ac63cd183215cf8ad847fcd070f7c96df76035dd273001b44bfc0eeea06cc463fba3934a8cb44ccfc656d9863c8937072b9754e7e515b67ce6ecb7ebba893b0c497183ec24027b78184da15313e759c1721a09422077d8f7e784f4f22c7307012539a96783b093a0558c38974661fa5254bd07321db884cc82992fe47141134c18ab2119faead513b4548ffc9153994da164216812c0a77694a025c70c432a45d600a97dde93ab6d8353dd2ad9d7590d82e56a586a7618ce00c68fa26eca4d01c384403da152b373f98e4bc1729b3d2b45869b97240ada7b08b5f55ab64aad0cf81b10389b18bf9cafbbee01bbadce3be30f42d3c7093e836e1dd432ff5614d72d2609edde08480d725422cff1d678dd3ad5b217f1c47b535910444ea74365e6f51a86ca336e00cbf0bf9ac544acd4bf4a8f77bc918854f6c198f9d8f905cdd42aa54902dfb8aad666cee77a4247f6b95009f9aacdc76b9d77da0cd3b5d4f8e27e194353939b3f1c34eca81077d66a32be1699f666291ebaf4575ab3c99d60e8bbc472e0ebac9011a445f3ce31a3da5e94cfc5506a24f7fe8e528d88778f6dc5f504f792c125be8bf5db839f1785779d6a541e1a3c345e5bf7660a23c9895e7b4205726caa73691c15fb16f975166c0e664e827c89404afaf56ebee5424263476ed9e109a8586888f46f632b0b145e1b303685a6731e3252000b9a42671ae237426453dccccc99cedcedf605bf3e0ed8a62d32cb1f479445f321bbefbf4916d38364b057a6d55ba8ca8f243ce34271df3eb624c432e2ed486808539aa66ee9f3a37a3e3c626c488f8ad903954f61485c30028897503517792233daea57a69b54c18b168510e923626ab62952dde34705eab8854c10207e6f5804fbca0e787defac30f334d8af10f7f284c464c8a2e02fd8536e8bf28f18e568f165ebc371f66037caedc2d3043db3fa9ecb5077c6fffa0dc5619b645c6dc9137a0180be6bb6be4bf748b6e9a777b14c546037ce1a7c7aec872cce5261ba396886102ee0462eabe3bec910d8194490e77f0f6612e0cd23801316c65c7185eafd6a8a34f07fe66e0837721feb8c18c3284aef4414feb98f8b333286b935b89b4d2d1280451ca59f708ceba1b2c64ee03d78a8eb4568e93f02784ed62770e09f0cad3c2c91f40c35ea5c919905131f22363cf9b05a868d3eed10d13d0ac6d00ee702fac73fdf4b4db3f63427efc9c122a8cd3564f9742b933cccc42e95d2b73a63b1011035c122965138a11f4b10743b5cc7dbc2735dbfdf9a5146e16948a4e5bf80c22006c05b462524fbc09a2eddb9d9d52f1526ded2ba68a502947b2a82b8328e4e68abd872828bbc08f2109227b16bfe74f94aee28fd8694fa042da39bfe52223e71cac96f0283084ea5de4629715407c04327547717c4e418327a371e8a2b552160557650a996a18079d968082b07f552c76912327d6135c7486d2c18399d585839a38cece2383ddc5c5e0925a9fff5460f750a2904b26db7233f8e055b9f28366cfec16b8a4b144edc4730cc09017380b876369fa83746fe8cb2188821b91f71a2a06779c182595875d697625720770bbd1fcc3e2199263ecc1fa71a83d7acbfd4bea4c3f4ee71ec803a35a9801790ce20982992bd008ca7d58d28ae67c5d0355a71c9ad1cff0e60b345bf489a0a2c34ec34ca7275240dbb35b2b1e002daa69d32da9aad8f3768f13e2637c445a3884d649a161f06dc80e98515e40d6ac0c6f16e58ce3dfd7cbc2b100e751754fedae53a0a5cd8c2e4b712a9a5ff91506f3917edead60bfd50164791af8bffeb4d044e0b5e83431c6fa6d6dc1798c58c1a0363b5a0f72ef8a7767b760de139731cf1c2b555cd2ac9a277368cf4410208ab9991206039ac06ed67632f527a0de65a39942718753ffeef2c63d64f8911982eb97244512f7c3b58ef7a13daef9db264a1568ea8ef6b6f07f2a35054c11cebb8a2ced1fd9384fe753dd7e9a23551994c15796ec0ced652eab5e5684e91c6b3d1b1a12e7c6389964ff1b7d924f466f33a705127dcb846f728174b5742e76debdf6ccc0bdcb41fb27f79b3e95fd0def4285ef8988bcdc4ae74c27769e10e230ebb7ea94fb78df2e5050e6bc4657934703c8e7e5a81fe29d16684db3ab89d456e70b9f75fca151f6ac2337bb663de4392e18e9dca5b30e5dd57eced891ddad3e80c2344a729eb028071529ea4a777835127825f652484e6853bf87c286636fcaa05b740aeb745a0ba0506d691ca8889be5f57a87052d5ba40793a1889902295d250d5b1ee212cab0f97b083f0855b02528764a9c276313866d4e4e1d4a8a93a576185ed49e5f3f1891963410677fedb942d81a98915203dde2d82ee8bb13e8e50a4b69997c4d030d8051fe3668ca43807f66d9ff9218608a671d69b432c17a3dde7cb1c9c1fa40f65852e802bf056972678a953fa625d193fd6aa37df1bb4ab67903928f838b65b684746365ce45172ab809bc42c62d6ef741e900ab7611b6280d48294f4788a965fefe9f7058a7e18f46c741b8f58a1e34dd70408673424a2fb845a253ad20e90d5233e9ef10ec61d8cf38e986a7e4dbd873424678424b4cd94f32ae65916774e5d8506f2dff10f852b47b4713f1cfca55608ccda486057f56222a29b72e47ab114ef265e99b56696e49753c81811c68d112cdd091b0bb44d1e696f434695909e9de288aa2fd72f1ce7f80551961e3e031f318d50c24bfdd95a26952198495fab98d81279cb361aedc3397c75641c50d00fa590e7b68e633df93be30d5db9a44d53a8b4aba392b8e8c827c63fd58e81f1024af32963b1ef4ba47a891b2e8bc81289c5e7032a85626114e7e0c311a1a9a54e24f550181c61eb9de43408b07d991fb7c7114f3fa8171d46175d34199bb14145e5fa9f1f88ca0f1bc2d3f352c08b1e0523647af6987368204a9bd29b346dd88b4a39769e0f620e70151d38c7d7647afe1a39c346eea5fe939539f67ce54adeef5f069862860c96b153b0c0faaa59d8eef72ec0e5680106d13a1b71279e024e8afce84ef7473495e76f190c82677d9ea60a062550fa7ef779fb770301d6214002a576cb4146788c48e6c06f2bc0acf150f90518e5f72d3745999fafde8c07da37bcf99f0f324b8ae0da3cac03d5bc95313c154faae2498ca30099d0123cbb457ab044ee727c5542a5a7d1a943cdb91137823538bd1adf94480b4cb6d9d3e808cc8cc39bd00051de6e3402df91c529700ac6a883926f05e0f820aed093148c55a307e95356d5dd1a1e24e853ee43d5f5996e57387b5b8700356839480bff7c61ec1e4b48e48fee846db3cff5992159be562e6a31228f5e4323ca4ffd3b14c6582889dc38c148238ce0d0bd36e169f41a4118ed980ccab423bfd7810b7404f95daee539de1fa597ea83b8c4474422fd11fdc062bc76f98ad642f082024e1edb379522bd3dda6324e9ea53cdad06eab07ec8e9e1255bf81769cddecd11ac7d391a45c21296c482b60925c03b3801b68549ccb92f30238bf75be5cc2cf8261881454334b1de9b4391346a76bb1524011319411a37af348487f0e1032ed773f3b7be40b875e2b1271e0579dce3bee3916014bbde78fcd61b54d16c936c1e48538ebc040aa7f9e62becba268ee572b5ddd291ded1ed95798c30665558e6480f673a6306432c67b6c3e9ae28b72a81c5fbb01d18056255e75b83699591e20faa9c49b0358fe5970b360e5022202cd62f76d50624e03537f1bbaadd04ba8fc49daf2960bcb8a4620e445744c69f34157aa577723fa7f360a45c10e891559c5c2e1c85e5ebc5407bae44fef2a2ee65a8e7a70708b12b93b53c1309aeb434890b4820adb5867d15446e99092e02cf082016fec2883304bc829495dd8961f39f24ca3c2536e666ac581aae65e624ade504999f21296bca7917a49f3c408af8229b79cfea7d0ea8c3dd9c282ed24ba703aa3a327fc3d0c53be4d404c8e9703ea207e10833bd17b964213016f1fc26b95db25ab94b2e722dbfad3b4267666eafaac44625acb448d0b90bef03975e512389eb2ccc0f5f196d2b3d3a15ced5e0e7eb5969242b9dc72de9d0e587ab715be5af49382bb8f8440873bb383c77fb2041e6bf71f48f158cf1bb565237541fa16da8ffe3bf33ab00bb38f4e7415f7df37f2803cb19eb78890c863fe713efeae53ebda873d7022083e5d2935e6a9cdaade575b9eb0fd327aede1ff928eadb2839e4414178a94163a37d40a1ae352ce84f5bba60070c92095dbcf19ab6d912ac760a116d61c67558f44fa818da6c126ffe85e995de0a56686545904e810e93ce8dbb66f63d2fa4422f69e4bbf299593726451ac7cc5adb1c270ac69d26a21223de35d9e407448240e926be5d4653561160b6afbd91390b0742e6439c0922dcdb5cb05b5f462e03d25941abed3899440f5930b517c4b96305cc08f76a1c30e65a084db319a6784da61a4bcba77663cd5b182ae2a9b136e06e0479c4c1b70fc2b46280fa7c0cb0bdc230d17090e54d952c12e0bdd9a9aa06441c11c2fee83c8d0537792d300b5fe494685e9e4e5639d3b47db4bc6d77bdb80fff266f1278023a1fee9b843295f32bc3181052dff76429ec69f278aa61e3c1da08103ac90992f3ac9487256ad601b8ef8c5f3b60b56ac76686385b65c6ee9f11f5e319dd7673be266df90b82fc25a82c7e20fea929b21212f49ddf0a94ebc6601e21753fc0f607601870008e0058d170af88c2bf290afb92641b691c74d84cfd871b759c36c2274ad88c39bf3a028e76f6cc2c78fade42700701c68a1d532fe9ba47ac5c741fa9fd15024b0abd535a6862d0ab04e7c7537e8578431e0e65cef54a3514a898de286884dd2b0237a23098d07ea4071ed44bf3767d9f3a335db6964a0f4f8ae6bc4cd01e498eec5ded115d399d51672bf18c73f2162fb40bca548965f34ae49dcb450b4fe1649a1de22810a18f71317d1b1d475f7e4003ac677b1e996f14c2e180b921e53c904b81e4fd26620e209f16cab9f299daedba19168c473d4b7d51398e75fc508a03ec5ea8f0c3b106eb8ce12ef222ad35a3ce4bb1db52ec30976934b025f2a5bfc08850641bdf8cb7704f33110c5a0ffb29a9cb5786d38ed95b724345292967f6000b138b25bf7329e2bd143b8c8ee3dcd2cde019e1006985711c85de63ddb504008f43d1cbe621dfc136600367a5b64e4961b76cac399876067b3b78fee237eea385bf120f4b9e66bd1a69064e7e4395bfc44930f8763b734ca54b9b85703c5316b2e512de93932b076d63fd8c6009bc649ebc4e624e114f31ddfe1207bf8b9efa935f759e22f075be2d4f7e394c1bf906f029b007350184ada7b9a51dfc7846d21c886b742a3b550c05266d1aeb046d77d170c4fb9694ff9562af61ec9798ce3ce2593e6eeb445e60cd5a451c723b9fcb761ad8f9d0dac7d1d94b1583df2073e52db626a799525f342276110271035dd3b03963d08a562897e364c612ac35d12ea29b84b1c9379fb381ca17e095cc08d458ecdcb89c1239a17ce5ef92d87d97bfd282138f604e26daeaeedab369ba52e311577a0660c80b890cfd7ed16710356c62b0a93aaad9509e66172d9efe6afcf00cfba9962bb6aa04989205d20a9768ed328c7c6f4423a848bb54f9224cce3b956f0f946443ed06922734822592cbb9159285646391d9fd145762897476a6146811d97a9024748fc5fb47f47ebe32e872cdb9ebaf5beb79d8a2255e9b69c0043a90d65f14242c2b26bb2f3b3586782669d4f266d41b40b9e9ab2b2736ca5174e4b55db6ce6fa6355b3507ba8a1022e8cea2f1ad90d2d6d6818a0f2bccdcdfd539dabaa21defc875f54f36ab8a50e48a0ab6685873d00bb88542c57c49961121bb3d0d08da8d8ae05651c419ef751930a3a0564ae16fbe2bdc475114d12bc9ab02be8744f79c665b9cac3eb5fcbd5dd8e3fc73ba9628022a3ba8fb37cf2b77206f9d38e4d09e7dfcbf32fd8145bdd5224da8c7a08790ee2d7069708a0310b6256d744f6b503f3c1b1f00366f71f16363ed56d666dcda3dddd964132512fc707c152b74a18c52c5a12cd5a34133fbbcc66e1b9e686f3b0d83be18e689518dfb7444cb0b2bc78d6322cd6332ec233a100440ae15e7613d4330e3a79a2254cf7fd808ea782b1095a26ff2830a4b8cd1c1b5435944173b5acf45cce13788f209e96183a30df2733fb1b1c513edf728d799c745665b4cadf197c7c018d869e9e0bf04b564a09270e925d269f37e25f167490ce8ed14b4ddffa4582141fd96473a1768b44fc232a7024474a626492df35b5adf2bfb014802012b37e77e8d84e4240a2e5b3d2fcd05fa360a6bee1a846cff07b1108bc86d71431db95ae919a6b7d85ab6c0ab754143ad3c4751f813ac92582616b8096edcbdab43d89e4d938e24a216ae0d309da672dbc706cb21e9fc8c5eda2b2ec450a68ac9cb1e1c0b5a7052a24088891c585cf4cf074113904a16dc2709310e71b6fdf39fb9342eadbd0e277e079a71aca4f43ff05b1063b1bf3e662840d8b9a621e59390339c4e4bfaa80bae1e89900010b6d47aaf1b0d5c1e4e0f13523edcc6ad887ea5baa70a79d58cb25b0e1cdfc8dabcee990c51ac3996b4b0941d5abbdc08b96b61b5ed4ea8ffebdf001b5638bb7669c1af50e0afce5acd2673864a1d9a89fefcfdebe991a52d809cc9731b939c6a590cd1bc2752042a2447e4a487b40551006f8ff4248171d15f1a0a42c8c0d78286420e78cca5a571cca5a745ca1c1380f5e40c244f49910c62a172a360638df8251d3d40a659b1673cc57a0d2419dc8d241c1e6ad5853578ad2004ed126f888c38a78268a54b1c50708f7c75109b70b287e07848133735af604e5e2b6ce0571209f63cf51602932f8ec886a98c6a5253de3a16cc68b0d57ebeee9f7adf9f075d011e89cf04947714d22e492a57fca994b99f9655764bf764ee10c258823a9d0788885a99ab86e0482178b27570033592de4afdbf6a45b7621a28d28d84972e8554fd6671f2ae4c840dbd33bcb2c160b0a7030959fa09438c63ba32c3e699dad00e1c869f1ba6be72982ab61c5e4f1e7440ce3e661120f395e768527ec235dd6b692b9778fc9bf86cf909ae9f80ab40f5a487f2561677e3e58ec0b92b7a861c57750b20d3427faae9232e53e456868323ac14ece0d51d234b1680662e73822b2c84d3c97306e952c36e120481b67f234bb7acdaa0c5ffd52d8c24a176fec31392610e6af8f6ef52ad5c03f9f6ebb200e0f2ca37b9f1964f8e93fcbe9c2f5017d47bb4bad9ff10ac5de195e702435f74438b9faa13bfbd28d540420bf82ea66ae4525705e4ae0844b6ae862c5855c0bb4a67e059b6c5ac721aad24b7ece44e16aba1fad43154cec88ee2082bbcc8d536f6832384745c29b31cf9ca594b32020a9fbfc34188ffcc4e61d0a093bd5ad5ab7aad4b59c76ae84004cb55e6d2558e863172d9319afa1d8c3b31640697a9d822a88fe1a5f0e4af08e7a17ca92a4f8519b9cf689af08fbd622cc177abfb8d0da4c58e6fea04d25c2b86b663f40affd786519f32ca9cef26396e8cf765bc09630157baa549995ce645ca5af54c506ab17e9a804a2e29eabfa1955028abaab0f5258778108bbb4a057cd8b901ce7fd9f2be1f159c71d3d7198f1f87209c9ff619d005c0f9432716ec30fd440220d8b78c70801719d930bd341d2a6dc7f4eea974c3e89ba5dac5302c794462acbbc6b97f097f7c2a0e7b131726b9cc929a123a2e60bb0408f1ae5719f2a691e36f6c9da2027c0d085ce8719c8b52bec6569ab29b40d0cdf47f703725f8c9f4eccefaf068867540890fb8de85f25ef12cbd0a44c443816edaf5cf4445c8c6d0feeca9a54b1237bd51babfaed41fbde9848bb6e75b988220f954f2d3a3288c264e60b0a3e59ac6c4c7d0a90110a30bb814cb48c84af3d5c0a76a192035892f8d19850a6c79074521f27cfe7ce31cc7cbb5e7e43543190a75b71cf1212869457f31fc86a9dccff42e2ac76b05d96c42d09a764839aac64ca98fd40a42f3044137db99e2e3a67652f8d0dcee00afdda03811a9fb67db2cefd1ca58cbffd1e6e272d7c5ab5c22414af5026a236f0e89125e9ec9a2dd21bb2a0d22ce331e6d55d62f4ae928bb2b2df94fc536016b61074e60084f821ad75bd7213cc0ea555369ee0d544ff1e83fa22fb60ebaf5bb2de1d55c28185e718b215fcee1a50fe1bd9808de9900d2109e26227dff4419720835e800ef16df2e080df0564f5421056f0469bf00ef1345e78a7b2fcf05680568321d16bd75a72f158a81e85ead2359bbdba6f59cf9a7e73955af71f547e0941aac0994488716c011e6c6062691822b5056b1343dd2ea20bc57af361affa225112eabb62ffc73a4df0f221c016c43619e5f04d2ec26f50995058d1cbc045c978c3b69f660e4f9e08a7e7100ca586da4c6580f38bc0b6ff2d70bfd034aaf6eec7b3d7832e4d8dd3f9e1ba6c8e021e44ccaade18cd9061ad20dc70aa7de0b3a39dc9e28ae00f1f1600251cf78ae98b5c57d140e79e9fb6cfb906eb31c8f4d8bb874d42b0935682787035bfe042edf7238801425beda9c24353dbd30c50fa101b292d73b5ca5fcdc8e445c02065b8f7887abbd82dbd73c9749f2c0e142886b3cb770237afaa9aa36d280efd83c70fca1595a7cacad55c827a61b2af74b7b9d2d272b63dc42003f1cf44271e6a0f88bd30cc4c1ca5988336bc7441c6bb86a8cbeb3f37f267751f3775078f1dabdd9adc825bd03124fc9fc015c4cb4f5ec910942e817b0ca595f46dfd8935cd6c70afe92ec7b743c5700f63fef905b3a65150e8cec056ab297148c82f78bca39582ce13712d127ce24c66a562d0f8fccbbc0acb43ec9607efebfdc7c42430757eae0f54c76a7b2f19abda885a18846c0d8ad020504da04fa8aa91da9bece05d8250cde67674675acd665b90e36b26882c20441779d904b60b5b933c47ea85f2eae024fe2b619ebbf295c4b0f8d2e4cbadfa229acf2fdb978bb1b33d06d0feb9b2a8281d0c53474f70e495a9af04f898e74097fbf34c8d454e289510ec981ebf44e195b373262875053052e149cbde84e74f45c6f8be96478eabb936637c4f29dfbcbd739028a3af1387eb5dfa3a0f77b787c84d31d90dcedcd8e399e96e9443f372e7924b0e768f569f760ff435753a0383ed3877ec701d949b96d44a42a661979edaa52086e5045f8207ad2398f1028faf31d130696e659d37ae8a11f10a349f9c1ca8b87a6ef7b1cae7d93eca9a53ea0c835511151aa9c1db8a7c90b8e0601eddd87bd0f7bbca337b5973253abea4e2ec045b6a0a96d62da8100af65ae3b953141296f66bafbd9fc743a8701cab1b4812f14d82f8377d942365c371188a677a378b606a00cb265f33e3f538ae38e3c5b0f446c00b288259f10e8ba9e0d2be90467810cfecf8eeeb3954445d79c4ddb60df97679ddad690eee6d78db6ebac7ec14625ff5735fd94422ddbdc4c415e3c35488874168057036005064cdc9e86e2a11ed3b0e0e87ce845ee05bc93adba31aac929f01a89cd1e8278592881bb4e81f4551935a3df5836568185a1643536f2e2838b5792c437af0a6588558edae1863aa7cc905460ddfd23406d894d71857854680e80821abb02f5c459ba7e10a65595b573b48548451892d9cb99a28460ae7d4b97c1945311fa833b48de94826d4be8a1a048432cf375a7a10abd8af56a7a03f4bfb52139c4a1f36afc5eea50d89bf3832ec5516f8ee56408e3c5a37b49d065673ae843e8d418c72dd90889531a6381d1a9eed20506caf094f88509190c44b75cfb9cc72ddc87222b9827a5e2e5ba643a3e55d394d31984d0d5519ca8a8dee131b6c8b1cd05ae6a6ed482b6c2f3afbf10ae80c98292b4273da8cac157db8debdc1ecb8c116f2a510bee669cd438ee15c77261e1316f57734a19f5972a8cbcfa3fd8d7ef912dfb1d18e2cda5d16ba58f086bb7c4408036237159ceffb2b913832ffe0f5c129aac2dc9a02b8a05342a00a045dc9bc690994cbf29322b47f9f668733f94c47519ce97fc9df2d57cec9e34448894bc588222ae451c908b16474c9ae92c0c78c81e2f4f71992f3d6d00d3bf4a923021f38ae131d6110e8dac7ccd05dd778b757a437794d800bd42b152408ec5461b5665daf0f6f232bd389f7f95aa7ff0921e003ac596f2156391ba651a81f2ab5144620c7b6d39b3d2b58882ba3ff8c23d10691bf0469ce536a024a08c69ca8726c44a40386ac1c12e65709dca92762c34b13f6d4e57161cecf0e268f912483d80de057be862e4944670923f35ee644f5c120e1ac456ace3131e97f265a62ee48e9cc1ad34d10adec10d8dc57a5b7eeb1ff336a7f02a219f42941e4c89470d7585019de356e1aa65bb024b592ec87800f40fed2385e4d7678902be8ba69bd2bff8c921578422321d803d2e57cc21a70ce4eb041231632fa994d3af7024fe0898cd26097d37764ff9e56b911ff8257e4bbefd7800b2ef2e1074619d2b431d74859432c315f74676b270dc318a1b81de1148d105de47412d9de7e299bbc687df7a7e766a434733fdea0bc4938695fcb87a0616d7f7c312568cb9331db2013c944952a61b59c96fe7b1d65f7589daa8e25e225f8672d644b324763a4138b01ce3854bb019830bc349b27d6759ac0eb4a43ac141a77540f7c5f36b4d7814fa9ce0ba031a8482302371093d489b9ba73f04591ea459b6bf80f86ff705ca8a79ab5a3eacac804d2fa548f7a53427d3345d9bb97a54eee7a912876f287ab75fa1e85f7155b11b91a979b90814343eca592e7e37485076faf607985215d6ced15492e2766c81531adf469a0e1a74cc1966e05ad4700ca52ea764e27b03b8ccfed65224896510f45d8b587b5501ae617867da13056f93546462aa6051a4ace3fb40511e7e90f2c6c9844769e95fd36ba1f1a5d4f4eb6462aba7dab6801cb3631617c0ef75ab3e0865ba780c7510aee0d9b4d609a5b5b2502153205ab03b0543ada1052a85dc30407c7d7746704cf0f2ebd8fb765d24f230ca9aea0d7a0a79bf3d0c12ae039c8199f5e0f6c71a83c2bf266c56dbcb23ebbfef5f171a6383a3daac25bed4bbf68a7aff32910908082995e2ff4adc1b8f65659913bd73c2a04ab2be8ef402947c0a87d5e10871807db73c4279d82813ec9fc3b9cbd3dfaa8183ef0ec73d980e5262cab77e7669d201415cc4538508bb9f158c1cbf560071beda694415d021b9a673d2fd6fb3a7f1f4dbaa3904579c25ce5d248d44f738998bebd82b15700c927d8ef5ee35f30b3770db3eb01dfd826fa55d27a7d03179a1d71ba0a745daabd28786421e3a9f9c23979d29dedc22cedab9d18e6d0979f6306863e49a69f4ba412304a534c95f4d71c6f5b1f22590b5ec6886c08082a773629e0480c044815ba26db9edde9759cfd16074544ce9f36e6f7e51b3d75254e9730bbd1182fa9c71be6b7dcea8e19e9b59ad17e5b55161d9f32c03b9e6bc775992c6553070a6b5fadbe8130ca9ccbaa681900b05707a614316c2df63aae32202765919166bf34b72a4cbd2dceb84cc4beeed3f618020e3b14d61c2744889ff37a223e2327af8ddfb105a0792fbb7e626717f5906ea0fcbde7868e21b56092abb13683755516fe5c5d20d132ff223d23741a6af4d459e6a868265bbd1b551f838f881bbb3f968fab2d15b2f50750fb4fe311de7d8f6d902755afe938c676230b5ab181b2ea180c93169632b2c86f0dcabe5280cec86d11d3b708b80d91e9f21b5c32c608d4c886a165cff5b2473b3d91e3efc5ab2cc4e403bda054a9cdc0e751020ffba0f96e70f823abedd323ef31420df58e6b608f367acc696958a0b02bae0f5c98ea3d0abb917749ba8d359cebf4e593598bd893c6cdca4b15b6eaf264e3345c60b4f4157720f2f010cee04e3ebf1743b95e407b13379c3dfef788eed2edd2e3919f0453e88f0f6875d0a9df608ca38c23a3e018e029cc7d02e3892d582583f2f49d70eba31d88b69965ba68d17cf4f83b12e29616b9935a030087802134a01329b57b2a9f6794fe3e1635b8540d1cfb8eee4678d901d21bdced8d3b7e5546aaf1d549623a33ae1a7e382a3344117afaaa84843118eab457e8e01fc7b14c3e4f87c02fb29a76a6d8dd32cf99161e978230cda77ab16334a02f7a21241e01f1e1f76e3209b525201b9eeede008f04921998f1a1679aa1ac3535871959a4e4103fef91deda7b0c53d41f826190ae8ed4f5d2fba9bc179bb398ad3d789c2551177ce421dd41bc14e631377482e759dd5aa67c266c7552bfa4047054f3024c8816f68d03da1290ed30bd0880849fd1af55108c00b174d7674b7d9721cc254d28e745a713179b1d5c7d117e32eb43110d657c05d41c7b38584df2bcd7334427cf40a803415d0124b998278c17d47122be3bacaa1e54b0a88e4231d8c7b24eeacc6268f670674fc62ca6228a26a8438fb53d9249f1d2227c21607615f5a75292cecb175417a45ace00491865fab24e535e358aecac97bf15d87d2344a6a20da860552141aefc4f8cb074342005e24885c6916d3ce73f678818ec9fb9481fa23cca07d20d0461c71e6801961df5bea3408eef520e18241408253b88f0b031f730db48e1ac2537dd00eeed5d402097034f9a8b7a48e3f8439758181a33a92dfe185198681c5a4de3c2e9cc750421ec4f1a2bc21f0e0ea1a8e07995d549fc66ea2350c8285ba163642152593654bf69aebd45553648e3b597f2ecc24ac35302234e3499b7e548f74f467ec24ddc8c464eee3d0e66064676e23093d986f5be8208af8eb8019ad9f325a145407f154f310289326734fe56742f973ff1c1088aaed4bd5e91ad314c27028b49ef6b088cb4098c841ec85a22e3a521195fdc7ad2f6ddcd4d8996762cbe768b67c766b96be813862809f0790086bc63f2ca3294f8a288f052431dd9e8959a608bbd995d6fa94c1395cddfe691e1ddb18da6ce3d5e85f16f687932ffa231a24a2072b0bfbd523b59ed60a68151c65309abbd80e0a1eeee7834d1deb3e29ff189f3c66145973f8738a23a1e34d26ab5c078e3385ea3b6dee1874781abf74b22db94476669e31bbe0b0784aadec2c505550242cde2437093dfcd205609ca4de800271237be2ba70675256d7236d65e1e87a2f02f28d631f7210f1636451e7020c8470b6f975ca5ec791f16feeb6a4626179211b2efc455bf508b8e513ff6859270364c75c7297e3ce6137f5e75a01b35d0f66c04d60ec32ccaeb74b493eca0380671378fe61353ffb9bceb0ed80a154f667cded1f6c1ec5ce996ae607eebf230d0965a16d41838e29674411c57ff30bcf8e5d33f68921261abff46feb70f30d9e5f70ac8c71547ed765fc55ad1ef95798856855feed425d74402aec6f7703eeb45ed81852b802a399f2380d7dffd3b297fdd7a14d7b7b450d598df84093676808a6eda987571d0282323558333835975d50373224e822764340171c319490e328326e6b66c0fc6926d05f71947966cdafe92e5733ff699a7fcffb262ebbe61add14352a60055c6832b8044a3312115119d4628209c9875fa76bc4935596a2be85a88e18f120f410ed705dfd436e7be4ffb0cc0bc633efc200d33e2541ba1ea060091b87b3a4f70352c6e05a2783323b7107266053de5be38f2dd9e9ae1d9500a93c88a6c765e794a58fd50d2fb42dcd09e059b0769bca8ec4ed83cd3e9a0a15d9bbe148e822ee8640171d35c4dac5bbfae5c2a12690c2e710c0de015ca5119d7e5f85c1150474da8d7f61f05ef67947c0d5a0a3e6f43b740a6d0918245cc81a309ee190e79f18368479bc0ca9c3466573f752bdca823afc225d78762c11ee1c230788e769561ed012ef0f16f919098e6f63c04841725d3ce3da8164fa70360e7144d89f1b301f0b464758980b2773d6d3775a865b34a1a1025de280d30d289bd9fed79223d5ec87b6069d03b829e0902d934115ac93642b95097a8e9fd07b17a5846019fca303a4f659abfbdaa36cffc69a5efddf367421270a7aec51378c18edce71bb78a9dbd710f06484aaf43cbac0f7656b23bc68b375b7af89989237eaf720220b5a8131a2aa59a7fe07d0c2bae7d1dc1101a9c0d8397ec227b81c0a2c25675283df23f98497edd78d6777b7bc7e8335831ce889f6f0459b47a455b4466220f7bd4a2294f99920145a6451835b0cba5189dd91d655492e5650aa75bdf8c468b6bcc41aebb8bc880e83c16d436f57b6ec2bca43ecec7160d6fe11297f8fffccd2e786b6d631d1e68d68c234d9b9a2ea43cceaa3d44ac5ec9ef55770aa47e3742dbfc0aa10785abbdcd5c3b518783251f6652d0c3aaf68d0d85693d383c19e7ea862a2f138c4a150b4df32bd5486a718e1f408863ce644d2c02a541c40bfe32f712e3b267f1f827768598eaa0f8af9d60b90d13ffc8bfa737af534d14aad0d015cdb84d4e764e0ae226f2b20dc2cef9810a83747d6c8bfe74192bdd77b1872195b11221cecf6a0e7f0cd61472414e0e94b382a9b6321976058ab79e60b473408515812ad86bce48b64a508562e22b18651f5f2c80c4175b98d0f4f738912509156df95f0e4eb1be3d82e38a01c9d3d099039049afdc0d08917b87ce1804039864e2119995e57ef7a2d507ac76403d2120e437328fbd231a70612aff613faaa6ad1a00e1426501d847bdabbe9de6e68d04a476845cf6b601027a303ab214c987585d8c1fa15288b38bd7e028518cac96e132b31b0a851d00ad0dea8396334ed43861bfc7dfe15b525e3983419db62121df8bd42c5c955ae6da3ea4ab11655cd290707b1e6a03c44f52069c59bc8720985e980aae9a8cfad23d47a02381a3c4a0ad0e4cf8342ef167338da217b0ab7bdbcd50a75484c5f23ee54f9919d7cfc7e4c7b424ab8cc1635c2c5c08f44f76814045ac599e113d16907bb397a8466f8661399ac7bdccfedf797a3358ffe8a53f96efa5afabc989b4f8d42667c2d7d4a997c03ccdcfde5b2a464299f401389877b770dff5be4b57405ffcb3e191a5148737be4bf66ec0e5b10ace663c7805f0b42cae4995b549485672d150c8c915d8f0a1ec1f68eb7d7f0f44244e3593036740545db58ff4046981712b2a9f5b34d1386a27da6892259ab97d2a67623ede56e2c1f119a60bca18c0db21593c88b142a37ce5467dc5389f46726f7087a29b7028b3db4f0826b69fadb6e0453dcff43852961b036cc6eb7e0fccca1f4de16a2bbaf04e42686a59f0be9f7ff0a015c3d255e70d97b6e237613f042ca0d37ca53149ea525cac962c1bbd3e489e96aaf0c839863d73ce2cabc6418cce0f9768d84d2bc74696e64b8f728729c45a137875088d76b896b6b043d8aaa1a19f20935ecb19d7979d129b710777ef5e55c5d47d6104ada92d471411728a4a0cea72fe965ad1c6c40e325cf1a9daeca311362841c1eda4e277a0857527ac424224548b0bc59aa3d817c612dcc4689ee0f58856c7d5cd4b49d1597e15c500ed876c7409625a8456b7f6f564f1fb2058e920d8a6ad1f6b761b741facbec938b9c411a10ff68043633fb7a23e1c31e78b09c51e41ba4c9b5e8b6a5954d807ff63037485c40d1a1534ccaaacb4e9ebcae5b528c7105393cf19d39a6a07fa3d87038489d04b33636afe9bc41b95f6c6b7ccf601394f16430826e8c30408ed2e07b886e061990ad3c6dd33ba00f75903a044e83dc2321fb618d823f0418cab72da9e8b51d8364420ffbecec8d612e9260f2abbd1ab3be950e06ba3189ce70e33a2376b5b58ba01b5a90d3cf825412fc7ce96898858a05a9a77ac455c12bc8e7bdfa8d7d642df4c28224e4961c777b0ab06c122166a80e6126a4a4f104a80b100cf4a97731760768296108b383bbed4efe333e270c340d4f05de50a3ffd90d8077f6c36b2955e12f585ad4ea253c3069b3a76a758d64ecaec707779df93d2645d9d265927e22562700ed5f238dd175d56b030a11f182f5baf131c0e146e275949fd9f92a1be1876b7a1c8b341c953b3011fd958a35a94154083481b063d26a2896bbc8cd4442e41e84cbb70fa7e49d5aba3483ec6249ca64ac2d3f245d1e3d18e281c398f8aa98412ba70c50aa1e7130aa9ebf9cc1c359025cc1cb33261a06b0e546ab65b725a7c8bdf71531d549b4a3a2fe358ba7ce1859ebdcc0d15068e81baf9f12099c213108608a2f4b112e185b093795a7f5574531d01c329675a3859532cd30a619bbe3affcb800738dc5add7af17681baec4edc14bb00eeef857675da8892d6c636f9fe07ab72c2fb3c71ef7bb702ea3a0609110c936845b96ecbdf80d76b908e695497710afed717a7d2cf3bda40eb12aef0bcdd5939d8b86f501d4c49523b48e629ad698cf70231e65cfa2a25928434dc306aa975886b08c3fc50f1f5cc456163b2d260eb4b79294b56f0d917c3c97039c247e6fdd0ffa16859b1675513f358f6dd132d6b92c59a184ee6488de53faa42841c1e2bc68245bca20dc518c7a18aa80d8674b802f96e3ef46b4b00e8af29228f9d332fae28a2cf238d516ad433472b340c43343966e8160cef7d46bd6e297e40aa2b7e61e7039dea0a6e5964bc059db32b775c98e29b1c7fff43b84590b5b7b3e9cb7daa8bd399e412baf4f338a6d3107744b47e45dbc5a9ed8e7341dff5cb60cddac545266c50fdcdb35bf8d2daf27c5e15a84af24c6b3bec55c93f40827384224a640d0c220c2fa8c15ee5acb437dd0974353f6065c44b6e7caedb6f8bef1537daa08e566b37be6691169db6b2e7928f672887d659f9e55af4584f51bfdb21731f49b8b6bcb676ee1e528f2488dae31c1bd6be6634949d96e2d90419dbdf40bbb591d9e475c91bf6e3c6cbe1d73606a8998e1d86100d292b29e17378255a6d84da42833c52690d65360f8ec6b2192be512a57af780aafd8474015d7fa3e6c6ab897d8fb1899e63f1a0ce0fd72381a3139d1a54a92716aa62456b1ca6eddcad338a30f3b4dca23ae118ae371d8ca7234810a60de72363b380d0494b0cc31d6e1139a183fce07b0a2a0487bd8b0a70b81a249c3cd6757f9df88d297ad9bb5bb5b9ff035c4884e62d9c677012dede1e23cbad2550e5abaf78b1511ffa9bbad5bf0cb24e7d4b5c052bebab7cc97aa61b2efa59381eb7efd261832afa9bdbed91e0170d551eda0c5462fe284ee128395dc66da45a4bcda0571ed4892436044429bee93c916cca3462061a62c9b134fb4d97cbfa78cdf01f63c3f3d719887475003af321ca642d52edf5fe8ed801481c67c94433c5ecce740f871847a592606fd42782d2033def436c6ef74889e15d14ecff21bad26432824c4a72ef898585561a62988c1ddba7954a8d8cd4758b383607f91630310316993af87b830f157bada0abd7c334cb379e4b7c79c6f66b022b7b521e420e3302077fc901d47656b2c383bcab57dd3120081c3681bedd3a81a3dc05dab450f78a997ad4cea4f1293cee32cb4f9164d0e589ef94d74f4a6ebaa9d94a6df01804711898e9e06cfc4b37b37050dbd97402f4a4dc216916e88b9037ce6fbd15ba5e4429dd96a33e6b4ab1c21ea2d24af9542186053f191b7110d364bdedf579ab9e50155ec6b78a7c3e9c72c259461c0d9f50a3a54c8ca6c7f17f222b865a72a1ac1f4aebdd3b57c0789bea5e666d66132c7a284e2ff98143996cf4d7fe4117ef66a2895b084de6de92b2f9f09ef3ab5c2b69c2cb4fde137ba8b615b9056ba05f61a9053dd0c6dd7f69acf9c3389a00d56b0ad79b00d35aa7151aa12e786a5d2e2943a02385863ea7afaf145bd2d38d7e810745e375e019a59f3cbf9e1d1270f6457322e5c276eb7635b1285431ac7b30ce67199eb8d8668943c717be4af7202b1d86d001aefe081c41e73eb62af1356df270ab237ebbc32a407ad96071bfb2d7a84e18ac927185c8da6a29b21563d06dd76b23e6de2829b743c05c93860641f04405b5fb925af00825fdab3422f09ca6da3862cb7560560c728efa080578bc5188cc9ea0f5db4c1433f045661bb9dc33f5f034dc098b51cf23ab0657388e22ebec1c1094ce42a4ebac462d7026e7f2ad942407b3512fbb97ec7f95d39d085d510bc140bd6899df1ec7c9837a53fa92aea1802e57caa85141de9229351bf3ef98fb015606267c48d8dbb704f8e61ffc11b5ca5eb506faa743bd4abaaf439d7c29dec5a46cb30e04f06dccdf62b1c8b3efc42ae356ecd82bde96e06de533fb903b79b9cc8b1332a18ffc6a14d8cad54d49ac28e31ff8b0f8f0d3e6fba3c9b5fad698d033884d326b5fbc3997cdf92e64369eec60a494a08e346f6294ba82217ac77e5a40fd87eb4eac3e978c3f24818f36dae795f30e253bf6a1c0d919a2f5090b0db77d73177d2bc4e7088154893bab49c20bc7ab784b93655a53608df8b144c7f49677e458caef43216f6f7e405d480233125f9f468f8120efab283f495556f5ab6b4a93f6f79a7d2a66d28c48565a0c56b1acebb022a3ccaaf70bac95641b1d7276304c9d99a4e98ba6e844b7772c9c16b33a55d97ec1fd145e1c52dbc7c19b5c69d9e552cbe8bce441d36b2d1fac259a704f2382616860c349395705f42806613cd17515457ddd121332f18791df0cd79fa54d96fb0b460f238ec31a731f17a846444ed70886d0f20f5e8c22122297362ad1d263e492e6134bee4ae424306545d35fce61d4d0f20be4e231a828a168ed70f6c5b18e0365cacce0913d0c5fa9ea3cd8a04cd2d22f92616d7253758f573d3e286ca6ad4ccbdb8d96ff363b399c4efbbad7a021afdb66c9f86fa698f70439e98995f58042f6221613f86183fefdddc6e3ce826341b1dc1fad76713863812b26244fb20761b9bc96c613f784db7cb10c578284dceb81ebf32c283784f9dc003a939887c75c0ebc9148f1499712bfd9e365b38b85460128209f56ea8b57e608de21ab2f58c268408037b0e1ce89408d34e3f984231802e9a8a56fb97f7800f339d3f3c2effc9394c1dfa1c490dc7fd73f2a24265ff9fc3b5b95cd01845f8a56f4413e7c68907bfcd334ed89495c65c1c0e661c227f3ea624d763951428fee25cb48647fd362b125a1cedbe991c6046381a3d071b19fe1690d69a406ca8e85c1adca61078d91bae8e3ec4df646d8de955f6e37df7d07c28cecae4fabedb78c92c335c403833ce94c98f3b15944e20d6f5614e17ee19785e261a0278aa1f3f98874d6b49f4b2804d898cb8e97e083fce77ed0e174964c8b07529a07b406889268d4f0f4cd723376944a8969e3bac3d8baf8a325a7dc3fd3f5cefc8197f5a34fdd2b4d2285c8f81a37d8631b22b19014a7d923f7f8cd0de0ac8a2ecc898190090d086907b2200543baff352a56060a3ea72193908ca7b64051df13e17fd7ba080faba2434d1f197d414e5c1220639510382aa72989ec91e743a76f81b71ddf7b29b6a5952b1f3bfdb3ef67861218a4f4f273111db789b939cc09d78995c018cf37a95c3181415c303a2678d0b745eb9cd221f7f2ba2f6f2365da5a4d8f5a032fb6c7effb69ce27beffbd949c35de029c6a7c77039cada0cb7b9f85a37c72e8f68a63199015e4272bd39f68db6b4a5b28735646ac5e4f09ba0e679b793e9dbe9ce61f610c4df572f7874e230184ef7fa9c89199071b5b340738d75949459828f09469854e5f8e7bc0ac778073aa6b8bf1ae9b84a4b01ad5d783369e9cd193d86d96c2fc2c4e7433de6ca790bb47c3a62c84f87f922f92b4961de6978935f0f0e9290890e401ee1b5d497b18070cd890a0c9e5653420225a34146142599249f32c427937476f8af2458bb9b95176e39fb804a144f29211b9627847886435304d7418a852339dc2ee5ac8d9e0856086c9fb382a345af6b0178f9d1016dae178090d4e59409e23bbb6e21b270c83ae9bf6c1589999b3291e61e7278caf75a13545981b2284552f3b3dfca86042e5bb4b69eab5bc50c318fe4e0a2cb691d8e1966cb5817ef7c58f7ae75bcf59b4c329da80b91a1e7a712d73114477c5e525b55c9758c6ab1cbe6e37f499a9f08b1a2340060473eb57161053b2c68747c142dd6069f6685d3466b613fcc86b228734d209e1ea31c58b2329aec5a2c66609ad457199e7021d3468f371d9170c6d78036744beeebad66b9dbb03d450625e5e72e21f196eabc0e426e16941fec48aea7f2d1b85fd29c08e5c5ba267b9334285a07d2c88a84a139e7893e9099a1d826c8cc61ff413642365e1601eb24f750782e8a804cf6a3811fc117ec9b4eb7102db20464751e978ff4349d539020f512e1ffd729ffb808b355707d813ad5717a33c583386026eb6a1e2623613d8b0798375b3abfd9ade4299e74915c09bc93683c4a1d83132f81d1e5ed897b20b23eea554cfdd4af8b7d2a569ae62c1732aa85ab828e063d41d1a7af2010f3882076fcdf1c506b2c742a7af47b29e686bae22dac794b438ff7ae2c5a66e330d59ee3ec3fea338873712dd9906ca0b08a72efb5ec6682793dc92c800558ab6c5bd4d3a9e9c1fffe5a06fae0b2979e0cea6ab2a01527ed91bae31cadebd158a3703d7e74a342ac2ab4674e5bf2451f51605987308e7c3162bb0ba6ec286509315210a0e9dbcc640a9de37d037f2557d702c403ac9a545a7c137d2ab039137387ccbcccde9b88b011392c32f8a7bfcc9598f6fc55c2b5bdf879162debbfb7901fc31f99ce5ee084682b0f5cda6559246fcdfb20972c2d47e5c499d7b69920aa58665dbfe6ba396c672b25a1f722e603a9bcea448b9e92e6cf5ed951648b39cfb731970106fbaa5f5f1c3dd0f5363d300af7678c1e5af2788bb8552372c6a2327de03ee17ec38a8eda01436b2a8f94f07d7197e8ee6157165d5f16e23756699df2c52733b13c72a3348cfde50b89edbe60316d7a5b0073dd8cceca6df1ca1ef58c076bac007a57b4e4508fe0216cab7984ff638d06406a9573e0f5ee105852eeb8847f2df37f255494e291c6a13d45a27335df816da0241cc9b67953a0d74586e1d7cebcaffbc33fe21ea7ed9bd9afdd72b81332213bdd258f5deea68c6385ef57c451f9e0720847a711849b0c37a2be5075e0be2e2e4f8b1568504bcd1c1cdd6069b45d1986c82d5dfbecf3116663309b8d286eb19f78bf1d31567ff4e4c62aff065369b70786f092034f5d2faf81f45c9f490e7a56bbf8811a93db2fc6c2e9589f8cfd8ec440318ee03cafefae51165abdc039d8688f897c5f4048ba6ec812a43530ee5b8da56450570de28fb546cd9dbcf8ee320576652181033bee388ee6574117a62547453f4a08621b8bf9bee80fd63f2e601c772afde658fdd4627f2e76dd9105cf4eea428ba8a55e90da92091a3fa486d159826c98707214d167e96a4412d0d34bec186a448940539fd9f07416ef408d570b31fa4947070eafb6f103b4c4cee553d29d07277b1b62ecdcc031bd4516bebdf3dfc25d11ea4d1500a1b41b1717e4a6dbfa4febdedecfdeb6c091d8f0d1db651f4812f5e4d0d9b7232ce645cfe280fa34e4dd5187bd9aa27ef388e875e7afd6311ce29a9e93a0eef814f7583a15887c31bd27345cf695d739d91343c63b7d10fd8a3441630b3c5fc2c890c2ea09ef36cde3ae6c28fccbf6f6337459782ff384605cccc63770fbf30df4beb18f3acb96dde2d1b0f5fe144517026191694f36e6b6066af870b89fef40f6e72fe0bdfd0574af8f01f7eb3fc07dfd06bc57df00ee1d137586579c5ec7954703fa079a7da68d3d436be60588c59cb0b1c80ec6bdcc469ea3f7fb4627b9d011bcdd9ed96fc86ce4a4d2eaa7031b57bb1bf48ab021e50e18f566d493916e9013e97d00824bb982b5613199e6fe2ed8ba27a5f80e83fd50804dd49eb97f7ac5ce629d4537a889839ddb84710a5be29e83c4c745c46586dfa9f0bfc0b576e16e5de9c9c11837d8236910750a7713de88bd1bf7c43011ed3dd6624fa8649d8f9e7d13ff7de4f40ef6337ca84d93568c6dfbeb83dcd52772599d6910921b8c7965e8e45223e2c5c314fe73cb84ba07e3f0c1203fcea2c28bc50bcdfc8dd5999ab973832b8526bf5b8e04b15de2b9590f15fbd817bf7a5d4d6a9b97d7f20ff87813da39a48b8cef9918713e7861293abddfe94ad02ffb615fe8cb6d39b6d74617379a6ef9118afab32b4a39ab70bc12bdfe4599a978d77c98dcf7081d74b78ef2e6327f92a7678faecbd9c59c4a4c785168e6d470bfc5bd199a790f419705eb2417fca3c04bb119045b7db8018b7d7c77857841d49486d98f0019f4df11eaeea04afa0428814c41f95072f55c2cf112f16f565f07e863dcdf8a10bf8db4d30301e57a10bfed586ffd28137219035dc0224be99d0f0178e97e5d1f67406425ddd5753e46a2459a5efe1226b7c0ba472f27c584620aa11805e6f302f30dd49c51e950e050c64bbc15b32ce175c87c3ef7f2d452e5b8d4ae17121c055bc1b8ae37df76f4e220bbcb21d708b1613d202dc0de8d27d49da7752bc19984c91d0a1a6936faa01f5486c45344dfb28cb3d0cc2daea6cb5985d1ed7ffdcbf69cf248aec32d887edff75fb6e79447ba1e2e61f4fbbe7fb33da72cc2f5706b686a897edb4febc9f0fde90cdd6f8cfc8962908691a6965eafb19c7f1f39ae1c90222e7e01ee8e12b564c814438c61c6da01fd86989cd8ffe9349c061d222f02d4e4af37cff12abe817b458d7c072e72ae97551543847d9bc1c65cfbf4c203faee097a9757c54e676456121561a88b269ae078a827faf532840a86903159aae262ac67e76dd3fe6d90cb7665dd80b910317271b01a703f672d05c0c5becf0f33db901dd8eca323f3c267d66994543fd6dc1d211d3cf5057020b11980b401b04bab0c0055d151abbb32aa6639bd3e0248e6092d9195f9e9e771659b08612cfb38d5e10faa1013b2b21a33cce1f809383e78a5f038dd93f44bd7b9be4f63b05ffc31c90b7a6d405088d5a7f03bed09bd6b3824c4eaab4ee0e397f9be4df87a8f8ec8d91f5b288caf1ab357340a3d848b4bd361059e99077cd36f4c83797ddfd92058708267981ec5d0c685613a5da17b2a67f2c652822a6ab8deb23d289e0fe3dc8b87d32edd62e720b29baa6f953b07589069d67fad07ea5ff55332cea5300dc56fe1a8f816fd6b38913de362525dee646c822bbd0d8b28a47f0640dea35bf424d7eb8f7ff84e03a9fd6f5ac784182144a2d7260e510acfbdcdbe206bee918a2a14452e5d42dc36c6f647ed4303349b07e34771d3df607225c450acced6f02c945809116f6ba0ca47cae2567187ddfa2e87d406172554c6676c457467b877109697a3b61225c49d0ce35be41162a184a8af5165222fd9b9a3af50e790cbc85aa215206620b3ef38d1f7ea25ac2dc675247e94dce73d174fa433500e15dc740d0cfd6ec9c67472092b6a3cc877136be1d3e226b1820470b859f37d19848fb28f4acc2d537386047d0a65fec7563fe0b95870fff0b2181bc1a641d3e0da87b1278870c94bc12f06321948bd0a0d16737565aa351a05f8fa6eb0c34a4eaee611505429f5e2c27c400cc64f36c42064dd86ccfc9cc0fac579233966f4cd0ddb01d0e9b6791cc08a717963555d24144ac6ace2b6f078a86add5ced3fd270ead1b30c70fb36763f7fed439483fe2b55999f5cdba3ce4ec26a1f9c9a21e4caf00b123c82af5130a539eb2351b59f34a288d4372333bec39c13d6adb1ba9433cd9612ded36c5d17ca76a6fb9e147cc82423ed9d409bf4ef40c8e1472a7cbbd06eeca5f695112d4526c8af95627c222b589b6219ed238691d1bedf7a31f834576392cb1e951fd9f032a6ebec04e2ba61e513afafc7a81a2632035925bb10129dede01a77cf21384cc84ceef79fd9cb457ecaa719163eefe079f926c19762e986a67ef7dccc6ad9b26c072e25aabbf2ee6db70e9f6d379ee103e3adfb283583c265ecfb66f1c0ea791858365234c0b8be8cf84a04c2695f47a195a39ad9ee60e1215dc05f348865a6a13b24f610aa894cb45a1acedc5e62b97b80cc9529620678639737ba333704e05413600f0f534dd9987d56492b920b71c32eadecbde64ef6362f1befa2b823de11d676fdb758fc54451cdcb6d9d6f282fca9b5d043ec9f2947393a1afcb9e9d9517b4d5d33d85bfd3d08490fa1ab481326e25204e5ae75eba50bde0e79c67bc740d93100edd3911725d4f78cd6dcbccb18652963c5a67e2c12dc38560617c9cad8e66ff40f29b0e8490f94e58ad039f9cb882bcacaa1d7c9e43194ddbf3d224a4bf74c635ff88500853ec4b43c93c8b33bedd0eaa43d404db0f34a43d561c1ceb360c715f7131ba425900518d3595a61c7488fc3fa61a83028865e74a488906c27b8538eae3ca0b1b765a9638ed881a093b79fe8a58ee25ac24b068069e17c7345743161df8c3f8bae19ecef80adc42727d45de90c59d1572b5899744083cea406a86340a943f4a95c1544078fd3dfa66169f59ddc2f00687e6c826a89e1b0f436dc23d09ae1bfebf2ce40ac0436bb7a5a494c9e5f8bb6cd0c7b4f9fe8f51a055fab80ff16084baef6ba2d80372f3ee96e38853bcc6f4a71f5ea5f6623e008de95e0510a06bdc42f98aad202fae90517d70863c63e7e9b3e2d13fe9d4abc9e10b18bd3c4d72b01d8fe91682988582246020e561a9c4988279a486913502d38732fbe81d5b934f2307b568b5ac2c35917acd18fccaf3118dbc28da9bc25baa8b1d98ba61555a9b468282270a74141f48f53c68739d5a9ee7dcaf21187a48c85692753280993cde68f931848b39b79b197b8b38eed377448e13e8983221fa922ecccd110e7eb1b58be55b482e884b5dd9e33e9e4495c30984ff3981e799042fc284d0f21da91878c59bc8753178be58beacd441e32f3779b8498f88d3a54549e9ab43ecc4bc3b26f4ffd6f3ab730d586b27530b248990943b4ba777b3864226a1480f03168f748825ec4fd66ed0847e2fe1b26fc65a75039f06a17f1b1a46fa453e30c355f56d4fa435204342a5d768346de3f7531f6bc7acf626927d26b5b897dde74492827449694cd7d6781253396dcd9a0cd35c3106f820b334b8d4942dbcb41553d146ae281ae63af821faee114ea3a3dadd29614f026c2ff6ca3838535cb26b79b9b5205c04620fd889f8c0756e087d3931e30c385c646784588db7a567465c98c02f0628b0d164bf876b102159b77ce28390d105de433b385878295580c5b6290a44528e8a225b6e91d88a3c1c31edb78dca19baee980f246172ad1b0b952940e925a33a876be62b505f17cc501dd6160af21bf78f07cde519543ea1cc6904e3e94f5990c092848af27a22c38f0b41c3dca9ad1e412879f3682fd1fdf9f7d48a51c6ee152a21d8520e272fb970835c5e8fdcdfaee38e454127e8a18cf7c6672376380db77524abe9ea4706a2c2294b5012c377a151b1e7ba8c791989593d6a4ab3dc8b3d84afa2a5a41163430af20cd99fdec17eed57e8d9aa496bae306a65c98af000d11a26471a249ec8439f31de5e814f8fbd764a711850684ebc35afc6ab102b5691fa90977dce4232b1bb425259d85dec6a017464c913db17d236ac1a32fb4aad6025a0f9d50036b1b5d2c9dd6d9eeb3e9f5a7d89cc04cc2e7c16b8ef671cd315c2827447f1682808e9fc0ec7c2fed46dab928abb225da0ed64743040482f5402a29f35d9bc33cfd61480cf334925578b140123b07a2481ff61eb4b592cb572a987c285aab79fb0c9186719db059df9c150a960d352fc3f5d2a50d0a842d94e50d395a5d3cc9a038a5b0d5d1bc771c64a025cecc0481a0689e535666a47a2ea36cbba05e5bff486285630388288bf4c1663bef42b810086a79f4b463a61e295bc0e5da18bfdca3fb4322e2b5fd3302735e5e793c6fe218ba086626b4e65844dbb3c23a422b60e77379ebaf289f866774140edd3962e9a621ec9dbf6021d9f1fe1cda6e155dd8da0e5bd005f3dc22e2a99ef00aac1a6b1f1040aa67bc1263b1b5653071654edb86a33e3f35b913bce6ed98d55829f213196bc7e4929b18fb8fa98b01c7b87eda70736f1adcf970be0397a975d7510486e2972b6724bc5febd81c406b635396afc8659040dac97737b3240c6d43dcd0dddc948017fd366b8a73f3aeb8b82585570f95553d062e553fe78e81aba5e0f845690f9f1da396bbf50637d024b1e4b14c6c4510514a1bf8ff3993a4b5187ada75a186dcab3d2602fabed302f47e05ae42055111561058c88a3afc58dfe05bc2f7338769b93e96af537036a8fb96d28bcdac60c7a20ba5d20b279add52f26c2977846284a4dd94a077ee523de7c3032c501c0daf3d9edef1370e09c0852a986c565766fbff275b6bf74e014613051076101ecaf34c5dd7a3e3d1adba18cff3bc944fb7c3f34e5e8763fa606058ddd0d1b81183e74487f260e84e469ebf74a7f668aa3dd619c0d43226e87a071478a62ed59d541d8dce74c5f3562e53b763ea3cefe45e8c0b4d87ea3a15ce29a7069cce7b49adbcaeeb3a55d7b93acfbb8129d5b97827d3ad9bf1caae33dd742e305eb75275de0e1e0d1e0dde0ca6367567a34b795e47e3c4329d3c183ccfeb52dd69d6b9e8e860505e87ea6a04c9e10da9605cbc4eb68a51791d0fddaaeb4c5e77ea84ba193c219e0c1e8ca7f2509da9f33aaf73753378309eead49950a6ae0bd2993a9acea58be9ba6e484783f7625275ab53e7759dabeb522e782c7427af439d3a211e4c67f268e84c26cf3b79a74e88e77531782f9d4bb73a795dd7b9ba19bc1795a93bad4e5dd705f10e070e2b22a61c509da973e94e383a171717cc0f3968e80070ea3c2fe5a9be63b5800323d4755ee7755d77d3aa26db0722ba2d3d1ca1bd872aca08a30719328ac064f6a0024a78304627c9d8a091aa78c1234d17f451155b4871246393f05005942d46d3c70e48aaa061094253061c2155e0e02164d69040101ed0d01144e6a503c2838e0a4062674c01c4abd05f4c0a34dcc4b27836635c616d1c07871cb0d820a18698c7d4e02fdc682c2b3ce918aa89f6d311dda6ee6e1b195910a593f6c122839c20fed987a06c0ad90902e4878f1e3a39384e8c58ac02e0fbcd3c43180d1ba61c26112c9d0cb0744292c2c13b55138a605db18442c5a86eb04111a72a724e2fc45821811401964e485c5c789101c7114b2e3d9c7c30d100935331aba0d54eeac53404c70b6a054b2b2d96587052844b1093144a88d9c112ea8c25544c0c33588ac933225872c151c3530d41f14025a04a0b30303861c4a9004b36646cc8986e5a3c56385a671881ca61b5a32262b26122b2b262c94494c323f5929ac092092615c3c90626c7d49d624e362f41a81c543da46248bda4a0c4b010c3820b0e1717543d98a860442a06531646a0bc58b201ca6974980d339c5c313652ad5367ba31f99c8c625e48792a26aa1caa22540b35ba148c09758a31ad4c2e2f329c4c2a25aa1b368c5e5aaa94aa33a94e3e4e3c4edd0a06538e225c6a404960a9c6048a68a54e39563f469c7660c40cccfb8c2a04a1065a5e10c6175e9434a426ac00f5e8502488ad4838028f1d2c1b2bd50f3e24293aa3053280410d4ce05c7162872776400317a460041db000163cbe1b16506626f06d4212b6e0400c1974b101228600c2890f4d92141909aa8186175cd802044458a0024308019b41065b6ba8b1031d441997cea882194e70f2c30b2eb4689002149060041de0c0059858620030207a6092a468c8052d40010b427045e8063670410aba188108aeb04209248e48c2161a883102116c81012a4b1f0e01b5686cf901193bf8a20b107c40031068c2001fc28070f2039321a021ae9a160d17b4e00b29a06882ca8740046028086848ff800c17b440052800c107347001081c60092a4f02305464882b888f9c9a1bad539ff1033274a0822f50d005083e7001081ca089250c40a507b0274e74e0f14d410a488ed8a8910319ac144089264c701a600025724a147039c354058f0a282978515849e014010f021e169d8e9763c2e93e981b530e2677a1064f862e872a06130c1d8ed30b9d0b2e2bdcb861629d6cc4d460d18821060618195e5a2eaa554ae5a5522894a9eb1495171b56b0a47251b99c6aac80a85c4c33c424155134b3a249bdac764e3136ba534c0a76c29968985a272d473cb194aae1a95c4e363466d8a9c0d2cb9298f06453a308cf470e94925397225282a522487e5a4778a79713921a33968060040e6114d1a15cad1a7628c23bc560ba213b191e540e622ca55235185169c1460f12262345086009061726312cc4b02025a80572855f9cb04424bb18891d80a57231d140d94e03284011ab538dd40c9d8d1e4504a1012e38cc80caea094ed4f060503bb454424e47fe872c8c580145f312f47243cac909079510233c5085112322c0840b2c1c2a3440240438c1124c3983e2081a3a36ba25329886a8600052c48b4a48ea6555c31464c88869869720272cbda8866820ad84720005bdb808c52085443cb0f4c2c906c84bcab5028dd40b0cd00c10572cbdac84689029b18432b1505d8a87d40b6a480a079e1e98d265c74a28f5a28281c68f8b8e5391cb0b2cc870430c2ee0b0cae1c8d10d45bcac3e550f1a3d820c19a9624eaa18502e13109798d30edf41e5a27a39f1401d39edecd0a1729864502ee0b8ac409310a02138562f2eb80429c2a708c6c78ae6a4e3a4231581251c6a9c7e5039a06870d17192c1468e690623963e1e9d6966ba39995041cc00810011d86a810a84c145161688801504204208256c9b3d1803c2890f4d9628413242120021d74e0f9a1b6c00809f50d0c5194828421074e0b16126061854585800061657f000a4836b861662605227d8e20314c88285150ea8028b144a6876f0f8a0782209e98c293041e603128e3002986d1d80093ae319f2a2cad28495202e35d002812c2e21405e6001e665a59221470738e0e4c3244501180a0272f9c8a9b9d1aa41e334c5120310c08d317e84c002158800114c960401828385d30bc258c2129e22405c54a90b24f1010c346001085022082aa698828924453c4376c474523045c17bc2698b1fc12be314048f07a8313a1b7834f066e022468c0cbc17782ef0b6f02e60b280673b41e9747435ac6640c9400306ef05af858e85d60aa81b5eab639d6a7830a817cf65b5f2542a9477ea4c5d97eaee1720dd1d03ebc58b7e513673a597e4f1a105692d3bd34b147d337e11bb31f517d70b10d60b4d77cc69957e0de7355e8488d31421e295d25e966a964b14582e4a60b980c1722141cc67d66b9cc6fd438a2b754c3d531f92bbf3ce1ae8937acec99e7cdff74308a67ee074a396cca06a68960b91c6f7abf7739e248f9b316b058515199566fca17bb6d5f1dbd06b681ebca5c52b14acb2e8b07e9e8e592b2b617dd60a881512af655a7dd167d61fa422f66b677766ec4fabf376370ddd2e2cb8e4f8f2e6c7e29ca9508092a1bb6758e5d0dd3874778d0ddd1084e4388fdf5b82380811b22324881020427e08f121a487101d213942708408d9d9d909b20364e7c78e8f9d1e3b3a3b393b383b4282ec0409120448901f417c04e9114427484e109c204280ec0009020408901f407c00e9014407480e101c20427eecfc08f203c88f1f3f7cfce8f143e747ce0f9c1f427cecf808e203888f1f3e7cf8e8e143c7478e0f1c1f427aecf408d203488f1f3d7cf4e8d143a7474e0f9c1e4274767482e800d1f9a1e343a7878e8e4e8e0e8e8e909c9d9c203940727ee4f8c8e991a393939383932304670727080e109c1f383e707ae0e8e0e4e0e0e028e1d0eeced1ac9409c6b23e79b179a1a111c28578b17909c2ddc6837077f7eea6e9ee1ddd7d43779f6c482db92be5c45db1948b95fa5232a44c1d8bb9ebc5261673579ebde8fe12abc9351abdee79f6224dcc5d78e2af81798e45648a1441c98085d240b7639a4b993ba65fcbddad03002c541356dc66c70ecfd3c3b781b44eb2f683ab3b9744d7de0b84b3f7da1e5490eefebe3ccefe5a10e5b14e523885d1354e8488e7d0f8575b14f36a69269334ee6e1f9a75fac6f79351315f2b9b49dded84657ac20edd4a3eba7168bab30cddd7c989d55d9d9c4edd3dd3dd5eb34c4fe89e9175b7d03dd47d6a9d4c2bdce86675b78deeaed12edd5d14ddeda4599e0c582622a61ddc85c35a5a99cface7d2bacdb02244bcbb63ba1ba6bb5ff0fd70be1f5fce0d8f590e0ece8f9c2993e9e884417266406e2cfdf0e779c12f7733a6b4bf3c2ced4ef0e321bb36835fe381ef63253c563dbc0474a622893d9667ec46b3bc5ab738b1bcd02c8fa6bb596896c74217b98f2b45e1ba32f0fd423bf200ffc6eac0e04077bbd0ac0e4b77d7179d88bfcc43b1b435ec358e298d2b7d58a9ffcd8e7f61e4c4e1eed6e9ee7ee86e189ad5e5eec6f7036b0eafbe14e7cd63f702c5bc4eafd6633534e4bcb85aba5c592cf11fc53c7c519c60777bb727eb6e1ccdea58f87e799ca9babbeb4ef5b5f7bed7e9e1d75be6bfb9fef8223952cf74deecb44a739ee3b5339f0de8ce8aee8ea1591deb6e1acd6a26babb8566b594f0453a678e3fe764ee33ebd5d23c3d77edf823be9f17d3dd3234ab717477ab59eda3bb71569cddbf59cf650a4e7282f87ee0df60b879798017f300ad284e1eb93baf8c8add8d329dbadb7391220c98e66269e9d526972ab2c0c0e8900207ab4ba24be244a54ae749ac4c41a64c19c273930fd14da152c57b50492e8ef22156fe929a999284f7a066a60c91f297992ade637297992156332857cd0c919a41cd98bc7d88545761744ce155f1aa9ca85439cd50208a0e365373c104460715ade374d2d10047c1d490e91e181a329ec7c8744e8386c9a3e1bdc0d0c811a4729b6a068b9ce7a9192c7226d7e1d5c1c8789ebfc07895aee7854a8cc3b8b8508911e2c53b9719212890f4e29d0b01e334bac79321e24526091d7a4c0e2343a54ad763f22474e8e1e1e4343cc9d4f578de6945834a0dafe23d30be92a102e331ddcc924988214c0e33b36472188799a152c57b68b847c3071a32420c61f21a334b26f7783025998c5e64aa743d2fee2253a5eb717118192a49e8d0f3e255ba1e1887f16468782793838793d3701f4c1ee32b192a2e4c88e8a1d1b9102f313242c078e722930405a2e8f04a79d7a3230b2b4a9ff14acdd8b0c8798e45eee4469e773472f06074f2a66164729397ca008c0e2ca899ee1b1311a6ee084c9fc41515238af0dc3bb9ba0dc074d7d93a282a5f4531bd5c4ea7d3c9c555ab93cae56452a95c542eab199be9743a9d4ca6d314289dbb7897f2d3949be7a8996c7294a766a04c31a1a6ac502ad549c6869a8932e5e5326353b99722028ae79d8cede4535eeeb90da50198ee3a282b37a11a2573f3c95337cf53385eb694bfcc44991205c72b35934d42dd6b657ab9cc403979371365ca4b356333994e3351fad5de348ed878795e029813cde9d4c9c4388c29c6944ae548b90c94262f94a36876bc52f9340325b592828b97c9533952de798d191899177f99a151e5f06c68742807c0b497802fa018e3d55f3cf1c5132738c1175158110022c080691d5050285fa15040545eacdc8351c974a8936de5283f9d3c1a95a356dead66bace5d3a952aa60ba393c1ab9d8bd4a95d4caa14cae6e2432e3327948cf7ea54264fa51c954251a1b20093ab34f052f9ca0995af4ca915585861851b505832b44023a8e3e2a53acdc0c0c850a10014947b302b99aec5b2d13862f294dba031849a51b98bf7dac1a472e9181c3a70880825c544252a56a2f0605ef068c4c4b8acdcb3ad5c75a4b382c6d08ae5d19886523327ef64eada43d5e8b8b031050c149853cf9cbca02098f6522914ca7432991e0063721853bbf269015a9cc8f26aef887895e144952f164044aa5db7530e934c378d9639d2bdba7c22e2d5de4444a999f6685ea6991c293fc97833f9643279ca4f3488bc15106a2647d79d4e2693a74c36af5592ce5113808181691a9ea75c65f2667298fac66665f34c0a20e3e5294006af7eb547737228a797e728991c2728edd1b44703980e01ddb2b162e1701794a3606672a05050601c8582c9b142b9e4d3cb2535e333b70e754f9d2de5a8d50c149a1e931858549e3ad978404cde2a2f87ca532a13ca752cc172b9f8c94fb695cc8bbbc844b1f1f297199719a294ab4c9db35e808357ca5160bcfa855ac28a170daffec200584441e5d57af517506c79e5ee65f254cac545e529150ac64f30dec9a43c9f3a15ca05e52a54cc6a658231dd4eaf93d32042796a264797e308cd2b05040425c7119a17cad6792a074a95f24ee960002be57da23164f2ce73ac9c26af686c3c20a89994775e3793ca91f2ce91ea52a85467e3d5f54d67e3d1f44a02303036365b4ce0d5af8ee2758a41b9560ec5847a717193cbe9e5313034bc93b1f1ba9d5e2acfa7d7e965064ae7346e946ecbeb767a75dfc4349495e77079bd10ad666eab996e85729715aaebfac64473ca31639ab1f1689a88980e25c60170f06a189b19289ee75079bb27034535e336a9942da83d20a7ce06c5848978e5e8992833b6ce9b3111e08b0380f19a79f51707c8f232d2af28365e26573914171d4fb0ba1c284739cd6be52ea89928dd9697e9e4394c341e8de74101e379a81c1e0dca753cc1ea1c9d7772d46986e6757a79367dd35e467b9dbb11551011af6ec648cfcc986092a0bc676e5d12ef653533a4f293ab666ca9d38ccde4cd745288b11194ca346804c1e4a011e32e3464a2744431a7ce347324e56d33e389d10418af5550ee5e9deb38823593c3e42a8771cf3473842646159423c66f2717cf713bbdbafd254a47043373f39e31cd04753434a9a1547b5f786ecac26b57946e4b12afeb23decca9c3808d9876b950449d770198f680d85c283745b1f1eabe8102d33e583962f2f6ee646e13803159597a99fc64030aca6d2a1f62bdb0e73030eef5102f95434179ee666c333618f75a060a8c7b63bc4c5f309172d5170918e385721854141b2fdc7d0305c6dbe4017932b7eed6addc088c8b37942e49ca55a6242897d5cc8cede4b97ba5664e36cf73f742cd9c82a24479e94e589c5cc5c54be5a9eee42b26562c1c348dca3154f3ea974d0c3a10c08ad2bd3c37994e7e4f273799fcb472148da194ab4e2893c964329986bc99d3a91baa797533b694afdc9381721a4a45b979b7ee85721b6a662504166468d7718505c5e49da36edd6b0b98f6be28401613f8a200597a988214a420852c549d9fb4e8542757c974d7738506172ffae60a962b575627787558565002b459e7f84a2f7483f114410f8f105ea1553a3de678d6c0123bfe122bf12f7c5cdef08d8ae10eddfd796e667ca3b75b625c88037fcd1407ca665ea9835772f6d22a7d1b156dfe4645b049f777edec65ce02f3a4a065c9c6705916373212e779d6dc16b16434dd18d3f13ee99546b103356b6ae9eecf5d9c6594f76ba716fdcd396bc4f0ccfae37ef6d5fab56e7333131fdfd46bab7ff74725b12ad36d4e8ac5bafb734c6338ed3670ca4471fac456dd5f7ddbcc302d9512c12c80b3d5f633546f29837d9eb4173f4cba9f7f9c771a85432e575248614d6034ddb01aa695ce8008a3b3c0cd5a06a20a104dc207020708161dcbe87ec2453fc1d2df93d813527cb04ef08950f7383fc3f2e327de30275b6e549c30f2df0673e285132c30274be5ecaf93264e6870e964754bd90f63f4f724f68316df93d80f55485ac3f72bcec27e8875ffb0839bb51f70d4c0d266960f6574e7c73e6871e78ba00f551a96b337e30f7d086f5602721b22470fd6cf982a01558be7df8b5fcaff9dc960958e3991244b18a648b8cc33e34ac7706271deec25c9295ad998c3589c23053fa4557a33527d29f6ce6098fe7c284e718ed7d6a4dcb57986758ef5c5af54ac43420fd629ce1e972b28c9ceea50132de4c469d14dae74c73eb4a02bd684041d4f1cee6b13a1aef94db55e93b09ae0e8ee16bdbe584cc2e8ef33c5961c2de837d5d69082b44462427e88b3a2c8040993d52dc127f138eb922c68b7249d56e9cb7cb4d7de977253594b90584b70c462d663d7fa88e20429d0877b70deacf46eb307b19488d138f736598979c6cf9427f747726fcbfd910f2da8a4f63d8961582ead921d3a3f56e2fd3d893da1bb3b3f4ef20266bb73fc9b84e569938491f36bb0fc3849a95b89cefe92ac24a4ef494c14a92d89b4f9f1ac193d9e351228d7bffd83d5563cf3fc997986b33fc2775ea007ab2d72b992c4f9e3ac3c356ea3d3c3ce2a85d1eecc23d8e4da4a61958eb00fadcfcb7293281c2ab25d8bcb5f71f386b54c71b04ca104e05a2873848595daecac0eddcf75e27e9c15f66219dafc3690e68ced08cb13a634c7b0d2234fe632ccd2fbb962a53906fd8dd2805e9495f647698e23a8a434471f404a9e6a698f1b91116ce272e9dceaf33004aed6673414adcb9564c312c342d1f250d3fdddc76538c72c96d8288cee1a9a2778fee02fa32c366bb3675c4271519ca0dbb0c4fe325aeafec232f736b7a11152dbb044f2af65245bc3f1241199254182fbaa647b4471825bbe27b1dcdb60f993706103bf06d63209161b9638c9d2f7248627cc8625fec9f86934ace1994bb286a7d0fd707e8d0708a4b8d29b953e7ca2d3e3098e8e0fd9297f781595495cae8c3f4fd1e51a41a51f2d984b7bedbd4023d8e4da7b9fa78686c80836c9e0a4559a9b240f0cc80f1da11a9eb51a9e4223d824a4195b301c0a290cffcf604a73bc3ba5284e10c914babb7fa4530485340b49162447485a2cf3d3c2722c47aa3447ff5abe9fe75f9a637a64025f4d6c049b84f591629f6796e63ecef17fd0111d02504607408b5a0ec02d0034dddf08d23c479bcb59a7d768a5bdb51ce66b49b2c4feb5a4a1230c5df972a258ce307e10c4b3e6750e81433584b4e82f97d6c36bdd264f908a6419faa499bacdfddb57c71397e7385fe6b939fa37594253c879739dfea34512e23152467fb8af7ef3bc343a5a9c753c71d3c3597bb18c58f1b0be11b2bf5c1fbf8ce0f43c0a9242d0154146dd5fb564396db6719bfb798a3e2d2b2807a88cfe302e316933f6c904288b6e3c71d3671608e802c9f0e3457fb11ab70987dc8626f6b7ccb759abe5ac0cfd65e39098284e9f98cf5afa4eb37e4ad68f4dcdd76b65349e294efaeaabbb8d34cb07063e53bafbc316749ce99831ad9656fafa32f5f0afadb6f6b81a48e4d3c4c3cff8f1acf90cf53061deecc8eaa9f5d4b05e31782dbd705e38ac1d72c0daa1ca177ef85f65f6928e69fddbfd5c67bd7fb33417675927917fe193a4bda248719e136514634bfad7322eed7d5a9d618dcd7e2dbd6438ffd2eaf44a7dd2d4d231754c6b491fae748e61981349bf3959a51e3e3845f23efd284f2a01edc06487ee4f1427755b31f52f067bdbcc315aa5b6e998867fa30ffef5dcfd9287eefe69960e59e0d2477b67d3f1ac79a6fe60a51849b3746872ed8c46fffecd62ea159c3ab0ba2de85fcbd98e7ffdc5a3a5bfb09676e6e1837f79b2e0897d35443e4da85f52e933fd68dfd3c8bcfe8dd2849ac5c3fac2cf7fc91765e1e3d26345caf8865845aad8402bba28d28cfdef0cff41b0c436d08ab54c35ab886515c1d1dd5fa66ef3cc7a6ee21c53ff8bcb09becc73a238efd7a7b90d9e3822637cd57a763c6b44b07c26c7cf79e6ea1cdddaa4ee0e40b38820e9fef2ff786d9e34d3904ed25fe636877f6919e56f128bc86a8816ddf767b352f6e024b1cfacdbc029fa744cceda7da3af52afa1559a4b7bbfff288d7f8931f5fbb56cfd478b1d4f9cfffd5a126b8895ee8f5669581fb38634e94ac7fbf9437f19e88e770cc1f9727dec2f4b62b9cae8be7fabb44ed0c30fe9cd5ed263b1249795eefebe96f1ffecda1a58e7cd5fcfb6fab05c3b5fb57e9fb436749bbd8629ce735fcbfeb52c8a93c62bcefad7925c2edffd2cd21976ff5a120f4f0d8dd21c7946b0090f8f284e9f1f69aee591cbc5e3787a12112223d804ebf428c7cf14f63fcb74a44872775290cebebe2ce30f795e4ab6878892edd9e10247b376b07c4f629f4bf0957e8764edececacba3e895941c26005b1d22fa317c4b212d7324893eebec146500996c572ce3e843d78ed2c084dbe967cf1332cfc20abeefe9ec4c2fa18080dfa7b12c3f9319eb0fb33d8dfeee3bf2e9751ec07ff47e2c14a93c86d6a7674724ab7b94f6734d70f877cc20f6b697bf0fdb1c4d582f76da015ef579cddd1c919274fcd4ee9363b254d6e46b3adf7c35cda1f6916ad95fd8d6670c230b53c4868164b2222f7e9fd320a0cf6b2dc1c8fc2af96e2fb4b1e574be2bf353c8578788880bf04c9e57a7a338cc433cf9086c73c61b93e2e0ae7d78460309d1ee5cd9230a539fac8d1dd95ce9a0f9d79fed4ead04f9110909bcb35f3fc093f638aef1b2d396267754814adcffd5a4e42a33dd626d922512c83c221fc379ae9482f09fb6b4158b6e1b48996ecee1f2dd2575b9434f3fc09e70b85f36bb63bc7fb79e2747a9415674358f8183f682fc9f3a1f55942a45a0ac37de5b942e2ccd54aa1d7d67894c0c23b7164c9b35312017f89cb05fecde50a33869178e61986433945307204957213fc107661b01f4bfc97b437d4e95186a2ade1bfb50cc353049253c232be74265a2bcb982a3d0c8bb3d228cef52949c1bf3c35414f8e6013b729b28156ec99798633ff08fbf17e581ff3d8a2b14867fe9f5c26093fac4fe212c996a40e35ad525146915cae1154aa94466f920f89e7a9099f16d22b7bd110017f0986515858c353c8e50ae7d76060941116650c5f0ac597c76dc2a179a711115aa596964b0b23c75b8391238c1c4b9838b3cd3a3d4a1a1e6d6a402337cbe687954311ba5b061b79fdc7e597f9e3f917acd473a2fbd0431326dd7dea16400e3b4aba3b49a9bb91bafb8887245ff839d371b4601780cf064e99bdfeb23c6bd927aef366af4f5ab7451d0eb5707ecdc863e160d37d5f369635d53b9a555384de51f1dbd0b3b5d79f36afcd78929e9be24d2fd1ac1a243c6ca01565b0cf33a4e2bc7df931cd54e91da8bb6b39a4b8b0ce9ef0b192cf332495344ff824496fc6ae114f1c1124c4c2fa2439635ecb14e7f7a978e77bf85eff658e77743380b5634bfd91f618167e588a60a5b5f4f1e1dcdcdcdce4faf82f89cbd14127c75bf3f0ef14c10f331da958860dba1b8866ed20d2499a084977b70070411cd1ddb65937d8babe0d9c32d8d39b757a7c38373fdedc90b6763440c1861e2c39424ea2ff9bd4d30db081d650dc7083e3781119cf8f67338bbae1861bbc088f87f5514196749f40d0270a9c0470f239f5e0e83ebd4e3ebabba8590038415f8b79b00090a587a4f8ba5b4a771400b080ef07fbd0d60f88ce0d898374b712ba973093007c3f59f8f46621193a6cd6cc8b3219ad5e182c992dbadd658266f996ced599ebdf9fcd68e8d3ff366b6eb3e3f0bf7a0da4359cdbb8cd9586d38ae167b0bc19570b62fa4d9fd91a2e3d27f3f0fd659e6df53ac1eef6e9ee1e1672394f9f79868e7313274e0f1fd35af6b04eafe159f30f6d9db12fc5b9c4e50abfe2927c48abb4064ed0ff4e7f26ddfdeaee1d7408aa0107f87e6469b356dcd1f9706e64e1cdd39b593580a059356ca059356491caf5b1ecf5a105ff6766ed350ae70bcd3b8dba9b483710395e21f16b9d351f8cffd2ea10395ea170be10188528ca486fc67f14ceafbdac910fe7a5914ab21591c419ce3feaee21aecedd5c81c2f9473530cf1153a26ced11d2e799916895d226c64f946d0d93b362d8e799312c37c5bf2ed7f819e730acd25903e79da40fadd24ae7f8475f7ec9430dcc93c4f42737c53f32c20356c081183a3440083ff8224b0d88fcd0428a88d5065e5a1b7041130e02295e5d02076440c2075ad8600309240c90b14243470152684003374ac0b1001c2d1003023f43c0208900457490ea96e9064077e3a8356b8609e0fbe5de06132768afe81f12980147fbf872be9c1bb1da4b6ff57df4085fe639513673397a2e9c7fc5d9dd3cbabd17bc1eba1bd62c196279d2e86d765f84fb8a824288eac4c6a6084f11af510a294d9e3d12d7d14d92678fc4ddbd3a09c295420a7b5af8301b386f4ead522e29215f1421e239c042d1aac08bf0787d1196672fc242d1a2a060ca010e4e51a864c838f42245bc86a6bef88117cb709ca7866e140e1c6574f787b67a2e93e3bbeb430bfa8bb25903e7df5a7af8ee1267bd9f2b8d22c76f66e2632f52c46bdfd3c2c7e231d1dd3f340b874d686b0f49433e2fa3978f1371a590766477c79af54214f87eb99bebf3e8eea06ed5075ed0c1f723e7c8e3ff66190f5c2dcde08ba20579f40071c019ce8f1990598f1e393ec2cf0112e6089921901f3f767ef490e9f8e8010a791df047c803ccb8bc3c92e45a5a1086bb7fb361fdfbb996d6e769d3287c5cc2669e3f4a1fd6a1a74da35ca3d167f2e5975160e418c2f28be22461b814cbb104c55986f446c34a614a739c79fed0e8ac5a9feed6c9690cb05c4035be5f28d21227e7d3b9b1b34ac3af348a712d4f26ac16acc0e901848ed759cb8ef18bb93a1dff78272e2dbdfd35ea80e86e5bb35aa0697cbf0c4e72b4e08f0fc8d7e306fcd082372f4e10dfe432bd932cd22c16c6e8eef0a3f8106cef4b715aa539b15a0fe78b6eb3e34c659eeb5390ce6625f6f0f38cd670f74da55171be148a73697313496f598ab56a54f5a94f45ba5661e94254ab53b58d0ee54257a35be99c82b42901271a54de6a853a99baae5ff0bef6bae3e1a443d7aa21a8b691eabaeb3a14ca8707e375d775264fa8eb549dd775a69414aff33a95e7c251d7a53a557b1d8dcfe4a552342fde9d3cef64a53b759df7d235c1eb5c1ad59d3cd3771d14afebbc95122f87d779a993d711c1ebba94d7f1d0bdd075266f6502944955a373a1ebbace13e2b5b0327552745e97f2bace33c13aeff4e2e2c38be978561d4a87a948a7f2bc538ee9c5f3ba1a1b40ba204e3930412623af4fed3da03b99684e28af33354a015d0fbaf69ac56275d7dda9f3ba23742b0f87ae0b363524cd6e2b8ddfe4c43b453ad6f2dee43ac158516cfee879688a25edaf574bd2ec33cbecff2c86a9c7627e29b67686a4d9c559e64b6f33feb924470bc6c49924e6d7cec84cc5727c79942268a0753243e67337a9287c6c459ff0c39f6c9784ff4d9f59ea9814bf46d6e464341e7e77cedc62c796f6d92ef16f874d0dcfdacb714ebc13c8daa430db25b46a2f135aa51853225bd4f25aadce07ad2e8cfe6a681cd7d038c67d517790ee8a13402c74aba3321a697544ba3b5b11bb5abd017c3f9bb535182e717d5c2d68b315f1fc3b0b5f49f861a520fea33f2242ba79927f54958448195b2419973fe1e36c5881ce50c0197f46abbb5b14a70f9e7db95a91284da26fa419bfdb84f5b32df2af2ab9cc57eb19cf173d87f536673e7d263efe71d7572afa6873b63dfe51bf657e5a6e8ef8c1faf74b9bab43fe21d91ff7e964e9f549ebb2617abde26c9e6eb1dbf0feed7156c8c387d9fb52607f4bf071a5b19ff9d7deeb046d1c878bc36cc865921c01f9e0452fa1243f024a7a011d1971a01e4f425242e41ff96f739bdd7a917f61b579249cab2ffff004bd741750529222ff7262b53816f3e9f87119cbdd7973b5e08714d3aa15672ce6d806cf66f6c37933a63d1e8b617196b6078fc5622e84fbccf3c76dc2eb3644465a4322279117f1bfd6dd8370b9dcd6582c06e40010c9712abdd71bcde0fc70663f7f9c692ddd0c0f9851fbdbb1c35d2185d9e0d9dff93fb44a6533ac4f2a01d5219c0327ed9108e1264ca15ca27f1ca0093b0be8ee2fa3e4487b737dd8bcb95257782df84776562dc084cb8426eef20c30c1a6bb3b4bb78c03961044cbd4090b5dae25ccb0841b23a874430525bc24e18a1a9e4217c89604e8b3bdbd28ce2d4a3d7e1e1a6daeb3660483b9eb080220c1ca119c206107d3910788e90863198108e68179d4c0cfa3053f5959cb94c683870b9339d73c4fd287847f9f46a337dff24671fdd9873e5946702378b7bbf0c4e5e8dc3c3867373724bee1a3037dc34705fa868f29fa868f2bdd6d62d1605385ac8b7597eb86743b743544b022e7c3b9c9d6de2e7777f8767751a2e86c3776776277676b1611765844b081d2ddd155adbba37577b32e6cd610ca600d01071dd8ddc9667777640c61d632bd9307266d0d8d14faa1f5c14240c0cd7d1b386f129210585f7656876c48d5f6f8e0be08f74561f861f86aef88eeaecd928104bac38fe24370a679479da0937384e5c4cf93863f8e341673ccc43f307c251ae4df13a549e472c57e78d987f4c73f3c91f8f737a55c8efeb2188ef9876bc2afe5385a9006876f936dd1b543af6c8bb22dc25404c27d90b549d827572791b549e41cc3ff7bff074a932e41fac14f777777d92c323a40460f1959e0fbed7c391fcecd0d190520a3e64f5af0e648e0df60b6f938970b570b0bdf369f09199e4e8f70e87ef7613ed0d145f8855f94515a2d83901c617c3f1ed5528c5dae6b7b30a407deee0a2bb5b98dbb5c1664f560c5831d7437003c4fc77d1d1fe3e9c5b0c4d0a223830748beae083ce8ee9ed7fa1c43038dc3228f8e91db8ee1432c4171824851bafb9bb5832dfa87cecddfe80e96e8fee8cd5e2d4572b940ea72915849f8e1d7c0d2fae4470abffcc149f72b2e89cf383f29fcbff76725c643a14f0e9ad0dd9debdf72d045777f6359df633928bf5c27bdf3e6d367284914a78f5febdfe75ccf7da34afd4b9bf33c1f7fa5cdb9cdb44ac370d23982144f59a6234582c7cf4347dfcc6be07cc76f9be324f22f769f74a549e4dfb5f919f2dcdba875b992623eb348fe657c69907ff8e51f58cbb6a80efd8d22c9b6e84691d45bf6d822fc7afa138aa565529584b3e7d2799b5589bdef43a5444cc2d9f358491daa2fc5de202546b608679174b10ed6ddd5ee1e9b45031c348f1e371f3723a874b3ea9e841fc587201525194af22952120058931791ad4a962091239da28f127de547ba2f86750a3d122e45f2964847b9b2c70a7d56023a0aeb83f87fee7cd1875629b6a24f261f045f47f5c924b82f22c72b147ed20f139d9bcb35824dc43081185a748fa0d2082ac132ee9b9b1b19cc6e1a45228a1ec070b396eb2d65b9d2f106c50218e0b89fa9ea8b1778a0bbed7d29f446bbbb9fe86eb1592ff0acf437f396338c276017e7639f47e52b28278c1a185bc0f0b10207b4e9b432753928cfa4f26c2269ebba3b1b6cf4ec5046ae7f0ba95d725f14a7cf1760742ec998922fa2f4576b419ba02f787c91c234571bbf3c78f0b020cdd7923cf2acd26bc372de722a3d6cde728ea05277b79dd5a1eeee6e1b9648ddfdea79cb5756029ab77cb58e4e7797d3dde1743cbeeeeea6b3e94eb0459b94d0dd1deb0419684f468bd824f8000143e86e530fe49104c460e18c2574f7294b032060b40208bc08d2dd9d0e07f82189950148b14577774a10a1869a8b222281eef69000e9f0032576286146779b5a60228c233871650b187477ea09053ca19381ab0a3b74b74746139a983205277c10a4bb4f50c4540ca8ad00ca0ebabb93814ca70b2706889283eefe7afb90087fb1988b62cdd3667f12c348b11ffcb112ff6c686c36e4df5febf3652c2b913c77ff16fb86fcfb28f912c5e983e4cb255969ec3fc82631897949e6f27f6667957e3fb3714abe8c6a9966330cf63fb3b35a5fcc4a25255fdfd792be586c66fd8d5818ecbb76e638cf53a4a5ec6b31d0a78f7fd7ce92c2a7d16652eca32f9298da22fcb58c6331cf189cd1fb372fb1bf6d8ea5954d0fbddef9a2b5a4dbecad525bcbef4a9992af79cbd7376f39495ac3d762fce0571f327af9879fe6192c5b11638af3f42773b9cc363efecd5bbefcda59b622fe6ca04829393d763f1469d913c336f06b3ef8b3d9efbce14a675f10eccbb6fab53ea38edfd649922f4abe9824f92839fdbeed5a1c6c36b3dffdd9ccfad73292e3dc1ff92839913c07c7cd4b45da47ba032179f920d5cf13ac163cf28f56e9cdd8633bb35cc63cfcf7fe26bd914aefb9b73db63eb3d33fcffbf58d78f88f73fd1b2cd7bf89e4f81963d8b5a00d4b8c614af99621b54b5cae2761b0979c07ebccb80eb9cddf787e9c7786fba21f9f116c428e6093477aa46b450ad6d2fa842512c6e534524afad012fd6cde5ca622cd4aecac0e91e3ccf8479ac4e3364844ae0d12c5e9f3a26c8ae2f471b95e5c2e180c7f08ab1f86b406a3e48491d8e59a898f433bc27e3671285a2197cbe5e201a9282b8d48f265935c2e1d8ea7cf5bbe88cc5bce2863c853c353682c2b0c0b1cdf155ae0e9e1154a2249d692aed82137c52b560ff0e27b0096fa7a801149abf4455ac33dc0ade001cb0a2b5f2dafdb4c7198caac287372b42015ad686245772d6fc6b6461dc045f787a92d72400c675ab397f49c68e4009dee2f745bd480311a9045e7c74a30580667fd06f860980dcb0f2dc82383858f4b1e71c22c0d16f208cd3bc92a6615305f4e66f33ff33146d21cb389fdcf62fe3f7bfdcf60e2a4f94e12e329fabcf83f83655c4209e7ff0cf678ca489a797888fc070dfd0c56ad9561a97587e1c4b283270ccb0a4685162ab2f4f724f6542ce54a617f9b2f5291f43d89c1282cac56060b296c8a1c4c51253747a7219e225634c50edf14ab6eec33fbb52429cab0505c0a2ea4b8128613f7550ad2ca3c074ab183448a28b4f497457f515489a2498bb279bf8ae5ad0e45811345582708451874091628482876f89ec4a058f5135a9eb8f244ac9fc8818da052f8b8648017ddfd31200b06287d8e7d1a111d09797d31c0c5596606748f71458bb64ee4d3e40a962b4bddfd85b3e74aadbb67cf951d3aacef44148c6a78d69c68e204cbc33a6b5f4b5a40180b58eafe16507f66151084ee4e52c004fa7b12833d486f5701341f914f1305d848c018fdc48913f934494008125080ee274edc26a4fe8393cf56fc391bcd4ac05102ba6b683c7c046481001201acee4c7d463d664b121b42437f915629f60378807500a5eeaf2616733c9fc47f6dc59fa3c93e5f749b9ccc6f35353c6b347e001c65783fcf70a6af26c6f85e4d68d14d5c698294095f0a159b68a2f46113ac8f5669b6b7b0be4dcedaec56c2b09245378dfa677bfbb152eb0fdf6278665f56adecd04daf91156f672207dd353c6ba168795c2e1e9e2122b0915e920921116402c7c4345c62cb7dd9184677dbdb12142027b6a4bd46617d9c9b952737efcbc627caf5474be47225e16c5de2e831c67fc3f065c333c986675ec200632019a04a4f17c57286f569b8af7fdd0038dd6dc3336303b03a7c1f2f1cd39715004b7f219df91440a97b160027ccf48f947842f734a2841678660fa757eb8f4bb7d95f363c939430ea568246090268e9264016b30923800178401a5a7a9ffc711685d4c8e5ca652a8ad3275325a00170d103a832031a8050952dddb4ca95ee0e455bab12becf5a151c1f7691e65a7af80208430056f08f16a45501c4be580ef4898902d8e9eeaf265182fea26c621a3aa62ece24b4c8794893584ac269d3b3ad4800a19b2abdd75c4b13daf1e66713092cdd48287523d104899dcf4a8fc4aabb7b8a98ca18df9318ecf17cf12f152d3255a262854a132a8eb3755239628ceeee2322d05f287ea6359c639af4e32c12c5727644ed881f5c4eb29647b8600417dd4f6c0de7363ff887c95cfff67eed0c7f989bf74eafb33e901156ba3b93f482d888a1fec612b4a18be58c14bf868d28620badd25afed162980d8bf0a2082c4528757f45b8d7252dfde5a5f1dad97d3297f36b494b466def4b495ac2d1e1675b8928e3a3dd49dd88882b33e35cdaeb2f228280d57a9e1e4b2a5292c407760489921e18d0cfebc88891129810d24b08d6e44514f33a89786a78d686d8d2dd5dcb21bce8ef490cf6b7c4f587c052cb2194fab3ad4314d1e648ff92b01a1e9d1ee58b3c3549f96d600d4f2151a4552a8452491342a8855875b53f5aace57b4dc9f24d51ea0fd7fcb5238de7be4ed9614a521059ba5f41c4ba6d7d0541d3a2e37e76a7142dfde526ee7e58cbcfb98ddb22294b8ea9e759136b122938dd32cf3b2af521f869ee09a2387d58392dfab3348a59b9da90fbe1b5b921ddd7ba4e520dcf1a0f0f4f12916b83327e7a2d4ce98a12a9b483928d1c18cd6239c2f0acf110c9955af2479a54bf86e381fddf194e29573ae276e8fe6e5b288ddfb2748dcd37a5dbce57f37746e33756b983d20ab6a2e7d27aa5556a03e4382bbe0cdb1aae24bfb0c441c3bfa00cb2127987cce5b0d29276a78bb3d2a02fac167cec19c787bde8af06ffcf70962fc4462dfbd06dc4996d12c6c1ac5b46e7649eff75b3e8ee8c6fedabb996de66ed65988e7eedeceed068cdadcd4b6e7bf8e3ac51c2088a92a5fb8b121327cdf56d141c51a4b6dc247924b1c82d2f96e1d740ecb49bbf482efae62fd9435ae9c6a168859426514ce91d87a2ad159146a2e34c435a46a122cfdf190cf7f54b71deec133acf0f61386bc3f89ec42c96d29256e8281cc2d8065a24ff778669530cc2b429cec22a46bb38411eec72251151b23d7802c9296bddb0ba83284e58c531c72dddb54c71a31779dee8fd1086e798254fd9b8947bdbd168d4dfcf505834e27c2e3ea1bb435cc412ade8c6b9b7f9481defc8d42d7eecb93f32b3f69238f7475cae24911489be27319c7b1bcc560692bf6c5794f89166d976c8d582fee189b3a313dd274b247fd970b41d699db584b20543f9e27b12cb657a9f2cf168ef0cf7f5daf0b1cdb0cc8282a30caa45486131a7b11a1a862f1a8a43acafda96beacda16ddaf5a026a425f2ce6e1e7641e8bb9cd1ecbe5bf34d7af31afaf9af7173e8ba6e5cb42445ba219f587fb221a4e376d35f382a759b3a5ee2ff6e0b54131fcb994d19b299eb5d94e7fb16b6333d66ff9c2f702376bd9d670b1c7d2dd3dce0ff83e56c2034fd88d1568dacbd2dd1d163523b0d2d9561c72663cd2ec5581858a6e6f8a6e4f0a0f0aafce5413403449e150b20441ebb314cd47abf6e23cd7c7b97f5856e21a58e7ed496171a34d349c98504303c354c67ba2db63c04a6594ab33b43500ddde956ecf096f01dd9e021230812db2c07d11155be44ac54a977c600b9cee1608caf8be7c8193ee5e1a0003043a9430060f3e4005df0f014d28f1019aeec713c9035bda035e747bc00a0fd03c40650495c659f47314f4c2f56d368754b442f793be5c078cbea7555aa5f396b3033170e009dd602d6f761b2838e08158ccde9782e98d865dcd400bcd0116075643e8866d808a0d14e1ad0df06c40a63b97d6e5d2c0a781315a1a78c16df0fd78b8eefb80a3a3d303378fc221a50feb9cb79cb79c1800a3bb691868528ead2cc6c8e204ddca42a9bb8760b04e0a59743711dda983110307129882058adcd5aa400286e8f684e8ee93a7d4aa00911605486f4ab7178492035a13887512060441022ce86e1cde89b38153e64a932844aa40b3a60454957c982ca3bb85ba3b094fe0af5a0ffdc3d3e9249758a350b41487fd71997a0d9cf86ff7911cffcf6080c04b2bcb13b214c15df8df5db3bf3077d7ff2c0b18edaea3244747402e2323d3ca22802c49641161f761363cdc153e0f0cb381b5b20879912245b2d89085d5eec202072f686131818689b3d28b4514eec20263f158f8d0c262a7e673974cb5f469b7aee0c0150db8a24a671a3e6c0495ae805d9174051277c1dc65234529d76df18025b03ec60febfebb76f6d8c6c5c5c5e5a5c7bffcb97c6978a75b7fad6045d287e9bc3f535c00041c9019a25b0e38a2f3f3c04f0bdfe5a5da9cd7979804f74158a7c77df2d3e9f1b69a1a9a99cdc17dc41cd3f133c5f4dad9ed7e0eac4f5a9c4562952691125b946d511dba1fde24b324b94c8254846dd19495988a34973c72a418dab1a750c014a0146574b7a4c0d29222014a52885f184ef125c54f7f52e09837f7a3e8412b0a2ddded4a338a1244f180ee761e771750520bd1b93f42bbaf232d287e907b1b8faf160a2cba793c31465f71820a4e90d172a2d69d829a329c77928dfa81c1fa35b799b81e16e00363cc841cafd087d627e3a7d11f9cbb7fb320a63fb93fe273dfe8458e6093fbb9fb33f3fcf9d944d2e9a124a43f58a4b92a09ffe7c14a91ea10cefd911023d5f0144a428e609317497a936c52f8cab5cc4a5f448e5748497869b4577d2458145f765687b2159130ce1629c11349385487329e48ae0dba1f3e6d049b609ffc4821fd793c6b467822c1f7aba5cb650567a5b43263ee8a799e6479aff5f96a7ff0cb86255298fb23210d4b242bce4411badb86a50d4bcc44942f5681eed61221304019312cd810d32d1d52e8960e24744b070cbaa5438b6ee9c040b7744cd12d1d4abc10d32f00a1d62c20f0d02c20f4340b083c9a05841ccd02828d66fde08c66fda08c66fd80063762c09041b7c02841b7c0d8a25b6064d12d30ace856142cd0ad285ce9561496ba9b85a36fa466df4801e91ba9ee1ba81af40dd408fa068a8abe814aa26fa092f40dd4d737503074b70c9018ba6190e9bad40aac1b2f2d6f8c6e792ce896f7816e7911e896d7806e7956bae51dd12d2fd72d0f4ab7bc1ebae519dd580941a35b53a4d0ad29644c91c18b9428ba25e500dd9252a55b529656315d14a15b5dfca05b5dd4a05b5d84d1ad2ebce8561720e8561716e8561710b001b3ba61830a1f748b0a19748b0a12748b8a0c748b8a2cdda2024bb7a8b8d22d2a90e8161564b7a800a25b5410758b0a22dda2e2a65b54ccd0dd356cbc70a3053362cd3223a959660035cb0c57b3cc0040b3cc70a159669c9ae5842434cb09386896135a907ac105b15b2eccbae5420fdd72a1a75b2e00e9ee1a365c563035502eac1a0869560d709a55039966d5a08566d520a6593530354b4b149aa5c508cdd2f2836669b941b3b484d12c2d216896160b344bcb039aa5054bb3b43cd12c2d0868961601344bcb10cdd292bb3b66858ea18554806e2109d12d2428dd4222ea16528f6e21e9e86ed44b4c4c0d1aa8be012384eb9690ad5b42b35b4245dd12eae996d04eb7846cba2594a35b4234ba25e475cbc813ba658408dd32a2836e1909a35b4656d02d2319e896912aba658401dd32b244b78c1c21a30346aabb3b070eb878d2dd5d03cd8c86ee6e165a6032ebee9e82c7c909c2705f4f31005a42858b6eaf68e5c44d15e9bc79883869b52e1bcb0bfa2c4998cd95c28cf80016eb9dfe372bbb76e8435bd4f3f3f4267958a7cb251bcbebd35921d239c33496cb31f67fdbf1b82448db42620aad0c8076b94291d63ca2937744450509248defb7a313c30f8ae22be7cbc9f9726ec0bf89e21cb117804e0a434246823ca08e093f3038620b1b4710e9bea9dd320204a0d2fd5b122a467477df906358c418eecaa5d5a2bb8bc0d22aa200ed2e5bc315818b00a26d60f57e26673861b3a5255a4b492cd5dc65b3dbb86bb477366b38ef15b432109664f0a965ca64a8bb69dd22e201758ef78d5a44f4747ff8be51a83489be188ef9fdb903e7fa3f9e838f9bff4d4f2d7ddc9ce7c67bdca67fd5bacdd0d3329e467548e774c3fa6824a610e96e1f519c3e41fc20880b747719c451777d243fce22a549f4fd002129791939d2cb7f80925e4047490ed4e348900c31712420a257911b294a82c4932449f20f8ba29de5c4f9a26c8655091ec243323227c9571b3d742b5784e68199c8e50ec114ba3b012821d18d1ba33b53908aa412100ecb107ed12a15e9bc49b826a3bd4146e2df1e0969937056145f58143b0a2d32b7b0d52ab7b4e76510dd9d845bb9886e1fdb4cb26189748483adb061899b6861b2dde5797acd97b9b7d19c5aadab84eeeeee9a6edd08b4e7e9369f4a5ff1fd9e8b56140c446940142a4fddc65d983ac69334d2ed0df17aa450fc32fc9d1592021776a364c9e80e3b2eda5d954abbab1ab9abe270d718ee1ab374bb6b546a778d3fddee7ab0da3ac6b8ab2546e1ae9618136ddc656382bb66b76c55babb654b72179432a064e1ae161424505868d131baddd5a253280bdd2bd426d0addacf97cbe4e8b6bac2d983ef07c24650c9e5ba32976b0495684bdd7de4b35a6b96d412ca22a49e929d4f2997b9ce3b69eea4b54c5c5ebebff33dcf20979759672ece1e9e04b1d86dfe6665d373b64b126588a17b099d4d773edda572a00258abdb0322d239236a23dd600b5cfd4d66a55b329c6e0b7e686fc6de0fcf470f9dce8c36ea4ed29ab01c1c1e37387cddde4db767e3e590030edd5e4d4db747d3edede8f66ef04e9d141b7400c09b39f5e75308db4ca9bba1740b9604be5f56faafb4063ebd190830da3f534fa6dbf36eaf866e8f8619ba3d19babd1c5e0c1e0cdddd3f5a409c4c2a683da9323e658a87ef4578a64cf11a1a4cbfff3b0bff4814e99122a496132c9f132524a39d1f48481f9e9e6db3529ffee5f27dd25ed267767e603ce33b3f9068fec97ebeb7d91b38f30c7d6a780a657c697949cff843d1d2e0d189dc065a11bbf00dee1f9e35d2aba5b518b6b39a6b68fcb13883fc8b8db3c6b0156db560cd331aabb1e14922726d104dcc9fcce1bf9f7f86699d3510ffed452a8237b946a3a2639092d67e08d28ca928be88ccecfc4be33e893cc693442436ceec0dcdb3ad4ab6c7bf9b4a7d4aa1d89758237156a93fa6b8a1d2ef246dfc2385fc8bc53c27fb6af08e91c6fd2327910dcd66cf2529ce9a4afdfb19027ddafb3e545be453419b34649370f85ff4e32c029f444269d1f261d2dd31c0c3511b27f622b175b464c8c8918fd6d18e236f1dbd70e41d350f677493d66b6ca0711e5e6383bb8d0dee22addbd8e034ee2e1b7ff2430b5a3c68a08666824f62a5dc6389ce92116cc203ca280a372ef049241bf84a49e1e36984ff83c2577294a333882809e949b2be6d263d3efad0829f0b73e1ccf5915e45062872d2b0f03fac8f8976e4c2f947f78b8c3e27f269e2e29459d1887f77fa97abf3693363c73b623a3dca987f2d87ef1fce569b8d8a8f9b591feb837614c5c7399e6e836f6945f1e51fc6a5c5d96a7324d86636e436fff857238ad3f3cc29693c7c929c375f3ac9f2d2497a4d0cdf80fcd0719db74d5176042b79b64536d022c9f83f08679120d9a270f684b32797c911e84519cdf77f5e94cdaa24fca0b03e921223452d2342ddf8c316ba1fd08d80968f07bae743dbedadba3d9597eaf6503fcedaed9dba3d9397df06d2dcdda9c0ebbabdc6ffb3ee0c71e63a717fa3b4eeae0a5498c24ba1580a5d143a2874774fe8cc689c3b27f47d6a84ae09dd1d13babb2528a14bc29698160f193df3fcf16c7e3ca423dde289b5dbd8a2f66af57657b6742329e2d26e69ad214ce8c6b63bc71a585fe643929cc795e6d81a7283d69016b48620a086c6c559debc86c63f7fd70f5c1d7059a10497132674f7ac5b42c8d0b9b9690959028b93f210c9c9c8f93557482759954c2abe404ada47fad012e1ffa0fc482fcae6db408b245f2b4e7cff46ab923b5ff4b9654fedd102928116902c2ea9560c52e8560c44e8560c37e8560c30e8560c5d742b8611742b062d502f681a3a6839b1411837cee8a2594b3883f50359c314ac300147adbb7b85e30159babb5f40c2d09633ba3b230cc176776134cb0665b47ed8d0c869f9704111221ed231033534360bc3f4abc13ea506e63698e686296e733fac8f69726f83e56430d877524291227e4bf0740555a3d5e304dd413d7277db8a92a1d50387ee6c6bae8f6414de0962faf3420afa46587eecff483eda8c4bd05ffefdcfd732bdf76fd6a7497d5c5827584b5b2b2e6b38232225323c65199cb38b3fff68958e16ac14d37b27e8984eec619de1b4e29cb7d15a2cce8cdd264986e9fb971f532acefbe3d7485aa574f4f133ad142c437b491fdc17c57ef8d122c51c534cebcbbf980e6e9f897f4f6fde911ffc9ec4ca19f599f5d8d39b320a88ed87b8af4f807e92f8b85c38f736184c141fe772b95c24fee1c90ff43ece6dfcc6d24ac77fa3b4e9f8e55f8873a5736631f96f139fcefc7b12b3592b14ca6ee1b5389f5e6758df33fe3c91785895846f8bc26c8bb0157a655b6494eb09df08d32a25c929debf2569e9d0d1dd323accdb8b7fe4f969b1ae8a8e08acf03d46e6bd52b7b33af41f94f144726d102eb3f509af0db24133cf9f6b333883fe8372f76f54fc1fccc30be7fe4856faa25912fcb46994fb231863b186a75052ae7f03dad12d192c2da525635b3247badb5d59e96ddc6ddc55ca5c2eac040f2119b55c8a96d7dc14ff074f32d329e6c45cc3b29669764c81fcbb5fadc54f62549caf3ab1e7448c5fc49886401fc633bcb3e6d33f27f39f9c4c86b3b50ff7f476ff66bd66c714c931f54772ff2aad748e40f97b380aff96d91601b56298d2e2d76e296bc5101629125bd23504e8160c56ba06ce4e082d1880ba5b3898d0a2387dbedcdb72f05838f4642e29f74762b9b7cd197b58b5319c9fe679c8bf1a78e763cfdd59a9acd24cbeed6f34ac438e773cfe5a761bec59e9abff97b9fc320a587bc74f3375908eb65af0bfbc49fee11bcefd115b94fb2361ab052a74677bf1fd5a2d08b5bb30be1f6eb160454687160bac15a8d062516977d91b24be10127e3297bfdaa26ced116e1edd376add384177e3d60d2af3c31b407dd36a0da0cb1067c51948691649d208c36d8a408b55a37be61942a934488f1e3914e770be96a865638a4cf10dab6be5e474e7f060ca418bc692eefe62b1ef9acc5c3227eb1a50a3eb412b46e8049d099c3023d695a0bb234177c745773782ee4e04dd5d08babb2dba3b1074771fe8ee3cd0dd69d1dd75a0bbe34077b781ee4e03dd5d06ba3b0c747717e8eeb2e8ee2cd0dd55a0bba340773781ee4e02dd5d04ba3b08747759ba3b2cbabb2bbabb07740ee8aae8eeb0747754747753a4408a26ddbd02289ee846f24a2a4ae2c3d05112218f1129298201197921210111c17e8e5e4c8c946020d60d760ca8b968e91a9eddb796cb4ecba546777fd627a4d3e83fe8c33693948ae4381f178bc99c1c4b994f1b8be41f7edc909a1c7cc807390e9e83ffcf60345ec4499a61f9c5213524cd34a038415811f7fce2b541ce8387db645cde582ce65f29ca3ca934a844f1e815c2a00599526840400400000003110030402c1c0ec8e341d174ca6c8d1e1480026cbc70944e9a8ab3248a510a31630c214000000000004040601800da5246702595070a67ac4911d45aca6c382a034965414cf7239d03f1dbd778816be4fba145087c9359391014d78e1a8e486f16b600b7f2f8277b0d290930485149c8620f23e20d5dcee44b4f926b0e4ad6e73372e90f90ec5d11e60b79e6de843e4756c4ebcfc4087dac1b6063be67aa5865687b68a443e41bc63c9724b53ed903f30e5f1c55978897e789894a76c7f91a8eb4687fc4566c7aebf0bda6e0842ff9f4f4db004b3f55cbd32d42d3743f8a1e19f98ffe6a3cf36e4b8f814a8a3939662e44592a062a993eebfcc8745c690f74271de39046ded7b5eb3d85fe78947016bfe3529d7450887ce4fec1a2e51a56ac08a8fd52faeb9ed8e02346da65f545ddb46f526fbe707e1abb6ff7bbd2c3213373828a258c0068e63b560a727ec4c4c012b6e7baefcb63d44c6bbf0ee83f004c3b9e5e032eeea51ea69e64033aaa5ad4f818c1cc3919f5565c8179bb6ffde38e9aed05f42190b841ae86191b9fefb61cfeb50b0f71549761468babfb3fbeb226041bf4748e05e27f87321c72eff116b8e0ba7a4c066768889b414f2f887a653e9d4e91f5ac413c102dbd2189cf608617810f88a72fd9261a756bb651fffee5c264740b050382e6e0073c2972074bbca4f25312c8cd5860d956306b1fea0a5a5e4360483c4ac5598628bc5e8af5af02e82482a01cb3a4b32a18af2ed6af0d44b8d04429c2cd3afa980e2bbc8e1d084cfdd547eab7bb1fa65830afdefe5548d87d4ae7fddf6b585888c6d366e9ef4302635fe37dc5268035942f0c82f123505b0830bf2e6b3caad51e0423083183bd34bcacc89eb44dd6ff255c7d5e39af5bcc6eeb3faaab662865852eaca220c6274eb01f065924ceccd0db56be3feab91ec56be57852089f7a4a2cbd3ec120a3ac9f69ec203685ce3713cd0e175b051ad0a1bddc3923b0770a3ea24738698a443e1d233adb717297f138285b5480932103c2242a35e5810ad0988c9a0db995fc5e9d57349ba8df3d7bce7190c2cc54d240a9b76fd98be14e936350b4a3f1633ea16980c014e035053bc221e2ca7025642e3c3510ce1f505f19c1cf2ff9044aaf02b314e1c6dad1ba8fa351fa3d35e5a1f5c142eaf8b12f8eb76c6c29ab0c8eba123f9c9542be912d692317f9be6e06f74555834d7e8ae9a3319d652f8be85e067614b9ea32fd7c307afedbc10b8e9c6f4c457f9d4fc473c739e185d3a993878c8e41a55f8c261ae5b313c6db77a46e4db1395cb6e59442c7d717c3cfa4d7f1fd2df95ce174056fe766fc019811d9877328ca6fe682a3b0231b75f98c002f1959f7067148ba4ea2a754cbe8042849720af307071903b64e2a5fad4bc6f4ec6d98566ccbbc337f0e19ed7e661a375a33f43a6299de92c8fc0eb332b7a785e82f845b755befeebb1b978f7ff315a729d9362266f02a106437d7c7e98fe4d50a6469671af9446cb07553464e995f45f87b842e7d444b2a659e2e9f945c4585b0e1ab4360b17e6c730c8a0ca6e92d04edc459d47b9f3867b9f2169b70e7e1e1404bf2537a14b93df9d009401370226c646bcdf8969884953173a9c2c3ffd77b7dff7fd7076acf7d2c77816c35adb5db4ec2d5b048dc424f8f69185624f7ddc80e84184de3908688e07a20333ac5f1884d42d4d12d903e0045fe7b537bb5265f95e350bffedcefa5fbf8ae9107812aed1711020863a3c8cc88b1e990732fdac9b7207e5df5fbcafedc2f3f202f629ef1add736dc16c151b2adce86f19be8d78fb07e816dad6a1a7af6d7a270dbbd7ef636ff77454cd138df0294b3ed1b9b2362f58772adeb558d91002d2d43d32a28957f52e129f55a6ed7939948bce1e7eaa80f97f76b451fd07cf0da9b260ca8356c38efdb10028fd922353fd9f9c8de56e6376bcd3d55bebcb8c865a8d9ec773bd75f72683274dd8d972d374c312bb9f65db09883283e68279c6a0b8f98188b954731e944d335ea99985eefe001f1518873485200f8a257c018f885c62967bc7f7c56fcee43d72db973f1c446289853b191ddb8601798d00fc2ff9a4e867513c8a503f8aea189f2442a8898dc03e9f1bedfbb5a2c4124967632893789f463d65fc7e6f6a42caee79fe4dc79eb9b04d1a5ff815d0fd27995621f719b66caf5cc24e3f2ba3d7436306d8f7c3e60cb749d8bfec5e0ef9fc2fa6a2c58e0933a6e16daacb942eda128b7b2acbe3c9b5812e108a5ae5553d89a5bcdb30a5a54d49fad17f41b8d3276ee921791e46441f8720631af19cac30a62ab549351ea8b25a1cac67792d66df8df07382cc78e761086ef213cd70b1f731545fa0b7d8f5be6a89a796ad59698fab6af1c6e81e33196ec43d31364e88596f03026415f69e83558c900bf226f3c10714d593c2228681e5804a6cad62c9e3971e8e446617c8dac0248ff1c1dadf4f12a9d69a0c10d0770f269f85211fd6d22f917f0b40a5f3be6665b6fb156c90ff14526fe1118067304185cd5b5b070b8633bd48197e118ad13e0180ddf741bdc47c5c83f482ffc135312597322774218e8aa8c00f65446913dc8f245101d2fdbf6c7a6a88c70232443af7b1adaf5c03fa96760deab790a0537a39815081b7290e86839d246d9965fc0786a66155700f692205bf964a8af0e36ae19bb98d2e74c763929e1324badf7a9b0eb59d1526b05a53233b6989bc9d89e1986de73aa972988bedcbd262b81934ec9b6cd917952bf6f83a248ea9c33d0cd6616bd9f7436965b431550aeb5a52ab4b19a9401dbb109732863b8843e10d6163ae2777c096d8d152c2e15dabb24cf2c5cfd7b1a86178abb501eddad282865ae325be0f43d5ce5a76b01325a7aa03cffbd83a9451df0c8851359ae0a086987b2e44b1beac8e0b49a2242bccbc8b265619ab45d49d95a40eca675b7188b4a00f7891676db2ddddb48a4df34db999aba220e7d0543bf633b84ffdba331b278df0e9cf5cdb49fedc2255b35e886ce3c69c45ff5af360b1252d6bd67d944cc7b911d33bb11f320f3967983ccae954b7b57f4b1923293a32d6651de97955729da313395c461678f10484bf807540a41e4eb2e04506ae22e60c366226f316e3a31aeb0852b26f4279311a0381f354f00cab53f5a92a663f36f0ea137bb9ec94a103e22f3a3aa9759db3e721c38fa7a099043ec37d5d7c370b682504ba72cef8eb091b7273e2f588131a65337a80698d0f8378047065a276152af88e32add3d92564d88b2d0640bb7c396b1baa1316e46888ca738801db812632773516d2dccf66ab108709b0b0a6bbb3a8b1e3fee92b2e16a87c073270db449011b0df5ea164f094ca41c61c5b73f40228f7f84e9ec8eab934bf10eb0a1d9be223c5e3c687dcfa8a522b5c1d71128925768c3d25d3f09e4ab7b5abc12b3f9f9b1fd968c29f4ee8c405cbeb5b81f14023c79da94897bab2ae43be186dd32dd8b13b33b527bd3cbafc5b28c60fc87c0ded02016b2350056aa6ac4c28404d0e61e08a528762f4881e51053d1efbfda3dc1e82995a4d9d448a932a3260a7373a8b8fa53f1c3e33e02e64e2a80fdc6b60adfebdf20f183aa116fdf9efac54c81686feeb54c5c600f728407e68f9523a9a37d64270123dbeb969f9d5511e3da000b8a5d328c24843411b15afd3f8593a8440cbe2414358cefc841f5e5330ebe95dd12f2f5b03cae3e58dd2bcceb46f7e689afde612cbc7d8f1b305869af9ef6865fe99cd9e4b489e78159511ea85e1d901d7c332c1799ecfdf5dbb7d5832910bc9b1f1f5255011df11a512993ff43e10819584d4289ee2a08bb7b6caaa59e2aa4bfc3c83e7e3bd757696da5ac34d4dff8cca3af38915ecaaa855482fa61875aaf9f40e4fd07be1c3bd8e70ff2b3a13dd9251dfbf6bac15802ebbb1332682843cd5aae273f2fd5a863fece97714f68ac23c3b84fecb997d3c8f787bf29f51b4464bf71ae2dbc638ecf5e56225eff3b042fa3f1ece24790a4fb367a790e7162a79dab2ae2a6e180f03acd6750bd60ca03c7ba2f910ee9f4b0d9fa9acd8ebdea0f427a95dc77e02f548a72e8b8c3dce54f2263b0f4dba5b686360f457b69e753dd665475cee6cb93d0898c7d7a7cf96ef99dfce9803e6dd8e6d2269dffce067f65ab7be09b61f84b83e01642175b65d6c753d6ca79c326f607a5316696281613046d35aca0ed2afe20ff2972158ef399fd0b31025384e98d58b75f6a793dbce8d0e1b02f71aa6aeecbf453b56c352f107abe9767884790065fc2be4ec09e50673c52f1ccc53e3da13f472dfda2b0b4b1489257619416eff6bdd5b8f6df8e26894ad14c56e18838fed846efa33fc8718039e1159de540cb6b622b2ba2b80b4c1ef8dab647fa7edf1dcde71ca305b3927bc80a2b40f227c5a19bc506c9ff5834734713e3a7afbed2cab9876105358ce2b7f10841657fd0e4f143c6d743b74b061c926b137347d95717578c62c5cd4f86bf9617f19040c8068fef3ec3707d848a195130dae26f3879727e3e1c5dabc6442184d9b51eea036e66277eab0d6d609017c40d2be95aa8273609c2ae9e91332cebfd3ff10f7c3f7e8e9f9892940ae153497d8e761b84da2eba037db33eb10562c3fccef23bd37c2c5700f60aa80b6f503fde90d0c8c33e7bdd921d6c03b675fd9bc118179fff67188fa2b404aaba5d5d14f0f9c368d3256900f9b73ab333faf5d64b99c2a0bca61cbb70c9f63f945e3b86e8cd3f28237a40e161e34607805d3473b006ad7acb6fa964e023d81fd90a6185b227b746aca2502e40f69af45dcead0689a9e4d4aaa333c1f1d602552a7a6a854a5866292c282d68c01a12e2095daa83a6276d250906215d23f9bc44240344e68cd52b7834a82083d32a67cb29f6231688fe70edd7f4bc5352f8742d26e70945aa32d598f9e2c51cacecf0a963ed4cf5e13f4a2122c19f8ee8f17a0ad6f9dba99c609c7e45b276f007a842c7b0512587a92a659878b2bc2e9e419f6ebc3936faad4f77be8b38ad11644082e7b2a86fdbaae3c6f537f4cc85727c13d8c1d6060ec6a80f3ca027ea9f6540df40c9b139c3b557497eaabded974f31dd6c3baa89ba8a9a07ad1b95d98df207522f65fc89bae56625f90547055f82452c63c4e0e25b0d4a85d58a79902efabee28632b10a13c3dbbb276c0693508fe149a5b7aa1d1559470726c0bc01f672b217bb59d409e12908bc7a417523968cef1518f9880615840ca12f31c070f36f17bdbcf6ff0a2962dddf623bc4c7edcca586a81895bd3d2041747e8573a76988c1f2f29fecf1bcde60c4e80f618cd524c56e3e7a20404ce5024ae88957c16b12826576529440160c205f4e9ed40746f63610831e1f7692a2c624cb9e5f2e3e3c0360cb6b7899bf56d4b4e094afbfe7981d0f009e479e1f8fef07f0227ab9c219f63762d1f9b724ff66a1a2a7f8fa5bbf73b9dd7ba3a6646c91c0d15dc3b17752204e24f31f189010e27e3fc6b28bd1133274abc7ab4f4c5d261a46781057f5095332ab9934e4b3a91c31c67d57417f3481ee62d1fa5efe1882b23f6725ff60fd805b10e8299d23b551dbf9a7f7192dc51d131de140134816f3cf5ec2479444e485ce92f7a230df30c620105e9be36f7c869b18768a2c9c3c59e6908131a0edfe158c3ec8d1d071e18fb89ec83e1f906708998c0f1d78b967747e83f19eb2cf2ee9efbd98fdb5f67aa9a07e3991c898ac2da83d22e63968aae69789f01d4e0069c4ec532ae1fd9e142ddbdfe761ab10dea57622215ed477b038733bae9f4f0173b303863fe2e7d701ec7498ba0d7587b23fbbd257e4a27b92b204fa5e5243a88e2c6e787981b5b6ef50bcd7cf8c0fe575b32c442e2fcc398e3a917260088aaa23e84541f27f39920ba4bd8ca13d1c3e1eb1c6273e43af816e1ce1d1a745a725aa3bf8e8c4f3422dcc690f920fb15575e82a5c5acb24b41f685d460d528b357ea2b6bdbc88b4de39c7b3876ddd716303f385cfa6cef9f51b36f955abf1a0b9463c0f1730c39ca6bef4405354331b0a28d99eb66d8e1ab639f5687943cc4ee797b0c21bfc0ff450f7a30abcbc1bf27308a7ecc312aed7b2270faa2ccaa06b1a67dd3bbd8277dd4d3982b38e1b9ec9626a006da3ceda156da3cf1c7647d0b44d9c242ee9ba754f2527076a8bee7b58c19f86f7bf875c23d99e53a5d1567ac577e976f7942578579b920103c39340f8f3dafc13b23796b9dad4090177edacacaa562632028bdc7272a883b6cab29b34b9eb5dd527352d87837c77968c5546ef87947d7ca04c0ef02c61c97980cb0c242b24c9178d4710b1f1920f46aeea96e41da1bdd75f443fca47539f25599cac08a41b98e607b94305d8535cca2439a208de08d4035378258e7d085751935f3d5c6a64981fa5aa89a9a616b2c02d8cf15fc6497412c8456e2b94dd8afb8a75a9690deb0a756fbba313e3f7f965a6563a09711e09c6a0f26d05cdabbf7cc4c566154fdfc7387da2be2d0b2c53f2092b03670058d036f1ef1c1c5be1d44e94d17f005f566ba5fce7c70680c28e7414c6cd4050c8bf93fbd1fb40904610a33d71584a80df0ed7096e22ae26f7e893e091a7e974bcf6d5b1cd7f9ff643ee09e7504f72bec82a273a192276baafe88a931e4a7816122d5997e3efc79649b0675b8868d5022ddcf8003cb18d26b5fcf3610159a0dd384ac22d58846d6075a77cacf719951fee088fedef0010fe5b19da33f1e3ff47fd35d47568f69e1b2211bc509b0cf81cd037e927e9785ce3f937766273587c7dc199fdef66cdfb7814ea8257c804ea415faf8c1c05bb98470ef50ac17e614a0c69938eeb58641cb1a688c48e6b083a2da05eb90dcc0f178bdb4d78536f631fe6ad6711fd366f78f8386faca470cd6b2277c42823bf74b607aaaa4b78819b4bf0d2972f4928e1bc3c20c124547bc15c955a9227e2aa48ad39d08f63132f8339dfa9b01cb9cc82937ad7ddcb40e46c33b060c6156cb1ad5a033747f931210c293eb11908e090e8b81c3a5ed6720e35865164ff3cb0efb19d24d303daed94ef30a47a244fb9d89617f004c1eb0ee1e8ff67613f2507770f1a6ba15ac91bd4c0561be0a57bdd0f5181813eeb223af53c723e013e173a36d8acd816d4d9a6dc376fe084207fb0b0f74a0bf88a143ecba5f4269effff716d5e9a1df7de080d3886ca8e6fc7cc860d17ee2b32b7859df2b3d8d6e7719ed5c559d32322e292c109f11024a2423889e62670dac0755d355776a7c6e2c8cbbebcae28d277df5a6c1163ab5fcad4c81658fa2b0c42afb043c3dccc13ab539af4060745c15306930b50b5666e055c0b026c669c8aa04bd5fa43da1f2e418e7da65c1693ae687cee382d798e3a1cfc0a09ca5494eb8e02761d2c87d3addc0790757d8f3ac995ff06a3c76389678d24a1620e6e956836eaf006c5e5866adf85c235cd69bf2b13b3c6860d1cbe82ec113978d42b6b5004f8dfbce33d6881f290d0f7ec897d7c9fd8bfee566024272b67b82d0c8cb3c006e196b0f205cf4383e52121f076b8c6e3f59a4c7b473df7e7a5d1263c69248c13865ff456c0fdef9acc36e53daf0a0dde57be0f959a6832bb2ad051d2a9a32436e9b4c2a9e28f98f5e657ca8c1533bbcca3de1749189662c115426b4e59dd4bb26c34fa903415d5e9347f68ea61005c09cccb3455b96d1ebc424dac96608f76a0ac2483c7338c2b6ae8cf924f0e74bbcba55d06a8ff9e8b5f41f29d725987d2a7709ab7cca79de93e6f4963309f9d68ad137bcb1bad38868fd047d8cc2e5084ab6964c7ec953fac3ebad451842551c13998bffc30dc4be795c4c9471ac0cfa050f787037e351ac6c5b032a48a49fd67fe896e68466ea9483a30bbe1a019eede242fa2c2811435c5ef602b9e5a997957d959e22673054d9b5eeddfd2418f0bcfb0d7c0b4203de81d6643700d15696daeffcaf81bd0c32530afaf3c220b3e96d49fc863157fbe7fff777b05f613d56b898a8457b0ef57c3a11f737242031cf2eadb21d2d85e97b6bb0432ef55e05a6a8956a09c7ffb8d9d5972754ab9465ae6776bd129788b6807d702ebbf5f50cf82ed0f8cc04323367fa483e21ba7bbcd0df78f11197bf185e018299b9e6b4f8682a61254cfbbd627f4cdb2f213c403d69a0c8b192f2f0e67ceb82c4249f381899bd4b606e2af7f8e305fcbead9ef380e5836a5d94f232cda011872ddaab5376127c45299cdad650c699ab787164abfbec3c5e975f47e34f3ca266a0494ebeba0cc43a4c638b6197f921ad18acb54f318b2f8087c8aad19c42c662f8456d3c581b038fb539778c0f6b6552cc16e08dda9e0b4630ac1b256dbdd01487892dda0e2497219231f27e6ecae61b6944d73beb486ab5c8667eb8582605e7fea9e8cef779beb082740f73fdf5e6a4d189ac622eb4df9dfa218178dcc58671c3342eb9cf4815f91c113fc2b8bf9994b4557cf31812a3a93b114a0edd09f9cdfe6b5af50882c6cdfd13c59e48aeef2f07289c1a49879a781c104d2de48d3e3cc1e2e7280e0e2cfded429e8faf3492d65b1470175f5adf8b4a6ff2d2519f4f5437b1e44acdfd4a5251db032208d4b5664cfbcfba7217fb3612875c0b4dd3858458fde173404d4909b1373efa02fd41a907d57e0ee83d6397f1834c545b21dc674d201559fa9a50c062e349c6e305f1e99a97db13c6e3c31cd2f078612a7d76a776d85a1de91cc8dff3c39ee41929dd7cbac1b6b982c755a7c006cb5c2c988ffc8815beac84968842723fed42a26007d9bfc3f04cc5ee6b48f5fb0d61c4ac464bf83641be03fa114f36731cc3228fa43fde60b240d0dfadf04fa7d3a55f644b20b7d41d2e1413956c3b23f8579f70208eb0c122676b3a689e1461642ae90fcebff4b6d0f2704ae621811037b91350c7258170d0eca7d7f200c6fc0ff122c246e805126d76ca2fb273ea39217d8c7b79ae20ecac1c3e8a326bfccef0d3dd0b0d6d57e8da7efb68761a08c8b3f6cc55acb749dd84c53494480fae7ac306ea8758419848f7e221ff96093d5d347a6ee9a7853f0f269a00b988df21762e2e1ad6a4c175f548d477d14705e00a514f86802201e258e2587bfc217a6a1313fb2172fbc16ab98a4b744ef3feb739cf001ee0a9f77b2a13bc49711be8ecfa0720a37053543d05e38ee3b7361452a4ef862d6a1e72e3affecd0cfe338b93d1556f6f6dd9570edfb42ee0dcc6774db79fdb7f9312f9b6f0ba3b5d111ce666906d3bf8293ede4cbda1d5db0b04ef77e86a8b4bad7315b0088af0dcb6e040f509a71d4bc4bcdb26acbcd9f4b8308f70a50b95102034ffa7c5bcccd813ff1eebe65b278a7ccdb843f4bcc7b306b56f30f3f761381f368999ac51a92638f50f0ab5b83aacfed88fe6102716d7786517a7ea2e9ce74013197c54f3ae31eb59f8d3eddfeccfe5ca05266fbbe13b4b54ecca7d28d06f33a346922dff9d51379b6dc810528bb1adcae77bf262a1c5f3eff77ec742b40ffbcb14fe97cd349e59d818401501ab81c07adb0efd5ae300987719e5801f8c62dce22a1a90828fdb83eeaa1f47f27b16e4eead34886e1beab48e19cc865a56fccb6b731d7d155f70a2a4ae88d9139a79ef5bd15a95acd00d4850e320a4f9a03cb28555c687df2826358c839e26c16e97c63e8e3d534d76a1e6db9205056e16d5e1e3d9f08ad3d7f9f69443fd5fcb4b2a0baab52fea21fadb96894bfd26abf3ce53b195ed4c49fad8c49aa382a8367c775e20046decbc8b5acfa6b2f851006705e27e3478e4a37d3976171a943a7750e8b60651f718d010fb5e43c730b60fe79e3d34334f38d209abc1dd72da7d84488b4dfc676465479ec02c9a7a3e549821dc1a1521c297ab5fdceea118527e98d2de85252b0bc17fab1ac3489380859f940f38f026f9f9e6c58fc4e2e1be0518d591af9898a3291af0ca6fdaa9b4e973fa4584ae6a0345cfb95657f5b82bc6ad018aef840e353db384c34d8c776d0510a35db053bd8897f3c35616cd1f77a154043ce832cc72dbb1da11057f1097e733560c92b192227c30e802c1f661340166025b60205cc9e8ce9bc6836d9a771e39a0d861b54ba39eacbc3e51fc849132b7c68be21fda3f3871e61fea6883766b23a44b007c729afa18d1369b7a12d75d6b571c408d40fab701583a6843b19903f7b92f40b0a775de9d8b62f088fdbe160638f6a4f239eb994669e419524f77c019fe63ee8fc04a422f21053737fa0615a0b21b07be1718376ea28ac6493903a3c40a26f6e209ee0186198c712cdfbc74d340d56ef63795d6c0fa391c695ef022351b9af981df982b1ed899bccd7dd51b4d4ada66e6bd4557d5f1f16ff57853eb08ba35fcb52263da1160873df13c5595b9ef8a4e1f2f7267487c9806271ecccdfa5a41f0ec32a082cbb76adfaceaddd496c027f9100133dd80cb79af270cc154e68bea6b6687414b15946cfa433371d14f1c73132c61590c5b984374236cc73841cc9fa4dba2f5d0aa0fe4696d8c22f64e06158ffe912a905342f1fcaf26c4af752915089ee32487d7c6915bc64baab3785b71cb91672b70153a923e36118b05bcd6ad39bfd60b9d0a4b995338f63a47fe1027d4ba2eea7dac3070a8cc8424434ea1807c40707762896a1cc2cd2d71815de59567b74f73ac17c627d0997b03d4cfe1c6352e110fac66d1a7f8a90c129895c6037500a532b902b160a7fdf3e26dcb07425a6c116004e6adb1c80bac5488f96991099a3ee9e3701e3e3c7ed5b5d429a0872c3a2ae2b3a04935f603f8fcf3c6ab25a18ce21219286f230e4087b02c96d5418cb777174dcae75472cfd921270ff72bb883887dd7c94d47b059cc70d2332d31f3b27369cf84bd8ae8d75668e0fda14023018a149cb2caecf0402955529befba2c8874d6b6ac540fcf1c3d39c4e8d33946a36aa0b987e03b2c7bea76eb344eefd4a36574a891aa9393c6917a42742f8995ea83b5cc9136c876407aa08a086f7b90b7057fd85aee739e89e11c499ece6fc82567be64818b101298930d9b225c9996d342901c85b95c7f11bb6a22b2aec0f7d8cc6ba46e7c7bf65b25dfb92b4d9938413174dfe0c355b2f7141889e4286651c04111d7f11bdf2fed7377783375f80fa208392315ce5303deba084600683f4b1830263677f7481d9e7a0458d96820799bd3bd3f6a01cebeb7d788312002bacc0febd9a2008f9365a21e8fc3d69a160dcf64112211a25f458822eceb49cd5cec00488b0815a9e4d29e50a5497512407c9cc410e0da0763061f9e15ee88daf26f32784e154deaa024a04922549994116f3a44904bea042344630f6c26785a7405318908471164e5b208dcb67a00e1d9292e7c0b632f673c8562db0593d5ec08520a1533c253aacfdbfbcdafbf4535073ad091ba49c778c788aba6c1e1e17140c68ca62b4cb93024659cf1600e6b2debfacad042ebb4b71ba93e637deccbbd07ad2e314ecd81264c644237475a5517a61036a90af1be3b64ec3b840096fb31fc1bff7d329f20a3ee1ee481b6ba1a9b0526eec0d046d80d2047aea9707c7cc18e64ccbee99e6f816ff83052416f9b51d28e4757f743f37080f670d92a8010bb89608da15a8aeec3c186d691e762896703e4c5d817dcf4b96db0e5987eb205a41ea7ca3cc28aa93793d83dc26403269bdc0bea8f8e1d61458fd099b11a2b38119bb5b9c508dffbef393c5251065da74a479331bfb9d52e015d87d0bae0fb67df58f63e4d7d1eb9479c759eb4875116b78c2c1228fe15f951c48f1fcf070c1f75fb276de0c1391d67b4134eb19f3307aabb0bf32095b62f832ff605ad12835e04fc873c43c43b18f9e6b10cda27206de9c05e0f4d36b5b82c1e8c7591b64c7802ba683401cc515261f80b98136c2874337709d2d865397108ec1181f1f1a10954a648cddc9ae140db7bbf0a04fcf184e668675f501ffeeca43feaa7e7f30a6027ee096eb0906fbe0e664a1305191d9449aeea06c48b2e65830d3b59a9f2bad5de7de4287ad34eb2651ad400639969672aacca1fc6d7c032621d2ab9b8e1b3db647f721fd2690d01a1f0b1b85769a7622de0e8c92567049a1d65581a536abd0882ead34c90dfcff447efaf926713e3b07ffe11435fe9656cf0ee6e5e038fb24138ec9a26e8cd01995d05d3091c36c1a8dc9e7463e07035a59b2d5cbb5561ee5638e586edb7286f7b3059adf12a2a5151c30a6334d154516f35c86b12f5b797f46e270532e96f0c5b294837d547467a01abdcbe2c99e24336a6d4ac115f8d17b764eae827f13cabfcaa525d3d94b2f59863141dd4f13da5338464c01f856145b47ecd3cae7ed94898b3b08b900b79b27169774b79b7a8f5e6796259e1861febbdf6077cd216c115447dd4c5e58d231cbd70f4e33d4b68d116898d03a054485ccd765b04f3018b803cc2f51485b526edd93a000786c569ec6701a28380c6e18735575b3eebdfbd6da8634b9eab38bd1f23518d2b35e16f5b49ec81fae10552731ce3b79b74997fa0628a00c06b40b31a8762ea4fb4e9cd07ad6374cc88a6a4193d7225a2d47f0b68ad72f7d2e2a7eb3a0aaddcc60bc48e07c65aa54d193c1853673127d32305574c350db8f42e80702f556e8e490652690afb488db81b00ad1ea445e4e8768222550a0146a8554972c19670677fc82bc34891ff4c087f4df23f52b89fc49755640d7ff151c2f67cebeb9777bf531c61507bb14998561fabcd2bf3d5b5b5a0f118850e01d2450913527ebb749ef78764283e03e04c0314228aba77ff029084bfdf29867554a61f4f1ccc326432c69b02aed67e359b9dc27ab98189adf50de6a30c31e61a111b0c145849f48064ef77c4775b03ca2f12162a54a05bd2994dd82930cbbafd0e91ba1b310a3ccabf364d5653f3ad26ef02ac1e564726603a7dbe087a62700345325d6fb925225ae985eaae6de582fa3e0b6b707ca6b8f26628c49b787069394a458d965b5cde5b56bcc2469d80e32dc71397d8d45a5358ab60cb53d125854d0b6b74b9e17dfb70c100fd13fba1b7c9710e42835d5813805b35ce022e80021b889b11233413e6530890b1b5a9f47210ff708ae26908d790ae7f6e4a53007356520cfaf994f638d9a001f829aee4676c2b9e1be79d9bdf4c931c760bc9aa5aebd8df0fca3f2a8d7a6c279c02b6e63396a480226816a06992ed6a22b23d4b6599c33777a7cfc72d599226797f5cf8bb95567b9943f360d728d7f39d3137b269920628f9b5f840ebbe354df0e01abb0f4869c2b0f46dc023c98f8507e407b0f54095900bd68dde1b319327bb482dc7ed073c51dfcdb928f05ea973685428efe4dd2e93fb9df0f2cfbe90be30ee6e71ca09b38df7c58e8503cdd3e3f85f42d694c150637a62e466c08ec1bedef74cf246ebad78a0c52dde07ac7f823aa1b3fc8d2566fdb7d3a007bd3fe93ab929c323fd8d8102a309dfaac407f673b22aebb5a306d6644dd704af93ea49f37eb375430f650a6f8f7dba17b27a64c4ea0fa540a161eba7302dd67e02c55f4d90a4ab345e52ebf9468b0e94473a3714ea87dd072ca79cd0aab1384d1b86168a55bae15cead8bdcb5b0e255e85f236c2c7f7c0d6ea9ead773ff5cc0a7904e0ab40746a177a0992b55a2dd85b02d47e7489f51c584b62ae09a00dfc159b9305f42de551a6991900b59c9bffe20b083f152f1bb59c7797a09e4487193deafcb1f7c6337649e82eee29c3e6b3cd5e49efe1b8a5b3d690e41edf94bd9ae42e7d6a802d89bb9ba20fb93713d96f17ff7803507c3642bf2e2b11894fa7f07000175b1bbd643c6adc5dea89703d30e1886b80b39753615f67092765ec375899ec62b5f30dc70ed44c9d283ce2d9277997cfd306cfbbe832dfcf7fcf3c7fb779fb17c1ff5719efc0d3044a5d80b127c01afcad8ebcd07122f4f6f1e6f2c65b8dc3809befd512435a1c49d978ed3a57cab6bee25ec1bee5107952fcf7fbfd268f222a1f00943e7ece43a7b011de14c29a6f1cf42ae777a380b411d5d519284702e14364367ab8ce1eec2b21b84fef34ea4b1647d42fc5dd935083632312ca6718d9f02c46818d8d4f4f5eb8ce67ce9d69571aab9bb5d3bba0f63d22e96f195d835a0ee54c5dfcea44283374c984f29db486d1367d6dc24c80c8b9d156c16d35a6cb0a824eb352ba9183eec6ce60d18da65f3a8f091bd08872b5158e78fecf8d91fcd14591b7f45f319b68b1b67f5ff0f19aafb241dbc3202dc279860cae6a3c8b88dd42682ee129a8cb7dc6404a2cbc3e73e135f7ba71df9a0cab97f927b8710ac2f57c61860bc875151ae68074cd0a7f6307e1cdbfc1ad57e354adc2cf98ab43034ec67c6e674f9243829d6ac4ce6aae11ac8459291d59e6837f629bf0fdac8fbff99dc2e92abe6e4034b0f1a567fc87d45afe772e8dc323af77a60ca98f5aed0f1dbe4ec075bdd0d3157e57c320e1ee3e2601fb0e04a539c913e30e0682199d67bfd148fd67f35ffbf08bd837501805324d5c9a157a4be54d0e504c0270c4dc951d9db0f60cefc2a81adb04c78515864d38a62807a4d13681db7eebfeb4a0edd0ccb486146b4678a46c15a83c059638a3e5c886dcbdb959fc973126ac6dc2f613f030dbbc1c6faba852df488fe23c9b5bd99a826eff9dd2926d3def087f4a5808b69382f2ea7790ff16a246f0f9fb2413f1c504de7a6f979d126cf3d4dbce09562d61b86b78f6f6c0eb082e3e0cffa6c2209c4b9989d40a57af6c37100e1955998e53d6dca21ec028453d1cd283054cd1eb22d1119d43be541b9190e8d88390f2b0d87e4c975a2828becca0d749e4a7c94921f0d2f8df80c74a5dc4fa31745c4874eda54117d7f63dc1370ab6dc6460e297265ee46166aa29d616c6d21e470ea2fb842b27fbe8e9404792e071971607d14841bbab4b6e4a847197681128d71bd6bd6dc4d8748a624df32c0bded690c27f2a126fca5a0848741ddd56fd4852a8e58642a4c53e72cf8f0cefebf486b2c73c8166014fdeaef5b014282f1baf01824a68a4b50b94df61fd358f8c3fada3d807bd10537f29c6efe26314eb569461db1e5435fdab2977cc05c94359593383487e730b0e4d43efe3284cba4b7b5163d20e64fd2794b685beafd35974033ab7b0b060205c34ae1dd7f7508e80b943346d9cfeaf913c206dc17cb5a4e01bef06d5b59c50777cce8a6f8ec94be9cf2243c5245ece58cb91bce7466ba4c1a9a55e640d655ccd7081b9c4191360c6c495f7b7cff9dea3fc7e717b9098412286cc61714bc0ce4b2e32e10ff61457aeb310bf47965fcf230959ceeaa82ca8da8942700f7594eec7aea61296213a1833891abc80e24ac7e46d049342c1d7852abb3128bf5fe3c6228794622ff3511e023a65a00b7d17cb862a37ceac9997cbc80ef77df219011cadd68ea7ef074d71d692d8a74e9f952f07dd256b643bc69e2757b2d3bbd6c12fe714a492cfcee0bf5344c2645ba9fec19952bbe6aae369eddc95db36210d4891341aeb9af10ffa3b306c032b95258b584c373a62c85fc03620bb978837eec04ee2e3c6fadb830bdca0e0d2864bece24e40d4d945ed651790466641bf12f8118db49198938219fc2ee7d1022712cf7c50c6177cd296c79a36ca9b92bc70487055e96b7666504db1d6e3e8f08828d72706520cec7b74ba5d46ea94d2b2be8c2a227e581b9cc05808d38d1a3c1f9cf7fcab2d86f0d31b9c9adeb753279e41eb3b7f68137835f86d355329aae74b8a9a7690c0ca51a517962a2f725928b97f0b71e823be8d0bd66e2fa9af36195c51b79e43d48073756376893566eb589af77adc95c5e7eb540993dd8203e5469e02987ffee98ebe0b1565cc1f915618b76b6efa8b05e3cf630bcac0792a3de3d2035c23a300e8f8a6604059944a54e20bde8f3446644215eba10cd653e22f30849fa9acbb64046e312a06a79b000f44b0e937d5b31a0407251f6963c1ad528714fe1d7336b29029dac31176288be620a84ad2c10e4a031991e9f24e63dbbf693764bfb29faed70f3dd7e12a79762781bb7dc70939dba08047d255d7ed93b36da11abcc9990c0e8111e6b3e4047eec6b526fa30298c813d54397155390883cd2e71bac367a8223447017907eac16320425ad7cf82c8e5e9dc1199dd9a2d31dc26eabc134a2350fe825af783789799348d30e8e932c6940bc6cd97af0d19f7dd83111e08a90caf9073c6e75d08f96517e5e396cdcbc91a111f64d68771bfbcb80564bd377d3c8e0c8bdbbcf7e815ef64f43151fbab8f6127b03b417d28dd93236024790ffecc9defbdb4e1933413aa7cf22fded75140c0a68574f50d7867c1377490b724831f5247b70a37db2114742838c18fa00ade8038101a607a8abc60436f039ae1132c819a2271d8205ebd870547bc20259412beb5de1a2a02ccc7f515d05720d5faed43db6140001c8493e96faadea8e6ac364928ec751d65ac93a76c42c15c89d17215e03c9150e1141792d57889c03b419b68b5449009cdc81da949b256b2c7110b103a56631d70e12de528416d94dfef458128af1c25002bffb1a414c5b33533a455ac5a9ef5f96b5d0cfe9480c8d754bc10d58757253f3a451e5a7bb0dda7df2af923ad57a34d4d622cd978b18946cc32892882580603bba4faf61e17f2989d412acfdf92b0aed8d3959d88d11d494718f3806b878ad6b29f51b1b6628fc5bee148e27c4749d6426ab8822d1749e85bc1d6970fd2259b82ebfa25f347466f13ed4c84ddaf621be25b41ef59f4c945e773f0b2f340140e0a5c3ce39539d6ab735c0a42dc8801ef23a512454d1afe5fa333321b2a5d3c35018a148578632dc6653e02df72f42bcde42a042cec00ff1f5b726f807637b52c9a2c14a08d8987550e227f9403ec56352b5576fff1fd624467812450eb668ecbfd4afd4ddd566be961edc96b71dc805890e51fe9749eafe5c85fddfd67e8cd2d41bd6342ebc4892fbaf2c5bf71d361dcfe8522e930d23ee3dd3c882cb31a464bafa7ef9d616921f06734c15a599cd718a7cbc757c9fa9b7900bec02d0ee0f1602625a7fb537048c37978fe55fab1c6eac50c81eb38d6db63456f9d9ef5fb4c3f864e07f7454eed6f362fd1e524cfd970f70ce8b00471f14c3fc450d043f2f74456d5873f514a9cca1128847d6c057bd828ab0abb9ce843ae0da0b7a4c7f80efde2ea47b8fff6c327b44658c976085b07a221a9a2c0da7e69f9808334595a558614489adf1e6c6b8dee2f183a3595b8e4384dc19d0f84cbc5d600d30bb3b2950677ff63481cfa975b003f639868941ddab7e39cae11ed1802bae614dc2990a13099c2ede7e1eea6c3f0c22dbd33390df07fda19765bd8dad27792ba8e36a72925cc040741772e4c2d8f2ea50f8d4b590327c5af362d9c424caa93ed7b6fd82a904566606e07614d3ae3852fc9c1ee2c8a02089105d845641bfa3b6582917628c1dc316dcf3a05344f5652a702b259394393bab70e1e8b5e74fd50f260f657bdc622d88e4d0c0770c7dae3e2a3a1c69e5deee2d787206b7d3e858d718b60b94cb1df83a37f1a5e0e964640555c6267207cb100e224562563454c018ba0989c70cbdba26744ecbe12924bfb8f11903cdce7222d876cf5010da15ccd54f8b434ed4a0fd6e003700d8cfcc1c0a1fd58d209414be4c1a2391ff50914d7b53e249c9b4edbef97885c8257465e5705dce8fa80c5a0ac4f443edb50c2dff7c7567210155c24eaaf3d152c0eca31c84c2f297f0e38f2590fe64fc09a248ef3695d6b8fe48aaa598b577b531a82c061c855e1a4cfc2e70fba60d4dba7c339f81d46be32327d7387b21702e41053e4d298166472f0225ba491a371a7926cf922c100ef1c889f8e562c7eb2d87c9de45c4c30c5773e6b2d67da20924a0a9af3fc084b259b30edc9a2502f6fcf605120b0e4cf354be3e89f85cc3191f547a64c789f28385f03ad2b770fa05ff572208cd0656daefd975e5e531bbc257d95341e3c9d8a6f0b572acee4209484c441696066c5e431ba08e5910c4a027d49b5a01bc516c008d06ec8e88c31aaf062a0033183bb67aa7734c2096978857decce5e156309a28120f7b9870266695bcf8c1b03db76dba40f9cbbf00ef0121e89352e40e5e2aeb4f450a7dc527ffc5dfda44d659083d0b24f0d02411bb096251510339c2400d2976d64fac637d5b721f876ec2b74524b6e949e4d620e2714dc06980db314f87d3ba168d77687a9aded3d81097d85de4bebc7db6fc73f432adc73476ce2448ecde6641a12955a70a71c69bfc130d9b01b9e8f1df9a17e97510a8226035ad46674c7b329feed29773aeec130a508db5e80a8eb7a26298f2dbebf48689623f8956b5aacf8b021167fa3bb3b01f484fc1575d4c301dece955e92af24cef14abb26155d5752d96652f59b9e9c89a643c4867f0ad080d35ca16b08a0c722639a340ec914eceb32cbffa0760a4f765646c1216ac7c81eb5859d548c4339c9e9a9ddd93d6a8b5d52ed9e9c9c1c63e61ded657647ada2b70c8fa3cec377d88133e729563c2cd00257a0d51aff31654faf788737f57067ea11f4bf0378448b5e9807c60f8936b88fc33b1a1e86f4ffdecbef087b46ca5300973f05c0b8017d9019f9bb33f603753ca72e178971c71a020f0c1a8612626994e04d323a3507fcbec7f99d30c780b4b13a54046dacb4c88a51dd6b849efd95b716225d5fb3b271e3d8236479383a8c1b5231623a060c0c1d0f859a2ba3b598b1509f3b7207b0c76ab0c6874b1f578a8ba08d0875f7d1a609fa2455c00eba492fadb971aca89cc5c070062354d36cf2071679905d93fe0b9ab7bc806e6d05105269a3393a8999692b4cea4c131faabb0037da7942eecdafea6de947994b4e71d71751baf8880e5d5dddc9d9ec0c1d44b384ea3ec415fab8611d2bb345bdab48c533ae6641832d37f41013e2bf6f65048fbdbec277f34bf71e1b1e70a8d6a11386af62ab661b2ff55a4469ae39bb6310c694e44f116ed1071978144c5b61749565b2eb68cd80c838d18d4b623c8ccaf73efd9894b45689b4aa7ce3adca39cf8ac15ff79c91f646ace45c17f21561e57af79c0f1956828d2747c150e3a6a31e2b57d7b94768851430a85ccb7c39d936aa3f5c2eca5868099392346be1ff9f6e29ef75e33f849b59ab26c550f92359ebc432b6788216b9c3c09d8005b4026a7b5b05a48f5d51a833226453176d6e685586113b9b948f622a9020c7dbf464e0f68a41420cb2205b30ab9dab51dd9a1bb5248d0cc66a0b1b2d85ec5d66037ffc8f4fdf21b1173301ef4f3e22329c3228bbe97aaa5374f8d1fb2b055ad79b85daf32df9a0d4d61d1cc13dfc49ad052d1a13909ac05c2d475ebb4120e90600528e90336e2fcb173ce4ef6d3c296f17fd5306b56024c833806812d8f7efaa6428467decf06eafae7c865d8500844b046a3ffb6e08ddd689e71bd4f2c14ca1fdddfd04c23c49fc231e92de996aa6580f9602486bd9deb0e4ddd72dac55fdc35a071a3c1541e3cdf85f1d86f655f493f42eff5cb0709b71935b5ddb16e203128e21a565e03cb594be9f7098f8b913e698e6f6db3392efb049d0c3aa040d85d6a70b473c5f42178c35755a0d06a19d27e90fe4df2eb98f36b24cc40a38ebd04b62f97a6dd36dda7df6c2c1a7b229509d48a88d06fba0e33739f9a9337962c5c871a96a8f67d33085646881faeb2e4c3dd743ebb120b935137b07b15c9c218cd424cf9833cf930d7ef5394ef7a277564dc49071ce7873b7ae586c6dac2dfbc47c82030ccc4912bc1a1bd3921359841244295e1cff436d3c3fd90c4677b201581354d8062af39bd32b22e6024538b66a703fa0dc8895f198a1139e0a43956eeab9f7459b0f8e3288fc9eca911c93ed622a8c041111797f6a7fdddded6d2d76d7c5a9cd20d44bd3af503d6d592ee37e06617bfd87a8693d6570ee264ce46267f25817f2815c02bfd085a1bc85d36c7421c6890dc6d05632a0e87b0954a7acf90dd204f534082869d289e4f88dcc432ee81f99f50b1c7dabd140936247a28a7721177bf06d66a7e14b3dbf11a986726e71eb3183a416ec5fb00a15a354afd0c21ea91fc8dfbcfd2901ffbeb5c3519a7c841fe8f267cbc3af46377af08624001a1239b02a441cb0cf308663a9f1ccc1cfa84bd219a4673074789148d045898a5890cd49a5ab292782a3b1d7e8ab8e9d0c3d2b0c32e76091c83b148bdfe1360f4eefd055090202235c558ae7403fa08311500692cf1a2e8fe023c49e2a66df90adcf7196c3a1c1f41f2bb3b2c05c66ef11c178ded22d95caaa43b83ad3236742050404a1d2113160ece6e96341d402fbc649f544b67208728d295e2434295131dce7f47ed624e6c4d761ecc3ca049c4153b2ca720a45878ed04ee4b79f407f7ee78edf18657084ef437331305510bcbc24ae822efdf164caaf725100fca75267f05da2160f8ab1c4be81d35d585499c31065148c7c6e70c1c99f0188413a532b25025b1c0deeb70470a2dfd0ec64120edf3cbb670e00e824bd2a28c7b09f28ec6bbb3c9ead65d5a323b88fda27de120fa12083a98f30b810444a2d8fbcbbb034e2b81134acef65fb993fecc3dc598184a8ee630a69b90a30d8df8e0ffa802d362ae3d2fca3e153cd14e8f3e6055b502d21d764b7d1f192a7a7ea5d6424008d9f75318b6a4d07883812e33d29883709a2019e227f4d7317a4bc675ee1ea4eb2f07086ebf988ce7a876be1364741c1ed46607db4e3657a9d80458f238684361d20207e7503051c79873a308897e93d518b9e6e95412fba99be0edc15dd08dbde9e5e00b43bbab66ac60722ae8637482889dba7fe97f0e1f3deba59e2309f683e6203886cf8bf3139867afbcd9c6730b7b885f5e3cd999575e899b94264a1162ccf4e43cfca8b18bb8d189487ecfdb5627d04d51a8bea6b0391a52a5b1968550c43ceec9a0316ab453c46664c742ab0d8a30d041cbf5a0f4d50ae58344ad84c192cce3f22b8f81aed3ac823a17ae0998afae326d507beb8ef630335c9679b268cfb66288b16b27d97be116f3b6b9a60dd00fdb497aea7c2d5fdaf3d9e3d533d03e770da6612b4a22c0400fde7f400c6300648b144cb8ce7ea2b3ae4795f439885d5e48d1f8fd7235d0eb380f7ef3abca601b8e182d1609fc9db61aa916953a8bb8cfbb7bb5a673d433fdc7ba289527df8570b78aed600839fabd0bc54102ce5c4dfbbdd0ab9f6b18ea91144f6aa6d065ad495b2e7e1edac4e223aee17c61b218c1e072840cab720b109018b625d99b8c1542fc90b518e4c503e25c7c6eb1f442b093fcb6c5536587f8c89731ef6af3beb993feec175aab7e0cd4de1580d649978c9083ff1717ef6ffbdaabbf12183c67bb22a482ac137b756fc867869a8006461b3bc8f486d56a856ecc1948efc6aa05bde568333fc376ed8d8056ea7c18964310cf76561445996c8f3c9665feca50ba23fbbc8331120730fdbb4cfcc27e5938642bc9b614ee00bbfcd494bc032305f00c18eb3f58b8384306df624a9c665a5a95f83be99b9d30446acda1ff8f334bb4dd012065f7a90da755b65c0b903b353c8229fef0220dd020d25127cd80501068a25b41be577b1ea6fbde0ca3836b75771f8ac884400c841f5543a46e20128d1c7dbcb450d3e25c5ecba7c91f6338fea27729dec61f265b657c0e7565b2b364c154dd7695f511172ac96fbd8278a9519da5e21dc679166f4d398f9ea3099e5e10f1a9fdef9f265e8c775fe3d9a1dc7a1077cf31031deaebc95280816a6013c1edf54dd946c579efc8e2f1f57d84c18df1e6cc15ffb745407c5b410ff81aa7e127d4e1a2359660308cc84f7dfc0ef5b321bd7041b38f14cfc81985cc8e3031794c1582fadb81ab905fad6b4af73889a903ea7a6980d03fe89c6e8aa2656b8460c4e05caebd7134fa1c24d4b3d9dddc0ec087acfa2b82aeb0d6a937d92fb70b731d5b7a9521dbb6b6a5a524bd51dca27163fe58a5423824f379de380a4564a22880055a9e1d36c69d3ac5f4a5a9cb5ad24037388518f270d96ec0bb238e49ef86745710bd07b20fa3e5a9b0bd12d27e3534d9c15ae18b44cb26783799f04537ebbe4a3b6671814fdfc76e8ab1a1743d700dc823e85dc70642ca8715a303ca832c41b7d4db49b6c0e85738eb8d0c7911dc983d2fb7472c72dd1e763333e601e005d9c9f04ec0787982d0fe6d902019cd95c715a200c0eed77bff250a8eab9fe6998c64201dcee4010e1d018710017f6b03ddbbe987b4f9ca78c5f2f2a1e86bd578f71ed5fe180eb70fed15e981cd67b066c89bd68c631b6eb334f97dec4e181ebf814ccedb4839d3825232e6a5de51045042ec9565f95597dbc6537a39e19c9d197a6d0a6925217642f5c76486ed4fc17946a9248897e32610906b2a8d0d82729e39e0931ee1369d716526670d5af45ed41e99241d27cd0a2a6829807e351e218cd86bd1b2fcdec63e1786231d046f75c05e9cdcadd90b0ebe27392b249430caae53168bc79a76a1ed5d80c0b55053f039c97440e57ad5178489b7f26347334f42ea873de74d48c2930d97cf1cd496fb412c59111e4769d06f2a31e169373e9d7a2eb7dba43c321ccbde2ced85d9b134c926645a97b3d7e9ac0c8c1d165ddabd32bb9abb2eabee3dc1637af555f10140f43491cee4d62aee68f48e1d2e82a9a7c4494e2971bb4c770181750e3c4ac84f1336d1bdbf868d8c27d12eeeee47151b3381e3c7213fe80d4053935ad74e95da1326125c85cf846a890a6f88da228b9b0de22cc8de222c0fb425808613e4928e0e76945c51eb1eef5fee1e0eb3842998c8d5329a4923c6bb8a95f897ae61fdb811923a9e072a649955f5db66eb786b52fee3395991dc69e7c0e91e05a1f948df9f8a7f2616c7b41cdf2da0a304c7752f64d7126417b986c856137145fa61fc81546057c682c094de5d02b34b7bf6a0ce420ecdf00c0414c7fb26dfe9a72a20211ee7d25eb6440d32b1ad465cb86becad1c00c079a9b10523920cd4bf336459d99db40588328692c7eaa1a8c0508d6b6e1fa079e387e462c9e7796216c463be7903bfd744e8d651646fe90995556879384c83efb7a406dad5e88a68f2f557aa9581a0265fb088a3db86d4a61542b6906de662ce688b446900825b675e8bb5424ba3af8f28419f88b53d6104e85752c893a1c60fc6682bf8ef6ea87ad0c36a436f153d80df3e71e63507a07236fd5bb57f338cc63c31b3a8da97dd54def56661424eb71151a9d6863f6ed8d41734cdb42cd6c672642021ca40668a0c99bc5ff33657c68e65ee5537884008756b8aa0f71346708158e57ba212e9ddf2e261995dcf5a2f976c9cace395220eb9b199a43a7f8ab1b839d7cf39caa8bc5729fdd21ad01ae494888545654607dfa20eb5202927926b39f983b0dab10d14a069467b76cd93b742ba4be0f1a49115ee6429b9a1726153a4446e64ecb5553cd15dfdd5a80d35a15b21b9ee8f978940a461ffa0ca2be39ba22d5f393dc3f70124b7def763b2addd5e75590f516d7681dc638fc6cfec2de19b8e96bdb04fbd6af3bade00a849c0b500789b2108d716370be231bfb66b5a75a767723d8190f689f3071fb341c344ef34d87ad01dc28db62b8652d6ed9aa0e6b1f8c64a5a94fa306f87b6b0e057ed40da3be3d3970fce2b466a0a9afbd4512419b518210be18c5014e08ccb2e4e63f6083c2f0c92224ad502d2a63e712b6460e9a0b8ef7949bc106cd67805fd6c72cb13675e821f8c974ce1d82a3837f507c6d4f5f1d38ce75ccce851e2eb5915f6c2d642e9a3735cb685a4304559a59487793b470bde7871aa9800e09414d27a1c0c0a7dc6d5c12bf5d8bb3493f3da19644598891c515c9d161551b52778a09081ebb2887d206f23d1f204c62daad1dd2f756c0479cc346eb4864019f95027ddf535ed7d4304551e49c6fd495f65c6dd8878e54e8a968e882995a2dbed1f654d9345385a5cb6ccf3999d466e1e2733b037f504eba9ac9dd132fc9ee20b118ccd31048b1665eadf81b3ef83841782d536d55e9c292394e1c5486fe379c37f7d9ca7148c71eec92531ce13038ca805b8fa55a9badc780941b8ae72f879e277a843365dbcbab151b4245caebd3616039c738f15e9648e68498ea00b904d2afb772ae55c165bc06102d0e2c49270bad6eb76a821ef3275dafabefc3982420a60022946ebc68671162c47141c107e7741907e8f952c9e2cca84e1727bb21359142650232a2b394e0b8286f7b033d268fb10ad0b323315075e6b31dd7e98df939dfa29abf95b885f0d11e52c86bb550596d7a08d9b092c34b40c839faa1a7bfc7b39376cf08707957301676d27a5eaaa70a50d40d615f24e5be123a1ff570382b7f8ea005ab925439fed3f6a5fd7e991b9f5d0fe30e4df15a5d47450883a29ba6e57b8913a7fa708034d0b881dbd3467e37457316945fa5bb465e15835bf086e9f44f649d7be551856c659bd307a16940dd1725f4952d5890d704153ef4034e3e105ee47a1f1baebbdcb29673bcbb2d9473a6390e42e92cbe7e856dd7155136ec90628a9b30ddb9c54fe4eb17d749b92fbe6d2ff1f3059b7f88fd659a36b26fb0789467ab0c1dc47c893a0e40192e0670b57e37376a76ea8e91e84f8e0e4128c59d0e968e6def752bafcce4a84a470b529c5cc41d76430bc2142f1840d84411a98bac8a9ce732afc849f8e43476f46c8511ef116a66625222b296585327d68afe4c48afb56ad15cd66a6926480fd4dee3da78cfc21555ad92f16dfee17c030ab9cb34d5c6ce0fae17c830faa1e8c63ddb010e2af2749cafa07b88a09199566dacb6e5dc86bb9eaa3db7f6b3429830d67df53b3f3c8b9a3f517904b2e9e8105cc6b06bd2252305c6c130df0f6403e1f95e0b98a45ce43a2aa730cdcc06ddd1b66124fd2ba0bc2e265b657d7e4034749f31efbc93faecb884aad36c521c17da321095a235d5c8e625be8bcc531bc82d73694cd9ea384a91a8ea1c382ba364824c7b960897581e6c04889e1dcc12c4d7da3f701b7bf83b28075cdb9271ff22d287d2c7e31af8ceedea40607c36b98deab0e2131c4563dd6c0c63f8ec90bdc6f7b0837410d1e703aba0a1b5378c829bc51fa2d32912bc144b94553fed3b1b5700958ed9161adca9be56584946698830d4b62e6704b447dc222c02eb0e4d6b21add1a5a4eb028f91984c5487728dbd73432aa73d02bf55449df1c3e052726fc731b6e6859ebf483aeeb276872ff9e4df3ea69bb841b359aa99927ba8bef4f813573e86d4e3c9376365c24b502b785ad772aec8350380d0093e927740bc0ce9250196c6e5801cf39d512416dc3cd3eec59554739924a7cd49f6d9863fef76dd133cec66c1585b486c6d5f9c74d65b7b08032aca846be329afe61255576462ac8a3e3ec2836c11f70ddb3be094f1ce4a4519bb5ec9b2a6bfab15e81f516e6e270d81bddd540f938bdac4ee77f75824d33929f90365e0ceb7880f429603f27d7d2fdb7589c8c9e7f12b1f83c127510fa685ad04cfd87a05b4c06e5a1b238b239f46c9ba687150e7863065fced6689a0fc6f801b42cec28639663dce047f20c434bf604aa6749bba8e5aa13bbb0a50a81415cf41f060966d041a9d20b000b3941d8b414f4d5cbeeb6df7f6483a707ab78b6d75066f688dd889b05fc65fee70e32277c9c3395523adea998d9168a95ff076cfa627345c886ee2063584866ae3f204dbac59e638c0f1d810969de4700f241342b3632372ede8b18cb04848c2b160ead08da52be318923cabf01c43b5529498d3305b4ad136d952d185e730d2b0787feb1bccc491eb29a54ecf0e78d96feba8dcba8f580c4d2c941ce688b21ebec6bd95c60dc4c68ae1da2fa873a719e091149fc256020654c3fc7bd3a444d23b50c364fc071155c10ea7573b314af8e45000cffcbb7d3197383705e60c66232478883c78af31aca16f1f9977d24b55c79c9c658010d40e6954cb43b50f160333a2450323427b9d76e508872a1f641061135140ab301c0ed6fb72118429d6106f288caabfe85ac1ad6a7c1f64e7bc0db228aba52c5a0a10643d574049633644c1eaaa2cdbea561b8749bc059f1340c75dde549a370b626d62302773580907960c4d676ff890ec185c6f3655fd3f41e3bb2a68b26c1d79b13853bc260d4194e73737ed9339e7c237e5d7691fcf6ebb4bd90f549bf7cfdeab7b04c2f662f6440f356603eb357b2585e1eaba15ce5b0720f99960a71373252eaf40ae1eda550958cf4565c626191af7c1b3656386f5cadda26a2b02a34fd8b7df57fa75cbf53a840e3163668108dbd5c86ab0464836fb81496a9dfcf329cf1cb76d240735c4d128e193c3358c1e30603c5cdfa25933c760d558c1cf209350e66da503ffab69305746bb1c48eedba549979a68b54fef12194543cc6562973da3c4ab0e15738b9c7cb85720df673f983e0f7d51737d8e2bffa82d9a6b160b81eae216678d2370c08621bee76f7075b762a487b547a635cb5f27df0a6838127b848a2165b126cca9f75945a6cc0c69064c4b3f8193c2df2b335cbefd8cf874cdd5fbd48a65fcb516dbf634e78e1bd9e850b938a970ae4459071cb59d2e8ffb4f38e323d0b639bce2710bbbcf8aadcd3c035a6223140d4f9a3d4248dab873f4436b82435b1836c8fa403a9375adfaae9e992c1afdb6a32f407540fe9750c3cd2b565c290b639b30cdbac6e1df046ae23471c3f818436b25139854b962b43f34e4c00cfab53dac727c3c6b25ae349f868f9ca19136eb3768dc40d56d53a3f68671895731dbf9e6f6157e58ff2d945dda72040012436f588552072799ee5af9c48deba8d183e6a565afaa4b986d441f1207bdb3adf67eab6ba5bcf07471cc26def1f6766e81f0e0acdfd8bb7b36a47369097ef62ff46ef924b8ad19e0dd1b02e55a42b52c15e13caa15e641a382f17eeefa0d6af124748b86e9416dd130cf7da95b0a1d96a208582210ddaac67788a6eba9d9e4c44535d66c330b0068c53639ed01cb39e3aff1142b1160dc67950ab714d8872f30a43c0cde814b74a5f4ae2e96360b681c0174ec1709724585a770d1f632ac654e1ea6a3ecb990573e1ca2d3b807bb1c324cd6ad75632a81a295bd32743c85bee1a59372339e4b670b074dc3263e64012e211dd371144e0bb05f400b5f4b9892927044edf7215a00a6b8f9a1dbf20216abb33e4a8c6e151286cc1958361e7554fe235fa6f044355af9afb16fe732337dd63972d413d75e97f6e0416fcd2fa8914f843397d9228f9dba2ea50545f5550fc447fc2ff910b3dd613f055e640979b0fe9666d8ffb654101c17148d18bd69dfa697e6a4d500eeefc1b7ca353605ad7b1c61d30274216efdd4a2def0615f39e8f7d8ef5456781ff5dd9b020ebe655a5ce33a3cc94bf4d0b7106f6fbf0372b756b76b7dd3aa187118b525da47f5477ca7fd5497e21af0f68d59dd8dd19a81c890caa78e72a2b9cec7be319d1c7b3d7cdba9694be980eabb241896e14c485554571c5f6a57527c5abeff1808bf1a52c205802756962161491985a59291f753e6d2a585fae3b4eff66b7031859f50f899aaa95e1a8a54c86f89b982939a20b533f955071111b6c180c367a9e4af355472c207296e70e6a47ca60fabf33e161c2075cc73e4b0f5b008e8ace271f268ac4473f8f73511fb1c3dadd670fb5c107122494eddfd7474624276f3868435c7663dc753c4c6f91f01d1ec6180678fbd44b43446971d39be570bb92133e292adef6404359f4a3822e6655fa90a5ebb5a84f06bed8d06c9a7b66992512c213e19b5b3d6d3d31988111eb7afa15b77d0b4176e60bdeff1facd600946662b8f2bb91ed016efedc7841c1fee03ea23a85c3ae258c7ec5dc71f9e20412adc00d6709b939007688c251a9dbf17562ece492219a85f8c393238bb3cfa718642b5eecaac8f624c3e843491ead00e3882ecb48ca7e46d0ff9e908849578c0eaf25be190b5bf182bee973bdbdb76b2fda0949c96fa2dfeb374f3ae3d4ee4d1b1253ad1e1a6cc7566d3952d9608bad6223c3f9b14eafd02fed7119d65a2ec77c07bfe424ced12a76bb5fa91b6967d51ea3ea1deebabe770e2df71e0bd1c1409975d28b862c5121936f9c1d40a5f9d129063b1fe5a3782ee89813f2d1a7e21b0260b0e96359a30161f4ae357d7674241c5dbc0e47e552ef4402a5c72b715593418a724eb6061cc5b438233c029522e8a0cf1643b190af5d73cc8c30e1101907963d5bbf3f709a3323c92bf8ffa099aff49e343e4ca3c6b5141a8002edb3510053cde1de04e1a726bcbe11c4425dad672f7e0dcc648a8a4337f5695f2e638fe797734396f017e541201ed12a1ff9dfd0e8ccfbf80ece78990ee216a8100d8520e3603957f6d0c711388a28709e8ab800443b341d3a1950e8d7cffca396dbc00a2d3199cd7a0396fe21bf7d70bacf8c74d5a1938dcc4fc66df3182a81474ea08079ba41eed80ed04e2b828d43467f05fe9a390954a2bc5c41bfe961299d8a5b1ff7c951ea55709dd4c8547a621cc77cd6fbd8a2b24ad085647ca006685aeabf5805867d06fff2cdb7ffcf3a051e7b27171ecfb3627bb483e4cc14cb99304f6c79d74d095869c48b16ad207b17961ec83c3f3f638cf3eb23da9f64899ba8c6b274d312136de6a5ee5710429fd52212b6f946cf4807fcdd8788ac8684560cb9290513b144690ba0031b974c23f727be0851f5376b6c9c996d23c3939bd078544cd356fc2e95de0fe665856883d64ca29da8ff693df229b4be012856c76b7c296e25dd200ed69095ed4167d2c9a0d1cd943e4aa6ed6275b1c41123c6e57f8ef9d0b21ccf372a053817ba8cd0e35956e8eb9768eadacc14b173d3befe96d708719ecd927e78a7ba8684886f35a4573659f3265de8857cbc593f4fe01b4c3cc953ecef94851d6a5dcc9ea42f00b1adb3bf94ea1b92213b1c3f82f51dc6c227bdb639ed0014f38fdf09119989c8d63f768080134a69318c6cf82df8c361c8a3af456edf49ad8aed65a74b2ae22801d7271be459e6d4a5c76e36873dc2ab71bd81eb341fb4e9769be04b276e16046ef581bdbd798fc8a911bc6f86447c3c4816898e205a5affffcb9a53b39ada329cff92c39a22bcde496f76ada3f6ab2cde2f52df7d38b6973c6789da3f4efb955ecea4787bdfa9b6d98d786a457db6c16347a3fc46482564f50d6aab491e009bc853ad7ae132bee085c01d852fbf666a4975d5e73a37399ae3dd23d03d5e4d2a171ea4d6c4948d8d104a754454e26b05327b084a6baaff51f4979ac66971289a24d23f18711b2161cf4cea789e1ba0798a2e2b80588ca9f02a95ced31ab38c39139c71b677e4b959f1eba67a0b2b5ab0e0f8f25e97e7edfedeee1066dbffc8bce03f7debe1e1a4cde6587a1ecf836607cfaab2ee2a88d6b9f1ecce1a74bbd71f33f70c0f0919ac4899842b2a3d33e3aa6fc9c5acce7021de1747e7a95e5a9a6d440f6eb5035fdb5b2382d1bf8a4072c7cd40855fe7af006629df36fa2f4e3365618ed3641532d4f4d7fd904c6fbdc7a363297561d709dfa8842419d57b667480f145ec02d3f05da09cf5c2fa526ff37f8bb876087986343507c75d8c91cd43722c53da552f769c62dd43585b49ce85b79b32acd16faa6a6b1639fe50203095ad9db90edbd13ae98e224d0d0077ecea27b201d25c867eb1d71640b779560c4d05f66f02553df34c51b46578f10382d2e995165cd877b0cf10310cbe75cf20efe8525826ee71d32aa708183a36ad4dc51f1df45584470f2aefcdd3d9bd665eaa28ce158b885a197af5ddab28d1f79fa28dbb3f1027eaaf771686383dad33035199cc0fa86b0c8859ef83303e6abc0d832bd199eec4515ebd3ac67c81379bd6bc9251b0bd1a26cfc25de607e87326ae528fa3a7ca8c40abbcc71d9fead46d52a89d5341278b7bfc679764502a2b9bf65176004ce3f0144716e50b26c0c6fb2fcd360cb0d616430ae3c64957aad39e88ea083b9e2a187b716770e2580840ba18c1fc15348ff3d35929f2a9438f22018f89cf62eb24ae2247bf86be35e733580a33d4e28006a2fb12ebae18243a5b8dcb0e5cd07d03d517a05a5494dec515c342d7dd3a1de4add84a531133e9daa269b41695e4fa62f844e950be60c322c11b252703facf440c03091bc31506fedd0d8b33ca08a555bd0b01efbd261263bed6752d0cff34fee13126367daa7ce5d5463bb9b78f179b0f1a2bb2af8b88358d94322607e83f857618d7066821327ec4baffe3b5a7334a661a31e9d7c18a6a8beb7f7c017ff6d0c689ecb8fd9f54c545c52f34f14408865cd4219e9e7c4e24cc6b5f2e67a6c19e8bab3f938ad63ba606e2b41e84fd804fabbefb8c715ef25a8842c1ed8c2f9ddc976b0ae6b921fd1b60e93193d689a69cd5155cf9c5d8202f6f854891c65eabcb10910d615667d8c90781a5bd52382389a36c13ded43028466a2504c6095e9d394b629ed7b1c99ecc93f252744ecf094038d5309769ab7dcb34d23748cf97d60e90b62bb46e881275f87895a8ac1572bd028f20bd8a76db1fd138148848e7bf34b9e07f55d78c4b206a2d2b1913275a34d5a7cf0a8ec9ee3ee61a470e80b4bcbb6200c685d9e726cb236c3ca2abc1f2b5397b50e0cbf4ca9d1191ab10df54d8e2e29af2f4f8200ee78e38aaaa8fa81699f527d068db2f16be2911d8ae8e22401f8c63c1ec36edf4d7a1a758c2e136be995551a208b2add9cc5fd51201ad0164d4cd122a22954d193c97f84058db621bd0b87d0c2578cafd4235d7bf20d810d7e6aaaabf6f3eaf1f8ebc68ae18474ddd24e5424f17b8361e21b245236631c5f9a84999395db0dfd2fc37cd0b58d7bc06c5e7085f4daace6087ed0bf64edd36e1745ead7a3e8159b79c45002640271d0762a96010df59ae787c704791d78eaafb9e5bc06fe077a3a091ed88e8f3db57f12233e7f977cd71b6c6cb571c8940de9f6dd4b449cf0869e63c5e4477c92f7527b147e8e84706828f8d8105e0f06aad772f38dc2f00e1583af78d85e8f5f5f553d026e965c3cd2e791af15c7d541dadc45537edd14e903998ee3ba0734d324143fe3e1bc9ce42463a12de125299424649a44dc6a10c813676bdef406c90ffad381b17df68260715d5ce570830ac49f7179e95e37b40d3505b0824c16f810a664077874533da532d7f9cfa534f885b028cfb1f393ef5b7eaf66bd2f94e1677ac8d23ef655084d8963f7bfa68b3e6bdbdc95e7cf09de1508e7fd68a7b6fce4b562cc86d320bca6653076e1faa1c1e18730023744fd4a3d40556dd4075d778431321b56ee22d812b424af409aae68f46cc01e004a77dfd01da8e8b0e3fb6784fae214fa7de743f13700f5d27f9a8fcaefb6f80340e6c27500987fb9c2658d1d3a5d80bd9879826b710527cfb34fbeeb3ed7d3ceea16f507002df61adb5100e5fdc0295e483dd29073d1880740f16386f2236b24098c8d0764082d0024912c3a136632a897ba5970a8cd41e303bddcafcf0656fe15ee087713a6eba04b4390dcaec3ab74397640fc85dcaeadd289cb74f94496cb86c3756488a9f44fe384a5451b1ea936b19310c4bff26505e44b736e0eec7e2b60fe648932c641be8ab15ce01baaebbccdef39543828bfac53ba38e58b238531210b324b40f39feeecae0cff3b11dfebe9cf933a1ab3b843a623375c66ae770571f514763ff66ec5f25a982720f4ed1cc036bf70078f36bb2313a97714d8fc5f569dca848da74bdf7b44c3e1ec38b2e5017d4740805d8c77c11e1b39399ed351f00d840b05486abb7b6a0ec7e7503dbf5350090daa8f97debf4c0a8cac6379aeb3d7491f3cc429a53018b647f1271a6c243ac03ce8693f2f38199f036faab6e4b840df894e7541b86cfdbb938806622ef9c0da453f62559912b807ed337e7d17c404e2ab8069f0a1044b8fdae580cf22df74bda921d0908b8e4c0703da4cdf0b68d1aabd0e531e78d2f2bd980f982a46ebcc2c8b988300576761675b13cb7335f006b6379ea467814e56ea8d6ec8eacf1700643fba92d1fc0bfe9f6c05d52f8df14e3c3cbac3c1fc61b5d8afd5a79fa0f64a6d28a33e7c3fa8c7ef32d0ec2f14c9b81f26b5d3f79d5953ed4f4efe9bb8be772b897e05c046e188b5b00df4cdcda3c886dad684ee9edb6b98e5c7c5af4f9047800bfdbbf2fad9d5faece47dcf8a5702d3f114b5cbc63fb41d6c97b9e74f10efea3fd82eb055f61d85da09b6fd82e9bdd9e7daabe4522979969ce7e49a30ca5ba170dae483676fbda3a64e9feac4510a1b6cf8d52e6e8b3fc4989f91d7ccecd023c8f5c6ec3d8fe416d10a4ad68522f67dee6bbd83ed0fbe057ca31ea3f51812863463e2918e098c70d36111578b1f05ba0c55de2bdef29f07470cbe7f694e7d80199f78739b8bf5ddb878177a6fe70f4addc7fa4014a8baaa6ae5efbdb166ec5ca7d2b001a02f93c5d3d7b6ec8ddfbfb4f895ae3a624dafe8d4f2b1bffbb8ede260c3dda43db30de950016c4886d0f365e98a0e07d6d6b14afb867c151e025286a3f750b7295a0457e6cd471ee02f76c1953e7d6933dcea2d5ba883b2e34caa53c28d204b2bf5787b59ce841510bd014957bb4e8a1f162716653e614b18f9e785fea2bbabe61d6710fda9bece0ca18003164db86ea985866950fb2632a18079a909df4baac74fc65222aef450f3d7ed5a526f7aa5e74b3ed35b4f9876f32b46eae0e905f906f6e672701a1afbbec8c7dec05f7b51ea7584e618ebbb9454f4eaa3b124e9c1f4f27f6fc22a94bc6b3eac32a7cdfa04c69bc9f9d739c2dc4a511561fd85d5ca749def79ef0e2a705b0123d8538ebb6565810dbfce3b1379623a3e92edb8758442adbd77839afc8582fd3e49a0d8058d2c57b62545d8d62d9a054630b709fd1e3e15392de727ca77571d3121ea5138d27eeb5214a628bb29d647b51fc768410c8429e47cb388715524c04f5c5fbcc8dd7f465c4cc7169a44393386ceaea3495105b8f3c3c4acda35cc104acce71331796cb27344befe78a2c25e459015956d9769323c1ea4b4f3c710091df914309bd914fa5ce8809fcaea51f58c7cd035466826c469cd0d6cac720d9a3b861e1588fc90e9e2030fca874c1b9daf2dfed4e79211aaefa023ac2a71cd816bb94a00d5eb18c8dcced1dd42eb9fcc105275b953b7031d895443ec824602705428e932474570eb25754ab4051881cfb61344cb1ac151f439cec55b3c44d7a6ebed2ed2c29011d25f5ce898dc3a4f750cc9628d33867b7e45621d24034d15250d7eb61cf955567a2b561958ed9538106f8d3d986db94e02b774111cc0fbfa7110d4613dda7fd826ad6f3f16199ef0d0650455f1c0e4a0f90f9840b47317c5320d5c21531651010484591d9bf9f3ae3a26592980ab0ad4034a0446c478a31cfcceef0ad627ab3c6dbb9134b49c0b2095c1143200c779e7997cd558a341b0e770507a602426c690c7908b8c51279d08e4d65fb4f0820684eb545ae705d04de309478799e8e56103ba0d18cd2e6a1add0a66aa975563b332dd9ebcf6dbc769944729da2b2d2884c5a8295c89708724caa42d59733d404526e9e206d1cd56e43c38959831e45ebe7ef1bd5730effe483a950288fb8e105b2217d1b108250a8af23c6874518aef0b017e08eb9a3b34f6ef6e88ec4621ba9603ad97f8ce987ecf31649c87f390b376a717bf5b69e2cf11cd5ddc6bae548d03e039f741d4a7879cc9beb63c3f2908c72553d2bee0d46a13cb51c0539bfa67c85f944675b18c9c9ba6982ad1edd66c5088f0a328b2ed5063f5f7ad9232fdbecf2b72c3ae3decbd4932276dbf45028b42e9b662552290c89c6cc21853d4f9dda62437ea669eb8580512350267970cadc442e071d184a57353f38647b1891fd65f4bd6587bdd7044f70b40207fa99b7dca843e636a923bae6a1c83950f98d097a41b8e9ebc086bc04a6135e810a2bca08e9c928ecf5517de6794f4adf3fdd59d920f3428a23c23f8a5fa91d8f901bce0292e01f295920388449c0eb518ba5025dcf949f368bc000e8f4bc27a639cb3b2085fcddc1e8172daea3174a480af10389548ceb4e2afa9a52798cd4e1662586d8d21cde83c56626d3d36fd15b8d9de1ca08b6841c86758553ad055168ed44b815971381eef478460b1c435ebdbdf6f8cbac372a5890612b68f243871204fb3541cd2e5fdadb2ed2f32b4c1adfa138e700c298b0e1034764746c9cf908deccf0078e6a406dd0f2928227c8132aa33199a38d5c7507a82f8c917193d72458b65fb16afe5fcd9d8a0acd1bc06598922edbfd67d803c8b0609d0c87684e0275947e571cfb1fdaeaebeff1dac808252d38f6bd0b0d141ac5e04d81f1abb9c92036e4735fa9e07ad3a02623e3accb3eaabbb767a40652413d75f22aae19058826efe1c18c3d92fd5a733622eb82b79e6b5d2ca985b4a2d688fd591ec5f1158a20f5487ee9e290c5a2093a228ec4dd6ab4fff85519d4886b63c8bb1e770919888a8fd625486c92e2e885474adf014341c3cc589e05eff8bc1bcac928a52d6b626631d5df0eec5457fbe3af64ec16fd161c71a9cb788ba6829c8cc53005d8a1483825a80de500f0310824db5614e69f8e66e443e30876b870d253259b0e0af6e59063f225b1c612933a8bb50262457a56904157414495a17f0ba5bfe740c7cb0c7aaf30bc045bf6d7af5b713c1b4b543d72000b68cf13f9ddc9cd3405dabdedbcc26ce3591bd2027106cf7b4ebc226d046c9b434f0bd6e2bbad413282a35c29af6719f5e9ad9d1d36d7464e2cf2b506f663850988efc02a0c3ba3a5efd075ef254a2d166f5d8c3491666fcf4b2c68ed4a7dd7edc2acf7a0b76d134ac728bc76ee9ad884691a8ab7f860e7ac1dbae00f7dcb7bf1fc0badaf5c0c7f7d1910b714522713d99b5d6fc12492dcc42f296b123ae0fb63455ac649f004c4ebc65f1aeb4551cf226c0cc481ededf79158a174b154f748979b287c3ea6211a5f227cfeee5655997d0ed3951a5e6eee69dc02f5392217b799cac4d1567ef26c5bc523fc7a7df46c305aa23b84c059608a090dd6a6f6e162843c39fd5ee3ebd8e3528e8117f36875b89a4d10de15b5637c1096ca442f3dc71f3723656b36fbdd8784687c809281a9a24abe38eac9036df4084d9895ed56837a650136dccaaac39a37015ec352e80fdc4c4b04384406110a24eb8cf8850e90e5b0fb02bdbd6b78e5638351d232340535db0eb0f4d6f58d2e6125c42b4c8d90ed3beca91a744f14b1f91c331e33671b7475ded4a8ad91427bcce27c23d06dbdd9c4d7862c74df6c3401f51a2c4f7dfe0e5ba77bfa713cd6b1c373046bef0b3542389a09f72ddbc47e94cfeb6c8e70f079903fa34487a19b402620cbab3d382d68f329dfb0e3a0951df20ffe4057dae40a6ec54b817c484577287020528287885c5e20d533db90dfd8434f4f9e498a357f37e6c1d21a82b7dd5daa8add587aba70483a0449e7a120d4873182a77f4ac12c5ef5acd2de1f9cc61bc114ba57a7217a180dca29854897acf5bbd5000975ea45b9abf858a063495516b3e0c09bd9741d256a112bea2fa1256bbb081be5c6acb50afb272f43155713e06bd2b7dab1a079f600668b876f1790095bc8dd40e6d2a4fbf1b4ea7c2cae42da3fb92844569933c99d3ed0d4afb990387c30ead0f1af35309ef9a761f588efa0a052045a56c1df3a68c0a248e91f19beec016983c75826d0d2746e1b91cf2050a53e109e9f0d6929e7bb979e7ac07b73bbded42e097b7384dd096d8f1e3d1231af38fe1c171e54d8e8a2dc91ccf43b5ca10e6339054272d38064b157b5c12a5351d34164d5ad63e9418f118a15e00265802f7b4436fcdc3029e139d16e2ed4357180bcb1ea146fa8a2478719c18ac78b01ea1581b6ef0dbf66bf9aa836ea9ff640db506bd6fb218153ab27c1c736d8dc0558db08b4f45448cbfe02007ccadfd79e0f5cd2d8bb9eb445a8e69dd9fb82dd03a881d62df0d635489446780423cfa506a89fad45ad01487ac755ac3ee18c69f59f6366c1473a3a622242374898e0a8b1b918e8dac7ddd6576910ddc9065159bb5cafc5f0435d5c8d6d1e95ccb73a8a31df49cba7d7559d489316ee2f1c86b3cc43834e29ca178afdc211c841a3702a58c8021f748069bf5ce4226d71c112ae786237525186f70eebd56b389581e579d1b198158e16290b94f122132ad55fe3c84b895c2c954c7a2567dfad36fa0d0640df6e819240a51da3729cd2a7c3c6a16950802cf995375491c2a48340354f93ff6ba76ad4e4580c63f3101de51687bd4d37b5cffb1258b6a0040dd6aa6b5284d807013c3f3383f417e1649c9b64332c619daef1f2c243e130dbf1de8eae2fe0a68b20b7bb51e1fa35b39964a869e298d4a3bd76a0742620413a50ed2bf8c3088a408cb431587b8baddebd3e8bd2e9dd928ddf2247bf233fa4c747b6e7b5d12f2008e60680c1ffd6212ddbd6a30ed33f76cef00a189e8af384308a577403771e2a9c6580a9246d843d11e1510122288f991676102674079f2f8141fceb6b47c493843d091c64f1d8285ea83791e8204e12fceb5cbe660b8de71be25438560c7cfba4044c6f531aac34bfff710682f7b76f134ab467e55d0747a5701ba508cd277cf110f9b40ccb52c2832afdb8534009e3c684505eb4874cb39070217baab6c9a81cd32090dc43ea13c001c0f0603d9d3761cbaeec27525ccda7b5b1cb50df41ac868a0d62c83651643978bb4c5bee0c43b219cbe30a543d729e7726507e3557163c6546f5415666e46c302a35b7ea463c24cb59b3433b4dc2bb2d45c609f7c08315b15dd554fe8326c066995df05c8e28819a9041519234cf2bb8c57c206131531328dc1f560427ae711aaa01d56aef45b9a12340ef373549ab6de1f93e772d8156cf18acbe03c75c259a7fc6e1a92c9f4c383895e76c544a0c61ca31741087660d44b385d0db4a89c29f803d0fc89a8e2dfdd111ddb96a5d3cb54b1f3fbdec337ef499824aa72c28c95c3e011fde808d2658af4aa4df257f91d02d962252b5058d654bf9506ee65299a6f3556711cb46097c9ec9827ceb9390be392801819b0a807eeb6904679cd4b027f687105ee7a29c3d94375f9d9e31f9b50ef01728bfffd2ba34aaa751c9d3ce6693cd4e1e6052015b6db29126808627de2316e3baa2163d649f02e9650340d944a892c1a2783880b88746b793232043b84bbf717bc8fda9315f754b1cd8686c7f0bddfac192e626772d11bb48f74c4e43aa2f1253b9fbfc813c129f05cc749077b781c2e2444f2f1b15c8e597295426b3cae1f3929b3e8314273ad80a0780249dc20e9413b92ada4360a2114bf60f4622dfef6f81cf0566525c7386dd30f45432c2e8db7e197c6e1fc5dd25ffe4e2972087a2d4941f1cdfa76ba51f811e3a9383b544d5643d6ae5f98b762ea0ad9bc96d3ed942bfc90abc85dcb343061d992440a2d322cd1644a8cd5c4d9e9f20c761df798530634093b41949074179b0369566332143feabc624bb15547c73c872c3a17e1d6fbb12d2974d4bb8565caf09e16396c2650f98cc08f3fd9e94ef93c3add1cf86f0b780dedfd3b70d9ee22a23d7e69fa229c071b7819df75651d7e34aa3b9c1e07e5a0ddbfbd3b8107544f863eef842403ad9d3130b3e13246d94ef01369b6d775d8d28e7cdc1b2d8e872ac89d1d8adfd7e245af91ef94948015ddae8cc536024a9648d4ae5d6b2938c01ebc4f0489e74aa2d7a3b0099d4867bb88d98a29faeac29afb4e575fa005f614d674420d922861084636e453585719baf8433ea03d47733746f682b159e30df56e301ad368d001981fa36434e6e7354db5681be06a6534e85a847409d69f898ba1224e9fe9e7b98d0c8fd6748fe62720ef29b1c5a45d1a058e890bb08b9aa65c104953b99c7c58434713a66d65b9f8c841efa16b9f214402520ed065ff47cc04c24e9356f5db3212527ed7a0af0428894cb4eb830c6646a820a138b759036cfd2c3350d422043a23324c688a30259d909db6643031e8cd9a2b6503fd628b0ce3857526eaf8e0532cb736744d3a1be3e3dd19c0e167b9dabf51f5ad40c949a55ede55d581dc988c86f81f029f3aa030c9e1e9d1344fd7f0a8913622f61edb2f00adc4818e03aab83029a00a072705d1014725f49245e709776106ab63b6e834bc0526cd8d3ed8bc2a101551bb7f936416f49d9d6eb600a0fff27e99ace4005e97bb454bdd0abaf0f672db3c3ebed189b238e66fbc6ab044175ce726ca0be04439827dd7b95d92ebf40fbd78ea7354bf3f14b90608b6b195a08864b2ba2d9ceeda235c2a47fa5618db41640765c50359be97127ab9053f94fc3e1df9f9d53b1db7893da42eacf33d52865adbbb395d752f40a4e27a8dd16fefe9f05de662cc1d64491d58ddcbfa3f9af6172bd6abaafd4336dc85ba10ad460df54cf6bd6184ed9dade1f95e856b2d986d7c4116cd4ee742a38a29c248b67728c7c1f7937178260e835d91016499036eb1c50c103b10b0b44907300cc3300cc3300c8b0e050b54b48d6e53b706235f2629257d008d196a27b0fa3742f6f7a248ca24539249e2ac42c03fc1bfac6ddb01c913470f450eca1e44246069ae1f5f26f5163187f0555a5e84a095b65c7fd1a7b71e2e544fd3a94aa0d23221969c534853b9e856d3c968642e979598dc68cbe8f5ad7aa68e25e21ed0cdc0603a4b0519922102839619d92f7bd40c2ec7584af59ccdd394e61c725031f655ad50fc4e0fc6418664d8d0ac549b5c31f7cdd426dd2043326d1069aefc6c316d4dc8cf9d8d207eecc878dda64de518e4db432ba18d29e1227dbc9ace0e6cec5c6228f5dff531979a4eeee2b5c789563f5fccb9ed459025e50d96970d4b66a56bef3db8b919d7a9cfc55a565292f3e65cd2e4af94eba5defb1f6d3455f852eac45c8c6aa3ffc834cd1499a7aff8ee79ef26b2fc78292c6e0606933ac8904c7c414bf5e8355b8f10325e4d8425c50d865cd0d43de75811c7deb4581f7195964eca6e0bda3b4d2bf93b7f2c59af944a59d05a35fbd5a56ab26fa5e96479958c52663086345d093de611ba841e6ad674a693a2c956d0d2424bad53f74cd56fd4742a98710e114ecd46011b2d175b7ec8d2734825bfa6d3c5c86732ca35da698e6bdea2b146531791fae77ca10757aea4820cc9b4408dc6aca3477f8ad6ad5f0c835151f9875490219915a4d1de234f6f5e2e3b75aba613a664bee5884ba3081103e5084b0f0ce6088b0b5129c8904c13d25ad1631046e5f43076d474b2cb4adc001a49315e6c61426f33ba6a422f6734b6fc98d7f3ef94eeb511f883088b9f81c160309d964d263bc8900c54416bf4e9dfe1e3a7e8d7896146b3650b2d56959436338458fbafcddcc754d38922440c94c579971f3e3018f8292d9b87c17430619c81a228392e2d245828a3bd53a6fca253199f77693affb16cd83f963258c250abd3b2e111a421f60f26a698a6626ba1a6330364340851bf63ce9f0fb1f8f1cf6845e4c53d649795985a80ac8d8b226399faadf5327fa46057a344aa929b2196349d29052848f1e982ec30d36f474d14fc50e9555c0ca9b27d89124b158ce18b3c39476e1b6a32a5e9841b34c460ced3834b7333a19509e1e68c30f4391572cc297d2ab9233da3b5e57d8c5b31f7c925724da74acb4a4a063ec7359dd560bcef076346a5ec2e665415e2a32d5d5f0d1bb904635aa4e974aa2f98d52a8a4e3952eb996e56369c9654347ab4b8cffdd92675c69c58d3d9b2e1c04427682836afc8c917c2c5cf9acef745321b97942668aedeaf736e315d650d359dcfb251799997e2e22e1dcdf4a22575ad522552e94145ace95c5f74dee5882b4173ae983f3d96f0dd6d6b1a83c16012735c5ad62001afcc84522dab365aab54be5ccbc5cce4d8abc412671389bcb80743a565254579e58525b9acc43746d05c43a4a98c9d430e3963dc6418101e2d75354a568c3cb1a8acfd429558642945b49e8beac76a689f72b0d5276b3a332953e5fb22657453aec8a5c8dc7fe4f850d399791cd7f4588e74160cd5d026e788d75b4a2dca682a9795981437045ffa5ff9eb6e7b99a613e5c30dcb72668f5dd96c322a9093c90820351573e96351317b69b96a3a5d38eb04da7675c5d7567d6de8a0a633d32bdb6b6d171d5cf1391877359d2b1b35c89c63aafed3744ab5a6f38d0d874826a68aa0e533ed7cf49ca5efbb7430cd355456cb794cacfcabe97459892c8d10344ecedad5e6b282ae5fd309597c03537b055db4f4aa137bd6ef543188349d9ace4b4b86b38919d503c5078a1014214050deabf1869fc1b239c8900c101034cfcf8898f531f46f9fa693e39a9741ef92c259a3e36ba0207d417179594109e30c14142140503288830cc9acf1814ca55062d52c2d952aa5eac4ac145151c134e7efda2ea16ae60e1906e3b2123198e76c5e27f7407306998b4ad143c79495a613458818282f8394ce0b8a102028199614a51c9796f49ccddb20433224e840a6f3c2c96422c0815c45810d18d9bce152010d28d61d289a445852341dd7ecc800fc8c62cdb80f6020a10b706047072cd0810a7441010e4ce003124011f00004763c00030e504e061a90d100037465f332cfc964d20dc5daf2bed30b3892c9644001467cc5023a32b35121b251e122572a9080092000030758d1e5850206c8cc6b3299d749599940013840800e0406a09b080860f38100407f4e04b6a8408ecc3c110800203b1338495959d974c0443150220192ccb818f9093c2861c08018c640f22bce7282013164a2000478fe7005387a94a1063900706252f2d48216b390452c60f10a57b48215ab50452a50710a53948214a310452840f1094f7482139bd044264a30517209453c5c54420f0f1795b004194ccc4080e70f5330448f878b2042c880e379d840428a51904082640e2472d0014409006009c01a025004203a52208914b841470adcf0383d9ee731810fbeb0c10d7e80025504000c1d2868d1f1431655a082147cd083075eb87052c8f8c29f852565c70874870676b0bc0acbabb08e31da28c20a553c6328c3174f88c3088f1acf638609c4d80e0793431561ece1d90851031ad28086e73139c3e601cff3989881b321c3f3988c01a69888e131a3f31fc6f3988421ea00030c32e8f09186e70b5e789e270e1d5f48a2c3c174ba6086e731e1c24384c5c53b1915efb1a3c749ea38818b0e12c8c20a4620c1094660861477d1c1c30d3cb6f03c3b7874d1f1014d669005178eb73c8f0916026072052b1cf914b8e0794c86508523efc6aa94e731a1c2f33c013089c2f3984c6165c39262f202cebb91c2b221c32585258de58275c6ca33a2e9f873363e585236cf25e58d9597b6c6e66ddee60cc8f22e9d5fe3794ca41085e77183b309c3a1f03ccf912f9ec7e4094e781e932630e1794c96a0043484bc2ff23c4838421c3a9411233ccff33c264520c263320421b0b846c873366474fc81b8f4704e18ff52366a1ce1bc74fc3942583629292c292bb0c783a1e2292f05bea040a59342e481a8f84b61d1bc17d25258d2f015efbca4e0084b0f2dc283c7ee61e1b0f28c70bef3c2f99697e73109c2f33c2640789e87c4e407cf0353323e787cac3c36e0b3a4f13c26474c7ac0833478f03c263b781e131d98e4c0444545e525087c1c24dd0424569e9114384c6ef03c263680c1b7a169e85015e850208fc9731a98cc4006cff33cc98de72e68744c8ebc8a73157f3036418c34a8f2b259e3575c45e5258c9615c892468b7384b418699b8d90ce7f1844585282fc4a8aabf878d97058d270e16c5a5e06296874a0ca668c5771be09f23c264654545ec270e9bc705c58d2604903f3060c19569e11ce8b8a19502545e3e3880a4b19473e05488f7c0a4cde5865e4218b49119394171d5d584147173a783a30e822055d9ce031e93c8fb2f13c269c183c0f023aaa0604c10241089e956724a9d1596c341b8a0d6663d9486c281bc9c6737e8c0f44e20386e8a80e0fc44287074ce1362a5f6852b956a04aca1acf63a2f22e292c29f1c1781e13376000bf0c159514f82a9a58868a4a0f15951ecf6342c424b2bcc4e731f91f3c8f097c60ca8ff72ecf792c1b1fcf63e25836415cbed3494578f0d0d181a4a3031d30714d6da8ccac17ec11e7b8a005cf039f25253e6449a3a3a9080f1e9a8af0e0a14552112f3691e547c70b9607c2d9b0a4ac1871327ec559dcc5a1179c77f0070f1e2b1b96872b1b964ea7035552d6f08204efd50883e5254295cb85e3661c819b2f5c38de027f1c819b2fbcf042130934a5e1d261d9f8d8d1c57a21c1d27c592f47de8d552f3045d38b172849789e7749e1bc01fd391d131eec794c9649af7ad12299968e8e0cb44247063ea123038ef0c00e1e2b292e99f89c0e64e09f97f76a74525a7a74525a9c654384a565250503292d1d216f6c7c643a94b8c0171e1d17c8c0d379b861d1b1030e31bcd06181573ccfe3f26858600670e0600634a88014dca583799e87e55bcad804d1510130c0d041012df0400beb45c70412f0645e87049ee72909621282474704e230a22302603c9be7795cf0e880802274404009cf6304b2e878c0183a1cd0862e7ae860c01b1e1d0c30f2e8604087618167038f03980e06ec78742c00128f8e0554e1d1b100381e1d0b50e3d1b100f4e85800178f0e05c0e2d1a180443c3a14008547870264a0e26f03e4071a2e29696c8270a07f01fd0b8d0b27e58b2f5ec55dd008e3884b4a87e50503478061f18ebf73158d0b27c5edf01d2c6e87cb0be7c5e5257ae08dcd116ff9f1ce69ccccccbcbbbbbbbb9b524a29a59492aaaaaaaa6a666666662652a4489122458a142952a48c31c618638cadb5d65a6badd5ddddddddad94524a29a51433333333f3eeeeeeee6e4a29a594524aaaaaaaaaaa9999999908218410420825638c31c618636badb5d65a6b75777777772ba594524a29c5ccccccccbcbbbbbbbb9b524a29a59492aaaaaaaa6a66666666a264ab156fd25cf9f1ac40c700f2791ee7bc0814ebe60d21cf63f2010fa8f8a3f11c33e0a34300984787002ef0e81000178f0e01e4787408e079740440158f8e0078e2d11100493c3a026088474700ec600002bcca260854d98cf1c646e5bf38a2c25206fccd192c9b94e731e1c0f3986cc044038f1967a0003171c073c4816c829cf13c2619c0c0636281e731d9616281e779bc035f43a3b96c3667b8b4bcfc9fd1e904d9b1b2c3bfd8d149f1954d749717f7d211f2ee8d14f8b2e3391e06e78f780ff82c6f784b87f3475c65878a73010b433c5cc0c20f0f17b0a8430054fc25062614781e93099ca83c8f89049ec72402cf63028147c709180f781e13079834008c327c04699933ca38e38c966940d200a30c32326cf42083070f95cdc6bd8b13f1960da705489127c2b251f182880b3183e5ddd8a8bcc00d19cb8b9577f94164a3e2c57af9f12c2944585a0991e7f140071e92273c9c1d0fcba383c488cb743ade621200932d1e67495949e1bc4e0aecac74fc8d1d9b3148509ec75d1c8c4e46c55d3caa6c36ee88bbb1d9d10509dcc5e1f3945062123a1e153c9d4c4b073e18cf531209483c4fe779489ef08867e3d27284f3344198b251e35f62e02d653ccf03df3bf03d0f1ecf799e67551bf2038d0c186dc80f203d7e9cd1d0c8b433d210d22388183fd0585ae4c065a382c6aa97e72921c4205c362a68ccc20fcf936969711e3c58322ba7f35254dc8b19b2804519b200f2a4b8a599e970be45e5354bf325168c4803be9194309e00580116b2781e1e3c6241e479322d3d9e67c3f92147be48e3884b299202064b0fcecb7b9b924000e27954389cf6362a2a3dbab08057d0e17932c0799e923ff4e189e31560b882060f67882bece02d2238e2e2873e74ced801539cc6c55b76a8a8f4e0c1c31504784eba0b1700401ab8688519ac308415b858c50eb850452a5441c6a358c750c50254b180e7793246901052e184944d4b06be91948834042fc5e557342e291c0f414b878b54b83ccf0383459c80424d0108168000b69484118719a022110c28411b8160c4246410851274621527b08312a8b0091214410c9c0178a20e53d8031802a08752dc808c0240a214744885176774e2904409384e18422bde0e3b74d1f2071d34f6e1092dc48a0b084e31c60ac0d8620f1d3b0020065d9cc10cab804053a004248480c21eb82085354cc012841cd402481b6ca08143451c00785e587250c013b6d0022b1800063cbcb040060a3a50afb883222cd008d7c41a8780451234d0c5015a169000d4834d48a2102637d8b18a3c140183129b284119b52882233c1008116880041250c21564d063038298c4192661c0cc0111200683e0c1e3145e38c53a05059ec785b3713dcc50459ec70b4dc73b667cf1588e747a74561ecb918e1f7195872c6f6ca0ca66f33245322b2f2c990cdcb0bc4ae60827a3e945e3d2f230f32ea4a04247c56d54be80cd87a617c883c7288e3c24631085289ee729d18028e010458a28c6789e67470948b063078f36dad8e1d2f19622d0df87172428b143491de8100a20e820085c8042155c80c2c8c30528d0ca6303aab0f4e874389ff22e687cc28c1e5c7ce2e1c2136678951ddec313469ee7c1745e9c2778404d2f9d98c5f33c693c5c74c20b0fa6e33bba887fa4f39de0a7648b1c393a3de0afbccb8f9577f9d1714959c387e6b9f8179b4885aac1d223d5d8c4078c3c4423a3093f6842060fc6a5f34488bc74ba08f2c66bc2c7f364820d4238659002135f2ccd97d74921e33f8cce258200bff3e2e24458528e6cbe480a104bbc810b4b7087834969f18c12d9a874585e3245dc48e184e0c8bbf13c2570789e92373c4f891b1e2e2ae186360ca904186f384731293128042c6f6c384ed3710d1795d831061795d0f13c9d8e1a26f15246d04686b3c9b4b1a3c3c174d850b2061e3c34bd78d1e9b84a86f32d6ebc8d8a115ff18204467cc588afa8b824de789e4d64f9f1e3884a4b4b0f0244808b48ec60049158004b86f32e2999950d2766deb77444f0be08245c5132063170f1084e3c0f0683e180cbabb8f873887454be080f952ff22a19964d0a0f4dc7355c3c228ee771e16c349d1d9b8d0b8fef70bec873c2789d94956713597e90d139e26634a2118d584423eeb009d2f9153c4fe7889bf11f339d235c3482028c1082223ca1084170a188143c8f15b848c4039e07115c20e2091b0e3c4f8927b838042a42f068a8a47818980e193ed830c3a5b3e9a8f4d88169a38d36da50798eb7f88a901d467c6547e7a5ac38cb11b8e9b8147fc35d361bb7e343f023f81d980e2766f5c686436447e75f565ed6d88169a38de7b078cae68dcdbb1d71f322803f58362e3f1c8d1dfec5ca6363e5b101fd0bc8f28250799e1d5d8451020b933b6c1c4c8e601247204441860f36426006193ed830a3a40a0c8ee0ddc9099e1337e8e109045fc0046d6c224b0a2022f13c0f66c3813b54523a3b527670bec866070f3182fc0872460f1e6dec21108e9844c902c5734ae1075194f4175adea5e3c6b76c84603a2c9b2e545c4a87c50dcee68d1d2cdfd968de0ececb66053b301c6f69f11df0031f78c377fc173b309d1d3f8e38f7d2d9d1c6bf705cdad8b171d1ace1830f12c0683aae39c2e264b86c82b86c82c077d90471c3595276eca1048f1e4691c960569e9127c2718d8f3b28c1e53b01cbc1e7319d5ab462440b86924ab4f7d23ab8d2dd2ac530a1c583124a40f689f829970c6e4f42b9fb7496ea77d9a14a6215eb668b58ad722b6269451591aad357cc5154ff849248b474fe54528d38196591461122064a186a7482510289c671d73e8ead1ce37af0114d3172cfb9f49a258e683126e82e2deee83e1783a3a411ed5f6c66d5a9eb095db2299430a2bda49b362a63cc188aadc9bc0c523a188c0a43c9221a63292e9689c5c5dad3512aa2417d1fa172e71c2b658b65a124112da1674f49a1472c7aec8c4209221a5bdeece4f235f47e09836128941ca27d8cecfd50ad5b972a157a293144e365efa37baeaab26149211a4cf1318eefe563dd7c2b2821444b0ad3bbe777fc450b4b06d1de95f7f2848939b43805c1cb162b666b55914ab60c767a49b9b3c73afec740b456287984f12d7fd1412e0383c16056265bd4ca33b296500288b650ea72ce9672670ac13fb4b50865dae4287d29b3123fb49418ea458eb93396b24bfad096b3b462849c6264dfd44c404af8d032aa145b1f267fcab5db435b29a58ccbed5ead2ad343838b60c34ff0177288b9240fcd5944e8f9420e578ad1359dcb8b123cb4b496dfb395f05531e8f647c91dda7aa8d9512dc8dedaf4ecd0de7f72eea15686be91d7a1e5afaf74f7ce23da567468fffe8a2577e9bdde8243c91cda43b6bf1eb97f5aabd01a4ae4d0fa21e8947564efdcb5138a1031c6d0747c0c4dc7356b330e4d6974e85da676dcaea3a6533edc04d95502879678d946b6d4a55511ad8d0b27da1e256f80a97a3133bb2bb40c69da87a6e363f8200345081094d64a0c256e68d4db293533d6685919a3dcf829a52f7eeee54a4d676b491b12c352c286f60a29a78b91f3fb33d7b44a975e50301894720b256b689f6e633aa7afd23745b5820cc9142951438b28a554f11144a9614a9ace97414a666607199261256968ba62ec08b9157c69458886b6083283c90fa2a59c4289b207256768e831edb85465741bd599a1b9841047d68b526211baa633690c4acad0d44696befa95a51a9490a17972ce756b953a8ae98da1c5149322d72c5346d72a8696925a4e6cd34a9fc85f181a6c7fce45f4deaa56ec296eb0048696ce217b8d749563f6486550f28596fbf6f9c64e49653bd6f142fbf876395a2861a6cdef427bffff4f39c51e337be442630a1dc266ac37ae464fd399474ab6d0daf9eb8794532a8f2a6a3ad30c4ab4d0e2fbe4dc44fbe929948c9464a1b9f71c5afe2247b856234d67eaa6040b0d767a840cf12ef8ec94e60aed51f4e79efddeeb7c8ab5536285b6b8df525eb4cc1f4349d3e9b2d954a1255a6be3a6a7d1c51553d3b9920a8dd5530e154a7707d7474d275b299942cb5eece2aee79421764c440a2d22c5168a0bc14f4bff693a5dbea360501285c6ecdf6bece786eb1d3da7b3d174ba510285e64a299736bd5a7025b5349deee250379753f28496345327a305d97bc71c45881828188c2a82c18081c160309999544594e5184a9cd054beb598cb5f7eb9f0751aa2a4096d1952b95845a8eb5954194594304157ccc8fc0b2e7e17872d696030288750b28496ca45b616db65cccbcf172c5142d3f456a5e8d8f352e4a226e5cb4a579284f7fd0a22a468b9fd4c349420a1c5f8c81d2a740bb1da2d3902f72647e66817f3f434bd88923852aefaf82227f608ad478a891223447da69e8b9d98c5e59ace23ef4686b389ec12254558980cb5beb49cf8a9a633c3d97c0a47c86b9efbb04409111acb5cb58f31a85215b6a6b3c7c0f840f18132068a0f143450840041f90283d1a442c9105a7e8ceeb499d28eaa98101a4a6be1b3edb70f99e5aa9404611329664c99d2d4dd94accd9ded0a7ed2742ad6313018142140b273500284a692f9a186ab5f74562a9b9839c271593f1425104a7ed0567345e592f27e4825f44173ad8ad48bec1d3b87af070d2eb4dbecae4ad5156bd970c0c0605a361cc858902119121c94f08035429998dad56931af847a2d06d97ba6d63a8b9ace974ee6a564968d8a0f0c8679a16407cd513b8790112fb70ca1194050362e8ec188a144076d3df5cf10af6785bc370c141ff147aa134a72d096157ac8dabdaecca950828396ef48b1b5acb5e1a3ee1cf91494c0d17ab12a46a97eb946a658302dbeb29010486ad15ea63eab65cea9855c869516cda5b4dc537b5ca432b5a633285d389bce2692593407555c975664e5a4fa693ad57bb8f1f1701384a12401892c9afbf4d872ec15fa8aac359d4f640101128be652a3ea4c07bb61dc54e9304e0f4d1e24b058b69c566228a55496897239a4d472caa9436b1f440b0392573466a411aa6c65eb8e9f2b5a3ed78979517a4aaa6bc619285fa0f840e9816206907d21694573eca5f70c69b33ab6aa3a24ac68cc1bb375257ec6cf07c92ada6b878ba9b4581f76ea5a2151457b90b97eecc17fc7d23e374852d16262d62e35f5517c999a4e956490a0a2c5ed049dbab43857ddd274c26779639381be51c1605c9e08068322448c0c0683e20383c160520d0c0683e9c47169318902c9299afb5aca25dfe5d8fd7353b48856e4049753cdaaa99ff3d2d9a8bcccd24ccb4bc68dcd46a515458818282a40f181020445081014e6600719922942528af64eb9c78afcbb23a3c07e415949d1743045505cbfa0a025455bb75c7a6aa894d3c49ea65345c5dfb284a149328a86624c47cb373273aa9c051992b10189285aabc8f0f77527ec55932009454bceb1179511737788250683c16c66121424a068ddedca35ba869a78a9a633938907249f68fc8a1864a64aa94b6f4de7ca0189271aecc80d99258616aa17359d995403924e34e7d8fa4dbc6e41a74458529892e88084138dc5c44cfd2957f0314a4835249b688a2d173546e78e127c4b13cd33e9c68e9f58dd1f25d24ca6204332434832d1fc579fe66a5ffc925bf00706d3c16094822498682c1142be38c68c0c3abf44e3669e1064b7c8157ccc12cdedc79812eb7af0f1ab448b8a54a6d828b127d5a8e9641b17961f1c4e18ef5bd0c060329d720c249468ef1477ef7a62bad11d83795f0483e1eea8b4aca4301c24936848297790e3c77ec94549b4f6c429359d6932c6f22a99f74558f2ca48acd44c371ba9841627d5ee6fa8323237375cde7097e3d292889040a241f7113d4f91ad3aa4f1114d3da9b5cfcf387ffd3ba239754b59a58d293921d788b6d2b9876be562bcd98c68bcdce68aef7ce5a25d44531b234afdd87acc4c5744fb844c9d3a7ea9557b229ac788dc4a0c32e7fed4424463063dbd4e4ff6d47a88c6322e96d279a7764e6588e6af5543181d63be9e71219a5b98fd98d2dd6cf48468eb1d7f3fc42a3a776a102d9fd2b418dbb79c31ad20dae2f850b353b54c219502d19e2a8b8d9aadc4a02f201aa7529159ee3bb616e51f9af23297e047a46a19f3435384124cab38c25db97d68d0a9ab98182ad587d225e58d451122c6914f412753f14fc987e6ae5f23f7a8d83356bf87b66b95832999b73b847205247a682a366cd6cbef256504f3d0f2d74b4e1f6ecc14d1c343d3f75072b2e89ce573ee0ecdbdbf7ae67a5f7aface0e4d4597143366b488234c4d274b4ae65d3cebc05a75532eafb449916afe450eae72c569314487f629a57209c5a49e7bf7349d45dc582a12247368eccaee5d540f2a7db6349d45dcc8447f95cca61a29601d04891c1ac765ce3ec6652a2dc4988ab370ca589d8a8415247168312aebb71c52be3a53d474663670c1a145e5bcb0d941f7502ea7e97c22f039bfc2ba217943cb4cdfcbcdd682beaa9a4e1549dcd0106255ac34bd87afd96b3a55fc5d3a1937545e9c1020284cdbd0183fa73af16782eeb5b3a1a1b5112ebf05134c4b8425a5c37979cfc9e41381cd1f880f1435507ca0a400c5078acb0b19180ce7dde0f8cac34d100c068341110204650c945a22059235b45d462a39f5e7d9998f440d8df57311aa5ff5e8183e491a5a46b7187af2085762aa107b02091a5a43c658eca78af15aac9ace4d64c1603098cccae46a9021191226909ca129b4c8f95ab68f9f916a3ac338036579416286161973b97c2d771d57bd0c8d9dc394d6731ad339274d6722034a5e999bc9564a695bd1b2d78ef572ffb27fe3c25084888182c1bc87f1cfc06030990cca204332245b2019435bbecccac8a59594f32486e60a192ff5e0c676ba2ac8908c0b48c2a05c6469bd8fdef0133b123034e4a05bf69cfbee72465f68aa917ba9ba963d3343245e68f91c62c99d6eb2bfa748bad0a0beb56831a77ee3aa4c122e6c4469c195904bc8f7394de7aa6e5949493f48b6d0fc2d73eccb4b9f639eb4d01e7e5ccc99ef13d3f66d83240b0db2edb85a394f2fa94b58684f45fde5451995a1e3555768dd6e53a1a4fd582b9656682aa532648dae55474e19922a3485fca073cb21aba2e6969634a8d038b9c8d2bd758adeaf4e31f26370fe8d0d9017904ca121063357913be687d1a581c16c382f03960d0b06b3f2c2a2820cc9381229b497a05396224a0f653e73145a7a981c933a74f90c3919c6245068ad502307512efcf7c6b324cea3c1714123b3392e9dc4489ed0d6a7b48fd3b93fc4b4332cafd279a465f33821bfa0084171fc82c2f4499cd0148211bda3452b615c4f4f40d284a658d4980e427f141f3dc8f2fb0509131a82eaa990f25bdd4ced125a8230a9b5d235e15b965ca384e6ce9fcb5f1575ad642d064912da5369b9956942fe5cafe4b8744890d094faa5decb7cdec54b392e9d23b466c9935370dbdfbeb5361bb7418664c62089a345f7a7ffab3d6ec64e4da74b274505a52231424bef776bb9a73a1177ec14a141f6fe91fb4d86fc456522348f6f294af7c891abaf1d4243d931bb3fbe5cee419884d01cd38fab5fafbba42b6a101afcc5705da94cd01773dc4880d0968b11a28dc94cfddfd374be4acb8b4b6693fca0a5b366540cf24775761d1f34672f39ce14a152aa77a51e3466dd4911f35fdf9b4a79d060a2eea8891f31a5bc3319a5243b68d1a1540a3643755e99349dba4874d096fad808aecac8b2d5b6b4bce4a04104d17bac983de850b1a6d3c86b329c7f63a39249121cb47d4f7db4224cdc6b559c048eb6d29ffb73ab53aff8b93768ec9992e38478552ed56b8386544a98bfcf3aa9a44ad309bd25616ad0382585bbfa6552a722d4742a0d9a82d17529a7a79431664d6767033799e3d2513368fa0bc295363a8a4fa34b4306cda5e59c9e9e7f4491b9358eb455cf7b39e626ed4e6ca4fd52c6fa69a7e7a06bf646d3b894c78892828b5fa3358ab47ffbd9ae5e5c660f464da78a7388bcb76872de85ad175e4e2d5ea92142ee5bd3b9345f322e2b7185e1d2122f33772ea6e7f3f89666ca74d08bba20d35698af4fd3b9ea25f31d8eb76caebcb02432384db9f89266d44e1a3bb14b2705088b4143cbec2da8ac21730fbecbafd592fb1a7a84cb3aa5c79ace231c179667ceb3b0fc10b269ec4c1fc6a456a96c95ba189a6ad84ad75a0fa1b4c2d0a246c7bc17b7dac46068f1bda8db2bc154b7f10b4dbd4a1957e67bcde485d6ea88bd6cef6d45df85b6d631a42abdb7587c900b6dbdb892a153c84edfdb42cb5f9e20e35f14d76ba13185de4afe4a3359b92cb4a86026cec516b13e868596b8d729fc75b99feb0acdb1f66415971742d10a2d2e5ebc7257728c6d15daba470be9fbca97aaa8d060b38dc929e353e8760a8d9f257af17d620090c232f6e429229558149a4bcb2db4761363ec9541a1a508fdb7bbd526f4943da1b9f56fd8ae21dc75ca9cd03aeee6e2b59ad0d03b629b31e52a54654253c4d25d8a0b1ba1b784e65eebaffbb8aa3f115342434edd625021ecf53226a1b957bee0bb429dcc91d0d8b94cca8f29c7ca8ed07c2104d55b2afd7bfa381a542faeab2f636c4523b497fb0ad773b6d25f119a8209e6b25b97e23b22b45c2e31b798b174e9436870d5d93bf622f4cf2784e6ab927bd12373fd60101a548e90f2ab6b8a4068eb595a29d77a09e1ba1fb44d6ac14c69154a307dd092ae97fea5ae5b45de83b699bd6cd54291a9e34143ec5df57b8e13003b687031873a2697dd8cd802800eda43b70fbdfaeb7eb6160072d01e53c6581d54cdcdb5008083a6cd91e5eba58fd67b01008ef6548abb7abd5aec39b54e6ad1d4b3652919ba6f2fb54e68d19eaa46f529ae7c10f13a994543be8ea5fd15d37a6ad7892c9a46b5ff0e393fe82aad93583465ce3b216565e6d675028bf68cd742db9e125298ebe4152d5dd4a8897cad828fd6892b9afa478d2a314ea512ad935644fea4d242e591150daae76fdef7dab98dab68909d5b6dea3a94d8aba2e9b36ec5da37aaf5602a9ac288de39a6d1b197202ada22a89e197562a8d53b45d3d75f8fe3ea98fa6e8aa62a6dbf3b95de3bf62e457b4fd0dd396a62c9dea468dc29c2e5f836177aac47d1fad7aba7f9d9a8196b51b4777e0b2ab51cb1fcd5a168ebaf602ec50925e65683a2a9c79b9e905b77f1717fa26d4cca41cd8592aeb7ed89f6103f8aca176c14dd76279aa7a5badbc8fdc1b5cd89d6ab1eaa97fce52fb5bd89e67a134b4c15ecd4985a138da1fbb554bab794f2d499680c2a4a15996229b1a7c6448b6be9bac73139ada57d89a6c9ec14c2f596256b5ba23db7f623db86484587ba128d1fdcdfb51cb64b2952a2a9944f91735c91a10827d1983fa2f4765dda8f4f124d297ef7466bd74bfd22d1de26549b165251213b48b4a8ac58df8aec51af3fa225185ddfcaf8c93a3247b49412722a3fa94376d688c612a987909f7f713346b4a80aeda3746c29976c116de1ef82c9f429b6d252444bf7d6fb312b7a08b64a4463f0557aef3d8588a6bc962fc896bbf48a0fd1225c658a29def4e25b4334750bd37572b6dd6e0bd19c7ade3031748e182d219a625da7fbdc7a56300da2a553eacb5e6e5abd92205a2f54a494431a135229102d46d5dc2ee64a2aa2048816f91f217ff916b157f587961844f0df63cf173f557e68c99343a71ebd4b4b55f5a13de4f031e7d6ff5b988a0fcd2d4c09a3720ea57ba9f6d090c6744b956aa8de434a0f6d975375edeb59ab432a0f6d3d3d8f0c3f32237e3c34a8bc5731fd3bb47edecbfd675c7df4ecd05232b42aaeb5f8f95d1d9a267efe85dcba963b3a34df7fa8174cc5d6af9b435ba72b15eea3dd7597435bea3a65d2454f573d0e6d11728a913e63383407dd7289b97d916bc66f684affc55e8d381d438cddd0fce93a23f5a9dedfe236b474116ec6e7c950aa6636b4565e46483d7aebb8790d8ddda633c4948baca2623534f72f397d29f5bbb798d3d0184b90b1e56cf4d4273e41437314552aa6ac11e34e7c72861611ecf58b562e874cf9c40ccd1d63eea14b89656ce5933234ddc4b05542f17d6ae51332b446f932ee7762f534f9640cedc566fb4ab5ae638af8440c0d324a2aea7eff8a31ee4918da534f282d9716a5efb82760686f973a87baf93ed3efc9175a4cd1a55dc656a6a7bf275e68b94a5976cace9418ee49171a83cc79ee4b458f18ee09179a3663faef5adf42eaedc9161a8c2ca576eafccffbf6440b0d7d275b2afd73c9d7ed49169af67b293de8942b52b72758686bc5151f25a60d9df33db942f38dc9758a2cbe5dcaf7c40a2d537674ef14fde5fa9e54a16dccc596478dca3af99e50a1a9b3a5ed0cc1dce56c4fa6d0a28311a67de831b3c5f6440a4de1b3440a574a7570ed4914da4b8c9dd79d2df6b6f7040a2d7d3d31f3e8deef537bf284c6fa17533142d68831b5274e686f57393d2aeb42a5f6a4094d3987a262292a66eced9e30a1b1f77f548be16a65bb274b6810b142cfb4573dd5ee8912daebe68b8ef5c7c59f7b9284a60a1773a498b137e79e20a1397feaa7d9b9907a319d1ca12df75246091febaf984ee2688c184186d84ac46bc5746284b63ac1b75c414ddf2aa69322b4f5783d76ef31dfdd984e88d0d6314609f5b791f7a7932134772a13542e3d23579f4e84d0a23343ee5362ee29c2741284a6d253e5947b6e3b1da613203494dbf0192dd3980cd3c90f5a72bb8f542d4e0aae4b273e681e7d5399b3d8afd7a5931e34cfc8d895197f4acad3090f5a5aa409eeaf440ed5d3c90e5aec75fa7a65726f394b273a6810eadbb850765ce72b9de4a0e9beca66eba9f4225be904076d25041ddca798f2d3954ee068da1ad93de7abe0d2956ad1105cb81f9ff2aee59d68d17421851272afd2ead469160dadc81a22754a164d978bef3977fc31418e4553ffa0b2aeefc27f0c8b96487f173a6f8f8af12bdaab4e117d2ae398ccae68e9544aaf98ea8588b9156d653aa62a595cfb222b5a27e6b9cd3cdbe1ef2a5a62a4602b43eeefe0aaa239f3bb62faa0528937156d134b0cdd260715eea2a23d4f8e5f2e74303ab4a768ab1ba967bfcf5d31255334b65ed94715bfd75953291a8c301d74bc529f4a9a48d194315da8362652ae511a457348d1bb5c5ffd9e50124553c5d8e1aa227ec9c550b47cfab98bb9f79cf3088aa6fe3d6ea8d85a49b1f889d61e5931c4d67afc367aa26dabdaf850dce75e8a9d68ccdb1564bc5163fb73a239b5ef8edf22860ae1261adac58c535aa90e1b6aa2bd760ad5bd43bb54c14c34f41e6fa7554ac5a810132dbae89c5faaf56264ef124d65528f0c997b9fa0b34473e630a605a1fb5fe62ad15429e7b4eaf1b3b51c251a532837eea642ebad9b445b1995b39365549e4e12cdf1477fea3a766ce591688ffae96b18d5f3b80e89a6ec10bd67971edbf54734d428f5d37f6cf147e688c6defedf0b2dc7d8b146341799eb721c21ab33c6888692daa5fe39f2c7ca16d1d6fd5fa98b0cb9dda588f6d90bfaa7e81829d589682ffd1331b5b4536d23a245872a95c3c422caed4334e8f475f404f3bb531ba2ad980ba2c4512dec5785688cadf7ea9321a49699104d3dfb85faed7f848807d160549facd455ccc756102d26c81625b43266f706a2410593f5d55a2f464e80688c18b2940955ffd0d442adce36512ae554fdd06242e5cbed62ddcc55fbd0102be4d24290a917992a1f9a5a48df63eabd4a67d53d34e60f72c2e852f5d01ce3e56c5727ed8448f3d0d2ea3a5afbfd503ea47868cc633e7752eb204348efd060dadcd5cf770cc26887c620ebee6bb78fdf631ddaebfb5b502df629a94887c6eec1b58ad8bb5d1ce7d056f25ca774ff1dbb974383b17f632f7fc6a1b166bff6d915e3769870684f73798268a55d08c17c83af4a6be9427e6e682f22fe87543944cdaf0dcd333542fbaa30533936b477ffd0dbfed709b15b43cb84d8c1c40bfa8bd1d5d0d8572643513d29859e86a64bfd26d4ab10c5e468681ad5af3b8de815277686f60931cd945895e12f3334a8fd32a52aa850ea5586d65031c760ba9496a69564682f25642a5fea31b474fa0af9e37f2f46313416934a8c392998ef85a1bd4fd8f07d821ad981a16d326b651b93436efb0b8db9c7cea13f77d8d95e68ae1e1b2974c84b3577a13d544fecde4aabdf4a5c68aa12b1540e3e7df9b6d0d4337608194368d3d2427bad3c7f9dc795d99a859692638c71195367ab58682c2e4f6b235a4dfcf20a6dfb53666a73ccee4c2bb47e2b95cad5e8492dca2ab45c7eaecdb2615c910a6d3ff1c74c16a7d0548afd547662bbc9510a2d2a7768996314dab37ed96f777b397a2834b4de39e85854adea3da1b123d58e153e8aa9a1131a6494d0d7d9799f6a427bbd78a15eeeee45f498d016f673cce1820e41b58486147b2f8bcd527a764a682c3ec7f9afc813c524b4d69494f28ec8f9534868cc7eb98818742a2a3e426308a17b1e53b376f238da43aef5c16655b4a011da2b5facd5ad42a658115af2b275ef1562682922b4541b535fbf87a04a3684c65ae1f32a84a9570ba1a5ce749deecac58456101a52c83277b17fcf1e082ddf67a2f56ba56fa67ed0f87529732a616ce47cd07829ef320675e1533d689d5047e75d6c95130fdabf5411a9841e4b4dde415bc8317cf6fd5e74ae83f6299d23675093bf37078ddf31d56cfd83ea61c241eb75c959f77b8c149ac0d1d8829db970b136bf5ab4fde52f2dd7b17539a54543cbfa1b634c0abe9b455b083d88585cf9ea51caa26daf97a27ae7badf63d1d857237c2efd8b1116eda963c51a178228d92bda53c8337eaad4e716215734b88c19290493973d875066dc50d28a86a02b66b073d93a5685c1646648e450c28ae6ea25e5ff941d62285dd3d9b2c2d164323b3b0519927941c92a1a83ae1544f1f1f2c8f98b0d25aa680d1d42d76b217f4e2ca1080182928aa65ab1dbe51e7441940c25a8688c9ddaecdec8e22e8f25a7686ca5b7a23acc9518c61253b48fce7c53bb4fce39a752b48d6cf9bb54f7f45f468a969cb1c73adf2323c73d8aa67161622f53f573ee5114cb72592a77a6b58b3595a1b5e8177be6de41873214eda9c47a59a5944f25c7349d2915289a33ca752c42889413bb4fb4dd6429bdc789b4379127da5b8975172fbbbbd3d58906ff79720a29159735264eb4f4d4bbecfd5dceb1dc44438a1574a7a0337c885e130dc2b45e7cf8693bd3bb4c34b69a1073869867328730d18b54f5aa4688a9956a317b7287a0aa82aeae94a6a0e4126d314e97dcf3a89c526f61562653134a2cd136a368cc963386709f52ec9728dafb5c09353afe957c35140d7d844e974aca5d2a27281a445041b5af52f2e7f813ed35a2b488395e2861f244cb7dfdc82bfabb74459d680c3f3ac35d9e5adf7a4eb4ffb5dab0577ff93db889963aa35ad9cc5377fc85630b4db48c913d4fc8d02688deda2213ed3d061531fb8a9b883d4c3456283a73695be5baee259ae308df7d640f418dcc128d75d332dad48ce83783a80e3224c3d9a2122d73bd571bd5f773a8e11ab205259a67366af48ac57f4c75d5249a72cbb49fbe8cea0a97a697156c2189c6ef25e6849ce9d6f5b2c1418664325b44a2bde4d25afcf87df4a41e247497c285547aea9a4e65822d1ed1fc7d75331655af74dd5b38a2f5c2e4eb53e1ae5b19359def72c4b9bcb4b0fce01e5b34a26982eaca3bc25cd11964445bfcecccb6914718d95b8453a8d56ab4b9bc85225a7a0bb1a78fd45bcad56e583289680cc5a7aad35f3b314444538ebdd709be8acef71da2b9b4a04b4d68454334e83139b51452efad3a16a241853612a2a97a0a41869aa97696e2209a62a9113de5448c3b0aa2a546ee4e973a8b88bd40b4cdf79d0b61bf76e980689fb65d4c88372153ecffd090cbc85629ccdd94ecfdd01c63465091b652fdf2fbd010744e1d5bf40aa2859e0f8d61dc5f450cdf2965700f8d6333949ee76bf522433db4d8acd3bebbe65d48611edaee2b84e063df7731e2a1bdaac72b3ab6984516efd054fc8d683d8f2cb152cf0e4de93eb76ba5ebffe757879638d33b5a5def50f2a34363efe8a9ea7fc91ddb378716d939f5b4483542f59c1c5ac6057b756ca590d2e7e2d09ef2fb7d6c1dda770787f60cea2a9556729690dfd012a78a1aa34299aed9ddd0f8fd2a98097fb5a1215e7f8b9e39075d2ac78606f59dc61879bde694be86a61042bccba1171772676a68ce9fda7f883c0ded3f2aa4e27a3199e1626868f0a9c6759f928a48999da121d6ec395b650a534533b4c46a353f056346f8b00c2dc6b8bc362a5b6468ac7e7f39527d5edb6b0c2db5af5219512f31b48dbfaca16b540455ad30349596236fe5f9a04a6f30b44cb52abac4ff5017eb2fb47f7dccac4999aba8da0bcdaddc64ef142ba88bba0b4df7692fe4e9b8d07a7127bbb55aff61aa2d3496cb1ec24ed0393ad44253bc8b605ca8d4629785f6fc76ada7b429327358682ca5a4f1a108e15399aed01e5b29390535aea64bb642cb859d5ae373d55daf42537f4d4e397df718ed52a1fd7acf94628a1df3bf29348f6cb9b54c997aae9c14da8b2cf92b7b15a12a8f4263891c624e1929f41414daca8f103de6c7ae13a52734e8ae0c37b94de952744263fcec97dfedbe6e6e42cbcd4e4c2dc78aa94d4c6830f2724f15540bb5235d428bcc2e41c8c9cf1b9912da82beed5aa173f5b6738b24b456c4afef93db3db5d01648681d9d3b832a45b8cf4fa9b81aab882d8ed01cd4a456828fa2a633932842c4405959f9a1749524628b381a33e585f0dba9a4ce46684bb127c78a45b6de666732bfe58890cd456c5184a678f972feec76bd649108ed9779eb53d72a125b0ca12dd54fdfd13b56654f080dbed42b5152cea062f95b04a1a55ffbf0dff1eb8efc4068998a21841254459dfa074d311519b157ce18395d1f34f68899c3cc885044a93d680a13e67a2a6d7ae89f072d1d2bfee71a9de1dbdc6207cdb7515a0ed3820d95bb0e9a2773ae8f2edd2518910bb6c841634e416e980ba55b893d0edabec4183ae86e51ca879b2de068f9bad0734a65852a5d2d1a5a4c7f5d54ecbf52af8a3968d13e2a57a79acf2ea9f866d1dce6ea872afd62f73673c8a2a9a5dd287d7f4ccc5e8c4553e8defac820442e7a475834e8ad09310551beddff57b4f777f0dd6ac3a8f29d2b5a2ec8122f177d632772ad688bedbe142333c68af658add667b554ddba55b4d4d84899e5624e8f2d5534f62c31169feb7372dd3952d13c3a85e8318fff38a6940315cde3ebb872a5944ed1389bb966b81e63febc4cd196726ffdf9a9fe4b2d455b8e7717649d4f8ac656c7e5fe0e215eaf8e906314cd59a7f74edb4c5564bf0b083944d19aa9d37f18d7c2e5a26a3a53730e3942d1985abc54ae151fc5f49ea6b3c389c1fcfbc7b261c16030988e0f141f475888a4a081c1c414ceab41060693060683c160304a0d95f71083e17ca6a533803ae40045836b299696325f99d8334da78b4a266947a591d648c8f189b6f011734f89fb7dcaf64473b9cd945ba8d0934aeac2f2455877a2bd7da7abf3175acae076266f9083136de98a2bba469bf6fdfb265e4a16d3a5effdd4944c66a79143136d996aa2b77c25d67dc4a9b2a4912313ad1167bffb75f98c29cab83c914e971763ad1de4c0448bcfa1441026e410fa5e79899654ad7ab5fea13ea59c7a90c3126d31e72a3154f1f7bd9889c174527ca4921fe4a844f3dd7eb8905b57ffbc09891c9460c5ca29e89c79a57fd621c7249ac26dd555f89295a5f7440e4934c7c9713383af5093b2418e4834c4ddc9d5ba7fca51ebd2200724da530ead77efc83ddefe473484105a19dfc556703d1595231c1747345f4c39767b5c06e35b4d27ff2047231236bfe5eae5ebd585430e46b4978e157a6bbb7dfea5e944b96c116d29f412477eac6a237c8efac8a188c6ef5d756b52adaeb0b3f4478e44344dfad862ecec47460c166448e68d1c88684e21abbec42eb9722a1de43844638b41b4d2ebf5e5f4938f85c160302b6b1811c268830cc998b8218721da820bf92b37d3654c53d3b9549c071992e1e428444bd7c719a18ba95e4125447bec0faed24e5ede5418e6b8b4e418445387d65757426b64f3050603dfc8c6a5164454b44be58ba8d97aa5e95c8e4b8b1b3902f1ca50d7ffc27ccf8c0c848ec1a4384748625a72891c8040fde2475668f953ed56369cc8f9222c9b2704080a5292c8f18797bcbabb7dc5d87e70d89c4f53fff7517772f46135d3c416432851da6c8592b55ae8bd86ccd1cbca72792183250c56410e3e34969c8a9a1c57749f8c73eca12daba8ba7039f662adf4d0f4fd62aa5f3d74c9ffe2c89187c6205b5d68b9df8f899c1621071edaaac43c35bae78cad5277682bd13bb75432777d6bedd016540e2a832c5945c5319825428e3a3487d0bfd58e5c740caea44383eb2db40fb9e4b420422c29aae598437bcfe8546f7abe1e5f0e6d1b3ae8aa16e295dcc7a1354bffc4dca9881e837068ef57728f5c6a84187b6f68abbbeebdea5ef33e3734f87e2547d8ce34e96b437ba998427e8ea3373b1b9a53103a7a0922560dd91a5a548c15fcf58debced4d01639d4559fb893329686c6cfc18f6fb5838e97a1a1adc7d66328a275869614b3b5af5c9fbe5a6668cb1dd2554f2b69ca5586c6af9053ebc5e8cabd22435397383a574ec531b477c9a94eaedefa742a8aa1355b88d0667cbc38550c438b4ab9a5127ceb932f4730b47d7dcfa5ece718b98d5f68686582aaa05b7695297aa1b964eca5a40f6e4296b10b4d35a9b4162f14b9d098bae8cfe3fa9850c52db4a40c5f39eef8b051d4427bdf49174cc9c5dcf75968f9224b113a5e7fe61e0b2d79e5bb434f8a7ec12bb4446c4104a1729990422bb44ce658554a4dcbfd55a179b7ae147d1d151a7409d17b6f985e749f427b2eb1e4bf9d1054e45268fe29fda6b4dc2ec5283414d97a29114a5ff8a0d0745dfe3efee5ba167b4263c53ac254b9d45531273487ce51424a59139a8210a682cb2df816624c689ad92aada7ffd4d3f54b682afd7bc52ef2f385fc4a682ed56f6f2b4e4283f0a9c5fc1c629c3021a16da75e7ebcca8bb1fe115a72fde26a3367ce451f477b0a39e890a79758e46884965064d784363d642e4243296e8ce9dd13a1397708593d2babe60fa175a374f0a586426829c6861b1d8429230c4243fe52caf8d6bec8d801a1bd8e2bf57b87582a5b3f686cb1a8de27e5ccc9f9a0b10893d9f9a66251750f1a62eedd4a9409b2f78a07eda9d8ec652fc4292ade4173b85ea32eb8c921d4414b302e4bff8ac5a73c072d2a18579339a6de6b1c347d303d7e8b2d8a8a530e385a2fd66f1974af4b792ddab287a23f5d49f3b1a44553851e43550822767116ed29fbef77baeee5cba2e9afcfa49266be65b1689b6c6d72285bf53682b068ef4547fe925a8698c657348e9fcf2da88a3df1bba2fdbf4aa560cc5e47af152d7923faf74f1f629115ed9f2b7ecc6064ce70152d3ddf57055fd762a68aa6ecd7eb46b88b9272a968a9cccc7c7522c6222a9afac55cd9bbc78fd9291a54fbb1a16b5ae6c84dd19e636edf7b11a5432f457bdc9e96258fdf6c2d523495de7acc5f2a7bae7a144da55bc978a112454b696352f64f85a23d7fe8f991f27bfa18140db6bae5dc631c5152fe444309f32506578cab7a3dd1605257fedb0be36aea447bfb1073adaece392a275a4209b94cfb6e25c5fa36d1341d43e951623099f569a2e943ddc72839b7afbe4c34c892f7e34e8a89c68a105aea69a6f75c5ea239f8a953bd855c3e979668283da52e396ec297d0ab445b4a6daa83ac3942458f12cd2575ea7bdd7ba8314ea2bd55cb5f2df8bcd5434934b6e81d62a78c57622f120d2ea7668c8817122daeff77ef09ad8ec8b947b4e6a7bb947aee88d6a99de9b77ae730b2463497d015b2fcf5aa8e31a225b616ba66acf495b345b4e4bbb992e38608e95244734670ed7a6efd57ae4434f7e9fff13345d1b311d1127b77879437e5727c8896effcddfb55df930dd150ae04d39b31f81671211a2b651459c3f5ec9810edbd55dc17995f2e4e83680ea5b5aad943ea3f2541b4979fe04328b363d21488f650f2d4bc38a6a4af8068d15db2c47671af7cfd434bfe188bcd11a5a5ac7e68f9d2fbf77695c2e5e9fad094db41e51c63e59ca6e343736a15c15e1bdff522b7879694d387c8b559af14f5d0e2aeeba62785bfd2e7a1c59430b2d808c58d10e2a1718ad9fb10624e95c23b347e0ae32b7690f9ea6787a62efdcb64cc99685f1d9a2673ae8ea5b812d3478796dc35834ed56ae5ede6d05e21774bc52787f6bed6bb86cb8bdff23834d708391fee4214231c9afa4dce5984cb01f08656d1bd7210b91bda6a3b64199f62caf16a434389928b8c22e256da6c680aeeebd507e143b96b6851992ad4dcb79255a9a139087325a82bfddb988696fe916a0737516cb76868cb35663b436fdfbf33b47ee4babdaeeb7d4a6668ea98a77568e573f732b4558e5eca546be593a139f7d043ff0cbe7a8fa16deaee3204150b9439a8040e8ac51249208a822006600004d2c9aa04008314003038201c0dc662d170a469db07148003486060a0362a2812c7428130240884a120866118060100846110860120069d41a435008b20888bde257cac184e2cc143fdd6bb13978cdd4a37febbe29adbb3f66508381ea0508d8b46c02f837043c0a5dcc975eb3d137a0fcd58f5de4d1b48d78ae21dcc205be2168d83711806e0cde796cffd579d33dec7acec2603f417b779d73bd6d27a9bf90575d2219c54c5661a13539f727d69bee3643362d4902e964dc78698ae3519ba23a3349cfe54a21954609d5195a04e807676879126ea2d7d2b4f5f5608180ebd9454bf260eb5616a2e3ec98b5db39fb533e2c70998892f70287a9c791792a2913d0e404e702fe6e4947dab160e3cd927c6ea62bed88493847020405228893ea3faecbe7c28ad9c8a594383da28e67ad1d10a1e2fa17224c6f3580fe9d6c715a916d449594711dbd89257af4945df269b5ddc37fd9eb7a6948dba8c159ce05a191c17e62d4b48caadcd0b2410f9f305d233b55812c68a8568a647460188441e2b4857b02a88b0fa365a86a6d91abaf810cd2915b978e6f58990130a9dafc6f4fe4e5f045775116caf0bf784102cf3750a235a4791f8ffa724560d0b93c2cbec0ab93aaa1725fbd643c5bd7a0791a29e2dd77be66fa93c7d979b9e32f773e364d387a1cb8ea3183db0b9ba75d175b9a576e02f69da3762916b0e1741a8ccbe316bb953061cc8cc16ea5516e85516ec650bdcebbd30d6aa52aac39317eab518b2972d8cd0eb2b582f38858182165076084c491a8962b6cc20aa976716d701d2071d41040d6be415ea36855d260073dd5401e6690d33b166c117ed0cae9621aec39f689c55c2b7701da82137cd25fcf5884f926f0ce7b4e10ce81dd6996099ae04f3900d14e602262343e362d4db461383da8f65288e4cce3499e905e4736b965abe7951a12b203d8845040e7397abac0d32f5d66d89b950ef8198b835375c29ced374d5b5750b34014ddb4d1af06fc5f0a9a00907192c85667d44b0991327cbbe6939d103e89ddae2f1f75806c5d83174b0a227e78bdaa972dd09b5df885f2f7c5f1a2b136de159789b9676cd4b2582d0bf103ff6a36087e757afc758661d08c5c14eeb09fc26c9e7a88c30537f4a406d400e688c155bed2916fa1671879c93c0606a984c3aed284c269e3b8ac7dc0c517639f4ceb94874bd29f49968a95c38258371bb6e2b67c1eb6e869d9c9988955562e77712e7e9d0521835c874a7ee005e9175ce3aa3fa679f79b195ea68d5789368ea440dc070002bae3cea034dcceb3d98f8ffb000326967d2fc8704e310204088276e5d08756c335e5dea4f37d19f3f2472a633ac1247396c096db5c1432cd37edea695b1d8b595f3a0ab1d75524ca4e0ae0907df608979344da96504295720177606adedd2166af1af1c01f02d8ceddf29aeef49fab1c4a4703fcb75a3787ab254ce12cdc8b9d9dc31944eaf02a0926e0425ce8d094494322cd0a9249e2a894d53e111c32303673583a546e34a5a3f389e4ac19ef98a001bbdf751352e90848f236be7ce0769d02b78928d8ce9377c4e18df7f31e048c858c1f2f8cd4a424c51adf7fee04ec01ca3ffa0f63a99aaacdd719a1cde60856a90d1c02a4eb4fa0b1d34ea5ba8e6af2602eaded44d78fb391f0998442d7763e1cb91583a530c82c73a7805048891ca12130032b1e6fb2001d990b14941222f0f3994362b96a88e1351d1042c82e42340b65960bd5934e0a6a018bbbe3dc31bbc1d8db3df593f21be1bcb25262e1c590896d85bb8eba736be084738f5284cfd3ce274d0a1d640720fa6168f53220e0d734a861df9c946dba6680fa8d40fbb44ed3e919419b028dd6bd66519d11e93ed87822ca129a96d2851bfe7a8786e0bca50da7748781d938e097a710b7e8aa3a53f0fefcd628d1a33c55d65a85c1817211df4117da28807735638ccad86fde8ac467480cd09be0759ef442e257ddc5186eb4a424e5daf2601f9573ce309c05c4bc3b27aea6277526e491180f23fe307cd9ad681de5d059aa9561cdf6ae5a95360d670fca4c10c904f43e22ab5be7a495083d0624c67fd9e708fb0c2f84d48e6e2f741733bf7e64bb745c8aa13e8992b0bd0d4ab7014953d3d25196dac365c10dac88d38eabbc0e9caeb24baec2897d3b18cebb2a89eca8eb39d7e9d48f06bcbcd7c2c62c8dae71aeb6d3453dd485cace673409500bf70e2800289497a7e1c8a5fc65c4d649fb51436e1c60d0e93a1246f85b622c4a4ff180ee045575a6c7059f54f729c1e9da71ebb2bc08d62f98bf03838ee9e9b17941e9396f2a12eb8089955b7629a5f6988d941bb15bca143382547e192d32bb3c454a57a778474e1ac38cc159c862d116d1c7b71512318b02de59cbf77b77d08c680440125d35fc93f8877f32aeecc1d3ebf57eb189ee50105ef037e8951eb1ecfcb1b568c3e29841d937426f7b4807a12173456d70ee206df33d5e29ade92fbbd8fb7ed2c81463fe24ea63dc75366fcf1cbecb8c9ed0304aee5213d474b4e7c845afd420aa4743b9a56825c73ad46c3c831bcf6d6d5a376558f2455cd76cdcd97b559f9f0445e1786079111365f15c0fcd23a700e4e46e70a7ddc1fa7c1c039c83847ed156ecc992623db1c83694afda60cb46e82e6d010c43cde8fe2591ed35b6cdcf43d9581763857f4fbd4bdbf97564b9feaa3d3bca4e5224c5069058d81ea782a0eb3258ff8113c9f47f51e1febadbac7fbd276a49c8b7cac07751cde4e834b93e8a806ddc7d376110ee2991e907bb7336cbce28a22eb5a8d547c0381fc405227ff0797522ea9714ead062b150d659e3032883feb3a3ea117a834bb18b7c93c6837c118e6d07b727b6d12a5658363e0a7d4290f4f276a6624089ff8a34d9a0b422abb2af8ca12b9914323c587e920e37c3554f8115fe28e9c6392091b2f70739838eda9484519dab4766e47d17c1acf277be00fc23099b1c3cd6c9eac99ce6ce6936cb825f7f71edde64d3b09d684c09223c244d3099ade53007d427b490e4526560426ee6903c1ac09777243efe3d3bd5807f12c0fc47d73986d68922e45779dafbf469778dfeec16dbca927e5da1a30b9270c3485e0d21b0aae79fbe8c1d2fe8a23748287d94db8c49bd32708e46cb13e8d2167da8aa6493e352092043198cee48135af663ce3678391393186e9080fa8d96aa067fe1cccc919319a4ee4813556433ce30783993919f3740e8fa8c96aa0077f18ccc901319b4ef2cc9a57633ce10783c11c18f37408cfa86935d3339f1c5026856280e39da37d18dcc4ab7a48eeac0d73b0db70122fea313128e24cfb0902cdac831b729f9ee68b3d58677820ef8bc373932f7baf6ee07979390ece211feb8d3a0e6fe765dc9c7b7ca2d7d5613ccc83716f0ef07dbd726d66cf022117a697744b6b689f2f41b98be3d4267d290f4daedc7bbc61e7c125e3affcb8474b19624b6c02d554c1ec4cdffcfd7937aecd31bed5fbba0f6d58a3e610aecf0b1a2b5ee1c2fc795e5c9e836c586495038fcbdb61493489c6688c0887ed5dbbf3ca8e973b80a865be9699d32c211fdad0f4c4f22224a225031b889ce296ccb5c97c6602b243c38a2808371f0d587e708d36f5a6a45b0b4cce8c8112b23e1d153da1c533f0afbafb091a86fee960d7682e29772c4381dc41ee8639ad64ff3ea592a5eb0e1a0971284aacc5f2118110556aed5d22a5897e1d84a549aa473149f4a7c850b62945139c5cfc2368c75cbb54dd407c6ccba1b84c926f865e8913cb4a3ac4ea1202fccbee5855c518699d751cf40d8a01aeea4ac2633130f23ea06db17a06f61c2ed8ad92ebbe0535d7fe8e9348933658c98429961bf28b571062cb2bd547d44d0fb9100e8ddc1cc7f7687b2cfe77606804cf968f6ad4c9a20f49cb6734b804883d3d556a8afa7a79e01854420204c434289ca5297fe69e76e7715034dc64f420f3d8730f9401c4a69c3efe7f28ca7f629e98b0d677fb53edd31dff024013d3fd2274c426c078000f79c5c13f3cbf7b9cccef17fdc842ec81e22774c18a60a4fa6f700e44b57ee1ea545bdea7c65c11840e509143239cbb0314dfa49e8be76099c5028068e3454a48e977b8777c568f88b6b526ace7a1c14d61adde7126752242d50d12cc4e3a1f97da7e38e10ae599b170d79e4e77254ba04bc289d0dc575112ed68aa0834aa9cf47005520012adb1ad3fd98d122ef4c07c8d68ac9ace7eeae2230bb0875888b294882cc219d082ffb80e848675a8e3c8ae43629e43e135e2c944ba2f78eb548ffb0eff301d8f2a9151922b80e2c85a319fae887e8dcc210d7fc0c09566ef7aa212e47f6cadbc82b892144e86f737bf61a712b12624677634d7ac248143912fc8ec76da8495a649ad9b53fd3f2e88d09e3cb5101f6f795162ef85f9710a523cc19ed95a6c6dbcd5c453c5e10a713a655f36ed361ee25e8171ac3f426a929cde3c986ad88bcd61ea74066b500678a111162b33f2ae43ba88b2c0101e2612e5b9b9a701fa7f47cc2cea32be9599adc00092e3775468e91efcd8ac341cf311e5f13b53db8c7fef332536cb6f3594115667a9ceeb43a5f5ead2eb8aa53213b6522caff03cf147515a9bcc16e3fb88f27f51e300d57876babb66d418fac7a57f4579aa4f6a0757a0dc13395cc15aab3bce63cddd88e75660f5579b04014ee85c26b82759cebfbf9978e994661bb4d865fd6df5e60484bc999d9534747ba49e10024653f022468616b6038535c2c614ed81281f23b3b83ec82d0ea5b5a76aa33ac16b16801a640a462086fef3c791fefb902cae9bbd9128f5f687e2a16baec2c59f8d11418dd653d4b3db11e986e55c857f6e159df82418ccf5296e7f4892695c1f0fc0deb5170daf3014bbb315573ce32dad1848262afb7e40afc2bd57e5a3da54ff0a13be7d15c7792b1e2aba4ce82aa22a816b042aa9aac810bfda6f1a528c4cb4b15da376e209c937ed1bb3cf46fc7b11e3e2a68c5ef07cb3d70621d2474526dc084676394218c00b21b2a13dcf0f14cdeb43d36c9171ba1011189b280012bb6e38e01529c2a03c075e0242782b03bc23204c9900344965ecc851acc0e14cf916dc51fe0890db02274f2b2672f615061a70ee19f0c154e7dc38f42561b4e09900af6ffde9df42b86fbf6df3d971e6e19e5fdab3ce6587125d29694eadacf86982c1f6347ec14369912dfe9b2c7005604827ac6a8061d5a5e51c5715977a864d8378429d5ca7ffdf15838baf0b9d91db8632d8310b981576298e2f96a8de764391cee30bea7ce923537f3e61bb1257f96d6b29d16b02b18b44e1028ea9e75821a1333d2361fa4512c19575464ff4b609fe2b97867a70837b359e33de14a23fa8605125a14ad4106a97ce380e661047a2c7275913094a95cb3164cbbb39630647adfae341fbf9ea512cddb51388dfa66665b27d9f44cbdab2105b96c498650150a128ed224167d6397d2303eea94fe2af141d90fb305c08a55a907919c3910e7fc0fd108a178813851db0fae4fd760e2e339c495fbcd1bbdfeec7cc2c02877c7a8b15130cfbcf95c183886215c9e9979fbd9ae6e91685d7b1c22d2f5296178c82151310f1df5520636277140d14ec4bff985e8f55ee71934f24f020470b7471f4db14a063127f9585f504d48fc6a752af0a5da9423d43225021ae537fc4312a31644016487a0e28800e393d6859e26042a0d69940d1b952f8709ef093e00ae8a2228aa55df88f50c88f40e038b6ceca2c83c24bb784484ee012b9922bed75939f8b3ea961a164430c4911b380546dc829cdcef4020088d80e964c70776f8fe6427d6e34bb4d76e9d3a56cc3e0bd7cd00be1380f1f5b64eb5cb215ff2bc223bdd469ce3b97d87ca246793fa4f59859be68905a0894c20373f342324a058f651d9f63e4397dc17092015f72e976ba91f02da44b1faf4092ccb53dbc61c60e65cb54bd3d0ed69c06db6c6a226aef78bf85ce5ad46355dae6029433174d3615501a77b97aa9203db5687a5887c203e4b0a9de984063823387c8b83027740f4b86a019d7b77b94c8e18b20544731fc0f5db46e814f2a6d3212ea7df554883724784725f4476be586d53d654d9bd38e77e6751d69789bc26c11011f8505a066ed144ca03a94cc60949468cdb4ded7b48948200941014ae9b94f07aaaf3c768ac77ebe8da5c84551595ff6e2ada0b534fd06b977b6953cd0e1ad687b39393c437abe3ad3a99188074685b16d013b613c1325c55bf39c2d498d15748845d5a8d5ff91b573ed6cc45b306c07f766313704b99ed0814afd60574f9d6193af00a532bda3540053fce389520657dc29e10e7d1374a89f69f1dea36716ecf6ebe401c414917db023882288d02c25fdf18b03bbd611eba30ac2f837a0a24a3f5e7f0428b7dec839bbec920f05feef66058312539b4b2c478deb648796f7e4c92cfcb554bbdff07ba890e509775b4bb79ca1ebd536eba9d72658ebfaf474c62f8e0a1bd130952203d38a3850f7ce4ce42e54c0797ca49cd5be40916e2fc847caf868feba43d52933d5239e9566670e688037056cbe410888a24940cfe886d3391a242714f8236fd9311eaa1b37591f6ecc7d2667f4cb3feaa2396bc3728466f71f7c47a1e3995a5fedcc709e0d2945d9709e18e0acecea09e13e3fa0231f599c6a727e93743237a312d203994f9bdb88111b183e886758227994841471863d8243bf5f540c3abbe195c700b5ee7756f651dca419d5d26c2b1f4ea8ec1811e9d1f76e8237eaa5448f17f023b9ad703e02711bcd247c40d57d5a79643a87fdbc0fbc77ec502e1750e9564196e92dee6404ad4d6e4ef5cb0bbcfd632d17d7e4b243153610dec761afdadc0167f487b37ee05b8e9aaba4308d1172720c9208cf124173666f550b235fa9d4257a6a0e3f0dd01d6833505e6794a30946bea6c8e9b8699bb99fe140a9595ad764338c2442b80939472086b991fb9d4e7cb7421d1f09aaa76c5335fb075c76f42a6f27af0895ff444774e043233b2f7a6c316b97cf7cc1456bf2cb7ae40cdd8b9dd9ba46bed0a5201e9a7a5b2bd3c89c58926ad896ac8e3b964ac2766b85f666f568e20308c3de47683ef4ce487f4a94fc19dd10dc1f08b756c9965a976965fcf3d8b7f71ee919bde4398c8e080eb0c7f0cd9cd3e5b937ae94f8e160c89caaad5fa27d084b4e2a8babb8dfceee7abf208a03a56b0170ff4d75f80f86588adf5f54c5bfb8951c67ca8861a629f096e5bacafccb46e303a03a53c7c240b1c9692c526819f786b0b1a2e7fe5f8166823f90f49dd2e03368af3ba604bd9d60a0c39e7432d12cf815ae8e04e107beb5785b02e5012e171a0318796a0f2149556f371acc510d84660937dad444b43685ab7405ee40eccc1a701816b9dfd0d6bbf8e5284fcb8501be04e195018402f638da0b82ba3a1b8256959e219e118e78c176497cdd813f29cc6902ca553a1a805c4cf6263d8e8fe82608ca6bdcaafd426b8c739b1ef7d181f7b6446c018599db6338c6dcfa2bc2e1544238a806385007e3a012c62faa60717c300efb21c0b581f1f43284206712db782636833762fa560f85737a05fc2796591b0490d8df0f360524de1c88abd3b9c41d7c3d11f65124af9224a2cef90fe0d269c42753a4757176b050f61aa46dd4264797918acbd752d1f3eaee9ce49f51fb1982a3802505d9e0b4383d3cd9c625cf93266414152e17d034fdce0be3b03c50d45a8e6e14e57eacfc706b204bf6beba93cef27cf10c14ee09b4c4501f0135008eac1d42964538c8511e1b3c2bd773ea009bb49e1796a150ab8cbab837c60283dddc62ede2f8be00b8a2315affa17d16e8eb1602481b914280a29c70d5b9a75d117ffe4d828a34884c22310b7ebd21ddaf38869c87420860cb1c1794b23cfa5280140984a6cb579bd20fc9891d759004416607af5df216bcf10b0b2b571648450a3d3d1ea6f5f37e7b20f8cf80d0cc36805ab7b1e6df4c58f27a2b5692389def8616781a6c9773829af8c9c72292cbdece3c0039e5da417d0c0cf93c0e929414f4dc2d861d45d3ffe199af99a8eaf08689f088eb3d97e7dd22be03ea15e485e8dc3320698251b655c7a731ebf56dfa8842c0566f4d6277c3fac21c61866a40d542f770b103de50f90b520cd1d2f62c7b52ba8c289fe8cc9af28ce49c5a1254746802156a416c787c80a138858629b0f67bb199bd4e235414f60bd793eb851e3abc314f04c36f98a0a99b342f9de7ff694e34e2f836c2b4eed7c18fd1525a9985149459c64cb9ec392e47cb8671626b71f524e8079c0110e3b6b97251cfa67d3fede0ca0215d009c17fe1a4cd2eb93034a17a05787e988fa2a6298fe24a2a99f29de23a0fb87406509800e0eda141e4e6ae5bee02d92282b4df1112cdc5c6d9514ff8d9f273e59c00e79f64e77bcd855008b8336861db41180cc67ba2dc5cfd6f5908224b595ab21f7e8c4089d22d496eb9cb968d0320476bad14c9739495acf410c32a548984f87b68880de44ea80772393e1703602620f8ad2c3d910e415ba4bc6a96b79277808c4abb6dbe104c0550df6dc250967c91414a0dfb4d9f369802f008bd55a0e34d1589f049bf6dfdc177df455493ee0e5781cd61bce8f2a4c909ad4a601ea0dd44d461d44186fe290d6c41ccea3a9f0a69e149412156fe3ae565192de5b50f083bc7a2a71cc2c4adc0e6907b06db99ebc6e8cf491cf71b6e8f7ed330f886062b19d46c1904a44bd7bd972b5dc223a4a1c4a7cec0406b3d66c6b485e2d567982850568fa157e39caba5bf52e44a594a7620ec3d9e6d6b245a29ff41adef045b08169c08eb45538513b60dad5a318f90aee8235c86133a57ce41c7e46aaf7cbc7aea701716828960c9808e0002ec0ecd5c40775b3d5b10265285dcf2e7b98ebb69a3469e7ae345efd837d722b10cecd60525319827a5d09e8fcbd1e2ab57241d7a7afb8703139397213b5204fbe7ead9346accdc860d43b2ce34122e675a4d3dec934302a9b67ba9d9069d86553d3c6058755c1d4ee40008902dcddb9383f937e35ecc4e7ef6609f8d62b7bcb1683fffa9085e961ae1e33407cb302309296fdcff52a8fb88cf744d7b9cf351c4232e6511af4783dd346791fdc92cc9e93ffd43e50f5b0a4438cd58935eb23d0c26cc096cf3bd2c0490b8d3841bae7fddf5f925e081971633c93df80a3e008e6bec085f3269243740d0f4b74408b6ac43d5c3f84c1000b0588cf7adfdf8e2019af7547b11a453f0469adb34aea52570f910d8a84385b77e0baca71f9afec81504130114365a68c96b7f45d49fdacac422760e2a522c16d17669c3096745ef1d01ea6effdbd07500f8d9cea29beb1e2638cd00f4e9def2b58b0e33387528985849030abdb7a13936913ddba1897c1fc5fe477b9fdc9139fa160b32b3798ec153be3ef9488fa48e1846aa60bc9de83cf6a1fe5bbfeeaccb6e4fb39e5b0e02896df40773df5a9b726aab4467a013433bc3f73e105a6f37cd76787e18824e83b846bfa3e184b877e0aa36959cd0373fd7dad1f8ab55980421bb420027505d1ea8ca88d59effcfc7a0edf9f63b78a5677f58ff70cdcd2e2fea887e0303d1e91ebbb71d5a936ef8feb4054267de9c99b560abb5079cca25d9fb1928044e77ba3e86bc2dd6cfef896c27a87498c7098e2eb9f44442f2e40bc47b9fcff8b951300dc2364cfc1720993a39416dc579c489df437da38fc3db4c152f7251ebdd408ddc1e9771b1c77bc9f731444a5efcb672263e3608f42ee198dffd0545dd5df7ab79f8c23259b788b931540d46a59f608460b7a421ed649d6fe475bca477c27b86a079cb9f7b267095016639eafe6a2787e2d5a223dc7ed3c16fc706d7371bfb7f80d9a0312ce69b733ffe2798fe6540b05bfe1da33ac23216857cf29401dd67fb8f35d5019c7d62f0e4a7254805f37e1ffe427b340b84d399d308383034db13062d220b2cef818a271a0fb9356a8a41f5b8becde6dda6e0f66e2b4d16669887e80bf0eec068f29b854ce714f9920cf29d9697f866135869cf3149e5e1ffaf2ae320d860911ebfa8e7bd187421afa147fe8445d8bf9ea3bdcfc8a57516082febc994f29128b698a50f775baa834b6f9867b6fa2efa6c2d6f170e8a767f771c858e44c7c4f953f27f3ca34d9834dd33486f4d484143bb6bb2c17f217aa89fdb07c3f1e44ec6f2c12701b6fd336128f19177369b056cdb2c8bc55cd31cf8e8c0b72864f29a93c1a65e27e282c4f35cf3b58f012d7b36e6effa4da77990d098b287fd8134ff1026b56785a8027e9d5e2f0e01e9b5251896b433570af755ca076d255c7bcfd8835804dfc64fc78bb3ff463a5901e2d5e6c4eb21ad94cc46e46e58d643dcc627fed52fb4c8dbd76e73c392fe3bff3af5dfe4b87b957df6905eea8d33a23e819db69f1801ead5baf7ef0b65a21bd1940348d22051b52fa1587ae76c8eef67f2668d89e7ae68627cc7dcdfdb9aeca801957d09dedaf54eff7e209de019b109e651e58d2d5ec679f3403fb73ba8395ed819b3a4d10a254e1c6cf0972024b41720e2f9e33a2d6ef37de1aac1c231f2be1d5b05b09ae6d578b81f53e21705098ec8aab873d687b731f1f511e99e267857dbec215a7e7b48daf1a79787723b6ef14303224d115a47ea9e91d32bdfb6ce84ac2b20622ac93a8d1a71cfccdfc1d1ce0627630e5be0c6cff2aaefc5679887510a7b34dac7289751ff38f8f488fa0f20bda80f4891b4a87a49c4c6b93ec30d29084da27e33c6829b92887331de425c12ea11f7725a9af625b105a2e849cccd581e9e9b2fdcb39332cd0e35dbee6deecd0080191eee1e32335225667f748be8fba3e7cbefd17e4957f8c0844a94e538051f2617ecf838335acb9536761c9a312b49a19a01babc020a20259f164d63ff98f6534f20b745a3051e75569d7e3b174b63cdb186c51700cbade861fe8467b94db093538eb23a8f720084695683ddfee37a7bdb720cd2fbe388d8e1393e861b843af8d8041083a02a6d8ad4adf746013a37ce1b7790b831ec9075ffe9a7434a84f4acf812245dbce2d1f2368e5579fd42daa36f23a7dad2c949a7656586589dc8cb59e963456ee08414762cf693d5b288a73f89732b042c75c4c0374c2214e3d50f75679bccb139be538a0b3e635178127404397d7e45fe5b110abefe2406fea2b31deed3c1df100cc50751e560e844e41b63a950102e15288c4d308572d0f17e70b05b989b71714c6ebf0641406825ce38792398db27fa82ef9f3ca01d4ce8c545d3c3b989c9ae60184e45d96d8746cb73ff3f79ebdb58f665c05ac25e21ce4392dcc6ea154f1d142ad6cd35e7d36a10a46a5dbcd11609a98c7a70fbfde89fb8a5e7dc7243fcabbd39dfce6ff536b5aba47526db3bcb1dce0d2e7093c3bb8f7e93fe6a2ce083d1fd3cbd8e0f4053e03f7365f7422bc27b30f4fc09176c0a6b1384684c5ce4c8a2841000765b5491ea3fc0fb89e9dbd667232b51f5e83f14f41c282c03ad93fee00e47c115086cea2ca497fd3cf82dfac38302400245ae65a922ad6c1990c13a8e71fe49dd14c873eeb191bd703fd27c115b49b4b24683179f708dde7bfb1bcf17d86530a61dec5055909e160e72aa059b06e0f8211563059d5ecab28fcce217c5c8e0756a20ee878236a840db984de4fa9df89bc28abb007f98f4d174b276e57bcb793b70aeae4b329e910566f324c1619dac68ce3b61d97eb6adc68c077779b3e9e8432b5741d58dcf0cc605c3c6ba2b9628e086757bee2990b5a326f83f52f674cc353d3c98745972ffdd5f869beeb1cfc7c91cb73cacdd692550ad4b7da5193dd964f5fa5fb49b9496efb2a092fcefb447dfea7e525c4cb2814b0577bb7a4291322dd20f67f172ee8668d1ec1cf8d32e9666579a0db1377b17814500222963d29ec1efbbba9a00bf1e038368c712b034a6624ece17f9a1c83a94d9be9ae0f89eb071b43ff127947a01a3e4b9055406782d571c5e6616c2649f29a63f11e4d5226b65e5869a8c091cc146cfcb4b0f64661008882d642c9219ac02ec11e54c18abd43791fa3846db1cc37ee4331d98f0303e7e3f6f906939f691fedbc276b32c779e6cecf79113fd9a7fcc46c9930ff8fdfe1df883d99f2ef8604031e6cf15e7dc48e5ada5ef99355551ac1f52349c0150de315e6ad25008fcb96387b0688fbbdfbd51b35ff0cb3eeefdfe602f8ea3ae3bc08965de6e52c562c4bb7ed48727461c9e8eb64e81d5529cfbb47c2a1140c3777648df7a67889def99d5149888398a5897881c75ffa3766e93110e80d66b255025628cdcddd7bce857a2c49dcbdc66d04c6c36d929fee6254d80c37a2f2cd1fdb2c0ca874da07e5f52868c4142929232ee0df60eda5eeda01e05ad2fe24a3fa1eb3ee678beec23fa92cc93e87dcdf568bfb80b05d0589fd5f365f263fd48db53227015fe5aa0e06a839357d431f1789d80ce6b2655e78ff68f09a81de5fe9ac70470f59818b2341e220d3f70648c8b288297f841109e9e9eb7aedba514d3116e80ebf53f438f5c76da07abbc3ee0ce3316e59b0168f69cd1a91ded7ea0c75a2178bd34d554b0c85284d87839b0cc207b86927dff200de6a0649a01d7b1c02dfefab60e0c0fcdf523e6d3b46a2e7fa390fb3075829515a6bfd365d77f9cd07e8a18d39a01e95ece09d24d08fe9fd0b40e5b70de7dd653a1747e0941da47c8b6d46258981e9881316b509bb0923576dbb94012cfde8d5add97d03f6b5023b1b3278dc490163c437f265b3a76b60596459db10526cf8cce89e99881651e4c1f2725cf3f730718f38888c284d6aeaf0aa0a3fcd11aa4c82c3e63d725befac49e61e87f598926f7e2896a7d0d2616a279191bf0f43b07d158c745560ec911b6a340a45deb3d663f0a95e99939492d832145b614ab9b29f862accd7b0b90095bdf6081112566c9503543c7576492fc736515ea853b3680a08aa4a55dfc3c619455f56e7499d0bee5bbe684b52799551bcff73f59654fb157cfa6627ab7f170a0ca536debf4e8defb8ce09653ed328a11386060cf89b78fe1463f02530096a083e3666e52e300b0bb80c965be220a30b0d003ca4fbeb31344a487437b24e6f14bebffa825e981c43ecf56f8786d038006fe8474f118773582103d64053038770786157e04b701986e078b82380b0738a0fe069b1b790c0d4018421f9ac3b94d0fc0c04e212ec3fa88d48001492f3887fece64a41b8d4b502d63c96dae6d7d69032d5b44b00dbad6a735e0568b04b5e304b719e98df2ed1baf16600de03c994df1f53b7f330005f03ce96ec1e58b7f0b9002c094ec46e1e5bd4f0b80027096c466e1fe8daf01800a7482e4a6fce6cda301500b609264bfe4f6c2a3095401f0c9a4f31238914990281e5838761bb1320058ac1c343c717a854c0dda2615b54aebb14be5cd6e78aef1c7002ee208be2b957725da3e3a81589917d322b15e83204d1f861a0de8e81c71d6d93aa8a12fcca349b4fc3924fe583e7cc84bdcb2a2e5d70ab3307d90c4a5512e0be2a777c4013ef97f8fbdddf55543dc7e4fe52542c29299fdd24ef1a88a1a2fc13d2a510f80bd504056c27c0e332698c60d01db5d781a3389b66f384aa63963ff99c8b880fcb2d9ab1d3adf9754c135655e16d2a3d00a585aeed34bfe8df97238858c373bd0062eedcd933fb58ec687bac3b6de3ff0cb4014a2f54ebe36fefd5bc83d4f39a64e77e63440f99876c0d8192551837b2ff3fee678c939528a066bae64cf2dd0b8f6421a98378101af1a84c3d995d706aa7ac23b485d351a3a1ce5a1285caa60cd7569538347ee3e154fb8a35ed55955b53e0ac203210fd4af00729da8d7fd913283769784b434a365e7f58c930e4709981beb3fbd2800562904860af5ed6ae0503310ca461e2d616b248f3322aaa029cf282d154d87356f35994c827acc6855629d19b2df18a483015276525ddb033c8934aaa46da9203d40be5378c36ef3fe6b8185fcd60c77a4f23e1f7b2b42ae4e184699e052b7228834edb253f1449617c851df8da1ce3a8314eefb5644f0ac51d3016996ba8ae3744d80fa2b51917e16f4085cedae877d78fd7937737bca0bea8ec867eb10592336d8729465411676f7c404ec04e667665a41f3c4a43056d405188cc800926a3af812e46407b8c3c702447dea1ab4d91a22cf04561931ef1f73ed433724d362065def2a79f80af4733904556d103add49f7bb9ec4a3b22cfb37b80b7d7c67af9d9365d93da6f0ed0b1f41679f08cad35079eb658707473a6e8cf46bf018a9a6fbebfb0477192c2dc004af2768727a353522750d336cf2a200c7d1ca1fbe184a8340a79100243973951e40eb1c81688e42406252daccc6cc14bb6dd7234f3b79115abcc02c24dfb39bf1ff595f6d7303dadfc9bbc292249f95e9ee2c6efb1caef636f24ae7bafcb14479079d02cb6f49f06bd5c42a37ca71774985bdc79d0ebee1ee7724a4b8e2e9749253bcc268ad9cb9e73902b41015101bdfcd83abbd08ccf1ed150804614137665632fd84cd1d8569220165d5189dc2f26bfa79993c7c1e76c2eaacd3fa73485afac1cfbffbca02add77ebeedec278b3f17598b7d77d2c795e05708acf92a248d210ba3d2000309f5cc37ba6d4d2f6133c1812bdbfcc551bd8e968fe6ff1bdaedf873904073042043e41aa35adc71a8ca6c676d8b792259d7d5585daf59bbe24ed68b061a2a7850f2eb2799de48928168b11087a65da713f170dbc0e3c4a2f21c3cc8579cd5d0b446c38fcd7c7cb075177e7a085b1115ee0bfb492d74a7d23af8a48e6fa4a82bacf0e87b4ea4ae24ad9e5d9c3c72f771ce58db41183eb4d3a1304d570122f4bba9e40ea23f2d0b5acaea4bbf4559621295fb135f05759b64c0354bddf3bb11e9268807c3d3a7523687af79fcb8d457349b3703942d36030c52bca808778b23effbc74ed8d54f147f93cb43ee9bb984db66744cef813eeff9b4da780a44a33fcbb0c65ab9798c315cfd0397c4fc744287170830ea6f02b4e7dc192706c4ebc3161865818b792a7db8a7b26cf40545e18db192f97b8771c23e87b17b74145dc0346c770aa8156ed75466e23ff60ab37cf5f1845d06d39cfb95d0753234feede75e1d520c7eca775877b5d65ee525d2e2a658bcedc4186e72ad35104f86c4c06fefd2655e4eeebe4c52cfe02f0d945a79b2a7d6ef386f14de2e1f54cb6b9c5cffc36842c999e2a94b80b136bf20ca97422797f97cd14ccc0088c17c3ba3a743e780d62cce72495b65b11818464f5a82bbae444d49f993f40945869f93133eb2e3bc0496f64d570cdaac6002f98ef97bc3373d6c0a73bda6fb5c2c38e60be14eebe681fc33a91e6a58d403dd07a6c565af4e08fe9879ad48e7267f207e3d77ba886e4d4abce218621350eb7ca8fd7dd06613b11a8e4c5563631ffc908591e0d2bffb7a02135bd9b60628593bbca6f7d8dca683ae68f717fef138d030a49e74ae3e9f3aed395e9471403216a2c5e842dd3c65f8b432c90bd3a2558b6299e0e02e78b28315e083e7dcdba3da24b0bd82fa0e9feedeebb510e9a9252d03855d0424c087aa189df9cbefdb8222a14430e1b7bd674315a311cd8c636b23802a8e057fc73a48a590fa6e85d1ed7834d239824548f48e2a8b604b20857a86116e02b59fa1f4a14f8b38994a15e7cae33f47da6cab96d80b7440d56dace27adeb8460d6720ff50677d71db2bb7c68c3d8b8c8df3f50c7992744162f13fe12875622557ad2972922c78266d41146e1623bce880c6866eed3e5cd2de3769889e62a41178e15d6cb833f57bb4cd86db2f35ea8e8639212923b8964ea4e861a77292041497fd3114701b1d5d5279ee03665115c06f944081fb79792cf78a0766a20c9c9da5f49752df055de11c0017b8aca6272030d42a9861560762e1fdb307168553dd9d5de12be1024cfb3ed01916a308c7dbe04e1d32379e617caeede7342a6038f04df332a4be7a33c04975707d443b2116a0a47ab0332075ef97e7f86c22c0220de1dfb188a8172241fd3ca4c6650847ba1747bc1e16f49c8570a82880003df4e18ff2b5e373b3b61448cb3785f3dca29e953caa3a10a063dfb7fddc0c1ef63768d9a8d79fe08c151ad6c4608f91631b062a03320e7b9df8a394092a8376b711aea69ca96cbe8510efdba37ce10ab910b57ceb48be66ce0fb9c3babd75b781820f3b17f7d3e2cb476a16f2615b4b310f272552b4e037c822a2ddd218090b238f0ecac88f44a93c004559861dee143848428c88f753eab03787602024682323a98821d0c28bee2212200d628a745802ec32087f0d8bbe18fb8a22f1c55c10e50b41b5e2d1bbf832717518982a3889384863366075f84aa651ec8a9f1665e2248aaa2a08c3f54ce9228288851042d10aca5847da3b25d58c9fd0edae705abe0945665ecdc7f6fd4909e0c1d0c02ffbefcc3ae2a9a860d7a40e9ef709ba15427d891fbdc1b3d649ea24036f1fc10780fd4bcee7523bd7cf3888724140a2e26ae60b36442f489ac1bb1bfb8933999e9067ae7a46ec100a8118a304f3d1cce35904991c45c89c6e7b638af70d09052402aac2800630a116ab776a71fe0348e0b442c654eab1bf2a0c50abcbd1c6ee0deb70aef302a6250b1cb091742b54f6b163e7c7da50449a8e25b4c555c4eed37f3aeb27b15fac5562c89336787df0fb944bcc010c4bdd0f9212f2839f4add9581cc0b44439f75f4f940971059e8d76d8847d4fe3f7af5866fa969688338974bcd05f72a177f0fff842e9f1f9a5f51f8bcebeef7acc0d1b0fa19fae55ebee47ad2b82317b986c6ef60427da34adab76f4c648e133bc6018632c0a935ff3efef560b218b1418801a56572799373526bdac0db390f2bf2ef05cbf8d4ac615738068c454175e35484165262be875f22394d1a06a30859c2b085d322d1e1a48f665daadbbdebaf31d00a2592220498f266bb69922a9cf808d2358075b13941e72ec47849009d7ec2f4f76a43b3eabfabc493e0bc363fb55d0046180ad2b1c016bac9c5500300e976ef85ef6582b91687000c4f1cfc0d079b9e41f90c2531b095d0d4a2fd0441cd8f2a15c1cae3b06af06de0c24e5208d1f47f92dfa2c6c38a56cf2d410cb165261ee9116472aea22fa1da81bd7707797bab808b11eeee9b1bc8d301f23cb866f6aff9188df173d1184010e836f1e2dcd61ec361ae5479a229f881263c0dd5750ca406970fef458005f2610995bc7a555bb1a4a7bd36d542482704de1549a3c19f6d9d709ad6756b3c54f00d73cfeb59d12154568e0a02ad2b429822da121bc943d63001c2011a493f9e314a6a37418b3965c9f936151f025b2084d7f4089213a39c69e750010f79962e47287b1bf0ea8579e267be1978a5a1526a80e932c343fa57d9909c0e1075a07b6aa5b43ac6051f09440a09418cc78438a71f643bf612698f467d9390c6845c810b427c298f8960d2aac670628448bab3e536ccac7fcd1fc77d77d99cda895c89236a43533e0add0a30ae3f1bce5d20e835021f28b449882594f3cc34b744413c634af8edb0c3aa6344ec3f1fd578f9a0345a0c613175608a53e76cd92b023dfe367151eb3359f8db52b6028373e2e7f2d24e3670581fe18941f9a9b3c3bf5c5315426ecd76843912ce60bfc66d555975380d303736a4a1e22eb2c026ad662307f572daf22fafaf2af7593a2ff7fe323b903f0581bc5b1170ebcba80edaac78f749257fd37414acc4b395ebe91d71300735cb60c6f17828310cdf1aff1436f8c5c3ebf55b038795428f3baa7c26952248a4bdb022b4daa49a9459e5e86b8a44414445117c7fe6872a580906a7c1fe5c82c017869dd3ca3a1200053a56fc0c791b6d992641d7465175a257c41a804c1a7addcf56ecaa23e63c06cdc7da34601a4904aa569ebef1ac986c01c628c29e083d1e15266c0723c718858b59dc004581f707921fdbce6b62ae93779fc92ad0cdb13ebc865d1a282de6fa9fa3649059dd8afe94941f9459879865450cc2d6d8605b1f64172390c4cab4c8be30fb2bdb3c594aa72b64f44a4ea9e0d200909f19f29017bef8576177099631c6ce9a897698668da891311a56edda17bc2aa31118948818479e0b813ea897e94e5cd1550257dd43500b6768ceb0b6e5131f8e0ccc7714a5493dbcbf52d4fbabe7d956ef0565ca004302366cb4d9fd2a0152b5d274063e4b41f35d0b1f52908b0f998e7bd5063652dae94d8adbc8a828d594cf29286846b3c84f96dbaba041111bf7289570ee44bdda073d1005ca3518f191897f9fee20fbbb01b1f1957cec7e45ea88e4eaf7e5f8f3d085a5ffddd9553a1e66706806970d765821bfec8404884ca8d653213985857ae6db1165ca5af7e08b9b45446c55024e2504980a3960b46439330f0f0f0f0f0f0f8fb9c18db4da0839843ba494a492d20b9757983948322529534a1a1cbc0b9c99f87466e2532ed98490024f7b03350aa50ac40ad9ab9c483131e8513a218e3f229b635d92b6d98338283d7e21a8f21bdd97200eebe1bfa119ee557e208e254772fcc507885334179559823e9f10f3878388963fe794d40fc7521a634aa5d26e27d3875356957f977075b5171f4e9192fc91f769a723dac379bfbacb2d26a410347a38754eeefc4caa176acd432a6acd8692be9a71aac00a3c9c4a79670a17a969a9bdc3c955e4b2d8d99918a51d0ed9c4a909da1ffeb9d5e17037b9529a34d9368fe8700ef3ade670c8f739af9e592bee278783be790f2b13114d83713889958509aef55de986c371fcc2eee48ad80b92379cdb2da4282564dc708ecda062c9935b5e316d38ea95abe450ed0c41ca86f3a410a3d255b88683a95974978b8b913f359c94981442a5b668b2cd349c54e4bdd36bdf6a6aa2e12043f9777bdbadefe60c27911aae1a2bf3fb99e1bc9743e6a8207b920896e124e7b4259cb490e11853bed56a4bc9a4b9319c84eeccb92b49ded72586b3bb5ec6bd8d5af748180ebf952a67460d18ceb99b64767f65ffa45f38e7ca84b4415e9814f2c2295cb5675ca95419365d38f8d8586589215c386bae0d7af388ce32e116ce56f666e1bec46e2eb570f4ff5e89b2f9254b9c8543fa51fe6949a82ed562e1e42742b8d9d28c6d972bf8a64705bbcb162b1c4e6dc986b96ffdd7aa700c1bcabc929697cb27154e356e396a928ce9ca5338a6723f79a14ea99049291c2fa3ad567acb0976140e3faabd5652d6904b41e1a8b7298c9a91a3529a9e70dcf3bb0bb1afb5109d701a0be291544cef8fc9062b9a7096d3c91f63c11b8187c78de0cc095630e190f2c8b90b426533092ee1b0c9453385104cb4e6886085128ee964a69bbf1062de27e1682124a5d2a499681b42c2613ffb3353ecf6cd9b878787c706c18a231c8466dab9df18132a6f842a5a468ba94423c6984e6e9031538e6d45110e9a673a423ccba52d7c058d2b8c09ac20c249e99d4d2ae569082765318e1819d498a98570ded077a1af23f3cc0dc24155f64cd1e7cdae36403885d8ba2453a975d7e507e796ddf4a2f5f48624f1c1f14ddc9ee6c56fcbce8a1e1c64c8094b56a7153c38a51697e4f3bebe139c400e1b5d7c50206161c50e8ec143c5641145b268d0879ae7b861c3ec0a1a5cdcf8c8d105013caea0518746041a4083ecc00a1d1c4bd605f792dd3fa2e7e090824cc1be5766e477032b707052a577bbbc52bec9fc0607cd60d26a4fab4a876c705061c2ccc418a184791e1e391c070daca8c1215d251934c6e294f669700afd223361c43d537c068755778ba23d163d74191c63522934bae83209ea181c37059129c8f063b1846070121f8995214df388e80527992f67ba2da67c652b5c70f8b92c56427b8c6cd68a169cd4850c163f5a3355d60a161c53da5ed9d98b79af59c529ee96504af2641fad51c5594304cfcb65e5712aa938095121a2b4e4b6e9082a4e6d23bce7829c9e8f9ce2b831cfac6efbc6b688298e23be31ef3b74e81d4b713853b162629f353a92e274996533259d97d2044771d2194f8c1a8b28ce272ab3379b12bbdc85e2a432ea99c888236410280ed69749cb426668d7f6c5274ed9fc4ace8b483d7a52000066f0c213074d1171d9ddeb62f69d38bf8787e96eb71b71e298f1eee796549f05a14d9c64d2b97419964cca9a385bb2ec3542b226b971264e73592f4ec5942c961613a7d15421789caea81a7389535c925c7b4a2491f76263e385258eade35a62523789f82b71cc30e23e218c5a969a12a7cd5f763f2be2cdec491c65738a6bec3b0bbf91c46152ab1789833899393f4156dd6e90388804f3cc33d1bb4d8f38957bc53c7121d611e488c35bb856a7681a7152aa37926ebc943d2b234e9273258b38053753096ea3220e498ade92a019534cb10f55f42211272dfba69424910dcd23e27071b92fc4c3a464fd1027dd5c3ac286c590581be234c9748611f5d65d6a218e222c7e86286f21ff58f2011ba8e1811784284383c5687c1087ad8d41258dfda16e2488931abb13e1ca7ef63481405b3fb7340a8892fab2b8eced9ec13f1c8296093a23eee528bd1f4e22bd4de644c89aa6fb704cfb5232e9fb171d693e9c7c43db2797aed334ede110828d5066b9a487b3068bbd274ad2a82ee5e1e4a1f4525536657d233c9cecac5ee2c4f7f912dde164bf59275b52d20dd90e87cbb0cd9cbbf6ddb70e279db9da44c4e0a2944b87c3f7bca6383917a2b273385e4c0c0d332278858d1c4e2327fd256b5ccaa689c3a934347eb34d827a060ea70a69324709f50da793b5512152aeb3931bce97725888b5b61967d286a328592a79d49a299b0dc70b2e5a92cb571aed1a0eda1d215b9bc65f0fd57050496a084b17b3daa7e15c39232951d156a3828663f68ae4a216c449f10c87530b7d7973bdf733339ce48bcec863aa176538486bafdb8efd1669bd20c331c94ca27b444a2bb55e8ce17c49fb9ddba4ef31f90b319cd2466a9f5cf5ea537a118663fefb5593b2934a6e301c44503267fa85be70506975c36e58b19578e17c95c2ff8590fc54662fba70fa53419450d3542d3217ce25dbc52c49015878b185d3f25952e15b2e8fcc0b2d345293fee8c9be6f16ce263aa2c5f9ca9246c606169cc3b9a801bcc0c231ee6eafed570a95ea2b9cfab4429cf9cb065e58e114724e1e9d193ad2fb2a1c2f74e40acd909d32bea0c249529defb6675a753585d5c3ef5ddbadfd9229782185f3a7e62553c923883d7de8aa085e44e1d45f25ce2f95a82c496aa090a5c8db55a2eea70f350f0f8fbb34c18b271c62b810e53d925888940f35c3e28513cc438b174d78c184d3e7e90b6e79491281174b6835bbc68c76b2da0f351c81d9c10b259caf666e4438cf1489297dc0066af48b241c9359a4f3fa11e2e27da8162903593978818483c873f57317ffaa3547386ed07133a35545e6d40807d7d124624a5992d9174538c8191945f2ba6ed9f881a38b2d16025980174430dbfc4cce199115cdc08b211c2b6794478c2f79d35f08e114ed25c6cd2382dc49092f8270986c753b375282c60984939cdccdb7d14a499cfce0b841fea25c6834edfae0a43a17ded48558cdac2640e30a1a25011a1168008d2cb6d0028bb423bce801e9bacfc3ea468c8607e79271cc2baaf59df63b38ea9fd493b3b40ebc9055d7dc1b37c43a0787add120f6976cdd2a2f7050f6a9057deba66fbfc17fdab35a72249b86d8a0b5d92443286b80cfcaab8414d288343849cd21a2b371e264d65b7831839255086ac1256597904dc2a6765bff2cd50d172f6470b68b703124fb43cd0239388b037878d8f01c39388bb71ebc88c1c164b5a4f467a7a57a189c35f3a411f55f709230daa535bc8d285d70921794b4b468a33cf416944346b8ab90ee172c38c9ce30da4250e15aed551c37fbeeeec9ce06ab5571faac2046c9a0541cdf7406cda22afa8da838886bb9e42ebb365a3ac5e15d53e6d51dad0e99e2902a09dd763fb251dc529c848ee5d324a29a4829290ed174587967863cf9284e2227ba2f5a9d50b128ced533263a512fd40bc5417c4dd7c918f3b496a0380621d455ec5711ed3f71fa5b91c9dbdd220979e290b54c3385e425d676e2ecf73f12c477be564e1cfdb25eb76d449864d9c441ef05f55ead1d29249a38ce5c9dcc275962aca00202553ed70a31bc7078939bb4fbc610bbd50a3420af0b67c925432c430c2e9cb772535fa41219626ce120d192894950d59d91164e15dc2cf76d5adb89593865fedff497272eeb59186260e118f2f89cb0b96c155de12031bca8c8e972b9490c2b1ce368bc68cf9844acbc54e110a295c997ad69da9d0aa7540da2ccd2e4e1918a1853306333852063f4d3d60d31a470faac3271137e315a5214ec92149616ae028583bcf69131eadcd58e4f38647db34c5a7253989d701272c2e61e71312e660388d184634e8f60dfa79490b833e170222241a8a492a9ad9770bc2e57f90c623127259c45a5be9bccdb925450124e695d838c27b28212128e13d7b29545ae98f27c84c3e5ad4d6b117763488d703a2f13b9524e446c4b110ef99256b2c8a56bc9c58156a311318870ae4c21e548cb6d2627433848ecad89ad9bd32c28047ca2ade8115126e8264610ce1af28f7c8d63b16bc500c26182ecb6b0f3922ae51178428c1f9ca29aa69a5109b2e3330117396c1c1b1e1e3689183e3865cab058dbd53315d48353dcb75c4a1d6263ea342ad0001a7689183c38a9568b6c658ab9b4a37185477922c60e4e4904694aa811a2356210a0518106d0c8c1858f20d5200888183ae0408c1c1c378526912d34e938a10f352e1c50830f317070de146408596349b4de88d121c60d8e1b92e234fa8ca7846c11420c1b9c7e6bf466b6d339110e1a57d0701a571c9e21460d0e41f52dc587c6c3a3c4a0c141746b065349f568dc3fd4eaaa106306c7cccbdbf5b5f8a7ce0f35199c2ca45ed9ba8c49cca7518106a41c62c4a03e9125b326194a693fd44270e3c68767d158dcc121060c0e2a89147e8326af1aff43ad4021c60b0e16449239e2e995d9cb28c470c129c64ca5b4aec894a0d1a8000268d880c0151f39b0c0008e2cb220008d2b68d0b882c6153448991362b46093113ffaa1ca33e6432d05118305c7921bb2994ad11bec5c050c551cbe943a7bcfa029d76549038c541cbe439785cf204676c55ce428c1a171058d2b685c41837c01062a4eaea92917d3aea8493fd4b604304e713e21a4c86f69cc91bf0fb51a37da900086294e22ca599d9e36d99cb528c5f9445496ad6fb48e000629cea14ea876d17a7b41f3a1d637ba0e063046710ea5e75f49c59695f0434d14c7384984dbcd7432fafba156e346ef0b6084e2146208a5aa1eee82e2f475a265cc522b9a3e719279e7652a0565316b1f6a356e7459010c4f1cf2a5241245d8c8d378b377270e92c284cdf7937a91c06d180a607002ed906d916eb2058bce4d9c6465b118837a5751424d1cb2a5a8fe9bb942d87026cebf31b95e449fd0a05921c0c0c4494524995ff45b2e19728963e5c909fd7bba3784250a302c7116afd814e32694cc5a25ce172cc8db599a12c753d3a7bb359c303d277116b5092975de9238df490c6e9354fba43212c79d8b607a4da5ba5881c45963d4d1a0953de228132c9550624e83851c71925db133cdd6aba2df8853506bab13d9b8a416469c52de64225d2df3847a11c709f1c552ac44501354c4692d5dd68d9b441c34ddc69e0d428c980b1107dd3ab923be5929bb431c2566d1ed5112521c19439c52cc6f4a3993baa072210ebb21b5694a9d1007d7ad8b69b5a9cbe3411cae927f88bc0fedba08e2bc61640c69d9e486d207e220228644d56c7e7e62409c7c270495cb952916f487e3b9a8c4aa1cb17f247e385d2aadfbc82d4977d487839ef47da93b92f4e9f9705263f24c65982475dfc35953a5abeec6d5665e0f47ad9454b0dca0f4822a0fa76c9a3216dfa62f233c9ce4afc44a97a4e9c8de1d0eb93688956ed00e87139a478848ae0e67fb3055fffa23f6723a9c33c9f07b9bdde4d73d87431c19b11362dab88672386a5eb7f8ddaba63f1287f326b50aab66a2d5331c4e66be3eda822ea1edbee11894521b64f24826f4c40da7fed16a317f772473db704ab3412ca558c66a9a0d27f5b776c9f5447fe5d7704c095a2574baadc55f0d2779f717a1da7dd4d6349cb722bd5f54131a4ed22695b629952efd7e8643be53fa228246901335c361f4697fcbcdceecad0ca78a8fb388da2bbe2e194e2a8d0a9d7f730ca7984494ecddb1fcccc5708c2fbbf3bb2a21371f8683106992b79bdc0f5302c3292c4dd80cd912a5845f380691e4a5058ba2aa4c2f94258598ae78b12e1cc4655c4ba5d46c63cb85d39df81cad3c212a94b6703a155e3a37dc52854b0b2759422604f79b7466cac2d16533e7920affdf0d0be7be94828878e12b9c6e94e6fa9667d8a0b4c249c64375f4dc6e785885932a5d21d6cd427e990ae78a2671f38853225a3b85634e497925b7794426523878588cc956c2289c84a594f28e2a299b235038988e936293b24917ed138ea284ad9948fd2deb3be164facf4d6fcaf52257130eaa42aece4c75ebea6b80c18443be31374bbdcc2d2a208b2cb84613602ce1a0f643a8bdab982bc570e428d701184a3848b452a34e897713930fb51a695b011849d8548544bddcf11181818493c80c2b99554de4be780e2ccc7228c04001c6114e17f2a132965f1a55083807021eb0056b61837071638100c308c7b4d2bfccb6a3bfef221c37867c7a2497c786d4871a114ed9f43596ac756fc987709c4d498c4e3365318e12b003685c41c30439b6d0e2d880008d2b68b40d2c1860022ebc0b09d0b882068d2b6898c01940e30a1a5cf8070e4e008d2b68448046051a40a3dd982d588b1aed66056108e124f3dd7ada13d623e6436fa071d1050e1be728002308471fa17df357d62a13ca61030b2d80b0a8d397e2baf395fa50cb02a91160fc80189490ab3b11b2c14517683100c30788fbf5bfb94bffdbc0028300a307aea4dc97fabf4ff2a1966dc3021e1e1e1e1e1e753502a005183c38c6aba4f39a266ca9860d4e67f99b02183b388828b2563bb40f35e3393847170e48c5b1991780a18383b4da790d4286184d9483639b52cb63be79b32b0e8eba9be3cc4c081d937da8ddc8d1372ae0e161020f8187070edfc204393c3cceee0a306e90251165a28c3ed444e0223859301639b6d0229d00860dce7d2a8594bc2aa88fb306e73bb3ed0b9aba929006c7f2b4182fab50c0c3e360cce038d1677255646570ae601577657eea74188353d0b9f18c6b19c53d2cabb105183038ff6f96fb9e51d95e9aa1a1e10460bce0a026eb6b744996ad9e0b8e29644eddfc48aee1324380d182639291273f4b4676353b80c182534ccd363a4366a5ce56712edf24d24b5289749d2a4e716e729b72113f334ac5b92a8deef63aa1e2f82272d3b9a57eb1ea1467d3116634462e281137c5b1726c7edd3e7fd74a298e97de5ceccf7bbf844871d216ebd7d31454c5cc28ce95c45b0e69736fe114c571549a942bef756413e3c08a509c35dd5a12593dd3efa038969ad658143ba1e77fe294f94a364dac9e0a31ea8973c42871a2c4e8a326de898314212b694c162bc870e2a427e8cbf77b112cab4d9c2b0495a692922922a568e218cded2b6bfac9cd9c0eacc8c4b9462f49b578af5f6114acc0c46125e4891acebec449fa87ae2babd74a5ae210d6ce724fce8b67a512c7a8b371c2885ab714a2c4c9b5bf925215d3caaa9338a5cfa8153b45b43c93c4714f5bf68c99334ba2481c74a412a9bf71fd2b061287345617ba6ba6f1ce479c77cc4d6d8818731b71c4e14ca94d322df98ed888b38ad4522a24ad1ba5c488b39a95c96a487331d38be0eb2e92ca2d71459c47cffda98e897db14ec47982797ec8da65ea0d224e21bc73536eacda870e71cccb243ed2a49defc81067bd7bf1ecd299de22853801c77e6304356eb4e6e8a0c1f9c46a3699ccb50d2e37838e191c2d63f0adbc12199ce2dd5272abb821d8828e1874c0e02496afb247060dbd6bdc68a31d2f386612419b750619b4751f5a2304376e24e00a13e4c022ddc8c22fd05e022c0ee0e1913c3c02d1e182e3cfe4925135f5f3f22d38a9b8efea0876ba74df2374b0e0984ec5ccf625d7b1891164ace2dc1ad485e01a1e5a4faa387b5be60d39ce541c7ce45b3291afed2242c5b952daf7b7543ac5615406dfaaa092040b534186290eb71aa2257ef7053995e254353296667df1524b8ab36969847c32b6aecb28c818c5d954181535488cb72477d1353e60038b1a5a98433244714a7a5ea176b6d374554346284e677ac9e4a67b53952f200314c7f4d0ad91426e43893fd48820e313e7be1cca47cc6ebec83fd4d608323c71bc78f731facbf2ed5a838bf52c105f146474e294ee43b8bdcd6fbefda1665e208313c7749a4195cd8c74517da8615102b7eb818c4d1c53b3e56cf74ffdf40fb52eb69a38e89021456e98ea5f060d3232711221882fadd3a72f495606199838bed65dfea8241ace4a400dc3b19738addb5f25b517d4fa6f8993b4917d613aa9c4e1c4af969e2695c26e28714a4b31b267ffca246d12a7d8dee17b52541af52571b8a0ea764d9d9092eb0f352b168993f86ce55d9f5bcd1a6357a029248ebf7611829f9f9a1a3fd40604cebaa861e3066a81c58240c6238e9264fa52613e37449005643882cb183685b7a6ab8ae5c0820b122066414623ce637fb94e5e289fb9d85040106430e2b077a54e8b861f1490b108829fae4b6ab642eb2990a18873a9ce10c4b62eca854a404622ce173e366649e1421e2bc940c44162843421ebe5431f20e310c97cfa2d4ea86419c338b6b3b8f1e1e1c105198670754b59ab86d2a00fad61e3460d72659dc58d0fd20219853886ad5b743391f6f030341c01c0810c429c34e6935369ec62edfd50732e520d1f4116378cc9808c419c3a82498b41b47a872f88f3a8dcdca457f7297a20ce3931644d230704715643e44de31755fec3394ebc05495954b3df7e38ce555da6b0d9a5b6ee436ac94523be264de1c3b9929cd29a1ad5addfc341e4abf6d726e9e12023688916c265f012cac329046551d46efa892bc2c3c92fd56e4c34f995b45aaeee011ba86143c61d4ec9ff5ca4f787f010dbe1a42af2f652febc63ae03a27662980ee77159f71277d26fb47338dc5ab8d30d16945a8c1cce7e7a7fe4e6ffca93381c33c855670c95428e0987531621e9464b286d62bee1242b4f4b68cb0d7bdb954592d9683d6ac3b184ae98c992418a890d8784119b6ca7e1b2b686933abddf7e23930c5d5143a9d236f9cf8b29b1a7e15c9a2f849dc9399515349ced4eb6b47686989f9c011563938ecd5b2e5b166498e12cf1637bbeb52e6cca700c5ba76ebe2e2e3624c329f3b3e272b559e46d0ce7711d9592883153c36238f9f96bc95f28230ca793e936a788ef6e65e80719603869dc248b655ad4438f4790f185cb3f4312a93d342ad0001a13f8820c2f9cbb33d4c9a0a3cb54be0ba794a35ed6448c98fa8207195c38e95e67c6551daf12f1111c1d646ce110c456aa20be1b33a9b5704ed70f9d3257215fc8166464e1a42e36e7ef77e9bd848553b6f55fce171141c557380657bf1459b258f864ad70cc3d2acfdce99ad173154e69eb7326b96797a5a870901737265c8ab5137f0a2725da52d88aba93232985c398ac5815e72162d271e0c8e13870700d2bc3119c146444e1783a495f694debb56b780838c7d9dd066440e1ec5aba1684a892bc291e1e358c5815643ce130bf679244041939c870c261d35a9c9834f8576b120e329a704859229de789cb6d2a138ea31594866f0ac252e2cf38ca1b642ce11c296b2e4dd2113d35251c93cc1c7622c28ed23671838c241c54da983629d45fdb1c5d581b6420e1e417f544e52fd720e308079395924ca9b4945ceb467781c3d420c30867d13c91c9a74f9fdd45385f0ebf7dbf8e30f93b31c820c249cbfafae912d1ff5ac6108c99526b8986e588493dfc332ba9acb1329e9a3cac86d51d4286104e4ac725b1a5a2e4cf1f84d3c692891bc264103903e11873254198ec909bfdc131f32fe8d83a2d31b520c8f0c1d162b6eb6acc1034dc3d385995ba94da4ce4328807a75a096f22890d4ad4a50632767010c9367374e545fa4807c71633611584727058b7f711b6ed2531060747ada0ac5347a8fc95b9c141886f48a67b1b9c425b941313437089650d8eb9619279a4c87bcaa3c141c59598973de933325517c898c15184a92573ad94b735150b326470cc18e79772e9628d5cb4901183a3dbbaccbf7f2895a49b0619303865ce2ecbf80cb992bce01c166f6252316b2e8c2507325c70b29399db358f6931992204192d38e56f3c91c4eb94ccbd0c169cca377926bd8b24165fc5416c4c96125e545215144315a7a449c8ddc656fd5c11083152719226f2c4ca5e2a5c28a1e224e3a40bf196b861534e71b8df4ff539919b410c539cee3b4b877c45da3c4b714e0b42d6f47ba4385949f84c7ba6364c6c14874d3911173e52103117c5b1f327dfe9490ac541d2c6566f3e957e61509cffedc5d289fda811121a154080470c627ce268f27ba76adb189e38daf6c4f06659fef5fb50f3116081c3863f0e2cb4381e1e9d38954c9193f4698a30ea723138717a91d1d7bd792e72d43e6003350410631387987e9b3f9b25313471cc912f79e9a44819ea1a38b80c07018c0a6264e2741f4a6cb02fd5710d260e6232a29c774a0a6be14a82189738f52825676319b44d6389637c8dfbd9192685a8312a7190b7a07e27e6dcb6104a9c2ac90ae9eed26612a998315e64c9a7c43d882189efd3fa4404c919c788c4d93644278c5ebd18cc2b6814c0009038a47989598487fe04998be3e1c15cb879c0066ae088f188a3a9797f68d33e21d245163c02471c45975b74f189a2f36fc439540c753f1366c4e1f572f5bb62b987ba88836bf672b5b81527c6ec328622ce7a1b72a44ce965f29d88536a46df2043d0a4e4867364e15d2a06220e62e674891297d41887386becd019093242ca160e431cbff2bf52a63f6214e2dc174c46ab20b3f21a5964c17a5a60d1808f1c5b78e7033650a304310871b097a43585496d0dba419cf57c7297fc28b16a0c4170b9a3ad4f95e60921807721023740f20bd8791722f0ae917c048b458c409c326c2f5dbb4dbc11c700c44145f437fd222a7f3896e86f4949693425b31f6a354cc0450e33c385e7c082c4f0c331aec4c93d4ac8ab891f6a871e1e5be0388dd187b3475e0952fe34a8fa3d3c70041b88c1878bb18743e4931e5f9177fc506b4fbc05054ce00cf0f0702cb8c8510829450c3d2033a4c7c84d2ae7e181e60c31f270104a34b96f6e21708318783805652aca47630ca5121a1540008d0378786c0d62dce1e4bb2105a1394c6c4cb2c3e1c3e45a25799144a5880262d4e1585bca828f6d87c5131d8e75975c84c82f7223690e67f5ee1d37b90d21c3723846f8b82ce1f2af984a1c8e314b2c287512381c74c6d7b58b1afe35f286c37ca9dea68c1222826e380621420c11b97a7abf369c6f6fbdabae63c361f28a94b07916bfaee1fcbd9564be492543881ace95532e8fc40cd1a4e19836685b522bcba7191a0e96937af5e34dc498339c6d7b93d21c739a2e15c30cc752ca34dc8bafab9b1e1e68885186c36e524de92c85e0124386f37d98b8d209b94ba60824628ce12492146d9b3154440c311c6465568ef01b35448c301c63d46bd1689be22a7660385a3415444fabab436b2c6ad8b8a115a051010428c006043c3c7084e0c68d8f326688f185838610d4a56e7501b5569ed21bc929ccd0c4d9c34c828c2d23228f52989189e3eac7a8b85c62e264a6a67ab12f9738e9d58c2d4a5896380561b531ec990c0b160ecca8c4f972569258dee9d630056650e220d3e85d53d17daf2c1f6a37dae424ce3dd24a7dfae843adb3043324714cfda37b82a8e491b4322e6644e27841e2b967cc24ab437498018973cbc8fc9d5263312e8198f1886348c272e2480b7d93016286234e9731c36cfe17b92626e00f331a71529a79fe44c81673b30dc20c461c57b409979159b4bb6a16714e49f2ec76734e98a188c3a5af8c32a5c933b34b989188930a72c4c2aa6a8b0a2912988188931e6171794a6696d4b8d128821987209ec784549e15745cb80d1b5890198638ab6c291d23137808ccca8d1985488270d31ce0e1510387023c3c6a6891640621cee52ab927c9e543ed8a41609ac4efcf6993b120418d1c386c60810ea071058d2b08e6da6086208e2367239f5a8f9ebf2510c7b4315fa9d0a5ca54788930031087d9f8a644fc912925530e33fe7090315b96a9c55f531638ccf0c371fc9448234af64ba9601b66f4c1acc936842d39da15c40c3e985255b2d82bbb88a17145051a40e3fa30630fc70c5a12437f5c4891173d1ce6d5b34333c8241b191666e4e1bcdd9a5ed3aca99494a50b33f07010eef55649858cf28d6961c61d0e233459f42e19b24fcf8519763865907d55a7bcb4859785197538a6153f13417d239be866d0e1904b6c097949f9b6d6733865b718328968a292af27cc90c3a93c738ebaa02d7224e37034a91643745352ab1b1cceabe97a44bc94739a7ec3496ce824d3183d548edd70dac8e21d52f38d24db701ab5aeaa98da154365c3d9a468d1bf33f717afe1587a268dd6145f365ad4700c42e27fcf799c96240d079184fa7bbfbaf88968384bf60ddffa1b5cf47e86f3a88c898bba2323c9cdc0467099e8a3846e3f14130533ca70f491985fd2d964385dd2d589fbff67771ac3e9fc44a6b5f50d1a248673e9d22961548ed40a87e174419cb2bfb86542366038cb98309135ecfb9fca1750fff5b8a8e1ed32c90b59cce8c2c922ada596aafad7c78573669bf8db1ffb60c6160e5a3a29597e49b314d6c23973257e9886fd89ad0733b270aa98d113f5f2c4a0e2583867a8ba6dccba4eafaf700c32544a2968520b32b2c221a858bbf7ce9c8eb50ae792295c863d112a9cf4734f6dd0612bb19bc2612eedb4bb6bb26c9914ccc93b5731a90ab2066644e1e0a6f447660e85830a57b394aff35d2d3526cc78c231bb4cfe11557a7ead134e215d76bbadd1904cde84939cbfd54b96a4cc05dd116630e1702922289d7913bfed251ccc52e42d4e9512562be1a4446f8820344e062b25e1d41383902e6b6291649070503dcda79a1fe1b411c255c6f3730da911cebe21af2659ca229c6b638cf8bd1a41053b81308308e7f0f3de202fccdefa8884194338e5a78ad66ca1ba3b2284933629219e1e7129ec201c74a9caaeb62f3a4d0784e325d12e9942cc254f3f389979889127847697cd07e739f771f71b2fdf708d3acce8c1c12e8a47acda98225f1f6a354cc0458eb222cce001ea825dc8a03e447e07bf883211f1564679af83447ecfd23493e7a0185b4bd73a15390ed45293f7a9194585fd06a79857335e4c8f8dea36305d6cefbf6bd00631a749639a06e99066a737313d8365f727db7a8e9215c9e0ec99aec394757e5d3c23066fdefb0c1be19d0183cfc4443ff302744ad03f23345dcaba20c9692d7a92e9d27f0bccea255f2224cd7e75060b4e15424a4c19493606ada2b3b45ca72a5272738f5525158a9a7e785b6889a0e28c2b27292bf3c753d41125db99da5886a029acf1b29b491983ac14c5d291aa645218e40811345512b129360a55fcd6947b4b5891283e1925c88630a9f256a1389b48166bde725098d65a9336d94dc7278ea545be0879c22709abc313074fdd74961ac927a47474e2f831e2be1a3f274ed17de289d27d1133b989b34fcc3aa6628c2bf151608b2eda0de0e1b14517ed4d850e4d1cfbdb22692ed3ccb2900f1d993054e65a7f89da59234c9c2ee576969ac8996c5403c7143a2e71eeda793515e4fd57ba850e4b9c2d99d8ac7021e5d553250a324c5a64b72c25ce1125e87e4956c7244ebbb1dc4de5db48a52489533c5535294feab564e988c4318d46caa29b49e5f8903898591e951dcaccb4e41127e870c4212897986f8377d7d188f3fe956d8a0a2a77921f6a5e3c94091d8c38cea77d65ed896dbc1f6a5aa40cb40da700176ec38602b0d8e24605bc0b116061c3021f39b0c0804717377cd0b18883165f758b293e8458af091d8a385fb21035b2af9fb8e8879a73b1c599e7e0b4057424e258a2a404154625ada6547672e840c43192cf6c29adf962fe214e194b6c53cabe8cb9218a5aedd9b1415488839ea49f722e9e925c429cb262b5646b9557640751bfc6a508e69b9909e2d41753dac40371ba14ca545ec9d39b540071ec161156cfdc84c6f10f65e7b9f8e58e902274f8a1c9b299fe2d4fb618632fe8e883379ec1cf27e9cef5a1a67c38a8cf6caafe541d7b38a593f1cf981fc971ebc15ce52262e29dd14a44b5ee36f2cda5b2284a5bb05dd916ac059aa0230fa753f9d56f3983470e918b41071e0ebb1326c6b9f2ad9d3bee30a3c30ee7f39a183774e78991eb70da95f079234b29f7e970bad90d75ad3ce14d3b8753724b49ce6b33bb3372385f4cf184fe8da523d2381c52e695205f5c638a0987e3c6d1f6b79a72c52281f91626a8001718301874bce1586325316a490b22f86e386e886afad2c935fbcb2ad0d186f35e08ef5aa35aff9b1b3908063ad8709abf6fd54963dbc0624390380705b8e040c71a4e22df23679d98c97224de428bb2d3a186f3e5faba542342996e53471a0e9a42d8864b352f3aa2e11c2195a9d4a35ef25ec7190efa1d3253321565edd261869410556d39a24d980d071d653846cb2842c784711dcb87da26194e4aa53aaded974356f3a16670748c013bc4a0999d8b6c98246247184eb9425253ebf443ed48173ac070d4d0b8c16e83a61e13878787191739b60042c7170e319769cd6bd32de37b41511d325772ef5d38cbd98a9dd986a0aae1c2496629193323e48d4c6ee1609eb129eb24c67b8b160e29afe769365321296147168e495b5706b1f08a289b00a0a1030b4713fdbe4d6d5a8245ae70ccafa2d4f2e84d2d12b3c2c13fe2e7c57fbfa30ae70c21249c8a74073aa8602539a916e15a2bffa14602e6a2462a50e898c2293644a6b94b9a725e87140eb1d2657e08c919a2e60c1d5138ec646bd33e26289c368c451b5ff9b9187ec2d1379e90ff91142a74e5c8d0e18463764bb134871a55f1ed68c2594b26253383b48309c7adcd1bb4fcba6685add0b18483d6e58c61929658f99570d09834c4ceca85ac65128eedbd79b36576001d483824ff49134fd45e9746b8d07184d3ab7fbf97c54888920e239c82a6ec1646a6944929c27947b26d66f4ae744a1d44388e05b114dc33f3a598211c5536fc84d4b1b65208679f5ce71383ac6a694be808c2e96ab2c86b5865fc7395d0018463d9d9c49c4985daae3f387b7ae52ddda199b468b3d0e183f3e9f2cb9b44925ab9efc1c1f6dd2a08092acace3c384db0db0bd3271b418a858e1d9c4b4429255a521d1c634e2f61da76624a5b0e4e316f48193142855897a942070e8ea2be9a3313238748e28e1b1c74acfbfb4f885db633d061837328cdd79e312ec3321f6a356eb4e9a2a30627938d1acdb25f1b8b63a8544fc61249241007c3a0303010088408b7b300c3130000000c16144663d1583498b4f10314800247302a4a362a162c26181018108748825028100886c46030180c0a85c260503818280bc4643e00a730e88ec5966ec1afa896d5a887b9c72740d1234fd2caa8fa225bbfadef4b548e6c7cd48212557d326ae4abeca7c09422d5b5663267c674976c540d0fafafa66966178dc43f8c543cbaf535d21a9c2ecadcb854cc22e2d385ecaa4b77ae6e2c7073b8a50c6eda106ba112ab7f797d27e215fec72c675cc6c8746233bea856859636e28c0fead0bc525ce16b75e80da9ad7cea3af4259556883a76688147115a15899df28e1b660cd4a1ed31befcb017a3312e292d45a60c1a425134e628c787d1ee804d1d94697e1b26da0334c1d3cd8ca9979da6b8e110a924cdafc98c5b4aaa4cf9ecef1f78b4f62c1322819d9c01ece2ff64df9c9fba7675d823d59639dd6ce0f1fe0a06ab5b580331b1ff30a5056189b3d1963f79bb6afcce4196b68e4767bbea1710146fbf8380451ac4120c215021e6055734b8af47616245e2ed8d79caea10568f91353772df7a87baa52ae2dc12f35a9f71f654abcb61fb6baf7af27efed7fa139f338969c02df1cb74b914397bee597a814d40b3aff85bfd8703a009e42249d3d5485dfa8c6211e28964c314bf4d4bade875e63b7b5634fe05116c475fee41f40bf387eddacd373322fbca9802ebb126a0fddfa50d2eb7798e684e5ae1215a80bae80ae5a0d20a02d5bcf141963c457b0607e9ecc955e8f90fbc23daef128752581352da48f9dcba5696b30e9795097907360619841c04f39f39fed9b689408a015d61720bae6d7226799158a5c489fe19321d71837f6f315b937e43922fc6cdddad757a479621c7b7281975361209ff19f70f4ad4e8a701ee093876b3f0e3f0c9d8ca615bd9892c40112a95c9e42601a3e41d998c93496f4695ac3538302306ddbaac138bc9bd8a753fe2e9ccf19a29607734dce097b8188b0c938ce04a72a72f1a2943b9997491754621bd3aa2a77840de2253eb406a5d095feac7b468bcc35fdfb0adccb9b5c800b7e2165697c854681dc30614c81f446bbe4c3c3f65a71ac329d327acab7157ca82daa90778d281473b1b1e57c9748aa31c3c32907138807ac62737989df1caa9fc8aaaac514c368f1954863270832c5a336e25def61125491920e13464e68628d1c308e5fac1a6f7195c76608660cb8131047b039f9b924b2fe7282a06e89b41231fe47d8736e65991330ddc419931cf3c1c29949cb82a1bdc95bdc01b6b676440f4039b08aa0cea186c967060b61320e489be43a3fd992c3510353136868e0689d6a4feb1a81d8274990e726b02600a01aaa5dcddf598f650e2619d3e96320a3e497e0f473d4ece7a0c50d06089e29e2f3d7adf236c13884930901341d016bebfc7b93bb016c462a310fd2ce47696877531ac08b109c20161e20ed1f3725997bf446b0d01f205791e0ac46b5995919ddca3f4aba1371e464e68c8af87a5c1cc479c4ae81ae14b09d0f421da604ca222f7f17a14cc3f7e7429b1bdb4137dc87881fa54d1304b09b52b8fb4d90060d47cb1f320f22238fd9fbc45b7d204c7e18fec883feabc285562f7df8640386ef828f7dd64ab8424474cf61ec9d78873ff38c5d4b545696467d438ed92f6843482f6b1ae42760c4464007380d316ef427a4cfc4f97d2cb1a6a2b1a2211593b34bb738291e676711ccd683b2641097edc179ecbaddfee26fcc74460168737126a2f928d7e6621130590bb8784bb21fc76d381f6e4fd48e7741d43d88d089c6ee53ad26e8fcea9d6741c65fc1ca37d47f125474c572e3dfab2d3eff6ce1364ff1b9b8fe6fd0aae1d8b2264644385963185d06cf09dc41439e90338f8c26d82c9f1ce567bedc284cbcbc0852d423dcfb05610223279f95bb0d2a3467758b5cd60c47fea8df6a57a66b0e7d6fe713274c51cb4078ec3fc5619978035ff6a620f715578e0a19075a5c088bd403beae995487eb9ef973e8cbbbe18fb2738428d495b0c7442a1665f33aab979e279db94585c3733126c5e78f83633dfb11b66b92c7aa8cc17f5239bc2c00ef505f820316af04a70da1ced56a5f5848a0a45c38d1fb1244f9e618542a169987e1ba04d4e0de48b186dc94a60140cf79b5eef855210edfdf3e12edc7d6d69836657e048696798b30a114a255d7cf9ea632c7ea25622c2d7125c9cb9858f00a4daebdf46df54497f53d9fa8c0ec68da9968b39a6e149c5b4293ebaf369e3c6d6ef126087d80f4fa1894de096bc4f42c13cf09d5a7dd9804d2736f580406df4620d08df1303f1c3fb0fe42b61a88793f7f3ea7622e7137ee8da44ab51c66d2c43b68e3d5dc4c11da6c0a0829d53fec84775264faa5d80bec010a8c9140a5c240f0e2ed09733f8b0b416f5d31248ba4c60480db18f82819acbcc90042289057f3d9c1a2005bb2f52605eca2d4503c93600c3e9a342a161d7312fd5707f4c6c6920310078b4ded0bb3f7b4bca4d0d71ae2e6410d22d4471ac993d57dcd731cddbc3ab685204450db09c5be3ee177bf4112383cce4b71a655fee6d765b4bb2d45fd535025f75813ce995c541fd8769acfce166f71e5d265d15d9e6a671fb7933c4039efa17a672be400398124d074cf57c2e7667ab531048d53e489f42fc3e858276a8ca0a7a8d236bf7cf52979696b0da16f13b4db1af1ac52add43b94f67aa4d48f213118a0f82a8b5845d41de9c74b26f9f35459f01690011443697ffb06201faec296f13e0e7a1c1e9cc42af1dca3ba1d77966aa7adc1357bd0744f8758218da1f05b383627c2a96911dbce404de924e9d5582230b5cfa5730d09fe3fa909f81e55cfdb014eab28e191877e088a94cab86e4cbbf822e7c1ce7e89b5d3086a6045e55aa81af34870348471fc3319f5bd8263af97973742f271bed046e7c4a6ac28316e24008f3cce18de8618f0bd96cefc17eb06349a8051a669a9bc590b175b5687c54a184ef70a17ea0eb8ad1c3dc51ac265159ea8cb511eca4f24d9d8b07a4471d411696aec71172a0b1f4a19e0059a6e23204242e8dd0294a3c5e7e173de190706b06f4b65ee18e67ea2b3705b5eb6ab24d1491f1176e256d08e9b5fe3dcea954ac0e1bef81ec2d39fe8a98a2ae688501b4a082669c7d9b2cfe1515db80ac5e6988748808758a6f4487124bd79c627e6979e3c1280f6c0fa757c419c9d15caa53d9e9c2f5edb578e8b65b27ee9c7e737e0ebe1b230e168a734034e3d83c6cdaea11bf727250df14e1a86115d33add6c0aa4b673a30f50c961bf429d30d3b2054af4a5f218f0523598a6f0a8c195638b6e18e918587b1f609b1e4746049e1ae50ab5aa5647a2a56498881803e75cc9ddc2501eb62c438e72c54c0ecf8d49b4748f7145cf0f1891b20aa43f722b6fe95b0ba8c6286b098456bdc4f829d1ec51b62398a0476a3633eca3e4a4c88652574a76b96bfb52030c3b30b012a8c4dec1f161248a91acd1e46dff56504f3c1e2a659552e3f6dc93456f3a14bb9d7fd777f59ad0bb297dc4f55930ae06ddc860c9bc89631ca51bd58ce46b6988e80f829de6acd579ebc51c8d08a0bba6fc600e5d552ab0d8ab63ee543089253f3a6a4365d9d0a367ee941324c9a38f44601827122f63d4acb8ebc0b77db3745cf17498a649011045bbbfc9f7e84f1bb8c453d172a8fc7bdc02183720e040618b16317fd083b6b5638da861132b175679d0e520d1442fdbc9f6421b7f28cfdb1419a9db476af5a699fa7a7afe74528ae1d69e2ee2c080b55e22612f102877006fc7b707ef802f0b20bebfb0cd299395ac59b68d8ad976f1b2834e44149717e44293e228b5a6691c264a5d14d65a0257e13827442200a8cfe56cfe06c525c150cdbe22b6fa8f6ced2fa3f9dd39c31797f5f4d1e5e553e04fc904f2d342723bb61125fa94e39b763622e4a117478698a9574266c0b5c65616ae20124833f1cacae87fe1c681da69e6fe25d0a0a578cd199d1d28a5f28615788ca81b5b4dc67044516d50f437d31f76a02873a9b1af8202dc3b7ba5dc7bf056ae193993b2ad9eaff6a34d7f87aeabac3fab9f4818a3da4381cd49ba900d8d438fe2bf4dddf82dc6d0bf08d1306dd6e0dbed558c740f1a89853f7eb1e9d125649228773ec4e610ac1b0a93c2d4413b724f881a9d3b20a62cc62ba151bf9758c132f9e2d5f6408b67a0508dcc67063aec2278c54d3b54f588b61529318b18ee76054c9b0d59f91d7b91b8f250d5ec6be38080b3161630e64154a018e01c7144f31aaceefb0754e4e35945916410d6678020b9104dfa1f107ff3abb010e580061643a49f163e37f3cfed2911e1762f1a4178af7b2d7519495098c82a88144537527228f51a7324a89f300b3da8eb5de2379456eb954ffb3a985e52c928139ae881d0fb50f76028655a7e15a763cf3687cf8277776be9b8b1dde1e62f0375fc5b97283862800ca6fc26a198a36d67e8f22994406c0b4ce76c301a144e111726c22c0b9874c406e2ea06e2f28d7d7a4d47049a029c3f612878369c3a5543a08ab80ceb764292e67a20cb9cbe66a794207c6f4413eca0063e52e02d11d60effff33d982aee1b8fcfa4fadcc8100c0f1ff7acc28a058cdde5637f225321c22a280b31ecd56b707fcdb8c856c23d91949b552b69c08c2cf40580d0c282bedd160a712ed6e9d7e001f32fb4ea9f111b5cd9cf1c910ce0a43f2cdff97f366e5cca6a2b993b9f4c450b9c7aad52f233a65cdf9858bea5936559171e3215cdef65dcf6cc507f26e9c889830e63014090f7cb855c34b83ff40ded3f8ce406970461f836b0c34d2b86a2b7bd08278951c5fe286b6065599cb4113e603eb3b8d81d36102978bf7ad3d56ddb1a4074d6a7b06a52a79a1a2a01d832f43d31f4b3c1369a9e0317e5e9f823c3c63d5245a4df7aed349b2eaf84075a8c34f129268e91703fe1ae6a7a81182964d40c80332ea38405f62043852b80e0a6095325dda73b9beb6bb77531ec0ea29ad4831dd85ac1726f54b6b860d57c6c4c576bb29ed45bb5899796c25cf0d45cfdb36938db5b96233039e4ca68109b7f7dfaa8dc1e574d9362530b09f50e521e49a97fdd22058c85689f32bad2f0d109f8e451f336778c1cdd04451e6a3a46e86018eacd14d64fdc63435303451e2fe09899cf260f6212f323560f7928682e34a20ed3d9c79da63c53c06c62df75ced4ed07a53aa8541ff10f28ba6a5426efdbfa0286dcb015056c3358cbe63f2d3d24d7b60a7b43868da8e6d8a12f2aeb5f2d4645e8a9d3e28c8d524494e4c8e6350f9456551e3b2b7b1698ff803080188cd9fc7f1ca3872a6c3021018516f44bad69221b439d8046a1e01525488c1947a0468bbdf0b875448ee2e178a07f1fe33ccb99dd84580421d9dbba945ba7690277ea40a1ae9cecd0200bb645a3c780ea28153cab943952420082fa1b50267656c4fe58a42ccfbf8edab2060ce00561e875f8021500a9725858671f3d5ecfdc5d42f56bae576150416eb895e9db8213c8a020939591c4c7492f0edba3163c9380ea09b8b35af5130317cc062ff10e1eca02949f9deb84fcc36a5d320ab4043763664969adc9a47261ea2b804d284039e23446dc62986c53eb9691b146679ec8f5c06585442f1d31521cf1fd47d01040409d085536ec0b71b4fc452edbaeb49939e1180d24cd5153118a0b6d53fcc1a579f64a2a6ac406ce2f7903a7bedac73f09e7e24e3b8eb030dcbcb82ba7560eecc78bd4523f7f833dd1913388734bb940df92257cbd0f6addf90ad5ac55db6bac91d2dab36003c6f7364541b5e512d2865e11b5182e3b586db803424d0c03b635446ab353c81c2a3e65a8c2ec0650ce2bb8303851af56291ab5930bc26a20b8cf08d0708ab451593712ecb7162a88e979213aab3b86d3b8210bde23525473c56474f401fb1dd4caf7c27b6273ef0fb78f647afecefc04b209d5384578b450246950cc24b6018d2e31d096f31b1514d821e297268cd426ff79f80a9fef08d650589a485bc71086080b4bce49a010328e722867a087302ad323ca3db3a1a0e00ba6b7c6f3360dc7bea9e8be5eef922dd07331cd3c157e190dafd0100c9092fd112bf995f4793f54b374a70755902291c0faa9ba4ecf403cf5d2080798c729cae3eb2ee764c0a87f34555a4d8db16918107f33f71ea65bb43348b3ca8d801d82abcc7186b350ca60292c7702681d3e4fb23b01a550c634b2c05668999ed60f9f14903a5d6ef5c831894d16efda64413c209d9b9b77ad61c561ec448abfb51ad3160acdc8e9d8a7c2a6e8f9144643c5aca424a4edd7dbc6a15142064769392d55b349eb3294129e0d56c8dd152343894490965ffafb77b07fc4c581a393275ac10ecee79720fa01524cd47466a85612634c85ab210dc36c44f5dccb12d8c861b280bff0bf1ed8cf9a314d3b8d41124d8068211ef1c86b640304e4e0b6df6dd7fe485383eba4c9da2e6d608501b10bc804fffe644268649201cf5de15ebf09a17753c8f30cc05ba09706f2e5b49db1c3b4d3031c510a03a00da3ad386e9095cb47ccfb7c3744d6dca2a3803da82136ae2f482288f2d03cea8050b3bc53ab707487c6db100299e57242249c905db1714311779091860252aaeae4c7e51bc3773203fa17e41692d2181546c87ca1446b00976f594c055fd123931a83ec83c25addb150b90ef972d5905ab752480fbeae8a0dd56a5f7997dd1b388baa9baaa01d0cf0cfd51981f420be47b3651f51a91a26fbb4220f05173ea9c5ea9fe96fe4610e78792eca4f6beb2b8aeca35e4dc8c6772e70f4fba592b4bea37eaf9c26e811e49d770f7380d41f895ad9884f501da702d6dd7df87a602e43a9ac69e29e71bac307566d7e0816c02c92223bae44c6e15926152868b990638c1c9d3a84d8d5c68dfdb6c03c763329dd56309d5ba19ab2280b1db20d804ab6630c7eeb0c5f83c5da0a7d3222dcd513d4d9b6bbe2bc2da0b1554cb56aafa007b511187b5d542dd2ac5d3969032450dc80a90d2a122b5e5820d899356deb47c4968fb1d63a2d05937a179e9cfd564296418133006429bda66de8b16daabb36975c27178cdad3e0be6200b362577eca57c75cc3602001196d37a1b44e4ef675820631ea34d2f67e2b430ebe43164cb23a448cd22f106cdc17395f0360d389057e51d1417cf95163c69718d321383d067ae928ab38e128c147f755f74b8c6f7734616c3923f579f4bf4abad18b9e481b54982e3c6966036984dd05eaea0af680a84a432997c7856e6eef33f6d3668a507470dc2a6c3705d9d0672478437026a0cd3df545925d06f4b1e304650916bfddeefc9c26e6701153cd436ba9e71d929527f266dae99f28955d021967ba1c02a9eba24421e6099f56bacbeff2d57bad2fb09ee44351fc007e50cfb051480369e58d4aa557d389a94034dcbf26b4e2d6e09b418134081a98c65d0d71ccdd380666434c534c36dc05a3e3202ca854c4f577303a2bd821befa6025c73132e686b27d6dd4ff8b2b84c1289cafac6038d8a4243605800f931c74e36cd4a758d77a62a1554f150bee86cedd0c683ad5743e4b1f4a35016d42212442e4a5d605eba2b36d47b4301a1af63034f2ac908524ab95e58bda271dbf44b6b77f5a77742fa881c4354e3d191a12078bcf8ec53bb95e96474465370962ff096ac185e466563013ca828fa851e80bb3439138c6616d86ac06aa1b862cc9453210d644d84c5175f1667b24783e43ca1ccb52d815765c4168a0ef260a4a734f2ed262134a82312bb8333b29c5f984e43c3a53fd36b6aedfd0142a473251612cd61208fa736056d6531ba68e02c47f47203e856c3e9b1681ca0b750d3529482850880efae57f3417962f14d967a46eb6c44f473ebe65229993d0cbb630440b0de57dda2f8a36dac9757a0c787b48ec83c9107d2638123d55341ac99bc88088cdf107065cc5b5403090b93b1cfc9726854b3af465396685bf90a2c82b0934b3ea7aa90304a5ec298ebb208618741c9b16c0cb81756a3ad887f495d9b2b0e5f93381534d8b10ad4eb539e6c2be7804b1f05121ccff83a0400c075bf12e4598848b264fa5f55feaa9547555c18180034a4673a3dbc48a3d66e12354a82028bd7ed8fe757642e8843407575af4abb648089ce54354658a6d902f7a2defda500a6db7ca78d8064a9d75fdcf9ea7ccdf1d718c2add9d6fc15a43bd214c7c30d9b49a869845314ae11c45b9347901c15b01e3627155f81942c35121db63992d85a11a37bd3cbb38beab14b3aa6e8855a50697a20c02e3f41db631b0b1c4c25ee8ebc1afab28fb3ed9b8f154f188db699c7709964d39dc068c102385a79447e05814f0ddbd30c7ccd056dae81177affc2766af3056279dffff857063ff598687fbe347341597d2e1812f355d841b032c5ef821e8e0f67653170b30d2c4d38d08cc3ca92af89c6de6455963039d8507649e1e2aee860b18cb60d0e2921f1d4b910b9d0055725c53913c9c385880b87eb854b9bcb965dc67ae5ba5406ae879eb9e8b9ce70f9cab91eb56466d9252e1c2e19976f2e6b2eebb82cb992b9b8effaad488bf8e2a2e40ae1423b2e230aa46ec154bbd403a6efb12d5cf05cc2b9e4b82c73e972b5e0c2e07ae4f2e792e612c0e5a82ee9d27788504f2e1c2e28ae3f2ed387eb8ec95f2fc2649016c9713972fde792e3f240572523a00b00399733972f970497082e4fd2550920e0f5f7b8705c16dea5e915cf85bfb9a4bf94f3073f172a172fd73c97a1b88c6045b086c1286b9cdf7be68caccb0425978131101f2266277dd01508fccf3e05499d908d12f87841665f50703bada50d67b43a39cecd315640b6b73f9805e82de284371386a341f91e7ff26640f2ed021d030d682021c962eb91b94156be5a37bcb1b383c66263ef46d0edbaad1c2fe470145b0d0f8e819f59b903947ee48f8cccc8a43859c4539cc03730887a1449553b56822374c1b12b7a3b40d2f33c1530a55d254b2cad441073861befe292908f315d2d43ea124ba207afd25a0ea2dc2ab5740c3ef87847ba5b73ea5ec3b30721fd44404491771cb2be761651ab9d6987fa9e5e04d1b90e956daa090e9f7bc480eef6666b0f233f82e01a389f68b46290e98b9a42b7c1700d0138f4b652cd3bd30bc4f7de7618d37c1d59ff118daac6a033a1740e5a0e3c1206e0c7cec82930240082fc4a2de47275440f5afb408fbe87081c9127e973dcd7e16a172295c6ae352e996b864fd886984dd64fe0d2117bb6e7964dc50ac0ac78b99cba4570867ab465c60399b1203bc0340c57232b875cb68088c2a95c3b4a12de4a697da420a2d07cd71e4aa8c1f44229e736fd8a504c4950b9a49e2e886149a56ecb05681ad600024de1ce5df2634099087139016c8d0d052f90e3dabfb38ca8b7254055bcb897b7425276e0f4f6d98c18869742c09814c80b12ef28fb8025052991cc559e2ef1ccc563bbbd46be70e43eb1c7450eb20b538c8d67c6859ac33d7001d366b486fc4c1a0835bfc582031883275b319e382680d59c45d95a0eff6f291f005c21b0670ef68efb900ddac83b8ccb621706d0b4a0858d2c88a5c830b916c6cc60ed4971b1cd6e7b527dd536c56f60b90b9188195da2f08e6ccbf40a94fdfd1183f3a173444b8047e16fd87624d28d8e1197289339b4b9cb5785212459e2bffc3300327add49d0c5ed0d1645434939bfa964569706c5a7974a09c7ae509959e46b5ac233812bf039474e9cb8744e92b5ef94dcaf969c8fcd6e6cafd35e35bc5c79e5bc18bdfe7bc9f925004ce2e5845fd7e5c5e5158357d44bac97bc9707793d897925f43abed748efbcd24ca48dd6e9943a5e82d8481fe3e70fe05e2cbccce3b578f142ac97f95688e09e3e5212371aa649569b1045c0eca081c56995bffba25eca2c232540c7e117735e94a6b612c97fa917fc7d5d47314cd13f501584bc205ea2bd64bc1c045f4f1e01c6255ecebcfeccd713271c34bebd0cbcdef79aa8c60b8faf0560defbab4064cdf0faf352e0b5e3e5968be49f9e3009b5f782e30b10ec597b6dc29ab0c83f5eb3bc64bc7abca8bd5ef3752eb7d3b7ae796df1f2e315f302fcd71c98622f3d2f5b7a1dcbd476948b8c140881f013be7cd9af9d3bb925b1552b05394910f003c2d0f86362d536ba0e1f8cd8890d99b4ecfc41b308dd10381343c8b56a7c9223b1bb5ffabdb75d5247f6a483deff5b6763b3dec6768f53a138b14b1567f24b21088066b4a4edb3085e961f1f8d506bbe9bd625e6bc19ef3805b936141b1a187664ec85ad707834ac470738a6fd89922573d47c8192181b5d4043b9a1f6885b46509727d96af90040e39ccd3e6e65a97a7c705a420db037840b9b6228eb3d2da0fd119fb53d24eace33980304a096ac1e686a32001a4038e956d57db014f7a7f0106f31e0bbafa6e56c742b19784afe2893e853546854066a0a6a815a7a6a70363b81a3735113500ba8425433ea181502b5ac504fa7c5f9e0527330ed56652ce08aa6f390e0d5685465e24a2ff88986e2b2f217cb43bbee07c2a6b65436ce72300c81e3e5422a3baffd825560d714d39261624cc6c0b0fb3c4377f702fd5b2923e206c42ca49c4b747108e05641904e25ac2945655966c9cacba119f02f73068397800e86a76fb21a84740754354b51f64c0095a233d38cc15690104f841d60bf8f49ef42308a5881a2f589fb3bf46a39f56f070329f75df017497de2fb1c07b77b2098c4f5e106afa7c029777c4a9c2e4e8e6c424b6a0573209eb826f4e9e22432524c1625119002644172c852c6d7235e47585e5975298b792133c4af8b7a22f514355b484b6a1cb69092ceabf9f2a84ecf65fd56157933ab420ae6c5dfcc7ce13c106abbc458463733552c500b2e712f46ed4d0e2a9689752c16c5c3cc1966304b954e194e3c35f84c540262ce51fccc5b715e12459225587835002791f61cf41830584f9e11749aea30692ca0ee9d89a3f0304f13254d8d2044708cf437c30a25ca74f9ea326899eca490b3e85c395a853bf4dc9217fcb040b9abae4059f564197ec8953fd3b686a47f91d4a525cf6151a778009a1d61bfad5b2dde1bc63b98ec985ae8ed301df86e32186a5af76b8b275c598fc11e7217401de70aec52ab75c406e4f6aecca57e8b9312de0a1525684ac194779512e0ef7aecce58a0d0b239f621f5e569dfb2d15768c8ecd5c81c08c07646cb139543fc1a83fdf4cca761fd1530d721f85bf02fca1e402e875e115865dd4e1951dbd04bbc9b18e4365980f6f32bb2424e8a54eba67c92b33c58e890e5eb7c38b1724539510f8ea2d8bac2060b119e3d11705aa676e3decc349894d879ee063187f15a645e7ebcb1f59df81064a7dd8b38b49a2395980e2705c42009dc043c6f687d36f150403b88a4cebdb8e441dbdaba35125e1e7ee8a30e9a9aba6e25ea1a276c91f251161ea57275fcbbf0d42652660315d351c3de75e50ad94e96d20246ac5169efe23010c0164194e335d5483573f50f6de80f6d7deb319948fc2199600e64d26a82500878a4df231dde03e08486e07bbd038c35372ad515e2554b6f6b52c5bf8729f40d9cfe272828c933d6670fa11b426f40797d4e32b46498c81023f8c013ca93e3ed7660039c4802be0c044e0a3350b46439fcffffffffffffbfae888dd2d6fe273f25992259b775a1627f45ca94644a29a94400c05d0e0081ec5b318802f814100f0a0e0aae0a76a556902966fb85085e44e2947e2a66d40b43e2e8bfe33531628b9cd3234e627c73a6dd74a66e3ae26ca14cc512f359e9268d388692e8776b9f5731ad042f18713c9536f8bcf5df854e0b5e2ce2b021565b746886d7a888838cba8e5fcad3715322ce973f439c0c134254138fe005220e4127e82d111599f93fc42953a935157fa7336988e36b92dd214796d2140b717a139d21726cf7699910a711b61a43b014b3f30ee22443aa20377c2fde62823886cb35294dc58c1366208e12ddb27e5ce499140488c36fbd5e795ad608fd0f879319aa37974d55a8fc70742f99f5b2b42c046d1f4ed982cc5763a32ef7cc8743bc7c63ddbf21f9af3d1ce446df1256994f24f570ccb4bb933d2fbd42501e0e497808a1716f4effc5c321864b327e49ed0ee7cd9873db2c4e7d68ec70faf9b7481564d0b0217538266dfac632bc9ffe8b0ea72c49a3bfe58b0fa19cc3c1644cefb39013c36772386b5ccfd024631c0e2657d777531209aa8343a34188dc94247ac3b9db23869292c74c04dd70f076957137db702a19a28ccc6c1ba363369c9448156288aeb0215bd670de53c9a5dc52c3d95a82a95eeab8b8661a4e2947d0e25722a6418886430a16bb69a5339c4793fe3131574947c90ca7ad56ddd20a96e1e439a62d8efd649d1119ce561ed1ca2ea6183d8de1e8a531dd2f444d7a2a865388d6729a4c84aa9c85e174a217f2efb9c43f2d18ce766ebf1b5ef28553aae9f69a93753a392f1c53540d21daf8c529a12e9ca2c613bee7ad7129e4c271c6e2e49fbbf813235b38c98a8594c1fdd2bbd2c2494e503a52af37d6aee045164e52b44caf9a9226b5c4c22996c508b1f17285f3eeb56c571aad70b08ab521f9d22a1ccbc4efe3b2cf4d6954386da56965651615c94de1184c33734d5ca4708831f428313ab4e764a3700c59e437a80ba63757503804ffbd91f1cbf468ed0987bc21a7b23eee4e299d700a9e3a41e4494966e44d38a4cb1893c45d4c38876ed43c22555aad7a09c792496393f46bd0a053c229c9b909596771c2c3241c752cc614bd5af36546c2612bf864d50f55b631473889f2b12c322546389567567e4cbad36d16e1942de75ccced6a578a08e7b8ace47e7a2147920de11c9abee12b8a92616f219c763c53ea1172a97106e1202bef57ae59bf5f040867b15842a54dba1f1c2e5ff8dfccd70b1f1cbfdbd2c878de96b4e4450f0e6ada965ce4760425f58207a7a0d498d8122146b7e42e4eeef11a4b5be2786cba3809dfd64cc2bb92fd2817078b4d4de953838be38d484b71b1cba3935b1cf6e2a5f89a5c175cb5c579c38c6eb06832fe46b53856eca6fcbbdc7c12a4c549951ea5fda2cee2b0dd79195d228bc356066d51d6257f84b138a6cda6af1b79be6f81c54982be148d0dba96b9579c4b3b64a452715ee2b9e2ec173488b4d2b5e2a4e6f392ceb5e89a25ac38fc9c7924d9579654b88ae366b6126db5a71a2c559c5f475b93feb84b1e5371b40a8da24a6e47e9858afac4e76f0a629ee2e8912c4485989a426aa638ca6f0453391682856c290e9f73da648efd86644971589713afad94612166146709ee3a7f5a6e6b15c5b16af205296127d6b5a1385b990a0933325eb220509cb4cac894aadfaceaf28973af9645d1a526e6507be22022666745ad9d3857c5cbfbf2917ad48813c7fa385dd1a4fff8679b3825a5fff2a8179bdfbc260e122749ad1b4d31eecbc441c6c823f354ebd88c9838ea85a59e107b57e14b9cec32b88baa58e220bb56f62bbd9538845161a204a1a7c4c9aa3d2ca8a89d14dd499c4bdd84ce7ec9182a441207cb3b15a634b505a58cc4f924989eb7bbb9f82d248e26e55fc4d25b449a1e71d4d070a99991be62de11c791796d93de3b9d7b1b7196e8a7ed457f888d39469ca4c58f347a72114bbb8853d2f98d9272d475c81471d0323b97fb6b949061228eea994fbf658b4ecc22c2fce52e16c27e8893d066af195e31c8c081011be02881cd30c4e1476cb35cf3d7e6c571a49580066804763440383c30a310275d2ad5442bffd56c2960811b399006cac10089811c984188e34a9036e76f7b39fe411cac436b925132c6a45210a7701b93a5df25d177d5a851460e6f011809042ab0a183198138d6a65c3dca4acd466c0b085460a38c198038458a13769438a5197f3869c65a8f1ce274ede487f35f8ce2bb5e26b7a2197d387ccca96595aeb24b6360045f2449c10c3e9c434f68cf53fd639112ccd843ced0432987fe692dd92d4f5f30230fc78866a1d2448a25a9cec0c3d19246b38a314e929461c61d4e326a0c911713244afac69a0d1b8863986187635c95f0215e7d59de1b6be60b33ea7012e3295b314a37d60e0b33e890f04cd1e26acc6dd85d61c61c4e3531eb8698d298f08d09c40c391cdc7299ef0995b6518fc3b12aebc4693bf91a171033e0707e3bb5bd5a316638fd0d8794279b6253506b1f72c369d34519d96cb17469fb30a30d677f93f5cb1065437e21d779eaae4a87196b3878ed86b029f55424590da7ec8c98f423cee83467a4e1bc2ea33662a4a072eb0dc010038c32601082341b33d070d2d7245f447be80bf9c69ab12acc38c331a26d78b69bba79f1c65a49c40c339c63457b881965388d5726cbf6b7ae49a810042ab0018048cc20c3c92c8eb0535a36053dde5833c34023668ce12caaceddadcd5bb4070215d870c10c319c52344dc8e96af1d5440431230c26839a0186a364afbb4c4154e58bde582b8098f18553c8e677f9f55332dd7398e185d38924a48ebeca1e9b2ec48c2e1cbe6736439af0a722621d6670e138c182d8d395e78486cc61c6160e96541aab8c6d31e60a196668e18cc97ef1445cec3520ccc8c25962d67015a2f8ebc8b170b6bcbba474097511e45738690d63b12c66252d59e178f7f35f429caa70feb7aa28b2c6a4c7890ae78b5fbb75ad8b2192a67050351d5e9a6f299c924bd4d1ab1d7f7d47e1b429294e7eb6265e0d8563b20a364255f809e7ccfd2ab962f448414e3864f90a9769b77ab1261ce56d67d345ba0f1562c229a4a80873e12beb59967090a723e8b6c8a0214609e7b091116d279dc86a9370cccbae2cd38d5a42c2215f8affcdd525351de13849855c13aa447b468c701226b5df74e66f0415e1a81962e86af95179229c62994a51472b55cc18c2617c5474535273e4d30be1a822a6a6346f989d3a08a7bcaebe0a690384d38b5033bdfbb5b1c3193f38bcfa86ccf3a1219aae0c41ccf0c1a964c69f507d1ae2ea193d38cbec8e88bc3451545781193c38f56bd074f912272b661707cd8a22eeee457d9ae80602e8e25417526e6fa4f82335b938a5bb5b0fad7aaf5a7171184d31a5d770dde294265c4841e4d3a52242005b9c7744caaafe8d879b20402d0ee6a2562df9a4ddc8dd582bfba20419c0f18505d206caf01c391c035f94c0035f608200b438c4d86a4af99d582fb199c5d1c582a6b5bac8b7c4cc8611401687bc3e31aea864d2ec3503016271ac78d9625fcc68f92b0b8b945e0ed31942c446659071821a35f24080571cd44e95525eef7df164c3b24000571c748efa5d57be1587ecbe415c43549c8ab1e220f4d4bee654994ba6aee214834ad90f8e4a6b39df580b03cdc0f38b1264000c31c818c30661902102770c94cb81810e429c945c8ac9829efa0a695144c7208e1725869548a2b764528f101d823868d9c4e823bf27693f1007554a2821455d5a581d10c70822fbe245d3cc7dfac329d96aec9123449430f9e170b9651a66f3746eba0f27f1bd20eb1bc4c408f3e1b899b115834692ad943d9c77b3955479531bdda287e3094b95278593f2e3e6e194663b548c9b7bd3160fc7b861d3e6bec3e9b6776424115350793b9c2f2326952b569daeeb7032d9b3b72e3178c6940e874b49d3b536659b9bcce1d457262392d46b74723849d2286125491611cb381c44cc274d56f0b99139389cf5d27d428edc35237bc3414ead23e8be08ab54871bce25821cd50aa1b6326fc339de67bc9412f599d26c38fd480a2957c6924baf0c3ad6700a175388bc1957c3792e44e887cc4ab142471a4e16db3d32263ef4040dc7c91a64736c898df867386c5013544efe6c5655e830c329dac53439bd235e082ac3e17deb441c5591e190da366d47caafe9e2633804d796a04385d50db2180e635e7aac720553e187e168b2a5bbdf36c6dd03c349c418c94e9d97ca6cbf705caf3f8bf2e7272ceb85430cb1f4a4ad97ad3475e1982989303a53a75c507570e1a054ca5972537df7c78e2d1c7b465bccb324ef63ad143ab47058f310f1fc66e44948164ef927fe675587bfbc840e2c9c53ecd4c4a084da18c42b1c44b2c88bb917fb8225091d5638dd559fb0c96116123aaa7012496c88974be785b40afea1830a46be960b3e3aaeb1299431daa2a4cc9b4b02880e291c2bafbe68c9df6c3c8d0c1d51b834b889bebca66272870e281c735f2519234d474392163a9e708c266b37ebc950964c1d4e3849750d41bd54930891097434e1205a5e2cbd8ad017f21fe860c231efe5925929ddb1848364eb1379e7d6197428e168596af5326c87979d657424e1b0ab6596d745a935c61d8e0e241c465c842a9b8cd17184c309616b1a23a27a06959183a8a1c30867b1932deaaeeeafb91b6b3020a38c1c8903d3d05184c36911aa82b094f632b9b176356a9c89d135a80e22740cc16aa81046d01184638c2459d624c94607103a7e6035c2e8f0c141b7e986209b22ce9f6eac8d11821a356c8c4146470f486a559ad3babc4bb3a887aafe282526a5ed63f80c9c28a1830747f38ed3ea93d1cfb41b6b665f94200339cc50805d9ce444dadc9cea4f9a757176cdea2fa2d4ae6bc3ae00b938dcca86dae0b6bfa1beb156468e31c020860347994201707138194448a3466b275db738d756ee523da74a4ec48627c32f14c016679191f74977da806db80d18e4a840193538356a945103a742016a71b28b9ac72559c620a3580168717a11d3186375d94848016671c899428ada76f78aa02c8e5db994e8facc5ba22b412c4801607118253662e2690b7e015e718812348bacd2bbe224af62d97d917a644c2b4e699398601b53ae7f5900569c6e921e29d9b28a8352d925fcaf37898baa38493f717b2774889a988a7388f81b434a8fbce2a1e29feb9ad57c3ac539f35808e5be273f33539caeca7b84c8d0bc6395e26849ac47ac70aa624aa4386d92232e6fcca338defd77e9f5cbeb9b92810288e22cf22f7d0919a3c8fca1389de41221a5a5d91d1f14a754fba597274c90eb3f71f04941c47c499e38be691d9129a8347977e290cf235bff560cb539714a792627a43a2b21b48953fbe46e512f618390260e2a76c2a5ccc8bc2813c7beb81121f87cf90513a70bb14687deab3c964ba436514d9fd612a7ec3dba3a2aa588d22b71ba4b8b9d114176974e892ee8c9aa96399fc46983891177f710d75c12271d79ab742d54a53e12470f59418948d5186c481c446e9b3e313fe2a8e9d2fb6caa20ab4c8e38bdfd9c1aa517aaac64ad6fb25231e6197132556f6242058b225ac4794569d88d1acfb4a41571d2ab13217ffc42899d8893c4207d53c478d2f48838ce8a12f7ab102f250f71caba3fbda3f6447d86387d8eec30bd71214e9bd7d95a2184be8d0971de189a49a57810075d9168bfc9f2879220ce973ee44aac090b4d204e29299329bb922a5f0071d45839fbbcfcbd943f9c466292f1f526bd4dfc70d6946869bb427d38ed7fa5d9b7296929c48793b6fdb0a069f67ffe1b6b0ab087939c04112dc518bb7c3d1c434813cfa07478c8f370f4d2a22d26551af1c6c3696b824510b398b0b9c3416a2a9768b5a199b5c3792dc306f96d4ab55b8793f6b9a06a6da28b4a872f76657d4762e670583d95d1496a963a23878350296229be89282a1387d3dc4eead13d1c8e7271ed2dd25f63d21b8ec9dd7f34291df1db0d2719d4d5e94409e9e3369c748dfad96049fe89d8701061a95929b3869350ae2f31523aa55f351c3449bfd26831f6b5250d0799ac33ec6eaa4c6b41c3e1c2e5d2617961612d6738c6fd1a21845acc702ca54f693b69fa54be0cc73711a308bdede393e1182f21680d577b358de120464d4fbb480c071935540c49260ce7fc1e55d92fa90b83e11c1abd63e38620d9f28563a94fcbf172a5355e388e66914d4b674ad685c37d58ca3f562fa9e4c2e13fb2c6bf951222b88593b45097a123d4c23163a439e9b366e1983d622679aaf2c455b1700a4f4de1632f9eab5ee1984def4b8c11268652ad70aa78e284ac9cf49957e1609594bc923ae24f4c85930a79454b5a2a57790aa7b3ad58a282bead18299c3295c6c418225d5089c2d184849f30428c899540611322429e70526ef62256b2448c10271cc67d9270fdd3132369c249d9a8bfde8b5c7e62c279d27e85e8bd84f3cdbb6e28b32831ac84c32635617a62320927b1af112fe9d07a2a89844352bb9652748d6c953cc2295cb474c45c1ae1643b63964e74d8e745385e5096252326653311e1609ab22948338d6e0fe1184b068ba8e1e4945808c7b93eb9ca5a10ce55d7224acf8e4816209cd4ae5e4bbc9813dc1f9c3d736453c13664527d70d251f7e01434346c6efdd78d148007a7db1452c674392795bb38c5098d2e234f5d1c34d58ee8f7b938feb65fc9ead828e3e2a4ad2aa74232d949bac5b1ae24e5260d6abeb6c5b9fb344790ad14b116075131b5e8878e16a79099fa92ab378b537c9574a74c83f978b2384d8a22d4966c46d42e16e7d2237782cfef766fb0384e1042a44c7ac56936889a9846db25ed8a6395fd7e8cca2553d48a43b217bdc996a2418615a71ee9b29629da455dc52945db7987d269629a2a0e6a532e9a98d5a89f8a8388541d13ad4af2a83888c5bc3ba197bce2531c6cbf2a65824c8138e51134c94d298e7d76291227a438e551dd93d5d990b6bab1a61606420b8117a308c30b519c5499d450d1940a734371fc3031a637635a58e8c6da79010a2324570992d4cab31d78f189c365988bcd79ae8498a118bcf0c4499d6fca604ade042f3a710cfd5aa694b814bb624e9c524cab6a57934d9cc2954c9536db2655a3260e9b42458a3d73268e5d2362ad4f7e6c5f4c1cecdfb28686c966d2250e29b327e89810462f6a89c36ede981f175432394982179538ea5bc845bbf4b177794189c36e4bb00da735684f98e0c524ce254ea63cee97c2c249128751c8da26b353da0a3ee670da5222846497962fba1c0e615c356491e5900112e3230ea70c22fcb69b4ca62230f880c3f9623c953da1527477df70507da6ab499edc70d6ccaa7a23db6bc329a95b4c0d6a4c8308d1387cb0e19c712743ee092722a972f858c3494abc11ab2a49554d236a382921ca4d5ef6f41b99341c54298b1674fec7ce8f86431c9df816aa43b79408868f339c25262d6944cb9850961734191e30c369b34f5abc8ae5858f321c92ce7ce98e48b1417563cd06367090f136bcc1c0018362387c06608481830c0c54e00b0b808143046120306a70c6f01c36c4e81ad4a831061962884146db07198ed136d28691216326fb31868328795323434a3a2fbab19646821a352a50a3460e1c0e060e1c88fbf0218653f4eaf6dce0592159c2700ce9452ffee9ebe8b5860f309c54d2942cb777c549fe8d35cd2f9c4f9b56dbf0e18573ac4f92a0b3f14488bac0c9b8a2337a5f9ed7b870aa0fb3a021a689f1fd2d9c564ff98caed6c720c38e031f5a48346310b7689aad4153f01b17a556ad4d9c65031c6594b5020215d830c14716ce22d3881872ff5465cbd840fb09c208038941821a35f0030b07cd5671539c5e4d909fe1e30ac7fad319a4677c632d6d7d58e160166663b67c317824ed47154e426e7e939682b8a5a658f8a0c2e934dcaf5bb220bcd2686ca0153ea670de789d5459a25238958ce7a6cbe4e36e173ea2700ced793128cb58953f148ea7a2858cb6aa147b79c2b94c492cd9187f6df36650eec30907bdd1f57e3627eedb490665f868c22983fa9893d967c229d3c9e07f155ac269c2c8a9dc1b2ff7449470bca4eb655aa487ba4d0c1fc1182188c24712de12d3ae3c2e49fbc007128efe79bac4845c23f9463e7c1ce158292f94ec58fff9f1081f46388d8a9c316f8610e1a3082715f1ea82f848d319237c10e1786541484cca34663a0de160296f7c8b984ebc828470b23e912359127236b6ddc147104e429cd4ecade36bff07104e26b5e2adee1f1c478df84cfb2d49bd3e38693fd30d6b932e447b70eafa9513b1fd070f4e37526229116677faddc5497ba4c99a71632bd2c559ab249dcf5618cbcb2317a7f79afb50dd16e6643c70719cd19f99c43178dce268a12be75cd3ca99c6c31610f0a84579d0228c30900566210bf7b7414619361ee0110b0778c0c2460918e0f10aef31c818030c1850c07b0c0578b862011ead6880072b1ae0b10a0878a822150cf04005023c4e6123011ea6c871008f5224c08314360ae0310a1a1ea2e8f008c5003c40e1e1f1091b60c0800208870c2840c3c313a734bf412c4bae8b09d24e9ca2a48a5fd193c5ca929c389f2911e424f539f0d8c42156ca92d3cff3c4ac37d614071e9a386748ba7e199945c23000830669038f4c9cacc5ef548c4653721b46c10313c7a0d429b910448a133c2e71d2ffbb24dd2a658287250e237745945ab812c76c31ce05ed12250e2afe3c27e5cb8d352f630cd402724bf098c4492684e43bf242b53592706310a6ae22ef21c12312474997f27a54e9089d7b0e481cb2a97a05112ec7c6983a23783ce2d4a1a44bf20da65ac337d64c113c1c71b498d616446e493195c208038c1734e220f9bd7b52dac8733323b6b539157d646511c79eb876a76444e3860a113c1471da308de7b5ada37cbfb19688534f8829453729633a178207224e524468cc9aa434a4ca214e273a5ebd4282ac94e648207818e224bad92aa6a4fe4fab390a71ea105a5942ccaf12421c826eddcba5f1c6da204e6a4466ca9553e256e30f3c04712ef5af21dfa43091a41e813849501f1b614a69bd1410c7b8f9b7f6563a1f78fce19446a62a55d90ab578e0e187d3ee681255af92687e1f0eb9ecede2bdae660de2c321e9adf02a2ac554a6d9c3c943b95a4ca6a287a38b48218df557a6bd793865f9fbc890553c9cfb64bd05b7bc5336b9c371e3e5c9ca2419fd847638ff9abcac296e6cd25b1d0ea94a09d1902462a9141dce1b7e4f545d3987d3a67c85102e460e47d579d3499e7169447140c6a46e77ae0487f39746d2b222539039f386c38bfab711c9ad422add701eb31c41bdc5f82769c361c44a879b6c387bec9a04bda4219997c3630d5663d5705cd39a5313421c55edc61acb20878d3486c300064865e09186d38f66859eeb0c52526eacb18d31c06881f3d91725c8000940a0021b31f040c34108edd6fa152756ed67f0c27c5664f4d98687194e6d21c9db09ad205a7a94e1e875f9b175d60c3cc870bcbbca969066f3a575634d0c0fc3c5f0308e181e862b08546003798ce1dc6527a94d068981838cc7e130a8fba2041978e41e20588687180e31dff288de778da27b84e114d39ef89b4f6c0bd1b0c1030cc770ea84c85e0bd37d0d0d1e5f384faa90d28c9e262ff9c65a0e327e0c30c81725c8c0171420777777666666665666ca2a1100163cbca01e5df0e04200bce0b105e435c4111b7326f115eac1430b5f6bbca96e5d3030822ff0e6e0918583b7e55162197426ea58388a50a5b2f89e4879eb2b1cdf3aa20815a2c2dae7610576b28b088f2a9c6d7cd47f8937f755c9f831c0b8f3a0c259b35cae2be88598fc144eada959a5ffbe2ded5248fc2a4c926da6289c2d08cd5afb36144ee2e2768fb6ae25613fe110e495de10a28c369171c249a588c6ca9198ef6ec2f9d4fbc6f72a4c38ae48f50c328cc55895259c6f64d988519570ca5d5a4c427091d33609871483599876e84b1541c2d145eec937193a7fce231c4429314a35c8126f31c2b143ef44c4ef7f28b108a7b3919429c3cee727c24992bacaf5b99b9fdd108e69de2f74a544d55c08a7103915838809c2d97cc4347f7c993e0b08c7fc97734728cb0e118f1f9c64cc5c2953b2d499ad870f4e316b3aabac99ae4bf5e8c1795ed6cb25bf1e3c38e7e653414dca7771eabebd2c594310bdab2e0e5b7e2b2a5b0e551773717abfff2fa5246d091d1707f52752966aaae3162791c344a2bbab7a671db638088d1171a14c5f56b0041db538c8d49d212f63cc2baa92d1418b43da10c296325bcbd664f015d8f540c72c0e6123a650e2d59ab65106186280110639b5326ae0a8820e599c25e6593c93a766fe9b581cdb64f04b9ee176a00316a78b23c73d3d2de5d161063a5e718a2557bfd4e51b6b66391c8c32c04053571c27ca9898b7f2ce28b7e290ce52d21a3af36524b3d0c18a53678cd333d7ace26093e27762e649ea55c549cb88f839df2a612d2615c7dc25a9352388eff25071d0ec3dc262529149b7a7388dc5c593954d86ec7e614287294e91ff4d8d48a315e5528a93c50b2ada5b720b1da438c40ddf2fa717e04062380ebd40c7284e59714ee65cde222453d0218a73998d161329853c7e85a02314070bdafce5627b63adb4a00314c7b0b18d245f346b72640d3a3ed1e189a38913162f43c44909df58bb197474e2e09336e8b7146f4bc56fac258e3260d0c189e389cc49415a8cadd87019e0e846759b38fdd5a8e992790ec7a189535275fae4afdca63313e71d1f9132177460e21c229612d9f62f719ad364dde61536be6e89830a631b3aea32c8e695387fc8e0abe99428713a5d328687b68ad8cc240e323c926bc5478aab48e210a45f8aeddb0d316423713acbf37e6bae9aa742e2604943bb2d624f50e5230e92628346c877a1273ae2985b36672eb9245ab6e40700367434e2905fc488e649519b4237961127a1829eedcc918d19bcb166037f81da227cd0a188a3fac7865efbcddba233064347220ea33bdb7a49bf08dd73ec133a1071526b997ac4c52892278738cad8c414cfb30e439c84f0f1f3b5d6b1d0518863c8f9fe326238e609d576595f929a2b0ca72eab98c2480a0cc758324caea41ee1a6f4853444539a3e84d20b07091ba3f2e6dbb7587701e912d646a7ce5c389c341551572a87496f0ba78a7d951b9446335d0ba72fb1297f3cefc46c8201b270fa9ad3d75f3d297445aa60002c1475e5b455d2e1ddd7158e932a4da6fcda0aeede85caa98aad55e130496d5ff4bc24458ba880c5b6481619f457cc144e23ed7c2bfa5b6551a5403c4d35cbeb8d544224304014f2d4cdbb9467193918000ac72c2547b70591b792f809a7d953424e5610b2428a13ce6ae12e829224b2fa6dc2418dd01bb348bd096e32e114d64210d1b2362f859770b2521975ffad3762af8443d2d956265a47c7ea4938a4584a6551d6132f94907088159622222a9b2d7484e3257bb1d6e01ae1b4a743c8464811ce611a8479454d72b324c2f93c2d4606030ce1ac7164ac94c44908c7fd09fac32b4a50f216830182700a2968854debc36000201c74d7594a496d3a52e807e796935c21268b10cdf8e0f831a7c14aaede47b40767fb8c51336c48484a68001e1c53ece9cecdf5c5e5767138d54c663162d7812f2cf085a581862e2a71f516d572575b3e178f50a9c7428e8bb472433053bac51a2daf94583cfd50db82d3a62f6649e12f548b2d549fba9416d56f58ca5729f7b338f333b54679844d9d2c68c40219ad4ea8d0162c4e77fa195352e9579cfc4e36c59de59b5e12a0e18ac3afdc6fff89a6a47e2b8c91adf42dc999b03a2b8869623a4e59c57c5a45de69a593327a8d9554717ed1186d2ba8e6a6a9388e6c53532e322a4e9b4c5ae8f4d12990e152da57ab7facc81427f5f3d52a23b2eb42a5389f504bdeb7fd1536438ae76673c436a59df8284e79314328ab8b28345516d244b08d98128aa32625b7c3028a73c9a023a2e2977afa89a3087d2727c3a5f3723d71f22b7942697c7111229d38e5f10a9a22839cb0657bd2cfed889b38be969ad9a5af55f73471fc11666d21bd4c1c2d83d8922f7135cc868993c58dd62ef9258ebe71ab368fb62c4296d02dac9f4c227b434a40a312a70a6727f2a5aa44800625ea8ca5915cc33ad37f06a5c633304062944de21c3b29437e6b61803ea01ea02189c3263531696e67f7ea9138ba97474a1ac3ef661212c77ebbc8235574b657658f38795bceba149f33418e3808b71152e4dc7c79d78853524a43c8abc5bf658c38a6fd8caa4baed3f90d16682ce2a0f28ad094a267347f1571aab42bb244d231593b11a70b0d25b74b7a051a883845b87c212697cd25fd214e1aef5245e693210a8d421c9455e9485749eb82c4508106218e9a3b2fb1acc53e9406715edb1555afb94ba9b4d830411c92afb849137e208e2993c5245448bab1668038051d214d5f989c71f91f4e5d6125be88da0fa99f13d7fc2ff7e1e4715de12e4ae8cb8783f8cecc297eeabc447b38650ac9765e42b40a163d1c82b812f37c4ba17f1e4edea75e359210c14f8b8783f23e31f6bb414542ee704a694c47a54cea1368d8e1ac313c641cdd15db0b3281461d8e5613c46e5eb94972d3e1107343d55a24cffc111c5ec60668cce11847c44d081e294b020d391cdf5a6326fd31fa2baf051a7138996bf86774b748e20487b3dde9881263831022e80dc718d2fe4af2ed86d3044b6ec924853429b7e114aabb76635329b791061b8ea392a45125afe1a44d99b828fd12322b6a38c66b99a03a2a92d2310dc7b4247e7de55b020d342052edb87c55ea0ca7501573a2f7c46b6e33a8d17bc6239d5886c324d1274292a94b454e86a35ae8531dd3cda53486a30591943ef4bcfa42c47096aca9c66d7267ca28126884e1d47f3125cb18769a27309ce28b0a3a296f8ade0c8d2f9c92c5f8d3f0c2497289045d9a614f88821a35dc7fbb70d8f092d3ae8bfc951cd0e0c259ae7cd5daf2c6c2bf8553aecdbba4c26cf2166968e1a4255896c784193fdf0634b2702c094abca6d1cd8006164e762154f76ad88af25ee17c76f2ea4ee4caa06185c3f5afdfa8d4619a54a4460d326854e174a2df3729a927e4e6e50334a870fe495a73a7f436c6f01b65d8381a53389eb6b1dd144d344038d04840430ad69dc6dfa8664734d188c2d1377fbcbb48fb3f390d7c8cb311d080c24966928cfb6623ce629e70ca7c49ac4ce36454db09e7700dd9b1ce927b198d261c7bf2afd79c08a9628806138e219990e12db537d66ae0631810d058c23109a1974443c7d4f21b6b2f70cf911ba0a18443daaaf8ced9330b31344023d02b1aa091849329511792d6723979390ed040c23147edcc27861c1b4d348e70ee97142aadee6cfb37c2496ef67e3519626c18358d229c4a76757ee4d53275b28006110ed122e938fdcca3ea1fc2d1455c50f11397f173211cbb4499dcd2a4209cd2c550f7b2a0397d1a4038c857b4334bbef96c42e307c7ef9a14166372e67b3e38c7685259e36e1231a11b6b03471930283270a8371861e42084460f50d513e4774d7a0993060ffa15d327f9d8852e969cded73d6b9d4124b97893de3fa15ba0460d5c7cdc623f6c510821e7c4ed4dcddd8db58f5a9c2e5cc84dabac25f3c9101fb408e36316c7128d71f64e84f60c3f6471128939d6539398704d2cce26649a58da356aea0b2ccea54aa898d7366f1779c54176476f45591149d9872bcebbe1644729f99a2b531af1d18ae3668cf94b2d396f4e35c1066ad430c11716b88001c4072bcac72ace174ab45c308d3fda7fa8e2582a5ab04b9594a5c3472a3af56a61749d868a739bd03a42d886b80bba407c9ce21c232cafdef94c5232c561b67b94c4abf493b287878f52a0d1d2c4aa2b6d860f521c4318b54b2b2624a51cfee1631487af0956952d24bce64314873c9f176d656dc62e784ff808c529488bb39f31fae598d2081fa038a9a41631df08b134c91c39d0274ef1948fce0b71f1cfbeb1f68505bec891a3460d1b398af0e189edbf2f5f47866d737c6181b48194036de6e1a313e7dcff922627ddbc47388112414b926a0e3f3671cacba1ae4daeb95a6c021f9a38e59b7d7f5149a98860260eaf9243e6cfa4e49dee0313c7aa18ed6a533b22623e2e71ce9aa02d06a5f2624ab1c4d9f5542f84dca1238954e21057bb3486eb831227799a17aa2979a5e42771482133e97ea4a4cbad240e9374cebceb424b542371b03961b9448920543a2171ce541542d21b1f71b694c7e48e4fb60e1f8e386f65cf103f3bb32dd788d35ec99eca4994a072153e1871109e91bfb48a5fca35153e1671f2d87ca13569cd9bc9317c28e238232b355cfc2fff5122ce194c86cecc34d91a45c4e9abbd42b414f2569a1f8738491b59614e9bfe5c57f83004a6de42964a29fe421cdddfb27955e9831027b1a7ceee4b9fd2ad7c0ce2d81a8432f1ee2122ec1f8238e548498933959923551f813864134a3395cd89340cef3150db20231905c431735d708d2bbab1b67f38ec0959b195941b6b288de12d4036602083319087d139830f3f1cee3e54f693e93e1ca3ba8d4eab381bb7bbb14646b21c1f7c38c8d534a73dd38ef60539501985e3630fc7b23aadae15a7828aef0d1f7a389bbf9dd49998f25ccec3d93b7b82ff6bc81ea1297ce0e170762ea22bfaa4a6a48f3b1cef433b82d48b1d8e1912f6e468d18865d6e19829c66fb55222662c3a1c2348508b04a814cf852249201487830161481006848b181700031408201830288d442291704010e67d14000353282646282c1c181c14181c14120d43c14020100e8701a050181004840361b0583c38cb71f1071c73480096d95a6a448c00c820a2066fd3e66f00988b90666198a4290432024c75a20604280a180ae8f2e2bd75181c7f071ced08e2c731e3f98acde0858d5c6b6cdc7332d3f82e5252a834ec05b3e48320b06e69423af9fd8b2c5cb03481478ad8981d027caace228a4d27a1a463c0a7395edd6940e9b0d63d7dfdcd6cb24b5b977e5c5e24e61b588fe36bb30309951cc65cee5c86ba6cfdf2a2fabee01eba6ca5a0a23d890bd9b9bcbe09bb9dd686601b51c8fcc9a255541e5ddb53697150692084055cb3be85a50cb5218085050e031c2e1cb61bfc8143034fec947079217e3941bd8e035d97329fa1047061bb2ab7f8b40a798e532c863331bb4623edc1c64982cdfc04b419a7d9122b9028d50253640f5d64f331f6d1d3174e7f065c1465404989215151917f404a1a82a9522094fa571a8602c3e8e975751b7fd98c7df804057f98602a87adfe4d2160fb406d067498d19910b3c8d0c8941ad9b24c1b45e4c82071f6a99abc5925242584ec82ca0e979542eabc896d9d2591c4ac0f7aef6c70cf8c972031f12114816081669da080ad9d15ab71911b1ca780604cb85813240b667f113ed691581bba0224fa94bf44d45a8046c04cd5f75ae3650892cb390ea6f10190d42841f22479e49052ae00cbd6c09782c7fc9a6f64f734bd65c0062475fa77fceeb31396cff9dbf8b7f9f9c92300ae1cf6c5a11b554772e90682987b859d8eccc42bb2270cc3e986d4a319f8670d80198e54c7a169335b4b9b2f7c93e0c23fe74802a532175ef05859212a5250316b4924b8c513bd4e2cd1f887cf7f464da8cbe1015e5530d198e73b00e4e0b5714b8dc8af5d20a4108614d78dfda8fc4e021648ec2a6e8e391c57ee43e605a6d3a2b6630cf885b4748e320819b8ec78c92c70cfb617b867d8756e846de320636825d382fda3396ac48f2d9b43e76ee53043a4d7e352fe355e15683ae6f039b62220618654001e473045404a907d411b833c821027d0dcdce8855a03f650d6151f3b06a636456e5c8aee9782a0571eea684ee04cf4edd1959c24d757ac82289da35028c3a1ae184315549b874cecb75cbd37e4a8121c3917cc84d0d62187ceb582410e687ab06406aa8724953c889139c641b93f444b4e56c7c281589efee1f8cc863a8acf83e29bd8dec2f78744227011068132e4e2e04950b7816abb5f70a74a9ab2b7779a23e2d0e8663b443c9ab2197a574627e8f783a23077f2bd55a0e27d52a12bec7a85bb23fd88e03106dae048bcfb22eaa8a6555a4372744fdb904b343935c6d7b871b1eea3e428a83193996b0c88fc7e94c22f9f9d19dae4e04a5f130b51906101a2a134407eb161622c8032e7dd0a7912d3133a9e2aaea56e4c26c834462ee0ba10831182d5038eec829b2e3687d0154bb9a8fd14ac3a1e1c1c09bf94af2f2703f2e51fc8c6f4848de770ad0610d962116e42f2031df57f76b76208245d77178661b8179161f71d1e966a2baa0ed0c08fda10537e0a0000135af6a0f538b55ee309960b3f3ee3bb917cb06774a59ab2433ff3c90894d249d75822fc58702cab2692cc128c285cbe4806779eb8177aecf37236ec7b63473a4de0ef240d91f1cd9eeb9c94b62ee9c2da7569e50d339c3d0a8169a5cbc89f6bc5584bfb11692c6f33974a24d19980c3e02b7e1a30e3bf5562d8af283532232c78c81474524cfbc766fd3488dce66a4a7ba97bf8d5135a787dcfc2800b4c7facd23ab5c758e09ff3eed9ac65598a8a75ab9d048ba52d67437368fc4e3c702ed08d7c74eb00d321b7df721896cdfeaf0053a6f3c34cae2f57718441d26b16898840c2aa4fbfa050f9312ef040aca0994233a55c663eca6e212972b26fab3a31178d603a13a2cb369cd789217013c054f259fd93292d00d86cade8393455681b6a472b8eb395372a0ac6671c3279f8e123b39c3bbe82c0485a9a8595032108ee0316827385563a41644506c54f93913622cf723b86a33b6f5cfce58cc7fba019c6330787c40a56de3a71e494a2895a9a72b3d722b51e058c3be4602187a2cf811bdf4762986e118244be8aafd0ef81e097590b98acfb06d8904270ac23c0e0f43aca1742b5e7c13c87c1d338a574d95f1ca1032600b1b44f33382f461b67fbb171a0e1ddcc6f85d3b0af5c5265e317cb3241ef4e27ebd40f5b48ee3b3a6a9b2e2827946363746ed49e0bd3cbea61fefb9ea2a04c803e266facefbcfb10f22e5456cb66f335a14026ac5fc21a7e9bacc3e025b7eef94ac8a4b50ae07e8b6c402860624158c8c73d3b1b54cd110a8bbeec5c70e901e75e7e0ad79a90fe15675c161a038107df280df50cd894a2e94ef0196f7fa7330e87841353a27a3fb041bcc5f4820abff49fda2b2de772f41a9f17f9f98ace744a2dc90c62e4796b5b536b64a6b7b57203c5b441a688884c885f8c206508fe298ab397d5fd6e3444b96ca715635bc100da05f4a22ed8da6f342f1e1fdd2cc1e15617fa26ebd5f2a0a3644b24f3b8c2ae6e26843ad6d2ef39184cfc8eff2bc863a008542718eac7c3f7695446dc1e9d24da631b4416893fdf3810035fe1a99707c522bea828dd690af589588aee9bc64ddd52e01b75ac3e0671e753076ff980ed2665e72d4cd763ba58fe7db4a85ab9745e9545ad352ebd5a4f9c753d22ca94fa51bb5e910270446c43b7b3eb8494bbb5b193278cb47282d760511b259a3681b2c186881b4fa188028fa276508866454a45db40e15dc52f4198ab443b0c3479407f1e3067e37a22a00b2d83208e6b9c3b58a1857183a740305e71c47f94b989331c4e0d29a2e2d2841f654f4a9975b16dd7aa5d8cad664d6c214379f502397fdf499050691db8415b570bc4ac8df81cb1d776de44615ea30219d51990a8aac646a61a166c1a2d407a4bd6b0d9a49634c647e3866764166ed648f1dfbfbb91ddc6c233cf95f82593d22e9811838cf795adcb33ed2a6d2adbb287166c23a5cfc58ea59900e382870d61b4008476faa697f64bab79c7e9e1b263ae818be9b819d2ecf6d334711fa3035ed4e1ff5494a3091a1a9bba03027596ff844d13d7feedbfc4e94a4b9ab0850850b18185e1d8f690b206241ecf0caab6e51d6738b8789af301f3001424f70315241913b9de0b737496ca7f4e5f21c509005b64804001411d9a07330b0571ab32b2330b69eae5c8b3c54312d18cfe7b20e32b1d12f45672a77f92ebcd086330a2e4d1ee4c3ffed9d15c37035614576323b0f2187098b4cdbe92b4128c6b3a2e74054e4bca9cecc6a9148146145dc6006d21f750d06d9283d3ee497004f9df08dde9038465f05408a0e19e5dde0a67bf4794268bcc3b03c896110f2238d112b6226b1e31da60031ab4b2de5c64cb66f72517d70a5e772c2e0ee156340e546167ea0159ce705773422eb11d52ed72d852b380157b6215b0960f2e5c62054295a64c2dbc8f33a20e9b5e3559fddd2e1c5d63215d0cb7090172a554c85275278e314f3f9ddd024c4a60e2102978a028df23954393654aef0622e3f64e6940665453c30a1d1b7c0640ed97c04dbfebd7931d9f979336b21af96b05047148568a8561418f1903d854702efabbab64875b2566a738f814363cba707eaa9bc1a6c36b50f4b99fc633e314a314af88a1e1c8600a2ae4e598c26ac099fa79f1cf2392c47410e7502c515e03fb20516b886f36140f518df404ec367d81c7a5d9d0b6b59f1f887f6abbf30307e932793839bb6405916ef3032fdf076755f2a3eae21123a8764c7467f8a6ab80bc2d7d81229754a4e62c99483f5b1091855772be71f00e1d0766802722391529ca017a563fcf2253f8d08cb9d46cfe5b4ee1fd41d3861e56c26737a640886c3664d266bd3fe449fdc4cc401e212b44c98285e3dd8a1d913d04e6484f2523ada26ba96c72b6245fb6ce4898dac8e85739169b708926fe3a39316c2de5a526caddead95d1e0f2a13502cc796692782500efc152ee8290f4e5ae3ddb0e10826825256d3f004408a162a85c240c8469bb97a1f1665b95b0a4b7e505f1700bb5d128f2a44b1c0f5a15b84a0ba372b5cc54b55fce3446bc0d12819895421ca04a148186ef4c637d125557a99026579e88e24c470dc890d168db8710dfb2def28925d785fd4d8e6386897a9a143a8d9781ab086d0240267adfe66d38a54f959aedf55960c478e9f8fc3bb9db387ac91f903430c797ee95a743442c89632c3880d6f9163fdcfd02590996df6bdf71bd4e0f439d0b40f437ebb5beb18f61287e2f99b2cc784d22c55c75a055beb585dc34497f68c5190e831ae05e4f3c0ecef7833c6339f4b1fecccb7a6a86b57fcaa38e1c9acc8f414874b2d17d231c9928b49da2d4efc58004f2cc6dc80115e22a3ab4bff887d1835867e88ff3cb69c608b1b72c81722e144225a207bb44839d757c8721c26b2b32feca9e0c4089addbc1d2d9ed8b2611f3e750c30d0db27206b7c8879750a3f44635ee3f3a5ee0f8d02ff704cefe491e6b33b35a0db8c929f65c3c289ed6b92777f912f57bedf0f3f8b61ad5f6640c70fb537c688973d9d151ffc4120cecbb92cf3c666bad814b7cd59025beb94995df39c957dee72fd67e0cf3ecd7af617b12eab8832bbcd807199c199c0c4396f596588ac276d9cc06bc0b2860db884cc9ddfd5807c5c8f2feaf2e53317a1596bcc12214072242cf0823000c4d6eb17f82d008cd4a669f430f5ece173063e3fb82586de92adc58bd79aa763b437c388fbe08d6e5430e9c606126e84dea4c8a819ab856ab9ba426e8d0b906853509d3061fd4b2ff52c2c772075b36f772cab4491fe306f9ea7841bc26a141380e6e77dbd8e85ade3bcb20330138e39be7fbe3e73552fe98ddae0bd8998927953946fd71c79863e7416e1f92446d814defe322c09afddd413c633464ade72678721f478348c93ac2ce9e3b15e6c260a164a1bb7b2a4292c4014266eab27792fa376ccf5446a110f5f7eb0c2ec2b21262db22dc2733a89ee0ec8cd496be31195f01d1643093d472825396f7d75c81572e44e65294aff8025aeddfa433c606c5d55cf3f9be3f1b8176b1ec2df2ab6e0e39e2ffd441fe2d3f66fdc9110f402d507495eb048347220387184f885daca5a70da126888c5d794301c10d7347a108e780a0905e6aff00f01d1fe27b68942f189165392a5a60115db709250c45e424f87f209f8473e372632951f2a6e611d981a059aa148dc71086d614a1345ace830792ec9c909213a8fbcda39f954329a36430146da36b6038c80b2f5092405b25d43ea0cf891d80799f813305cf4ff58310419a41a521812a409bf774384010ec2bb0aeb5cf1439c0ceab0bd2f345c144450160a66088a887c5f84013c56c8932440907c7429068f9a8845e4e7fc43c8f21f029491758a4ca0ad6774302ded9ba6ab866ad9c8c424860cb00a48bcffe547a2543c5bd9c7cb4f48c0b40c08fea02e9d4993bbd251024bbeb72a6fb3a5b8f2971de5a33466732b0b5b0f68b713517001c234b5b83407cfdf558b39e6e7802088fd4b130113ebfbe3aa049005bebd95ff60484f9017b6dfabeb52869319775d112493520713082e5e991fd3479c42ad00bc1a381246dce8f17438638a0710fe7f7f58a7426c673c7492b653ca8c18f79e31fbfa628895126d1f2942dd36b7e591141900e22112b64e22eb80abf55055842993883ae0693d3495902048240ad6444fe2452fd45bebbd4d21c5808870456b56184de26a589b248a62d3370b5623e55ec73ed0e03293ea1cea1696451da0cfdce92a9ee38b391ed9b29fbcdfa9776683230e096211861faf4badbe53384beabf78d9358893eb2da78567505d32d8c726e3965a076a6369d9773d9cb308bb55545224b568e598169f750bc2924a0655cb6c0e4b1efef051d8006f035fe5a01370769f04ead213458eabb26f5587ff1483e3166be0b6cc0424d259b1450038f048b7e02a0e2f74d11f44d4ab55f050037270c86a22ac8a7504582196eb12a5d4472b9aad60b9325416fa6991da841f7b8405e9672317ace4b2640b35a62b10e9a26154ff18593e473481638b191ac1649e1aa5bb8bfc9d9561ffb9c44425a8036d596e2b56139daf5b8ea509dda17f2a4d34d78a1cca5beac3f7d1848885b8c05da6445ad7c61fb3de41807e808d02131699c065352b1a3f6780b6343710e32c0c1ef3d8296937657a6cced0db824c19bf028d87ba7022d90106497160439f4e143a8a2d7103d240c5970552057ae30cb9e51a958acfc18e41e2cc9eb19fc435d46be3fc84f9b36b31b19e22a425b9473767793993a0a16ed048d600e2aa05f28d220da084374b609a0c12e2efd299fbc370b780729bd1db06766fd7a8048577a070adeed713d3554786691398aeed199f969051b9660463335fbca78270c22164ca4bd18b3357219f1931176ab703fbbe3fc89959790a9fdd33468893675328d4a4f574f3879628b4580be7ff570b8b59fde9e01f733e30d2f96e19a139407b1e2c84318092a8cd7265a5e5da46e87ddcb2c2f601142d0606e756213a344efe880a3635293a310e4f4620611a72a445ed9ffa095216471516c4afacbfcc1c66ea533d7c7c98f250b2264eb55567511f88ae78a51c21a7d47bf73f844f5b0e09d663f251af3e841ef878c31651bd9b9b8f6ff1416f3ed29b8f6ef2516f1f45ef3e6e70b3dbe9ac7f65bd89e6939be1edb3dbcd0b7e14265c4041800b1fa7298ab21f269386cdc9529ca9795c037a6118bcfbc569dd2db35f46853007c2b749c4e1a2b33d4540b5d95e7d9d5c1c589bf95d201b6103635279fa9968ed35b8102a672c04bf39c26839ec2fe33df722256ecdd5e0215d078bba6577b27052679c6005602edd4472849d2a7a07d4e0798642b73c2713fb8c378261d4579b3e90bc792b3afccbd57fe06d485bb7495f11c7e6e712f607e20808a0dc41fab8b657553643d3c28d4439eac12f991aac4c15ebfb931fa879200087f7d248074a200809ab400f75593275015cea5a4b53b78235d898c64c9448141a0a00658bf282b2403141914451ed949a48c7abc4c15aceaee9d53ad122a551d500d036681e5186ee4e7cf41b8c9235f655a6bfd76e17ccfcc088edbeab80fa8bf9fd88b63d64c836c3df60fc76dab70733e8b1129f5104e8a4ecf261e739ccf2103b70774e0d4249506c185b1c851cac47abd30aa95007dcb6f45eee2adaaa8f84090674a9dd132c98ec2da7fe6400e4e792ee1681b34b0834f886403861b4f3d9cc9cf21ca13eff4d7ed00dbd2ad944a4a84bc125392b1bb8bcee29be0fa44beff3ec70a7dc146754b47bec4329e88a0b9653f2acdc305b624d9640df771080c4d2580e6ce68e22bcb81dcb73ef6aa72213b1480ff28928702b5c2f07ce5c37bdcf45e91e3714c256760bd381768bf6c94a7b6c1433097088d47e74b1f20c0b3316d91dd1001a790887275656322fdc6723ba0ce3e3e754805470e760fd1b0b2b2a7ea2345e06c3badc4e918b071df1d4dc9c51690faad6a99bbec8552e16b5cfccd137a2a4009e1eba0a34ea04293e075952b71dfb73821184d7472a6fdf17f803531085bf73dc0543a7d5b12518cf1c1ba338939efc41fb0a43fed3b0d169a6b8bc0177cc90d068f104f438f055cecf95ebb4b5eb40dbb3c32b99199aa57876843377f01c77f243c302a42b5b51902f2133b89772807161ff681d1c7481f455689fd732407d6eb87062e136c096ccb267548cff7a27c2a65c8c48e4d0e867e2c4b87e999a232854bf25815a7c5610f6121edc1f13b2da97009bc77c987820c234b4789b09eea5a058cbc40e45acb422e5b02255bf66c18c38eae02ee3a6a5e520e2b5d32a7e0a29e5860496b269b0edc200a48161695b81ad4445fe1e7bb283f0ced9586a49899b977ed5958781b2982718a49a0979ee544251e1dbcb83089adaddcb23c9cf71a1643e7331038f5e392d155a748a3ef696566ce5846dcc2e7c78883b31a37e8c8729a3c40473a082be528024bb67f0c33e5fdb0b4df5c80effbfb74f1483c63bc5560fdc67700b954036678c883cdda17f81eaf0838f1b67c0f6a457e7bd7e0068fa1f833aaa29bb93bcc7ebce5b0ba998eff3885223379478fb46e7b57537de7f594dacd12d4c28ac56886ce3c093cedd2bc2696e273a2b41d071e5ff121dd290a62e4a743fc6474487f1718f38ccb915a9530256cc0ce07cc25fd7aac1943a651097ca10355183d78bfad930e87c2e2c6d66288cca4eb66a0a0c692ca3e8ba5af936266558f1aab5718f75dfeae37952e736287f2d4574527b6c93a9f5533a751d66e7a463d0e9ecc273be8e79555c9c3355b7ee528a42539e564456d81d439c57a610ec1c98726d346974b338b4973037adf1b6b713e938e7d32b9aed8ed3fa5cdf858333b7835ef8ee1475b1ddfd4e557d52834e65bf96b95496b450e6d797dbd7714d788f164b463c3b58d34c24d9eb171ba1dda1ae6db7bf5be43c8fd94633aac394dbd64ea08695fb5d537c3bd285ebb8ecced6786fdaefde84d96982d66b76292d171680bbfce4f8f9aaaa2b862b0ed96c0e422d57b54e66a47c809c518fa24fb603feaee6d1b1db077ab3cfaafd16d1e18a49a3b2c9ee0075b61dfd9dc801d5a55a2890d3d61195885735f45b8ef83454cf74f0d0ef9ef3b1e36b2c499bd053b59d023bbb6c409794ee5dc7b353492f39cb1c37a793d39eb637ef538f51c4cca916aeffd4daca5d71271cc2d7760abf9bc82c330dbe9d9d1cce535fa9dd9cad867697e258518c560e6a8bc6e55b2e1291d135759bbb3fd4b7edf7bcf07e9b6fe87f17576f97979fa6ba9262cdbe46c4ae786f3d8051772539bf6672e5b98a5945967bd174f531e22c0661affbd389d35f4b655dcc792dffa12cdcf248a3902cbbf424404f7a31727056f6e0169057da8ddebdc0ab958f84cb1e72bbcacebc6fdc95d45159193ef5096d085def8f719c0fb55e996a916d7cea9548aad03d07d820e07bab7b188b496918edaf3cb241e7eb5fd01b53ba60e7d9e1d43a3338508e772c64f4d7e114ee7ed1fb9577bbc78cbf1b4991398c92542c247f02b2a53b044bd82be7f92d73384f6091df47938ae6e2e9922be3f4c2a507d815afe4941c196b641fd4b0a85754e326c50aaf164ca21da4589607ac5838c0bd2a871cf555ea72c0b8480e4d06b464a9fe966b2cc0032aa3ca4855a13a99225b3fd414543fa8d251c0f250a82b5462a81aa8084775a562a1ca7b541c4e5b2f380eca19ea30d40dd420a85519d587123b6f1fa81545f551466c7d1394e21ba56344653219426540dd81281d173fee864365433d85a8bed85279be41bd6aa838648e6afc0b8a0494155424a85ea8c811453b6f55d3b3a07e40414105836a0e0ac8d2505f62d688b62a14301905d44cb7427b860226e09946e79b281db2d14cb806750505a943c5a14796471fa0f4a1d6a1b6403d429d9850712468ca900de5007504ea126a18d42d8172094abf907fa8655078506da1b250c95065110ad85157a7dc44017b4658a6f8a9d1d3e7d30bea3fd4e51745fb00b69b6ba0ba4359419983f22e14b063689fdb2d94f918d250fa465064d38762821a06e53a286019f333932e9400282aa872507550358a2abbddbc0bba85c2834a079505954c54b6541b5430a85aa8900ecaa5c507e9ad83ba82220955832a0e557f544c9e02de764971b329e0ddb9675e4bd437a0a9426f07150db5184a07ca15941694024a33943b9471281b28074201bbdbd0dc3b20b24ea55e7b37cab69dbba00c903d0f6c2adc98917a8659c5d9fa3cce5c1c74a0ae91b3486da459f9f146559e989fbd39a4d56b2af046da92ca35d50794c91af8a76ed3db21fb38be1ecb18f554f20258eb4727291c240a0e6f6215f54cde0ecc775302a129c262858335381ac826b9849ec3508a0706bf1417e9ef614cb0a711405768556468d0833786c1d96baa7849dec01a2876af0e200b7271e3103af90fd79b6be0b2e992f1e47451db294fb3c8ec96dde30bbbf433f522f02f5330753a0a77989832ae08d956369bb3e81f80853a250b61a7288a739771f573c19a5ec032fec81b2f9a328a7a45a7c2f53e8d9880b1bf7a7bc0523a84aaab50c26dd3941fdde31e594e24f8126d9c4f51615268c1501acc4536bde69f9fc8d08423ba3c6b386ae72ba4295c982d910f549827f2ba246bce1f189660c83b4dc0fe0cc90df112067fd461f1eb1cb8372c76096c95f809a240ba5037313d9147e7924f3e0f4f009c3f61075ba9ce738033baa4f1dcec2338d968b2c5cd63392069872474d8353f70fb7f1f05b59870734b78abadf058f3daa74ca6439c0b6cf479daeded7c8612f60fd4cece5498f36a90383daaa6b32870f1632549bfbffa139ca4116e8c4c11dc78b0723ebc448c9d5ac25d25ca22e90ce768befb7d77969dc123256f236c608154e536f06732195902082006acd0b7a3297bd1bb9180f8a67be08d3025e1d92f1989a810d1310dc929b612fd224b79b589a0d9994587c96be8ce16c0037b30704f10a295255f225fc01f75dd2fe948bef240cfcf61f5ce6ee1d05abfc597c702c234b0d20f17dc699ca83ba0f3a6b751d36781b6fa7b47cb04c427d5192b3985fd765eff961e540ab6a37e32d3a130cf0af780adc46afc04e4b9d50038d0bcd3e3585882fb1e0880defae4f91e18a30c6248ef107d80090c73998d1a5ff93ec1acaecab0fff250a882e2537df21226c239d8e0d678d62b0a36ce005f1939406b4d017c7444fed02ee7e0289f07e157b0d3324e37e7ddb2f5662bbecb0a3be87a74179b6eb6f9d27a484697bf6e26dcddda40d13f2edae5a0d78eb7bc6e7dbb4578abe936feb78bb7f96eff7983eab77eb4326fafbc2eb1e808eaabda771c7a5ae671095fda6588767cc739b8833d5824da75591adb0a5c37877d98553c443604501775e34bc76254a7540eaaacf5a9085a3328e71c52c4b5572ebdea0c48c03a6f67e595133a253ff06493ee971a184dcf53e706a22d2f98d89d3685d90ad4ff5f88cefaf8c0c967261ed11fded9d57e05a5222650684b7ece4aa43b258cfd2f64855b1ad8a624867763ce77932976ab9e244abf3bd03cfb6084ef63674f022a3f2fc32f56f2ffbc741af4df34fbfb7402cee74a510b056103da41ab3b67850c34b04e033b77ccb8d14e256278701589cc5553f1dda39fd980a2ff94f29f5cc4cd5d65e274232134a8888dcbbd56614771e43d0fe93b4854b6a0795d45eb21ef2c24dc1bddd22c118e81a98d28528ffae0a9a4b23f4e1c1c1b55a0d1919810fdbe40b19e55b36c18ecaf3ef48216c51fd1c493b098c8ee9a4b0572d2e2138a09c4c77ce84fd1621106fdb4d3632ff037b2f56847d056994d2b9d6f8b8398afbe02b4d8020ec584330c3660b46439330f0f0f0f0f0f0f0f8f3121b5b576084990524a49695894a1bf28a594524a2909ce4c7ce9294784904d56473878072f9d952b0c560c140c6f9690c9ec3f3690b2db52fc24175335bb438c3590466374dcae901d8db2009d2ffeda10430d2465d737daff62f75f73438c34909366d3dff138e657b153440c3490e2d2071db4785a25b1015a6c41b4d8428b056c7106724c191e838b69900a0c0d31cc40fe1fa929f2c54309538c32107546a6f7914155858d0cc4b251d93b64d01808fa1b62d473c83919140369b34c75da280a033959d02057bbe61b2c309092dfe9a064454db13f5f20cd7a34f57a79cf93bd40ce5e6aa54ac368caa50bc4a0573d5fce0e17482a6ba53a252ee656d90259e5c4586cd09c2ad75a200793b9a03ee7acd47c16c8a66543260fa716428f0552b99ea8183559c6e55720a8898b4a1fbae2686e05827f26ad39eff8a691ab40baf49c94d65c502a6d2a102fb6d3ced3df6e935320e5f4fda6215312b3a214487997e378b8fa953e0ac4ac22377a368ec50e14c89a52505fd949b5a5f009e42aadf78e713a817049bc767891c1c5bc2610ec7a6dc47986de3198403cd359a72f7cee5415c6580241fe9d4e2742c9986206868e2fc030667b319440aa2c326912b7416c8443889104e2f78fbc75b738083190404c1dd358ba67cf72797ad485c720c6118899f7a37c9a8ad9630472522184e7a59c59634c11c8a9e49452152c8e059f08041d5f9584a76e086491651a3f53cacde40de7410c211463ae4cc91bc4080241773bf7c6f7804030f98ba21a2d6bd0fd0724bd1be4557acf76b1c6f001e134e6d7fc9467ec4715c4e80129684f2a95ae24d433198307246161c2e3b21f6307a4601e73d055eaffd2154307c498dc4c6c4c3fa74f142307e44ea7e2a8caa5b318382076c553db492699e317df451815e30664f31cfd4bdd205dac1b5fa41b5ee8f815dc403b1e8c1d880a8861030523460dcc460c1ab8c72ccc06163c6441ba2cb9bfcdf92d5a70960fe1110b5810653b9a2ca9168f5790b2461b13a5f2e71c2a0f5710364ee578a92fb9472b48aaae95e4c46ca5c578b082ac7153324d32cf934acd6315e4e4e1fa92b0307abf5605c92aeacea998ec58d6231584bbecb7949e4b09ef1a755110060e151ea82029b7d577f7912b57cdb4d040034a9023012d4011d0f10eb833ab4b789c827031645f2ce4357dfa3c4c4112715b318fa6701d3c4a41fe24ef6b3ec9595ec76af02005d984e898c53e6f10238e8294a35ef0922227f46d170531842ea1e4685cf37743410ceda1f78368127f2128885a32d6c5b38fb561be35787c829cd2a653598f7bca52d4e0e10962b69cb63b6568fbe075825839fa1bd55e4e90469acaf4ec2c61236201baf1018f4d904d8b7b1ceda1a73f945a13c4becc982cc64d91a969c7814726081737a66ef7ca1aba5940025adcd0b18516366c7cc1c573f138340075f0c0c4795ce2d6c31264b1f33c3b8da36226a42327e0510972745f91d54945c41c39d08d30de0b760f4a905baf72ed5e08ed418983edc6def19804393326d5b65212e7110992f096ef7cee9984100a230390208a972e61c95fc4c745e0f108d2b8ff6d36353d69e992021dd9010f4710e44249391d592afee260bbd1821c3b1a41b420d621d7792533c305183b1841cce92aad57b41c345c16410a0f276433bece2a08a51bc6ac045ca42fc03095f050043968e7e465972545de5e7824a21362ea5accb3c338d802e18108f27d450d6a73bacb5cc1c0e310640d9df36f3f7de8943104c147b478fa14a12fa710a4cd9ce3afc6b959e04108e267cbe116ebfe32e575780c82b41acd73e7e4f0108421847688c69ca455a658c7038f40902eccdd789dce11ea421e8020bde7cb69e663e5f4a33f103dc5a0dab955ff2ec3a67e20879ab7f364b9b21378f481fc4925e91b84867b8c1f30bc583e1047dbe8c56cd23df4a69b6d64c668a5e500de0b3cf440ce9e8d1db2a3b8e60b079b6d51012b73b6f5c80329cce8b8def9f0403699e354ce9882a74def40fca0bdb1cc723b10b49cf8189af53a90c5e2bf5b8a7d9a4d4f0792daa44bdeb6e79807e740d22657611a64d873530ee48dab29cd96122a949864f0880369d4a7e47bba79c081d86984faec69f36f520183c71b489db75e462f75f41463c386163cdc404c9f631a599db2039dc070a1011b363cda4090e13c8a6dd63dd840ca5b49c91afd7539ee1e6b20b586d0b661e23ba9a7040f3510644f281193cd3c9b418f3490d7df76c3620a0d048f3169cd5be219889e33a7e51c5e2f940e0b1e662057f20bb23a9ce795a70c04919a1a540ed5830c4451cfd8919d745a7b1e6320d7cbca8cbaed6e343dc4408e16357885e5dbbff00883d9f0000339e3adfc889359edf5f80231c79249eaa9dc858717c8274b25b1cd94bc2e106eae6c64065d327bc9830be48dd992e9dc21decc93068f2df8a395d1c672eef48387164859df9fb2fc9d058268787b531d1dbba5c62378608170e596c46766db4aadd1081e5720ab89f116f7b9a0675b81a063bc5792197b5481241ec358ea59fe30af1737f20c1e542089e6bed353fa54e5e8183ca640ca1ab39fa81979c1430a242d5d3299cadc79cbd3058f2890a4a6ef4bddcbb9330c85bfc2cf05f74b42ab010644408b2db470c0103c9e404e6721aba2e5d1eb492e7838811845a8320be5c9400ea21e4d206f8a0f5177f9e3b720c70e1f8107134831db66c9d841294001083c9640541396a228d5cc6d9b9b161a68c0024e193c9440b07c9bed9315ef4a2909a4532293d6e7ff98a74402e972d07e3ad635a00528021e4720c6d773cd71bb0b781881e8c9d2b8ede609efeb8c031e4520e5ce5710226e9d6bc4c166010f229033a5a7fa960c579b93230c372f4c07ca2ae03104c2eb287d9dfa2dc14308e9f01743ab636cb737ee2e071e413055f492769e4ce6120eb60602a9cd934c22eb42c9ae71b055c1e3073b3c7c40529644666d0c25a6230e0e03a3e0d183428ca5fe10e9b169b53a1978f080145e3e8a0a32b9c728ba3878ec80a8f6175485cc372ac83d74a08d778d7cc8eb6c9b03b2c976d179ac74c618e4001d2d4011f081070e08f2452ea54c71da84e706844fa1dad4a81cabe0db80a074cd67f5a4ac01c144e8a829f9c9830624dfba3ca249b7a48eb320e53a512764f682858a2c48fde5fd9f3f587fde63413a19b7d367ccdc0e625890aa63e3629a4a3bd27d05319c8a0b559f51a27105e9c3085942f575acadad20aaa5799b7917214cce0a62cccd90f7d14ede25ad82202e2fc80c9e637e8fa9e2d8f1d99d622715e42ccf3a42b642459d5a4d68ef68cb06700aa2868b992bc8b65faa7d00a6205fd57b9ed0230cd8b061720ca014247b539db7c993ce1129082ac5cb26da9d64fe7d14c4cdcb792bc8bfd41a898278169aeb7bdefaad0f05b1b65bb495160bff1714a40ba7d36f5336a5b3530e0ce01339188027483732d99d149bd130804e10cc62654dd43f7b277182209329653909115a6cdf04e9cda4eb86df38bb694d90d554e89e18fb6d0d67821ce22b655067edf71f2648152df38953b1b316a01c08878e77c00961009720b99c6acef6571f4d6409e2794c27efaa2fe5732a410eff34df8bd1f6dda104a9348c10a1377237c64c826829c75b9067c9fb2f92208dba58da74ea0e4d792408a64294ca933124881e7a4234ddbdfdb88f2066b658540fd5b7947404297f773021946afd1d1b4192d951aff2ca0872dafd2f3be52d8218b2358831173100451066eb3346d1d9984f8920a56a3f7bcf1122c857d6f6b51d3a04c1563c4c5612d9b91b4390e6a2f5678c27fddb1482b8de1732870df91c764210342e33addf4190f388678a9518eb08825c3ac996950d2ec2a481206cdf8a059974ab280b10243fb7bc4b1353abf11fc815f7ae5dd9fb713b240cc00fa48db9924ea6fb9a84be0f64f392f98450d294f0970fc46ff11017c3e3a9bc1961007b20a8cec9f4a939bd68a80782ae18ef35cc9607924ad17bf4d9a8d349090fa4ef6cb947084b6f973b10e39396ab9cf9d752c70ea4dfec1a5dd1bc9d690ac2a803c9a39ade06990ebbf9e84fd1d33407e25a123a6cb3375732c98168b939abfd447120c96041fd7c966f1e111c883969d14d5bca3ebee70dc49cccfd741ebb9c1de306d2c5fbf6202fa70de478a1e3e537cd5ab2b0815c71b5c2c7aeac8118cc3f25e123438de8d540f8b9a46b318613e7f93410e72d87f567eef09b4703d146849cd335e2a2e66720e89c69aec2427de9db0ca4343dd92a4ffa2ce7321053eee81c5e393a65260329d6a93c06c2accebd6605bd675931104686366d31aacfef3090327e7c3a8f291888173a4df7efc9a7f80ba4d175a91bd61d8017c8f6a9d285366d5fecf4ee76a31706c00574f7a599f16c817cae17d26cc4d75aa8455ecae1871c485632a5d9b0729a3bfc8803395305d1c1d674dfecb6c3071c485e329b9af9d3a6967fbc8198549f69d119f5c2871bc8627e1aef83ac0d4453e329aa7ab88e32631b3ed8403c3f95c5f442f809d11a08fe61d3fcc5eae0d95603399eda6a4c8be9172e1b3ed2403033a55c47b3cf280b1a88a1546d29b18a71ab3f03b93f89cca849997e92d3f0610672caf79d61d134e9d096819c22836e31f196315605860f32903f9c6cadf02a9e463d06a2fbbdaf978c834d0c64b7ccd94dcf65ca37103ec24010ae5e217a4e6c631a079b590e3ec040bcd6cf261fe38aaab6b2111f5f20269139666bbfd578cfe448011819383e7c788118e47967ac29dbece6183eba408ad9603f9e75c9c2f9c105b28b6c7606956f537f70b0d9b061e33bc0012f12804a90e33550a5f8d802b14fe70969559e4e7308f8d002f1e7a35f87adff11a12c9047d5a7e9cbdf23f3f38105529709196b9559eb73e2f07105d2bbccc8d42672ea5f5be1c30a44115b172a34ac68db53f8a802514d7c10a137890a44bf4ea1d9e961143ea640d6b41eb7655699e681c28714084aa954ebdfe1a1deeb8f2810de938ca23f851f21170eb61b1f5020e61bdf7c3a69f1cca6c08b1b89828f2790542ced265e2b0eb61cc7bef870027143568e4e4af909cf690229fbbb5bb45c3a7bcad479f1c104a2ad46dbb57c9fbbb45d7c2c816422535f5f0aabb1a812c87e1a4adfc8a0f2b99d0462a8f4f12b5aa7a44476820f249082d85e4cd3bd497904c2a68f375ea563820f2390c28bce31ff3dde5e2e3e8a40cea7ff3258ba515f0eb4e30b4404f2a826d3761b22c37ad2c710ba8db315b597b7f44cf92462792ee654b5dcd01a7c0881a4f132e62e53a3ed3de7230804a5de1d4455fc8e1dff0002d1aa2eb3c6945a7afa107cfc80789d97429c5bc918d70c7cf880f07bb9ad23f5a26cd60352ce71525d74e93fd32ce183078459353daa4686d90a95f0b10352fda618256e9ee3fe98850f1d9082d21196f48a0cab9e1c1074a89c47befba8df2c163e7040d6dcd95350f24fd64c3720a9382adc33f58bea8d0d48caba620cb7e4a2d2f95103d2bfc6cd49377573c518f8a0013153a79833ad6930f5460e306ec8980541685d3b35cb1da69605290879aa363b8e96ef6241966d3fe5a384ee4513661364c082ecf9b374f0ac65bc82f4da27947ba857d3a70c5790e7b428e529c85b41ccbf6322eb83dfffcd0a624c0d327990112e7fca580529a88c9ae9ca51052957c692f62943a87f53413271725e4c4be357280315d71a90710a52cf9f8c533fdd79998621c31484ff1dcbe8dba94b4539c0d8910109c82805d17b4be43c78c81edd9f15c820054963fcfcfa47bdbc5c18891190310a627e0f3f32c84441daba3f1d96635ee195110ae2b99967ef6fe0d0918230ca74b80e0705f972acda9882e7a6f43f4192a67e9efac5a3e59805199e20b9657c127f97394cef04419507b9396be2a72a27483723bf9329a131b8e65690b10972fea69f1e4be9ce449a20a83871a649dea49d5705199920e8ff586193d66aea1a13c4cbcdca9ec5f355882f41d2f07f61c3a8d01264d341a8f8ab4d0b765e414625c822e32d455c57264ba104317beab610f12c8b1d5241c6248841be05b1ac144ec58f2488be767da66422414cf349ff755216fd351f830c4810df545a2f31cdece23e8294b2aa76d29f4268c6c420c311a494f54a8396f4cf6537a2afd4713282fc3d1af45f16410ea7564698ae203c2e1da7f705198a206cb2f2f1fc9a09321241f6d4f92ac6e87c25c426051988202615df76eafb62e53e0a320e4110222df6ef2e33c8300449c613f617d3fd5f1292510872b8d9f0f1a4e604198420c66a6e788cdf20c89a5c93ca39a9472f0541ce9cb51f966338d85a202310e4904169b0144e4e3676810c40902ca56cb518d4976dcc1f881ae3c8b15aad11adddf8028c4c80161a90c0ce40861f8839aac79027975208a53e10fbc2560c8dfb694fc507628c2feba94ed56f72f7407edf203c2e69cf1763888b1c1aa0c0076eec90a107ab5b5cde2a75f240d07c1d64ca1aff42061e889d7a419bbedc81181f73a974437b6907a2e72052db2e598ee848461d887bb339ffd4ed92a8e84052d195f24bc62e71770ea47ce23a6bbe1fbda2e360e39303a9f3749eb258964a6d2ce022791c48e94146b3c756b793295979dd42c61b7e2b0d4fba3a6d74dc408e5996747e8c0d1b376d2086d6a042f737a70b306eb00564b0e1afadd1a9463c8971b0edf81b4e02196b2066879913bbe9aae48c832d07185cdca8800c35b89e3d54e5e441544c83319fac9af6fc1e0e36341054a458a9f6be7d9b71c83883e1ca33dcf56c06cdac83ae7cba792f3332ca40d69cb1b716951e4aa991b5e78d81e4a27126361603296be5d30f1fc6c156612088b7ee861b21f39b050c442fa5974f93524ac5f017481fc4de6abab5cc29bd400c32275d29a596dc6d67d900195d20d756958ed7880b8fe776dbbbfc16489772d68d91f972e8709d0c2d90ca43ac5fac000c959105b25895c7142b8405527b0aa283ae7505b2c7af2ee1f1f699712b90b3760a3a8390e9b5a12a90b3a63615b3462a1074ce50a7b38959dfac8c29904e094f3a6abc738071037dc145175f709132a440aaac613e09f959ff1c4681f417232634543ab5f7460e306eace0190232a0403e295a64c533f9e0171c66074a666abb00194f20e68da93b787e9b9e4f022590e104927692ab1bb33793884d20af27217bc2e22ce65d0613c8f1f4953aa1d773527909a451c234294d27d54b93a104627916532e9a4f0249c5fd92317c28bd7623819c7b41a4070d1f81f431cbde56e7d54dae1148e9e754d746b303376414817cb9a4df85f6ab8df705ca200249a7cffdd4a6c7c1d68252d60c903104a256a5267d41c57af370b00d1b366c98cb10828c209045688e953b454d492c1c6c366ca8ca0002392ea67e1db5253ed31806193f40bc666a4beabfb222c8f001c174844efa6a7b543ce54504193d2007d3d9147553d021fa02c8e001d13f75de1ecfb9469b7640929759ee971d74c98e0e320d327260327040d88f596a54864a17341937b04edc9c7d1615a90deaec6ccb1b1935f0f38edab0e675ff412f904183ebd3ed2e642f3ebbf23da9d8278136b7418c5990b353a5795f14ad168d218b8b110b929d8c21545a8f2736d38718b020582ea5fdae945e41da74b7b5bb53ae99e20a72476d0de252cc544964d80a724ee3fe5a61c7600539dd68c8e07f568c5510638cdd3ca3efe748c1c7500539c38a57b6eca2497938d8d0d2c4480541bd89f6cfad26dd35bc11c44005c9b29b922f3ad2a409eb10e314e4ded4d14953767b349982a42b6ab0dbfc1eada15290720e35fbea6194109382e49a520ca542f6281d8f82bc16decb329838ff5614c4960fc2f4c5743685829c477cee3f2dc24f030a72e5b23fdf6abf54f51358f8a5d213e4a0ad821421a4e92fab13a40fb54984d9c7ff78e70b2e92990abee08201a088c109f2f88f9c97bde8d0a74d90a39d74dd8fb626483294d61eb19852e59c09720a277cd4630a8f796182142ba7a4ab5296ce95740992d41142e7899b8f8d2c41aa8ff541a64e25c86b9f2b65d5f0749f5282184e5cb56205634c82942d3f8f89c98e52aa18922057cc6f3769f2ffac8d110992a7cbba295d8704c9ed4ac5d928a910e311c454b6a1ee66ead48c311c410ed24446c90795a32d5b685115d0620b2d8a025a6ca1454d408b2db4280968b185161587188d207f5e8fa7d553fa7d120e364690ef83bc4af162560d6a4ac4580441e5e029d272b9657271d888a10862650e5a633611e4a06e3d95dee689188820a5cd676a36583411e310e414539f53477c9d89188620b8a9bab220f55a3c13881885208a8727a1d432a80cb10e2db6405efc41bb6184209ca7c9784c35b2dde369a181067c51810a68b185165bfc21c620c82aa226df3ce772ec0541b0af98a1faeb52df8b1108f28d68efa7bce9546430a0c5165a30a00511031044d3b93afda5d7984b6d410e0dd8b0617470e1056a21c61f889b7e53d2bc1e6312bf1f88d147a68eb6697ac5af00064e175ce0d8c2c61362f4819c93eeebb5a4a47cfe7c200721ebaef6b6b98362ec81309e41475bc3679df973a4e063e8813827f741ae68c98d3721461ec8e95477f8b0abe57b99420c3c90ec73e90feb2c2716de8198477b2bdf5cdf82540a31ec402e794af465440f5001173bbe048802366ce8b023c4a803c1439c6efa15d169f11262d081e423935d944d6d3a53366c1821c61c88edffe9f289901c08174766d5cecfcd92c7816cf272f2a04bba5e1e8910030ee46042c9758d37bf69215a6ca1c50d5331c47803e9834a62ec4e741296d6430c3790648c5145c7e0625da53690f46d1b49830dc44ae2d36676769812d25883a951d7b3a8bcc8010603bcc80146f2010d35d41e5b1fe2a5ebba27667f326ea6fa5c5617c78eb7800d1b38769ca681d455aa4cd85f34d0403415c23dcc9a589cce404e6559ebfb298cd68e19489bbccbb7c48afebb94819ceba623938dbd9c940cbdab8865be6aa79ecd66698c508b5993e518c8275e45e35fc997f88881aca99b9a624993d34c188cb9a474d09a35188869da566c842731f57d815467a65266d7eed687861788719673eaf71833de42a30ba42f2b952627d3e002d95234db6c506fda4a05038d2d10c754d388b11833e3af05f299fa6433ea6781249b82b87c3ae3938d34b040f2be7465c2322ba606051a5760cbf3e3f342bd73f536f37450297530918615482956eaf7daecc8caa902a7b9156b6ae25a41a6ca9efcf0294c830ac4d6a09de45f65742e10a031852a5dfb6c6c58f886d19082b256757af3e2e9f59d99616f1a93b8cc242b8d281063b397e78e1a542e060ac4bb603542f68f348d71b0e5e540c58b145060c7175c8061813533a4f10492cedea14e8cce36aaa7e104829c1e9d3ba5ca94ff4f400f683481a48378fbb098b544ce366ca01b6830811c22963cc7509fe396964052292cef92cd4a209c8d29597abe3295970482261721e466cd0334904054ab0c53da3ec6dcf91108a6c26acbe96784eebb634d6c6cad42a76b6af3d60f79d328026977d3b9df775ee60d0d2210c5c3bf8553aa2c974d6308e4246bb4a9c6b85f1da42104c2a74b8bdda584294b1868048164a1eb1f2c8aba9cf2ab82b325d0000229b446add1613b97edf9041a3f20e69973f70f2328d0f00179a4852619947c051a3d20ca9d7de63eff77bbd0e081f6a5bdd180c60e4866a263f6c7f22472f35ee400830174a0a10372bb47f97eb50e9b950c347240ca8af1a334e6071c0d1c9053be74781ea103c6161d071a373826ad9501600d346c408e964cfb65ba90bfeb8c8b30fe86173a7e05ed346a40b8acf7b81c52acbfa44103b2cb658da7844eeaca9a310b52e7139fb48e99e530ca82ecf95255cad9c6a2d20c2dcf5bcf39a962d6227a5890bb77749792a74e7f3de315d899e7dee6e8e70ab275f66fb5a5cc680541eb5aceb7eecadb0c569063d2fc9b467ea45770c62a889661d393d2ed7e414815c4140d97d92e5892a3490539e534ef9845948219a8d0e46daa9d539975cc3885af3b6ba773962976e2927273d1fdae98821c3a89cdd82852ddf75290d32765e162e9243f480a62b0d9f87cb5fe31faa3e8b2323355ec5a6c45b7e39ad7ce25db8aa11505d1bb72fe2b93c93e8e7d8019a120578ec57e8651bb5382821c34aa6a10d3a4ea829f209a6898fa2619df3d33c313649fd92047a83ca31364778f6947b5b479ae3941b64bcd1a5a5f96417e9b20a715a599734e29734ad2043967ee8e0ed57771b49920e9539b43a9d8304a899820e995ac68de6d71cbbb84973caeba59e63e2d41d0cc9b46e8b9ec5c7bc3ab12accd8baa9d586a6b78ae27cb5163e39dbe293083124413d9cd244817644a9dcef5facb9a2109a27e504b2556f953fc4482943ec23e78e9b8b23512664082b81784d785cb1b633eb5d0400376e8403b5e023b98f10872d669d113a7c93dff198e2028917d17a7a25dff466c04495dfa77d74efb1e4be86886198c209c7e8dcb25f263aa5815662c82186d54e9cc495438f15104c16a366d92b137c53acd4804b943354fdedbe7c209118493695d4e5c121a7d3f04392c83ea8c9973d4501b82d4a9c46ad4a58520c6099d4df378561e4290d5626936f7b8fbf306413eebeab89a53362be64d982108f2c631add75fbf4b9a1108d2062b35b77155344e8020fac670db5f9beb43fc87bdd6ac6a4c3d4f4e6cf475c80fa4603a45afdba9ce73231d8fba401860c28c3e1043cdb6e2ef2aeb75f8403619cb95e4837b209f7c8a7e36b61ee7d30351a4f8762a995dc36d79208c92b71afa6e468d8f0762f61e1d4d7db2120833ee40cca16d6aa64a8976d70e24f1d3f0782ea3a2d575206b2c914145fdb49d6507172c207420988cb60de115456a780ea4e49ad2c9d1a31c485e5b76a5afc681709b4b4ebed783289923cc8003d145dd55d7459b6ff60d84cbcf121aa61584a9dc40b0ab520b17547e28591b88a952a72436642dc20c361063a8cfa7a296a79c3e065ad740dccd5e0ddf0a154b67a881983a59163375ad2aff8c34104e8852ddbd1b3c83bb4498810682e8cb7c41fb7a06f25a7da90695c6c148810fdcb031c30c04d1a9e62c754cd22beb22290466948138e2a392ac8fceb30460748133c84052fa4468891f3191c190c018ee94b3eb18afbadd95cb183fc92036d3a70a2a4109c09040186050c0868d1280d105e6d811c60c3190e352b28f41e63cf56618c8e31d5ea5df4dde6560206eb828e3ff617378d01748db2dab2363d4129a17b232334dd119cdb48ad3f853771748ea972acacb6e5232498730830b04a57a2ba5bbf8176587c28c2d909265d8cf29fd99cf0833b440b0d9bf305a752accc802c1eeb753f80ebaac8470ccc002b1f4757c3c13425cb51957207c3c7d79dd4e72d387c36758e14a33be55bba7b3dd624615daabdb75d731dd118dd5bacb24b27affc6c1c6011b366cb8ae600615481bee74e8503153205cf8e86e55772b3e4a81189683c9507a8b02d152a586cb4999d2f15ac00c2810add26df21493507a3c1fcc780279db2e5ff6a454f4b6743c0e0bf08d16cc7002f9cb840ceb9a29a5a709e454b9b36ebcd815375f610613c81aa7514d79d0a0535c022965b6bdec3e4a091d9fa104e27a4caf9ba34e0251940cd3102136f3bd3390404cd1fbf68fb14e41c91f9083194720057193153ce7ad0faa114863732a75870e9adb2c0241bc98264d569673561a602290b4698f79449afaef1207db8d954002145001093460d7183063088877dbd9e555c6a9766ef6f05839c50d4aee1c98218474aa94e4cf5c7f727c0a1a9003b5e025d0c5d360461008765d7ad489e688f34c40870e64660081a8572e6e57ee99aa637470e145cef801419b2921373c86a76d7c40d2a34f636ff07b40f835573f1d3a5aa9cd0392a7f9e4c1a4366307a4cdca49b4df4507e412faadf49c69d3bc67e400bbbd7039ad5bafb9351396be2ae80d4a563370404c314c6e94a67469974ec28c1b90fa8289fff425633febd0f15d6ce14a98610352923a1744a990f2a3d3d182b740df985103d287f8d92fcf399a767491824fe8a012a43560060d08feda574a9f4ef2b1fa9805593377d09f64d2e9e4fe90052956501d3747cb192ffa8805f9bf6310a29dae54d241c2072c081e9b3775b813ea6d7d0539671979ca83d0872b48d1f3e2346d7daa527eb4829cb254cf834a164e7f840f56103fce67b64d2988aca48f5510f794cc8f5fea872a08e7ba21efdbfe4805792d7f890e99820adeeef84005f192962a99dd22d4ac1fa7206585986cffce87294895728c9dc5c24e8a4c29489a54f79916cdb4156b418e6e077c908220b2f32ba68f50182dd0800d1b3d0a52c65807719d4f47c6860d5190e6529b2819bfce423f5d202e1860c3868e6dc18eab7e2dab373f7c90055ab0a3053bee091fa0209525b578f5a44f1047df3ac88eb52b2ae409727bee909aa7d257ca7482a03b34ccebbb46889413c4cb4c35533a77ba0982a9a49d93feaa9a209ccc17a2e276ed332713848d0f7a664fa3aa9820bd0725e3086f8fb99a85e1e312c41069dac635c9ca9fd45af8b004d9a4a7353f53552508ba2aeaaba8b64aee514a902ea651f71f6341f8980439e556bd9151a32a0982cea0d53e2795b41a065af91d39c0b0800d3e2241b2d3975250e6eaa53b691c68cb2d3e20410a422ef4c2ee925bd0c723c8769a3cff932e1d416e133207b5a0e34e845f7c6e3682242ac56fe9343a60e0d88126c04518095053819a0a900c1f8c20bad65a76f40c4279ec6311844f4255cfc3fa500429ecbdc8b46e7abfa6ecc24722c8dddda6cfc267f0ad7c2082983fc7a0ad6619c2e443103cb64cfbd9884dd91a829c64aab0d7982c0429865a52672374d44e2204e1d2b785e5ae7ccc6810a4129a73c55c694554ce8720c82daa4ca892e157aafe0804c175358bcef26619ba9d073e00e17a7e8cb5bdee7c7db6951cefcfbca917f325021f7f2057c98df03c8f299ef4c30f84b5b0d8a9e7e332db471fc8b629290deb61217cf081a0f3a6bb4c61d5b2f86977e5630f617ce8e13ef25078288f5f9cc968e6d81186f9b803c133095193151fefa21d8839c63c9a67fd44b5fba803f965b46d733769ce3e1dc8edaf396ff52e8c36e7406c9319192d43017b207ff84dab789d3e737a20e6b77c69f6f240ba33534aa9bad4bd2d1eded1541dccda3b90f3fb7e3815b4fd26d981247de6c3d55d07a2e8204d9c125bd9233a904c7ab8bbdf702a8ce6404a1b2c8bd55aca5de4400af320d309bbfacbc781382aeb7cd6eacac9e14052e14c5a0ead8c967d0371e647554c523790cfee553c5c69eca8b6817c6a513546d9400e2fe72995e8b4195d03f1a2ca68cce2feb7aa81544ab37278abcc9f6920a98e311734f4e49c6820696ab0d7b474f1cc33109329fb529954ca17cd40d8bb55933175a3735a06a2a71322f3ab33454fc940f8d29eb3c80b2233a66320d55aead8fcb996931888621e96720a03e952be93ef24a4c7203090326fc6b1ee60393b5f2086e97fcb95e20562eaa054ccdbc9507d1748c97be6c32f7b96b840aa94c3b8ad5b20c5897ba6d95a205ec5285a5e6ea2eb2c90af3ac6f4cc5820663ead7b7d495f7aaff0b8a8ecb4142b9062deb29495ab96b50a44dbebf42dab4b25a40249fe653c755abeffa640906b9be3689aee8b10eaec3651206d901b5b4356f68702597f3786cfb12bc9d31348bafe6ae2622ddde404523655416a8d544f5313483af7f3aaa652298b984070db38aa2b23af374b20e574414ea5cf74cf288194abf2e94d492096c5b031c325d161410239d5dff293521eaf7284949ade08e498c3c994cd7861fa22102cf3ae2f4f0492700f3d279be9fb1f0229e5bcada02d9ecf2e04c2a5742fcbaf375d0781a07d4194c998273b4020b849332556fe015194967a5dbfb28c7d400a9f2a5dd7ed01e1d469b224b4c653cb03d29c9e9913da0131695ed0955a3a5cd501514b08f5f09cf2f79903828dbfa5f81ba35e7040907131be270d7315de80543a8b6c152566c43620cde54ad93f4302d480785a419d0735bb7a22000d48b22fda3fdfe8de6816e44f42e5f427db941f5990cebb2c6747df9b4c2c8873797f647b2e55030b923ce5ea79e3ba9f7905d1f3a98de92fae20c64d753ea731dafd56907253b3f26ffe9cf46305f993a9c7bdbcf9b27dab20498fff1cf4c8ca964f15a4f5a082d8522f150429aa169e3269687aa820c5dc41865142973cf34e413a1dcf10973c3f09cf1444b356d3d8ab1d5bbc5210f3a57ecf99ddb2b62305f9d48a12f53ea1e3340a62d4acd13af32f2c4814c4be78691fb694a74e284862638ca65301057994a5a8bde771ef4f90eae6cb3adb7ab6de130411d39652051922ea4e10cd6ad5f2e61c2b8813a4924158a7f49e4bf126889e64ba8a541304118d59a155cb04c1e407e59af5a4b96a9820a77fde4dd1bb494fbb0449648e52ba1f4445cd2c41f211bf594fb34a1083578a5da92e4f254a104676cc39a4e5d6ee4c82f4592deef5837e4a910439a769963cd5bc5324085aa4770a17f4ecc6214198bb4a1da1a6fe790479475f48df98c1367604b16bddf67d54129546104528a939ffbdcac90872c59c55e3fbe5126ed5580439e60babfd6042974a1124d95696aab91a89209bcaae8f9a964b93e3c60e54821c60a4433b4704e9334557d76d92a7271c6c695d350e419059f1e2695c72afb58621c8d13e8e8ea650b510e4649f7133895e3351dea106210cadaea047ab07a4a900737071230c1d696ba8310852cd57bde5a97dfab48620c896a7d29f7ffbfcc6034192ba15a3e998f45e8a0041cce93345cbb2a415778d3f90f2a968f11e4a5fe6ad861fc8713b7e776e861f50a30fc468ba52be54655d62c2c1d67c20d98c56e9fe0507dbeaed819c939cd03f5e16164f1c6c7d56c67a20ca568e7d55192b878a830d8f8b1c3b320fa41d156754b24a7a61175c9c000fa491bdf9e22b583a59e9b803f1f4d3e55a19d981601e3ca6fb13426a5d7520d906b1ceff980ec4a05a4a8756b7caba990329e9fc2c15d3b47263e440fc0f19ede29268ceec086ac481a0628e7b2b1a23eb273b0ed48003966f1a36c7c1e6f786f3c353543546ad3bcc4ca427af9b4db34add40f48ff9ca3dcf0a6ab481d47ec264fc2062e64a6c2087fa5e59cfdd68a3312d34d08030bc78400b14a043c75b400336a450630de44df27d7425cd046aa881d4b9339d4cf2417ffa5980ce175ca4a581184af5621297dad38bd0400ab30d4f9d55ca5dc3408d33905e2e7bcc69955d378b832df1d43003419adeffa6b814ae340bd4280369bf938e5779a7c5b51a64208f50f93ca5ca2d7d738d3190630af3a267336c445f430cc4b0f6b68e7143a63d0c04adbc9a2b6bac8c668281b4f522328b7c5f20ce9fc7b394398e9eb28617c8319810adb19fc6feaad10562cc18cff4fa48ff8dd6e00249ee475d4bcbb4ae17bb05728979b6cbb79f1deb1c295d0bc4be643976dc105e9ec5c19a0592a5184c73bec7c18605d2aebea8a0456abe7e05528e4caafe37f6b3a63550c30a246917ad74fa390d4f75548198c3328c0a7ea20239dfe968a27f9cc29594556ec62095026133e94a319ec2f75c51205ae6b4d4b40d6b1b52030ac4f01fa4e8efcaef553e8120ebe9cd2d3527102e9e7f5adbae0d59a9408d2690ee475ad8cf211c6cca0462e76f996becb69b6fdcd8a1030c1c37bec8710ea8b104728ee5f9be2ad574da64a08b2eb888800d1b607071230c1daa0401d448025a34e9b5b029a8ac8e2ed08d1c60dc08e3bd30d30fd440421e22c3958edf204c1dbf358e60c9aa6e5d9959ea598fd6f0233edc556a18811493c8a756675ca4940f6000036cd8b871358a403ce59726acfddcfbaf4104ec3b884e27460ba83104b2bd06a141a5b986104862bc437a484b8d20104547565241c805697b0d20103d58e607a19f63da4b8d1f90426ee41a3e20e73ffbec3917c35c357a40d0d31a35644dc4ecacc103921c352a9be4a9a3c60e883b3a63f4525bdf23aca103f2e8bc973ce98d4c97522307ceb65ac5daeac9a7b54ff7540d1c104ed344f7fbad710372e68d9fd3b3d7ce2c47831a3620c6a45683fee6a88e190a7ce0c6066ad480bca3842ca5f48bc9b4d4a001a9ac3c955758e678770a1880012d9ac62c083235c514747aa4404316e43c32877ad1b9735ff4a01d5c78c1451737d018402316847fadbecb1f47d4670c0b62d67831dea7fdf6f5af20a807fdf75da251e3c515c4ec29e6396d2aad20c7eca5d45506f734172b084ae65dbf967c15ebbc66ace7bc7d7ace592a21639a53ffa88214be975f6beaa4899e0b3038b05ed0488523ab92503ab5021aa8208652b9c2668b397e274f411c4b739da3c5a5fc16ca618a5a9459e5c6344a410cbd162bffd66b0ea51c29d8f17cc37406344841acb9aa8c111793aecc2808962a9cc6344ac8518b287ab90eaf51998682304a26617a44de05550205498a66be523984e7b0697c420f22fb445f4f28e7aa56b7d7b932a2f3f1ad27338fbe1324754265b9ff9706274872752ee73967ce66da0431588d878626487b4a45b74ff27290298d4c90dbb72aeec86c321dc704b1565334585295afb45d64c0868d1bd638a0718947a3ca85d6342c718685e5677d5ae5cc8d051d59f7a2736f4124a05109f2e8986cb49d1c257633e631d0a004b9bd47cbc3c80f3afa4960ea65ad56969baf9f5a56795452d142f4db920439544aad934154ccae38d854c0c5c105789f794682201757ab2a3648104386cdfba3d64790ae4f55529d7d4b6de50892f79c90cbe7da717323081f83ca2f6a71e949cb0852ac3eab399db20852a6b8f9a83cd23f4f8a205d1a3191a7359a2f9988aedb2ddf6cf7c584ea0e2acfef9b8a0852ce718fdbab24f2929a40e310441953714f7f6ac346df300449ae79ca2454acabd65bd0280449dc2ec35ebe70dfd12044b194bc55b9f10c8220f4a37ba5ec71952d340491e618d6bb91038c1b5fe4400f60cb81bec881767cc1455380462048ca32b4a9d6cca4640910c4244edfdd6e10edcffc812053647c8b61f36aac092d400534fc408c56ba6a9b44dff6828b1c3bda765c8e1d3afa405062c373ae8a8d416b0f83061f4859f45abecb97af1ddc0369e4657a20584e7349dafb7920b86b4c25bbf229965a0af20434f040d020457f7c51f2d4df68021a77206eb0cf6bc9f207bf0b30c0285dd0b003e952eb56d272da49661c6c3776e848418e1b3ab868d3d105173b52a006a0510762ce98ba43bea510338c16ec403a1054e7fa184f7d1a73209b721d5d39de9d52a52107525099adaaa4a6fa059b461c083a2274124a3c9faa9c1474817284c14d030e64378f31a69432a5726305e88b3505d07803c934c85f53231c3bde028963c787912dd87149c30d0495f2797f0a69b481643332bd77d4cbac098e6ca824b0c5f26028100883e16028180421f1b4010313000000081e938522c1683c225695791480035934244c3a242022221a168a45829120180a0442c150180c0a8202e160188ae41025d3791e91cb2240f9a52dcc0aa40867b551337b152c35fa5b5925a73dadbc46df779cb327d35b7616d15e80e0cad6620ba2e54cd2f1f33873a2bbc1bbf0de019c0933444bd08acad63c2c07b64c26de19e514cc611b4a47369a278d593954b032220a3d9611d799a416e4a8df5ad721f7debebb2ace0bc9e40cdc87ce30350581e5672af564fc76ef8760ca433c539ea16f396eddb3a586e585a56c7192fe3b855ba448e1f2187166e9f67c6a33ab5ab8c488781ebd633fc098a5c308638bf8fcc4a96a8b7c7fb4ba571749ad753d23206e9eb677fb351f241fd9414a251864452e2f3169e477e9b3c7d1f78e5167867ed94dd671c99c923bda434a50b1aec08895469000623e1da4672b74cfa5c7a6b3d6395030f8d87a9b203da11bd3e4859b92c4ea0e93bfdc47df6562410839a5ef08672b59909b19b3b90ad109e996d10e99a636eac877ed4311b7a83025c3a97528e35e84c3cebbae4979f08603aac657d88408636e7915f6420281838a461f1f087453223263972a44f754a2d956b7a77eb7e76a245f15682312ce0e46adc0e2800fbb7ca1f4cabde46f7289891d2f55edf0be802afab40f91064eb52d3feaf227121f77135b7954840451c6f6504829268e7cf73ef397e9d89ed20119753234ee528bb7519fcdecb035c7779a43619336d79601b246fddb42b03f118dd4a3a4f3ae1993d867fde2e944fcb70ac243edd088d62c05c48d876ec50e2438331e708fa2618e27fb32150f6f2c0834bbfa1e8193e733a6eab68aa8dce0ab89b4f9b11e371335cd0e4da7589e3580495ba1bbc0380dcc8b4e0b92417ccf9ac11a14dc6bb6919495fa046da82e09b24ea455bb1005e1c688f5c082c37766c45e1c933031b78b6d1494d4549c34abd41b060d2ea9ce46880004e4eb9ad7fd88ffcae690cac9b7bc628d924d597d88398f83c06212ae34deb2ebd164d534dd13cf91b3aa4bdb3ed894b753c94d59bd57bcca1685b8220241dc18d74d67636051090d965b2b89a36e7594109dc51403a1a44d7d551ff6b95ccbe23f6ca3b4d2676c9686e279076cd30302a2577c3d66a08d20e519f2f3c71163a51190e1e0d104c43c2bc0e27a1a659b974fd1b14349658f670646c8d1f48b742be46d054e089012b9374802ceb4c672410da78eb168cb94731654c9ebd5a7f372d2760b1e73b800ad02c8d21436b10fa4f4fae81c242ebea453e26242e54ddd3f21742e03aa6fdbf59ecc0d70d077f98128ef4444e89b4a907f4549d15a6b4265ee85dfe41a0757196a7023831dbc147da0884de816adac552d41585544c3173587dfff547462d6bb4fc0909080fbff7085191c107d704c6590fde8d308a14d4113e2eb9600f7589df95335705c5926570acb36160b59a3552c78f7c0c1a0a9d7d3cc258bdf32b8a323ad849b9656cb50fc30936acf36554e20c3df694860a14467adeab2949ae7832bd077acd645915554887c98b08344d699c3b1c5afcbcd181e4f8c30fe249822cb8916cef50420ce1704961e6d30fa5e9c19f569f9707f85b41819385ceafccdae73290cb616b44cf07bad81f5a05500a27d848413ba97954823f8bc2eea1d3b1661d01bdf1b2b683c1a95bbbf7ba650ea205858b7c9153db729a3293736b67139ef1173118928bab4173cc48bdec8dd4c7e0f6cd33dc8f4a1ee30590c619f548998b2828f6b398776da1ae27311eea3b927e6b0b7c1706b58bce0786dd8403ef6f5822050034e357fba4193f5d0279dcc7a3992394b301dc1295c1573c23c615ba0bcaf1078933f782b0f94899ad00fc7790d47b07a0f089c472db6f236af15968032f59e8020e59f4e667d3996008fcf6802ac5a58277584538e59fb4dfcb052fdc899e09cfc5b92b4a77a794c5d5f7ecfb5052a709c8ca0c5d31a6e32416165f9521c325b003e3ed83427cf3093642bb71b22dc49e21db67177b7c74666207a2af975bfa6cfa0ee28a231e8868b29826698fac752d1141ca0601ab1bd1b32a6404781670fa5c64e0c2cea00c438f0981fc20ad1dcdb8484cfdb3181849c62f747fb2fec11c96e8735a5e87e20f71208c701f9c12570deb7a59850bed712b27e9bfb33ff9b13a82930c124c825b2ae5372773217a37d1ca3e5d03a4ceef9e1c671bd1c3c367746c09f66f11308cac8644d320a05d43ecd25148424b6951db521e0af879fbb5e2a5b2f4ec61d390f8b1510dbece0d61d7bd9fc20411ca24dbc9ce8de4c90d73594c845431379bbf37e6c870892bf8aae62295870ee348acf3978744c8a3da1cd453ffebecbcb5ab7af65ac77ee72db32bff02b4865b567fc7acc09044d0efe34abccf7e8cf7cd34b94b922fa5337f639e3e9febacd2c8f3366cbadc99d185281cce4793957e6d0acac33b24b3834efc7592e0e2e1dfb7d44873937d6f97ab6228919ac96edd1acd860bcf9de0b64a2cf195165b980481532dedd92abd82541f2188d42a8c94213b25adcd1ca881d8472148ccc622532606f7300972258d0cf549fefecd47e323224045fbb6f105abc34a21d71756b38d60aae4a87b35a467caa1b12d64c9fe26c7f923a8a444958e6da1fa142141fdc54fca3a6f9d73341d894f1c03a91ea0906ba59aa795b664c2f51d936a66127c242a66a8a84c2238582de04d40717a2602b6a813998d0c98e563161231eae19e91852970b6cdb88025811211dfeb7b03471da4a1187bd267b42d605db43ea94631687014978a24af7e4ff597c7398178b0aae2f7b7a5bb386792b227b8b50d00bc86ec6c0468d5ee12a9db67a207a92311297f4a1f53255dbc52a0bf5fa755af061fb82760c08e97a3a3f2c30ce1a24112338a3782b08b5d487e6350e63b418f8f6a79fb9134c23aca02db9371e42dd68455d7b96d0124b69fbcb5215e65045d198174450197660f1fd518b1b7b016d31ba151bd180ec71c39af647404e3dc380e1f7b43568dbb2b47bb43912156cff9ee38cf43c0b9b72587c706421d8ca04a7c8305494bada9c29048d5b555e1be5af6f832ac87dace29e6b67c93c4e4d1af90c7bbf3f996741bae039faf529c3dbddfe570c94e15de865cdf2c78fff6896fb5251d8b986fe317c97a7f113618bc1e2b4ede5458592c2abb5a28a8bf6de2bfc671f513bfa493ed9fe2ec28da66edd0bff6df247cda087844e0d4a28cb17a5850a88a8eeb8be75665946476aea69478cecf51edae35917792d29a41c68e10c2c0657b89e05e119dbc828140f215484ac117c3b468e4d727fb213db6299e7b248c6ca95f3b50bdae512cc6302d3af35e980c1c36333b1e20bbba7c4ee6901d7a4ec7a8128844c2196383b3c333dff207f07ff904119b280b9dff8046a136db220dcff7130a04649451c754be386bca6b2cbea340f82cf6d60eca67ced9a0f3d36fef9b76bbc4fbd5ec7c17fdf173a4ed9f803b8bb21f992465d2c18dbce769e2e658c55b18813a7f0130d19e1a7139d1b026cb447585d1dddd41bc3704f8391596f868e92992303c84c5bbeae3e07b98c2903de1babae4ae8aaf422a39e4c4b296fe4c0877fad90f253965fb052f5ea83cdf87c37b03eef7fac1f5b43fe32ff46116c04e587fcf9b82ebeace8d0dfe8aeee6ab176a36052022a07d17951a30266f1f3246e5dea22d9831b10c005e29a1fa219deced3bb54986a731fda5bd724fe98669dc93793a59abab9d42d37ffdaf683901801f3ffe581df0327f8ca70dfd8e3cb6320930e02a35a2d2a709f238d7900aecd5d0d28e9060d98b254e22073f97742198ba37293ca360a7d52dbf4c4c735ede5951498870bfc33cfa8ea634b5f6656f8309053726098718b6d5a82711e10a9a0cf1773644d366b6a0f47ac614c80d38862bdf0294e5f24801db4ccf55108043021bc6e88c55dd5d7543637875043353c57bf6c5c3f9b8727a948b6f0566a8584907d4553a48b7c325fca6b814be8a6423922a887a68078517aee36f6d4b6edae8e15676116f9ca4a3172fda666492d8f24064b4807ad4d8c19b49c1f69961e0ade11e51934162005fdd40bdb3d197a217aa237737abef37adddb8ecf72c17c0b6943758d28d9bc921dce17e3b01a4bbe2687fa6009ee14f138649374656881ce5212582e41321b1d19477c90376b05e506b07badad00999d13d711c272206268c1b40867f79ee66b1d1bcba6a3b4f3d24135d256d0006143d71e3b80402267bf4611c2474e093fe858685682f12f7db1e7f40d0ee0f6f0759818713d9fe0ccdad7b12c1d71b77a5839485b0f878d3fb022656bdd7a1dd18e4ce566e5b3b5a96e8a460ade248329b5cdf2932a117d4c049bc0bfb091d02fc4fa240b4fdc79c4e14f6f949c2c45bc0ee59e46111865c40947f0b224eea538e1062a082f5b69379b29f02ab2a4402cae307d0007d142bd61a74916aa948e7e37527ea807d976a52cd6bac9e0f9c11d81b21fd4d2c1c9d31a50a90c78e8fd7f0a22910e24577ffa4f70fc638919dc07498b39f1e0c92c4d630ecc051c3ba50a80ba17e0fd351c10000667f700f51503d6bebd0eaa34979217d6769f38ae83866e7751fb4b80e0891a1232e1fc1a93977ebaad70164353890b50184b2e6e1bcb9c382d1b4452eed9cc67e48f0a8b70000a3d055e9b5887b333237df2202cbd98c1d0d6de9cd2e2fdc83e9902c6a83d00f96208b3074846fd27a10bf4733d34329dd13242669f5bf09c92bf529fa3c61e9948bedb8d4d5d7daf351956d1a6153a1e74967c43761433adab381bf474974e7ff15ac51a6fe8052b304aeb9325c9931431177820b7e302c22dd093d30dc2ae4d2ad4697dd799be020063f4471ddbf36d2d2b5ee866a7bbbfcacba6a9ead425c6ec35953c59895739593fc9b30abd08d3bae6ebde2923d910c502b807c4664a0ceafd34f7ae379f57122e9c46553edd77799d2a4cab4a1a53bd643384d23bba807797ba2a42afefcfa9301100892edbb0df020921b9379823dc8f74078f5ea6cda9c9cf33e9690807cbe6a4bcaf67b116ce0e8e3f93b6afbfa4206c0a689ffde4f300008caf2297c3d95acdb4d82b66ebd4c9c60fdb86016b447d26291de40cd706d4c1b350d4a358343499ffec874d24d4dea0b3e60c76f14a3980d38a65b33991cae1fac08231892baedc86c900421abab923fef9deb32e34753140dd4f5ec89f5fce381bed1c45c3231b501293126eef24b3d11c49a8b25655efe198a9318edd008058920ccebac9cc4e5f5f3a1148380ffe78c94455ef4d31acf616643a2ca54d5964fae0311af561992d1c9c6d599e6f9b092a871c8347944d2a20efc43489b2193ec4956bc3ce84597b07b8cc62e5758116b0825e2d5d2e8e173c860710f8e0906e1c9a8a6c8c20b64db72bba4a4b3d9424732f6ae14fc4905d294484a80aea4c801582139ed5b0bc3e056099d9730ceddafc2169c17512f07468652f657e1dc5548fbd5039aae752fd057cbb58e20c27824354154feffab36e95a7aacd04dcd59de5d0a12e3911529f414a995cea474e1dea9893d4a366c10635e60870674c51f2465dcd2c6945a8e1f9851bc11763a6b41807e2a82033c8ac2e7bbbe68cf32837bbbcef725618ee86357ea44b5e13129230f48087043a916a35476a2ca68ea8b7079dfe021899305dcd1b421ccd78a2729ea262f65cdf1aff44e9f7c7ea77e9beda2194233e495c33347275950e53266c9323d28c8b82c09f2f7f988eba44c22f0aa2ec0e3b008b13650301ce6c690e8d6c6e4ef74f2144d6bbe2f864880b22e627e2a8ae5bde24cf8da6242e22f7f4eb9fb0ac5311aebec24a915eaf5d4044614d921fd86988e35bee70dc20f3ccc7ad058b778164ee45f63a0ded2c15602c19636d9b6cf7001715ec14c7481ec472142cce425b6cf5e84249455642357c295231d476fbbd7b8b5572d018eb760914037fb67f4bfedd4cd44e9d9129e3408c18d69402ed14794a3364496161aa38034611a50e96c60f014f3537a409951c8d9185ba905893bc833f94aac14c69c938688328a5a10c79169f19a27096bd289e684d01253376e5ff7630124a12a6508ae64e84741f942bc9c7b8b9da902297b03ca7ef434af0c542f5de440e7025a0321efe03b28bcf8bf0d109acc30c705d43bd106e3e6f857df153e7d0325cf1ba65a38c2665f07935148ca894ed49d0656409842baa13a3d1fbfac38a8e4aef00940c761bebd96d00adff148d3d54f3403eb3bc4968703e255d877ada44fb591a6b24c4efbe349e1018893c29b67bf0f867b41d1d19dc5090d86e1700d33b2beb342d74716289a7de1fe74a412de9c2e123a49e79f40931e98e80e7076de1d6c6a6dc6680d363da0e11be1eb69666de18a8bef6a71a1eb5022130031bc7a03b60a91b304803e0eb1f5ad225c6f44c62809361800ff25394afb6c9ca5cb57d6fd565412c351719cc4e074d824b073e377e1ed818b149e5556e1e36ca42225cec492048c098f4c9fa73cf9dfd1249ada236d6f560a91da3d1060cc60e36efb09999bfc69d350510ed2cc4f4d9fe19895cf836f2a68f328375432cac6f160e6bf15c234e2ab12209e433aecaa73d503095f34d228d2182d684ae412becc7aae837d275783c592d0535cef1942da1b20a5a2e2a8d8fffaf0191ae4412e034b6774714d147d5927576e7a1ef24532ea74314b1232d01eca259237601cdbddddf8c83a761085f7b93c45dda136dcccf1319a2c2e50324cd3f3f755e0a2705d81f0529250a0d9839e18d5d782163730e9fb133c22f63a6cc026be7deeda80f207180ea9329cccea08c94a9612c8cda24a4d32f71ec2b852428eb8e822524e823f15e99db1ac1c46fa3c578829552050223da9168968193d4a4cf02e88fe0f4f44d608be1b76ea64a7692ef07afa162b28389c83bfec5c22451102945a371e53c990933a2564aabd4aa4758de86835149d461555367187f74f330c19a9167247844341779cdfc38eb0ff2ca3588a7682ce2e119037585d9d871b59ffbe9c1529c3f6c86bd5e4b3d9acabda43bb8b5cac239d78d5653d8f2dc76dbc8a5d2f527aab515e1906c11b703f5dc4f468d152a2031f5436a2038b49908dae8376fbb52aa2efe5e84b4f745c92ca2b6f29ea96055750b3f7bd147399d56f77396b5e7bc556c5accad8ecdb7658b2f5341f84989c17d4e063e417f9b676b0398b68df138e05944136fcdbd9af0b80d5d18fe23dc6a531b3aa47bd8f8c5979dc89d2163c31c858acc837ae634fccfcdfb6982ad4a129d3b549995b0457a3a3eee275103db6b12c7d9c3468d64592b3ad290323c411dd656b0368fb41a4543f5de83c514c97de2d3ca0a6b405e86a6f2dd0ace957fb1cbec5f406d6a39937610ac502959b657137e46e7f7c22d1abfa364b8146345b03ccc410f5bffd46400e700503705bc8c169c9f98f910d7bb04d0dc1cf6c7ed8bb1681b596bf07a9713b16d6a71bfae8a83d4698159ae1e4f2ae6947f028a0e350e027e2c8b25f4efb3592d785b3688c6c57a7a358bd721f795641366bccfa00952946d13ecc2fdf25cc88bca8558f2d2a6f1601cf43520da87b1ab2e2ebd4482f523d9d6c9fe2974593ac5d4f576ed05428d896d75e3e215454dd81a9189cb49b0e37be01d339b668286b56506db455873dab0a391e05482abe4560208c88359155f6b4776eff3c8b608a1cd74ffb3efa6bb5e433d2df8090075824c22a5e3de262b829c613ae0c68bccbb79201303821291116d8c3f6b9bbe67606c2949e4c3d02dfd538796fcd93ac0c0d0891a25dd687be5ec436b58b728a57ee0c31ce2fcfd63b983679d00b0f9e1a675017028e28276a4e8830eb8943c1ba7f1fde7cb48db84fb4ad852fc84dd48966d8a1d45f9b787db79b755544ff6392edcb7e84d31b505e50acc1649a13bc674320efbde372185e2884564ca615d0e53d057773daca5ae2a0f1f7d7e84200993d50fd1e0295e8510a72680b0cb366e878b20984217d1303d490f1524e9d4feff9da5caf7465895cd6c863c609a4b71fd44817548b732da8a70e881d645c99ed6e6262d1e989aec0218876e53a809e312f6da12d64593feaca68a80dedf05230b4eed5ca15ef2a1b312c0fe658be7583b2b7e035ef2d8c93c8a28b55058f60d15235f05859f04a6087a8ca400046050cab1b778236d5847030e82c4319306e13082a008e7c884433feadf8e590dbd60a3d4c584dbe9066e06238e497ef9485ce49fbd781b800a1342f82d8f93ab0dc239eea298d4758f69c1d6dd5183bbb4a1f6614cf6d8fa5d35ad93e4b1f511665aa864ad42f689338126a4cb6de9d49a774027a57f08f20f2ec71ad9798b2a9d50c131365ff3c0fb8e75c9f10d595c81078b406acc2883ef183c44d4be2a7055bb4b8548c5bde46e5f1713fda490d7ca165ab271926fff0324122cf1f49d504e58c9ec0b1a948077f249796b78e586d1c53c2c4f47d3632e38821485bfbb4b112a2a504ac15191da8987c6d80f0b8e989b2ccdd0c71c90d4e8f319c3cac9b0947abd0c46183221125f41db0d8c6299a3399e319c0b83af55fde1bf65b36951f8df3bc7fc411a73d641ca5cea935e0e0eb0245dabeac7d91536949878cf003877e7a93e36dd04b34e30b60a1312b57a07e83083857610cc5bb5f88d8682d51d63667ad212061f27ba70064042ec6c226219e2c40c327abc11a118b551a677001987aacdc1ba541184ceeb4aa9a318c35d48b57b97b3c40cf5cf1b6a193d43a67fb802a6d80f88f5c473b980b42a4958947406ab896b6a3649abd6c3aabfcc57a57063c6f5220f36f3ec3230d6a0b6592ff450c62eb59baea3e797780b70d5c5dcf311e0f1b91ac0be921bbcc6959bba5782557b5d9039dc8a96d0b387891cc1132efefc2c58d52774411e954a21ff7bb83890e857d73ae3f82da2efc54aba04aa8767ff92365d7756ba81909d08a3783215158e7f3390d41405fea3e84252f6d67324a5f486984dc52e3cfc91d2a0702467b52c5553279da45a14f0bb0ba4c05f6d032647dbb06c70cfbd5faf0361fb29171e870ce08ef797d79c7c221b861c87bad09fd7e66f02b0b261c3a6f870bba68e38ae8b4f892064612bd13701085faae254a6559f6a4aa4a4eb74163fbb1eadbeb2c6114923da67a81176a3af80fe7a45bd94bdb2a7c3a925323838ca322872009e87880a11cf1ac2c5e89ca5a040c83090abade086bce931d6f159d0232f22e7535af913d975d7e280c116b6009555a7b79450921d63b5b47fc25915d68acb5320d74a9f7ef195aef9ee1af33824028faf227eca703053efe661934033f89e464f1e44fa6209e397a10a0e65eb83b546b0ae8afbc89b9a553f472baf2e595cc27adc7bb1475480083bc51a6fd62347da5f3990da3181af81b974aff30641d59a0b8324c894d3288b032cda68432988fdd387787822a982c54e7abd688f2c50dc4a5c52a4dd35663c5a3f7591360957d963e999b024ef4db704e4a1db6e9734f1bb4f77719086f7f3b88962c7717383b510116e1f5a17168d6ed90a4c1332dd24f1314df29641f0b15d0cc875a9a050e99716cf95ef2a6ec3d6f0732d8e82a327d241819905a75d9b215a1108f2713c148c5e8ae8862f8cba62a816320723192fedc952200fedd100cb621189ea7841ca1b28f167c5880ca43cd8c0d45e2e362e4d3ebf0321b44f0f58107aeb9b03c4104d5b43beb5b1bf09ec784d78c816ebb91af8ba7d3c3e688802a0e55715a6d7338c32bc27e59a04e6b1cd6b3d6c25b77647bbb3a8e448c66aaf708380323c99493ef93a10a0d6346d77b3826acde152bbfafeef1fb8c359679a0ab7f03b6ed378b2d9f146693589cd8cafc7bb1ca4c85c22efd8586e87fe0861d9c4ec5d1400be2efb92cfb6bedc71478f8ed8d84e5108276c5b0313c9585551640052c82fd03a01c77a95c08f8a9a778cd0ee8136ea0a098c433af24b5929fbda28b1674946dc461cfdc8b55de3c28195c7f8e18a42b181c68cccf0c86ea4dd8d9ed748eb4b0c46ba7ea35d57db670b0bd69045463bacca8873d6b89a3718a27e50e211b3de9e6602ff41c2bf6b5ec2a28cd4684ad6eb5a7043a42ed69fe201c3f03d75c74b007e9e480c22d9953cf1dbad5d903fdf081f90a012abc3dc451df08c0c311559b0cc834245e27be9d68963b75962b64d01809c98149729838819c7302ceb11f7e35405819179b6cf9ca492d2c6c22d65786cf4e7fecf364dc3b9da7ac90d3ecb5e4094dfbcdd0ca640e8e0c4f368026b137406bbe6faeee3af9d28eb63cf150e5a961ae32b691e9ad9dc2f6715d0c924de4cd65e829cf413ab188f6d0ffc0c1fa52fa049d82603ae7527acba01df42b6968040925f3d9735c26d2749c0671b97aba24814a6e0f8073949d01ed7233ab33b741513d9cfc766a500172507a5751a43a36014c5b281b11e7cc60fe1eb80ff6ed3156b1a1440541a12042663d55b4a958ce2645023c04ea7e0a601afcf8e89ee4068aafc96b2d7a34fd5a6e8199d3500a71507bd56517125bdaabd98aa2341514b209849be10fe1761c0259260a3a62c6bc23e2766f230eb89c4416dea8b119fb08a5206e0c4945b1b019e88562af3a2b3f98dc0758a3865749f4736423ee1deddf10a78c2e59e15f3fb5044221da49429da88aa5620f7262fd83b93ada42f901a07a195521549e93e9449f3161f3603c44519741978ec77620dca6b2d705ac55d437f469b8118802530495292594a5b26e08627cdbabe334a1da5d8a306a7dc5617e430d3d69a6af6a7dbd7a155a9916caadcb16085d3a5c5e5172418bde4073283de88fbf2c41e4953892ce87ba4136cbdf6812331abd3a6a5ffd1f2295f609df56a88119617ce2b6f063368f716234e7089608f1f3e40aead8c476530be246eaa5338d5b951983cf3697378f792060c3ed080198843bef6fcedf12fc93a152edc1e96a3e3309ee4dfe99452099efac02008b2c421b9083ee1b05601e3f163432159b4e56f4bc656c88e5d376d5a5c07e67d1802a443e0c7d3b236d2936692298e4c09e28f6b9ab72ac63a00d475fc281f20fd397e8ee62fa503612495ca87c26dbb10480eeca05edbd89e121cccc893d7c1daa8bcd932a66efd4c9fd0ec9c5f8125195ea7cc4258fc68527cf58d394d2a4e6d7db8625d114206b2e692da5e26bd376a2ab2650933342f37d21c46b370e84342ee0712c74aae45285f1c45dd977190d871bb2b7bcade57fe4526fe0ec7ea70cef10470850c1f02bfe6cbc71395546ef3b4ca49d96711a0c18cf03df5807a50d41902a61ad6da49106f26781cd583a22282fd8f3d27c530eafc06172513d0057980c5f743c055bd19148d96c91174ffda48172000e3d58f75168ffa9a1b30a2f6a6b09aa579cb255743a1a8528bd931681a141bf77fcab5e02420a479260146c426845d27fea5f11ea843c093ff7917897de128a3d7055bef03b4bafb8ae0de47f1eeee04c8fde9790e850f5734db1527d9ccb98644a1ebb24506981f5a772fff08abbbf10825e1c781f678e580a03f19e8562b296de5ae1942a70f4c16b12c00f581200cf782040aa1d5e28bf6cea295c5911042ab5da8870a518502e9f91a06ca1f7c62b3d69a03559bea6cf48de561237250ed480d6a83e63bf736eb8c1f2f890f84c4d23c590b9e1f5d22a6d1a3567ea02a7a1264cd362a7742ed7b75e5956f1547c6fc5f5e9b289cdb5db19ddd724f4c2b422aad99bd4780163ce9614fd2c40af98acd55e233bf1cbf45e1c48fdb098284c4546733ea1a6a17b582cc59a52df74f9a38058d48fc586cb779717a2518db8140f1b5fa4d8e7ddad6f82e99d3a878a330dd7ab2883087a4dd366a5a4d7409104e4eb5494caa530db297c4464ccd20d0dd6a28efe441e8839a1823393bddd4b9580f4c71e047e6cc1c73462c4e10e9c0598c576f4439142ebd0c2341a12817368b722a626e1a9062d9021ba5e84dc310cd33738e9a2878a3f752268f23c90a01831d095dd5d1e4d03a9402599fac50008084df3d3dbb13f529d170a25073a2d33d1a379ce23d497ec704b23db3ddc041e82fda0d41230be360ff142bb3aafeb95f0ee7d02d26caf7869bbd5591b2aab7222c7170790671e812fffdfea1f149ab2d3fd33ea59e527686ec51022593f49475e44c05af370bac236af414efb1227f64e6ac50fa1bf194e3886f5d5878f070079cde34ae3e82e7629bafe670b869d8be8cbcd3c9000c9637578653cdfee304ea4d369738d7cd8e73226483bc8480ed429e4647459b103e41f81d7e2462cae1fe5570a5f148b75501b4a3e8c8d0d3eba9346466b8169d4c38b6b2438e284e3d35e0a75dc871373271df60ca2affbfc5ed68a4675a8093d37051818e2bcf86cd282d9711cfb5b0d56cf6f15f79a64986f1ba8314456d58acd4fba6c04f4bc516f627405aad29508683918cee498b63843bcb0dd325ab2f165ac0f4b10688ab410276c0c998c5d2c5fa55898f028b6960a1cf507ebf3a018e155e978f4de940b2b8a89c12f0f2c0d27d38635ec84b8166982e9c69b6168b83f5da40e872c2ada58b1d0d63aa1acbba36a28bbf627859bfc241b4a5e752681919defa33cf59d158ddd35de55382507501f5900c1a9b0a518301993e240d72ce07c0b51befea5a63c987b9899d18803d29c4199dd35502d6d071b67b862db7f33cdd5da8b89d4841fd602723e748da97c46eb606d465a5d3406682e14422d596af7aa33800446526d223f214086adc0a18742778a8bbc5c6ff1a61812ff03ee060374e296251717d90e714b2670c321c27fcbff4ed908dadb81210870d96db822faf82b45a913e0605b21b98103704d09dd62b1120fa5dd59ad693845ec3b7a1c1caccf12c7752491fc5e48db4640a5a9aea8242473d6461d8fce9bcfb772835b6bdb727ff1f692684703b72f0a102caf1b319da5b07a90c3dd01569b8b1470b9cdbf260f1aa57d1953d44771c958f6e03f421650a021ae0f91810454a760d9d8be02763665ce615949789ba5e47be726bd139be1434e45956f4420813138f81a889839986d23434c50b311c7db342f67a3e23462d7fce8366c7f7a8bccff9a61a90f6c1dfd1b15a98a9069c935dba93ea6f929d1b84b9a98c96b31df14147b579a683716e36e0ee6c6ba300aeb9e19f0cca2275c4f42c80b10627bf7b6226bc2d18d8be52b15fcb14d9838dd4d93cc56d81443ec625abefe9c15360101cf1ca43cb32973f12019387a67e190bb02c5192359f8629e59da40cf4323583c58903589c2d617b013f8ef0c7183be675afae307367d031d41e4dddd4cefc5daf2ab9343f4b6d002656f0460333d37e2a6a18a13bb824ab38440003a6a41970bd0eab8b32095ff3262b43888155d39843ccda4d651014fcecb08b8785769ce3452e4db2a89a2cd1b9187befe691e76d350475726c0d39af97aff2f487a7a16a1bfeca5998626663e5d7dd22f0c159a939246f7116633221cd811d43cdc1cbfbb688a0841abb892660bec8f67ba23b6579fe10ac72bc1526678c462d5aa8f939bb35fa6ddd4c7ef332c038f1bbf0ae5b94e26552bd6967a99a453db33ea176a41085be7af7081847d6a7fd9a3b0a54f20d69a5dd0817cc224a023e279dfae892a86a9cb731c8927556e56d18a57cbc28110d997ef467267f998029cca4765d59112ce4356d8c853705f3113363151a545a1931dcea69d0af9d17f9bd4d4c1af2f005f7ea634dd55543d79c2423b4fe40acccb956f2681962280d716acf4b85c0c68e9757ec0a86c591a780bed1732349ddf20723da28c707a59660ca8c8d35d22c58c0744b77cc2c5eef849da21c423060b8bbd4b421eb059fa8ddab29591c52b92e3eedd1d7743388ab5837f2f7a12016ac4e2a3440835d4c906254dd7887ae4378c85002fd4469235a551851b4def184e8febc0a5066c3c8c0cce710f720d6db0bb70c28ffe4c58f5c48af91611fc5b662b6b9c55f89eaf205433a7d81e500ece13fc6a4114e2ce32a57575279bfe1056804e89e431693218824cbcb37891ad7a951ea8a50ff076ba78902491f41509b4a9886528103c83205cc77151491472a5107d12cb6c89370cf7be75a0230cb25a61533db760d00b35c12961e77988e95a965e0dc8e62c61255ebdb36679b571d27b1ba8a4409a242e7bdb921476308720628a6d9a81ce3043b07894f6b1a887e2d23836f243661091b2d303fc38cdeb197cc0c700901880201fa97b0acff695bd503cd8b92ce66036aa34e60444a824cff17d35648f5ab28c67e15d9f3fabbed999bc9152f9632df56f4428925bbf34826055d29ccf9332de918c2b7d02298d070101e88062c4375d4ceadf0e5b4cbb3290e934d1e21d0afb886ea6c89f0d24a895aec87314f2c284a03c36683c8db74af996be0ac55a06f96c9182da9c0695ff929060340bf2a8870b96d45c69876e121a2f6e0fa497e3082d74609f40f5c12f80b42eba9615bbcd370f221991b84c6c4866f87ae1c22c91a2288944752ca292252ad4fc1417d5eefeed6f2f1ff5d2d06fea5722af90ac0941a35a346e2a356813f2d19ab5799a01e2db04677514295ae798a7d6d69061141c8e6e99b31f97f892b4176b65cabdb9aa987ce87a485b8f10584e6ab7496578147e9a4ad36f488e89a6996cf185e049df117f84153992cb14e64cab13ea0ae9d9d1f54293d02e98bae3ffafa1ff5ad68f52bbea466a57dd65a9844b901b8098470896cda5d09585b4ecdd38370cadc0044ae6c0242b137b1dedd6e849095dc56054164ecc6b829c60d8c0630b26e37be9d57e51261183b315280f10ac2e8ed8194e08378f4f62c6f2cc913a3b78a15f56ea7dcc19ab7cb11aab6688db7dd77c8e0ec4195828a951077fdfb8d55efa071d40d60c0266c8ad9aacac0e860ccfc1a00a3b5411603861b9c8e06cb389a362d74181c550174f316d033f3948e03d1cf6ab0f10d3dc9e55cfb0424209001f5ece0b60b0c539faad9e1969f4f8ceb6a4cd03614b0ba80750c9834716f1fad650537e08ddfd19a3c44837933bad64e02900205b8f21a1034e403183580cf0047d080966aeb070d80c05d8055fc8d892676001b000c00603780cf009f04c00860c304083fab5bbdf4a60c4c017423e00412c0b41a54a5d52400e3fc0d74c8bfd0bb5b232facf48ed3d8e74b5f66067bb803b6f13ba6d7c88417065a3108c843f083d160e40b95ca01ea2ed7823440b0a6d0013c0c3c0c3c0c3c0c5ce3f9d6d7ade768edef942431ba1a6827e1524a29a594223de81c2084103be7fff97ebfbfa902d907f6070f08690725eef31105b37b29c184941559117f40c118e2b3de8451eff41cc5c2c713cc7ad193329b770c1cfc190307e6c309987e5cd70493ec9c04252d763c3e98604ee1b3696f959e38a71408e16309c62cd141ce6cc8cef1ae071f4a305a3e592d157f2c9ce8071f4930690935ebb9326ba1334582e95252ebfe2e779d9244f83882a9434df47f59ebb6d6071f4630c859a8f3ea38103e8a50338c031f44308dd096a72de83a51f51a5b3b7ae8e88f2198fed4cbcac9fa174b8d31f8108261544c7553e5257d170c9394f392a978e2a6570a0ce309272c7acc3b49bdf60b93e7d49927df623e9e3070d8d8d183c718327c61344f39e54f6a2b5e2abd8c5e9844cb6a25e7e9c268890c5e98464c0a76f2177fde0943c62e8c26af9570d124a9da5464e8c2744b56d1d3ce2a2cc953a9c7e35cbe21231746ff344ad4f74fc174921e761a90810ba39954b297a0a153acb48c5b98ada4cc3c0dafd4e193610b731eb14e661627a955326a61f2f0649269d73268618a9dcff8303e3eb294310bb3fb7a95e9d5f9d0d61b64c8c2a87a524ae1a4cae972b13845f30ff61df4b0309dd2fea6444baf4d938c57184fb68b499264274a966040862b4c9df7fa04d339ad307fc9fed1d3447a529b15669f53f7a094a48c55984bd692206ac2281de20b64a8c2701546354c926fdaf4a9308bb49822724c54183b6c28e1645e324e5198311bb3e81537ab5e974b9243c7c6324c6110df2729295754f293529892f6f25cb1252b9e90c2242ccdfc65dfecf08fc270d29e4a49c9456110699e1d3b25399787c23c97a44b71b143ae091426d3104f7f3ace4ae713e6933b71c2fae62fc713a65c9e26c8be3b61362de2db942529754e98720eb2943857c9d49b60afaa82e84f13a6bcffbc26e34c9894f8f10495a398d0cca47a09a35e6528412d9fca9630e8c969bb6d258c2e3fa794495f9326254c4187f17463269330ccee884a53f25d4a269230ea25511d47ef93f025913099521925590e12a65c56723c282997d01e61903b6a7f2ad58d5a124718f4b43e9d0e76c16f84514cd0909f791b9e6784e9634bbfdb673925be08538baa1b9d3fb560528449bed22421bb545d50228cdaa5c449ad5d277f10d1a997c82a7d1fc21cbd52681fd910e6d8122f554f2a4985306e5a75a7bb8430ca29d5c9647310c6b7ebdaf34e10666ffb3cdf55200c17b767d4eeabe900c2e4a1e368a5c9c957fe0fcc9d14cae54ffc601275f4cfc4ef7d30256125e916b9fc39ee7c3007f9d14ce7f88d33f91e8c15fbc4be1bbb921fd783a94684577fe8eed1f13c98e4847bddaba0dfb3e3c1742996ffe27730ad5dbb09a6a176a61d4c4aa8dc7929f45509eb60de9382926eb64a38e9605ecbb5b06c97bbdc1c4c4a3a4988f970279ac8c1a0c3428b9668b1c48ac7c1241fed9420fb94d01338985573fffec4d2d6ff0d26214f29a9ee45c8d5dd60d2a10455f3e8f79e369874685a122a5c7653d960beb13fd551bc7428d7609a8f1355ab65754335987409b99e93584a83494f8ab278b2840693a03df409234f8963a53318eba2a7a59e24ec5a92194cefa74258f7787a923218e7439abe97c5bf09190cd796361f44b6bd640ce65872f405352784f8c560ba60267e522aa790a730182f5bf6d1affafe24040693fbdd9e9c04254a2ea12f98b2df04ed1af5d112f282c12dfafb894eab72a32e982cb363cbef7653445c488fb64b422831b40593a0da4fad4db84a29a405e3584e9daf93f0a1f45930c89dff2c172b9a9cc782d9d59374c943befa7405839988fdc9b2673bb282312d77924ab424ada9ab60fa12c495de9a0ae6b917f1499b4ed2ce53307c4e1fd12995f8269682a9a45c93c54be896380a064bbb8b22040553ec890f27447bddf80493c737ddf9ae4a949c602c3f13cd2698a29786a5774c309ae062297b909e2bb704cc367d4fac4a309eeec7f9bb68a64c82494cdcbcaeab749b21c1783973f2e4e5c8388249ed8ebc963cadb51c194630efcda893bed2896539328a6092a4e9294b52f4e42432886050a3e28b881cf9abcb1882e1e3e45cccce569ecb108249dce58427cf499ea46018a4f7ff0b0c837d2cf11efcd37ace2f8c2a4267110b9d43a87d61bafbb6ca1d64f5bd30c5ffba24a9122afde585512ba6e9fe6befbf0b83ba1c478dced942535d185cf6b4a85452ac0ee6c2603a69876db8308a4efdf59c5b98fc54d6468687b7660ba3474feb7755d7c224fde82c32a285795487725352b8cb496661d2c1d2c6f3ce49b12ccc37e22ce404d9ed3e1686b3589ee274099bc3c220f4ef2895674d8afd15e615133ae81f13d739ae30755676bf6fff24b6ad30772ab964a8cc0a53a5a4469488ab30a52c2d292fc99ec4855561125929a37549ba68920aa35caf5fcab925cb4785f9e38fd0e927aebe3cdd46c91426ebd89dc4f3c496a914664b39998a5b164a8a4861ce49f5b8856514e62877e1c754a94a220ae38b9a7cb35a695b87c2287ae62bf768fe6741618e134f5f12fd84b1ab2a7d9fe909639aea7851e276c2e8ed4199a0ae3d896e3961ac91a74fecd46ec2e41674a73c9f04a5a4ac26cc3fa23da98d8fa3cf8439e95e152549b25f8d0993d44f21b48d6a0b934b98374b16614ad23f556209735027a34c49e246f99530566e1325ccb722aad7838cfd6812c9d5d3d76a234918e5dd4d798f49b14291309828fa7f54d096d7030963770a2a49f289f549fc086358bb9f7a9533e93ac27c4adad55edd59b98d3049bbe76e33a6849032c29cffd946aaaec54a2ec2e0febd627efac5738a30ca4952be1c4f9ea8f70897fa0390401c4d6f0751d1b29f8a9b638000c2582aefdc89374268fd0773ce96e41d952a7f3adf0f06935a4a5d7ad4cb61f781eb1bf1bf9577663e184bfe2c196fc2df5f0db207ef666305d183c92d65bd4bd7a8ca5d0c903c583143b35b364d4eccd36e2dcc6f2b20783096091b13aa6b63f63b9854b4aae8a5630783862a39ac53b2374f1dcca19370a2443ba18349a54dabf39ffdbc923998c43e1ffb345f0ee6f512a5d29ccee7ebe360307dc14b4e7b23db7a38987449da643f97082bf91b4c624f922ee3c2d7e4b81b0c42fdd97eccef13a7b7c1247c925694a061f27dce068397346da277be06a3e7134bbaefb33f5f0d0631a632478a7cd4521accd676a26765f5a14683492e9a3ad3b94cb6f70c06f5592db1ae13623398f3a6cab699a90c0693a3bb841613194c928ef25d41bd09afa531184ffdc9ebe5b6973f480ce64e93a39e9996f5466130a5b7cd2c398bc0603c39e67bac74678287be609af9a4cc458ea5fbbd6094f72bd51beba57a174c57634aace209133d870ba6fb53f104d19d2d9882924bf25d123b5ad28239c9e1ed49ba593009b16db2d9974eda62c12cdac5ff42d6573058c92575a58d36616b2b9854903ba7e3d55530d728d550d28c0933a182b1b3533237957f2f998271e72df4faa36791b3144c52c4989c66657e238e82f9049d4695caa3c382180ae53c42d7e70e3fc134b2ae173c7e4996c34e309dd2b850d24cfe04b90926a957612df6ac7b7899604abb24c816d3ea22ef12cc72aa6fbd3642455b2518cf530537bf360926a14dccd55f07b71d09e6d141c7f8f4237447473075afe9bc9fd7a9648424c182cb7a968b60126c37cbe24a04b3c84ffb6b26c6877008e6d0957e3eec022204c3ebd6e5f07f52e58a06c3b8279624cdace4f709304cb1458d7c1142a537c95f98cdca64cf966447d7d31766af1af96aa7ed85e192b4f04a7dfaa14e5e18bfae454c4c55f12e7761ec8ffd961fd5e404e9c29c9e2fb989bd2a7184b930ee698fbef2e2c2746d1697f2939437f116263126773bd8f7990a6d610c21cbc774be3ad4b53077cad0727d1e2d0c72c6f34d9768412d370b83ecf8efb45f1606fd77f28aa5a4e39462616e4f23a363aa8921040bd38c25f17cafc54cf40ab3cca949f9aed159355718feaf4df010fab794d60a73cc6d1d153fde773356182e4893a4f36c15a6249ea0538c5559b25461f0ec3749d2df6f65b15418bf629d893f23c49aa0c27816f733b427c9ab730ad3a5b47c1bbfbc749529aacf2c314325298529ef8baab429290cef26261bca42f6390ab3b675125f574bc93951183c596ebf58589396f2110af3b5577c3e93e3f1c4a0c02ccaddd56cbd5b6a77eb74d19efeef2986f509738eda59d485889c9ce409e3edc917c353ef9d907d74c2b81ba74e7ab4110782f0c109f3cbed89ebf7697c6cc214ad3cbd25b14c658feaa0797c68c2a4d53e868750eae02313bd882569720972b37fc684eba32b7c6c470f1d2af8b84463e1ea96532d87a9b95262a97c58c2fc712b9e57bcb596be125d4acbe5d932ab3626e7248e49e6f7a54309b3e5afefe0bda224c1a4043709834ac2a513f4b58285d18724cc9fb7ddedd329d9a316095336a52de24cee54ad41c2acb95a8236d1418e0dcc98a1831c3b763cc2d449c5b7f41f39c274f2ec535777b7aad208f3574cb7f1bf15752646987392dba3259f1791cb55d2d0b88b1996623c34dcc40e2ac224b8af9b203fa7e42c4972e4d87182fd4884c95ed4a93229f98108c36f9f1f8730f89d204fc50aa194e83f0c61fe12f36527555db2f2a310c6ef1cf34bc172d092f3374ac707218c8b154d0fabb97255b113ccb7e349167d54878f4118e4f4a2f6292567e28230896fa90b23af6239121c20f01b366a6ca03f8cb3234709c47361b1244180e82bd42b57726b77b38c933fbaa4dc395efa87b4f98ac8d8ca127ff8c118150b57ae26b35561f1266acec3dd3e982d9af8f14e4e92e7fcf8605049e7c547e85b2fa98f3d98c4ea512abb4f2ce5c10f3d342e17aa2a2ff6ed7177a9e375aad11ed4e4230f262d8b66294a6337b71abe1df8c043e12597cba2d858c534b11096a319669feb5363abc71824f8b883b1ec3fe46a44344e1f7630c7ca3127e2d48f3a9842f9c8f24aba3b76f8830ec62a49ea0b4a18535b610d3ee6600ad76d29d4a40ff6b90f3998b284b90bdaf4e249ef8c19336618e1230ee66c294f57ec7b25e13463c6071ccc7e29dd9e8eece30da62f1fb1112d9d92ea74f03868ecc84183af4af0e106e3ff0979627e66e0c3383d76f0b7818f3698932cb22e559e70fc0d1a651ff8608361c4590a775dfa588396dc92b65655a59075395ecca5b3bc7da8c194e5c23f7ccdbedc30709c1d34c2c06103078ea383070d1e1f863f8de47cb991157880151f69c0e42f39e89e4c878e31d060d84e9f2749debbdec91a5b63e44066232bf0c0c8c806f4e30c06edffb691d122754b3ecc60ce95b23932f5aa44fb288351f445e75162f44106730ad224a527989ccef9630ca67dbfd1694d9254f9470c66f7b065c2a4647f2f62c147188c97a289a72c7786b6ea0230984adcb6baf224ce5f8e828f2f18e45592e2eb89b4d3563be1c30ba6243f6f6c581e2db9526ff8e882613d99dcce2bf767d206870f2e1833e4c9a126ed3b7c6cc1187fbea2c4934a87875a308d87379342294910530e7080e0230b061de16ebfd69546893f0e1b485ff08105839c69e71c36962ffb7ef8b882a94c095a64ad6be3c30ae6dbef18a1ada7f151853b84923b3fcd9863c7c360071f54b093cc4b62e51f533049a54b4ab92431c7ec04c187144eb5ac9a6bbb55d7b6701d2ffd4905c5e77061ca273dfe244977eba86f61ca25c52f496ad11606f7d0b9905ad48c9341082d92ff1d2dca24d1dfb32d0899453b26590ab26ced1059a815e642ec3454eb11120b53ce1dd49d9a9674490f0b735cd9f9794c0d0ff11546132fd47c74dd1526f93ba33cf67469dd0a535d09aaee2c07396f6285b1c289b990ed49535f85a9d39e19a20ae3493929e121324ab6c42c15e6d455d6a26da1c29462d65f2729482d71b15398c2c9ebb015948aa6aa105398dcc35ecaa642568e2c0821a5b024612cf7a70a434861581195ceeec4360a5352b9f55f2aa46cbb386c88c04461dcdff6248b89436112ef04b7a42a080a9312ed444b3c15f289d45286ab5938ab0e7ba2583469a142e5104f98459ebefc4f8574c2645be2c949744608e184f14c993ccacd5494e89910b209934939cb7a1acba5cc3484104d9873daab9a328f1e3d1b9209a3a74fa753e63dd9a84908c184419d246749a7e55efd2e075684904b9894250f3a4992247d67962196309dae2bcbb9a34eb256092195f8530ad313a6e2a8242194307cbe1b4b569690499865823cc19388fe2435d62e5112c5fb71dbd3193f514148241a0b63224f87d297ce98711d48c14808248c971d2e89d031f41aa3a810f288104758238c3fb204bb390b268811269525e9134b3da997fc228cbae529ffe69e4ffb8a40e775f6309127c2e827f524fbcb0d2f1d11c7c79ab193acc4123e8730c8e97c268fde9d2cd910c6f11cb7ac745b08c3879f54d92a27a16212c26862a8adead5d67c39086d4b5ce6ecc55a642cf69fee1c4255770a8608c26c3aab7607ff0261d49a11f15a6db12d0384c1e40af224f1938358f5076385366d69dbf6b3789a10217e30aba7f8f2f173dc5fb40fa6f825c8533ba2b653e483d12ebee5917659b5b2903d18f5d7c41e371384d059881e8cbf1e642937c1903c984def739e8dce0a21783009b1aa25c7b2ffef0bb983497293933841ce322f84d8c19c923aff749e13520753b849f2103a98620927a712543a9f8fcec1ecefe14e6c8b399db435089183c95bad545e6a7130a53b21e39354214f2c040ec6d0495fbbd628491aa5d91b8c19524c99baa05a2deb066327f96a3fc3444ec415d20683ef080d71b3a5b22b216c306927d9d36e864a42275983b92baaec9acc0fa3be1acc96d4934ab23e8871531a4ca946cc47cd216830dd08adf55f2d3a49ea0b42ce601ced7e2a2a25412f95cc6052aacba429a1933c250c2983c1aa738a21e5e75f7464405e8cf668aa9f9031e05a29bba56c51c44a784a32e24674d44843c4608aba15c404f7f1fe4f4818cce947b665930d018361d7ff2aed3743d7215f3096484f57fd952c8478c16075da54cec489ef215d3027396d891274554eeac3a3c78ed3830b215bd05cf4ca35b6ea03215a308952b1e39ebf44ff1c94e3461834b290d7b8ca579ab94a1571d3bf930f9fbe4357b6460816cc3dba99b3179bd1b80a41c8154c2a0955d57cb93ef9b30b8458c1bcbf2b1e4f90f3383768f4b07143078f2a9435438dbc68294577f4d01142057309b1bbcfb9732153309ca97ca9aeae102998ccc2b5bced8d42cdb84108144cad97c6eb52ce134c722571ecafde102718be66733e6f7fa8d6168534c1a04f3839776a2931d7618279fc92eae53e331159d220640926d9f3a1cbc55b6d4f214a30e99c26ce93ae2428690b49426b5a17342eca993c0841822967e90e2d7e6249b9137204d3f6e9efe9f4c97d6f231877c752921d6d48110c7ef679eab9654d5ede104204832a49f4097ea295b62443307db0f825951294d025294408c691f9de41a4de499e06c31497e3faebc97b2b190830cc27e8523274bcbfb9342201e417260f911bbb5ff263b22fcce14ccafb26fe62548e2a01a417a6ef58d994b47ce9629fa3070e10e8008417461f11794a5b8a2727a50820bb309c58ed32513e29af18882e4c5771a30439392280e4024b92ccf738429d2063105c18c73d9e495ddf964a89b7c8aa54e3345c2c59ea38958297a8f6bbd5d802b1855984560bd1b561e9ffd5c2a0e3c7e9b47dd1465e470b93c88b9793eefb3dd7406661d22ba6faad67f4a94a16c6d82cd737214f1880c4c294040f272549e8d3d6d50c1626792b564949ca4fdd89d92bccbf254b3c48d35bf936738549437eb9dba5dbed492b0c9626774ac92e472b64c60a73f897abbd3e377523b35598f57310a2d5bd4ac8d54c152679134bea9b89af6162960a9370e2796ce8070415e624bfc98f18bbca25687a8ae4ddafdfae3d99294cf26ee9cb546baac8ad1426e9fa263444849da09f91c21c2f9a45fd241ac8284c4a4e3a5cdc7509168e1c3868f0b0917602105198644f0f73bab4160a735dac581a1e355098cfa48a8b26a8f3bdd2d9274c29c5b6927457630bc413869737c1d2e809d1f22b4827ccef216f4c5a09c300c209b37f9026d7bf6fc2b463515d4c9bec713588260c7b8214d169843893520a4826ccf527e57ed6aba40b6a010413a61637f14b3ae9a4da12904b982a5bf8d8ef23318058c2f826963e25722e904a18fbadf35dfeb5e74a054209837c124d89a694a4a56d9049dc0c1b8048c22443f49b9c252e5ad82361fabeabbc2749f96dfd06ec00010209d3cee5a0f353d8401e61d41262d2bbed07e20853c8dc3f1d726c4e0c0290461847472f25ff89ff1bed09788030c29c4f6a4f5a44946cdcd03186bfb3f1281a802cc21c3be9fb562f134e30591045984fd835fdef265e73ccba0348224cd257fecbd1d4aa29291e078208539d5227bf2759c3a3c90ce410267162cddacf9c8536952a22003184b92fda8f98930352087334659a974b929dd20b03841026bf9297f91326df618219800cc2242f9f43cb6f9f5b09441099e76c6b4a0575053d76f014c011860d1e0890000f0a8c21c6022420001e9fd058c0040010812b0a74a1c059b10fbcd46f291d021f35c376463da00001e001a280bf0200d083c718292040003e8c33461838ce0d040880c78e04900000010000000010801e8f2307ef0e5840e16143c7514000a600001e3cd00c0208e0f4383ea30001383d8ee7d831e30000184003129043078d1ba4d383070d1a0b0040001870001ee8486c381b3d3c87186b381b3d6ed4e07168d048c0881a8e060d048ca4e1002368381b3d76d4e07183068d048c9ca1c7f330c3d9e891031b3e060d1a09182983c9b3992457298fe95dd558b61ac34a8cdf412307369c86db48af8347570f1c36503042061d6224315e0c038c8cc1bc9b27c4096f37f1a462309bb01fb7848b9a1d71188cee1ef645994e8c1763c16092aa92d6116fa9b1c5031d498c1743c578318e070e1b3d76fc0d1b3ac4c89176e40ba6d1b3101beaa1afca821b38c108463a908291a4c488174e3a4ae5f841940875170c6665e2c8d8d1e94a1de1026e9d31abde36562e33baa45d2721b760640be69284b56f440bc60c17af0a9ec2716e9ce03d4709f846b260b814973df74b4e1dec112c144be65db36bdbcd4eb647e592ea7c3472057392c73ce84a1e5f4bc73746ac6016659e92144bce74f69b878e1c348a0546aa60ce50ed9e4eba54b58e50c170561b7fc27c4ee71b998279fe7d4d47a78611299894bcf03433ebd2255f63cb711c1a370e8e1c367ae830218c44c120a4e577499b56f1af1a5b3410c708144ce723b74d99b81ce61d7982716bdf459a2478d610d6d8e2d183c7b96183112798e2f29c94f474895a413a0e8d34c128fa74a835417bea737520f60813eacd92b4a834d904234b30e8a86d5ab4f439164edf8200b0614409869f984f5adaabb14930dfefc938d549fe068e20c1943adf65cb3f97ca317204635adf870971219f276963c4084653e269d26a8923871862e448b763a4082651c52449b493437cdfac1e23443055f0a46228cf2677ba39928d1b2a28c18c1958f53710b2816364086b865d14adb7945e56733e09268feedcc9c134178c08c1b4268709f924dddff3c1306c8925ad7cf94d3e2930ee17e70beb85713bfd8ec577797157eaca35de6e2e10447661aea4db292bc58df83d76f03872c7f700c187b1e34970b6e37bd88881882e8ce7e3234afc7361126d948916bf22828b625bd585b1b80fad1c6fb153df97a0c82d4c29579b269e059db3a9d8c270278e67d1e1a980482d0c278f8e594aa5446861babf249d05197d71723366f44064162641b73f4475598c8bfd7760c68cff444416f7a8d26d7210db4d0c91587cc9b28497304aeb8db0c85714e3dc2c5db6657dcaa9e8295b769ea144c415c68b93a54aec562c1666b35b52c60a738ea23eae45ab30991c2f09f14a1566adb313256696223ea930a73a75b5a163e2374685e9d49dd0414c1539859aa2586f69ddeb62dd46aeaade4b5fde1887b50e3152294c923c275dbe0bf2cac222a430ede5b44ada844661123f2aef99077b0822a2b84c79de4b5e29e6a138ed5db5553ebdd5eadba432614c752e583a0d22a0308ebcfc96e2820a26743e614c8fd39a5b6f3254f584b1c49f9ca2d949274c9e67f15f4d7ecd5d38616a0f95f2f373c72cbf09b3f7c73f978f8a68c2d8a52e5fcb059344a7ad325159fd5a8ce9efdc20820993b4fde3e9e3a7289f8b5cc2a42bc5a69e783a5db4452c613ee1a64afdd6a99d0a0a2295f02c9f1c954f3ea184e1933c39096f5f641226397792fd61469412a3240ce2c3c2c4fe4e295347c2e096f26795f85d1b870d310e032290302753e9f36e071942076b6ca13178d407441ec1e558d6b5b095c4ca11e6ddcd38f1ebbf46894720d208e32853da675fe6800823cc675e492999265eb61b10598439d78cac3b39bab6e478280f118828025b99b9d8bb1d9e4822106187484398445df6c5925f3abc45245208dd82ac9c86b9cb7fb8944afa94dee0ac60c60c1e3a10218441277b0da54af62494a441a062365f4c33114158200c103543e40fa6ce7d523b67dd633f3f88f4c120973b9cff9bf41f2d1f8ca6d645a86c0b99aa8aec813d254917644e28a2879a9107a3d9a7a6c9b888e0a166dca16688d8c12464e814174a523da1235207c36d8978c79be73d5d840ea6ac2d8f75520adae2273287a25a52734d8fabf2d2db6f4ace39fb81881ccc5e3f7ba2584e1c0c77297bf8fc92f327d34e88c0c1e069e939999cfdecf71b0c63fa544584d22344dc60ee247f295326ff4aceb7c1f8d13e9ae4494e7d26890da69071a2e5f01ec6b65c83417b4394ac927bbc53226a30a82be975563b5c55940653579ad026762268304995af929cef14de22720693601aa3e2fff4fa5a1133183da9e977749ffd938994c1e815445f6c5bc45b4c840c06a56bf6667b72c91e14198341ed54cecad68d888b8818cc151e94389efe832ea148184cebb16747276b4f118a80c120444bfa6c62fc24c1abb1b5c3c639c10ce385c81750c40b6653e275267fbea7ff2e98c4eb7a64a80f9de7e482f12ab769f5e86dc19ca3d9dbd5cf5a3096248dbf999b1474b6ee44b260b4b012edfe743706112c987f3f870b3aa75425555410b982299cf5779908f11743112b98f3a5934b954ae17d4aee0a225530fdc9b194d62d45a9d64e840aeb029129e00a44a4c02712851c8840e1449e20e204f397503a89a74b978834c16062a92457feb024ffcf04e37caefff6297592682f61eb7ab358e9b2b2aacbcc84d7b80a0b6a8250125182792dd689d059bbdcfa960006345e240926399f827caabde7d24490600cfbd11eaa2a89095fe40866af18c2bb543ca95ec4085b5769758759eaeaff134c3495b24410298229089d648ad40abdc610218249ecaa1615334a16f3880ca16a20220483bade4e6241683df107c370491e5f0bcf4e25cdc030f7ab79325d82a7c7d22f4c9eb72dfb9b094a5f6787105f9834b782078fafb8257c17d20b93b01e2b27e9730e2214c20b73955e2f314b7b1247c62508d985e1badac364ac07b5d6efd061ba307c9253ab0ea273ccabb145c3719c5c983f458b078871a8f4ed6582d26024148a43226128208a104f0f00931308000044220c8662b158a449a3f4011480024c261c32322622241a14101e22161e0a85014118100a0302614018100a85c3a070d0a267580fadbb6178dbb1c37adb02394b7c9cde185a7d963e5d2b34c7bc89fc6322a28baf3e8d50aa991681a6822d1151e9cc396e3837bfdc36b9c225bf4c50e701000a9626f4c3498aedb3c1e488a0d2820805b37b05690a04911e9ec69fced579a558bb777bd2cb23e9f72d3f952f3ff2bb03ee51945c8773df1bd0b80c366ab21edf08000d47f1380a5b238c7038407ccc650d11e30167499daec01714f88cf4f0367ba75d1f2062f40ba017adf6d97dbaccef8b6033057b1ef9a4aa5f2ca16c5940383753b011a8a6c305f5b70bf9a9ec83bec73f870315d4e0ef2c069e367a528481a64c3be0abaf4704852c6d22095078f2de1c7a2b343bfd5c18c46b8995dcdbec66802011f646d90988c7a0e461cd1650304d91fe81b70ce944aba17853eb89bc44a0b2ff64f956e7b494e5437f1577877354f46218311aafde88f2a2cffa2b1162b16b29481d03b8eb091e6aeaac49ac4e206908e74ea804bf5edb8894cce267f8286ddb1921d6e803e899b8b3c2d9c33bd47cfd648f752899c3eb4c35ed41719b7894eeeb6ae0e87d7ad979d02fd711e42376b30020c239a0e8da27ce8d235e4950f94d58f578696ca2f4777749611cf927a6248b4ae3d3f7605b499b3314da3a10bf8183436770acdf671461aa03323b904b6d703d42936cb966210007dbe53bb4eff483e3c2ca01f7d1832c4471e2af29c62398aac06fc1b1913e8a31ee63546c15e8e27dd121fab20267831e1313a3d35f8dd92cd4467f18042e5c12c3288243b75f9d6ec8d08076a3f98021c54874ce60dbc1f445ed7ced00732c932493a336adace633f5c0ae214aaa81b58a683f159f299686732c8e45532f04d65a4c5777e5b805ec02c2511ab4ab4af93d7d45e6adc01c895fa7c4103c682d3aa4b5a4083618b871124f09f29d6ede468a410f669c8165c68093a7680907f284b92ca774135b38d7c2f10fce13bea8a087c2998c87de88bf10253b5722e43b8bee00fcab193f6e84764e6a8ecceb78e24a7d66b1edceaafa9e1aacc157d5fadc0cc064b4a699fe5795131851333b016c7078608da25390dd2ae55b02ff695a92e7eaa2eef789179256be8e097a5b220a80d393045220f822187a4befa0f40cdd8857d1a230dda6c72ac9526e37f98a690bdaa85c8a27fa6da58c07293d52cf4d0239f0112979ac4877cf254541135e5acc16670184a95e801c46404bbe300c53b2ef6f031107464e2679a672d918c5fc4c302f3dc97ac7339aca74d715b1926f6ebf96a087b7c4a625a4745e9415263a80a668e7c322ae7ad288916ae3fa57d4fcc09917ab9d4da42dc0d0168853bb51ec323ae066cb82b5e1c2e10ce85d4d5b31f76b46f087154d86c708cc3923e88f9bf272a29df96bca47a0338b94793282815c0e50b9273c35bd7a04774907e6f0aa22633cf015fe7cf2c3cf95754b5e078684bc9d05cc3053618e12fa619d928625a4b8558a087408f1923f7b128f7463b195a3c5b027d9b0655e6ddfe5acff0686f549d1c647d42175ed441d479dc51b0041dbef9a1e7a2433c71ba3d43ca395b530a5306b69c495d9f86c858bb41bc0252161448e1f6789462984b186821dfb0f9529e490550a5a219c9a8b412e5d99865c0c36a3f052d1f4a2d2c2d00a7c33306da16e54ffac78991a839d5e0eb24f6c14275ced08ca46e138ccd6ac5ee9e450e71b79f766974277d7444a72dd8e62af682a76a04226a516a2e8fe4e5f140ef781218d59ecaffa78461ab147b664d114846e3e00862634de05a2a2ac442e99fb27d92354e93b68772c79e7ad74d4391d0b837355d36713f90ec04f625f67dd62a65b2e356958d3d32606cdef3a098a01e1d2972307a583ad53b7c5043025d9c713ae3db5f597520d3f2d8497f1b76dda5409e8b5f7da64fcebfba194a7a1654ba65499a06f3bf75be1d63a264924f7acbb89604ea2f0b20b246cbb78a524d6f7766ac11d793ea155e449758fa1039aeee3a1a2448107ddfd8efe155c8f8942e155e69eb2ba51eebb4cf2f0ed53b0e344245f8f1069e9efeacbe078badfd1575160852de3f653817ba3282082a635ba887f34a2b92f78795948ae8cb4f9033a37d48127e1cf5d4d9fc0684ee9bc04691f403644e542d74085265339303425db13491f1eaf9836b4597d17ecdb9be30536d9d914904ff6a3508d89004acd05f272e90604b15f650399a51cc12dc6fa7fad7c236556cb9879cca0c6a52a5d5ae544f19b0afd918c530558f52c5eee9734325a8cfb4068cfec78d8ea7fcf429f6669f398d9edbcaa6b70679a4dc7e4bb7463443954ad82ff5c97f77fb226a3f659efad59f480b0ae9fa75416101cb1f011377d1ba5c94eea905232b75c195f4ee5a2367a358d8210cfa29b4c1a6a75044598067e7242bc4a638da7185cce74b02b2d50f903c1f7f24d250fbca2303e53d8622187fa9cbac41bc5951862b29f6b856b7ec55a9b363bcdbeacd62dd9204fef165bd6e9d7bf4a0b4a37a5c79be4b70a8f81d7f173c5e8c381e5965011e1de6dfe027d79928503e6df5dd050f6d403336d5ae8c6c37ea31ddc0edd4080eb7fd57a7140df752187aef60aa784c76b1f331d555bc48e571d8a46b1bb2a079164e3a34566c67e8d548ca40701c03985fc826b37133bebf57718b34794bdc750bc5807ce3d7f847794e20de83bfb6e06069a903b47b328e6b167d9f144ee07659a0d58b44d3df36ca4d9477b034e550ea2a1957b7a29e16d47319f9e67b11a096ad3f61151346d1ee12523178d4a379b7de89036ebb63ac1e0bcd12f95ad5d2b836c5b6b046759cdff97efe9fa9ae79c49ec721352b6c0c4bf20f53874abfa3ac4fe0a061b40ac0411b7f124242c3076aa9485c8c44e35461e0d8a3f9f2eca8e01c88dfb44a08254dd6b78c72d2896177a9a04473dc8195a9a18434080b6c92dc6cf652c5b37f19ca7d09e801263d24c6e04182370d4ad87b346048143deb1c170540e34ce1bf3f060502b9aa6eba40e3b812da546d710b1ac8691192d7ab63566a6191c0fb761fe468c3250b49a0a072a299aa9108958d7d3c4d18e18215313b9c33cbe8f9d16cc3040fd8fd210035a4e0671cacfc1c8017735c7e9e176e5ee8c2e59ecb29295e4759731c9c9319d91072c1df89f5368f66331a884059df0732c5e6c683ecb4227d122642c9ea310050f7de004cab1d9700ebc136cab505c86d519e104e2a838e6927ef152d3e601de3cca255e189e7708e1d63c44a00ec38f96c8a6958edc64d77f7b988004a714a9bf24b2b9732233aece33fe34dcf99f1a6d18c52d4125e2535cb825e22ab4428de5ae1356efb7399fc57a759adfc2a12f2887186aaa3d55703885754e60b0a41e4a33f628ff2ee043cabd46c0b9c81e1b28185c9089596a82094e8f212363d6e67843949e2e28aed49026e4b9c2426a72758d3a1ead4d9906f67ca55e42741255ff684656d8a33903fc611f55e76a63a4e6c873cb916ea332523d30bea17b8032ccfd2941f60eef8e94e59d1cb22f7d100172525720c89fe4f8bbe4a71d7b50923296957de27302b9579762cd21b6c029548117efe4268c17458fa2cbed57e6390a97b84b4e7479169832a9c29c62761699469dd889c7022079dbf297304fe83aaa0f30419d9116135bb83240ca0c579f85928a9566a65827ceb369582a6cb1db835e766c2a8cfe4c9251dbb4e41b4b864075da597f76897115890cc3a7689e5d74aeb1525e56b33618d076b577cfc2ddc94cad4e169b4f50101a8f0f5f40ac0a9d6a7eb7bc6bf0bd2f5d9da07cfb960e4d0852569489240b4f09a8aa1a251cc647b0b8fc3286d15eb754c92520be4382bf8ce388a3ced7a6f9c007d7ef2f6608124388ecb4d1912ebcdba3ec49868cd08fea37243c338e5ace326b077d3e1abc0dc770c5fd85e690e6541c977ff728ff07afd9ead5f06213d59a90f1834402d3129a2b466754f0319cd82cb91771b2b984be9df7ef3dbf6386d1fe84a0cc26d19e420ec279c142791004c2d86d73f7b37ba5540e3ab0b5262f50f422435cbd447db64e4822516b61444b8450fdba4cbfaff11aa167f9871820d82bdeea36c98bb31026bb755db96a6914d353971d479c9ca082adb8f2760706722bc3942b405a8ed22afd5787d320415ad711f51893a15311c92acd37296f2115aa086860793b73f41714463ba1000168604ca6cea42ae33fc3584dd11eaa0dbaaaa57606a3b06b7fcc69c1ec5e40642a490cc98e437b9594de0a7ac3e54a911c3e7d7a8aeac4de3b98f25d0d5256c16635b1cf2021410efa0e2a28f6fadea44f2053056045530bfa0381a16e0093d11e0f2e4dfc0ccccfa0b9a18948c583211016a2368041145c45c22b7e0cbae79b74fa5d15e3f5fea8c1d6edc52212bc47920149981f88f9fa029ec7e4f7f57a9f79fb8faa1376a3c7a4d4d6f310f46dc1e8700f7e2572e1b5f66cd32032cdb1aa0932a5f299510c8abcbded06fc0d2187a20b0a69727a22395006fc28987f4702110db43af5fcc861ddf604c1af4cd8191eef8fc7f0e184007cd891e6818e8ad3da682c52d4fcf909283241cc9c2eeceb2b001692a03a8a03c1e3d9339c1cefa19df252124868c43b45abb596ce15fb30929a32778a852e0e73091b4b6be0a0a06dae92c6779cead8d29203928ef34ed08927c48443918e31d4d0e384b7dadf6b8b86ffa61c665ae02044054b73ad3498cc074838bd4f9d853549a9bb79fe7e968d252218cb4c23cd441d98d6df1cc4f96a2d43e41542a57dd7b09f23a3d09d04896099b62062d8b882ba542b58b8f09942f07a807902c813e2658f93e08534213913ae74506465ca884170ade341baf923d50593eeee85db6c92c1dfa6eb2c2bfad6558273f43e76e34094cdf5f57ac3cf25a29198c293f2d04dcaad689683526d52e1dbf4879230e104d36d744a2124e3d0c861555ef227e2da049a809ec59e57b0f246b639bf5e18c8e1455e2a2b52fe76407c116ea9a99c9112129b144111a2cbab537aaf734127ff383202d89a83f6b0f1c000cd1ed1ac7efda099604fb0cf08dc1c22139e71865278d909cf1f4c17be71d4ece128914f2991fffe1899f7750e1e1bb0b60c5c83233d5c306bab6ac47717a85e1045d2c963b48a8a5b0f2e87f4d114d5c144b38e3264a68f6fc54db14343bbc20a373f7cc1904394f5dfafeba315065c855ce3239cf9933e7816877f0596ef639a7f0c02cb660ff8d15451146d587a300b5d0348e6b909889a40037abc08ca9e187d22a69ce65e82c3dd7ee0a081fda1dea8bcf859b84e5a08bfd194e1800e3043638405cc0c8fefc08316cd3f1b2bb0c30ab7660489c0cf10d8af90a558125992f4f49772538085a9015e950783c724f9bc0c6dc141c10222402323436bab0838f694a7e25b6c3d32d0955bb2e15a9c0156f397125e2a0c3cebd4d9be8fc1fa46109cfa258400f6db118de897ddd190c47a2ae845db5fc17d680ab633ce5baff830079bc36bc729bbfa44aa750e58c7caf285d2965128c8a2b86bb4b0d0141e25cddc809d99c062c3f4682082ab36b9e07b7ef6769b43ce7682485c1d8005aeee5f2bf8d3456e6e53e6810f9e34a01cffda649be2f8149a6b11c3b31150c70669c98d817019105b2df0ee495503de90884b68a3890541caad273e1f7e21716b769f085da06553069f8f43cf990935a0288e19e6e57a16fdc654c33262e404fae5b0603c6fc0708c7480a34ef32ef69ef5173cf186bb08542a42184fae16c136ff0e5e69a489feeca4d46ee9451a14a0fa544cc542ad05f8f4522bc0377c9ecfd8ca8c8af277bc10b9fa30e307aa20eaa142227632bbac354546087b195da01154116dbe97ffa8ab2fa280c7d6efbbfd45142a99723965646a05de598f8d1ae882ec936ca4965a3534a457fd6818b19226d94890e963408aba412b2057c4eaa2e25c0f49837c117d5e3a0cbf056c4a425f3039c38ab075d35694199913ddf924a2f415b6164b1f8e7729e06e5dd25c027911c3c66a7c9a2822fafeaca452babb3377790ba07a2a3fb5b67e7065852edfea8bf8d59a00a558190833fe86cd5f672ad3a376a54dd1ff4461227e12c4ccb80e705b164d2b92a301ed42b788b140069ee36aad84a265e81f90e8ba52f269f39ca8cbaa9e6df03d3bba788e03c74655a5a027d5e672275315f0950f14316f0d0b54994ff5a110b7b45ac73c5f15944a8412f19d965ae11d3f9c54625d059a72a5c1b0ece3374003c3a399be93bbe800095863f3bedd3112d1b0273e1e22b060b756d2132001b8dee62796a94d9573446cd8cb11f9403274cb450826a418b318ff57fcc164c3007d64864f57b0af30b929294a377c8ad0177c60892a17752996c43fa0c961187d37da4b0c7f27f41a5f840eb534085d21dda6f4a8be45cb2fa65a7fafe169e6fe92c0ee636bee73911349bc83497e2761fa5a91a4c196c7a5e7438f8efd643fba6ed2922d0179f7be993e67c5c37c8cbc915f53842e54b47b9ce66d27ec51526bf387ce0ffbc54baf4a11d0cd21a255dd63ba0fc18a8579c8334e358395c6b328493fafbddc0a63997108a5ee92b439e14dcffedc300af295a80d6551120db6f65c43515207149858f3baea232beb7ce0319244d5363be8a5a549deed62c00d6e5319c261664fe4f22b081e014c33586aecbeabdbf28a4a79560e2dbae39b218995139ada74cea4a2ebf2ba33169f0da8562f05f4505bc82cb1046f3c21a30f1354c81bb6d3a13ae4729f0fcb29eaa625e92153e967b606d4feddedefe5ade4f85bc1431b9bb776907de760441fb171f3110a07dae43f658b5cc80e5ad04bf71276daaf4166ede3efda24774b223e8aa1fe6451a801a09ebbf9d345382b4b58183f921cd872d79dc5cffad7aa2c64e9be2e1ef616277b47ad3f20d8a0e982a23146a1b581317cdb14c39f138802e5ef3fbfe941e6938104fcd5542c16ee011faf1d23aabc08d96d3ac1f166d9582d5ca0b771111433fca98fa4d51d33ea7bc749f96214d69e891ff53785f8607c07131c6d332d1560b44639648999417b25be8b35927a989d0cccf270ea6f3ef7ed925b2ed620468e864c4750358928cd9a630688ee316edf6f4d91f93de8bee2f0d0cfb04ccd3dacd54ae155083d5718959d76ff7ff0baf9d77779b4b143ac5eaf6f2469e6694534d5e244c4f34c713eec840ffde37525793dfc92981c385bc0a4221a5cd5e24d2038417cde48ab0bb8833a1fde5b78137dbac6da9d9ce3e8178a983cf5f83854dfe6285539bea80e079150e4790fa6aed2c57ee67bdbc2b989c1ce3689adc00dfe30920e217122f7416370b4fa4098909a6383e72ed548e51a8590cc8b7f0a08985debac750dd418b305cf44223476ff20efd44577aa059f6480760329206636f641bf2a6a704abfa389f74d277727bfa137720dbf82e7c5787b905f48f00a0097f45c269a9f10e7172849b291db14b4bdbc8a04407adce888b86eaa6803dfb17907d96caaf15f15d03315be7f03cbc6461b0c69cee52f7fdaf8b6df853ef9ab314f2f1b7acb384ded7800c5d1806355227d174d9f94f1c403b72bbe518935b3978eee366786138997f1c66a5bda76f490b2cf8443d25ed35a44be9ba7c9d77779fe7882e2df36d03f6a69fd48e20c9203da64289ad22bc601d0315eae295b9d297df9d29f0ca1d34c1bc1592011acebb5110bfefb460ac360cf25246446e81901c163c76c92c5a0cfe8b0e181ba3694ee90345e25368922bfcfe54413051c8d3dec33e3ce3202e157d92f3b61f924fde5c565201582e294f392fcbe516efcc210e43d387c49eaa6d988776136938b7de0622d3de5e6e803f1a491e0bda0d5f9be99d403163cfe4c8023d5c4dc569b44ea4b9460ecfaf6dff31f568b81102d94e877460d0b5f2f1d01701a175c521eb915e1799a14e757eae00158d96f1fa5854ea4f43a2dd176d116302666f2248cfd40f5b87434d2e6f1d2e59748bf50f289aa329855cf63887846470d5cef5f7dc8084cec2cd9ad48178532b67cbed9ca1bc556184c5949087838e5de5c647a8754be3b61d12ab9515b122ef6b0492bb9c032b7afb9cf4d5dcd716c63c7a2cf94a7c86849973167308c254169ac96c36d425629dbb758a6d8aa1213b2263bae6bf467062bfe4afc47e9842ed211c4b0da286cf7df0ab0005430a64fb13250e1af038216e694c69f03d05d24587428a9c0ca15549310460e92ea9c3f6964d823ba41374844488824c82da28df83fa20d22d3d4733507e6ca9c74533c403e17968ba44bec4765c38655d641956bc42946edd7a2728a937b34a7d5b081d63c826d735050292e23915e685eeb8ff2831e69426ca841f34936559e3cb0517db97ab4986e5a351dfaae94c37b5dcd4efa399953cd9405f25f78a73c13e4b96268c2a39255edc64eda895db5f1a97c72932e0928faa18e918e3c5d148f67781acff094781f1a56c1ccf8f05ffe51df6155ee869d8bcc6db54905d91e5ca619239412489670f80dbb009cd0d6c6f059e053f4469c799cc70993224aa30949e27650ec575bd83be4596afe56c13464c391c129889655760323146d5a73cde09e62884cd45971ed40c429d24232348fac613cb2c4a938254c695a82fbcb39f4f15b17b0bf1a685d38199c52b4d1397f834888be27efef31897d980d49a4b43cd973d4790a9e26eb6ef9a930ce90d3d4731113cdc95410c315bd71c16c3b088d4261f5d47d6a27358b58897fbbfe7832f28b368826f07f41d6f1dff8f33fff177ff4afffc937e7d7292323 \ No newline at end of file From f604611c52324d7a35c335e0f4deaa14d8b4b8f4 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Thu, 7 Dec 2023 20:56:11 +0100 Subject: [PATCH 41/44] progressing --- package.json | 1 + src/views/runtime-upgrade/ConsoleOutput.css | 11 ++++ src/views/runtime-upgrade/RuntimeUpgrade.js | 69 +++++++++++++++------ 3 files changed, 62 insertions(+), 19 deletions(-) create mode 100644 src/views/runtime-upgrade/ConsoleOutput.css diff --git a/package.json b/package.json index 179cb83c..5adcd863 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "prop-types": "^15.8.1", "react": "^18.2.0", "react-app-polyfill": "^3.0.0", + "react-console-emulator": "^5.0.2", "react-dom": "^18.2.0", "react-redux": "^8.1.1", "react-router-dom": "^6.14.0", diff --git a/src/views/runtime-upgrade/ConsoleOutput.css b/src/views/runtime-upgrade/ConsoleOutput.css new file mode 100644 index 00000000..1c2df4fb --- /dev/null +++ b/src/views/runtime-upgrade/ConsoleOutput.css @@ -0,0 +1,11 @@ +.console-output { + background-color: black; + color: limegreen; + font-family: 'Courier New', monospace; + padding: 10px; + white-space: pre-wrap; /* To ensure formatting of multi-line text */ + overflow-y: auto; /* Add scroll for overflow */ + height: 300px; /* Adjust as needed */ + border-radius: 5px; + margin: 10px 0; +} \ No newline at end of file diff --git a/src/views/runtime-upgrade/RuntimeUpgrade.js b/src/views/runtime-upgrade/RuntimeUpgrade.js index b1fc53f4..131961db 100644 --- a/src/views/runtime-upgrade/RuntimeUpgrade.js +++ b/src/views/runtime-upgrade/RuntimeUpgrade.js @@ -1,21 +1,21 @@ import React, {useState, useEffect} from 'react' +import './ConsoleOutput.css'; import { createTestPairs } from '@polkadot/keyring' import { ChopsticksProvider, setStorage, setup } from '@acala-network/chopsticks-core' import { IdbDatabase } from '@acala-network/chopsticks-db/browser' import { ApiPromise } from '@polkadot/api' import { useLocalStorageContext } from '../../contexts/LocalStorageContext' +import { useApiContextPara } from '../../contexts/ConnectParaContext' const RuntimeUpgrade = () => { const {network} = useLocalStorageContext(); - const [dryRunLoading, setDryRunLoading] = useState(false) + const {paraID, paraHeadInfo} = useApiContextPara(); const [chainLoading, setChainLoading] = useState(false) + const [blocks, setBlocks] = useState([]) const [config, setConfig] = useState({ endpoint: 'ws://127.0.0.1:50877', block: 10, }) - const [blocks, setBlocks] = useState([]) - const [bobBalance, setBobBalance] = useState('') - const [transferDisabled, setTransferDisabled] = useState(false) const [chopsticksApi, setChopsticksApi] = useState(null) const [chain, setChain] = useState(null) const [fileContent, setFileContent] = useState(''); @@ -23,7 +23,8 @@ const RuntimeUpgrade = () => { const { alice, bob } = createTestPairs() const [runtimeVersions, setRuntimeVersions] = useState([]) - + const [lines, setLines] = useState([]); + const handleFileChange = (event) => { const file = event.target.files[0]; @@ -47,16 +48,16 @@ const RuntimeUpgrade = () => { reader.readAsText(file); }; - useEffect(() => { - setupChain() - },[]) - const setupChain = async () => { + + const setupChain = async (providedChain) => { + + const endpoint = network?.paras?.[paraID]?.[0]?.wsUri; setChainLoading(true) const chain = await setup({ - endpoint: config.endpoint, - block: config.block, + endpoint, + block: paraHeadInfo[0].head, mockSignatureHost: true, db: new IdbDatabase('cache'), }) @@ -71,7 +72,7 @@ const RuntimeUpgrade = () => { let spec = {runtime: specVersion.toJSON().specVersion, block:chain.head.number} setRuntimeVersions([spec]) - console.log('specVersion', specVersion.toJSON().specVersion) + setChainLoading(false) setBlocks([{ number: chain.head.number, hash: chain.head.hash }]) @@ -85,34 +86,64 @@ const RuntimeUpgrade = () => { const runtimeUpgrade = async () => { const runtime = fileContent - // expect(await chain.head.runtimeVersion).toEqual(expect.objectContaining({ specVersion: 1000 })) + setLines((old) => [...old,`Executing Runtime upgrade to Spec version 1010`]) await chopsticksApi.tx.sudo.sudoUncheckedWeight(chopsticksApi.tx.system.setCode(runtime), (0,0)).signAndSend(alice) - await chain.newBlock({ count: 3 }) - - await chopsticksApi.tx.balances.transferKeepAlive(bob.address, 1e12).signAndSend(alice) + setLines((old) => [...old,`Runtime upgrade to Spec version 1010 executed`]) + await chain.newBlock() + setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) await chain.newBlock() + setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) + await chain.newBlock() + setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) await disconnect() await setupChain(chain) + let specVersion = await chopsticksApi.rpc.state.getRuntimeVersion() + setLines((old) => [...old,`Spec Version (Runtime Version): ${specVersion.toJSON().specVersion}`]) + + await chopsticksApi.tx.balances.transferKeepAlive(bob.address, 1e12).signAndSend(alice) + setLines((old) => [...old,`Alice transfers 1 Token to Bob`]) + await chain.newBlock() + setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) let bob_balance = await chopsticksApi.query.system.account(bob.address) + setLines((old) => [...old,`Bob balance: ${bob_balance.data.free}`]) - let specVersion = await chopsticksApi.rpc.state.getRuntimeVersion() - let spec = {runtime:specVersion.toJSON().specVersion, block:chain.head.number} - setRuntimeVersions((old) => [...old,spec]) + setLines((old) => [...old,`Executing new pallet call DoSomething`]) await chopsticksApi.tx.newPallet.doSomething(10).signAndSend(alice) + + setLines((old) => [...old,`New pallet call DoSomething executed`]) + let storage_value = await chopsticksApi.query.newPallet.something() + console.log('storage_value',storage_value) + } + const fork = async () => { + const api =await setupChain() + setLines((old) => [...old, `Forking ParaId: ${paraID} from last block ${paraHeadInfo[0].head}...`]) + let specVersion = await api.rpc.state.getRuntimeVersion() + setLines((old) => [...old,`Spec Version (Runtime Version): ${specVersion.toJSON().specVersion}`]) + + + } return ( <> <h1> Runtime Upgrade </h1> + <button onClick={fork}>Fork</button> + <button onClick={runtimeUpgrade}>Runtime Upgrade</button> <input type="file" onChange={handleFileChange} /> {loading && <p>Loading file...</p>} {runtimeVersions.map(({runtime,block}) => <p>number: {runtime}, block: {block}</p>)} + {lines.length > 0 && <div className="console-output"> + {lines.map((line, index) => ( + <div key={index}>{line}</div> + ))} + </div>} + </> ) From 56f3244c3e14ca11810f5984655967d4e7d78996 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Thu, 7 Dec 2023 21:47:12 +0100 Subject: [PATCH 42/44] gd progress --- src/views/configurator/submit.js | 1 + src/views/runtime-upgrade/RuntimeUpgrade.js | 69 ++++++++++++++------- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/views/configurator/submit.js b/src/views/configurator/submit.js index 805a4886..2699d5f7 100644 --- a/src/views/configurator/submit.js +++ b/src/views/configurator/submit.js @@ -28,6 +28,7 @@ const submit = async ({setStateStatus,localStorageContext, configurationContext} if (data.result === 'OK') { localStorageContext.setNetwork(data.network); localStorageContext.setCoretime({...coretime, scheduled: false, lastBlock: null}); + localStorageContext.setRuntime(jsonData); configurationContext.restartForm(); setStateStatus({executing: 'success', status: 'success', message: 'Configuration Submitted'}); } else { diff --git a/src/views/runtime-upgrade/RuntimeUpgrade.js b/src/views/runtime-upgrade/RuntimeUpgrade.js index 131961db..fe97f180 100644 --- a/src/views/runtime-upgrade/RuntimeUpgrade.js +++ b/src/views/runtime-upgrade/RuntimeUpgrade.js @@ -51,8 +51,7 @@ const RuntimeUpgrade = () => { - const setupChain = async (providedChain) => { - + const setupChain = async () => { const endpoint = network?.paras?.[paraID]?.[0]?.wsUri; setChainLoading(true) const chain = await setup({ @@ -73,7 +72,6 @@ const RuntimeUpgrade = () => { let spec = {runtime: specVersion.toJSON().specVersion, block:chain.head.number} setRuntimeVersions([spec]) - setChainLoading(false) setBlocks([{ number: chain.head.number, hash: chain.head.hash }]) return api @@ -84,45 +82,69 @@ const RuntimeUpgrade = () => { } const runtimeUpgrade = async () => { - const runtime = fileContent - - setLines((old) => [...old,`Executing Runtime upgrade to Spec version 1010`]) - await chopsticksApi.tx.sudo.sudoUncheckedWeight(chopsticksApi.tx.system.setCode(runtime), (0,0)).signAndSend(alice) - setLines((old) => [...old,`Runtime upgrade to Spec version 1010 executed`]) + const runtime = fileContent + let bob_balance = await chopsticksApi.query.system.account(bob.address) + setLines((old) => [...old,`Bob balance before runtime upgrade: ${bob_balance.data.free}`]) + setLines((old) => [...old,`Calling missing pallet DoSomething before runtime upgrade:`]) + try { + await chopsticksApi.tx.newPallet.doSomething(10).signAndSend(alice) + } catch(e){ + setLines((old) => [...old,` ${e.message}}`]) + } + + setLines((old) => [...old,`-------------`,`Executing Runtime upgrade to Spec version 1010...`]) + let res = await chopsticksApi.tx.sudo.sudoUncheckedWeight(chopsticksApi.tx.system.setCode(runtime), (0,0)).signAndSend(alice) + setLines((old) => [...old,`Runtime upgrade to Spec version 1010 executed ${res.toHex()}`]) + setLines((old) => [...old,`Executing 4 blocks...`]) await chain.newBlock() - setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) await chain.newBlock() - setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) + await chain.newBlock() setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) + + +/* const call = chopsticksApi.tx.balances.transferKeepAlive(bob.address, 1e12) + const tx = chopsticksApi.createType('Call', call); + console.log('tx',tx.toHex()) + const humanTx = tx.toHuman(); + +const { outcome, storageDiff } = await chain.dryRunExtrinsic({ + call: tx.toHex(), + address: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', + console.log('outcome',outcome.toHuman()) +}) */ + + + - await disconnect() - await setupChain(chain) let specVersion = await chopsticksApi.rpc.state.getRuntimeVersion() - setLines((old) => [...old,`Spec Version (Runtime Version): ${specVersion.toJSON().specVersion}`]) + setLines((old) => [...old,`-------------`,`Spec Version (Runtime Version): ${specVersion.toJSON().specVersion}`]) + - await chopsticksApi.tx.balances.transferKeepAlive(bob.address, 1e12).signAndSend(alice) - setLines((old) => [...old,`Alice transfers 1 Token to Bob`]) + res = await chopsticksApi.tx.balances.transferKeepAlive(bob.address, 1e12).signAndSend(alice) + setLines((old) => [...old,`Alice transfers 1 Token to Bob / Hash: ${res.toHex()}`]) await chain.newBlock() setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) - let bob_balance = await chopsticksApi.query.system.account(bob.address) - setLines((old) => [...old,`Bob balance: ${bob_balance.data.free}`]) - - setLines((old) => [...old,`Executing new pallet call DoSomething`]) - await chopsticksApi.tx.newPallet.doSomething(10).signAndSend(alice) + bob_balance = await chopsticksApi.query.system.account(bob.address) + setLines((old) => [...old,`Bob balance after: ${bob_balance.data.free}`]) + setLines((old) => [...old,`-------------`,`Executing new pallet call DoSomething`]) + res = await chopsticksApi.tx.newPallet.doSomething(10).signAndSend(alice) - setLines((old) => [...old,`New pallet call DoSomething executed`]) + setLines((old) => [...old,`New pallet call DoSomething(10) executed: ${res.toHex()}`]) + await chain.newBlock() + setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) let storage_value = await chopsticksApi.query.newPallet.something() - console.log('storage_value',storage_value) + setLines((old) => [...old,`Querying storage value of new pallet: ${storage_value.value}`]) } const fork = async () => { + setLines([]) const api =await setupChain() setLines((old) => [...old, `Forking ParaId: ${paraID} from last block ${paraHeadInfo[0].head}...`]) let specVersion = await api.rpc.state.getRuntimeVersion() - setLines((old) => [...old,`Spec Version (Runtime Version): ${specVersion.toJSON().specVersion}`]) + setLines((old) => [...old,`-------------`,`Spec Version (Runtime Version): ${specVersion.toJSON().specVersion}`]) } @@ -137,7 +159,6 @@ const RuntimeUpgrade = () => { <button onClick={runtimeUpgrade}>Runtime Upgrade</button> <input type="file" onChange={handleFileChange} /> {loading && <p>Loading file...</p>} - {runtimeVersions.map(({runtime,block}) => <p>number: {runtime}, block: {block}</p>)} {lines.length > 0 && <div className="console-output"> {lines.map((line, index) => ( <div key={index}>{line}</div> From 80ef041f45f085b98a2e8619ccb49783ef86ac67 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Thu, 7 Dec 2023 23:16:03 +0100 Subject: [PATCH 43/44] WIP --- src/contexts/ConnectParaContext.js | 15 ++++- src/views/runtime-upgrade/ConsoleOutput.css | 2 +- src/views/runtime-upgrade/RuntimeUpgrade.js | 72 +++++++++++---------- 3 files changed, 53 insertions(+), 36 deletions(-) diff --git a/src/contexts/ConnectParaContext.js b/src/contexts/ConnectParaContext.js index 6a716159..b101795e 100644 --- a/src/contexts/ConnectParaContext.js +++ b/src/contexts/ConnectParaContext.js @@ -13,6 +13,7 @@ export function ApiConnectPara ({ children }) { const [provider, setProvider] = useState(null); const [paraID, setParaID] = useState(null); const [paraHeadInfo, setParaHeadInfo] = useState([]) + const [tokenSymbol, setTokenSymbol] = useState(null); useEffect(() =>{ const startApi = async (wsUri) => { @@ -46,7 +47,17 @@ export function ApiConnectPara ({ children }) { }) } }, [api]); - + + + useEffect(() => { + const getSymbol = async () => { + const tokenSymbol = await api.registry.chainTokens; + setTokenSymbol(tokenSymbol[0]); + } + if(api){ + getSymbol() + } + }, [isReady, api]); useApiSubscription(getNewParaHeads, isReady); @@ -78,7 +89,7 @@ export function ApiConnectPara ({ children }) { } return ( - <ApiContextPara.Provider value={{api, isReady, paraID, paraHeadInfo}}> + <ApiContextPara.Provider value={{api, isReady, paraID, paraHeadInfo,tokenSymbol}}> { children } </ApiContextPara.Provider> ); diff --git a/src/views/runtime-upgrade/ConsoleOutput.css b/src/views/runtime-upgrade/ConsoleOutput.css index 1c2df4fb..2263c009 100644 --- a/src/views/runtime-upgrade/ConsoleOutput.css +++ b/src/views/runtime-upgrade/ConsoleOutput.css @@ -5,7 +5,7 @@ padding: 10px; white-space: pre-wrap; /* To ensure formatting of multi-line text */ overflow-y: auto; /* Add scroll for overflow */ - height: 300px; /* Adjust as needed */ + height: 600px; /* Adjust as needed */ border-radius: 5px; margin: 10px 0; } \ No newline at end of file diff --git a/src/views/runtime-upgrade/RuntimeUpgrade.js b/src/views/runtime-upgrade/RuntimeUpgrade.js index fe97f180..cb631d6e 100644 --- a/src/views/runtime-upgrade/RuntimeUpgrade.js +++ b/src/views/runtime-upgrade/RuntimeUpgrade.js @@ -1,4 +1,5 @@ import React, {useState, useEffect} from 'react' +import { CButton } from '@coreui/react' import './ConsoleOutput.css'; import { createTestPairs } from '@polkadot/keyring' import { ChopsticksProvider, setStorage, setup } from '@acala-network/chopsticks-core' @@ -6,10 +7,14 @@ import { IdbDatabase } from '@acala-network/chopsticks-db/browser' import { ApiPromise } from '@polkadot/api' import { useLocalStorageContext } from '../../contexts/LocalStorageContext' import { useApiContextPara } from '../../contexts/ConnectParaContext' +import runtime_path from './devnet.wasm' +import { cilCloudDownload} from '@coreui/icons' +import CIcon from '@coreui/icons-react' + const RuntimeUpgrade = () => { const {network} = useLocalStorageContext(); - const {paraID, paraHeadInfo} = useApiContextPara(); + const {paraID, paraHeadInfo, tokenSymbol} = useApiContextPara(); const [chainLoading, setChainLoading] = useState(false) const [blocks, setBlocks] = useState([]) const [config, setConfig] = useState({ @@ -22,8 +27,16 @@ const RuntimeUpgrade = () => { const [loading, setLoading] = useState(false); const { alice, bob } = createTestPairs() const [runtimeVersions, setRuntimeVersions] = useState([]) - + const [enableRuntimeUpgrade, setEnableRuntimeUpgrade] = useState(true) const [lines, setLines] = useState([]); + const [runtime, setRuntime] = useState(null); + + useEffect(() => { + fetch(runtime_path) + .then(response => response.text()) + .then(text => setRuntime(text)) + .catch(error => console.error('Error loading WASM text:', error)); +}, []); const handleFileChange = (event) => { @@ -77,12 +90,10 @@ const RuntimeUpgrade = () => { return api } - const disconnect = async () => { - await chopsticksApi.disconnect() - } + const runtimeUpgrade = async () => { - const runtime = fileContent + setEnableRuntimeUpgrade(true); let bob_balance = await chopsticksApi.query.system.account(bob.address) setLines((old) => [...old,`Bob balance before runtime upgrade: ${bob_balance.data.free}`]) setLines((old) => [...old,`Calling missing pallet DoSomething before runtime upgrade:`]) @@ -98,32 +109,18 @@ const RuntimeUpgrade = () => { setLines((old) => [...old,`Executing 4 blocks...`]) await chain.newBlock() await chain.newBlock() - await chain.newBlock() setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) -/* const call = chopsticksApi.tx.balances.transferKeepAlive(bob.address, 1e12) - const tx = chopsticksApi.createType('Call', call); - console.log('tx',tx.toHex()) - const humanTx = tx.toHuman(); - -const { outcome, storageDiff } = await chain.dryRunExtrinsic({ - call: tx.toHex(), - address: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', - console.log('outcome',outcome.toHuman()) -}) */ - - - - - let specVersion = await chopsticksApi.rpc.state.getRuntimeVersion() setLines((old) => [...old,`-------------`,`Spec Version (Runtime Version): ${specVersion.toJSON().specVersion}`]) - res = await chopsticksApi.tx.balances.transferKeepAlive(bob.address, 1e12).signAndSend(alice) - setLines((old) => [...old,`Alice transfers 1 Token to Bob / Hash: ${res.toHex()}`]) + + + + setLines((old) => [...old,`Alice transfers 1 ${tokenSymbol} to Bob / Hash: ${res.toHex()}`]) await chain.newBlock() setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) bob_balance = await chopsticksApi.query.system.account(bob.address) @@ -136,6 +133,7 @@ const { outcome, storageDiff } = await chain.dryRunExtrinsic({ setLines((old) => [...old,`Block ${chain.head.number} / Hash: ${chain.head.hash} executed`]) let storage_value = await chopsticksApi.query.newPallet.something() setLines((old) => [...old,`Querying storage value of new pallet: ${storage_value.value}`]) + setLines((old) => [...old,`---------`,`Dry Runtime upgrade to Spec version 1011 SUCCESSFUL`]) } @@ -144,21 +142,29 @@ const { outcome, storageDiff } = await chain.dryRunExtrinsic({ const api =await setupChain() setLines((old) => [...old, `Forking ParaId: ${paraID} from last block ${paraHeadInfo[0].head}...`]) let specVersion = await api.rpc.state.getRuntimeVersion() - setLines((old) => [...old,`-------------`,`Spec Version (Runtime Version): ${specVersion.toJSON().specVersion}`]) - - + setLines((old) => [...old,`-------------`,`Spec Version (Runtime Version): ${specVersion.toJSON().specVersion}`]) + setEnableRuntimeUpgrade(false); } + return ( <> <h1> - Runtime Upgrade + Runtime Upgrade Dry-Run </h1> - <button onClick={fork}>Fork</button> - - <button onClick={runtimeUpgrade}>Runtime Upgrade</button> - <input type="file" onChange={handleFileChange} /> - {loading && <p>Loading file...</p>} + <br /> + + <p>This tool contains already a newer version of a runtime for the <strong>Extended Parachain Template</strong> (This new runtime can be downloaded).</p> + <p>This new runtime upgrades the spec version <strong>1000</strong> to <strong>1010</strong> and it adds a new pallet called <strong>NewPallet.</strong></p> + <p className='mt-2'><strong>Fork Button:</strong> Forks the chain from the last best block registered and show the spec version for that block.</p> + <p className='mt-2'><strong>Dry-Run Runtime Upgrade:</strong> Performs the runtime upgrade and a few validations.</p> + + + <CButton className='fw-light' onClick={() => fork()} color="success" >Fork</CButton> + <CButton className='fw-light' disabled={enableRuntimeUpgrade} onClick={() => runtimeUpgrade()} color="success" style={{marginLeft: '10px'} } >Dry-Run Runtime Upgrade</CButton> + <CButton color="link" className='text-nowrap pe-1 d-inline-flex' > + <CIcon onClick={() => exportWasm()} className='me-2 text-dark' size='lg' icon={cilCloudDownload}/> + </CButton> {lines.length > 0 && <div className="console-output"> {lines.map((line, index) => ( <div key={index}>{line}</div> From 3b81a55d7f9f15909812b76b585b047c50354837 Mon Sep 17 00:00:00 2001 From: Hector Bulgarini <hbulgarini@gmail.com> Date: Thu, 7 Dec 2023 23:18:14 +0100 Subject: [PATCH 44/44] READY --- src/views/runtime-upgrade/RuntimeUpgrade.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/views/runtime-upgrade/RuntimeUpgrade.js b/src/views/runtime-upgrade/RuntimeUpgrade.js index cb631d6e..534cdf72 100644 --- a/src/views/runtime-upgrade/RuntimeUpgrade.js +++ b/src/views/runtime-upgrade/RuntimeUpgrade.js @@ -146,6 +146,24 @@ const RuntimeUpgrade = () => { setEnableRuntimeUpgrade(false); } + const exportWasm = () => { + // Create a Blob from the WASM content + const blob = new Blob([runtime], { type: 'text/plain;charset=utf-8' }); + // Create a URL for the Blob + const url = URL.createObjectURL(blob); + + // Create a temporary anchor element and trigger download + const a = document.createElement('a'); + a.href = url; + a.download = 'devnet-1010.wasm'; // Set the file name for download + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + + // Clean up the URL + URL.revokeObjectURL(url); +}; + return ( <>