From 3196092ee320e9f5b83165a7416c5fb7dedcf032 Mon Sep 17 00:00:00 2001 From: Charly0475 Date: Wed, 3 Jul 2024 14:10:14 +0200 Subject: [PATCH] crud --- test/Charly/01-begin/01-begin/.gitignore | 7 + test/Charly/01-begin/01-begin/config.php.ini | 26 +++ .../01-begin/01-begin/controller/README.md | 3 + .../model/Abstract/AbstractMapping.php | 44 ++++ .../01-begin/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 16 ++ .../model/Interface/InterfaceSlugManager.php | 8 + .../01-begin/model/Interface/README.md | 9 + .../01-begin/model/Mapping/MappingTag.php | 49 +++++ test/Charly/01-begin/01-begin/model/README.md | 1 + .../01-begin/01-begin/model/Trait/README.md | 24 ++ .../01-begin/model/Trait/TraitSlugify.php | 40 ++++ .../Charly/01-begin/01-begin/public/README.md | 2 + .../Charly/01-begin/01-begin/public/index.php | 51 +++++ test/Charly/01-begin/01-begin/view/README.md | 2 + test/Charly/01-begin/02-mapping/.gitignore | 7 + .../Charly/01-begin/02-mapping/config.php.ini | 26 +++ .../01-begin/02-mapping/controller/README.md | 3 + .../model/Abstract/AbstractMapping.php | 40 ++++ .../02-mapping/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 28 +++ .../model/Interface/InterfaceSlugManager.php | 25 +++ .../02-mapping/model/Interface/README.md | 9 + .../model/Mapping/ExempleMapping.php | 118 ++++++++++ .../01-begin/02-mapping/model/OurPDO.php | 50 +++++ .../01-begin/02-mapping/model/README.md | 1 + .../01-begin/02-mapping/model/Trait/README.md | 24 ++ .../02-mapping/model/Trait/TraitDateTime.php | 35 +++ .../02-mapping/model/Trait/TraitSlugify.php | 40 ++++ .../01-begin/02-mapping/public/README.md | 2 + .../01-begin/02-mapping/public/index.php | 59 +++++ .../Charly/01-begin/02-mapping/view/README.md | 2 + .../Charly/01-begin/03-test-mapping/index.php | 207 ++++++++++++++++++ test/Charly/01-begin/04-manager/.gitignore | 11 + .../Charly/01-begin/04-manager/config.php.ini | 26 +++ .../01-begin/04-manager/controller/README.md | 3 + .../model/Abstract/AbstractMapping.php | 42 ++++ .../04-manager/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 16 ++ .../model/Interface/InterfaceSlugManager.php | 6 + .../04-manager/model/Interface/README.md | 9 + .../model/Manager/CommentManager.php | 165 ++++++++++++++ .../model/Mapping/ArticleMapping.php | 124 +++++++++++ .../model/Mapping/CategoryMapping.php | 89 ++++++++ .../model/Mapping/CommentMapping.php | 152 +++++++++++++ .../04-manager/model/Mapping/FileMapping.php | 64 ++++++ .../model/Mapping/PermissionMapping.php | 49 +++++ .../04-manager/model/Mapping/TagMapping.php | 44 ++++ .../04-manager/model/Mapping/UserMapping.php | 87 ++++++++ .../01-begin/04-manager/model/README.md | 1 + .../01-begin/04-manager/model/Trait/README.md | 24 ++ .../04-manager/model/Trait/TraitDateTime.php | 34 +++ .../04-manager/model/Trait/TraitSlugify.php | 40 ++++ .../01-begin/04-manager/public/README.md | 2 + .../01-begin/04-manager/public/css/style.css | 10 + .../public/img/upload/2024.06.24-09_56_48.png | Bin 0 -> 48148 bytes .../01-begin/04-manager/public/index.php | 114 ++++++++++ .../Charly/01-begin/04-manager/view/README.md | 2 + .../view/comment/insertComment.view.php | 25 +++ .../view/comment/menu.comment.view.php | 8 + .../view/comment/selectAllComment.view.php | 33 +++ .../view/comment/selectOneComment.view.php | 34 +++ .../view/comment/updateComment.view.php | 34 +++ test/Charly/01-begin/05-together/.gitignore | 11 + .../01-begin/05-together/config.php.ini | 26 +++ .../01-begin/05-together/controller/README.md | 3 + .../model/Abstract/AbstractMapping.php | 42 ++++ .../05-together/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 18 ++ .../model/Interface/InterfaceSlugManager.php | 6 + .../05-together/model/Interface/README.md | 9 + .../model/Manager/PermissionManager.php | 63 ++++++ .../model/Mapping/ArticleMapping.php | 124 +++++++++++ .../model/Mapping/CategoryMapping.php | 89 ++++++++ .../model/Mapping/CommentMapping.php | 152 +++++++++++++ .../05-together/model/Mapping/FileMapping.php | 64 ++++++ .../model/Mapping/PermissionMapping.php | 48 ++++ .../05-together/model/Mapping/TagMapping.php | 44 ++++ .../05-together/model/Mapping/UserMapping.php | 87 ++++++++ .../01-begin/05-together/model/README.md | 1 + .../05-together/model/Trait/README.md | 24 ++ .../05-together/model/Trait/TraitDateTime.php | 34 +++ .../05-together/model/Trait/TraitSlugify.php | 40 ++++ .../01-begin/05-together/public/README.md | 2 + .../public/img/upload/2024.06.24-09_56_48.png | Bin 0 -> 48148 bytes .../01-begin/05-together/public/index.php | 37 ++++ .../01-begin/05-together/view/README.md | 2 + .../permission/permission.homepage.view.php | 25 +++ test/Charly/01-begin/06-manager/.gitignore | 11 + .../Charly/01-begin/06-manager/config.php.ini | 26 +++ .../01-begin/06-manager/controller/README.md | 3 + .../controller/commentController.php | 95 ++++++++ .../controller/routerController.php | 46 ++++ .../model/Abstract/AbstractMapping.php | 42 ++++ .../06-manager/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 16 ++ .../model/Interface/InterfaceSlugManager.php | 6 + .../06-manager/model/Interface/README.md | 9 + .../model/Manager/CommentManager.php | 165 ++++++++++++++ .../model/Mapping/ArticleMapping.php | 124 +++++++++++ .../model/Mapping/CategoryMapping.php | 89 ++++++++ .../model/Mapping/CommentMapping.php | 152 +++++++++++++ .../06-manager/model/Mapping/FileMapping.php | 64 ++++++ .../model/Mapping/PermissionMapping.php | 49 +++++ .../06-manager/model/Mapping/TagMapping.php | 44 ++++ .../06-manager/model/Mapping/UserMapping.php | 87 ++++++++ .../01-begin/06-manager/model/README.md | 1 + .../01-begin/06-manager/model/Trait/README.md | 24 ++ .../06-manager/model/Trait/TraitDateTime.php | 34 +++ .../06-manager/model/Trait/TraitSlugify.php | 40 ++++ .../01-begin/06-manager/public/README.md | 2 + .../01-begin/06-manager/public/css/style.css | 10 + .../public/img/upload/2024.06.24-09_56_48.png | Bin 0 -> 48148 bytes .../01-begin/06-manager/public/index.php | 26 +++ .../01-begin/06-manager/view/404.view.php | 15 ++ .../Charly/01-begin/06-manager/view/README.md | 2 + .../view/comment/insertComment.view.php | 25 +++ .../view/comment/selectAllComment.view.php | 33 +++ .../view/comment/selectOneComment.view.php | 34 +++ .../view/comment/updateComment.view.php | 35 +++ .../06-manager/view/homepage.view.php | 30 +++ .../06-manager/view/menu.homepage.view.php | 17 ++ .../model/Abstract/AbstractMapping.php | 3 + .../01-begin/model/Mapping/MappingTag.php | 25 ++- test/Charly/01-begin/public/index.php | 14 +- test/Charly/02-mapping/01-begin/.gitignore | 7 + .../Charly/02-mapping/01-begin/config.php.ini | 26 +++ .../02-mapping/01-begin/controller/README.md | 3 + .../model/Abstract/AbstractMapping.php | 44 ++++ .../01-begin/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 16 ++ .../model/Interface/InterfaceSlugManager.php | 8 + .../01-begin/model/Interface/README.md | 9 + .../01-begin/model/Mapping/MappingTag.php | 49 +++++ .../02-mapping/01-begin/model/README.md | 1 + .../02-mapping/01-begin/model/Trait/README.md | 24 ++ .../01-begin/model/Trait/TraitSlugify.php | 40 ++++ .../02-mapping/01-begin/public/README.md | 2 + .../02-mapping/01-begin/public/index.php | 51 +++++ .../Charly/02-mapping/01-begin/view/README.md | 2 + test/Charly/02-mapping/02-mapping/.gitignore | 7 + .../02-mapping/02-mapping/config.php.ini | 26 +++ .../02-mapping/controller/README.md | 3 + .../model/Abstract/AbstractMapping.php | 40 ++++ .../02-mapping/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 28 +++ .../model/Interface/InterfaceSlugManager.php | 25 +++ .../02-mapping/model/Interface/README.md | 9 + .../model/Mapping/ExempleMapping.php | 118 ++++++++++ .../02-mapping/02-mapping/model/OurPDO.php | 50 +++++ .../02-mapping/02-mapping/model/README.md | 1 + .../02-mapping/model/Trait/README.md | 24 ++ .../02-mapping/model/Trait/TraitDateTime.php | 35 +++ .../02-mapping/model/Trait/TraitSlugify.php | 40 ++++ .../02-mapping/02-mapping/public/README.md | 2 + .../02-mapping/02-mapping/public/index.php | 59 +++++ .../02-mapping/02-mapping/view/README.md | 2 + .../02-mapping/03-test-mapping/index.php | 207 ++++++++++++++++++ test/Charly/02-mapping/04-manager/.gitignore | 11 + .../02-mapping/04-manager/config.php.ini | 26 +++ .../04-manager/controller/README.md | 3 + .../model/Abstract/AbstractMapping.php | 42 ++++ .../04-manager/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 16 ++ .../model/Interface/InterfaceSlugManager.php | 6 + .../04-manager/model/Interface/README.md | 9 + .../model/Manager/CommentManager.php | 165 ++++++++++++++ .../model/Mapping/ArticleMapping.php | 124 +++++++++++ .../model/Mapping/CategoryMapping.php | 89 ++++++++ .../model/Mapping/CommentMapping.php | 152 +++++++++++++ .../04-manager/model/Mapping/FileMapping.php | 64 ++++++ .../model/Mapping/PermissionMapping.php | 49 +++++ .../04-manager/model/Mapping/TagMapping.php | 44 ++++ .../04-manager/model/Mapping/UserMapping.php | 87 ++++++++ .../02-mapping/04-manager/model/README.md | 1 + .../04-manager/model/Trait/README.md | 24 ++ .../04-manager/model/Trait/TraitDateTime.php | 34 +++ .../04-manager/model/Trait/TraitSlugify.php | 40 ++++ .../02-mapping/04-manager/public/README.md | 2 + .../04-manager/public/css/style.css | 10 + .../public/img/upload/2024.06.24-09_56_48.png | Bin 0 -> 48148 bytes .../02-mapping/04-manager/public/index.php | 114 ++++++++++ .../02-mapping/04-manager/view/README.md | 2 + .../view/comment/insertComment.view.php | 25 +++ .../view/comment/menu.comment.view.php | 8 + .../view/comment/selectAllComment.view.php | 33 +++ .../view/comment/selectOneComment.view.php | 34 +++ .../view/comment/updateComment.view.php | 34 +++ test/Charly/02-mapping/05-together/.gitignore | 11 + .../02-mapping/05-together/config.php.ini | 26 +++ .../05-together/controller/README.md | 3 + .../model/Abstract/AbstractMapping.php | 42 ++++ .../05-together/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 18 ++ .../model/Interface/InterfaceSlugManager.php | 6 + .../05-together/model/Interface/README.md | 9 + .../model/Manager/PermissionManager.php | 63 ++++++ .../model/Mapping/ArticleMapping.php | 124 +++++++++++ .../model/Mapping/CategoryMapping.php | 89 ++++++++ .../model/Mapping/CommentMapping.php | 152 +++++++++++++ .../05-together/model/Mapping/FileMapping.php | 64 ++++++ .../model/Mapping/PermissionMapping.php | 48 ++++ .../05-together/model/Mapping/TagMapping.php | 44 ++++ .../05-together/model/Mapping/UserMapping.php | 87 ++++++++ .../02-mapping/05-together/model/README.md | 1 + .../05-together/model/Trait/README.md | 24 ++ .../05-together/model/Trait/TraitDateTime.php | 34 +++ .../05-together/model/Trait/TraitSlugify.php | 40 ++++ .../02-mapping/05-together/public/README.md | 2 + .../public/img/upload/2024.06.24-09_56_48.png | Bin 0 -> 48148 bytes .../02-mapping/05-together/public/index.php | 37 ++++ .../02-mapping/05-together/view/README.md | 2 + .../permission/permission.homepage.view.php | 25 +++ test/Charly/02-mapping/06-manager/.gitignore | 11 + .../02-mapping/06-manager/config.php.ini | 26 +++ .../06-manager/controller/README.md | 3 + .../controller/commentController.php | 95 ++++++++ .../controller/routerController.php | 46 ++++ .../model/Abstract/AbstractMapping.php | 42 ++++ .../06-manager/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 16 ++ .../model/Interface/InterfaceSlugManager.php | 6 + .../06-manager/model/Interface/README.md | 9 + .../model/Manager/CommentManager.php | 165 ++++++++++++++ .../model/Mapping/ArticleMapping.php | 124 +++++++++++ .../model/Mapping/CategoryMapping.php | 89 ++++++++ .../model/Mapping/CommentMapping.php | 152 +++++++++++++ .../06-manager/model/Mapping/FileMapping.php | 64 ++++++ .../model/Mapping/PermissionMapping.php | 49 +++++ .../06-manager/model/Mapping/TagMapping.php | 44 ++++ .../06-manager/model/Mapping/UserMapping.php | 87 ++++++++ .../02-mapping/06-manager/model/README.md | 1 + .../06-manager/model/Trait/README.md | 24 ++ .../06-manager/model/Trait/TraitDateTime.php | 34 +++ .../06-manager/model/Trait/TraitSlugify.php | 40 ++++ .../02-mapping/06-manager/public/README.md | 2 + .../06-manager/public/css/style.css | 10 + .../public/img/upload/2024.06.24-09_56_48.png | Bin 0 -> 48148 bytes .../02-mapping/06-manager/public/index.php | 26 +++ .../02-mapping/06-manager/view/404.view.php | 15 ++ .../02-mapping/06-manager/view/README.md | 2 + .../view/comment/insertComment.view.php | 25 +++ .../view/comment/selectAllComment.view.php | 33 +++ .../view/comment/selectOneComment.view.php | 34 +++ .../view/comment/updateComment.view.php | 35 +++ .../06-manager/view/homepage.view.php | 30 +++ .../06-manager/view/menu.homepage.view.php | 17 ++ test/Charly/03-test-mapping/index.php | 207 ++++++++++++++++++ test/Charly/04-manager/.gitignore | 11 + test/Charly/04-manager/config.php.ini | 26 +++ test/Charly/04-manager/controller/README.md | 3 + .../model/Abstract/AbstractMapping.php | 42 ++++ .../04-manager/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 16 ++ .../model/Interface/InterfaceSlugManager.php | 6 + .../04-manager/model/Interface/README.md | 9 + .../model/Manager/CommentManager.php | 165 ++++++++++++++ .../model/Mapping/ArticleMapping.php | 124 +++++++++++ .../model/Mapping/CategoryMapping.php | 89 ++++++++ .../model/Mapping/CommentMapping.php | 152 +++++++++++++ .../04-manager/model/Mapping/FileMapping.php | 64 ++++++ .../model/Mapping/PermissionMapping.php | 49 +++++ .../04-manager/model/Mapping/TagMapping.php | 44 ++++ .../04-manager/model/Mapping/UserMapping.php | 87 ++++++++ test/Charly/04-manager/model/README.md | 1 + test/Charly/04-manager/model/Trait/README.md | 24 ++ .../04-manager/model/Trait/TraitDateTime.php | 34 +++ .../04-manager/model/Trait/TraitSlugify.php | 40 ++++ test/Charly/04-manager/public/README.md | 2 + test/Charly/04-manager/public/css/style.css | 10 + .../public/img/upload/2024.06.24-09_56_48.png | Bin 0 -> 48148 bytes test/Charly/04-manager/public/index.php | 114 ++++++++++ test/Charly/04-manager/view/README.md | 2 + .../view/comment/insertComment.view.php | 25 +++ .../view/comment/menu.comment.view.php | 8 + .../view/comment/selectAllComment.view.php | 33 +++ .../view/comment/selectOneComment.view.php | 34 +++ .../view/comment/updateComment.view.php | 34 +++ test/Charly/05-together/.gitignore | 11 + test/Charly/05-together/config.php.ini | 26 +++ test/Charly/05-together/controller/README.md | 3 + .../model/Abstract/AbstractMapping.php | 42 ++++ .../05-together/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 18 ++ .../model/Interface/InterfaceSlugManager.php | 6 + .../05-together/model/Interface/README.md | 9 + .../model/Manager/PermissionManager.php | 63 ++++++ .../model/Mapping/ArticleMapping.php | 124 +++++++++++ .../model/Mapping/CategoryMapping.php | 89 ++++++++ .../model/Mapping/CommentMapping.php | 152 +++++++++++++ .../05-together/model/Mapping/FileMapping.php | 64 ++++++ .../model/Mapping/PermissionMapping.php | 48 ++++ .../05-together/model/Mapping/TagMapping.php | 44 ++++ .../05-together/model/Mapping/UserMapping.php | 87 ++++++++ test/Charly/05-together/model/README.md | 1 + test/Charly/05-together/model/Trait/README.md | 24 ++ .../05-together/model/Trait/TraitDateTime.php | 34 +++ .../05-together/model/Trait/TraitSlugify.php | 40 ++++ test/Charly/05-together/public/README.md | 2 + .../public/img/upload/2024.06.24-09_56_48.png | Bin 0 -> 48148 bytes test/Charly/05-together/public/index.php | 37 ++++ test/Charly/05-together/view/README.md | 2 + .../permission/permission.homepage.view.php | 25 +++ test/Charly/06-manager/.gitignore | 11 + test/Charly/06-manager/config.php.ini | 26 +++ test/Charly/06-manager/controller/README.md | 3 + .../controller/commentController.php | 95 ++++++++ .../controller/routerController.php | 46 ++++ .../model/Abstract/AbstractMapping.php | 42 ++++ .../06-manager/model/Abstract/README.md | 8 + .../model/Interface/InterfaceManager.php | 16 ++ .../model/Interface/InterfaceSlugManager.php | 6 + .../06-manager/model/Interface/README.md | 9 + .../model/Manager/CommentManager.php | 165 ++++++++++++++ .../model/Mapping/ArticleMapping.php | 124 +++++++++++ .../model/Mapping/CategoryMapping.php | 89 ++++++++ .../model/Mapping/CommentMapping.php | 152 +++++++++++++ .../06-manager/model/Mapping/FileMapping.php | 64 ++++++ .../model/Mapping/PermissionMapping.php | 49 +++++ .../06-manager/model/Mapping/TagMapping.php | 44 ++++ .../06-manager/model/Mapping/UserMapping.php | 87 ++++++++ test/Charly/06-manager/model/README.md | 1 + test/Charly/06-manager/model/Trait/README.md | 24 ++ .../06-manager/model/Trait/TraitDateTime.php | 34 +++ .../06-manager/model/Trait/TraitSlugify.php | 40 ++++ test/Charly/06-manager/public/README.md | 2 + test/Charly/06-manager/public/css/style.css | 10 + .../public/img/upload/2024.06.24-09_56_48.png | Bin 0 -> 48148 bytes test/Charly/06-manager/public/index.php | 26 +++ test/Charly/06-manager/view/404.view.php | 15 ++ test/Charly/06-manager/view/README.md | 2 + .../view/comment/insertComment.view.php | 25 +++ .../view/comment/selectAllComment.view.php | 33 +++ .../view/comment/selectOneComment.view.php | 34 +++ .../view/comment/updateComment.view.php | 35 +++ test/Charly/06-manager/view/homepage.view.php | 30 +++ .../06-manager/view/menu.homepage.view.php | 17 ++ 337 files changed, 12930 insertions(+), 4 deletions(-) create mode 100644 test/Charly/01-begin/01-begin/.gitignore create mode 100644 test/Charly/01-begin/01-begin/config.php.ini create mode 100644 test/Charly/01-begin/01-begin/controller/README.md create mode 100644 test/Charly/01-begin/01-begin/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/01-begin/01-begin/model/Abstract/README.md create mode 100644 test/Charly/01-begin/01-begin/model/Interface/InterfaceManager.php create mode 100644 test/Charly/01-begin/01-begin/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/01-begin/01-begin/model/Interface/README.md create mode 100644 test/Charly/01-begin/01-begin/model/Mapping/MappingTag.php create mode 100644 test/Charly/01-begin/01-begin/model/README.md create mode 100644 test/Charly/01-begin/01-begin/model/Trait/README.md create mode 100644 test/Charly/01-begin/01-begin/model/Trait/TraitSlugify.php create mode 100644 test/Charly/01-begin/01-begin/public/README.md create mode 100644 test/Charly/01-begin/01-begin/public/index.php create mode 100644 test/Charly/01-begin/01-begin/view/README.md create mode 100644 test/Charly/01-begin/02-mapping/.gitignore create mode 100644 test/Charly/01-begin/02-mapping/config.php.ini create mode 100644 test/Charly/01-begin/02-mapping/controller/README.md create mode 100644 test/Charly/01-begin/02-mapping/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/01-begin/02-mapping/model/Abstract/README.md create mode 100644 test/Charly/01-begin/02-mapping/model/Interface/InterfaceManager.php create mode 100644 test/Charly/01-begin/02-mapping/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/01-begin/02-mapping/model/Interface/README.md create mode 100644 test/Charly/01-begin/02-mapping/model/Mapping/ExempleMapping.php create mode 100644 test/Charly/01-begin/02-mapping/model/OurPDO.php create mode 100644 test/Charly/01-begin/02-mapping/model/README.md create mode 100644 test/Charly/01-begin/02-mapping/model/Trait/README.md create mode 100644 test/Charly/01-begin/02-mapping/model/Trait/TraitDateTime.php create mode 100644 test/Charly/01-begin/02-mapping/model/Trait/TraitSlugify.php create mode 100644 test/Charly/01-begin/02-mapping/public/README.md create mode 100644 test/Charly/01-begin/02-mapping/public/index.php create mode 100644 test/Charly/01-begin/02-mapping/view/README.md create mode 100644 test/Charly/01-begin/03-test-mapping/index.php create mode 100644 test/Charly/01-begin/04-manager/.gitignore create mode 100644 test/Charly/01-begin/04-manager/config.php.ini create mode 100644 test/Charly/01-begin/04-manager/controller/README.md create mode 100644 test/Charly/01-begin/04-manager/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/01-begin/04-manager/model/Abstract/README.md create mode 100644 test/Charly/01-begin/04-manager/model/Interface/InterfaceManager.php create mode 100644 test/Charly/01-begin/04-manager/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/01-begin/04-manager/model/Interface/README.md create mode 100644 test/Charly/01-begin/04-manager/model/Manager/CommentManager.php create mode 100644 test/Charly/01-begin/04-manager/model/Mapping/ArticleMapping.php create mode 100644 test/Charly/01-begin/04-manager/model/Mapping/CategoryMapping.php create mode 100644 test/Charly/01-begin/04-manager/model/Mapping/CommentMapping.php create mode 100644 test/Charly/01-begin/04-manager/model/Mapping/FileMapping.php create mode 100644 test/Charly/01-begin/04-manager/model/Mapping/PermissionMapping.php create mode 100644 test/Charly/01-begin/04-manager/model/Mapping/TagMapping.php create mode 100644 test/Charly/01-begin/04-manager/model/Mapping/UserMapping.php create mode 100644 test/Charly/01-begin/04-manager/model/README.md create mode 100644 test/Charly/01-begin/04-manager/model/Trait/README.md create mode 100644 test/Charly/01-begin/04-manager/model/Trait/TraitDateTime.php create mode 100644 test/Charly/01-begin/04-manager/model/Trait/TraitSlugify.php create mode 100644 test/Charly/01-begin/04-manager/public/README.md create mode 100644 test/Charly/01-begin/04-manager/public/css/style.css create mode 100644 test/Charly/01-begin/04-manager/public/img/upload/2024.06.24-09_56_48.png create mode 100644 test/Charly/01-begin/04-manager/public/index.php create mode 100644 test/Charly/01-begin/04-manager/view/README.md create mode 100644 test/Charly/01-begin/04-manager/view/comment/insertComment.view.php create mode 100644 test/Charly/01-begin/04-manager/view/comment/menu.comment.view.php create mode 100644 test/Charly/01-begin/04-manager/view/comment/selectAllComment.view.php create mode 100644 test/Charly/01-begin/04-manager/view/comment/selectOneComment.view.php create mode 100644 test/Charly/01-begin/04-manager/view/comment/updateComment.view.php create mode 100644 test/Charly/01-begin/05-together/.gitignore create mode 100644 test/Charly/01-begin/05-together/config.php.ini create mode 100644 test/Charly/01-begin/05-together/controller/README.md create mode 100644 test/Charly/01-begin/05-together/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/01-begin/05-together/model/Abstract/README.md create mode 100644 test/Charly/01-begin/05-together/model/Interface/InterfaceManager.php create mode 100644 test/Charly/01-begin/05-together/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/01-begin/05-together/model/Interface/README.md create mode 100644 test/Charly/01-begin/05-together/model/Manager/PermissionManager.php create mode 100644 test/Charly/01-begin/05-together/model/Mapping/ArticleMapping.php create mode 100644 test/Charly/01-begin/05-together/model/Mapping/CategoryMapping.php create mode 100644 test/Charly/01-begin/05-together/model/Mapping/CommentMapping.php create mode 100644 test/Charly/01-begin/05-together/model/Mapping/FileMapping.php create mode 100644 test/Charly/01-begin/05-together/model/Mapping/PermissionMapping.php create mode 100644 test/Charly/01-begin/05-together/model/Mapping/TagMapping.php create mode 100644 test/Charly/01-begin/05-together/model/Mapping/UserMapping.php create mode 100644 test/Charly/01-begin/05-together/model/README.md create mode 100644 test/Charly/01-begin/05-together/model/Trait/README.md create mode 100644 test/Charly/01-begin/05-together/model/Trait/TraitDateTime.php create mode 100644 test/Charly/01-begin/05-together/model/Trait/TraitSlugify.php create mode 100644 test/Charly/01-begin/05-together/public/README.md create mode 100644 test/Charly/01-begin/05-together/public/img/upload/2024.06.24-09_56_48.png create mode 100644 test/Charly/01-begin/05-together/public/index.php create mode 100644 test/Charly/01-begin/05-together/view/README.md create mode 100644 test/Charly/01-begin/05-together/view/permission/permission.homepage.view.php create mode 100644 test/Charly/01-begin/06-manager/.gitignore create mode 100644 test/Charly/01-begin/06-manager/config.php.ini create mode 100644 test/Charly/01-begin/06-manager/controller/README.md create mode 100644 test/Charly/01-begin/06-manager/controller/commentController.php create mode 100644 test/Charly/01-begin/06-manager/controller/routerController.php create mode 100644 test/Charly/01-begin/06-manager/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/01-begin/06-manager/model/Abstract/README.md create mode 100644 test/Charly/01-begin/06-manager/model/Interface/InterfaceManager.php create mode 100644 test/Charly/01-begin/06-manager/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/01-begin/06-manager/model/Interface/README.md create mode 100644 test/Charly/01-begin/06-manager/model/Manager/CommentManager.php create mode 100644 test/Charly/01-begin/06-manager/model/Mapping/ArticleMapping.php create mode 100644 test/Charly/01-begin/06-manager/model/Mapping/CategoryMapping.php create mode 100644 test/Charly/01-begin/06-manager/model/Mapping/CommentMapping.php create mode 100644 test/Charly/01-begin/06-manager/model/Mapping/FileMapping.php create mode 100644 test/Charly/01-begin/06-manager/model/Mapping/PermissionMapping.php create mode 100644 test/Charly/01-begin/06-manager/model/Mapping/TagMapping.php create mode 100644 test/Charly/01-begin/06-manager/model/Mapping/UserMapping.php create mode 100644 test/Charly/01-begin/06-manager/model/README.md create mode 100644 test/Charly/01-begin/06-manager/model/Trait/README.md create mode 100644 test/Charly/01-begin/06-manager/model/Trait/TraitDateTime.php create mode 100644 test/Charly/01-begin/06-manager/model/Trait/TraitSlugify.php create mode 100644 test/Charly/01-begin/06-manager/public/README.md create mode 100644 test/Charly/01-begin/06-manager/public/css/style.css create mode 100644 test/Charly/01-begin/06-manager/public/img/upload/2024.06.24-09_56_48.png create mode 100644 test/Charly/01-begin/06-manager/public/index.php create mode 100644 test/Charly/01-begin/06-manager/view/404.view.php create mode 100644 test/Charly/01-begin/06-manager/view/README.md create mode 100644 test/Charly/01-begin/06-manager/view/comment/insertComment.view.php create mode 100644 test/Charly/01-begin/06-manager/view/comment/selectAllComment.view.php create mode 100644 test/Charly/01-begin/06-manager/view/comment/selectOneComment.view.php create mode 100644 test/Charly/01-begin/06-manager/view/comment/updateComment.view.php create mode 100644 test/Charly/01-begin/06-manager/view/homepage.view.php create mode 100644 test/Charly/01-begin/06-manager/view/menu.homepage.view.php create mode 100644 test/Charly/02-mapping/01-begin/.gitignore create mode 100644 test/Charly/02-mapping/01-begin/config.php.ini create mode 100644 test/Charly/02-mapping/01-begin/controller/README.md create mode 100644 test/Charly/02-mapping/01-begin/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/02-mapping/01-begin/model/Abstract/README.md create mode 100644 test/Charly/02-mapping/01-begin/model/Interface/InterfaceManager.php create mode 100644 test/Charly/02-mapping/01-begin/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/02-mapping/01-begin/model/Interface/README.md create mode 100644 test/Charly/02-mapping/01-begin/model/Mapping/MappingTag.php create mode 100644 test/Charly/02-mapping/01-begin/model/README.md create mode 100644 test/Charly/02-mapping/01-begin/model/Trait/README.md create mode 100644 test/Charly/02-mapping/01-begin/model/Trait/TraitSlugify.php create mode 100644 test/Charly/02-mapping/01-begin/public/README.md create mode 100644 test/Charly/02-mapping/01-begin/public/index.php create mode 100644 test/Charly/02-mapping/01-begin/view/README.md create mode 100644 test/Charly/02-mapping/02-mapping/.gitignore create mode 100644 test/Charly/02-mapping/02-mapping/config.php.ini create mode 100644 test/Charly/02-mapping/02-mapping/controller/README.md create mode 100644 test/Charly/02-mapping/02-mapping/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/02-mapping/02-mapping/model/Abstract/README.md create mode 100644 test/Charly/02-mapping/02-mapping/model/Interface/InterfaceManager.php create mode 100644 test/Charly/02-mapping/02-mapping/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/02-mapping/02-mapping/model/Interface/README.md create mode 100644 test/Charly/02-mapping/02-mapping/model/Mapping/ExempleMapping.php create mode 100644 test/Charly/02-mapping/02-mapping/model/OurPDO.php create mode 100644 test/Charly/02-mapping/02-mapping/model/README.md create mode 100644 test/Charly/02-mapping/02-mapping/model/Trait/README.md create mode 100644 test/Charly/02-mapping/02-mapping/model/Trait/TraitDateTime.php create mode 100644 test/Charly/02-mapping/02-mapping/model/Trait/TraitSlugify.php create mode 100644 test/Charly/02-mapping/02-mapping/public/README.md create mode 100644 test/Charly/02-mapping/02-mapping/public/index.php create mode 100644 test/Charly/02-mapping/02-mapping/view/README.md create mode 100644 test/Charly/02-mapping/03-test-mapping/index.php create mode 100644 test/Charly/02-mapping/04-manager/.gitignore create mode 100644 test/Charly/02-mapping/04-manager/config.php.ini create mode 100644 test/Charly/02-mapping/04-manager/controller/README.md create mode 100644 test/Charly/02-mapping/04-manager/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/02-mapping/04-manager/model/Abstract/README.md create mode 100644 test/Charly/02-mapping/04-manager/model/Interface/InterfaceManager.php create mode 100644 test/Charly/02-mapping/04-manager/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/02-mapping/04-manager/model/Interface/README.md create mode 100644 test/Charly/02-mapping/04-manager/model/Manager/CommentManager.php create mode 100644 test/Charly/02-mapping/04-manager/model/Mapping/ArticleMapping.php create mode 100644 test/Charly/02-mapping/04-manager/model/Mapping/CategoryMapping.php create mode 100644 test/Charly/02-mapping/04-manager/model/Mapping/CommentMapping.php create mode 100644 test/Charly/02-mapping/04-manager/model/Mapping/FileMapping.php create mode 100644 test/Charly/02-mapping/04-manager/model/Mapping/PermissionMapping.php create mode 100644 test/Charly/02-mapping/04-manager/model/Mapping/TagMapping.php create mode 100644 test/Charly/02-mapping/04-manager/model/Mapping/UserMapping.php create mode 100644 test/Charly/02-mapping/04-manager/model/README.md create mode 100644 test/Charly/02-mapping/04-manager/model/Trait/README.md create mode 100644 test/Charly/02-mapping/04-manager/model/Trait/TraitDateTime.php create mode 100644 test/Charly/02-mapping/04-manager/model/Trait/TraitSlugify.php create mode 100644 test/Charly/02-mapping/04-manager/public/README.md create mode 100644 test/Charly/02-mapping/04-manager/public/css/style.css create mode 100644 test/Charly/02-mapping/04-manager/public/img/upload/2024.06.24-09_56_48.png create mode 100644 test/Charly/02-mapping/04-manager/public/index.php create mode 100644 test/Charly/02-mapping/04-manager/view/README.md create mode 100644 test/Charly/02-mapping/04-manager/view/comment/insertComment.view.php create mode 100644 test/Charly/02-mapping/04-manager/view/comment/menu.comment.view.php create mode 100644 test/Charly/02-mapping/04-manager/view/comment/selectAllComment.view.php create mode 100644 test/Charly/02-mapping/04-manager/view/comment/selectOneComment.view.php create mode 100644 test/Charly/02-mapping/04-manager/view/comment/updateComment.view.php create mode 100644 test/Charly/02-mapping/05-together/.gitignore create mode 100644 test/Charly/02-mapping/05-together/config.php.ini create mode 100644 test/Charly/02-mapping/05-together/controller/README.md create mode 100644 test/Charly/02-mapping/05-together/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/02-mapping/05-together/model/Abstract/README.md create mode 100644 test/Charly/02-mapping/05-together/model/Interface/InterfaceManager.php create mode 100644 test/Charly/02-mapping/05-together/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/02-mapping/05-together/model/Interface/README.md create mode 100644 test/Charly/02-mapping/05-together/model/Manager/PermissionManager.php create mode 100644 test/Charly/02-mapping/05-together/model/Mapping/ArticleMapping.php create mode 100644 test/Charly/02-mapping/05-together/model/Mapping/CategoryMapping.php create mode 100644 test/Charly/02-mapping/05-together/model/Mapping/CommentMapping.php create mode 100644 test/Charly/02-mapping/05-together/model/Mapping/FileMapping.php create mode 100644 test/Charly/02-mapping/05-together/model/Mapping/PermissionMapping.php create mode 100644 test/Charly/02-mapping/05-together/model/Mapping/TagMapping.php create mode 100644 test/Charly/02-mapping/05-together/model/Mapping/UserMapping.php create mode 100644 test/Charly/02-mapping/05-together/model/README.md create mode 100644 test/Charly/02-mapping/05-together/model/Trait/README.md create mode 100644 test/Charly/02-mapping/05-together/model/Trait/TraitDateTime.php create mode 100644 test/Charly/02-mapping/05-together/model/Trait/TraitSlugify.php create mode 100644 test/Charly/02-mapping/05-together/public/README.md create mode 100644 test/Charly/02-mapping/05-together/public/img/upload/2024.06.24-09_56_48.png create mode 100644 test/Charly/02-mapping/05-together/public/index.php create mode 100644 test/Charly/02-mapping/05-together/view/README.md create mode 100644 test/Charly/02-mapping/05-together/view/permission/permission.homepage.view.php create mode 100644 test/Charly/02-mapping/06-manager/.gitignore create mode 100644 test/Charly/02-mapping/06-manager/config.php.ini create mode 100644 test/Charly/02-mapping/06-manager/controller/README.md create mode 100644 test/Charly/02-mapping/06-manager/controller/commentController.php create mode 100644 test/Charly/02-mapping/06-manager/controller/routerController.php create mode 100644 test/Charly/02-mapping/06-manager/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/02-mapping/06-manager/model/Abstract/README.md create mode 100644 test/Charly/02-mapping/06-manager/model/Interface/InterfaceManager.php create mode 100644 test/Charly/02-mapping/06-manager/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/02-mapping/06-manager/model/Interface/README.md create mode 100644 test/Charly/02-mapping/06-manager/model/Manager/CommentManager.php create mode 100644 test/Charly/02-mapping/06-manager/model/Mapping/ArticleMapping.php create mode 100644 test/Charly/02-mapping/06-manager/model/Mapping/CategoryMapping.php create mode 100644 test/Charly/02-mapping/06-manager/model/Mapping/CommentMapping.php create mode 100644 test/Charly/02-mapping/06-manager/model/Mapping/FileMapping.php create mode 100644 test/Charly/02-mapping/06-manager/model/Mapping/PermissionMapping.php create mode 100644 test/Charly/02-mapping/06-manager/model/Mapping/TagMapping.php create mode 100644 test/Charly/02-mapping/06-manager/model/Mapping/UserMapping.php create mode 100644 test/Charly/02-mapping/06-manager/model/README.md create mode 100644 test/Charly/02-mapping/06-manager/model/Trait/README.md create mode 100644 test/Charly/02-mapping/06-manager/model/Trait/TraitDateTime.php create mode 100644 test/Charly/02-mapping/06-manager/model/Trait/TraitSlugify.php create mode 100644 test/Charly/02-mapping/06-manager/public/README.md create mode 100644 test/Charly/02-mapping/06-manager/public/css/style.css create mode 100644 test/Charly/02-mapping/06-manager/public/img/upload/2024.06.24-09_56_48.png create mode 100644 test/Charly/02-mapping/06-manager/public/index.php create mode 100644 test/Charly/02-mapping/06-manager/view/404.view.php create mode 100644 test/Charly/02-mapping/06-manager/view/README.md create mode 100644 test/Charly/02-mapping/06-manager/view/comment/insertComment.view.php create mode 100644 test/Charly/02-mapping/06-manager/view/comment/selectAllComment.view.php create mode 100644 test/Charly/02-mapping/06-manager/view/comment/selectOneComment.view.php create mode 100644 test/Charly/02-mapping/06-manager/view/comment/updateComment.view.php create mode 100644 test/Charly/02-mapping/06-manager/view/homepage.view.php create mode 100644 test/Charly/02-mapping/06-manager/view/menu.homepage.view.php create mode 100644 test/Charly/03-test-mapping/index.php create mode 100644 test/Charly/04-manager/.gitignore create mode 100644 test/Charly/04-manager/config.php.ini create mode 100644 test/Charly/04-manager/controller/README.md create mode 100644 test/Charly/04-manager/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/04-manager/model/Abstract/README.md create mode 100644 test/Charly/04-manager/model/Interface/InterfaceManager.php create mode 100644 test/Charly/04-manager/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/04-manager/model/Interface/README.md create mode 100644 test/Charly/04-manager/model/Manager/CommentManager.php create mode 100644 test/Charly/04-manager/model/Mapping/ArticleMapping.php create mode 100644 test/Charly/04-manager/model/Mapping/CategoryMapping.php create mode 100644 test/Charly/04-manager/model/Mapping/CommentMapping.php create mode 100644 test/Charly/04-manager/model/Mapping/FileMapping.php create mode 100644 test/Charly/04-manager/model/Mapping/PermissionMapping.php create mode 100644 test/Charly/04-manager/model/Mapping/TagMapping.php create mode 100644 test/Charly/04-manager/model/Mapping/UserMapping.php create mode 100644 test/Charly/04-manager/model/README.md create mode 100644 test/Charly/04-manager/model/Trait/README.md create mode 100644 test/Charly/04-manager/model/Trait/TraitDateTime.php create mode 100644 test/Charly/04-manager/model/Trait/TraitSlugify.php create mode 100644 test/Charly/04-manager/public/README.md create mode 100644 test/Charly/04-manager/public/css/style.css create mode 100644 test/Charly/04-manager/public/img/upload/2024.06.24-09_56_48.png create mode 100644 test/Charly/04-manager/public/index.php create mode 100644 test/Charly/04-manager/view/README.md create mode 100644 test/Charly/04-manager/view/comment/insertComment.view.php create mode 100644 test/Charly/04-manager/view/comment/menu.comment.view.php create mode 100644 test/Charly/04-manager/view/comment/selectAllComment.view.php create mode 100644 test/Charly/04-manager/view/comment/selectOneComment.view.php create mode 100644 test/Charly/04-manager/view/comment/updateComment.view.php create mode 100644 test/Charly/05-together/.gitignore create mode 100644 test/Charly/05-together/config.php.ini create mode 100644 test/Charly/05-together/controller/README.md create mode 100644 test/Charly/05-together/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/05-together/model/Abstract/README.md create mode 100644 test/Charly/05-together/model/Interface/InterfaceManager.php create mode 100644 test/Charly/05-together/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/05-together/model/Interface/README.md create mode 100644 test/Charly/05-together/model/Manager/PermissionManager.php create mode 100644 test/Charly/05-together/model/Mapping/ArticleMapping.php create mode 100644 test/Charly/05-together/model/Mapping/CategoryMapping.php create mode 100644 test/Charly/05-together/model/Mapping/CommentMapping.php create mode 100644 test/Charly/05-together/model/Mapping/FileMapping.php create mode 100644 test/Charly/05-together/model/Mapping/PermissionMapping.php create mode 100644 test/Charly/05-together/model/Mapping/TagMapping.php create mode 100644 test/Charly/05-together/model/Mapping/UserMapping.php create mode 100644 test/Charly/05-together/model/README.md create mode 100644 test/Charly/05-together/model/Trait/README.md create mode 100644 test/Charly/05-together/model/Trait/TraitDateTime.php create mode 100644 test/Charly/05-together/model/Trait/TraitSlugify.php create mode 100644 test/Charly/05-together/public/README.md create mode 100644 test/Charly/05-together/public/img/upload/2024.06.24-09_56_48.png create mode 100644 test/Charly/05-together/public/index.php create mode 100644 test/Charly/05-together/view/README.md create mode 100644 test/Charly/05-together/view/permission/permission.homepage.view.php create mode 100644 test/Charly/06-manager/.gitignore create mode 100644 test/Charly/06-manager/config.php.ini create mode 100644 test/Charly/06-manager/controller/README.md create mode 100644 test/Charly/06-manager/controller/commentController.php create mode 100644 test/Charly/06-manager/controller/routerController.php create mode 100644 test/Charly/06-manager/model/Abstract/AbstractMapping.php create mode 100644 test/Charly/06-manager/model/Abstract/README.md create mode 100644 test/Charly/06-manager/model/Interface/InterfaceManager.php create mode 100644 test/Charly/06-manager/model/Interface/InterfaceSlugManager.php create mode 100644 test/Charly/06-manager/model/Interface/README.md create mode 100644 test/Charly/06-manager/model/Manager/CommentManager.php create mode 100644 test/Charly/06-manager/model/Mapping/ArticleMapping.php create mode 100644 test/Charly/06-manager/model/Mapping/CategoryMapping.php create mode 100644 test/Charly/06-manager/model/Mapping/CommentMapping.php create mode 100644 test/Charly/06-manager/model/Mapping/FileMapping.php create mode 100644 test/Charly/06-manager/model/Mapping/PermissionMapping.php create mode 100644 test/Charly/06-manager/model/Mapping/TagMapping.php create mode 100644 test/Charly/06-manager/model/Mapping/UserMapping.php create mode 100644 test/Charly/06-manager/model/README.md create mode 100644 test/Charly/06-manager/model/Trait/README.md create mode 100644 test/Charly/06-manager/model/Trait/TraitDateTime.php create mode 100644 test/Charly/06-manager/model/Trait/TraitSlugify.php create mode 100644 test/Charly/06-manager/public/README.md create mode 100644 test/Charly/06-manager/public/css/style.css create mode 100644 test/Charly/06-manager/public/img/upload/2024.06.24-09_56_48.png create mode 100644 test/Charly/06-manager/public/index.php create mode 100644 test/Charly/06-manager/view/404.view.php create mode 100644 test/Charly/06-manager/view/README.md create mode 100644 test/Charly/06-manager/view/comment/insertComment.view.php create mode 100644 test/Charly/06-manager/view/comment/selectAllComment.view.php create mode 100644 test/Charly/06-manager/view/comment/selectOneComment.view.php create mode 100644 test/Charly/06-manager/view/comment/updateComment.view.php create mode 100644 test/Charly/06-manager/view/homepage.view.php create mode 100644 test/Charly/06-manager/view/menu.homepage.view.php diff --git a/test/Charly/01-begin/01-begin/.gitignore b/test/Charly/01-begin/01-begin/.gitignore new file mode 100644 index 0000000..63052b7 --- /dev/null +++ b/test/Charly/01-begin/01-begin/.gitignore @@ -0,0 +1,7 @@ +# fichers non envoyés +config.php +# vendor contient les libairies externes en php +/vendor +# PHPStorm +.idea + diff --git a/test/Charly/01-begin/01-begin/config.php.ini b/test/Charly/01-begin/01-begin/config.php.ini new file mode 100644 index 0000000..5515502 --- /dev/null +++ b/test/Charly/01-begin/01-begin/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/01-begin/01-begin/controller/README.md b/test/Charly/01-begin/01-begin/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/01-begin/01-begin/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/01-begin/01-begin/model/Abstract/AbstractMapping.php b/test/Charly/01-begin/01-begin/model/Abstract/AbstractMapping.php new file mode 100644 index 0000000..2da5be5 --- /dev/null +++ b/test/Charly/01-begin/01-begin/model/Abstract/AbstractMapping.php @@ -0,0 +1,44 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst',$tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + }else{ + echo "$methodeName n'est pas un setter valide
"; + } + } + } + + // Méthode abstraite à déclarer dans tous les enfants de AbstractMapping + abstract public function __toString():string; + + +} \ No newline at end of file diff --git a/test/Charly/01-begin/01-begin/model/Abstract/README.md b/test/Charly/01-begin/01-begin/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/01-begin/01-begin/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/01-begin/01-begin/model/Interface/InterfaceManager.php b/test/Charly/01-begin/01-begin/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..4406a64 --- /dev/null +++ b/test/Charly/01-begin/01-begin/model/Interface/InterfaceManager.php @@ -0,0 +1,16 @@ +tag_id = $id; + } + + // Appel du trait DANS la classe où on souhaite + // l'utiliser (le chemin complet est en haut du fichier) + use TraitSlugify; + + public function setTagSlug(string $slug) + { + // utilisation de slugify() qui vient du Trait + // model\Trait\TraitSlugify; + $this->tag_slug = $this->slugify($slug); + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/01-begin/model/README.md b/test/Charly/01-begin/01-begin/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/01-begin/01-begin/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/01-begin/01-begin/model/Trait/README.md b/test/Charly/01-begin/01-begin/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/01-begin/01-begin/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/01-begin/01-begin/model/Trait/TraitSlugify.php b/test/Charly/01-begin/01-begin/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/01-begin/01-begin/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ +"; + +// on peut utiliser l'écriture longue pour appeler une classe +// via l'autoload en utilisant son namespace +$tag1 = new model\Mapping\MappingTag([ + 'tag_id' => 1, + 'tag_slug' => "php-8", + "Je m'amuse beaucoup !"=>"14", + "Nimporte_Quoi"=>"yep", +]); + +// manière courte l'alias n'est créé que si on a 2 classes +// qui portent le même nom +use model\Mapping\MappingTag as lulu; + +$tag2 = new lulu([ + 'tag_id' => 8, + 'tag_slug' => "php-8.4", +]); + +use model\Mapping\MappingTag; + +$tag3 = new MappingTag([ + 'tag_id' => 13, + 'tag_slug' => "php-9", + 'Argggg_ho_tempo' => 164862, +]); + +// on voudrait un 'vrai' slug +$tag4 = new MappingTag([ + 'tag_id'=>15, + 'tag_slug'=> "J'aimerais que ceci soit un slug ù$^*ùµùm^m, non?|ééç!è", +]); + +echo $tag4."
"; + +var_dump($tag1,$tag2,$tag3,$tag4); diff --git a/test/Charly/01-begin/01-begin/view/README.md b/test/Charly/01-begin/01-begin/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/01-begin/01-begin/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/01-begin/02-mapping/.gitignore b/test/Charly/01-begin/02-mapping/.gitignore new file mode 100644 index 0000000..63052b7 --- /dev/null +++ b/test/Charly/01-begin/02-mapping/.gitignore @@ -0,0 +1,7 @@ +# fichers non envoyés +config.php +# vendor contient les libairies externes en php +/vendor +# PHPStorm +.idea + diff --git a/test/Charly/01-begin/02-mapping/config.php.ini b/test/Charly/01-begin/02-mapping/config.php.ini new file mode 100644 index 0000000..5515502 --- /dev/null +++ b/test/Charly/01-begin/02-mapping/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/01-begin/02-mapping/controller/README.md b/test/Charly/01-begin/02-mapping/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/01-begin/02-mapping/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/01-begin/02-mapping/model/Abstract/AbstractMapping.php b/test/Charly/01-begin/02-mapping/model/Abstract/AbstractMapping.php new file mode 100644 index 0000000..b6d1d39 --- /dev/null +++ b/test/Charly/01-begin/02-mapping/model/Abstract/AbstractMapping.php @@ -0,0 +1,40 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst',$tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + } + } + } + + // Méthode abstraite à déclarer dans tous les enfants de AbstractMapping + abstract public function __toString():string; +} \ No newline at end of file diff --git a/test/Charly/01-begin/02-mapping/model/Abstract/README.md b/test/Charly/01-begin/02-mapping/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/01-begin/02-mapping/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/01-begin/02-mapping/model/Interface/InterfaceManager.php b/test/Charly/01-begin/02-mapping/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..dd39141 --- /dev/null +++ b/test/Charly/01-begin/02-mapping/model/Interface/InterfaceManager.php @@ -0,0 +1,28 @@ +exemple_id; + } + + public function setExempleId(?int $exemple_id): void + { + if($exemple_id<=0) throw new Exception("ID non valide"); + $this->exemple_id = $exemple_id; + } + + public function getExempleName(): ?string + { + // décryptage + return html_entity_decode($this->exemple_name); + // return $this->exemple_name; + } + + public function setExempleName(?string $exemple_name): void + { + // cryptage + $text = htmlspecialchars(trim(strip_tags($exemple_name)),ENT_QUOTES); + $this->exemple_name = $text; + } + + public function getExempleDescription(): ?string + { + return $this->exemple_description; + } + + public function setExempleDescription(?string $exemple_description): void + { + $this->exemple_description = $exemple_description; + } + + public function getExempleNumber(): ?int + { + return $this->exemple_number; + } + + public function setExempleNumber(?int $exemple_number): void + { + $this->exemple_number = $exemple_number; + } + + public function getExempleDate(): null|string|DateTime + { + return $this->exemple_date; + } + + public function setExempleDate(null|string|DateTime $exemple_date): void + { + // on utilise le trait pour les dates + $this->formatDateTime($exemple_date, "exemple_date"); + + } + + public function getExempleBoolean(): ?bool + { + return $this->exemple_boolean; + } + + public function setExempleBoolean(?bool $exemple_boolean): void + { + $this->exemple_boolean = $exemple_boolean; + } + + public function getExempleFloat(): ?float + { + return $this->exemple_float; + } + + public function setExempleFloat(?float $exemple_float): void + { + $this->exemple_float = $exemple_float; + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/02-mapping/model/OurPDO.php b/test/Charly/01-begin/02-mapping/model/OurPDO.php new file mode 100644 index 0000000..f8a6507 --- /dev/null +++ b/test/Charly/01-begin/02-mapping/model/OurPDO.php @@ -0,0 +1,50 @@ +getMessage()); + } + } + return self::$instance; + } +} \ No newline at end of file diff --git a/test/Charly/01-begin/02-mapping/model/README.md b/test/Charly/01-begin/02-mapping/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/01-begin/02-mapping/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/01-begin/02-mapping/model/Trait/README.md b/test/Charly/01-begin/02-mapping/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/01-begin/02-mapping/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/01-begin/02-mapping/model/Trait/TraitDateTime.php b/test/Charly/01-begin/02-mapping/model/Trait/TraitDateTime.php new file mode 100644 index 0000000..e9d2946 --- /dev/null +++ b/test/Charly/01-begin/02-mapping/model/Trait/TraitDateTime.php @@ -0,0 +1,35 @@ +$paramName = $date->format("Y-m-d H:i:s"); + } catch (Exception $e) { + // en cas d'échec, on met la date à null + $this->$paramName = null; + } + // si c'est un objet (DateTime seul possible) + }elseif (is_object($date)){ + // on formate la date en string en DATETIME + $this->$paramName = $date->format("Y-m-d H:i:s"); + }else{ + $this->$paramName = null; + } + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/02-mapping/model/Trait/TraitSlugify.php b/test/Charly/01-begin/02-mapping/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/01-begin/02-mapping/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ + 1, + "exemple_name" => " exemple1 ", + "exemple_description" => "description1", + "exemple_number" => 1, + "exemple_date" => new DateTime(), + "exemple_boolean" => true, + "exemple_float" => 1.1, + "je_suis_un_champ_inexistant" => "je suis un champ inexistant", +]); + +$exemple2 = new ExempleMapping([ + "exemple_id" => 2, + "exemple_name" => "

Un autre exemple

", + "exemple_description" => "Voici une description d'un être aimé", + "exemple_number" => 83, + "exemple_date" => "2024-03-01 12:17:00", + "exemple_boolean" => false, + "exemple_float" => -82, + "je_suis_un_champ_inexistant" => "je suis un champ inexistant", +]); + +$exemple3 = new ExempleMapping([ + "exemple_id" => 3, + "exemple_name" => "Encore un \"autre\" exemple", + "exemple_description" => "Voici une description d'un être aimé,
, ou non", + "exemple_number" => 21, + "exemple_date" => "Miam", + "exemple_boolean" => false, + "exemple_float" => -82.3465, + "je_suis_un_champ_inexistant" => "je suis un champ inexistant", +]); + +echo $exemple3->getExempleName(); + +var_dump($date, $exemple1,$exemple2,$exemple3); diff --git a/test/Charly/01-begin/02-mapping/view/README.md b/test/Charly/01-begin/02-mapping/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/01-begin/02-mapping/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/01-begin/03-test-mapping/index.php b/test/Charly/01-begin/03-test-mapping/index.php new file mode 100644 index 0000000..78a6b06 --- /dev/null +++ b/test/Charly/01-begin/03-test-mapping/index.php @@ -0,0 +1,207 @@ + + + + + + + + Test des Mappings stagiaires G2 + + +

Test des Mappings stagiaires G2

+

Table Article

+

Test de model/Mapping/ArticleMapping.php

+ 1, + "article_title" => "Titre de l'article", + "article_slug" => "titre-de-l-article", + "article_text" => "Texte de l'article", + "article_date_create" => "2021-09-01 12:00:00", + "article_date_update" => "2023-09-01 12:00:00", + "article_date_publish" => new DateTime(), + "article_is_published" => true, + "user_user_id" => 1 + ]); + echo "

getters de article

"; + echo $article1->getArticleId(); + echo "
"; + echo $article1->getArticleTitle(); + echo "
"; + echo $article1->getArticleSlug(); + echo "
"; + echo $article1->getArticleText(); + echo "
"; + echo $article1->getArticleDateCreate(); + echo "
"; + echo $article1->getArticleDateUpdate(); + echo "
"; + echo $article1->getArticleDatePublish(); + echo "
"; + echo $article1->getArticleIsPublished(); + echo "
"; + echo $article1->getUserUserId(); + echo "

"; + + var_dump($article1); + ?> +

Table Category

+

Test de model/Mapping/CategoryMapping.php

+ 1, + "category_name" => "Nom de la catégorie", + "category_slug" => "nom-de-la-categorie", + "category_description" => "Description de la catégorie", + "category_parent" => 0 + ]); + echo "

getters de category

"; + echo $category1->getCategoryId(); + echo "
"; + echo $category1->getCategoryName(); + echo "
"; + echo $category1->getCategorySlug(); + echo "
"; + echo $category1->getCategoryDescription(); + echo "
"; + echo $category1->getCategoryParent(); + echo "

"; + var_dump($category1); + ?> +

Table Comment

+

Test de model/Mapping/CommentMapping.php

+ 1, + "comment_text" => "Texte du commentaire", + "comment_parent" => 0, + "comment_date_create" => "2021-09-01 12:00:00", + "comment_date_update" => "2023-09-01 12:00:00", + "comment_date_publish" => new DateTime(), + "comment_is_published" => true, + "user_user_id" => 1, + "article_article_id" => 1 + ]); + echo "

getters de comment

"; + echo $comment1->getCommentId(); + echo "
"; + echo $comment1->getCommentText(); + echo "
"; + echo $comment1->getCommentParent(); + echo "
"; + echo $comment1->getCommentDateCreate(); + echo "
"; + echo $comment1->getCommentDateUpdate(); + echo "
"; + echo $comment1->getCommentDatePublish(); + echo "
"; + echo $comment1->getCommentIsPublished(); + echo "
"; + echo $comment1->getUserUserId(); + echo "
"; + echo $comment1->getArticleArticleId(); + echo "

"; + var_dump($comment1); + ?> +

Table File

+

Test de model/Mapping/FileMapping.php

+ 1, + "file_url" => "https://trello-logos.s3.amazonaws.com/c3f2bef1693561dfb24e0f00aa592c80/30.png", + "file_description" => "Description du fichier", + "file_type" => "png", + ]); + echo "

getters de file

"; + echo $file1->getFileId(); + echo "
"; + echo $file1->getFileUrl(); + echo "
"; + echo $file1->getFileDescription(); + echo "
"; + echo $file1->getFileType(); + echo "

"; + var_dump($file1); + ?> +

Table Permission

+

Test de model/Mapping/PermissionMapping.php

+ 1, + "permission_name" => "Nom de la permission", + "permission_description" => "Description de la permission", + ]); + echo "

getters de permission

"; + echo $permission1->getPermissionId(); + echo "
"; + echo $permission1->getPermissionName(); + echo "
"; + echo $permission1->getPermissionDescription(); + echo "

"; + var_dump($permission1); + ?> +

Table Tag

+

Test de model/Mapping/TagMapping.php

+ 1, + "tag_slug" => "nom du tag", + ]); + echo "

getters de tag

"; + echo $tag1->getTagId(); + echo "
"; + echo $tag1->getTagSlug(); + echo "

"; + var_dump($tag1); + ?> +

Table User

+

Test de model/Mapping/UserMapping.php

+ 1, + "user_login" => "MikeTyson", + "user_password" => "password", + "user_full_name" => "Mike Tyson", + "user_mail" => "test@cf2m.be", + "user_status" => 1, + "user_secret_key" => "secret 123", + "permission_permission_id" => 1 + ]); + echo "

getters de user

"; + echo $user1->getUserId(); + echo "
"; + echo $user1->getUserLogin(); + echo "
"; + echo $user1->getUserPassword(); + echo "
"; + echo $user1->getUserFullName(); + echo "
"; + echo $user1->getUserMail(); + echo "
"; + echo $user1->getUserStatus(); + echo "
"; + echo $user1->getUserSecretKey(); + echo "
"; + echo $user1->getPermissionPermissionId(); + echo "

"; + var_dump($user1); + ?> + + diff --git a/test/Charly/01-begin/04-manager/.gitignore b/test/Charly/01-begin/04-manager/.gitignore new file mode 100644 index 0000000..d11ccf2 --- /dev/null +++ b/test/Charly/01-begin/04-manager/.gitignore @@ -0,0 +1,11 @@ +# Ignore config file +config.php +# vendor contient les librairies externes en PHP +/vendor +# fichers non envoyés +# PHPStorm +.idea +# VSCODE +.vscode +# Charly +.history diff --git a/test/Charly/01-begin/04-manager/config.php.ini b/test/Charly/01-begin/04-manager/config.php.ini new file mode 100644 index 0000000..ae92c13 --- /dev/null +++ b/test/Charly/01-begin/04-manager/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/01-begin/04-manager/controller/README.md b/test/Charly/01-begin/04-manager/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/01-begin/04-manager/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/01-begin/04-manager/model/Abstract/AbstractMapping.php b/test/Charly/01-begin/04-manager/model/Abstract/AbstractMapping.php new file mode 100644 index 0000000..6c5f9c1 --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Abstract/AbstractMapping.php @@ -0,0 +1,42 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst', $tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + } else { + // sinon, on affiche un message d'erreur (à commenter en prod) + echo "$methodeName n'est pas un setter valide
"; + } + } + } +} + + diff --git a/test/Charly/01-begin/04-manager/model/Abstract/README.md b/test/Charly/01-begin/04-manager/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/01-begin/04-manager/model/Interface/InterfaceManager.php b/test/Charly/01-begin/04-manager/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..421a87f --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Interface/InterfaceManager.php @@ -0,0 +1,16 @@ +connect = $db; + } + + // sélection de tous les articles + public function selectAll(): ?array + { + // requête SQL + $sql = "SELECT * FROM `comment` -- WHERE `comment_id`=999 + ORDER BY `comment_date_create` DESC"; + // query car pas d'entrées d'utilisateur + $select = $this->connect->query($sql); + + // si on ne récupère rien, on quitte avec un message d'erreur + if($select->rowCount()===0) return null; + + // on transforme nos résultats en tableau associatif + $array = $select->fetchAll(PDO::FETCH_ASSOC); + + // on ferme le curseur + $select->closeCursor(); + + // on va stocker les commentaires dans un tableau + $arrayComment = []; + + /* pour chaque valeur, on va créer une instance de classe + CommentMapping, liée à la table qu'on va manager + */ + foreach($array as $value){ + // on remplit un nouveau tableau contenant les commentaires + $arrayComment[] = new CommentMapping($value); + } + + // on retourne le tableau + return $arrayComment; + } + + // récupération d'un commentaire via son id + public function selectOneById(int $id): null|string|CommentMapping + { + + // requête préparée + $sql = "SELECT * FROM `comment` WHERE `comment_id`= ?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + $prepare->execute(); + + // pas de résultat = null + if($prepare->rowCount()===0) return null; + + // récupération des valeurs en tableau associatif + $result = $prepare->fetch(PDO::FETCH_ASSOC); + + // création de l'instance CommentMapping + $result = new CommentMapping($result); + + $prepare->closeCursor(); + + return $result; + + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + // mise à jour d'un commentaire + public function update(AbstractMapping $mapping): bool|string + { + + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + // requête préparée + $sql = "UPDATE `comment` SET `comment_text`=?, `comment_date_update`=? WHERE `comment_id`=?"; + // mise à jour de la date de modification + $mapping->setCommentDateUpdate(date("Y-m-d H:i:s")); + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + $prepare->bindValue(2,$mapping->getCommentDateUpdate()); + $prepare->bindValue(3,$mapping->getCommentId(), PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + + // insertion d'un commentaire - À modifier ! + public function insert(AbstractMapping $mapping): bool|string + { + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + + // requête préparée + $sql = "INSERT INTO `comment`(`comment_text`, `user_user_id`, `article_article_id` ) VALUES (?,1,1)"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + } + + // suppression d'un commentaire + public function delete(int $id): bool|string + { + // requête préparée + $sql = "DELETE FROM `comment` WHERE `comment_id`=?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/model/Mapping/ArticleMapping.php b/test/Charly/01-begin/04-manager/model/Mapping/ArticleMapping.php new file mode 100644 index 0000000..7a2fc92 --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Mapping/ArticleMapping.php @@ -0,0 +1,124 @@ +article_date_create; + } + + public function setArticleDateCreate(null|string|DateTime $article_date_create): void + { + $this->formatDateTime($article_date_create, "article_date_create"); + } + + public function getArticleDateUpdate(): null|string|DateTime + { + return $this->article_date_update; + } + + public function setArticleDateUpdate(null|string|DateTime $article_date_update): void + { + $this->formatDateTime($article_date_update, "article_date_update"); + } + + public function getArticleDatePublish(): null|string|DateTime + { + return $this->article_date_publish; + } + + public function setArticleDatePublish(null|string|DateTime $article_date_publish): void + { + $this->formatDateTime($article_date_publish, "article_date_publish"); + } + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + $this->user_user_id = $user_user_id; + } + + public function getArticleIsPublished(): ?bool + { + return $this->article_is_published; + } + + public function setArticleIsPublished(?bool $article_is_published): void + { + $this->article_is_published = $article_is_published; + } + + public function getArticleTitle(): ?string + { + return $this->article_title; + } + + public function setArticleTitle(?string $article_title): void + { + $article_title = trim(strip_tags($article_title)); + $this->article_title = $article_title; + } + + public function getArticleSlug(): ?string + { + return $this->article_slug; + } + + public function setArticleSlug(?string $article_slug): void + { + $this->article_slug = $this->slugify($article_slug === null ? $this->getArticleTitle() : $article_slug); + } + + public function getArticleId(): ?int + { + return $this->article_id; + } + + public function setArticleId(?int $article_id): void + { + if($article_id<=0 && $article_id !== null) throw new Exception("ID non valide"); + $this->article_id = $article_id; + } + + public function getArticleText(): ?string + { + return $this->article_text; + } + + public function setArticleText(?string $article_text): void + { + $this->article_text = $article_text; + } + + public function __toString(): string + { + return "article_title"; + } + + +} \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/model/Mapping/CategoryMapping.php b/test/Charly/01-begin/04-manager/model/Mapping/CategoryMapping.php new file mode 100644 index 0000000..cbb3d1b --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Mapping/CategoryMapping.php @@ -0,0 +1,89 @@ +category_id; + } + + public function setCategoryId(?int $category_id): void + { + if($category_id<=0) throw new Exception("ID non valide"); + $this->category_id = $category_id; + } + + public function getCategoryName(): ?string + { + + return $this->category_name; + + } + + public function setCategoryName(?string $category_name): void + { + + $text = trim(strip_tags($category_name)); + $this->category_name = $text; + } + + public function getCategorySlug(): ?string + { + return $this->category_slug; + } + + public function setCategorySlug(?string $category_slug): void + { + $this->category_slug = $this->slugify($category_slug); + } + + public function getCategoryDescription(): ?string + { + return $this->category_description; + } + + public function setCategoryDescription(?string $category_description): void + { + $this->category_description = $category_description; + } + + public function getCategoryParent(): ?int + { + return $this->category_parent; + } + + public function setCategoryParent(?float $category_parent): void + { + $this->category_parent = $category_parent; + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/model/Mapping/CommentMapping.php b/test/Charly/01-begin/04-manager/model/Mapping/CommentMapping.php new file mode 100644 index 0000000..c3de343 --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Mapping/CommentMapping.php @@ -0,0 +1,152 @@ +comment_id; + } + + public function setCommentId(?int $comment_id): void + { + if($comment_id<=0) throw new Exception("ID non valide"); + $this->comment_id = $comment_id; + } + + public function getCommentText(): ?string + { + + return $this->comment_text; + + } + + public function setCommentText(?string $comment_text): void + { + // cryptage + $text = trim(strip_tags($comment_text)); + $this->comment_text = $text; + } + + public function getCommentParent(): ?int + { + return $this->comment_parent; + } + + public function setCommentParent(?int $comment_parent): void + { + $this->comment_parent = $comment_parent; + } + + + + public function getCommentDateCreate(): null|string|DateTime + { + return $this->comment_date_create; + } + + public function setCommentDateCreate(null|string|DateTime $comment_date_create): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_create, "comment_date_create"); + + } + + + public function getCommentDateUpdate(): null|string|DateTime + { + return $this->comment_date_update; + } + + public function setCommentDateUpdate(null|string|DateTime $comment_date_update): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_update, "comment_date_update"); + + } + + + public function getCommentDatePublish(): null|string|DateTime + { + return $this->comment_date_publish; + } + + public function setCommentDatePublish(null|string|DateTime $comment_date_publish): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_publish, "comment_date_publish"); + + } + + + public function getCommentIsPublished(): ?bool + { + return $this->comment_is_published; + } + + public function setCommentIsPublished(?bool $comment_is_published): void + { + $this->comment_is_published = $comment_is_published; + } + + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + if($user_user_id<=0) throw new Exception("ID non valide"); + $this->user_user_id = $user_user_id; + } + + + + public function getArticleArticleId(): ?int + { + return $this->article_article_id; + } + + public function setArticleArticleId(?int $article_article_id): void + { + if($article_article_id<=0) throw new Exception("ID non valide"); + $this->article_article_id = $article_article_id; + } + + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/model/Mapping/FileMapping.php b/test/Charly/01-begin/04-manager/model/Mapping/FileMapping.php new file mode 100644 index 0000000..e26665b --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Mapping/FileMapping.php @@ -0,0 +1,64 @@ +file_id; + } + + public function setFileId(?int $file_id): void + { + if ($file_id <= 0) { + throw new Exception("ID non valide"); + } + $this->file_id = $file_id; + } + + public function getFileUrl(): ?string + { + return html_entity_decode($this->file_url); + } + + public function setFileUrl(?string $file_url): void + { + $text = trim(strip_tags($file_url)); + $this->file_url = $text; + } + + public function getFileDescription(): ?string + { + return $this->file_description; + } + + public function setFileDescription(?string $file_description): void + { + $this->file_description = $file_description; + } + + public function getFileType(): ?string + { + return $this->file_type; + } + + public function setFileType(?string $file_type): void + { + $this->file_type = $file_type; + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/01-begin/04-manager/model/Mapping/PermissionMapping.php b/test/Charly/01-begin/04-manager/model/Mapping/PermissionMapping.php new file mode 100644 index 0000000..a17e27a --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Mapping/PermissionMapping.php @@ -0,0 +1,49 @@ +permission_id; + } + + public function setPermissionId(?int $permission_id): void + { + $this->permission_id = $permission_id; + } + + public function getPermissionName(): ?string + { + return $this->permission_name; + } + + public function setPermissionName(?string $permission_name): void + { + $this->permission_name = trim(strip_tags($permission_name)); + } + + public function getPermissionDescription(): ?string + { + return $this->permission_description; + } + + public function setPermissionDescription(?string $permission_description): void + { + $this->permission_description = trim(strip_tags($permission_description)); + } + +} + \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/model/Mapping/TagMapping.php b/test/Charly/01-begin/04-manager/model/Mapping/TagMapping.php new file mode 100644 index 0000000..798f6b9 --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Mapping/TagMapping.php @@ -0,0 +1,44 @@ +tag_id; + } + + public function setTagId(?int $tag_id): void + { + if ($tag_id <= 0) { + throw new Exception("ID non valide"); + } + $this->tag_id = $tag_id; + } + + public function getTagSlug(): ?string + { + + return $this->tag_slug; + } + + public function setTagSlug(?string $tag_slug): void + { + + $this->tag_slug = $this->slugify($tag_slug); + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/01-begin/04-manager/model/Mapping/UserMapping.php b/test/Charly/01-begin/04-manager/model/Mapping/UserMapping.php new file mode 100644 index 0000000..400ecea --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Mapping/UserMapping.php @@ -0,0 +1,87 @@ +user_id; + } + public function getUserLogin():string{ + return $this->user_login; + } + public function getUserPassword():string{ + return $this->user_password; + } + public function getUserFullName():?string{ + return $this->user_full_name; + } + public function getUserMail():string{ + return $this->user_mail; + } + public function getUserStatus():?int{ + return $this->user_status; + } + public function getUserSecretKey():string{ + return $this->user_secret_key; + } + public function getPermissionPermissionId():?int{ + return $this->permission_permission_id; + } + //setters + public function setUserId(?int $user_id){ + if ($user_id < 0)throw new Exception("ID non valide"); + $this->user_id = $user_id; + } + public function setUserLogin(?string $user_login){ + $this->user_login = trim(strip_tags($user_login)); + } + public function setUserPassword(?string $user_password){ + $this->user_password = trim(strip_tags($user_password)); + } + public function setUserFullName(?string $user_full_name){ + $this->user_full_name = trim(strip_tags($user_full_name)); + } + public function setUserMail(?string $user_mail){ + $this->user_mail = trim(strip_tags($user_mail)); + } + public function setUserStatus(?int $user_status){ + $this->user_status = $user_status; + } + public function setUserSecretKey(?string $user_secret_key){ + $this->user_secret_key = trim(strip_tags($user_secret_key)); + } + public function setPermissionPermissionId(?int $permission_permission_id){ + $this->permission_permission_id = $permission_permission_id; + } + + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/model/README.md b/test/Charly/01-begin/04-manager/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/01-begin/04-manager/model/Trait/README.md b/test/Charly/01-begin/04-manager/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/model/Trait/TraitDateTime.php b/test/Charly/01-begin/04-manager/model/Trait/TraitDateTime.php new file mode 100644 index 0000000..6b56182 --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Trait/TraitDateTime.php @@ -0,0 +1,34 @@ +$paramName = $date->format("Y-m-d H:i:s"); + } catch (Exception $e) { + // en cas d'échec, on met la date à null + $this->$paramName = null; + } + // si c'est un objet (DateTime seul possible) + }elseif (is_object($date)){ + // on formate la date en string en DATETIME + $this->$paramName = $date->format("Y-m-d H:i:s"); + }else{ + $this->$paramName = null; + } + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/model/Trait/TraitSlugify.php b/test/Charly/01-begin/04-manager/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/01-begin/04-manager/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ +PyA07*naRCr$Oy?K;mXL;uNyK8K@XDykvuc}h1w3K!%v;q3 zGkvE2oO7iArrXBGHnuU??mq1~LH8jeEc6d$;F(UZYwoN490t{4fj?FlPO(^`DFB3Pk7mWKUij zbKkMGdKP~Rj9C{iA`AmweDS9|^w2}R^2#e1m1;3^Y-biITOeKh1zrx%Om1?dkdfT+ z^99rdehnDPJL&gsJmj2OKwaGGm<4AM#|vTO@exw!h#vZM=N*yZpHeREG? zITcvr``LW53mMoZRLy;=Sj)NZX4CpZ@Gc9+H?; z5=SkNF8MuqS8v#SLnRgzT!e;>LZc>YCRmx3M=~Ico#Rshwf>s<+~g+sCs>qsm-8|8 zo9nOUJ)#wmF6v${3ZxQ~TBg;CNf&iVFWi%6-%Nv0Tu=i70V+@<#PfVCO!XxeE^$K> z3<-#mpUpWSvf{Kv@_YFng*q>#z6_Amg}j#nC=pf!PU7y)${gwI)NE1bdH@&hN-nQ= zZh>@p-H&&5HjSI9O;%`Vp!z@+`5qBAS<|`I?o$!S zu4O8KrXsMzNVWyZI@YsQ2|#Br!jsE2@9Ltw2VT4&NK2)Hib-3R^y0YN%E47u%}{{! z4GqxYnMr2KWqjAdOSyPvY(?wVRLo-HEotaQQADUrWT<{_!8E9*U24jAjlov;J9X5VDmb5jTx%?f_cpQzZo$Ow~&kQy)=MErdJe%=}zrJPDrH647hf?^vbsbnZ8 zwW+46<5kc=jzXOVmS<>>)lkVGTUkc^2#kopmRI<=wF*5E+_d#lws&>W7Jw^aNY4hG}4i0z5+{h7?FmsKp>ndj(d65w~vM$*#^$ z+GCK0mVjA5U*0{{0_ma_(}I?CdU`TyYirXnND}n7Ea{>y?uB?#Gf2g*RWTWk;HU2h zNXIFpGn8x>->~8gthlp2h5~2|(nz@40@T?cl_XTNC3V9FNPQDLTP&+b#+zY95OVwG zom|%0MZ2$)N7zyhl6R3LQk?Z|HsCFHcittlAV{aCCZhKC_7+Gl1me!>Jym5?#g77o zihvY&;hlrLGBHj*lclUcYN{lU8HG4zMC6Oj4dU9V_@x43QzxOsk|uRj10)s|cUM5F zYM`+tRUkDyQnfrQLk-g1T|IPGCH@ruILQ>v_rdggs4`9y1@){h!F%jQiw0@KiYlAh zYE@gN3qfahRrE+?SdjE#hj@8nfIxW>~z|=XZPiplNG7U=nz-V z&kG?8!7(B2f@`Y3i7PBw>A5t**=ui^UikBPS}l;C$BTO*4sFCG6YZCplud&Z0@8s) z{CaXyxw}=vR`IHU)CmI|-=jD=%FxkwXmc!#a!tjWs;(J7l!db-*`y!Jl1faflD{!X zZDAONSmiR^m4IDtJ0IPB4ej{~xgbIk%Cg`BFT}G=QfpRXZ|sLQm(Vfr#KXqGmJOnr z9aRsrF2ohR@b9@Okal!*%sJDRCB5*sZvHb+AQh{n93GRhWiSXlcjOQ+O-`xAQ4nc& zR=cbr*&yJhpFGPmk39_I!%(YW2SIE}^`SIKCEYUzq_I0J_1Kyvqy<4Tg_FScSk> z?rp=AYInEJ0hISp;jg%^@!!Oq4Ggk@%}Nh0GdlU$rPr`6O4C&faSemOFqrZ@!oD6h z-hDG$?!OZ@tt85t6l0L4FcsL7$8UO!x}YU(fpodT@idmyk5{;9P_iuz(!&Q8NK5G~ z0Zwd54bnkCN6q8)r=H>mfBQEuG6-HlWqca|Z9>fKO}*)VVrq4{wGERF&u1q&?p?c^ zySg{gGviU2oF?1RLD8`|mWfz>?=5Wq;=h7b?U1u5IP!9Xw79(Ww>09a!f!4ce?gE+ zowO~dOE4`|#UBA(||ZN@pn8CMVi0QXjmUUBCYsSl0t> z4kcF?f#$cQEs(~6$I0$)3#5x(p3CETYS*n>(kQm12}q|JAT=aQqe0qMDskYMXEaEM z1*D~S1yXTq)4tDoEcVdDXSQC=E~}GlzDmk)C=fB;m8QIB6W9FjpNH*hpxvS3=nSup zN$0w|Es!Q46=jB>{PZWPpY*lYUd3pEba{Ypv1g${npo0>Kx!&?x4oEv^lSLTgW#9z zAl2O5*&U{*OXR3zlwsidJ}ZIUbo22oS8`oPKfTi)ZY`t|8BBGinB2CC8~@`MVb=!e zO5??32Wg{A>aX&-f79i9=2K>P;e{7?=%ELB{q@&dAYCjtmdo=_57OzAENR*gX)hIH zODZ5eLFCP~q`DT`NaW16YR#Y(a0y?@5%2>W$#C!1J-n}T4Vwy(&U+Y^!(`fIY<(9u z{onr{cCCY+ERn5S>*j*81=87x08tBk?z!g_NZ)+(O^jCJXt}^|ap!R|NF}=~?(P6D zO$tbJ1lWq`Ahf@wk?uGDuWwwxlsY1*CK8l?gcK1F4j7(!fe=Zd|dM zn|n8KquE8rjE`+NOt}WbD>K~uAHD!LUk)pBI(sagHL4!l*a%u6oefga-F@bnrW8#)*h*8nX^DD1p5}_XmJ2p4$nFpkakzA?0xD94bs75ipY>y()p}uv*i>k zEB{ZvtC&<7;Rw%)RJ~JrOE=>3@zs0y$lA;3I5LH6S{zRYSl4dj%K!7A7Z$J5CzW3Fy5DG}6;EX^T z`^CytReh#fe1)p?mqySNnyiWp-k;sded{l0citxJMNGBZOs((W@_+wn(zos*vO`Kn zs0a^<>U}G_8%xa8m%u!hw3RqoJV2JiGv|V|7=u)CcTWM*Uf<*GCw|PMfA#051nKEM zTXW1h7o>7NU0AdQ0lVqtp1$3DFte6iIiT9^Fqn(z|JW^T`~3Z|aV7b}B)K-p3%6p@ zdQ85MyW0Zka)93A&!G-d`N0gB3(`_5hc8_)P1)UZ3R2Y_6HADyVSEwohE2N%Ye;jA zy_yHsT+Rlk4N+>yXHBf#8@c8WJ_CEU;5i|dtr|~TiKF-mEa>jG$P9}I$Z~k5x}l2E z7ZFKzH?gFLrBy9Y@hm{P7%MtACY93=cUSsEh31zFO*(y(HCTMC=W?!Hxsfh2g>OWZ zJ5${Bd!NGk_$`ow(3bwv*6g80TT&4sYt}f@FKl(eEC)c&cMh{aDlw_4W76lEKpGg* z^xdeFCYJP(zx*>I$?ndHNzW9dk}MKZf+#g4QoC*dnZTeoGT6gPZd$#StGd_Gm+NG@ zRAA!=ZlLdTABG)kkPh@PQR1G%IBM3{Uat4xT%Xs1mb3-ZbA8Fr@A2v&H6lW>q^8Nx z0w9&d(Y~jj>#dRHJ#fTJ{#6oV*M236k-QUT;V*k*Kad*?>(ShJIr zp2b8^VfXJpz{(F@2Rk=8rv>fppqS5-U0+L6VeYL?^#H zu-IvJazod8uJ2e!fA31njVrm~cRm3-*TU9*ZH0XiGJvIep))k+aNm#ORZD#QFPG>?)6e=z~I1=5QGdW%0v0jUg% zP?l7=yV{bT4x~a09C+bbzWvAl874;0IY^b{O7aleplOhfOfr!{FBX^CE4gCLX4dwu zqJQfquDJVl*4=so^!HGuN|;S44_+mUl~T*uL#zeT#jmB-Gtbi%NI)vHSp=ja=~)Nq zcwWn=%yDA(HD-h8aQ8&aw6!g#b(E{n&Ub)um&e;`E@nY=m&IRc!<2oh{tl2T?c?W6J zr_(cJBrerJllU}^$x1S8%5<}3Wj{N2?Bx9)xs%=Z+=jiek7>W8_`GSu!WQ9dHOHp$ zI1|veKzh!WTI)b(dj<4}!iKvmmUKiE>?I~$1|SuX$Oy!G7FZ>tL)viYC&Rj27rmKw zZoK^#uK(CwyzirTQZWOSDRwOz%d!ZqIho!waDUbNHogDZUgxEJT`MMC%B#Hu@1>OH z)xZcDMc8n6f3i$KDwiM`Qz63IGXKppBqI&oIP{tstk7fU)=RnZ&fB^3zK?R{)q5~A zDcuzAYLJFaEBDNFdE*VD38<&a5-*qOZVQ66#ob*3WSzseP-7s(lEyJX7{u=a$IL0`kuo(x`-~A$;t7kvs2o3n;$J&;5oeu=kQ<` z1xVw?ucj`>>iCiYmdW7~tBMerBg6+x+S}Us;vf7keDM$dE&W?IQ!M1MOcUF-FolRO z^J$u8$KeY#9@sBgx{X(}Gx3xafXY&h!e>1}~@8QiSJ zoWex`(o=nqghnWn)k2wRYN}FAA*iu&-FiNB-#y&*v3uEd-PO3+EV)!xHJ6KPtSqC< zkpbEg(;9qR%=8_#d$YyhN zc6ZU$-A%Tw4cmtmc7_aE#zh{Unk%KDD#y|xaY*F(M7~dZCabKeIL_i)E*EenH+n&L zw*}IR1fB6|o-IfZKK~5g`IA39KeWKbUc$uPjX|1<=haBb#+NVGB5*B8J8a%_B{$!8 z8<+373OAR<$)-uSx6{?$Nl&VSb~jBXoziOhVp$sIg<~5N|2fgq%wF|YNSRwMHKq1 z+_sggZ@Q6d-v2(@R`o(#hRAT}&i0UVvt&{(Y0D<(q{uocT-(O zAZx(J!^lHvjGOal;tVgfrJV~>5yuuu&j%lTh<*F^VzeyjnXIx4|J<_$>HcS);^9C0 z5{wRCSdb={P-4>9l1d#^7)O4SXm;d#3Q^f@o7r{k9;S3BKVF1lo2+GR54s zaczf`63-UPYZ;h*E9qIYnmyND$2IS}nYL9M z@$EE`ZBY|)zGdK>sGl7I(&ZA}VZ`oLYq@IU7CJ2hH!jntfm1T@DhSl1^!f*FUh*=r ze93%b9Va)}h@vp$>8BC}`xZ!-D;7_AUS|tZkx%*VU;OF3@+l{cnNW@8rvPbO?l|3r zTc}xkF3rzY>VdHZla!B=XNiF#Kuy`u)<&kSou2-6eBk5%nx6HW=vmW8#e|9(QL_xH zDl6oZ@+)+Qu%~w|H*VQPn-6JQCz!eCr+_{5XPcK$3gWHzHa82^%X*Kcf>fW`yZ{sG~Lr9x?gpM59i6TsK zdFK-Mmts?B_G>n^sY+E|s&kjbR5GHJX_ih^z6 ztm@&?Ti*v)?t+v-=o)y^Ef?zxpX+WmpkbA-v}9`AHY3v&gsWhF`v zssg?ti65yECkY=Nxi&Th0iu99Vl!#(>)Foz8!w}OszPTaP`?ihL(R__P8pb2Y~za0 zKLGFF16fmz&5-dIOAAs>Rh;z*quG{paPU~PdUan5q-Tzo3-XHP4pLRBoV)1euC4_% zixQwF7QImt5r8JvbpFe4g^}uz*^0~ko!fX|<8IbWlS1=6Lt5$Eb%mIFu|?(qDKhXoAj$@R$v zF3wyX-c#@_)KSD*N*#174)=F$52xsE%&UcZ{M2M^bQk(m`w)4P-%UCm6p{wH057OWL6ue(7sYTVXi7Z2d^mIGH zIk}UKgDeQrW5u;KzfcZ{P{ZEQh-#rqq83|11DDflLai#P@1}~OCa-HL{VRf zq@n7Wr>muk!1w7NvkS532c)sPt3bL3a*lF$qq-$s=p4`89X>rs2QXS7o$q3w+Z&X` zXbUg4g~@0a0;J6T+RQI7S)nh@Bw%pyhw<5VYI!Pgq#zkD*jaw*j(&XrrwMs2HNMlk#^68||pTnfTvxn8~U1V&B@ySVMN(E-TA~m3_ z1hF;QAQ1=?pd~nLc6T+ysOjU^FJvNetw{}weVmmg6_92fe6gg<5v0Glb<&2#Y%Bnc zJPpM-zN&xM8aa~nlUOY2g;aeNiY+75?YM4N*P5Ii+a-TZOokNURU>kuXcwE4y1-Ub z|7CKHDlwyC!g#70Fhax&0|UG=KBI>SThdjj+nh6g$cn({?I$$BJ{&xzq_xesOrkar zi6u`PCpI=KDQ~o6u$C=7{Tq1g?Kc=J=Q&&$V}ugZM3lv%+Nkz1U)483#IcRI zS2eMo&BE3V&qV{Yv7t5j!V94FJqgm^+@|mOL8=#u2C3fE^%QCi-9#obF0RMZsRL=i z*3wt8eN3!?HW6xmi!vkP%4%Dz++3v(8)^3{jHNx~iB0m9^7AZL@qB<(n#fOE+nf#3 z4h%Mv<&*37aMjB7xM`PT6Qk@KKf&7*gX|9{m=U0w2A*qCj(q$;N+9~=)uz^DJ)8ZN z`p@-iprt$)8zR0ZLHe6b3!LrFCLU)3P+ew7#udbVSyP8_;?4RkKIiH0vkS;bbxJaK@cdt|o6cLJGm0>E^HgUgn461=9)>8nQ2&&8XxsT*^N$pTA z!uUzzkSeFt_sLk6O2`PgS{q$$b#*M;6yGZBC$nIDN*Ii)Sug{<9J{+3q{=B@oV&XS zkS1p!F{$)wZX?6L>AQ;G>fV5puaGh=4A-WTbvPIld1G>rH%5+f&>vxjK*g%^*{ej9 zfSQzZ=FDkHK$?)}^|fwJsx7>*gs`9)NAuN5wH0rW8Mbk$lwevh>B1NG!at({0$CHv z6_dD6GM8b5bZHo}=3{`#f~&^h%!g13pccv?+z3zVg~;oqb|{(80N?ZCeo3*)2DV|T zMV*nc^@Oa*rs;HS(qdgCQyO=CD7Raza#M*TNnNQJ*zhSDFea9CV1Sn=bWG}-);R@f zGjTyDj!+=|-0D5t(y@W=N<><8gXFqc2BTq>$yCHxCgRt_hk0%MIOUYZbgjgABr$8C zwQ`%LMI@VFqR5c^KS{35UL&UvQBqz>LJOP=Qq4FLZ>D0J3@cjTHg-0FG-yg3or0cD&>GULhD zNyMw?lWHNdq7gBM$xj9j@$!ToB781Es<*F(Fqy=aSztS9zQ_H-$^ZZ$07*naRIq9f zw{~n`MJXaz)9!3!o0J@}?lp?tX^w_PCNma?^J5$y8RE#q2$R$(;88_tt=hVZN1}k6 z3}0$a=+^5q2{=!Eel@RWnGFKFVge zG=p>kOAisA$WuyXsTt-hOWNysO5^DJfBhAF$?k@F!K&lQ?lH&RZFa94Al1(okY*wQ zX^PLUzKYx0H?XQ~D3D5)T2%Y|oXdz;V#Q_KXy3e!ePcr$96rI=)FhMDB1fmk7%WUN zT$~_}Pl13Ufr?!Pu+q~hpgo(1oS%$b+=>;`0xyqgff7bYPF#ajENN}eR(3VJyS7af zmtdBaCB3-G3@7iXD(#|HR&00Trz96$rGgA8!pCJwm0xY#5^=XAPMi#3I3F-pDKS*c zGwIiusFo>s9yO(AXA#Jv#L#i6DRekf55JAIb4-!<5Ri#>j>NX|<%gJ+8kr!XLzF+F zkUOrtj6N4Sl`^az|7PXHQ#4sVw4k;qYM|O7^xPS3@S`g zA+G=%Dnf+PI!d^}aZ~u*`f*}#6VktGRRgwQ^6{=6Jh1U{`o=4CR%4JFQWnx6t?t>% zWxpo``?yZ3MlI^i=7NHBRu{}gO$(fr1JzccPAX`24CgS0l#HXUc#3=Fg<>@$GLEHS zF%iMO$s)&RW*D29q2T)z0-vg6B*jV!z%5(t$e|)97z9yVT2aP0ib0iFsz!N3K&zUQ z&4^SG&|dTDta{va#g(jcWfC?-RUa#36UDGK*UXGeE(Q7@eHqcs|cSxyV!)Q1*QS!&KlDKiDs*S zRdL`N<@bjCPDB`lDiLJa7BW4|5W%akhE=Q4QT6Gmc-(*WRcvrj(vwsYwnVJ=6US*u zy;MbqF~L0nsUkBRY=AU$W@mRhD-{LO$G-lT_``!3e(fB9)K(z9r9(h!(oxmPBXRd< zG8O|VkM=vSXZvSA4%;_ExeOCU7|C<+2TzedbexGJ$FaOXCDNvgd5V!o-UukBOh!sG z3{OokUdmGw>+DyU@k$h^QWin%*jJMK+nD>(kkDO&!JXDd?pb#!oBb5os;_qI21ucD z%~p0dCyqpsFxJbykd{<7uOCXQnt)VV)h=F;He6b5zmm@Vcw#_(h-?hdqy}Od%vcdc zg$Gl89hsV7C|_WBdWPwmPr;NfeNDFZBSQgMmt1s0DM|I#`zj?VR3H5wDVkqhrcrtr z<7}-d6NBU!k&o+p$_48!``ml^)oip=q~#n-Rj3y0?1sRKu)5m8m0m}2sV$<&RF-71 zmQ+A`;F+iDAjPYm7Nm(q)mdfP5n`v)09)pYhLYX2_#LsNo$KkZ*>#YLJ1U8zfs{|~ z?i<+jxsSunO~S(0u1GC}qsN(iYd@o}?`LZ70Of%}%$W*Z=^Qe3{`knSBIzqtdNX2h zYMg>!Wu{spAJ&+Xtajv4u9d09<0z!_MmB1>!qr-l61>#F1Fi7D&&hg^gXyWK=Qfo z3wcttn#wq?Cc+Gzqr#Pswe?LoxV>3*(VxqYkyb4xJq zF-w|UA)P)*vZ-~#K}^T{u`&PJ}fErY1Q&GR|LEXdSQSbBgt};MhY>OWNJj7V_4HE97u5g9hKCqDae|SNVPcv8VH7r%LoyB0hP=b!@RRtny9lQiYz54ytBItusTkx|7w{?qcg5H^GWFwazWK zEe0tR2pKaB?e3~NX(o|;2haxa6TOpXjexuk~!h4SU=pM!w37t!aN^wk1BbNP*IHM8{j7EYl`M>@l_ zS79P!knhQ`}!Y z&KRVtui%!>b*!#X2dOOYk{NL{hXU#5FMbL(_d$CG<(|l9DsH=KAeZYZH_n04DHxrG z!y^=4-bXMv$@tL|c$0amqf@xm0NV>lVX9Gvs=d#YjaN3{xa6gd9T8d~u8=Njs05Xz zSX^3!Of0DaX&Oq`ZPFl>?5-s1WR%5n1nGOH>Dv%vryi0Rl?7b3pk%wM+VW?VS zN)kg=*?C=%#bHRfLrN-UEW8}5o!BsZY$3kO3{2n06`+PvW(X+^4s&eZeqR5@FFCw# zAO1{%XlfcN745?Lfts1=*d~GR)k`vA=o1989fY(;usSqZ5B%HRx3PmP{Q}aN8fM8? zB=ll;mcsfTQaA5r<0n518&^RlO=x8lc_Oi-OA1mMeiX&-u4H#R*EU&FVL`#94M*Cb z^P@MhT|g=xKwDN@(jLt3I&W}k>cnW2Y&f$ z4*&9HrjHLYIW!o%v9YfmX(o@vtyJp69Nn=ae`O){+Eos!2B~l5tS*;3M zOLy)(P~l4_EC#uRivCrBLJ{&+q65ds9~tD>z5`4iJ3*=%Vw9>x<*Fizq`Z(+Xef`z z4GmICK~Q8-i(_A0 zAf3zI)EyG4`%~@E5uTJ)EQ6tv$KK%~_D_y8VusAPHU&rGP74cL0aF%?Daz)ugG)cB zN;Cz8ZiFT7SUyi}e4O!j-r@M$Z}ZNpuQIiFKg^VIWAUvfJq86zbuI!_MbOu^84c1H z2=R}y(1pApApJjf-p=kI!@8P|NiEw^qzQ?W1*F;gZ)Tg63RZSOCIhyv-7YOiWzlMP zzX4LQq!N=xbXEnV(ul4>dNgMsAl(|fyJ1^aS8@_6iMmEg_My(9SNVXXbe0TFirH4; z0!oJ5s(83gJ4_W}d;+Em>MIA3v{$e8#_cUQ*3EHOw`LZz`O)ZN`=%*4e5(!|lN^ZXR+M=^d>c|>RT zCH;S(SmNO11ji?*7%mm@GHJ@TP1V-Pp~z60=n9zfWyh|p%G5>yY1^bWGtKa!LyR1J zho3(FIF(~ZVRST(H3PL+6VgH*j7oJN2C2ALazgJ4q&COfZ4J`jjX|1CtKmY+52V2? zODZ7k{>b~;EFj(5uRH*uQ6^kq#du0GeQ`J1ydag^Ef-pv#TDl`X*i9ibt~$X4l$^C zAoE~`#}qijVwtF1qcWW*ELHJKRlI7AVx>e`q&wHHX8ko+klwjPd0*NCVTl#&=buli z$P5WcFCH?3cDM9SETN6W7rHPl-6@I@BpoWij|L8Nw3uh6T%qLqIPL8UoPPWz99xm0 zly)&&N-6Rj6@Nyg{E*uCBzu4LD}Mdc7a2Zu5XY-h9UD=s8CSGfJ&7yDbJgdhNoui` zNR$|2v!N6ZRF3^@ENL@HKcy|H0;$eiFAqy9G3i`Oin642kZ$Q$F=+#&+H27ujU{W6 z?w7fiG_f!$P@L5oqe&L3K_FCpxN^LDIU{jiRJtIRcf}4yS87A0S_Hn zAG+AIv|}a~0n#H!2BLNAB*)nNSdO$neM1xOywp9V+e27%1G|yG9y}BgH8G=-@owA`w?e;{wP3~hiYq#-2f;9F+WmD7ct{cas z2}lFdfu;pc*-ao7+MQTZad(?sI%N@02hv2{LcMPcP95m0YoEmV%CI)iGi|DGC)!bs z%ioBw72u^Vs&`v814fzy~6s0#Z} zjIeKPjB(eYY{z-@L~>nI-?cKGlu>Mpv}mk)6?$Ehp@Rqb)$`Bu){DPj>Wu@CFGH=S zxVCmE>gNGM#*@XNdLESPk%71X6K#+XSSt*oAd; zp)6^9`gSBSX*36s&u2jbU+-bSX4?h%Mzpq4;_d$ZQQi1Kw8(lX-XvM6O7#%QJiZ!IEU@Gv8L8`hsgNW`-2FI^Z85?GD;2qxl`HTGO`4h#<38axN-8f6^?k)tHN1nJF+{ z_VAoEo@uM>sN!lWPG^7-Q~jJ!YLo#zjzf8TjG+Vj_|dn%!ST1=gy9jaR8~>SqMCYGf$AwEk>Dj+@HX4BCO(p;KInxdB_NSiIG zsbkV}4AR7kCb|ufs6@3f_;?vdW2iUwpN6j2mZo>x6~byLxPJ&p0MkWCq)2u-&Hf-kY^WTHOULkj?_B z3WDP1hhz~aiMzxdu1_3D(iEpq#7`KDOJ_yn5N=MLR6zQ@M<3;(2Os44@#D)2r1kW9 zoJo`WhrW(v{(pPL1Gle>l6zpH&Mv# zktm2wF#fAw@ZA)TaLMBy(FY{mgT7&nrkB9g}t?AnntMBNdaz zk}XTdI9gOpdj8$r#F8d}(y5BsWPn+~tv~kb5 zC9PpeKdWg{bZiFOY`X8gnN4Cz-{T;aI6H|o>!UZ+FPi=kySwKLqzdy(YD(vEcb79r z)%|GBaw$Tz&a_EAR0s>BVU5=YCpk1-;DmJQi?EdAD7v2%L}hS;@QH*GD(9h$XE_-=q*0{Apf2ew?>Q zD@++KW!Iu&2@zeAL>i>xCP_b`8~8Y-0xN8jgFk22%|vaGAxstd+8gzRlmh~3@Z`)*~O zh&cCkDusjhVhN@N(%IH)R!q9Qvb#;bu3~~1iUlI|(6KONpfthHq&+D}Q+6_x9X-}S zIG5rSE5f{J3>hJgsPXw8m1D>FhcEvL#RCVRP*DAaM%5$oByX(KeVX(jWzQyc-o#&u zHCV;%RcZh_bD`_Dv50jtCr$lMeKi!{XSFxPmRhz30cj5)I*tGClH0g6%F$mjNf$j_ z!@{=&q?XF=_TGCdYn3I{AQg#-CFky*=fqJnNR>uZ^WHWmCY|lK#59$rr874ux#->9 zjvJOfPj&k)IG&QQ-5lBS(3Aa0EBotzyuMEo$dlpi1Zk(&#J6qKs`K?I?b$MT~$yTPyW)K|4IQM7GQQ%^s6)k zm9$D0i!?SarsjVtK1?FLtp^K>ev;@Hd0v?=U^6K`d&$jg@>8s+Kvw8=SV|SY;7Uwt zvGQZLu_m#kZ7Ib?RvGB1t(TS@1r7Wecqa$;iZuYh6+_&JFBEl zspPX|72rooFpc#IeR(jD4#D*n3 z;m=0n=wh;@=NmdpclU$M(mVsNVlJR}U4!px-|M*XgKJ~2b1XoSLwOH$>i7qC7V-rY|8>6gd(kg?v#z6LJK9S=ZY`*nZ1k*AQL&RTi5^}Qk;l5JFwZ9 z?O{)MKilk1w%Z-_lcLMl`nyUWM>4k}?%dQosj|SyczG4pCJ8G2c_k~Y8TEeb?s;MEu=Rhs61=8gKQt5(u^brB+LmH%e_r4Wv-@bjG z@Ow#V7x4m>MQadLL;RG(kP-0aa-xo2^OX3Q#G7Jq#U)l!lJR~ZZf}FdBqaS|gLn%SPey_@lM-H;DSR`+|cu@*Z;?YQhR40r)T(3fV6mj&` z*ZB40Kjxk9{}8+8D_Il)sC2;uMnIt4V=acH7)G&jof=mdFA!x##jTatGt}b{v!a@;`W`lS@4=Zn@$GqDD)?u-(uql`!tZ$RtRDmfQ5 z2ugS0xI!gX+1&)BH?dtbj`}(YvT5nGQvIxF0@A%tKEZeY;!lZ2PAoW|w0SWuWp=j( zQhnt`h-?{yRFlG@$Y92RSEnZV_1F*tG8fcz2?U@r2Spg>$}bFXLXS+fLc3Svl_#I( z@xTB7;KVQ~v2L-(t$|QzAQ=+Ud{!&j=2K3t9LiouieVVOebw) zMf#?+0=<}68OJB!l-EnSR_WPcGl83+YWf&c7f%N>C#Iro= zA}r}!Z@&@kxMasNaCa5zRA^QWV8VoFj~?cg@eyWHDK!p4Wp$OS8xQA=d@_N@8rx>_ zt+)B_U-~i=`wtKnWgd&r{gU=t+Qkb4Cdx&^_B3Hpl07*naREnB!>Fb5}^pQjC%}C43!#X;TNy& zCc9B&F*6h@6&xu;DUe1=nsP*j2p>Fj+JQ|6pMQpL|H&W1_(%(+=Lcr4L+Opcv$(swIybe1@KS1(%xNZ)wlwdm4IFI_eum9h6yQh0N6hUX3+WWup2 z+FBOH4m8nDM&Aj0sDqG>T9vn+dWuKB{xyuLX&kRctz3%Nyav87hZ=6Kc6YV=+h~mv zhLB`*dm^}}dz%92ZljalLP&c}n#My)jvj0)z!ZQwl>pat6exs8Jd-k*Ov8qouA=Lz z9dO-l*suz6Hl!`p8W%_w*b|U~Ww}_Ug`u-pT9Zde4k8~aB^-G(v9xZi*A$m;+cZHrMdhsGa`ugjyM!RlTJ~#9L0`x z154$76cw;qqC*rFMuz$3SN@!_mwu^uyD~H>5RR@Ye`sscAh~ORianOhumT*Kppf$Q z*oUoT`0edCa;4G5nvzLZB~rp{XQ&aQ4X+4^8{0(D4U7FfsD`uudgMmCO$q3fp^)nFMBI$EJZ=Z>|A zumwv@}zy39X*WZAwt2nhXNy+#X%w4oK_vGUnK>kRw0u8SrhmH9REgLH~wT1FpUSW7zXm>kKX z)dIgDLxk7NBaVGC!M;_3(J(xz1oP^vFGss~?_M?_6(zu5&E$Fh@F9+e9_4g8&g@#G zd{ZTXJgTh7rm+Tx`SxG_6^9>v6lxU}+sTN4P(+$#1mQd&m8GtdxTdI<>y_UnQ_gB| zWxA6Ot=Y*fnRWE#p{*7v4z3Ih7EFm16{U0ehi&0I7Wu4=vAv(Qw_k_xf$L$*YCQ^D zSVk(t+*Fp4K31iUu47qc6%{_4`m9W-n!1kbD(#qv(ABCG@`==|RC9Z5NexM|!3zUN zd3j=zQaY`a{V$}uDU}-jkNTRPEKkvd;OxEY)MsYnh@R%q3=O& z1nmL5-(AHgwqMK6N}AphxN4x2CO;%44@Ej4VmkB**L0KFv4Q>%+z7W_2isOdc?#On zir^>_v}PS>8z=xzdRUcE+B}w2ULqsq6<0X!Ne^Q&Y_0FG{6RXCvN)PSgH)JO+t;=% z=_!G_2#~(~%1hA|mtV1@mb6a6YogI6%77z5#IuJFvbUJ$L>N%ZWEDt--P(tMuvO)F6I60>sVVb z$yIfns7VOgYH6Svgs#nim&dvG60ZE6kHfb0uznS!q>LkUCDHwjGr#pK8&_sy!h?pJ ze$3W&N+^nr;X~qTC*wMmEtQ(lX)LMq+NxS|JfF0)QeohQXZiLY{U?|jQx;w}yZU3! zeA4<1o8%mu6!#>Y$f_|DX+GO`xf&w8svOMfC(WmAj-;anK&rijc;C^<>=rF>es_1N zLE7ZlHAJZ6#V_97NEoTC?%VkphN4h`)Keg}NPEKT^f8PoRx!^D|M(4Fd*pj?Vn`*7 zv@;p1nx_V-zUwEe{GrCR%hc{R#mhChA-jhAR$RiBRyVzc2uFFU(o`;`m3U5wlsqhh zDJvv%#a33_eFJTG+^A=?ID&ksj@TGt`Ri8lnf}GEU~EFUr2;&a5Hf^IdwP&sF-V1*+Yfwn z)n(k%yOm9~6geR-$Rxekbr!{Rse_7Dok|-N*LJb#o?FP>eG_b1qvv0UOX>7?LD~#fwGBz)NR57!OmGsD9^>W7aY`vYX5&IyQUU4VbVS>oH|WNI7D!JM zl`cbfcOgqU97a4P1C(Z_851Rgbe6zyutHO*7Ni0nml{KR-{c>^^d}$#mI_7eKvE@o z_<#m!!=aqdk_t%OFr+hr-Q>7u{Vs0F_OsDXV;5^`PKba>Tv4f^iV{T8f#EiT{(Enx z_x5XG&kk)xMfJfEITziAmKFh()5r&$DM%A5t8Hx3MRQ?6x_yqj+fkK@d%3Sr~B(4uG7Chd;k{ppo_`jTt8teU2;YGGC+X45X1 zfHW1FOxG$*WDGJlT*~^-e*~`HrpG?mI#?CUUA46?Q%V>??_rSUnqtyhJJzzQ5}-gT z8b`93wLp5>eD3T&UL=-OK$=YI-d8B_{R8_rYD5%WY4VnAjE(CXw0Qwp-@~68rx~G>10vUxsVPQVFpQ~xR5SR-H-e3EvaTC&vti@ z^YY|q?Cy%Z%=t?k2}qSCUEN3=btFP$Es&l8K;@|y2}nh6PtP_n**i1Cx8Hu9v2>bp zDx)T)8IhwTM%rpZsQ0Li4)XV3{xTDhve+QdppwF|g$^v*O+X8lzbYwFeRPe9b#OD9?({SfC1UZp!(KSz3(vo6L zrH(57q(bF8&4kN$2hv#CLDfQ=W6~I;GCj@^kjlwRMm*qLXLnm5JwqIx_UR{sRFoOM z``z!VrthJ_L5!tN9BE>^b|ZD^!Jrlf+LBr}d#9)Q&i*$T&t#}L8GJ*MMmBB`k@I{- zsGr=ok8gbSt4!?M2jio-qT+{75Q9_?nLRy7l>#6ks{;7#6+5}7cMF^IuqJddD>ZeF zMaNV?ltfLbw+;K|-Sq#5&%?$pY8ib5OL)AJPHu1~gp_+)kj|B)oNaSwXLp{Ji@8=zx_B7R57LJpeprn@93CFJ zFd&s?ZLOfGV>oF&tAr6%!{F`dDZcm4+e`{b%`}1GVuU7c7?JgBbku4L{N!gm{I`Ec z>G*M?nF$e8QM1>yFqu{xRO9aEvu3d+l{%rotS^M$UAddPyEd{V551uSm8zRt?`<*Xlb6z{c1q&~{2Ksp$~3x|&K z%ESo8behmkoi~t*=F==oI!{bmXo2($?*9BjWdHK*Z!3_Fj*eUikP2l^Q)#43p<^qP za->1}*3=Z=k3m{9G8&|ji5rAuf~o@P{wJQ{(f{&asSFPh6=!hc0f{w9!zz&KnJ^21 zRASP;NQ3mA?#*nSiRhAcxN1eoEC@)a(k3(QY3wVvvEkDnB7MjER3;ZIChsSiux8_} zx^B+)adMqhU#wGu^h7BAq(^vVQiC*d(lJO4mCWg^lo@#8xpP8h5Rf)o(&ofbDoGsW zTn?o|a(CXqwpMm`frT)?r02K)`JdJ3!}0O)#t3UN2xO}??sj`+yGirPv66(;h0BM{!3IaOI2}u9*yJj2-NZXN~ zTVWhs!7UwYSXuT}cDEU%2c-ma*9~m@`~z^w258S}c4Yj}A{i~l(R_&`p~QXro8MF* zot&Iljv$@pher-DYT62t-k8B~&ufFwNp8W6s1k+QPl@gA0m>RwsIiZL? zNi+7mF0bb9>d}ay(lGjT|K;4(vx%K~lRjxVDHRp|N{-2R#$sws7nlC)k7D0;HLPC= zxm*)So2!_yZ@R=FJs!aG?+ozT^qA@z!p+9nU4yg&sn7z&k_t%2Rd>$W(gNoL>58Jq ztn6+s#i4XaZXS>(4o3^5$#ylrCH>YnzNvI~CnuH(NULE;4N20NNS*YtL;D%RMBH5g zsnASQMnr}x?(`Ht`^SIgr{DS)j6#8^Tu_!Y#8(P~iE(SVyK}8+1ElFNQd&m0r2F~Q zwyU|Kk zclU4&p53>P{k0-_$BErtv7~cB`iDxHK@=3<4M;mN8kV$k4ZVfhEK6EyOL1@>kR~(i zl=yhdlE!y-{+RTizwr&FySqF=nlJMBz&l8sr9f(EOX?aSS)+zMInJ~H?H~B{!;dPy zF0s3NYLK2B5(o!ghz!zECPR~M$n^1vEmv}NCCdh>lNL&<_A2Cr;haU`%1vDM`A@(t zR}tl0jFe1(IYrE?gYB~oNM|*G&pJp`caLh!F@#@*8fbN(81USIy&S=3#<2-Z$?obM zOP65E3_Sll-~J;3={SV7a|Y5|JJ--XBe{aa-Gy>{W;RH-uZNCYy(hLl#k=M1&RZvy z63jn;Q!ME+2I&(=4sp~AshW~FaxnamlnFV@BN`pyhhO_U_I>X$rA}|wD)YFzNyfE_ zwl3mhl8ucO>c!m^;cMaUUg@sj{;gMWZ6(9Tib=LyQ(ZCwQc;i(-oKk|pS=%m*oBw2 zaGYk4#-qra5p~`{s^_>V3Z4OPO_lk{p?5eT`btt?mgaz1^T{o~@Vp0WC$uDTB(-ugZ7t8!5m%jDj9Tp!bXZH+oqaoW_@4}n|}LVxPBLY z%F;uKo3qEs{LH#*dVVaa?#t2bsnXLPnl>Ug^XhnkpB_HMaLS_Sy3_)pDe5v%+V|1A zyHE3-FaHUQORHM5B~AKW8w=-jt!l#m>cL%`^3wZDUJ}yVKcqsy)Fh>-Yp341-#zU+=UDjHvgKHpvC%GSTNGB-K?n{)W(v6-+wkahzsLH! z?^7UkQj*5$2Wg=JttvC(pLG0={V!!AcqtmPJ66UZm6FvpHkJV8XCI9NKJh+a;%J~UE^%eP=e{JVZX!Im5$uiYHP|!m z-Qy@Yx@?ZyRo#8_L0T}`H1kG*)P?QXXfeaMcl8>qOk~jHhS<~)5yxa(UBE~pvwaH| z{r<05bJx8w}0V4P`*g75zne5z-#F|ijT*66%#SjF2U#=JDia_Y+!qt z31{8`nELVaf#VL9I!X?kK=nfV6Zi3;x8mMDkNqK%lq|$V&OzD zoL4moGpuq%Sqs>qHp9A6209I3bE$#ychASPPrV-)I|8UG>la9QWtA5^xGley4es!_ zN7@ zl*Z8-iy>i{a9GMg-aIS(XE4mR@zPy)GN3Kq*eEnS?XT#-ToK zpxki~awyrAB+W#^0@8|i&&Nc9bY!)tyXl%rq--N<}@6s~Lw0b_it|M+$zmMNQZTj>klLcTbvwY-Q9V&=+9&=7E%n z=O$X5EOKT9J8cIm8yfM%aMqdAY-x0KUv9CKeH&wWrSe=>b>{jk>C8*11VcZ z>H35Hut|Lm>spwYg9@BAVj512k49}<8kMYs=%|kCtYndmMy1A4)p^HZ+$Y};3@h&) zq+Tggsi@(ZA^Wo=WwpRt$vFDK53x^yRIU3qIuOFkjcs^oMup-EY z=?%9a2?jzc&LU=KP}0(hCvUz5FaPs4puG*Cx+~TA`)QNvoFc=(2!|kz;Y0O@<6V&& zls6|)5wfHz22~7tcatGYY|;Zh_kNU|cM4EjrWi+F%SLUJ`fV{1#3Y$$2&7Us`nFqd z#See^thNcrD?g114T?PvONaJFq5^LMB=wT->yqMgr}KCp+={b$`XO+wXzN zBG{=;xVc2WB7K3(;PDN7>@y9kd}R|4%n{Q-dB(*I#BuDf@i?ZY9`%_phNtPSvXH2& z!uSuI37mT*FkzVFkQM_e|0-+49#MBSH%DJdIrCDcfz5VSdgZ*)(1_(*cOVf_$q39C zV)+(jL>545?c9lnZu$e(J@7C>$s}^A4j57^$}>27bsQB|J3iJZ$HJ+hQ8;((4ADMH zTazfWELg5Bv1Nj^!!)q9B7_-V{2;7%p8yQ25L=$U2T7#Y&LjVIS%}QnQDA?Tq`6E6 zx88aye*EJf?|UHSbm)YEO%CwfhHZGgr45}djBSOHb~8vC9VkyGu=FlL6TQJ+v{Tbj!v7<2wf zi2V1lFlJ56TXT9MQQg(^U2z-+@7?tZq$p&{&1z4(`pJ;XCIBm1Tk*=~t=OKq~ z5mTHPVr@y3va6h{`tz`*BfYyVb>*1y#SZ}|9S+phNUID2lt9gc)YoX4eX$Cp@pYdNJJmE%>KZ6Z+o)qvvYG>N zeC8axD77<4tXYdcFSs1;>no)D zIrRgAlznGJn&!dc!P4tGrxrUV(W@#k3|&q5zeV&@wTIyN^0BCAHK+C@N-PCZs;_Cw zKwHE>TYU`<_`(N)W9F(lP$30UuZV@JE8GJ}cPG*Bo#5T=rtZEKAPuYtd8VpViHCtE z#`Ri~cy|3}Y-sO*RauF&X(MAK5zD2p`N?PS$hE%)8k&G)3dj+p4AB&9QooYu7YO;3 zFTJmqU&;x{wuht%&O#YZte%WhYo}mbv4h?8BI3fgE6i{x*0f%Xt&Y@XY&73*8u(CHdTha*TBv{lJKQq!BH z0xOq>mFz@)ycCcB{qIv*LJ@CRmavZ(wJch4mFCPPy#c02^0Tm5T|$_p5=*^U`VO z&xBz`#-NfPoGX3(`<(#Nu8yM?7>gG_=^lCHk#DLb?QNi$Q`!PxL(0X=TO08D&Rs~d ziExPS{S+d(G@4#pj=Qe87Fe@c_3@-6b$bD+FU}{j!KX_V$lmI%N~I1jD+pHMwCZV? zS2qb^*Fv*lW9qplVmL!FqsxI3b|hD2T8w<-CGW|4u}Q`DE~?A17%2;OyD-_`P}f*7 zEu_K*S}kB(4p`sOftS{ALI*6Vugk9CY0E^G($?#9YS}hQ92?O@C!%d_`1fyqgN@HW z541K(u56gawsTnlqtZ0GDw!IjbOz~LB}hqPI3hX{pBOm{)16WYQ?X(OsS}C~Wk_ea zZ50+;#@FE3AAA{@K2iFrN@|~1z=HQ#45WSl_XWnDzJDixRC9Of-EC%9hJ6jBS;IgF zfL&~V*qFi#8#bcJQ1ym#p)_KQ@ojIwpD(=vsiiA{W>RkDNRSh!YtI{@KIARbL?cawRd9Vfm3kk=RXF_84pxOC9Wg&eGN;OlTvZoUJR<9 zLCWwLt3^)-eRJza6Z6+iugtNc|BZ`wpOu+?JQ&Hb(Ai^9{ zuf7JKi{NXG8rWQBpyY@dIQVOy0>;+?v8V#6Dw?6Xqf?Sf5elzylP6^d%hbwiH3buT zusDCykL#Vx&J)+MBOZE(iz5om{d0w z(P$L2&pZ)zO#U8KrO;@4)sonL!gGo!$QIvv2dR>1l&CqwM4E-h02z-pi45M@x)mE5 zTab&!kufaUhrr~d=f^gciW*8Kr3qDX^JYAC*Iiip$iqNevxHudO$#s>2GN}+x~RJ{ zc*+UH=is7MSrSGhnH3Vl+2anz3DME0>u{ww9NAl>GV<9orXj_{H}VLzBQ0*xHLLCWa5B`S&(huaPgFyBnw2_dxoeg^#<(%s*zI0jW|SRgcm)5~{$~ zde-1IvdBepC^2%V=tyGG&Huu4H{Ss?>=fgMa>ueMdsL64eA%HQE2}?(;+M2~67eK4 z7^rr_7-7axAFaaV+EJKZKLO(oISB9i_ywq#H$&-cIn~yJUQH#*)WjC2h`0HRa~A_C z?O7^|LY((10MdcRz)~w6MJ>(Pu&WV`ok?lAk#cE&vP!)wDXP>&1r#!Wtj-RM2!-&< zLl0rm9k-)(?P?&|A!dQpGqedpwR8nlUMUbKHmQ>8lH_dyWe#w3s1|3|AB;JuLTysT zmlZ)?MAO}o%&WRaq} z3ma9PDXe(p2|W6Tn~~bEQ9=!-oAp5IN`{E6%HE`)!1J%H#gbP1-!n`=>R>5MR3MBp z*TgV0j>)6Opnl3kob|bnn`CyP}(8?dFl9lJUba7~7znDY~Y!}?GR_2eTpggL8CqCyIAN`bAkOB2AN4I8l&8MM2dh#4+wl3BFBz8ZJ^>IQ6k{dKt6gh&aC&LhX^ znndCObs!++V2ERb)$3s*W<`**(0ON zrjEDtsLn6~e?*)tDx54{y#IbY^7}smT*Sn-%)+s3mBFK{DY90um%^t>_2NkLyt}+@ zK1&?HyGp8YZrwpRJU$9l%^8$uS^xC0wA9cVGqFzhTU zlR3ni+i~-iKgar)UV@Ws1#)Sry=#y|ng@u-*$pf~lv@6+tKnWKt1VK6_GxuBTAEvs zhKtH*6!EfhoO#w+_`-!3V&=TL61yZo8LHs^oRaxW4o-SMNIfCuBjt&T%cA*-R2J<{ z4lA2>U|TkcO`RRsnMorZ4guj9!d46hD^;)>q8AjFgaLAxsh+wj>!oAWDm-?}Kd|Qh z2PAEdiSdk^<}B6JSi(hlADilg?guH=T}woy3cHMhiDRn9;k4?BI5=E`csn`4x@;<7 zI}Vbrjchz3y>e>Lo{zETo+LeBvJn&EIJ0*1Z3RR%7D}cUTlK#SWtZ-rMY(%N2PVs# z@Xw&*h;hzun2|8z zDFZ(j8biwc26qn_GI2l?gb=7Di!1YYN=tG2I}g^;@Fc< z!nq&#Z;YQl9c9CY!3aeVvBGe&HX^2l2#X3*P%xt6b!lV1IR8dq(&kLLz^>LLcDA&j zp|u$aIOs5KBq^Eb-POKpmt+9uiiY5tB+)B%lx1MZ_%X6+Ni@i8-ipP4_#4(d^)wRA zjR-R#K9h#Y3>6(qChtQAp}Wsp2UDcPjO${!4IGX#oHKd`j;b7k>JA&R3`0d6r9xBW z=41k>DMRDvGEDsZ1t>dqHc(v-gu_52sq(s9P>&UWFgr{2Sa+Zvql~ zxkM18qy_%#pZ~&-$lYyiRg!d{11V=PS5ym9n0mwi^=o;4%Qn2;-iS`=hGrttnZov$ zUd3O2_ETWzHXxglObjJSZKd)SF>Lfp3=T}!UA6kCMm9(*q=Uzbg)qE+Easnb3g*tA zkEt_eB3@CASiBqvMPP-(h=d{tk&WYBR2(cW(3x@3mQ0{Ekw9xQfsRZDNjry>Yr|%D zHq%DdVCxNbP}77U>0See>NUd|(&~{ORvV?ZgSg>h%bJyV=FYpY@u7uqb~eH=sruWn zvuPPmTd0C66)Hatd2?AwI)kJG5*Zu^Wrm4~b{MCXjK)c|6L3(Z67kNQ*rLo3l0J5Z ziFj!o+uB-?tcap>+6Wx{-H*eVQ4f@s0#Ttlcpqi76QKN0x~v9S9eGLmc7)sDz#g27 z*;HC2sc?4*(#IZqq?=9pmP%3yxOuC*2_!5Pj(M%U6EAPyip}k9QV7gUXJGAW!fn6# zEjB#)AAotK>|kx%$hk}*SKdpR2f-xfBDKN>3R3dqLZu}bUSE$nN6*KhM;wj%NmG#t zN0BOt!3jqZ3P)jC5y_gN|5;*$j)PP-izI=WO(UJl3h0b*2yV!dFbZ2Y@(EPC46h}J zr!LYmj7xqS$vNGDU01w)Xwx3%qSAobKtnVSk^bl0=m09z@% zx^+8V-MSea(XeYCHzSIHwC6QXDSZBQJa4c0 z{>byY;V`VyQW&Li9DB;?IP&&t^wIm^na0c6vdh!BpB)#LQhQ!zdpLQU2{IjwD%fLHB7_{q4g zFpb(rSKy!zo{jK%#{e}YKqL%EITzKL+*@+;J!;o&2&DTuNL3g?GFoIFiSH5_+eOl}(3o+sytNrm?c9ns7TKbN+O-3Z{Ozw; z{nXP)Z`_JdMoWpp+t+Gie=G(iEQ>fayfjhmRAP*h)%sW|fzlEoa_3?wnJ@{5oP09I zOg{hA%7 zg{|vWW5x5&;f-gXLt@=}#bHjQrNf*YEz+(KD^{Mcz=tNHdMDq4-_5K{V) z0%)Gd;D0egAl|jjvsn8GY;HH6bTbp-I2zV4Gmb|)-2Tp*dONgr=P?l zx7>o(XO@Wf(_#pLQbbb(z2El~NQF|zsb+?RKkHZwk&vHi0Sq^=g2Bugm^t@Q%$R#9 zDo58L7q(!BO>~+r+QSBH%Y^Be;w9xrIS-W0W(%>M&Kr^mEJR4SPo$7;ZAG@T9WN|i zh%IYZV%zeiKvSdY0%sVA89b+p92+NzB=zeJK7e{6Eblz>sqxfChW}qH#ZxLKW?{0~aVDdx7nYSP z@l_T_s639*lO|%u+_|WqG8q%5O_5qZ?9|3$VosJo)F355H6?+B17#mZY@m75Hf&$B z9;;qmimmI`prfe)nXMavY!b1`3Z!;6$f72$84Y%CAt{7eJdo<(uSdZX_^{WGPzr$x z7nqJX&aa=1Q%lBRL`w!0G?!`Dnu>bJ1%`Gg9Y>w4^*f>rHOI|G%_q+VYD<9XI2g*)H$~z=UyGzoC9)7?*>BN)v0g!4K33=4Zj__g@(o#XK+>9S?%>b|O zY{v42jo6iJLA)%2WzRo{JAeO2IIGqH?HPnAeRK+ymZUyzXirkLH;{V%;=FoDX-a8f zSRrI{OqCM@&-+Q@YY3rO47o%SWh3e^W9BT>&zO#~spEmNQk0dJAr^_jV(inK(44O< zh}_)Ri0vCUqix47Y<*)5+PCjSmONz%r!Yn(z0sxl5*$TR2(CnaTT|P)L~-7dAgT#a zR%CR58pFUCH-z&>9fBiDM`2<*B(^BqaqtG+kPBPlNd_{mBLBBm#bD2yf+-(73plVI z7&A4Oj5@1A_p$@>UMeLxkv&?|23Rc)uN zppBEVfXxYDY2y~W(Xbf_Cyn-&COmQX-FW?;2Y?-|u+o%qN_uD#xpvtGeH8(ds7IT$ zpdM-{7l=Flay{Z&G7Xs0!;}>?ZCK$LLZK*1YO4_*H4JV^4ADpo;cx_|NiMFI{46rx zh)gntOlLyWTy!LWR0haqMKDs$Cpkgxv4^g)<#;rI=XQRr#yUhKpSz;u!v4Ct}q5PE*a5 z%S)7s>s?wB;(Z{^k6|!lMZc6GkiH#2+Ep@;C+{gP+XSwCQ0=Xc}EM`bzUx}-#OJKsob<+S|K=O z=n!OdFi8S5%c78yj}R8zA`L& zZ1te$xQ~ph!C4HXd3BR?K7!Tzh(YH;Y!sBp8+RB;d!9F zQkn!sw?!m>zux{{mX0`YJWg?0ju|c%=0u0%xatX*9UqCBv?&C7dUNS4lK3v$wtDMH zBxwUR67Ej%IH(q~okyIfN#tTUfKA?7$)m;aupvd;D z6q7pV-~6g-aE({apnR+&Ptp)KPhS622B|L2MenpMCgL+w3?#M6_&ACpu9R+}09v?T zE$Isq-y1tG_DY9T*ijiSW6cO=Myheb$SIgtG6I#YS(MwBIIQTr6P8qnq!QL3R^b;r zlS87q6rrPMUY!h%oH<(&a{xrg;Zt#XaIJTroMq10%_M-lT0RX+rMtZC7R5z zuS?PbNLi{xg=bhIgp)sIT2iOCA(h4U)(&jgx&u45ZNW2-Jb))3c@WL3RtX!(rEQlh zNYk#$U@_H6FABxgs)2x1RCT#vP{H%5be^=){ApD0e+aNY^MsfwHI;i~z{I7KeEUkBCffpFBv5Q0lxJGd%{AfHg0s z3LVaw^gRY94vy4fUe##4tE>)V>@bGeA;dBTas>e@^hY7xt3`!1j2i3W7;(~J7)vS2 z-lMdOLnhK;#ViWBI;p^;R}QJWy@K`~22%DLDS%WJ`3NIrTS(g`I#LdHwKQV&#$|Z< zrRQ<$KmLjJFTbLQ21$B5Sf9ie+mM?C)4Od&Vi~;+agnf2x6}Iek)(FdwpORrJYg?1 z;)!`#Cc5Z~-dT0VcwXHt*n3)5n_7*|tK}*!Ojf@+`Nxfn=qr6j%hVsx~&!MOkad)-q{J$0X!q*4UvKbjbXsD9Yo+@I6|0? zN}Moy3XZNAgNZ0XtR;yE3zwP78y=N>QFU>GGaU_~HRPhRGz??*1k`=(bd=6L0A?ji zqcBeFv5P$WTkKKo+!_=__8)-yheyvDI*#6^Anp3LwWKMyloUw$Y0Gw^VdqXPS+WH8 z+MLF_B^wKBo%~CqG1T*fKV-tsvV2Dv_XwBRJ3PMLS_P7 zWEclETtsNUdv$*^Ap>o(5LTyJ5Ib-@roI0(l%97CvLnkBQNcA~>XN1&QQs>SJ}7wZ zuLt=Tb-&|CBMOD;J@Ld7NbPDw zX=N1>Ep4htsc&R-NtL`c>MiDZB7}E&4Jf~~^+y8t2uOo7)dQ&(viW<^@lF-*@SIah zJ)k6vIR;9ZdIlS#QHlfOqi{&gC>$86!Z;&_@|2Bu#zjd^5l3{KiWxd0g<+sGVq!Q6ZmV=g!aIA|=gF|`EHOHK7!Re4lgqWx12?%whe1nI5+{1<+5$xoEJd-pwe zx@Vqo=GzXWd0_g>Kzb@;iqtvUP>zGf#zs8$_~W?cmYea+Q%@t8N+Xv{=Uc)D>m3!d zNd1zozaZ_R#tc-F2HtnxTkElO^a3H8gI0&7B%-=|ER$};3voZSQqkto3N?J}f zq(RA{Rz=ae(hzrV((Z3Z2SNI;fBX}d{^U}$vtiR+cirKhb=FyLOOX13%HK7iKozr6 ztQT&bi3A>h>~Z}5rkim8op&P=iR1(BI^R+=Wb{A;?M&u==D!Q7r$JB^QFr~j^r`L^ z0jXAPb>K$DQAu(K9ELtj16Cv?xu;G?3e^Bc!NL?&;ppL0F}b7)Ih?C=(YA1vR?bR9r=wJcr zpTnZe7zS>-;YM73*#fk&IQAWP{M$X}oO6O}cNgyG?p*xMI#x-}?h~96vZJFDRh5-! zX>G+5RDEy08P6Y*Fv%^!wDMs%uzD2Y%w%Ew(^V;a z%xWPkh@Nt)%an?&qM8#G7f6LIbPg*;?C66r>FncS95h)0RQhNb5)*YT#miOO5I}c# zo(CoA4cFg*D;He;&H|~dMm?yZ4$G7<3=s-Ry`SaFmf?>#+=R#Pdk{?x4QOMJQ_tl= zsX{V2TSvGagC-v!q20#3N*`@6FSUKsHE-woil9knKwp^>?P$q!lcgu9T2uYxhOVly zSFM4?x1|LH+Xk!Os}VtMs2pR>5}Z725+)jP)F6y1BZN|VU`1Vbg&xUpjIIVjshFl6 z8gh|}80d%?=!}O^f5PDycJ|T0%t>%+%8)ipM02L9v&7009${j4C+E=dg%Qv|<@~wv z`WtY?g3HlPNqWmIe|O*azW2TDC26sjt-~c!=h@?-N>6UXz{^iRiwFOG7nVHvG&ZkT zg^spnk)gH~LWA9jPRo@dXf{dZ;$2mh60Dqy5OY;kj3eJ-KA)Q9OTO;HMOqOU zl(hA#==0>ZEs5sr#li9|EOC-!9MsJs8MBb7t3cKKSr~r8JYd!&xFaj1_Az_bNtFng zLRKhF1Q~+do)`fx%mk@O(x&|gq#QiyCQ6CMJkO34Hm+EW=O29nuPuBUt6y1$bVsKo zH7{@4h&JTV0SB2d>-Z=V1>=yGO^_-|p61pn`kWU9Q5Wi(b>lJk@+yrdg+#HX#P-tC z2+{&UL6;iwJhq;S%PO|CJBQQmv??&lD#47}(HI*oM_nY2+Khp^q=^!nLZbeY(hA;{-jEz>HzOn{mODZtFqzV-|1996xNzz6|MwMQXtQDrM zvV#omP_LK+FG#|CN7z71iHVl#D6Gk&F!8v*tUEXq8S@IckROZ<_2u&*oh`&(1r{; zkwp@=bivTo2mBx!jnJ;5cqNEO<*Xw#%-b-yss6f@8e zH!<~`6Hq?q07Pa_0ftuqG<-^H>O&wfy64#dV5J>klGz;e=NN>3AdQo@xUr9;_ zkjIx5w6!IqfLYth4OqK)2^wBl1~ZXCBAZ61ox!?>E$DDE*xuHJ?WtC5MJJM~cnN!z zi87cKUNOsDvT>7}FTxcpv=CzX5mObtmhNQ)si(^FCqb!f%^0deF;o~KOsF0%fE-a) zflAxLuv`dbSwn17*2yiknV_v|6?y5_5(A}8P2nkRF=S@7Rd9!uArVnU-*|tl+Mrq_diHlnJ)h?0zB6^Ly$8O5ocV_9uJdft7UekFU({VC z6uhhq52R8>G?N87(?EL?XzIkK2Nt1y^=9nYxEY!DPPmMrlAvG$&2|#Y8@Hg%$)F>Z zL@JlT&bCG*kwK1?6r?-1E#TEQXyG>n$gngpG!cOz(vqrdsS!qbv=nhGjEYbM72z0$ zm6W3s1QP?EQ<8V zN>t67in=3a!#sF0Fnv4_w~(}4xpykHQCM9;>V;`o<48EdeWafaWI_(@+jRu!qqzRM z>u~kuSD>wFKLV+C(&WpWNb3e&pjjE2Ica5|19r5bbLm<%yu1QiUVIJau69@*DPi*@ zQ%RK6R-hxBMlzj3GMhn1x>Eql-_wSJt!+(W$K?y36jUR{uY@YAtwJ#LHtF)6v|$+^&DXwWsS}2d7&mnkSlLgf zEo{ITJsjbw;}AdO0F)m*1(-1fsEPw6Y=F#CEvo8Z$h6csbww81;@UQ)B-QeI2&j8y zeIdK;#v5)Bkam!9w7*DFKS-5Cb)@Q@#3ZSv3iF1O6EJA6?&<)xw*f0RVf7=6(e%bT zBpMn~5ss=h^b*%ppp!yfxt#pokxQe~biC4+UO_IYSg6v#xOb|fQ<@@G#!3aKW+p2n z1A2~i0!+T{u470sFn%vp`#i^2A%x=*3_M~1i3#bDA#q-IJ|lxDTTzN+WeKY19E4#< z&r_0f%y6KhR2p))5ycu(S+<_R9RMh^V|0UGKLaW_ONUh8-N&u%*b;)d=8CJ(-rNG? zh8wPPKmF-X?-$2jZl|UVInrYwX*3OCEVFl#vmbHH87^LhaO#eqm9ZqIt>@$5!D!X*ld(f zn+O~*Nx~|qECouUKscgez=fva1(5n@gw6=kAtT>+#XuRXG_m{BcKlfC?mC$NS`y=22JWCp{W&UZbf?iHf&wA1c`N9(6Vte zqRA{G?I{V3kQ>YTKDm4|CRM3Wq^=Y~D*#l$>Rni~>++>o^4=zotLvx)bwQ{!U{V3T zIzhz_At?@KvF?y5{bktOG{N#FQ5#iL$D@AcbkrU+6__wus{6@@l@!7u>2oR-9Q5nv z>GP{Z@9$kQZ+h6Jz?$0s=FaXsv41?-u96_V=BlgF*)jyuuH!1{T8h~ts;o?4dP*1& zWwrR60&B{Jy<#19u3Ur8bz9J}Y9ri+7GxWm5l!YWqO?NPQ*o|11UySK6>MNtXsoal zYU*EJSOzOO2zr%T%@QVA))QhU^pGkHmX3uHsw_vWwhGx{Wf*tbk#I*=Av9(rP*x(< z^2Mdhu5Qx9MTt%_j=F3^Al)6D?bfk=klJ<*zrXP&0coPGy{jZGa9{UNNvfDX{#IlZ zT&zr}yHf*hI*S;?Hi@i~vg@}XwPqt))^0-6y3MfKQfOPZS)4s|@(4r8 zHlcCzHY9d7p=I+nX~}4%ZA7!K#5hA)rpMVr`1j|slKjpZLv%v18hkDmLW&YF9z&?2 z6m~@koM9Cx8#4lo)WJgf?+j05!}fp`=sk4v9ZiIqqzS2jwb1IgnO%RMq&!IXQ-!@s z4!V=Cm*OUewzLD8T%m%Y%4744RIe*rCjqcpI6dIjlkfA?$mv;Xtiz!~>HN$MW} zot2{GP=WkjDB`EGVpM%0kAzNYppz3@vy2&@D!oOVO*vQPa)#J!SZe+<$BkZNI-_j0 zU*0bDBsD`LY-dl9GHXT(glh@Ub1CUam03HXBn?ln=%*j44sXgOrnau7!gOt-{!c1h zo~EZGhC(p?AImQD&ihA(l9Z04Ydo9uH^2Rr`?=44ZV05l5eOD5?kSmEPgcz_5TWH| zuc&OBJoljM_~tvPDVm}JmJg`@*i60^pue=If`P8|sY`r{4ejNm7A~mRLWQk+WHVTE zX>e1_dkk3xdJ53&&Y9o2#|DRs>aMm)JKEb}{QB3wbpQ8%|91$ay@1rO{uY}mnyatB z3l=Ttt?(FaQiV~rChQ6z-7Z3(H(0JDA79lt_jR5th|R7tv{*~I0s4*lM2jw9-sg@( zJ1EU2u%>C7^cs413DRHv>KE?kKmYk5koGcRdXl925Z#us0Mf2t>#I7T25RB>K>X7C zB6yyBeAORU)oQlCRD{1&cagr2Lm+)?SBu_2Dw6bc(+zY>W;Sfl7V4611s1Mfwah|4uQ1$p!8=<_NPT_ zcfi=wvE9fswvFqryIw%r%C2g(N#Bl=)E~C!E9BANfelVbeT_YJ{{G&_zO-L|yw5`* z-Mu$f45T;Qa04#C{BpFjGQ&03T;+c4YhUZPx~m->d@*_w_Y`E`y<0DSw6u%xnkVT! z_7sTr6_6HVAMK5??9VxaW6fjs)Oh#j`uoE^-B^^4i|enyPC(j5NqY6wSGr&S`qu{p zQoS=@U?!6hM*^u#+@jH_^#AN>Be471ovhe7n8L;DvGA7^|1!<|CpdxlJ@?lOOHcR2 zXW+i2rKMu1S5{W$j|qB_dF}qFfV(rfcz%v&Nl8f;x?nb&h2;_Jg9Hfw_4#1Aie6U zE8K5<;~N74sRo)phy%pI;1&*t`<%qPGs*cvczsSBP9%L@{cnD!fy?{RFNxpx1TZbR z_&ov3<9Qxli=VQxGI=&mVD78WHJBID*D+cv(F+johk)f66STY^j&WaGF$Z5?$LR0* z?0V8C5(&BP-Y_rvdq4fz&#%pKyeKTV`G4n_baZs&-)Dc$`)2IZCrGcja)JA;Z+>e) zAZ0^du2uvjAWkN3T(SCE$@}`gw}Fw|Nl(?*VAX%)dG)H#NzT7(N!r^A%KaJ} z8}pzqFE7snl*bViot>R>?y9P){5AI03)Ef3InMeScpn_|9Xoa)9*-Bjw4SK?=U~TK zYbktQ0+c`ZWsq|2Q3E0f`R)irKS()lynoJ3t)1+xcQ=^x_GFV@dBqjVadi0=mvsZF zN&@cLt*#}{vSrKg&_fT&p!g-4mO{ZB){{nqYOoFmUZ0>DIdUXs%$R{g4?R@C!}IYP z8#ZjfOE0~I_3PIQNRK@7NQ@aXMm~Ofk6_>gT(V>d{_~&z$cyGn=Ckk_I9c^Vz!mwR zgAT$er<{Ue!-fs!UG)1HKF6j_oACJKkIPRj-A9ZVfz6vY=OPS9RR)rN^eS(OE0|??|tuk1$+e6 z0}niaJMOqcKuRD}8cm!y5%cEF!v{b3LA>i-@5-xk1S4PIAOHAAc@6?xOR?a+ala{3 zrr_WI{x|CC>biVA*u|!&=jZuWuU?Jse)qcqRKMo1JNA5k9ef-|jx7@}KK}8K%i`9P zr<>2Pr=NeI^WwGFUc*HfU4%u87Rh~T?Ma_UYk3D8Z~%VvqaWeSGtV68CHCt6L6G{% z48l0N?6RM918Go_7JCT<#lsIjER&lnnBGU*ar&wJQd8S{{BE$TJdf4t*HK3uB_O4w zD+Q#FKKiIEG=6aQ<}~VUHucvl%SkQv#5o_gx3UDW$xD)d_o z(&wIgPC&YN@nRXL;Qi=#I(_RW;Y(lo5b-9usq7cNex|_uCV=`1iBVJ{!OI#V;^^ z{CLq&xbt*)-duYUC_8E~%rTqyYa+O=y%Wu-byJ48EP2r_QR z9d{gl{_~%UWTgsAY5M!$|Grmsm*=M>B}l1G(>4rleckgw-W>0L#flYqNvgwJ`W%D3 zR&cy~0$o{IIamnbo8SC~grjn-#Uvmt?x)yOAT4Gx^=I5@k5cQ|Nu~aWznWb4m*ZD=moHylRFd{*fCsX|>wO8B!w)}PR{EJUXNnYE zx^yW{KKW#kjM@g#`xDgs@Vf&KJP}L#N{Q>PyRKJtSBG5)(gz=WunR~B z3z)vfhKmlhghw8EBp-v`(;)SmD21^KVf5(HxbAn?;rQc^N30|U+jhLhRK@R_o$6R8 zm>k|>wCUi&tv&EsYtgZ9|JesJuFpREY#yXRb4zOgen}csclXpH)7Lxg>H9t<>4HnU z+oV#R?kxbRR+0O9*ouk@eC%T%!?(WmEwK+d30{8rWn6H<1=zlQdtN=$=g~GCB`59J zKmYm9qO$4$_b-3>O93e-kB(3J??J20^zPCQe>1$h8l=45-jbw#M;@P7V$GI?V~;%! zS6p!=rXMgJ@lt}cd;KL{Oq`%(#Zhj$z8VECK}Ly2(9r(pril{T^Q!-*ug#ym%>g}` zRfU*B#R=M^T9Uq#K&oug4j5M~xYYe-Fi!d=gH(q_I7xc43H_j%Jb5yH_`@HH13(iC z2+nVQ^P3`hnwy)u;G8d>=cNn&BOm#QfSc+tHv*Ru*$>j-%F6rWYEMZ@&}e(Muf=4r z-}Cx!7D%E`v;k^AuK9qaKOC`ive_uMY8CdjB7?0XyR zaXm>=f>bIqyxAZv21E@~PLg8Y)!@S)ee}`d)uqZyY1q=zB5~4R|N7Us_S$Q)X3d%| zhfuBM%jf>z|Ni$ynrbP+Sg1#s4y%b!_FGIw671e*-RSQbOz~E3b}L|Elo{mZEitB z!wz{jl&F-Rd=JrZ1T__vD36z+rn*{wlF=0jhY=!6h}9FLk*uz6<`_~9ru|JVg0Wt{2THGEAmw62pnU36 zpAx$~zezX6LjObl{+{#C#qePx5cUcOOA&B(aRbl_Tm6@_;byXEZrFvE#$8yqdJUE> zeGSW(zJ~3aH=}7+6Pg+uWfsND;?nO%7NMMj3AH1of%5pV^_Vz*0uDQLF2>i7!|>t5 zQB^-y^>$?=9qxZb$J>4WJ$DCtNLJP-9 zbGeJD-@FFLpK3h!*Xq2M$OE%+b>rv)P+2}j@=3408tp8fvO6HSnBxzw%2PNr1 zLCX1~sjeJ9jxQN#BuQ`q^uH614FSqy_~H8@IFCK{SaGz`UosG<7mWy6ihROUgY-(4 zPYHrlCV#$SdU5ZrKcu2xbYC1%4gl3ms-oP2Akp4aP9%C=Nf;nli%C*_eLn++_pL#~ zb5p|TK_}oi!8y?>O?1`{??bDXL6G)zf3s)L7IJ}>X8QSgPQCiBTenWiG2U{^E!ets zYd&7<2ZffNd|pZq7AL0)MiB8lnkUR>;yr6MR%;yk-t{@Ts8QV`sf7CnH5DGu3B`qv z;U|(hy53I#q^c>EcyMGcWKE#W%_41C*y$$F)Y6R2tJY!diZ}4$)6Zhvs?~VyrI%p2 z2JBQC$mXPt1)D$-=u}_XK9V4%aZ8z49W6t|HQ;2j$RdRrs}iGzkHF}?F-T&baf56}V z_BXup$}93Nf*_@aq@^k6!U-pwAS4;G+Bo-m;#PNC+2s$tgS4%+6~;y1`L=t>Pn5cw zmrzW{>OtKt22$-}_n*VRnsDMUobc11{*oF0f~uafVPQ4?FCzJUI81B)#HF zk6{1ZZ-2|B6Q*l`E6}hh5XA23ruC==S27L)XxrYmUyQ~V)FgNz5-hj~GG48(7aU&=(yOn& zT0&JtLCW4v>>x)Y)BsW;s<$@QHSNHf9b2$r$2M$PzX6Zlb{AH?vJCdFCgtb}g<*Q_ zA(gb#tus7|UOslBq@l!AJ&DalfyYw9()Jt?j$>v;9j1&JgGm!7Vf2itnE$a05Sug_ zHhUr)E-c#cI^F{y2-2XrqRl4FIHK0VvDWrG=LT(l3J1;wdW-!V_v1U`eA4VSF4T-J zFwK+a^=|{VNdxL`Hl4-|*I$n-u4MU?78n1VeJrYQ96kX2Rl;jcy;YcY--qsSC+nt zXBIBP`j?l(ZfI12QA$UGj1rFj)FAbmRf)*+K$`FB=1Ewp)#_NaI1s4iurMt)43jE` zVN7K$YU)N{_9@3=&gsXaeEN7~!X~VcG?>h9+9q8j++F3=@^3+qzWd$p&YKb3kMn>8 z7skt}jRXP8f9r)^LQT0GKKjv*$|8Hj5l3|M1MD4;UUpfR8|&)-_ILAAyX}r7-5Ve! z0H|jE&;R_7IBoo%TP-d5H#&Ss=_4qa4a2`tqB3-&9Y@6^y$-=>Nvf+)(C(!TO8b)w z1SJ^(98__&^N7bW#!E>?4l(1cykDJE9(V~w%arscNe2Z|X{qQpZ&ueJ+f4B8FgS7?y0Aq5-mwP>GU}WOg<}ZP1>MLI{4%#KPf4aI%8<>OVYPFNC`Ho zC{!KkjnglM(vAa8b%ucAATu|T5|1mOmN0$ANwuWcAk{8+UW@1Y-S2*v_at)>(kr(H zly*$eCj7)FJ|P5uIg&a=f5G_|2#Dy=5rB#$6&VcMFp#ue>`HWE zebWwX*|h`Pwr|Bl_uhx+9{&$gTerio!iX3q9Cj+tvL~y=aq?aahFd&%s=4cdRI`+H z&qfijt^%lGyRZxcmII8atdd5{Q;bR+J81@{Rn=kYoS7JT>S3rmVit@M)j-&UEnU)G zyx=*Go_uPtG*#w(`8O_-1aAt13%GN6zNPxV!p2}UxuyQw_(esO|U{?#Ho2ClcJ`w2{P?XdVwntMs3Ex zG@}w{jh~5eqsE|o)?^&<(F=e>CaaF;v@0D4FTA(}-?`|!pd_^!>S2RsUrRw9d#1Wi zKvI$tptR+gq@gtsJ*IkpdU474;lH^sGsaF<8^d}2t=MAPZ4&nQ2Y+iyrNgFEY20wb z^|2D9z3Q$ASHk}Nw2x;YMg(;1xku~)IK3Az?4tQ z02%?TY2AetZ>+$^)obwJZMS3jQ_lbm%_w7_-zao!<)q4HG6LM%npzxw_+dEx^wTlp z;2HAVls-}h#x&5<+KO%4w+m~Fq!T7ZkX=(6SHRCdm*b$sHBse;QRf)AVB{Q3sv3b2 z(l0tN%hHE*D!sTq&ob3Y!v_1{RXT#IndMJbEUg#lYRfMp{v;_)(^=GkgT z9&tq8o36uNlBn-xDAAL8?|t{;KaW3wd+xmlq!s4u930QK4donBp(BQc;cgg*g+^k| z$O)J-VG`=+9gLYDdk-*W3=m<3KpW4#^di2)$_$jGwu;9FB`LKU+K^1aql9FK`p3r2*rbtog$b5mi`SF+l^=e;rC+0+gQQ_rL%B z0#NNh3No_#0_&az>AB~fE9$P6qy!wu(S-rZ{->I@V#ymT5Y9Nb{SSY}E4SYbw09zI zga9W8Ct||!QeSv)B_*YJ?|U!6r$7A}NkWK(LkL-_^eQ*b4{di#rj2Pzb_dn-Yp%H( z_uYS=l8QMSmhB*%vt%0e&Ip{DX>4SBxxY0L2)?9Go`(rqdrB)bbp%muE1$l3SG@VT0 z#v9pY;wrSYwZi!3SHI$3cKHIYh?fN;p8?~`Ast|=k05CIvcC7d@8#p9J&^_aYm*k6 z)TD9IaTLse3GPdfQq9pI<-O4^`N~(ml229B$M8FCU-EDMJV>t0e&>RJRpm?M%jY?1 zhidg#OBJ;s_R*TmcjJDL4#vAH&mod@9GF?bV7?!u4r>>~l(5S#xcK*LFJi;a287zv z`1Qq?A-QY?kaJK+oE>326U zY1!K{+|?%Ko~cAa<|xBuk_GdPuYB3PY{3Gt8JGp}b_OXOBD%C=v6sYw)smDFQO7#_ z0x6HvAHHb5L>)@fo?QOape41DETYeR<}e(?Pt;KLvO5Xws9g3Vkm z+bc*35G_#&)Qd0qF@F2o-@wkfs3?iSOsYcb$q*2+fsw9-S=MlzHDNYJ)(peMQ;xzx z?>ie9TMH-R;!K17&K9I6u_?u_~$}z@ax}q-9eh{ z>=bG#K`QyAU;WaBF3Z`QUaHc*08&=uBiTR~9P7`-rX(c;gey-^>Nf|MDi7_+{({s$ z(7X@50`nUBzVxc9|4ol3y}oo5>0)O(*4Dol*LAPGElCMds=A%o47R6|SiE@yHt%S_ zvv)s)2mkgDpsf|Kvk;bpX&~gdC@(2Rdq=wzf&1kzekp2hh;dWNEzJeZto#G{r5eYJ zC0Xu&;C_7UqaQ^}YYUv5i*g~7j-x+v0WiHDsEpy6 zS6{;aBS;sj5R4s&qYiY;=_n$fn(bF;rf3G!;Idr$x_ZwbW%QsMNNGnDsxo*w?f_L? zQFj9QaRXI%2Mf~k&O1+R#UL$A-w!7RLCUx$Gh_Oaq(SM$=is^YYOKK%1Sx?@N5fBk z@)NOZ)MQkjp0ZSWdzEhnNGT&bQYmcgXvd>#R-m;#fhYcY8(w;BArcMS>BG%~G-{X# z8>TqM=v4XMMc+f+s5&(+F4;Muet}d%Zy`&(!}I3N1?%T#QfW|;W{xGj&S3|LF~*5X zoH1$!#?_2O_0;h=^^+ffHD@YN6UTEezaWkyvY~|TrxViq!bcC^6PWZ&vp4|f37t#+ zcf99RT|rAAogUDVG!N3RU3j5OBClkeu+IpMeP+%Kvd3q!=jKECuI3+UsUj=@%p@f)-$HsOI6A5 z+V2af!SfXZssEn(3c&i}+rMV3YZ~O;deDE>k677JK z5s(^|i3mFgwdV4SW-bJ|i?|%oK zCMtVW0X{^!plf5YQH9g%XJCBgaEzHc38#JH11erRyc{n)|1AFBMHk_zMT^8~r=$#mt9d^Od9*0+W6VYMFeOyw~7++cRJ-Zj(~o?E+Hft6d7p{qT%5QX^KY7Yq@52vjq6(j zQWL3+jm@b9?jlHATCwPcf8eDD9z!PC4%iux4n)ZZTag(E(rlYKNXdg` zxPvcOC)gHq1o>A+N>Z|UbcZzm{(g|sUL=uvZ-P{(K2g=BT}n0(B{)}ShHZ3xr8f(t zvM2=Nq<-&i4kR{&@*ur;<*R6JX~h#a{sT)MdJImo6K*y|ktWlGQZ&LGOvjP9}r;Zm% zYRpyY?vm%96PuKA(i|mep5|CEy@J|Mf6WV0LCI3$e9`YO*fntXz}gQ<`lZkRuY2va zzvv=Gm8LuhW3-1SAE+c9EJ#WB(#g2RK*|+TJ9X$@@2@1)Dz4u~EvD{jiNS@1&Ie9N zzF1CVei)X~s&9WM3HRGwbvFo7I@p93=-F?Wpa5AAN%;naQT7-0#brA7EwjXdjo0ETw#&|t3{9~AF?cj7-=9# zZ6HdCiX5h*8fTB0iTaumsG2qor+(%`Fy~ALs!D`4q(Lg`Zr4HwGSvM6sn(GAlXHXb zk`D<*h-FXiHar0+Ld-QAZ!s$YP%r8pLpl&qpa ziTK7FZ{#!g^*+IuMsPCohSV}HB2;~Q^H}d`b+;Qx&pTfc>@`rOW{`n&&c&`=77x7s zDt5NE;A->%_zTv_Q5qO@d11SXsNvtNRaE*?X*msJr+wAV4h{?f|!xFjV= zeUem3R0BE3K#S|(p=GaPb7Lb`zPuE7{P8d7T)P2bHiH?lORaIrniu*_m{u?Wtq&B!n!<4u@}3iC21G$?p0UeymQYh3Q`Hf0C;Bo z1}xjKUNTi~|I=Tv^|_Z2PN!hHIT)r3*Kox-#KvCyFyPP0JOAjT1ptw7q#H={`J^7( zD(B>|X~RZooyltXuPt4gFIN%{TVjtAr0m2x3T2pCG92fPKLlgzMq|pkC!qYaBZ0b7 zWGkY0F#u90Qvj(}bvcLlA=pkj=_GMfQIaw-0m-IdkdsGHper z8h~_W(PpF6p%aNVAys7^I}HN$tpsTTz>208EM312TN@kj@4x&N%kO>=Rw{+ClY>d3 zfayY5JyOWe0?U2;_Xj?RFMRO}m^E`I%Hm~3L8_fq*<2Q#oe3;nya+d3cRlXE=UxFf zom&jYghQ6ZM*wxYjIHNaGWvu5R4cz8V7&u9E6TI2yS&0si=u1FD=3U`>t{v zNt&9IF9wmfM|DLE#?nbqWkn2K5|xF=2vn-Qy5Vq8no?8ZcU+uly72vJjc8A+yMFGj zkQqMp(T}*aDfXngTP%**Tbxw0cjz@^Di>40G~=ikjjN|P>D~q@JDwq`w$Y)4t71UZwmb|zel14ATdBoY=6C^LSJIP7pqu&3ss z9W7dt@_OqxZNwdS-hq4Xxfic2c?s<;tt#=Gp!b6NA=^O=E=D4RIjFUcYo?&+xwmNaFXOiC@%L$zN)ND<7a z@s8J0mG!8!Baq|DXAI8AfvLUSC8gc)_*7)wgIh}27&e5Z1ith#KOR9?PVZhPpbQgYi3l3Y?Lg~dLJwP{kF zs+Jss>>=%CeWBSviYwC5(V-fWK2s}PFpydyjG4~(vNTUn-)ryX22A(U*+JUa*d&94 zvlOIgq+HknSyaoDVwQw?lq^r0Ed`UUz}}Y9%-w97lj*qpqe_p4_@sHg4FcHMkZ$GEK_arpO)|?xTsM{Og1N$eA;v za-eOG{Bg%l={@*g89Q}K3X2O>?<${ez=9Bu=j)h>f`URV^TRbj2*F}uIenRWecIIl*aQe_dYRn9qHf>5;DVhB z>j0rJ9WpY;Wf(}a`8G3c?%o}cLsJH7xl+tsj5{d2=s_7cdrl7abxZ%ifE@bdfV92+ zPkH;b*X7j5`z2O9PYP4yw}91Cuo84BD=U@0o?cB`uoswvCbX2Mh3lU^qpfeeN{dUB zuQ!jhi#E)8f(V!|F{zhQx$7IZO6{V{rT*Hh3C$qy!>fPyOL{_q;2= zqL`r-`V_8foK60!o4E@}nWS*xL^cVNvryz}4!?zNnYUSj#HTe1Zq`88WMI>-TKn95z)}-dwW&&wyhC`RSHcsj?SQAGMk^uGY#vWBK7Nn2hn4u41qDpOZt7Pe6u`WB9b^Qb+JlW zb6LHts#z|}RxXztZogHQfA>boUtZ0ZMB*fO{qYs;ZS83w)ikZMK~|0lr!(4*Cj3m6 z3;W1GZ1#^cNT7)5DlhKc+!qr%Of;ZAn_!Z~75p0JY>jf6Ae9}YO{Pg7yl<2D!j2tZ zdXPeC0>=?y^h{0VEb@f}sR0L|GL#q-nrLCBCIQ~#KJk$_Fqpko&0@_4+05TewWv`b z4X0oXr1=E}K2yB|(gX|%fmTJ?4UCLPXJ3yT>^iIincCibOFn7+w~TamYosTSj+fv? zA%do5bTKCId!&$Kb7lZ3-829-kvOCJuR@BXHeN1YySzqLRxXj+`a1d6h95}HO*crv z%4(7Fc|JqF(>v1M?$0MhldAR$jiLZRtQ#Q3(t#YnUaXA;g?Nv%vuoEb4J2Vk8$GLi z&cF&#u@>;VadTjNKsgXFvy|P`wA@6HQqlFhXP;FfvO&g7TuLBi@d*Ot3R0IGI}^R8 z`6qPfn#dV{)YHb2;?ke(Ct@8}i{hZF009psLywzi~XE=p?=x z2C4IJoi`KspbU44GmHt^l>E3X&M%gmms}y&FR7PRwaewo)z{04jkk-`E)=i4NPA4R z=sr+Z{Fo|8X~qYn2y@ep?oShd)K}B}^3qE$>Ci2=-q>=cW(xCfa^Fy_kYckG4%ap9 zI=N<@2vTaJTbf(^rf&jAvl*n;jgZOwbfpxFfhNrrq}rYri)mEPCC3g+z+6CT8kPAh z_?*myF*C`2AD?jvv`HOtcnCtchsKrm1%*2$Awx5(N%*Q#0Sg491M zK1lIT)f^4{(|!U;XGi4N@#Au=t49vK*CD&#dQ$2kT`Z7tv)Jx{!Dh3#K)@HXQY)%JFgM7Pns$l;DT@L~ZT2V;Q}=~g z!h84&T$cqUr^j_!WGaRr48wN6AZD)E%)e#>Rn*L&Oo^v z&CCQBcy@rweeiqu{l>vdlQ?`jXwyt(g)T@Fzor?QOfIwe@Z3{J2xj z4h>0h*?iTA!i-SL^Yl+bwQ7D|zIM(O=EWrsQth(|DTxO zH+}mSS#|YQvf`R+L>4XZ!@j|YQl;|_OjJvUk{^BK(MM$W?lvDJ=gy`1q?|w2oc%>Z zx<09Uw#@7`%ZHH@FfH0!!CfA1L zfR-)N7Vazj{9%wH)To5&?Ci`qYLWXv*sNZ?THDIjtzG8_cw%`9LVZrnPx=gkDM6!% zB{%~kg%93@mz3e;sPy#rN_SV696o$VKIqsh9q+#{`}gga{@z}V(gGBsl*WO}HPM!U zw7`q$kfySt5?M6ALawU2LI(-o)NrFLs$L>>U%yt0%1b4$tjxa^BNj6f%Yekq?v)W3 zk3RO8f{A?z3u*S4Gsu~usD^?Ivsm0cb_Jo82vVX-v=?SW&WF+G*q(50)|WHP=m|7B z!rZEn!WK~4z8Xlwj7(#m{N|~rmC0#z3$r zfGJZkLnevDA!m*U<#|L?!+s?jXPO#mN`w!GpKGysB(N#+w&~ei&qfGXp#k@Y)}si) zdR=Y7!yWr>%`wxuxi4ya*<_oKYMaP+d7n+^x&)E}$0Em+!aexF z11ijXs+^dnPr{Z;3Zy|ti&`{Lkm+a&PtGLI`Vn1kOom5BXvhSmPa^&#m zvTyHRWmp&*8kW(~)2dbZeMNyLt*@?8j-=Y9)l$23nOt+_N~x)?*1%4zs8D1P$9 zmB4vaa0W!b`gdQr1O-nztP7e}N;Cmzc(#u1J(XezLJJ&a({$_+LXG{V8i^nvu?VAN zb!XhN)|@F=D#?H2Hj!4dK;^VR`hVWvtxr6m?QvSnkfup#79`I!!ypATB>UkvWnsdH z$cpG$Omc=uB8u0|lr*qrbHMpNnhMQj01IncGfCM%s$kHz)L*igEHGNgMjF}>CCl>x zUNkYLDCSsLN`{{YLBs}gZ8SU2j%4OKR_LvT)9}g$eWyG-!i0N6Q|AIw?hRIbp3%w@ z-R~P28f!zYa9&A?mI>NHH;`sZx&ca}w$^{@4_xvYJd$2gg^s3`;sr7^I4DQ^`ej~m zv5X9l=#*-h7D&e!NDK1fQXG#yyi!?EStX@aO!QWjuD~1{ONd7SJCS3T^VxtI z(xm1?+5qNo1sD4aczK^Fx^Wg|v(VTJn;&F_5DepD@3@vS@&`V#X;${TySrN>_9&Y3 z0%dvl8q(x2UPkGJE69WoEof`x6$zYo;z8{3ZCBY0#42r4$bT6VWsvQp$e*B9074rwtV%n$Ub<%TN-d9IJcSEV z14+2hBK3Yir;-AxF;VJIPZChF1nD2Ht5rxg>_kZ(CRXscl}irnBlk`}8^MH`38ZP3 zMKH!9{L5w>q%F-dOmz1rcW?A|?%XM*6nS&=v&h_?(u#ipANneTl;utV#2p6gxG@SU z7gs@BN*YLmU=Zdq1^$4PukbcBES9I$-{*AOOwdN@x_L^cVfKO4T~$9w=9|0E$S|q8 zA8*{?5qT}Gs7PznJ)hd$DXr8c{GqVq45ta0^Im-MMJcPCGk0@d%&+Jdq7LyK zNYC$JBohhQ($uJ$bae2f#5Ue_r}u}KU!DW$`K{|$>f3W5%@EC+!4m*Tn;JLEbK9Hc zG(PEuJAdfC{K_kHAf3TQzSJ)j2~s~jF#eh|cc*kDY{}>#LX!g0GlM7Pf2nysEeiU~ QjQ{`u07*qoM6N<$g88?WF8}}l literal 0 HcmV?d00001 diff --git a/test/Charly/01-begin/04-manager/public/index.php b/test/Charly/01-begin/04-manager/public/index.php new file mode 100644 index 0000000..bbcd2b5 --- /dev/null +++ b/test/Charly/01-begin/04-manager/public/index.php @@ -0,0 +1,114 @@ +selectOneById($idComment); + // view + require "../view/comment/selectOneComment.view.php"; + +// insert comment page +}elseif(isset($_GET['insert'])){ + +// real insert comment + if(isset($_POST['comment_text'])) { + try{ + // create comment + $comment = new CommentMapping($_POST); + // set date + $comment->setCommentDatePublish(new DateTime()); + // insert comment + $insertComment = $commentManager->insert($comment); + + if($insertComment===true) { + header("Location: ./"); + exit(); + }else{ + $error = $insertComment; + } + }catch(Exception $e){ + $error = $e->getMessage(); + } + //var_dump($comment); + + } + // view + require "../view/comment/insertComment.view.php"; + +// delete comment +}elseif (isset($_GET['update'])&&ctype_digit($_GET['update'])) { + $idComment = (int)$_GET['update']; + + // update comment + if (isset($_POST['comment_text'])) { + try { + // create comment + $comment = new CommentMapping($_POST); + $comment->setCommentId($idComment); + // update comment + $updateComment = $commentManager->update($comment); + if($updateComment===true) { + header("Location: ./"); + exit(); + }else{ + $error = $updateComment; + } + }catch (Exception $e) { + $error = $e->getMessage(); + } + + } + // select one comment + $selectOneComment = $commentManager->selectOneById($idComment); + // view + require "../view/comment/updateComment.view.php"; + +// delete comment +}elseif(isset($_GET['delete'])&&ctype_digit($_GET['delete'])){ + $idComment = (int) $_GET['delete']; + // delete comment + $deleteComment = $commentManager->delete($idComment); + if($deleteComment===true) { + header("Location: ./"); + exit(); + }else{ + $error = $deleteComment; + } + +// homepage +}else{ + // select all comments + $selectAllComments = $commentManager->selectAll(); + // view + require "../view/comment/selectAllComment.view.php"; +} + +$dbConnect = null; \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/view/README.md b/test/Charly/01-begin/04-manager/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/01-begin/04-manager/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/01-begin/04-manager/view/comment/insertComment.view.php b/test/Charly/01-begin/04-manager/view/comment/insertComment.view.php new file mode 100644 index 0000000..cda81f6 --- /dev/null +++ b/test/Charly/01-begin/04-manager/view/comment/insertComment.view.php @@ -0,0 +1,25 @@ + + + + + + Exemple du CommentManager::insert() + + +

Exemple du CommentManager::insert()

+
+ $error"; + ?> +

Insertion d'un commentaire

+
+ + + +
+ +
+ + + \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/view/comment/menu.comment.view.php b/test/Charly/01-begin/04-manager/view/comment/menu.comment.view.php new file mode 100644 index 0000000..bc39b5e --- /dev/null +++ b/test/Charly/01-begin/04-manager/view/comment/menu.comment.view.php @@ -0,0 +1,8 @@ + diff --git a/test/Charly/01-begin/04-manager/view/comment/selectAllComment.view.php b/test/Charly/01-begin/04-manager/view/comment/selectAllComment.view.php new file mode 100644 index 0000000..41a6d19 --- /dev/null +++ b/test/Charly/01-begin/04-manager/view/comment/selectAllComment.view.php @@ -0,0 +1,33 @@ + + + + + + Exemple du CommentManager::selectAll() + + + +

Exemple du CommentManager::selectAll()

+
+ +

Pas encore de commentaire !

+ +

ID : getCommentId()?> Voir ce commentaire via son id | Mettre à jour | Supprimer

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/view/comment/selectOneComment.view.php b/test/Charly/01-begin/04-manager/view/comment/selectOneComment.view.php new file mode 100644 index 0000000..faa9e50 --- /dev/null +++ b/test/Charly/01-begin/04-manager/view/comment/selectOneComment.view.php @@ -0,0 +1,34 @@ + + + + + + Exemple du CommentManager::selectOneComment() + + +

Exemple du CommentManager::selectOneComment()

+
+ +

Commentaire inexistant

+ + +

ID : getCommentId()?> Voir ce commentaire via son id

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + + \ No newline at end of file diff --git a/test/Charly/01-begin/04-manager/view/comment/updateComment.view.php b/test/Charly/01-begin/04-manager/view/comment/updateComment.view.php new file mode 100644 index 0000000..a561f15 --- /dev/null +++ b/test/Charly/01-begin/04-manager/view/comment/updateComment.view.php @@ -0,0 +1,34 @@ + + + + + + Exemple du CommentManager::update() + + +

Exemple du CommentManager::update()

+
+ +

Commentaire inexistant

+ + $error"; + ?> +

Modification d'un commentaire

+
+ + + +
+ + +
+ + + \ No newline at end of file diff --git a/test/Charly/01-begin/05-together/.gitignore b/test/Charly/01-begin/05-together/.gitignore new file mode 100644 index 0000000..d11ccf2 --- /dev/null +++ b/test/Charly/01-begin/05-together/.gitignore @@ -0,0 +1,11 @@ +# Ignore config file +config.php +# vendor contient les librairies externes en PHP +/vendor +# fichers non envoyés +# PHPStorm +.idea +# VSCODE +.vscode +# Charly +.history diff --git a/test/Charly/01-begin/05-together/config.php.ini b/test/Charly/01-begin/05-together/config.php.ini new file mode 100644 index 0000000..ae92c13 --- /dev/null +++ b/test/Charly/01-begin/05-together/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/01-begin/05-together/controller/README.md b/test/Charly/01-begin/05-together/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/01-begin/05-together/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/01-begin/05-together/model/Abstract/AbstractMapping.php b/test/Charly/01-begin/05-together/model/Abstract/AbstractMapping.php new file mode 100644 index 0000000..6c5f9c1 --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Abstract/AbstractMapping.php @@ -0,0 +1,42 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst', $tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + } else { + // sinon, on affiche un message d'erreur (à commenter en prod) + echo "$methodeName n'est pas un setter valide
"; + } + } + } +} + + diff --git a/test/Charly/01-begin/05-together/model/Abstract/README.md b/test/Charly/01-begin/05-together/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/01-begin/05-together/model/Interface/InterfaceManager.php b/test/Charly/01-begin/05-together/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..2d70ae1 --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Interface/InterfaceManager.php @@ -0,0 +1,18 @@ +db = $pdo; + } + + public function selectAll(): ?array + { + $query = $this->db->query("SELECT * FROM `permission` + -- WHERE `permission_id`=999 + "); + // si pas de résultats + if($query->rowCount()===0) return null; + + // récupération des résultats au format tableau associatif + $result = $query->fetchAll(PDO::FETCH_ASSOC); + // on ferme le curseur + $query->closeCursor(); + // initialisation du tableau de sortie + $arrayPermission = []; + // Pour chaque élément du tableau + foreach($result as $value){ + // hydratation de PermissionMapping + $arrayPermission[]= new PermissionMapping($value); + } + // autre manière de faire le foreach avec fonction fléchée + // return array_map(fn($value)=> new PermissionMapping($value),$result); + return $arrayPermission; + + } + public function selectOneById(int $id){ + + } + // insérera uniquement des enfants de AbstractMapping + public function insert(AbstractMapping $mapping){ + + } + public function update(AbstractMapping $mapping){ + + } + public function delete(int $id){ + + } +} \ No newline at end of file diff --git a/test/Charly/01-begin/05-together/model/Mapping/ArticleMapping.php b/test/Charly/01-begin/05-together/model/Mapping/ArticleMapping.php new file mode 100644 index 0000000..7a2fc92 --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Mapping/ArticleMapping.php @@ -0,0 +1,124 @@ +article_date_create; + } + + public function setArticleDateCreate(null|string|DateTime $article_date_create): void + { + $this->formatDateTime($article_date_create, "article_date_create"); + } + + public function getArticleDateUpdate(): null|string|DateTime + { + return $this->article_date_update; + } + + public function setArticleDateUpdate(null|string|DateTime $article_date_update): void + { + $this->formatDateTime($article_date_update, "article_date_update"); + } + + public function getArticleDatePublish(): null|string|DateTime + { + return $this->article_date_publish; + } + + public function setArticleDatePublish(null|string|DateTime $article_date_publish): void + { + $this->formatDateTime($article_date_publish, "article_date_publish"); + } + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + $this->user_user_id = $user_user_id; + } + + public function getArticleIsPublished(): ?bool + { + return $this->article_is_published; + } + + public function setArticleIsPublished(?bool $article_is_published): void + { + $this->article_is_published = $article_is_published; + } + + public function getArticleTitle(): ?string + { + return $this->article_title; + } + + public function setArticleTitle(?string $article_title): void + { + $article_title = trim(strip_tags($article_title)); + $this->article_title = $article_title; + } + + public function getArticleSlug(): ?string + { + return $this->article_slug; + } + + public function setArticleSlug(?string $article_slug): void + { + $this->article_slug = $this->slugify($article_slug === null ? $this->getArticleTitle() : $article_slug); + } + + public function getArticleId(): ?int + { + return $this->article_id; + } + + public function setArticleId(?int $article_id): void + { + if($article_id<=0 && $article_id !== null) throw new Exception("ID non valide"); + $this->article_id = $article_id; + } + + public function getArticleText(): ?string + { + return $this->article_text; + } + + public function setArticleText(?string $article_text): void + { + $this->article_text = $article_text; + } + + public function __toString(): string + { + return "article_title"; + } + + +} \ No newline at end of file diff --git a/test/Charly/01-begin/05-together/model/Mapping/CategoryMapping.php b/test/Charly/01-begin/05-together/model/Mapping/CategoryMapping.php new file mode 100644 index 0000000..cbb3d1b --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Mapping/CategoryMapping.php @@ -0,0 +1,89 @@ +category_id; + } + + public function setCategoryId(?int $category_id): void + { + if($category_id<=0) throw new Exception("ID non valide"); + $this->category_id = $category_id; + } + + public function getCategoryName(): ?string + { + + return $this->category_name; + + } + + public function setCategoryName(?string $category_name): void + { + + $text = trim(strip_tags($category_name)); + $this->category_name = $text; + } + + public function getCategorySlug(): ?string + { + return $this->category_slug; + } + + public function setCategorySlug(?string $category_slug): void + { + $this->category_slug = $this->slugify($category_slug); + } + + public function getCategoryDescription(): ?string + { + return $this->category_description; + } + + public function setCategoryDescription(?string $category_description): void + { + $this->category_description = $category_description; + } + + public function getCategoryParent(): ?int + { + return $this->category_parent; + } + + public function setCategoryParent(?float $category_parent): void + { + $this->category_parent = $category_parent; + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/05-together/model/Mapping/CommentMapping.php b/test/Charly/01-begin/05-together/model/Mapping/CommentMapping.php new file mode 100644 index 0000000..c3de343 --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Mapping/CommentMapping.php @@ -0,0 +1,152 @@ +comment_id; + } + + public function setCommentId(?int $comment_id): void + { + if($comment_id<=0) throw new Exception("ID non valide"); + $this->comment_id = $comment_id; + } + + public function getCommentText(): ?string + { + + return $this->comment_text; + + } + + public function setCommentText(?string $comment_text): void + { + // cryptage + $text = trim(strip_tags($comment_text)); + $this->comment_text = $text; + } + + public function getCommentParent(): ?int + { + return $this->comment_parent; + } + + public function setCommentParent(?int $comment_parent): void + { + $this->comment_parent = $comment_parent; + } + + + + public function getCommentDateCreate(): null|string|DateTime + { + return $this->comment_date_create; + } + + public function setCommentDateCreate(null|string|DateTime $comment_date_create): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_create, "comment_date_create"); + + } + + + public function getCommentDateUpdate(): null|string|DateTime + { + return $this->comment_date_update; + } + + public function setCommentDateUpdate(null|string|DateTime $comment_date_update): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_update, "comment_date_update"); + + } + + + public function getCommentDatePublish(): null|string|DateTime + { + return $this->comment_date_publish; + } + + public function setCommentDatePublish(null|string|DateTime $comment_date_publish): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_publish, "comment_date_publish"); + + } + + + public function getCommentIsPublished(): ?bool + { + return $this->comment_is_published; + } + + public function setCommentIsPublished(?bool $comment_is_published): void + { + $this->comment_is_published = $comment_is_published; + } + + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + if($user_user_id<=0) throw new Exception("ID non valide"); + $this->user_user_id = $user_user_id; + } + + + + public function getArticleArticleId(): ?int + { + return $this->article_article_id; + } + + public function setArticleArticleId(?int $article_article_id): void + { + if($article_article_id<=0) throw new Exception("ID non valide"); + $this->article_article_id = $article_article_id; + } + + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/05-together/model/Mapping/FileMapping.php b/test/Charly/01-begin/05-together/model/Mapping/FileMapping.php new file mode 100644 index 0000000..e26665b --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Mapping/FileMapping.php @@ -0,0 +1,64 @@ +file_id; + } + + public function setFileId(?int $file_id): void + { + if ($file_id <= 0) { + throw new Exception("ID non valide"); + } + $this->file_id = $file_id; + } + + public function getFileUrl(): ?string + { + return html_entity_decode($this->file_url); + } + + public function setFileUrl(?string $file_url): void + { + $text = trim(strip_tags($file_url)); + $this->file_url = $text; + } + + public function getFileDescription(): ?string + { + return $this->file_description; + } + + public function setFileDescription(?string $file_description): void + { + $this->file_description = $file_description; + } + + public function getFileType(): ?string + { + return $this->file_type; + } + + public function setFileType(?string $file_type): void + { + $this->file_type = $file_type; + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/01-begin/05-together/model/Mapping/PermissionMapping.php b/test/Charly/01-begin/05-together/model/Mapping/PermissionMapping.php new file mode 100644 index 0000000..db0a4fd --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Mapping/PermissionMapping.php @@ -0,0 +1,48 @@ +permission_id; + } + + public function setPermissionId(?int $permission_id): void + { + $this->permission_id = $permission_id; + } + + public function getPermissionName(): ?string + { + return $this->permission_name; + } + + public function setPermissionName(?string $permission_name): void + { + $this->permission_name = trim(strip_tags($permission_name)); + } + + public function getPermissionDescription(): ?string + { + return $this->permission_description; + } + + public function setPermissionDescription(?string $permission_description): void + { + $this->permission_description = trim(strip_tags($permission_description)); + } + +} + \ No newline at end of file diff --git a/test/Charly/01-begin/05-together/model/Mapping/TagMapping.php b/test/Charly/01-begin/05-together/model/Mapping/TagMapping.php new file mode 100644 index 0000000..798f6b9 --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Mapping/TagMapping.php @@ -0,0 +1,44 @@ +tag_id; + } + + public function setTagId(?int $tag_id): void + { + if ($tag_id <= 0) { + throw new Exception("ID non valide"); + } + $this->tag_id = $tag_id; + } + + public function getTagSlug(): ?string + { + + return $this->tag_slug; + } + + public function setTagSlug(?string $tag_slug): void + { + + $this->tag_slug = $this->slugify($tag_slug); + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/01-begin/05-together/model/Mapping/UserMapping.php b/test/Charly/01-begin/05-together/model/Mapping/UserMapping.php new file mode 100644 index 0000000..400ecea --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Mapping/UserMapping.php @@ -0,0 +1,87 @@ +user_id; + } + public function getUserLogin():string{ + return $this->user_login; + } + public function getUserPassword():string{ + return $this->user_password; + } + public function getUserFullName():?string{ + return $this->user_full_name; + } + public function getUserMail():string{ + return $this->user_mail; + } + public function getUserStatus():?int{ + return $this->user_status; + } + public function getUserSecretKey():string{ + return $this->user_secret_key; + } + public function getPermissionPermissionId():?int{ + return $this->permission_permission_id; + } + //setters + public function setUserId(?int $user_id){ + if ($user_id < 0)throw new Exception("ID non valide"); + $this->user_id = $user_id; + } + public function setUserLogin(?string $user_login){ + $this->user_login = trim(strip_tags($user_login)); + } + public function setUserPassword(?string $user_password){ + $this->user_password = trim(strip_tags($user_password)); + } + public function setUserFullName(?string $user_full_name){ + $this->user_full_name = trim(strip_tags($user_full_name)); + } + public function setUserMail(?string $user_mail){ + $this->user_mail = trim(strip_tags($user_mail)); + } + public function setUserStatus(?int $user_status){ + $this->user_status = $user_status; + } + public function setUserSecretKey(?string $user_secret_key){ + $this->user_secret_key = trim(strip_tags($user_secret_key)); + } + public function setPermissionPermissionId(?int $permission_permission_id){ + $this->permission_permission_id = $permission_permission_id; + } + + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/05-together/model/README.md b/test/Charly/01-begin/05-together/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/01-begin/05-together/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/01-begin/05-together/model/Trait/README.md b/test/Charly/01-begin/05-together/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/01-begin/05-together/model/Trait/TraitDateTime.php b/test/Charly/01-begin/05-together/model/Trait/TraitDateTime.php new file mode 100644 index 0000000..6b56182 --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Trait/TraitDateTime.php @@ -0,0 +1,34 @@ +$paramName = $date->format("Y-m-d H:i:s"); + } catch (Exception $e) { + // en cas d'échec, on met la date à null + $this->$paramName = null; + } + // si c'est un objet (DateTime seul possible) + }elseif (is_object($date)){ + // on formate la date en string en DATETIME + $this->$paramName = $date->format("Y-m-d H:i:s"); + }else{ + $this->$paramName = null; + } + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/05-together/model/Trait/TraitSlugify.php b/test/Charly/01-begin/05-together/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/01-begin/05-together/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ +PyA07*naRCr$Oy?K;mXL;uNyK8K@XDykvuc}h1w3K!%v;q3 zGkvE2oO7iArrXBGHnuU??mq1~LH8jeEc6d$;F(UZYwoN490t{4fj?FlPO(^`DFB3Pk7mWKUij zbKkMGdKP~Rj9C{iA`AmweDS9|^w2}R^2#e1m1;3^Y-biITOeKh1zrx%Om1?dkdfT+ z^99rdehnDPJL&gsJmj2OKwaGGm<4AM#|vTO@exw!h#vZM=N*yZpHeREG? zITcvr``LW53mMoZRLy;=Sj)NZX4CpZ@Gc9+H?; z5=SkNF8MuqS8v#SLnRgzT!e;>LZc>YCRmx3M=~Ico#Rshwf>s<+~g+sCs>qsm-8|8 zo9nOUJ)#wmF6v${3ZxQ~TBg;CNf&iVFWi%6-%Nv0Tu=i70V+@<#PfVCO!XxeE^$K> z3<-#mpUpWSvf{Kv@_YFng*q>#z6_Amg}j#nC=pf!PU7y)${gwI)NE1bdH@&hN-nQ= zZh>@p-H&&5HjSI9O;%`Vp!z@+`5qBAS<|`I?o$!S zu4O8KrXsMzNVWyZI@YsQ2|#Br!jsE2@9Ltw2VT4&NK2)Hib-3R^y0YN%E47u%}{{! z4GqxYnMr2KWqjAdOSyPvY(?wVRLo-HEotaQQADUrWT<{_!8E9*U24jAjlov;J9X5VDmb5jTx%?f_cpQzZo$Ow~&kQy)=MErdJe%=}zrJPDrH647hf?^vbsbnZ8 zwW+46<5kc=jzXOVmS<>>)lkVGTUkc^2#kopmRI<=wF*5E+_d#lws&>W7Jw^aNY4hG}4i0z5+{h7?FmsKp>ndj(d65w~vM$*#^$ z+GCK0mVjA5U*0{{0_ma_(}I?CdU`TyYirXnND}n7Ea{>y?uB?#Gf2g*RWTWk;HU2h zNXIFpGn8x>->~8gthlp2h5~2|(nz@40@T?cl_XTNC3V9FNPQDLTP&+b#+zY95OVwG zom|%0MZ2$)N7zyhl6R3LQk?Z|HsCFHcittlAV{aCCZhKC_7+Gl1me!>Jym5?#g77o zihvY&;hlrLGBHj*lclUcYN{lU8HG4zMC6Oj4dU9V_@x43QzxOsk|uRj10)s|cUM5F zYM`+tRUkDyQnfrQLk-g1T|IPGCH@ruILQ>v_rdggs4`9y1@){h!F%jQiw0@KiYlAh zYE@gN3qfahRrE+?SdjE#hj@8nfIxW>~z|=XZPiplNG7U=nz-V z&kG?8!7(B2f@`Y3i7PBw>A5t**=ui^UikBPS}l;C$BTO*4sFCG6YZCplud&Z0@8s) z{CaXyxw}=vR`IHU)CmI|-=jD=%FxkwXmc!#a!tjWs;(J7l!db-*`y!Jl1faflD{!X zZDAONSmiR^m4IDtJ0IPB4ej{~xgbIk%Cg`BFT}G=QfpRXZ|sLQm(Vfr#KXqGmJOnr z9aRsrF2ohR@b9@Okal!*%sJDRCB5*sZvHb+AQh{n93GRhWiSXlcjOQ+O-`xAQ4nc& zR=cbr*&yJhpFGPmk39_I!%(YW2SIE}^`SIKCEYUzq_I0J_1Kyvqy<4Tg_FScSk> z?rp=AYInEJ0hISp;jg%^@!!Oq4Ggk@%}Nh0GdlU$rPr`6O4C&faSemOFqrZ@!oD6h z-hDG$?!OZ@tt85t6l0L4FcsL7$8UO!x}YU(fpodT@idmyk5{;9P_iuz(!&Q8NK5G~ z0Zwd54bnkCN6q8)r=H>mfBQEuG6-HlWqca|Z9>fKO}*)VVrq4{wGERF&u1q&?p?c^ zySg{gGviU2oF?1RLD8`|mWfz>?=5Wq;=h7b?U1u5IP!9Xw79(Ww>09a!f!4ce?gE+ zowO~dOE4`|#UBA(||ZN@pn8CMVi0QXjmUUBCYsSl0t> z4kcF?f#$cQEs(~6$I0$)3#5x(p3CETYS*n>(kQm12}q|JAT=aQqe0qMDskYMXEaEM z1*D~S1yXTq)4tDoEcVdDXSQC=E~}GlzDmk)C=fB;m8QIB6W9FjpNH*hpxvS3=nSup zN$0w|Es!Q46=jB>{PZWPpY*lYUd3pEba{Ypv1g${npo0>Kx!&?x4oEv^lSLTgW#9z zAl2O5*&U{*OXR3zlwsidJ}ZIUbo22oS8`oPKfTi)ZY`t|8BBGinB2CC8~@`MVb=!e zO5??32Wg{A>aX&-f79i9=2K>P;e{7?=%ELB{q@&dAYCjtmdo=_57OzAENR*gX)hIH zODZ5eLFCP~q`DT`NaW16YR#Y(a0y?@5%2>W$#C!1J-n}T4Vwy(&U+Y^!(`fIY<(9u z{onr{cCCY+ERn5S>*j*81=87x08tBk?z!g_NZ)+(O^jCJXt}^|ap!R|NF}=~?(P6D zO$tbJ1lWq`Ahf@wk?uGDuWwwxlsY1*CK8l?gcK1F4j7(!fe=Zd|dM zn|n8KquE8rjE`+NOt}WbD>K~uAHD!LUk)pBI(sagHL4!l*a%u6oefga-F@bnrW8#)*h*8nX^DD1p5}_XmJ2p4$nFpkakzA?0xD94bs75ipY>y()p}uv*i>k zEB{ZvtC&<7;Rw%)RJ~JrOE=>3@zs0y$lA;3I5LH6S{zRYSl4dj%K!7A7Z$J5CzW3Fy5DG}6;EX^T z`^CytReh#fe1)p?mqySNnyiWp-k;sded{l0citxJMNGBZOs((W@_+wn(zos*vO`Kn zs0a^<>U}G_8%xa8m%u!hw3RqoJV2JiGv|V|7=u)CcTWM*Uf<*GCw|PMfA#051nKEM zTXW1h7o>7NU0AdQ0lVqtp1$3DFte6iIiT9^Fqn(z|JW^T`~3Z|aV7b}B)K-p3%6p@ zdQ85MyW0Zka)93A&!G-d`N0gB3(`_5hc8_)P1)UZ3R2Y_6HADyVSEwohE2N%Ye;jA zy_yHsT+Rlk4N+>yXHBf#8@c8WJ_CEU;5i|dtr|~TiKF-mEa>jG$P9}I$Z~k5x}l2E z7ZFKzH?gFLrBy9Y@hm{P7%MtACY93=cUSsEh31zFO*(y(HCTMC=W?!Hxsfh2g>OWZ zJ5${Bd!NGk_$`ow(3bwv*6g80TT&4sYt}f@FKl(eEC)c&cMh{aDlw_4W76lEKpGg* z^xdeFCYJP(zx*>I$?ndHNzW9dk}MKZf+#g4QoC*dnZTeoGT6gPZd$#StGd_Gm+NG@ zRAA!=ZlLdTABG)kkPh@PQR1G%IBM3{Uat4xT%Xs1mb3-ZbA8Fr@A2v&H6lW>q^8Nx z0w9&d(Y~jj>#dRHJ#fTJ{#6oV*M236k-QUT;V*k*Kad*?>(ShJIr zp2b8^VfXJpz{(F@2Rk=8rv>fppqS5-U0+L6VeYL?^#H zu-IvJazod8uJ2e!fA31njVrm~cRm3-*TU9*ZH0XiGJvIep))k+aNm#ORZD#QFPG>?)6e=z~I1=5QGdW%0v0jUg% zP?l7=yV{bT4x~a09C+bbzWvAl874;0IY^b{O7aleplOhfOfr!{FBX^CE4gCLX4dwu zqJQfquDJVl*4=so^!HGuN|;S44_+mUl~T*uL#zeT#jmB-Gtbi%NI)vHSp=ja=~)Nq zcwWn=%yDA(HD-h8aQ8&aw6!g#b(E{n&Ub)um&e;`E@nY=m&IRc!<2oh{tl2T?c?W6J zr_(cJBrerJllU}^$x1S8%5<}3Wj{N2?Bx9)xs%=Z+=jiek7>W8_`GSu!WQ9dHOHp$ zI1|veKzh!WTI)b(dj<4}!iKvmmUKiE>?I~$1|SuX$Oy!G7FZ>tL)viYC&Rj27rmKw zZoK^#uK(CwyzirTQZWOSDRwOz%d!ZqIho!waDUbNHogDZUgxEJT`MMC%B#Hu@1>OH z)xZcDMc8n6f3i$KDwiM`Qz63IGXKppBqI&oIP{tstk7fU)=RnZ&fB^3zK?R{)q5~A zDcuzAYLJFaEBDNFdE*VD38<&a5-*qOZVQ66#ob*3WSzseP-7s(lEyJX7{u=a$IL0`kuo(x`-~A$;t7kvs2o3n;$J&;5oeu=kQ<` z1xVw?ucj`>>iCiYmdW7~tBMerBg6+x+S}Us;vf7keDM$dE&W?IQ!M1MOcUF-FolRO z^J$u8$KeY#9@sBgx{X(}Gx3xafXY&h!e>1}~@8QiSJ zoWex`(o=nqghnWn)k2wRYN}FAA*iu&-FiNB-#y&*v3uEd-PO3+EV)!xHJ6KPtSqC< zkpbEg(;9qR%=8_#d$YyhN zc6ZU$-A%Tw4cmtmc7_aE#zh{Unk%KDD#y|xaY*F(M7~dZCabKeIL_i)E*EenH+n&L zw*}IR1fB6|o-IfZKK~5g`IA39KeWKbUc$uPjX|1<=haBb#+NVGB5*B8J8a%_B{$!8 z8<+373OAR<$)-uSx6{?$Nl&VSb~jBXoziOhVp$sIg<~5N|2fgq%wF|YNSRwMHKq1 z+_sggZ@Q6d-v2(@R`o(#hRAT}&i0UVvt&{(Y0D<(q{uocT-(O zAZx(J!^lHvjGOal;tVgfrJV~>5yuuu&j%lTh<*F^VzeyjnXIx4|J<_$>HcS);^9C0 z5{wRCSdb={P-4>9l1d#^7)O4SXm;d#3Q^f@o7r{k9;S3BKVF1lo2+GR54s zaczf`63-UPYZ;h*E9qIYnmyND$2IS}nYL9M z@$EE`ZBY|)zGdK>sGl7I(&ZA}VZ`oLYq@IU7CJ2hH!jntfm1T@DhSl1^!f*FUh*=r ze93%b9Va)}h@vp$>8BC}`xZ!-D;7_AUS|tZkx%*VU;OF3@+l{cnNW@8rvPbO?l|3r zTc}xkF3rzY>VdHZla!B=XNiF#Kuy`u)<&kSou2-6eBk5%nx6HW=vmW8#e|9(QL_xH zDl6oZ@+)+Qu%~w|H*VQPn-6JQCz!eCr+_{5XPcK$3gWHzHa82^%X*Kcf>fW`yZ{sG~Lr9x?gpM59i6TsK zdFK-Mmts?B_G>n^sY+E|s&kjbR5GHJX_ih^z6 ztm@&?Ti*v)?t+v-=o)y^Ef?zxpX+WmpkbA-v}9`AHY3v&gsWhF`v zssg?ti65yECkY=Nxi&Th0iu99Vl!#(>)Foz8!w}OszPTaP`?ihL(R__P8pb2Y~za0 zKLGFF16fmz&5-dIOAAs>Rh;z*quG{paPU~PdUan5q-Tzo3-XHP4pLRBoV)1euC4_% zixQwF7QImt5r8JvbpFe4g^}uz*^0~ko!fX|<8IbWlS1=6Lt5$Eb%mIFu|?(qDKhXoAj$@R$v zF3wyX-c#@_)KSD*N*#174)=F$52xsE%&UcZ{M2M^bQk(m`w)4P-%UCm6p{wH057OWL6ue(7sYTVXi7Z2d^mIGH zIk}UKgDeQrW5u;KzfcZ{P{ZEQh-#rqq83|11DDflLai#P@1}~OCa-HL{VRf zq@n7Wr>muk!1w7NvkS532c)sPt3bL3a*lF$qq-$s=p4`89X>rs2QXS7o$q3w+Z&X` zXbUg4g~@0a0;J6T+RQI7S)nh@Bw%pyhw<5VYI!Pgq#zkD*jaw*j(&XrrwMs2HNMlk#^68||pTnfTvxn8~U1V&B@ySVMN(E-TA~m3_ z1hF;QAQ1=?pd~nLc6T+ysOjU^FJvNetw{}weVmmg6_92fe6gg<5v0Glb<&2#Y%Bnc zJPpM-zN&xM8aa~nlUOY2g;aeNiY+75?YM4N*P5Ii+a-TZOokNURU>kuXcwE4y1-Ub z|7CKHDlwyC!g#70Fhax&0|UG=KBI>SThdjj+nh6g$cn({?I$$BJ{&xzq_xesOrkar zi6u`PCpI=KDQ~o6u$C=7{Tq1g?Kc=J=Q&&$V}ugZM3lv%+Nkz1U)483#IcRI zS2eMo&BE3V&qV{Yv7t5j!V94FJqgm^+@|mOL8=#u2C3fE^%QCi-9#obF0RMZsRL=i z*3wt8eN3!?HW6xmi!vkP%4%Dz++3v(8)^3{jHNx~iB0m9^7AZL@qB<(n#fOE+nf#3 z4h%Mv<&*37aMjB7xM`PT6Qk@KKf&7*gX|9{m=U0w2A*qCj(q$;N+9~=)uz^DJ)8ZN z`p@-iprt$)8zR0ZLHe6b3!LrFCLU)3P+ew7#udbVSyP8_;?4RkKIiH0vkS;bbxJaK@cdt|o6cLJGm0>E^HgUgn461=9)>8nQ2&&8XxsT*^N$pTA z!uUzzkSeFt_sLk6O2`PgS{q$$b#*M;6yGZBC$nIDN*Ii)Sug{<9J{+3q{=B@oV&XS zkS1p!F{$)wZX?6L>AQ;G>fV5puaGh=4A-WTbvPIld1G>rH%5+f&>vxjK*g%^*{ej9 zfSQzZ=FDkHK$?)}^|fwJsx7>*gs`9)NAuN5wH0rW8Mbk$lwevh>B1NG!at({0$CHv z6_dD6GM8b5bZHo}=3{`#f~&^h%!g13pccv?+z3zVg~;oqb|{(80N?ZCeo3*)2DV|T zMV*nc^@Oa*rs;HS(qdgCQyO=CD7Raza#M*TNnNQJ*zhSDFea9CV1Sn=bWG}-);R@f zGjTyDj!+=|-0D5t(y@W=N<><8gXFqc2BTq>$yCHxCgRt_hk0%MIOUYZbgjgABr$8C zwQ`%LMI@VFqR5c^KS{35UL&UvQBqz>LJOP=Qq4FLZ>D0J3@cjTHg-0FG-yg3or0cD&>GULhD zNyMw?lWHNdq7gBM$xj9j@$!ToB781Es<*F(Fqy=aSztS9zQ_H-$^ZZ$07*naRIq9f zw{~n`MJXaz)9!3!o0J@}?lp?tX^w_PCNma?^J5$y8RE#q2$R$(;88_tt=hVZN1}k6 z3}0$a=+^5q2{=!Eel@RWnGFKFVge zG=p>kOAisA$WuyXsTt-hOWNysO5^DJfBhAF$?k@F!K&lQ?lH&RZFa94Al1(okY*wQ zX^PLUzKYx0H?XQ~D3D5)T2%Y|oXdz;V#Q_KXy3e!ePcr$96rI=)FhMDB1fmk7%WUN zT$~_}Pl13Ufr?!Pu+q~hpgo(1oS%$b+=>;`0xyqgff7bYPF#ajENN}eR(3VJyS7af zmtdBaCB3-G3@7iXD(#|HR&00Trz96$rGgA8!pCJwm0xY#5^=XAPMi#3I3F-pDKS*c zGwIiusFo>s9yO(AXA#Jv#L#i6DRekf55JAIb4-!<5Ri#>j>NX|<%gJ+8kr!XLzF+F zkUOrtj6N4Sl`^az|7PXHQ#4sVw4k;qYM|O7^xPS3@S`g zA+G=%Dnf+PI!d^}aZ~u*`f*}#6VktGRRgwQ^6{=6Jh1U{`o=4CR%4JFQWnx6t?t>% zWxpo``?yZ3MlI^i=7NHBRu{}gO$(fr1JzccPAX`24CgS0l#HXUc#3=Fg<>@$GLEHS zF%iMO$s)&RW*D29q2T)z0-vg6B*jV!z%5(t$e|)97z9yVT2aP0ib0iFsz!N3K&zUQ z&4^SG&|dTDta{va#g(jcWfC?-RUa#36UDGK*UXGeE(Q7@eHqcs|cSxyV!)Q1*QS!&KlDKiDs*S zRdL`N<@bjCPDB`lDiLJa7BW4|5W%akhE=Q4QT6Gmc-(*WRcvrj(vwsYwnVJ=6US*u zy;MbqF~L0nsUkBRY=AU$W@mRhD-{LO$G-lT_``!3e(fB9)K(z9r9(h!(oxmPBXRd< zG8O|VkM=vSXZvSA4%;_ExeOCU7|C<+2TzedbexGJ$FaOXCDNvgd5V!o-UukBOh!sG z3{OokUdmGw>+DyU@k$h^QWin%*jJMK+nD>(kkDO&!JXDd?pb#!oBb5os;_qI21ucD z%~p0dCyqpsFxJbykd{<7uOCXQnt)VV)h=F;He6b5zmm@Vcw#_(h-?hdqy}Od%vcdc zg$Gl89hsV7C|_WBdWPwmPr;NfeNDFZBSQgMmt1s0DM|I#`zj?VR3H5wDVkqhrcrtr z<7}-d6NBU!k&o+p$_48!``ml^)oip=q~#n-Rj3y0?1sRKu)5m8m0m}2sV$<&RF-71 zmQ+A`;F+iDAjPYm7Nm(q)mdfP5n`v)09)pYhLYX2_#LsNo$KkZ*>#YLJ1U8zfs{|~ z?i<+jxsSunO~S(0u1GC}qsN(iYd@o}?`LZ70Of%}%$W*Z=^Qe3{`knSBIzqtdNX2h zYMg>!Wu{spAJ&+Xtajv4u9d09<0z!_MmB1>!qr-l61>#F1Fi7D&&hg^gXyWK=Qfo z3wcttn#wq?Cc+Gzqr#Pswe?LoxV>3*(VxqYkyb4xJq zF-w|UA)P)*vZ-~#K}^T{u`&PJ}fErY1Q&GR|LEXdSQSbBgt};MhY>OWNJj7V_4HE97u5g9hKCqDae|SNVPcv8VH7r%LoyB0hP=b!@RRtny9lQiYz54ytBItusTkx|7w{?qcg5H^GWFwazWK zEe0tR2pKaB?e3~NX(o|;2haxa6TOpXjexuk~!h4SU=pM!w37t!aN^wk1BbNP*IHM8{j7EYl`M>@l_ zS79P!knhQ`}!Y z&KRVtui%!>b*!#X2dOOYk{NL{hXU#5FMbL(_d$CG<(|l9DsH=KAeZYZH_n04DHxrG z!y^=4-bXMv$@tL|c$0amqf@xm0NV>lVX9Gvs=d#YjaN3{xa6gd9T8d~u8=Njs05Xz zSX^3!Of0DaX&Oq`ZPFl>?5-s1WR%5n1nGOH>Dv%vryi0Rl?7b3pk%wM+VW?VS zN)kg=*?C=%#bHRfLrN-UEW8}5o!BsZY$3kO3{2n06`+PvW(X+^4s&eZeqR5@FFCw# zAO1{%XlfcN745?Lfts1=*d~GR)k`vA=o1989fY(;usSqZ5B%HRx3PmP{Q}aN8fM8? zB=ll;mcsfTQaA5r<0n518&^RlO=x8lc_Oi-OA1mMeiX&-u4H#R*EU&FVL`#94M*Cb z^P@MhT|g=xKwDN@(jLt3I&W}k>cnW2Y&f$ z4*&9HrjHLYIW!o%v9YfmX(o@vtyJp69Nn=ae`O){+Eos!2B~l5tS*;3M zOLy)(P~l4_EC#uRivCrBLJ{&+q65ds9~tD>z5`4iJ3*=%Vw9>x<*Fizq`Z(+Xef`z z4GmICK~Q8-i(_A0 zAf3zI)EyG4`%~@E5uTJ)EQ6tv$KK%~_D_y8VusAPHU&rGP74cL0aF%?Daz)ugG)cB zN;Cz8ZiFT7SUyi}e4O!j-r@M$Z}ZNpuQIiFKg^VIWAUvfJq86zbuI!_MbOu^84c1H z2=R}y(1pApApJjf-p=kI!@8P|NiEw^qzQ?W1*F;gZ)Tg63RZSOCIhyv-7YOiWzlMP zzX4LQq!N=xbXEnV(ul4>dNgMsAl(|fyJ1^aS8@_6iMmEg_My(9SNVXXbe0TFirH4; z0!oJ5s(83gJ4_W}d;+Em>MIA3v{$e8#_cUQ*3EHOw`LZz`O)ZN`=%*4e5(!|lN^ZXR+M=^d>c|>RT zCH;S(SmNO11ji?*7%mm@GHJ@TP1V-Pp~z60=n9zfWyh|p%G5>yY1^bWGtKa!LyR1J zho3(FIF(~ZVRST(H3PL+6VgH*j7oJN2C2ALazgJ4q&COfZ4J`jjX|1CtKmY+52V2? zODZ7k{>b~;EFj(5uRH*uQ6^kq#du0GeQ`J1ydag^Ef-pv#TDl`X*i9ibt~$X4l$^C zAoE~`#}qijVwtF1qcWW*ELHJKRlI7AVx>e`q&wHHX8ko+klwjPd0*NCVTl#&=buli z$P5WcFCH?3cDM9SETN6W7rHPl-6@I@BpoWij|L8Nw3uh6T%qLqIPL8UoPPWz99xm0 zly)&&N-6Rj6@Nyg{E*uCBzu4LD}Mdc7a2Zu5XY-h9UD=s8CSGfJ&7yDbJgdhNoui` zNR$|2v!N6ZRF3^@ENL@HKcy|H0;$eiFAqy9G3i`Oin642kZ$Q$F=+#&+H27ujU{W6 z?w7fiG_f!$P@L5oqe&L3K_FCpxN^LDIU{jiRJtIRcf}4yS87A0S_Hn zAG+AIv|}a~0n#H!2BLNAB*)nNSdO$neM1xOywp9V+e27%1G|yG9y}BgH8G=-@owA`w?e;{wP3~hiYq#-2f;9F+WmD7ct{cas z2}lFdfu;pc*-ao7+MQTZad(?sI%N@02hv2{LcMPcP95m0YoEmV%CI)iGi|DGC)!bs z%ioBw72u^Vs&`v814fzy~6s0#Z} zjIeKPjB(eYY{z-@L~>nI-?cKGlu>Mpv}mk)6?$Ehp@Rqb)$`Bu){DPj>Wu@CFGH=S zxVCmE>gNGM#*@XNdLESPk%71X6K#+XSSt*oAd; zp)6^9`gSBSX*36s&u2jbU+-bSX4?h%Mzpq4;_d$ZQQi1Kw8(lX-XvM6O7#%QJiZ!IEU@Gv8L8`hsgNW`-2FI^Z85?GD;2qxl`HTGO`4h#<38axN-8f6^?k)tHN1nJF+{ z_VAoEo@uM>sN!lWPG^7-Q~jJ!YLo#zjzf8TjG+Vj_|dn%!ST1=gy9jaR8~>SqMCYGf$AwEk>Dj+@HX4BCO(p;KInxdB_NSiIG zsbkV}4AR7kCb|ufs6@3f_;?vdW2iUwpN6j2mZo>x6~byLxPJ&p0MkWCq)2u-&Hf-kY^WTHOULkj?_B z3WDP1hhz~aiMzxdu1_3D(iEpq#7`KDOJ_yn5N=MLR6zQ@M<3;(2Os44@#D)2r1kW9 zoJo`WhrW(v{(pPL1Gle>l6zpH&Mv# zktm2wF#fAw@ZA)TaLMBy(FY{mgT7&nrkB9g}t?AnntMBNdaz zk}XTdI9gOpdj8$r#F8d}(y5BsWPn+~tv~kb5 zC9PpeKdWg{bZiFOY`X8gnN4Cz-{T;aI6H|o>!UZ+FPi=kySwKLqzdy(YD(vEcb79r z)%|GBaw$Tz&a_EAR0s>BVU5=YCpk1-;DmJQi?EdAD7v2%L}hS;@QH*GD(9h$XE_-=q*0{Apf2ew?>Q zD@++KW!Iu&2@zeAL>i>xCP_b`8~8Y-0xN8jgFk22%|vaGAxstd+8gzRlmh~3@Z`)*~O zh&cCkDusjhVhN@N(%IH)R!q9Qvb#;bu3~~1iUlI|(6KONpfthHq&+D}Q+6_x9X-}S zIG5rSE5f{J3>hJgsPXw8m1D>FhcEvL#RCVRP*DAaM%5$oByX(KeVX(jWzQyc-o#&u zHCV;%RcZh_bD`_Dv50jtCr$lMeKi!{XSFxPmRhz30cj5)I*tGClH0g6%F$mjNf$j_ z!@{=&q?XF=_TGCdYn3I{AQg#-CFky*=fqJnNR>uZ^WHWmCY|lK#59$rr874ux#->9 zjvJOfPj&k)IG&QQ-5lBS(3Aa0EBotzyuMEo$dlpi1Zk(&#J6qKs`K?I?b$MT~$yTPyW)K|4IQM7GQQ%^s6)k zm9$D0i!?SarsjVtK1?FLtp^K>ev;@Hd0v?=U^6K`d&$jg@>8s+Kvw8=SV|SY;7Uwt zvGQZLu_m#kZ7Ib?RvGB1t(TS@1r7Wecqa$;iZuYh6+_&JFBEl zspPX|72rooFpc#IeR(jD4#D*n3 z;m=0n=wh;@=NmdpclU$M(mVsNVlJR}U4!px-|M*XgKJ~2b1XoSLwOH$>i7qC7V-rY|8>6gd(kg?v#z6LJK9S=ZY`*nZ1k*AQL&RTi5^}Qk;l5JFwZ9 z?O{)MKilk1w%Z-_lcLMl`nyUWM>4k}?%dQosj|SyczG4pCJ8G2c_k~Y8TEeb?s;MEu=Rhs61=8gKQt5(u^brB+LmH%e_r4Wv-@bjG z@Ow#V7x4m>MQadLL;RG(kP-0aa-xo2^OX3Q#G7Jq#U)l!lJR~ZZf}FdBqaS|gLn%SPey_@lM-H;DSR`+|cu@*Z;?YQhR40r)T(3fV6mj&` z*ZB40Kjxk9{}8+8D_Il)sC2;uMnIt4V=acH7)G&jof=mdFA!x##jTatGt}b{v!a@;`W`lS@4=Zn@$GqDD)?u-(uql`!tZ$RtRDmfQ5 z2ugS0xI!gX+1&)BH?dtbj`}(YvT5nGQvIxF0@A%tKEZeY;!lZ2PAoW|w0SWuWp=j( zQhnt`h-?{yRFlG@$Y92RSEnZV_1F*tG8fcz2?U@r2Spg>$}bFXLXS+fLc3Svl_#I( z@xTB7;KVQ~v2L-(t$|QzAQ=+Ud{!&j=2K3t9LiouieVVOebw) zMf#?+0=<}68OJB!l-EnSR_WPcGl83+YWf&c7f%N>C#Iro= zA}r}!Z@&@kxMasNaCa5zRA^QWV8VoFj~?cg@eyWHDK!p4Wp$OS8xQA=d@_N@8rx>_ zt+)B_U-~i=`wtKnWgd&r{gU=t+Qkb4Cdx&^_B3Hpl07*naREnB!>Fb5}^pQjC%}C43!#X;TNy& zCc9B&F*6h@6&xu;DUe1=nsP*j2p>Fj+JQ|6pMQpL|H&W1_(%(+=Lcr4L+Opcv$(swIybe1@KS1(%xNZ)wlwdm4IFI_eum9h6yQh0N6hUX3+WWup2 z+FBOH4m8nDM&Aj0sDqG>T9vn+dWuKB{xyuLX&kRctz3%Nyav87hZ=6Kc6YV=+h~mv zhLB`*dm^}}dz%92ZljalLP&c}n#My)jvj0)z!ZQwl>pat6exs8Jd-k*Ov8qouA=Lz z9dO-l*suz6Hl!`p8W%_w*b|U~Ww}_Ug`u-pT9Zde4k8~aB^-G(v9xZi*A$m;+cZHrMdhsGa`ugjyM!RlTJ~#9L0`x z154$76cw;qqC*rFMuz$3SN@!_mwu^uyD~H>5RR@Ye`sscAh~ORianOhumT*Kppf$Q z*oUoT`0edCa;4G5nvzLZB~rp{XQ&aQ4X+4^8{0(D4U7FfsD`uudgMmCO$q3fp^)nFMBI$EJZ=Z>|A zumwv@}zy39X*WZAwt2nhXNy+#X%w4oK_vGUnK>kRw0u8SrhmH9REgLH~wT1FpUSW7zXm>kKX z)dIgDLxk7NBaVGC!M;_3(J(xz1oP^vFGss~?_M?_6(zu5&E$Fh@F9+e9_4g8&g@#G zd{ZTXJgTh7rm+Tx`SxG_6^9>v6lxU}+sTN4P(+$#1mQd&m8GtdxTdI<>y_UnQ_gB| zWxA6Ot=Y*fnRWE#p{*7v4z3Ih7EFm16{U0ehi&0I7Wu4=vAv(Qw_k_xf$L$*YCQ^D zSVk(t+*Fp4K31iUu47qc6%{_4`m9W-n!1kbD(#qv(ABCG@`==|RC9Z5NexM|!3zUN zd3j=zQaY`a{V$}uDU}-jkNTRPEKkvd;OxEY)MsYnh@R%q3=O& z1nmL5-(AHgwqMK6N}AphxN4x2CO;%44@Ej4VmkB**L0KFv4Q>%+z7W_2isOdc?#On zir^>_v}PS>8z=xzdRUcE+B}w2ULqsq6<0X!Ne^Q&Y_0FG{6RXCvN)PSgH)JO+t;=% z=_!G_2#~(~%1hA|mtV1@mb6a6YogI6%77z5#IuJFvbUJ$L>N%ZWEDt--P(tMuvO)F6I60>sVVb z$yIfns7VOgYH6Svgs#nim&dvG60ZE6kHfb0uznS!q>LkUCDHwjGr#pK8&_sy!h?pJ ze$3W&N+^nr;X~qTC*wMmEtQ(lX)LMq+NxS|JfF0)QeohQXZiLY{U?|jQx;w}yZU3! zeA4<1o8%mu6!#>Y$f_|DX+GO`xf&w8svOMfC(WmAj-;anK&rijc;C^<>=rF>es_1N zLE7ZlHAJZ6#V_97NEoTC?%VkphN4h`)Keg}NPEKT^f8PoRx!^D|M(4Fd*pj?Vn`*7 zv@;p1nx_V-zUwEe{GrCR%hc{R#mhChA-jhAR$RiBRyVzc2uFFU(o`;`m3U5wlsqhh zDJvv%#a33_eFJTG+^A=?ID&ksj@TGt`Ri8lnf}GEU~EFUr2;&a5Hf^IdwP&sF-V1*+Yfwn z)n(k%yOm9~6geR-$Rxekbr!{Rse_7Dok|-N*LJb#o?FP>eG_b1qvv0UOX>7?LD~#fwGBz)NR57!OmGsD9^>W7aY`vYX5&IyQUU4VbVS>oH|WNI7D!JM zl`cbfcOgqU97a4P1C(Z_851Rgbe6zyutHO*7Ni0nml{KR-{c>^^d}$#mI_7eKvE@o z_<#m!!=aqdk_t%OFr+hr-Q>7u{Vs0F_OsDXV;5^`PKba>Tv4f^iV{T8f#EiT{(Enx z_x5XG&kk)xMfJfEITziAmKFh()5r&$DM%A5t8Hx3MRQ?6x_yqj+fkK@d%3Sr~B(4uG7Chd;k{ppo_`jTt8teU2;YGGC+X45X1 zfHW1FOxG$*WDGJlT*~^-e*~`HrpG?mI#?CUUA46?Q%V>??_rSUnqtyhJJzzQ5}-gT z8b`93wLp5>eD3T&UL=-OK$=YI-d8B_{R8_rYD5%WY4VnAjE(CXw0Qwp-@~68rx~G>10vUxsVPQVFpQ~xR5SR-H-e3EvaTC&vti@ z^YY|q?Cy%Z%=t?k2}qSCUEN3=btFP$Es&l8K;@|y2}nh6PtP_n**i1Cx8Hu9v2>bp zDx)T)8IhwTM%rpZsQ0Li4)XV3{xTDhve+QdppwF|g$^v*O+X8lzbYwFeRPe9b#OD9?({SfC1UZp!(KSz3(vo6L zrH(57q(bF8&4kN$2hv#CLDfQ=W6~I;GCj@^kjlwRMm*qLXLnm5JwqIx_UR{sRFoOM z``z!VrthJ_L5!tN9BE>^b|ZD^!Jrlf+LBr}d#9)Q&i*$T&t#}L8GJ*MMmBB`k@I{- zsGr=ok8gbSt4!?M2jio-qT+{75Q9_?nLRy7l>#6ks{;7#6+5}7cMF^IuqJddD>ZeF zMaNV?ltfLbw+;K|-Sq#5&%?$pY8ib5OL)AJPHu1~gp_+)kj|B)oNaSwXLp{Ji@8=zx_B7R57LJpeprn@93CFJ zFd&s?ZLOfGV>oF&tAr6%!{F`dDZcm4+e`{b%`}1GVuU7c7?JgBbku4L{N!gm{I`Ec z>G*M?nF$e8QM1>yFqu{xRO9aEvu3d+l{%rotS^M$UAddPyEd{V551uSm8zRt?`<*Xlb6z{c1q&~{2Ksp$~3x|&K z%ESo8behmkoi~t*=F==oI!{bmXo2($?*9BjWdHK*Z!3_Fj*eUikP2l^Q)#43p<^qP za->1}*3=Z=k3m{9G8&|ji5rAuf~o@P{wJQ{(f{&asSFPh6=!hc0f{w9!zz&KnJ^21 zRASP;NQ3mA?#*nSiRhAcxN1eoEC@)a(k3(QY3wVvvEkDnB7MjER3;ZIChsSiux8_} zx^B+)adMqhU#wGu^h7BAq(^vVQiC*d(lJO4mCWg^lo@#8xpP8h5Rf)o(&ofbDoGsW zTn?o|a(CXqwpMm`frT)?r02K)`JdJ3!}0O)#t3UN2xO}??sj`+yGirPv66(;h0BM{!3IaOI2}u9*yJj2-NZXN~ zTVWhs!7UwYSXuT}cDEU%2c-ma*9~m@`~z^w258S}c4Yj}A{i~l(R_&`p~QXro8MF* zot&Iljv$@pher-DYT62t-k8B~&ufFwNp8W6s1k+QPl@gA0m>RwsIiZL? zNi+7mF0bb9>d}ay(lGjT|K;4(vx%K~lRjxVDHRp|N{-2R#$sws7nlC)k7D0;HLPC= zxm*)So2!_yZ@R=FJs!aG?+ozT^qA@z!p+9nU4yg&sn7z&k_t%2Rd>$W(gNoL>58Jq ztn6+s#i4XaZXS>(4o3^5$#ylrCH>YnzNvI~CnuH(NULE;4N20NNS*YtL;D%RMBH5g zsnASQMnr}x?(`Ht`^SIgr{DS)j6#8^Tu_!Y#8(P~iE(SVyK}8+1ElFNQd&m0r2F~Q zwyU|Kk zclU4&p53>P{k0-_$BErtv7~cB`iDxHK@=3<4M;mN8kV$k4ZVfhEK6EyOL1@>kR~(i zl=yhdlE!y-{+RTizwr&FySqF=nlJMBz&l8sr9f(EOX?aSS)+zMInJ~H?H~B{!;dPy zF0s3NYLK2B5(o!ghz!zECPR~M$n^1vEmv}NCCdh>lNL&<_A2Cr;haU`%1vDM`A@(t zR}tl0jFe1(IYrE?gYB~oNM|*G&pJp`caLh!F@#@*8fbN(81USIy&S=3#<2-Z$?obM zOP65E3_Sll-~J;3={SV7a|Y5|JJ--XBe{aa-Gy>{W;RH-uZNCYy(hLl#k=M1&RZvy z63jn;Q!ME+2I&(=4sp~AshW~FaxnamlnFV@BN`pyhhO_U_I>X$rA}|wD)YFzNyfE_ zwl3mhl8ucO>c!m^;cMaUUg@sj{;gMWZ6(9Tib=LyQ(ZCwQc;i(-oKk|pS=%m*oBw2 zaGYk4#-qra5p~`{s^_>V3Z4OPO_lk{p?5eT`btt?mgaz1^T{o~@Vp0WC$uDTB(-ugZ7t8!5m%jDj9Tp!bXZH+oqaoW_@4}n|}LVxPBLY z%F;uKo3qEs{LH#*dVVaa?#t2bsnXLPnl>Ug^XhnkpB_HMaLS_Sy3_)pDe5v%+V|1A zyHE3-FaHUQORHM5B~AKW8w=-jt!l#m>cL%`^3wZDUJ}yVKcqsy)Fh>-Yp341-#zU+=UDjHvgKHpvC%GSTNGB-K?n{)W(v6-+wkahzsLH! z?^7UkQj*5$2Wg=JttvC(pLG0={V!!AcqtmPJ66UZm6FvpHkJV8XCI9NKJh+a;%J~UE^%eP=e{JVZX!Im5$uiYHP|!m z-Qy@Yx@?ZyRo#8_L0T}`H1kG*)P?QXXfeaMcl8>qOk~jHhS<~)5yxa(UBE~pvwaH| z{r<05bJx8w}0V4P`*g75zne5z-#F|ijT*66%#SjF2U#=JDia_Y+!qt z31{8`nELVaf#VL9I!X?kK=nfV6Zi3;x8mMDkNqK%lq|$V&OzD zoL4moGpuq%Sqs>qHp9A6209I3bE$#ychASPPrV-)I|8UG>la9QWtA5^xGley4es!_ zN7@ zl*Z8-iy>i{a9GMg-aIS(XE4mR@zPy)GN3Kq*eEnS?XT#-ToK zpxki~awyrAB+W#^0@8|i&&Nc9bY!)tyXl%rq--N<}@6s~Lw0b_it|M+$zmMNQZTj>klLcTbvwY-Q9V&=+9&=7E%n z=O$X5EOKT9J8cIm8yfM%aMqdAY-x0KUv9CKeH&wWrSe=>b>{jk>C8*11VcZ z>H35Hut|Lm>spwYg9@BAVj512k49}<8kMYs=%|kCtYndmMy1A4)p^HZ+$Y};3@h&) zq+Tggsi@(ZA^Wo=WwpRt$vFDK53x^yRIU3qIuOFkjcs^oMup-EY z=?%9a2?jzc&LU=KP}0(hCvUz5FaPs4puG*Cx+~TA`)QNvoFc=(2!|kz;Y0O@<6V&& zls6|)5wfHz22~7tcatGYY|;Zh_kNU|cM4EjrWi+F%SLUJ`fV{1#3Y$$2&7Us`nFqd z#See^thNcrD?g114T?PvONaJFq5^LMB=wT->yqMgr}KCp+={b$`XO+wXzN zBG{=;xVc2WB7K3(;PDN7>@y9kd}R|4%n{Q-dB(*I#BuDf@i?ZY9`%_phNtPSvXH2& z!uSuI37mT*FkzVFkQM_e|0-+49#MBSH%DJdIrCDcfz5VSdgZ*)(1_(*cOVf_$q39C zV)+(jL>545?c9lnZu$e(J@7C>$s}^A4j57^$}>27bsQB|J3iJZ$HJ+hQ8;((4ADMH zTazfWELg5Bv1Nj^!!)q9B7_-V{2;7%p8yQ25L=$U2T7#Y&LjVIS%}QnQDA?Tq`6E6 zx88aye*EJf?|UHSbm)YEO%CwfhHZGgr45}djBSOHb~8vC9VkyGu=FlL6TQJ+v{Tbj!v7<2wf zi2V1lFlJ56TXT9MQQg(^U2z-+@7?tZq$p&{&1z4(`pJ;XCIBm1Tk*=~t=OKq~ z5mTHPVr@y3va6h{`tz`*BfYyVb>*1y#SZ}|9S+phNUID2lt9gc)YoX4eX$Cp@pYdNJJmE%>KZ6Z+o)qvvYG>N zeC8axD77<4tXYdcFSs1;>no)D zIrRgAlznGJn&!dc!P4tGrxrUV(W@#k3|&q5zeV&@wTIyN^0BCAHK+C@N-PCZs;_Cw zKwHE>TYU`<_`(N)W9F(lP$30UuZV@JE8GJ}cPG*Bo#5T=rtZEKAPuYtd8VpViHCtE z#`Ri~cy|3}Y-sO*RauF&X(MAK5zD2p`N?PS$hE%)8k&G)3dj+p4AB&9QooYu7YO;3 zFTJmqU&;x{wuht%&O#YZte%WhYo}mbv4h?8BI3fgE6i{x*0f%Xt&Y@XY&73*8u(CHdTha*TBv{lJKQq!BH z0xOq>mFz@)ycCcB{qIv*LJ@CRmavZ(wJch4mFCPPy#c02^0Tm5T|$_p5=*^U`VO z&xBz`#-NfPoGX3(`<(#Nu8yM?7>gG_=^lCHk#DLb?QNi$Q`!PxL(0X=TO08D&Rs~d ziExPS{S+d(G@4#pj=Qe87Fe@c_3@-6b$bD+FU}{j!KX_V$lmI%N~I1jD+pHMwCZV? zS2qb^*Fv*lW9qplVmL!FqsxI3b|hD2T8w<-CGW|4u}Q`DE~?A17%2;OyD-_`P}f*7 zEu_K*S}kB(4p`sOftS{ALI*6Vugk9CY0E^G($?#9YS}hQ92?O@C!%d_`1fyqgN@HW z541K(u56gawsTnlqtZ0GDw!IjbOz~LB}hqPI3hX{pBOm{)16WYQ?X(OsS}C~Wk_ea zZ50+;#@FE3AAA{@K2iFrN@|~1z=HQ#45WSl_XWnDzJDixRC9Of-EC%9hJ6jBS;IgF zfL&~V*qFi#8#bcJQ1ym#p)_KQ@ojIwpD(=vsiiA{W>RkDNRSh!YtI{@KIARbL?cawRd9Vfm3kk=RXF_84pxOC9Wg&eGN;OlTvZoUJR<9 zLCWwLt3^)-eRJza6Z6+iugtNc|BZ`wpOu+?JQ&Hb(Ai^9{ zuf7JKi{NXG8rWQBpyY@dIQVOy0>;+?v8V#6Dw?6Xqf?Sf5elzylP6^d%hbwiH3buT zusDCykL#Vx&J)+MBOZE(iz5om{d0w z(P$L2&pZ)zO#U8KrO;@4)sonL!gGo!$QIvv2dR>1l&CqwM4E-h02z-pi45M@x)mE5 zTab&!kufaUhrr~d=f^gciW*8Kr3qDX^JYAC*Iiip$iqNevxHudO$#s>2GN}+x~RJ{ zc*+UH=is7MSrSGhnH3Vl+2anz3DME0>u{ww9NAl>GV<9orXj_{H}VLzBQ0*xHLLCWa5B`S&(huaPgFyBnw2_dxoeg^#<(%s*zI0jW|SRgcm)5~{$~ zde-1IvdBepC^2%V=tyGG&Huu4H{Ss?>=fgMa>ueMdsL64eA%HQE2}?(;+M2~67eK4 z7^rr_7-7axAFaaV+EJKZKLO(oISB9i_ywq#H$&-cIn~yJUQH#*)WjC2h`0HRa~A_C z?O7^|LY((10MdcRz)~w6MJ>(Pu&WV`ok?lAk#cE&vP!)wDXP>&1r#!Wtj-RM2!-&< zLl0rm9k-)(?P?&|A!dQpGqedpwR8nlUMUbKHmQ>8lH_dyWe#w3s1|3|AB;JuLTysT zmlZ)?MAO}o%&WRaq} z3ma9PDXe(p2|W6Tn~~bEQ9=!-oAp5IN`{E6%HE`)!1J%H#gbP1-!n`=>R>5MR3MBp z*TgV0j>)6Opnl3kob|bnn`CyP}(8?dFl9lJUba7~7znDY~Y!}?GR_2eTpggL8CqCyIAN`bAkOB2AN4I8l&8MM2dh#4+wl3BFBz8ZJ^>IQ6k{dKt6gh&aC&LhX^ znndCObs!++V2ERb)$3s*W<`**(0ON zrjEDtsLn6~e?*)tDx54{y#IbY^7}smT*Sn-%)+s3mBFK{DY90um%^t>_2NkLyt}+@ zK1&?HyGp8YZrwpRJU$9l%^8$uS^xC0wA9cVGqFzhTU zlR3ni+i~-iKgar)UV@Ws1#)Sry=#y|ng@u-*$pf~lv@6+tKnWKt1VK6_GxuBTAEvs zhKtH*6!EfhoO#w+_`-!3V&=TL61yZo8LHs^oRaxW4o-SMNIfCuBjt&T%cA*-R2J<{ z4lA2>U|TkcO`RRsnMorZ4guj9!d46hD^;)>q8AjFgaLAxsh+wj>!oAWDm-?}Kd|Qh z2PAEdiSdk^<}B6JSi(hlADilg?guH=T}woy3cHMhiDRn9;k4?BI5=E`csn`4x@;<7 zI}Vbrjchz3y>e>Lo{zETo+LeBvJn&EIJ0*1Z3RR%7D}cUTlK#SWtZ-rMY(%N2PVs# z@Xw&*h;hzun2|8z zDFZ(j8biwc26qn_GI2l?gb=7Di!1YYN=tG2I}g^;@Fc< z!nq&#Z;YQl9c9CY!3aeVvBGe&HX^2l2#X3*P%xt6b!lV1IR8dq(&kLLz^>LLcDA&j zp|u$aIOs5KBq^Eb-POKpmt+9uiiY5tB+)B%lx1MZ_%X6+Ni@i8-ipP4_#4(d^)wRA zjR-R#K9h#Y3>6(qChtQAp}Wsp2UDcPjO${!4IGX#oHKd`j;b7k>JA&R3`0d6r9xBW z=41k>DMRDvGEDsZ1t>dqHc(v-gu_52sq(s9P>&UWFgr{2Sa+Zvql~ zxkM18qy_%#pZ~&-$lYyiRg!d{11V=PS5ym9n0mwi^=o;4%Qn2;-iS`=hGrttnZov$ zUd3O2_ETWzHXxglObjJSZKd)SF>Lfp3=T}!UA6kCMm9(*q=Uzbg)qE+Easnb3g*tA zkEt_eB3@CASiBqvMPP-(h=d{tk&WYBR2(cW(3x@3mQ0{Ekw9xQfsRZDNjry>Yr|%D zHq%DdVCxNbP}77U>0See>NUd|(&~{ORvV?ZgSg>h%bJyV=FYpY@u7uqb~eH=sruWn zvuPPmTd0C66)Hatd2?AwI)kJG5*Zu^Wrm4~b{MCXjK)c|6L3(Z67kNQ*rLo3l0J5Z ziFj!o+uB-?tcap>+6Wx{-H*eVQ4f@s0#Ttlcpqi76QKN0x~v9S9eGLmc7)sDz#g27 z*;HC2sc?4*(#IZqq?=9pmP%3yxOuC*2_!5Pj(M%U6EAPyip}k9QV7gUXJGAW!fn6# zEjB#)AAotK>|kx%$hk}*SKdpR2f-xfBDKN>3R3dqLZu}bUSE$nN6*KhM;wj%NmG#t zN0BOt!3jqZ3P)jC5y_gN|5;*$j)PP-izI=WO(UJl3h0b*2yV!dFbZ2Y@(EPC46h}J zr!LYmj7xqS$vNGDU01w)Xwx3%qSAobKtnVSk^bl0=m09z@% zx^+8V-MSea(XeYCHzSIHwC6QXDSZBQJa4c0 z{>byY;V`VyQW&Li9DB;?IP&&t^wIm^na0c6vdh!BpB)#LQhQ!zdpLQU2{IjwD%fLHB7_{q4g zFpb(rSKy!zo{jK%#{e}YKqL%EITzKL+*@+;J!;o&2&DTuNL3g?GFoIFiSH5_+eOl}(3o+sytNrm?c9ns7TKbN+O-3Z{Ozw; z{nXP)Z`_JdMoWpp+t+Gie=G(iEQ>fayfjhmRAP*h)%sW|fzlEoa_3?wnJ@{5oP09I zOg{hA%7 zg{|vWW5x5&;f-gXLt@=}#bHjQrNf*YEz+(KD^{Mcz=tNHdMDq4-_5K{V) z0%)Gd;D0egAl|jjvsn8GY;HH6bTbp-I2zV4Gmb|)-2Tp*dONgr=P?l zx7>o(XO@Wf(_#pLQbbb(z2El~NQF|zsb+?RKkHZwk&vHi0Sq^=g2Bugm^t@Q%$R#9 zDo58L7q(!BO>~+r+QSBH%Y^Be;w9xrIS-W0W(%>M&Kr^mEJR4SPo$7;ZAG@T9WN|i zh%IYZV%zeiKvSdY0%sVA89b+p92+NzB=zeJK7e{6Eblz>sqxfChW}qH#ZxLKW?{0~aVDdx7nYSP z@l_T_s639*lO|%u+_|WqG8q%5O_5qZ?9|3$VosJo)F355H6?+B17#mZY@m75Hf&$B z9;;qmimmI`prfe)nXMavY!b1`3Z!;6$f72$84Y%CAt{7eJdo<(uSdZX_^{WGPzr$x z7nqJX&aa=1Q%lBRL`w!0G?!`Dnu>bJ1%`Gg9Y>w4^*f>rHOI|G%_q+VYD<9XI2g*)H$~z=UyGzoC9)7?*>BN)v0g!4K33=4Zj__g@(o#XK+>9S?%>b|O zY{v42jo6iJLA)%2WzRo{JAeO2IIGqH?HPnAeRK+ymZUyzXirkLH;{V%;=FoDX-a8f zSRrI{OqCM@&-+Q@YY3rO47o%SWh3e^W9BT>&zO#~spEmNQk0dJAr^_jV(inK(44O< zh}_)Ri0vCUqix47Y<*)5+PCjSmONz%r!Yn(z0sxl5*$TR2(CnaTT|P)L~-7dAgT#a zR%CR58pFUCH-z&>9fBiDM`2<*B(^BqaqtG+kPBPlNd_{mBLBBm#bD2yf+-(73plVI z7&A4Oj5@1A_p$@>UMeLxkv&?|23Rc)uN zppBEVfXxYDY2y~W(Xbf_Cyn-&COmQX-FW?;2Y?-|u+o%qN_uD#xpvtGeH8(ds7IT$ zpdM-{7l=Flay{Z&G7Xs0!;}>?ZCK$LLZK*1YO4_*H4JV^4ADpo;cx_|NiMFI{46rx zh)gntOlLyWTy!LWR0haqMKDs$Cpkgxv4^g)<#;rI=XQRr#yUhKpSz;u!v4Ct}q5PE*a5 z%S)7s>s?wB;(Z{^k6|!lMZc6GkiH#2+Ep@;C+{gP+XSwCQ0=Xc}EM`bzUx}-#OJKsob<+S|K=O z=n!OdFi8S5%c78yj}R8zA`L& zZ1te$xQ~ph!C4HXd3BR?K7!Tzh(YH;Y!sBp8+RB;d!9F zQkn!sw?!m>zux{{mX0`YJWg?0ju|c%=0u0%xatX*9UqCBv?&C7dUNS4lK3v$wtDMH zBxwUR67Ej%IH(q~okyIfN#tTUfKA?7$)m;aupvd;D z6q7pV-~6g-aE({apnR+&Ptp)KPhS622B|L2MenpMCgL+w3?#M6_&ACpu9R+}09v?T zE$Isq-y1tG_DY9T*ijiSW6cO=Myheb$SIgtG6I#YS(MwBIIQTr6P8qnq!QL3R^b;r zlS87q6rrPMUY!h%oH<(&a{xrg;Zt#XaIJTroMq10%_M-lT0RX+rMtZC7R5z zuS?PbNLi{xg=bhIgp)sIT2iOCA(h4U)(&jgx&u45ZNW2-Jb))3c@WL3RtX!(rEQlh zNYk#$U@_H6FABxgs)2x1RCT#vP{H%5be^=){ApD0e+aNY^MsfwHI;i~z{I7KeEUkBCffpFBv5Q0lxJGd%{AfHg0s z3LVaw^gRY94vy4fUe##4tE>)V>@bGeA;dBTas>e@^hY7xt3`!1j2i3W7;(~J7)vS2 z-lMdOLnhK;#ViWBI;p^;R}QJWy@K`~22%DLDS%WJ`3NIrTS(g`I#LdHwKQV&#$|Z< zrRQ<$KmLjJFTbLQ21$B5Sf9ie+mM?C)4Od&Vi~;+agnf2x6}Iek)(FdwpORrJYg?1 z;)!`#Cc5Z~-dT0VcwXHt*n3)5n_7*|tK}*!Ojf@+`Nxfn=qr6j%hVsx~&!MOkad)-q{J$0X!q*4UvKbjbXsD9Yo+@I6|0? zN}Moy3XZNAgNZ0XtR;yE3zwP78y=N>QFU>GGaU_~HRPhRGz??*1k`=(bd=6L0A?ji zqcBeFv5P$WTkKKo+!_=__8)-yheyvDI*#6^Anp3LwWKMyloUw$Y0Gw^VdqXPS+WH8 z+MLF_B^wKBo%~CqG1T*fKV-tsvV2Dv_XwBRJ3PMLS_P7 zWEclETtsNUdv$*^Ap>o(5LTyJ5Ib-@roI0(l%97CvLnkBQNcA~>XN1&QQs>SJ}7wZ zuLt=Tb-&|CBMOD;J@Ld7NbPDw zX=N1>Ep4htsc&R-NtL`c>MiDZB7}E&4Jf~~^+y8t2uOo7)dQ&(viW<^@lF-*@SIah zJ)k6vIR;9ZdIlS#QHlfOqi{&gC>$86!Z;&_@|2Bu#zjd^5l3{KiWxd0g<+sGVq!Q6ZmV=g!aIA|=gF|`EHOHK7!Re4lgqWx12?%whe1nI5+{1<+5$xoEJd-pwe zx@Vqo=GzXWd0_g>Kzb@;iqtvUP>zGf#zs8$_~W?cmYea+Q%@t8N+Xv{=Uc)D>m3!d zNd1zozaZ_R#tc-F2HtnxTkElO^a3H8gI0&7B%-=|ER$};3voZSQqkto3N?J}f zq(RA{Rz=ae(hzrV((Z3Z2SNI;fBX}d{^U}$vtiR+cirKhb=FyLOOX13%HK7iKozr6 ztQT&bi3A>h>~Z}5rkim8op&P=iR1(BI^R+=Wb{A;?M&u==D!Q7r$JB^QFr~j^r`L^ z0jXAPb>K$DQAu(K9ELtj16Cv?xu;G?3e^Bc!NL?&;ppL0F}b7)Ih?C=(YA1vR?bR9r=wJcr zpTnZe7zS>-;YM73*#fk&IQAWP{M$X}oO6O}cNgyG?p*xMI#x-}?h~96vZJFDRh5-! zX>G+5RDEy08P6Y*Fv%^!wDMs%uzD2Y%w%Ew(^V;a z%xWPkh@Nt)%an?&qM8#G7f6LIbPg*;?C66r>FncS95h)0RQhNb5)*YT#miOO5I}c# zo(CoA4cFg*D;He;&H|~dMm?yZ4$G7<3=s-Ry`SaFmf?>#+=R#Pdk{?x4QOMJQ_tl= zsX{V2TSvGagC-v!q20#3N*`@6FSUKsHE-woil9knKwp^>?P$q!lcgu9T2uYxhOVly zSFM4?x1|LH+Xk!Os}VtMs2pR>5}Z725+)jP)F6y1BZN|VU`1Vbg&xUpjIIVjshFl6 z8gh|}80d%?=!}O^f5PDycJ|T0%t>%+%8)ipM02L9v&7009${j4C+E=dg%Qv|<@~wv z`WtY?g3HlPNqWmIe|O*azW2TDC26sjt-~c!=h@?-N>6UXz{^iRiwFOG7nVHvG&ZkT zg^spnk)gH~LWA9jPRo@dXf{dZ;$2mh60Dqy5OY;kj3eJ-KA)Q9OTO;HMOqOU zl(hA#==0>ZEs5sr#li9|EOC-!9MsJs8MBb7t3cKKSr~r8JYd!&xFaj1_Az_bNtFng zLRKhF1Q~+do)`fx%mk@O(x&|gq#QiyCQ6CMJkO34Hm+EW=O29nuPuBUt6y1$bVsKo zH7{@4h&JTV0SB2d>-Z=V1>=yGO^_-|p61pn`kWU9Q5Wi(b>lJk@+yrdg+#HX#P-tC z2+{&UL6;iwJhq;S%PO|CJBQQmv??&lD#47}(HI*oM_nY2+Khp^q=^!nLZbeY(hA;{-jEz>HzOn{mODZtFqzV-|1996xNzz6|MwMQXtQDrM zvV#omP_LK+FG#|CN7z71iHVl#D6Gk&F!8v*tUEXq8S@IckROZ<_2u&*oh`&(1r{; zkwp@=bivTo2mBx!jnJ;5cqNEO<*Xw#%-b-yss6f@8e zH!<~`6Hq?q07Pa_0ftuqG<-^H>O&wfy64#dV5J>klGz;e=NN>3AdQo@xUr9;_ zkjIx5w6!IqfLYth4OqK)2^wBl1~ZXCBAZ61ox!?>E$DDE*xuHJ?WtC5MJJM~cnN!z zi87cKUNOsDvT>7}FTxcpv=CzX5mObtmhNQ)si(^FCqb!f%^0deF;o~KOsF0%fE-a) zflAxLuv`dbSwn17*2yiknV_v|6?y5_5(A}8P2nkRF=S@7Rd9!uArVnU-*|tl+Mrq_diHlnJ)h?0zB6^Ly$8O5ocV_9uJdft7UekFU({VC z6uhhq52R8>G?N87(?EL?XzIkK2Nt1y^=9nYxEY!DPPmMrlAvG$&2|#Y8@Hg%$)F>Z zL@JlT&bCG*kwK1?6r?-1E#TEQXyG>n$gngpG!cOz(vqrdsS!qbv=nhGjEYbM72z0$ zm6W3s1QP?EQ<8V zN>t67in=3a!#sF0Fnv4_w~(}4xpykHQCM9;>V;`o<48EdeWafaWI_(@+jRu!qqzRM z>u~kuSD>wFKLV+C(&WpWNb3e&pjjE2Ica5|19r5bbLm<%yu1QiUVIJau69@*DPi*@ zQ%RK6R-hxBMlzj3GMhn1x>Eql-_wSJt!+(W$K?y36jUR{uY@YAtwJ#LHtF)6v|$+^&DXwWsS}2d7&mnkSlLgf zEo{ITJsjbw;}AdO0F)m*1(-1fsEPw6Y=F#CEvo8Z$h6csbww81;@UQ)B-QeI2&j8y zeIdK;#v5)Bkam!9w7*DFKS-5Cb)@Q@#3ZSv3iF1O6EJA6?&<)xw*f0RVf7=6(e%bT zBpMn~5ss=h^b*%ppp!yfxt#pokxQe~biC4+UO_IYSg6v#xOb|fQ<@@G#!3aKW+p2n z1A2~i0!+T{u470sFn%vp`#i^2A%x=*3_M~1i3#bDA#q-IJ|lxDTTzN+WeKY19E4#< z&r_0f%y6KhR2p))5ycu(S+<_R9RMh^V|0UGKLaW_ONUh8-N&u%*b;)d=8CJ(-rNG? zh8wPPKmF-X?-$2jZl|UVInrYwX*3OCEVFl#vmbHH87^LhaO#eqm9ZqIt>@$5!D!X*ld(f zn+O~*Nx~|qECouUKscgez=fva1(5n@gw6=kAtT>+#XuRXG_m{BcKlfC?mC$NS`y=22JWCp{W&UZbf?iHf&wA1c`N9(6Vte zqRA{G?I{V3kQ>YTKDm4|CRM3Wq^=Y~D*#l$>Rni~>++>o^4=zotLvx)bwQ{!U{V3T zIzhz_At?@KvF?y5{bktOG{N#FQ5#iL$D@AcbkrU+6__wus{6@@l@!7u>2oR-9Q5nv z>GP{Z@9$kQZ+h6Jz?$0s=FaXsv41?-u96_V=BlgF*)jyuuH!1{T8h~ts;o?4dP*1& zWwrR60&B{Jy<#19u3Ur8bz9J}Y9ri+7GxWm5l!YWqO?NPQ*o|11UySK6>MNtXsoal zYU*EJSOzOO2zr%T%@QVA))QhU^pGkHmX3uHsw_vWwhGx{Wf*tbk#I*=Av9(rP*x(< z^2Mdhu5Qx9MTt%_j=F3^Al)6D?bfk=klJ<*zrXP&0coPGy{jZGa9{UNNvfDX{#IlZ zT&zr}yHf*hI*S;?Hi@i~vg@}XwPqt))^0-6y3MfKQfOPZS)4s|@(4r8 zHlcCzHY9d7p=I+nX~}4%ZA7!K#5hA)rpMVr`1j|slKjpZLv%v18hkDmLW&YF9z&?2 z6m~@koM9Cx8#4lo)WJgf?+j05!}fp`=sk4v9ZiIqqzS2jwb1IgnO%RMq&!IXQ-!@s z4!V=Cm*OUewzLD8T%m%Y%4744RIe*rCjqcpI6dIjlkfA?$mv;Xtiz!~>HN$MW} zot2{GP=WkjDB`EGVpM%0kAzNYppz3@vy2&@D!oOVO*vQPa)#J!SZe+<$BkZNI-_j0 zU*0bDBsD`LY-dl9GHXT(glh@Ub1CUam03HXBn?ln=%*j44sXgOrnau7!gOt-{!c1h zo~EZGhC(p?AImQD&ihA(l9Z04Ydo9uH^2Rr`?=44ZV05l5eOD5?kSmEPgcz_5TWH| zuc&OBJoljM_~tvPDVm}JmJg`@*i60^pue=If`P8|sY`r{4ejNm7A~mRLWQk+WHVTE zX>e1_dkk3xdJ53&&Y9o2#|DRs>aMm)JKEb}{QB3wbpQ8%|91$ay@1rO{uY}mnyatB z3l=Ttt?(FaQiV~rChQ6z-7Z3(H(0JDA79lt_jR5th|R7tv{*~I0s4*lM2jw9-sg@( zJ1EU2u%>C7^cs413DRHv>KE?kKmYk5koGcRdXl925Z#us0Mf2t>#I7T25RB>K>X7C zB6yyBeAORU)oQlCRD{1&cagr2Lm+)?SBu_2Dw6bc(+zY>W;Sfl7V4611s1Mfwah|4uQ1$p!8=<_NPT_ zcfi=wvE9fswvFqryIw%r%C2g(N#Bl=)E~C!E9BANfelVbeT_YJ{{G&_zO-L|yw5`* z-Mu$f45T;Qa04#C{BpFjGQ&03T;+c4YhUZPx~m->d@*_w_Y`E`y<0DSw6u%xnkVT! z_7sTr6_6HVAMK5??9VxaW6fjs)Oh#j`uoE^-B^^4i|enyPC(j5NqY6wSGr&S`qu{p zQoS=@U?!6hM*^u#+@jH_^#AN>Be471ovhe7n8L;DvGA7^|1!<|CpdxlJ@?lOOHcR2 zXW+i2rKMu1S5{W$j|qB_dF}qFfV(rfcz%v&Nl8f;x?nb&h2;_Jg9Hfw_4#1Aie6U zE8K5<;~N74sRo)phy%pI;1&*t`<%qPGs*cvczsSBP9%L@{cnD!fy?{RFNxpx1TZbR z_&ov3<9Qxli=VQxGI=&mVD78WHJBID*D+cv(F+johk)f66STY^j&WaGF$Z5?$LR0* z?0V8C5(&BP-Y_rvdq4fz&#%pKyeKTV`G4n_baZs&-)Dc$`)2IZCrGcja)JA;Z+>e) zAZ0^du2uvjAWkN3T(SCE$@}`gw}Fw|Nl(?*VAX%)dG)H#NzT7(N!r^A%KaJ} z8}pzqFE7snl*bViot>R>?y9P){5AI03)Ef3InMeScpn_|9Xoa)9*-Bjw4SK?=U~TK zYbktQ0+c`ZWsq|2Q3E0f`R)irKS()lynoJ3t)1+xcQ=^x_GFV@dBqjVadi0=mvsZF zN&@cLt*#}{vSrKg&_fT&p!g-4mO{ZB){{nqYOoFmUZ0>DIdUXs%$R{g4?R@C!}IYP z8#ZjfOE0~I_3PIQNRK@7NQ@aXMm~Ofk6_>gT(V>d{_~&z$cyGn=Ckk_I9c^Vz!mwR zgAT$er<{Ue!-fs!UG)1HKF6j_oACJKkIPRj-A9ZVfz6vY=OPS9RR)rN^eS(OE0|??|tuk1$+e6 z0}niaJMOqcKuRD}8cm!y5%cEF!v{b3LA>i-@5-xk1S4PIAOHAAc@6?xOR?a+ala{3 zrr_WI{x|CC>biVA*u|!&=jZuWuU?Jse)qcqRKMo1JNA5k9ef-|jx7@}KK}8K%i`9P zr<>2Pr=NeI^WwGFUc*HfU4%u87Rh~T?Ma_UYk3D8Z~%VvqaWeSGtV68CHCt6L6G{% z48l0N?6RM918Go_7JCT<#lsIjER&lnnBGU*ar&wJQd8S{{BE$TJdf4t*HK3uB_O4w zD+Q#FKKiIEG=6aQ<}~VUHucvl%SkQv#5o_gx3UDW$xD)d_o z(&wIgPC&YN@nRXL;Qi=#I(_RW;Y(lo5b-9usq7cNex|_uCV=`1iBVJ{!OI#V;^^ z{CLq&xbt*)-duYUC_8E~%rTqyYa+O=y%Wu-byJ48EP2r_QR z9d{gl{_~%UWTgsAY5M!$|Grmsm*=M>B}l1G(>4rleckgw-W>0L#flYqNvgwJ`W%D3 zR&cy~0$o{IIamnbo8SC~grjn-#Uvmt?x)yOAT4Gx^=I5@k5cQ|Nu~aWznWb4m*ZD=moHylRFd{*fCsX|>wO8B!w)}PR{EJUXNnYE zx^yW{KKW#kjM@g#`xDgs@Vf&KJP}L#N{Q>PyRKJtSBG5)(gz=WunR~B z3z)vfhKmlhghw8EBp-v`(;)SmD21^KVf5(HxbAn?;rQc^N30|U+jhLhRK@R_o$6R8 zm>k|>wCUi&tv&EsYtgZ9|JesJuFpREY#yXRb4zOgen}csclXpH)7Lxg>H9t<>4HnU z+oV#R?kxbRR+0O9*ouk@eC%T%!?(WmEwK+d30{8rWn6H<1=zlQdtN=$=g~GCB`59J zKmYm9qO$4$_b-3>O93e-kB(3J??J20^zPCQe>1$h8l=45-jbw#M;@P7V$GI?V~;%! zS6p!=rXMgJ@lt}cd;KL{Oq`%(#Zhj$z8VECK}Ly2(9r(pril{T^Q!-*ug#ym%>g}` zRfU*B#R=M^T9Uq#K&oug4j5M~xYYe-Fi!d=gH(q_I7xc43H_j%Jb5yH_`@HH13(iC z2+nVQ^P3`hnwy)u;G8d>=cNn&BOm#QfSc+tHv*Ru*$>j-%F6rWYEMZ@&}e(Muf=4r z-}Cx!7D%E`v;k^AuK9qaKOC`ive_uMY8CdjB7?0XyR zaXm>=f>bIqyxAZv21E@~PLg8Y)!@S)ee}`d)uqZyY1q=zB5~4R|N7Us_S$Q)X3d%| zhfuBM%jf>z|Ni$ynrbP+Sg1#s4y%b!_FGIw671e*-RSQbOz~E3b}L|Elo{mZEitB z!wz{jl&F-Rd=JrZ1T__vD36z+rn*{wlF=0jhY=!6h}9FLk*uz6<`_~9ru|JVg0Wt{2THGEAmw62pnU36 zpAx$~zezX6LjObl{+{#C#qePx5cUcOOA&B(aRbl_Tm6@_;byXEZrFvE#$8yqdJUE> zeGSW(zJ~3aH=}7+6Pg+uWfsND;?nO%7NMMj3AH1of%5pV^_Vz*0uDQLF2>i7!|>t5 zQB^-y^>$?=9qxZb$J>4WJ$DCtNLJP-9 zbGeJD-@FFLpK3h!*Xq2M$OE%+b>rv)P+2}j@=3408tp8fvO6HSnBxzw%2PNr1 zLCX1~sjeJ9jxQN#BuQ`q^uH614FSqy_~H8@IFCK{SaGz`UosG<7mWy6ihROUgY-(4 zPYHrlCV#$SdU5ZrKcu2xbYC1%4gl3ms-oP2Akp4aP9%C=Nf;nli%C*_eLn++_pL#~ zb5p|TK_}oi!8y?>O?1`{??bDXL6G)zf3s)L7IJ}>X8QSgPQCiBTenWiG2U{^E!ets zYd&7<2ZffNd|pZq7AL0)MiB8lnkUR>;yr6MR%;yk-t{@Ts8QV`sf7CnH5DGu3B`qv z;U|(hy53I#q^c>EcyMGcWKE#W%_41C*y$$F)Y6R2tJY!diZ}4$)6Zhvs?~VyrI%p2 z2JBQC$mXPt1)D$-=u}_XK9V4%aZ8z49W6t|HQ;2j$RdRrs}iGzkHF}?F-T&baf56}V z_BXup$}93Nf*_@aq@^k6!U-pwAS4;G+Bo-m;#PNC+2s$tgS4%+6~;y1`L=t>Pn5cw zmrzW{>OtKt22$-}_n*VRnsDMUobc11{*oF0f~uafVPQ4?FCzJUI81B)#HF zk6{1ZZ-2|B6Q*l`E6}hh5XA23ruC==S27L)XxrYmUyQ~V)FgNz5-hj~GG48(7aU&=(yOn& zT0&JtLCW4v>>x)Y)BsW;s<$@QHSNHf9b2$r$2M$PzX6Zlb{AH?vJCdFCgtb}g<*Q_ zA(gb#tus7|UOslBq@l!AJ&DalfyYw9()Jt?j$>v;9j1&JgGm!7Vf2itnE$a05Sug_ zHhUr)E-c#cI^F{y2-2XrqRl4FIHK0VvDWrG=LT(l3J1;wdW-!V_v1U`eA4VSF4T-J zFwK+a^=|{VNdxL`Hl4-|*I$n-u4MU?78n1VeJrYQ96kX2Rl;jcy;YcY--qsSC+nt zXBIBP`j?l(ZfI12QA$UGj1rFj)FAbmRf)*+K$`FB=1Ewp)#_NaI1s4iurMt)43jE` zVN7K$YU)N{_9@3=&gsXaeEN7~!X~VcG?>h9+9q8j++F3=@^3+qzWd$p&YKb3kMn>8 z7skt}jRXP8f9r)^LQT0GKKjv*$|8Hj5l3|M1MD4;UUpfR8|&)-_ILAAyX}r7-5Ve! z0H|jE&;R_7IBoo%TP-d5H#&Ss=_4qa4a2`tqB3-&9Y@6^y$-=>Nvf+)(C(!TO8b)w z1SJ^(98__&^N7bW#!E>?4l(1cykDJE9(V~w%arscNe2Z|X{qQpZ&ueJ+f4B8FgS7?y0Aq5-mwP>GU}WOg<}ZP1>MLI{4%#KPf4aI%8<>OVYPFNC`Ho zC{!KkjnglM(vAa8b%ucAATu|T5|1mOmN0$ANwuWcAk{8+UW@1Y-S2*v_at)>(kr(H zly*$eCj7)FJ|P5uIg&a=f5G_|2#Dy=5rB#$6&VcMFp#ue>`HWE zebWwX*|h`Pwr|Bl_uhx+9{&$gTerio!iX3q9Cj+tvL~y=aq?aahFd&%s=4cdRI`+H z&qfijt^%lGyRZxcmII8atdd5{Q;bR+J81@{Rn=kYoS7JT>S3rmVit@M)j-&UEnU)G zyx=*Go_uPtG*#w(`8O_-1aAt13%GN6zNPxV!p2}UxuyQw_(esO|U{?#Ho2ClcJ`w2{P?XdVwntMs3Ex zG@}w{jh~5eqsE|o)?^&<(F=e>CaaF;v@0D4FTA(}-?`|!pd_^!>S2RsUrRw9d#1Wi zKvI$tptR+gq@gtsJ*IkpdU474;lH^sGsaF<8^d}2t=MAPZ4&nQ2Y+iyrNgFEY20wb z^|2D9z3Q$ASHk}Nw2x;YMg(;1xku~)IK3Az?4tQ z02%?TY2AetZ>+$^)obwJZMS3jQ_lbm%_w7_-zao!<)q4HG6LM%npzxw_+dEx^wTlp z;2HAVls-}h#x&5<+KO%4w+m~Fq!T7ZkX=(6SHRCdm*b$sHBse;QRf)AVB{Q3sv3b2 z(l0tN%hHE*D!sTq&ob3Y!v_1{RXT#IndMJbEUg#lYRfMp{v;_)(^=GkgT z9&tq8o36uNlBn-xDAAL8?|t{;KaW3wd+xmlq!s4u930QK4donBp(BQc;cgg*g+^k| z$O)J-VG`=+9gLYDdk-*W3=m<3KpW4#^di2)$_$jGwu;9FB`LKU+K^1aql9FK`p3r2*rbtog$b5mi`SF+l^=e;rC+0+gQQ_rL%B z0#NNh3No_#0_&az>AB~fE9$P6qy!wu(S-rZ{->I@V#ymT5Y9Nb{SSY}E4SYbw09zI zga9W8Ct||!QeSv)B_*YJ?|U!6r$7A}NkWK(LkL-_^eQ*b4{di#rj2Pzb_dn-Yp%H( z_uYS=l8QMSmhB*%vt%0e&Ip{DX>4SBxxY0L2)?9Go`(rqdrB)bbp%muE1$l3SG@VT0 z#v9pY;wrSYwZi!3SHI$3cKHIYh?fN;p8?~`Ast|=k05CIvcC7d@8#p9J&^_aYm*k6 z)TD9IaTLse3GPdfQq9pI<-O4^`N~(ml229B$M8FCU-EDMJV>t0e&>RJRpm?M%jY?1 zhidg#OBJ;s_R*TmcjJDL4#vAH&mod@9GF?bV7?!u4r>>~l(5S#xcK*LFJi;a287zv z`1Qq?A-QY?kaJK+oE>326U zY1!K{+|?%Ko~cAa<|xBuk_GdPuYB3PY{3Gt8JGp}b_OXOBD%C=v6sYw)smDFQO7#_ z0x6HvAHHb5L>)@fo?QOape41DETYeR<}e(?Pt;KLvO5Xws9g3Vkm z+bc*35G_#&)Qd0qF@F2o-@wkfs3?iSOsYcb$q*2+fsw9-S=MlzHDNYJ)(peMQ;xzx z?>ie9TMH-R;!K17&K9I6u_?u_~$}z@ax}q-9eh{ z>=bG#K`QyAU;WaBF3Z`QUaHc*08&=uBiTR~9P7`-rX(c;gey-^>Nf|MDi7_+{({s$ z(7X@50`nUBzVxc9|4ol3y}oo5>0)O(*4Dol*LAPGElCMds=A%o47R6|SiE@yHt%S_ zvv)s)2mkgDpsf|Kvk;bpX&~gdC@(2Rdq=wzf&1kzekp2hh;dWNEzJeZto#G{r5eYJ zC0Xu&;C_7UqaQ^}YYUv5i*g~7j-x+v0WiHDsEpy6 zS6{;aBS;sj5R4s&qYiY;=_n$fn(bF;rf3G!;Idr$x_ZwbW%QsMNNGnDsxo*w?f_L? zQFj9QaRXI%2Mf~k&O1+R#UL$A-w!7RLCUx$Gh_Oaq(SM$=is^YYOKK%1Sx?@N5fBk z@)NOZ)MQkjp0ZSWdzEhnNGT&bQYmcgXvd>#R-m;#fhYcY8(w;BArcMS>BG%~G-{X# z8>TqM=v4XMMc+f+s5&(+F4;Muet}d%Zy`&(!}I3N1?%T#QfW|;W{xGj&S3|LF~*5X zoH1$!#?_2O_0;h=^^+ffHD@YN6UTEezaWkyvY~|TrxViq!bcC^6PWZ&vp4|f37t#+ zcf99RT|rAAogUDVG!N3RU3j5OBClkeu+IpMeP+%Kvd3q!=jKECuI3+UsUj=@%p@f)-$HsOI6A5 z+V2af!SfXZssEn(3c&i}+rMV3YZ~O;deDE>k677JK z5s(^|i3mFgwdV4SW-bJ|i?|%oK zCMtVW0X{^!plf5YQH9g%XJCBgaEzHc38#JH11erRyc{n)|1AFBMHk_zMT^8~r=$#mt9d^Od9*0+W6VYMFeOyw~7++cRJ-Zj(~o?E+Hft6d7p{qT%5QX^KY7Yq@52vjq6(j zQWL3+jm@b9?jlHATCwPcf8eDD9z!PC4%iux4n)ZZTag(E(rlYKNXdg` zxPvcOC)gHq1o>A+N>Z|UbcZzm{(g|sUL=uvZ-P{(K2g=BT}n0(B{)}ShHZ3xr8f(t zvM2=Nq<-&i4kR{&@*ur;<*R6JX~h#a{sT)MdJImo6K*y|ktWlGQZ&LGOvjP9}r;Zm% zYRpyY?vm%96PuKA(i|mep5|CEy@J|Mf6WV0LCI3$e9`YO*fntXz}gQ<`lZkRuY2va zzvv=Gm8LuhW3-1SAE+c9EJ#WB(#g2RK*|+TJ9X$@@2@1)Dz4u~EvD{jiNS@1&Ie9N zzF1CVei)X~s&9WM3HRGwbvFo7I@p93=-F?Wpa5AAN%;naQT7-0#brA7EwjXdjo0ETw#&|t3{9~AF?cj7-=9# zZ6HdCiX5h*8fTB0iTaumsG2qor+(%`Fy~ALs!D`4q(Lg`Zr4HwGSvM6sn(GAlXHXb zk`D<*h-FXiHar0+Ld-QAZ!s$YP%r8pLpl&qpa ziTK7FZ{#!g^*+IuMsPCohSV}HB2;~Q^H}d`b+;Qx&pTfc>@`rOW{`n&&c&`=77x7s zDt5NE;A->%_zTv_Q5qO@d11SXsNvtNRaE*?X*msJr+wAV4h{?f|!xFjV= zeUem3R0BE3K#S|(p=GaPb7Lb`zPuE7{P8d7T)P2bHiH?lORaIrniu*_m{u?Wtq&B!n!<4u@}3iC21G$?p0UeymQYh3Q`Hf0C;Bo z1}xjKUNTi~|I=Tv^|_Z2PN!hHIT)r3*Kox-#KvCyFyPP0JOAjT1ptw7q#H={`J^7( zD(B>|X~RZooyltXuPt4gFIN%{TVjtAr0m2x3T2pCG92fPKLlgzMq|pkC!qYaBZ0b7 zWGkY0F#u90Qvj(}bvcLlA=pkj=_GMfQIaw-0m-IdkdsGHper z8h~_W(PpF6p%aNVAys7^I}HN$tpsTTz>208EM312TN@kj@4x&N%kO>=Rw{+ClY>d3 zfayY5JyOWe0?U2;_Xj?RFMRO}m^E`I%Hm~3L8_fq*<2Q#oe3;nya+d3cRlXE=UxFf zom&jYghQ6ZM*wxYjIHNaGWvu5R4cz8V7&u9E6TI2yS&0si=u1FD=3U`>t{v zNt&9IF9wmfM|DLE#?nbqWkn2K5|xF=2vn-Qy5Vq8no?8ZcU+uly72vJjc8A+yMFGj zkQqMp(T}*aDfXngTP%**Tbxw0cjz@^Di>40G~=ikjjN|P>D~q@JDwq`w$Y)4t71UZwmb|zel14ATdBoY=6C^LSJIP7pqu&3ss z9W7dt@_OqxZNwdS-hq4Xxfic2c?s<;tt#=Gp!b6NA=^O=E=D4RIjFUcYo?&+xwmNaFXOiC@%L$zN)ND<7a z@s8J0mG!8!Baq|DXAI8AfvLUSC8gc)_*7)wgIh}27&e5Z1ith#KOR9?PVZhPpbQgYi3l3Y?Lg~dLJwP{kF zs+Jss>>=%CeWBSviYwC5(V-fWK2s}PFpydyjG4~(vNTUn-)ryX22A(U*+JUa*d&94 zvlOIgq+HknSyaoDVwQw?lq^r0Ed`UUz}}Y9%-w97lj*qpqe_p4_@sHg4FcHMkZ$GEK_arpO)|?xTsM{Og1N$eA;v za-eOG{Bg%l={@*g89Q}K3X2O>?<${ez=9Bu=j)h>f`URV^TRbj2*F}uIenRWecIIl*aQe_dYRn9qHf>5;DVhB z>j0rJ9WpY;Wf(}a`8G3c?%o}cLsJH7xl+tsj5{d2=s_7cdrl7abxZ%ifE@bdfV92+ zPkH;b*X7j5`z2O9PYP4yw}91Cuo84BD=U@0o?cB`uoswvCbX2Mh3lU^qpfeeN{dUB zuQ!jhi#E)8f(V!|F{zhQx$7IZO6{V{rT*Hh3C$qy!>fPyOL{_q;2= zqL`r-`V_8foK60!o4E@}nWS*xL^cVNvryz}4!?zNnYUSj#HTe1Zq`88WMI>-TKn95z)}-dwW&&wyhC`RSHcsj?SQAGMk^uGY#vWBK7Nn2hn4u41qDpOZt7Pe6u`WB9b^Qb+JlW zb6LHts#z|}RxXztZogHQfA>boUtZ0ZMB*fO{qYs;ZS83w)ikZMK~|0lr!(4*Cj3m6 z3;W1GZ1#^cNT7)5DlhKc+!qr%Of;ZAn_!Z~75p0JY>jf6Ae9}YO{Pg7yl<2D!j2tZ zdXPeC0>=?y^h{0VEb@f}sR0L|GL#q-nrLCBCIQ~#KJk$_Fqpko&0@_4+05TewWv`b z4X0oXr1=E}K2yB|(gX|%fmTJ?4UCLPXJ3yT>^iIincCibOFn7+w~TamYosTSj+fv? zA%do5bTKCId!&$Kb7lZ3-829-kvOCJuR@BXHeN1YySzqLRxXj+`a1d6h95}HO*crv z%4(7Fc|JqF(>v1M?$0MhldAR$jiLZRtQ#Q3(t#YnUaXA;g?Nv%vuoEb4J2Vk8$GLi z&cF&#u@>;VadTjNKsgXFvy|P`wA@6HQqlFhXP;FfvO&g7TuLBi@d*Ot3R0IGI}^R8 z`6qPfn#dV{)YHb2;?ke(Ct@8}i{hZF009psLywzi~XE=p?=x z2C4IJoi`KspbU44GmHt^l>E3X&M%gmms}y&FR7PRwaewo)z{04jkk-`E)=i4NPA4R z=sr+Z{Fo|8X~qYn2y@ep?oShd)K}B}^3qE$>Ci2=-q>=cW(xCfa^Fy_kYckG4%ap9 zI=N<@2vTaJTbf(^rf&jAvl*n;jgZOwbfpxFfhNrrq}rYri)mEPCC3g+z+6CT8kPAh z_?*myF*C`2AD?jvv`HOtcnCtchsKrm1%*2$Awx5(N%*Q#0Sg491M zK1lIT)f^4{(|!U;XGi4N@#Au=t49vK*CD&#dQ$2kT`Z7tv)Jx{!Dh3#K)@HXQY)%JFgM7Pns$l;DT@L~ZT2V;Q}=~g z!h84&T$cqUr^j_!WGaRr48wN6AZD)E%)e#>Rn*L&Oo^v z&CCQBcy@rweeiqu{l>vdlQ?`jXwyt(g)T@Fzor?QOfIwe@Z3{J2xj z4h>0h*?iTA!i-SL^Yl+bwQ7D|zIM(O=EWrsQth(|DTxO zH+}mSS#|YQvf`R+L>4XZ!@j|YQl;|_OjJvUk{^BK(MM$W?lvDJ=gy`1q?|w2oc%>Z zx<09Uw#@7`%ZHH@FfH0!!CfA1L zfR-)N7Vazj{9%wH)To5&?Ci`qYLWXv*sNZ?THDIjtzG8_cw%`9LVZrnPx=gkDM6!% zB{%~kg%93@mz3e;sPy#rN_SV696o$VKIqsh9q+#{`}gga{@z}V(gGBsl*WO}HPM!U zw7`q$kfySt5?M6ALawU2LI(-o)NrFLs$L>>U%yt0%1b4$tjxa^BNj6f%Yekq?v)W3 zk3RO8f{A?z3u*S4Gsu~usD^?Ivsm0cb_Jo82vVX-v=?SW&WF+G*q(50)|WHP=m|7B z!rZEn!WK~4z8Xlwj7(#m{N|~rmC0#z3$r zfGJZkLnevDA!m*U<#|L?!+s?jXPO#mN`w!GpKGysB(N#+w&~ei&qfGXp#k@Y)}si) zdR=Y7!yWr>%`wxuxi4ya*<_oKYMaP+d7n+^x&)E}$0Em+!aexF z11ijXs+^dnPr{Z;3Zy|ti&`{Lkm+a&PtGLI`Vn1kOom5BXvhSmPa^&#m zvTyHRWmp&*8kW(~)2dbZeMNyLt*@?8j-=Y9)l$23nOt+_N~x)?*1%4zs8D1P$9 zmB4vaa0W!b`gdQr1O-nztP7e}N;Cmzc(#u1J(XezLJJ&a({$_+LXG{V8i^nvu?VAN zb!XhN)|@F=D#?H2Hj!4dK;^VR`hVWvtxr6m?QvSnkfup#79`I!!ypATB>UkvWnsdH z$cpG$Omc=uB8u0|lr*qrbHMpNnhMQj01IncGfCM%s$kHz)L*igEHGNgMjF}>CCl>x zUNkYLDCSsLN`{{YLBs}gZ8SU2j%4OKR_LvT)9}g$eWyG-!i0N6Q|AIw?hRIbp3%w@ z-R~P28f!zYa9&A?mI>NHH;`sZx&ca}w$^{@4_xvYJd$2gg^s3`;sr7^I4DQ^`ej~m zv5X9l=#*-h7D&e!NDK1fQXG#yyi!?EStX@aO!QWjuD~1{ONd7SJCS3T^VxtI z(xm1?+5qNo1sD4aczK^Fx^Wg|v(VTJn;&F_5DepD@3@vS@&`V#X;${TySrN>_9&Y3 z0%dvl8q(x2UPkGJE69WoEof`x6$zYo;z8{3ZCBY0#42r4$bT6VWsvQp$e*B9074rwtV%n$Ub<%TN-d9IJcSEV z14+2hBK3Yir;-AxF;VJIPZChF1nD2Ht5rxg>_kZ(CRXscl}irnBlk`}8^MH`38ZP3 zMKH!9{L5w>q%F-dOmz1rcW?A|?%XM*6nS&=v&h_?(u#ipANneTl;utV#2p6gxG@SU z7gs@BN*YLmU=Zdq1^$4PukbcBES9I$-{*AOOwdN@x_L^cVfKO4T~$9w=9|0E$S|q8 zA8*{?5qT}Gs7PznJ)hd$DXr8c{GqVq45ta0^Im-MMJcPCGk0@d%&+Jdq7LyK zNYC$JBohhQ($uJ$bae2f#5Ue_r}u}KU!DW$`K{|$>f3W5%@EC+!4m*Tn;JLEbK9Hc zG(PEuJAdfC{K_kHAf3TQzSJ)j2~s~jF#eh|cc*kDY{}>#LX!g0GlM7Pf2nysEeiU~ QjQ{`u07*qoM6N<$g88?WF8}}l literal 0 HcmV?d00001 diff --git a/test/Charly/01-begin/05-together/public/index.php b/test/Charly/01-begin/05-together/public/index.php new file mode 100644 index 0000000..9c1b38d --- /dev/null +++ b/test/Charly/01-begin/05-together/public/index.php @@ -0,0 +1,37 @@ +selectAll(); + +// vue +require PROJECT_DIRECTORY."/view/permission/permission.homepage.view.php"; + +//var_dump($allPermission,$permissionManager); \ No newline at end of file diff --git a/test/Charly/01-begin/05-together/view/README.md b/test/Charly/01-begin/05-together/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/01-begin/05-together/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/01-begin/05-together/view/permission/permission.homepage.view.php b/test/Charly/01-begin/05-together/view/permission/permission.homepage.view.php new file mode 100644 index 0000000..68d3233 --- /dev/null +++ b/test/Charly/01-begin/05-together/view/permission/permission.homepage.view.php @@ -0,0 +1,25 @@ + + + + + + CRUD Permission Homepage + + +

CRUD Permission Homepage

+ +

Pas encore de permission

+ +

Id :getPermissionId()?> Intitulé : getPermissionName()?>

+

getPermissionDescription()?>

+ + + \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/.gitignore b/test/Charly/01-begin/06-manager/.gitignore new file mode 100644 index 0000000..d11ccf2 --- /dev/null +++ b/test/Charly/01-begin/06-manager/.gitignore @@ -0,0 +1,11 @@ +# Ignore config file +config.php +# vendor contient les librairies externes en PHP +/vendor +# fichers non envoyés +# PHPStorm +.idea +# VSCODE +.vscode +# Charly +.history diff --git a/test/Charly/01-begin/06-manager/config.php.ini b/test/Charly/01-begin/06-manager/config.php.ini new file mode 100644 index 0000000..ae92c13 --- /dev/null +++ b/test/Charly/01-begin/06-manager/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/01-begin/06-manager/controller/README.md b/test/Charly/01-begin/06-manager/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/01-begin/06-manager/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/01-begin/06-manager/controller/commentController.php b/test/Charly/01-begin/06-manager/controller/commentController.php new file mode 100644 index 0000000..a238191 --- /dev/null +++ b/test/Charly/01-begin/06-manager/controller/commentController.php @@ -0,0 +1,95 @@ +selectOneById($idComment); + // view + require "../view/comment/selectOneComment.view.php"; + +// insert comment page +}elseif(isset($_GET['insert'])){ + +// real insert comment + if(isset($_POST['comment_text'])) { + try{ + // create comment + $comment = new CommentMapping($_POST); + // set date + $comment->setCommentDatePublish(new DateTime()); + // insert comment + $insertComment = $commentManager->insert($comment); + + if($insertComment===true) { + header("Location: ./?route=comment"); + exit(); + }else{ + $error = $insertComment; + } + }catch(Exception $e){ + $error = $e->getMessage(); + } + //var_dump($comment); + + } + // view + require "../view/comment/insertComment.view.php"; + +// delete comment +}elseif (isset($_GET['update'])&&ctype_digit($_GET['update'])) { + $idComment = (int)$_GET['update']; + + // update comment + if (isset($_POST['comment_text'])) { + try { + // create comment + $comment = new CommentMapping($_POST); + $comment->setCommentId($idComment); + // update comment + $updateComment = $commentManager->update($comment); + if($updateComment===true) { + header("Location: ./?route=comment"); + exit(); + }else{ + $error = $updateComment; + } + }catch (Exception $e) { + $error = $e->getMessage(); + } + + } + // select one comment + $selectOneComment = $commentManager->selectOneById($idComment); + // view + require "../view/comment/updateComment.view.php"; + +// delete comment +}elseif(isset($_GET['delete'])&&ctype_digit($_GET['delete'])){ + $idComment = (int) $_GET['delete']; + // delete comment + $deleteComment = $commentManager->delete($idComment); + if($deleteComment===true) { + header("Location: ./?route=comment"); + exit(); + }else{ + $error = $deleteComment; + } + +// homepage +}else{ + // select all comments + $selectAllComments = $commentManager->selectAll(); + // view + require "../view/comment/selectAllComment.view.php"; +} \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/controller/routerController.php b/test/Charly/01-begin/06-manager/controller/routerController.php new file mode 100644 index 0000000..49e1a9e --- /dev/null +++ b/test/Charly/01-begin/06-manager/controller/routerController.php @@ -0,0 +1,46 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst', $tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + } else { + // sinon, on affiche un message d'erreur (à commenter en prod) + echo "$methodeName n'est pas un setter valide
"; + } + } + } +} + + diff --git a/test/Charly/01-begin/06-manager/model/Abstract/README.md b/test/Charly/01-begin/06-manager/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/01-begin/06-manager/model/Interface/InterfaceManager.php b/test/Charly/01-begin/06-manager/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..421a87f --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Interface/InterfaceManager.php @@ -0,0 +1,16 @@ +connect = $db; + } + + // sélection de tous les articles + public function selectAll(): ?array + { + // requête SQL + $sql = "SELECT * FROM `comment` -- WHERE `comment_id`=999 + ORDER BY `comment_date_create` DESC"; + // query car pas d'entrées d'utilisateur + $select = $this->connect->query($sql); + + // si on ne récupère rien, on quitte avec un message d'erreur + if($select->rowCount()===0) return null; + + // on transforme nos résultats en tableau associatif + $array = $select->fetchAll(PDO::FETCH_ASSOC); + + // on ferme le curseur + $select->closeCursor(); + + // on va stocker les commentaires dans un tableau + $arrayComment = []; + + /* pour chaque valeur, on va créer une instance de classe + CommentMapping, liée à la table qu'on va manager + */ + foreach($array as $value){ + // on remplit un nouveau tableau contenant les commentaires + $arrayComment[] = new CommentMapping($value); + } + + // on retourne le tableau + return $arrayComment; + } + + // récupération d'un commentaire via son id + public function selectOneById(int $id): null|string|CommentMapping + { + + // requête préparée + $sql = "SELECT * FROM `comment` WHERE `comment_id`= ?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + $prepare->execute(); + + // pas de résultat = null + if($prepare->rowCount()===0) return null; + + // récupération des valeurs en tableau associatif + $result = $prepare->fetch(PDO::FETCH_ASSOC); + + // création de l'instance CommentMapping + $result = new CommentMapping($result); + + $prepare->closeCursor(); + + return $result; + + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + // mise à jour d'un commentaire + public function update(AbstractMapping $mapping): bool|string + { + + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + // requête préparée + $sql = "UPDATE `comment` SET `comment_text`=?, `comment_date_update`=? WHERE `comment_id`=?"; + // mise à jour de la date de modification + $mapping->setCommentDateUpdate(date("Y-m-d H:i:s")); + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + $prepare->bindValue(2,$mapping->getCommentDateUpdate()); + $prepare->bindValue(3,$mapping->getCommentId(), PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + + // insertion d'un commentaire - À modifier ! + public function insert(AbstractMapping $mapping): bool|string + { + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + + // requête préparée + $sql = "INSERT INTO `comment`(`comment_text`, `user_user_id`, `article_article_id` ) VALUES (?,1,1)"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + } + + // suppression d'un commentaire + public function delete(int $id): bool|string + { + // requête préparée + $sql = "DELETE FROM `comment` WHERE `comment_id`=?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/model/Mapping/ArticleMapping.php b/test/Charly/01-begin/06-manager/model/Mapping/ArticleMapping.php new file mode 100644 index 0000000..7a2fc92 --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Mapping/ArticleMapping.php @@ -0,0 +1,124 @@ +article_date_create; + } + + public function setArticleDateCreate(null|string|DateTime $article_date_create): void + { + $this->formatDateTime($article_date_create, "article_date_create"); + } + + public function getArticleDateUpdate(): null|string|DateTime + { + return $this->article_date_update; + } + + public function setArticleDateUpdate(null|string|DateTime $article_date_update): void + { + $this->formatDateTime($article_date_update, "article_date_update"); + } + + public function getArticleDatePublish(): null|string|DateTime + { + return $this->article_date_publish; + } + + public function setArticleDatePublish(null|string|DateTime $article_date_publish): void + { + $this->formatDateTime($article_date_publish, "article_date_publish"); + } + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + $this->user_user_id = $user_user_id; + } + + public function getArticleIsPublished(): ?bool + { + return $this->article_is_published; + } + + public function setArticleIsPublished(?bool $article_is_published): void + { + $this->article_is_published = $article_is_published; + } + + public function getArticleTitle(): ?string + { + return $this->article_title; + } + + public function setArticleTitle(?string $article_title): void + { + $article_title = trim(strip_tags($article_title)); + $this->article_title = $article_title; + } + + public function getArticleSlug(): ?string + { + return $this->article_slug; + } + + public function setArticleSlug(?string $article_slug): void + { + $this->article_slug = $this->slugify($article_slug === null ? $this->getArticleTitle() : $article_slug); + } + + public function getArticleId(): ?int + { + return $this->article_id; + } + + public function setArticleId(?int $article_id): void + { + if($article_id<=0 && $article_id !== null) throw new Exception("ID non valide"); + $this->article_id = $article_id; + } + + public function getArticleText(): ?string + { + return $this->article_text; + } + + public function setArticleText(?string $article_text): void + { + $this->article_text = $article_text; + } + + public function __toString(): string + { + return "article_title"; + } + + +} \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/model/Mapping/CategoryMapping.php b/test/Charly/01-begin/06-manager/model/Mapping/CategoryMapping.php new file mode 100644 index 0000000..cbb3d1b --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Mapping/CategoryMapping.php @@ -0,0 +1,89 @@ +category_id; + } + + public function setCategoryId(?int $category_id): void + { + if($category_id<=0) throw new Exception("ID non valide"); + $this->category_id = $category_id; + } + + public function getCategoryName(): ?string + { + + return $this->category_name; + + } + + public function setCategoryName(?string $category_name): void + { + + $text = trim(strip_tags($category_name)); + $this->category_name = $text; + } + + public function getCategorySlug(): ?string + { + return $this->category_slug; + } + + public function setCategorySlug(?string $category_slug): void + { + $this->category_slug = $this->slugify($category_slug); + } + + public function getCategoryDescription(): ?string + { + return $this->category_description; + } + + public function setCategoryDescription(?string $category_description): void + { + $this->category_description = $category_description; + } + + public function getCategoryParent(): ?int + { + return $this->category_parent; + } + + public function setCategoryParent(?float $category_parent): void + { + $this->category_parent = $category_parent; + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/model/Mapping/CommentMapping.php b/test/Charly/01-begin/06-manager/model/Mapping/CommentMapping.php new file mode 100644 index 0000000..c3de343 --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Mapping/CommentMapping.php @@ -0,0 +1,152 @@ +comment_id; + } + + public function setCommentId(?int $comment_id): void + { + if($comment_id<=0) throw new Exception("ID non valide"); + $this->comment_id = $comment_id; + } + + public function getCommentText(): ?string + { + + return $this->comment_text; + + } + + public function setCommentText(?string $comment_text): void + { + // cryptage + $text = trim(strip_tags($comment_text)); + $this->comment_text = $text; + } + + public function getCommentParent(): ?int + { + return $this->comment_parent; + } + + public function setCommentParent(?int $comment_parent): void + { + $this->comment_parent = $comment_parent; + } + + + + public function getCommentDateCreate(): null|string|DateTime + { + return $this->comment_date_create; + } + + public function setCommentDateCreate(null|string|DateTime $comment_date_create): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_create, "comment_date_create"); + + } + + + public function getCommentDateUpdate(): null|string|DateTime + { + return $this->comment_date_update; + } + + public function setCommentDateUpdate(null|string|DateTime $comment_date_update): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_update, "comment_date_update"); + + } + + + public function getCommentDatePublish(): null|string|DateTime + { + return $this->comment_date_publish; + } + + public function setCommentDatePublish(null|string|DateTime $comment_date_publish): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_publish, "comment_date_publish"); + + } + + + public function getCommentIsPublished(): ?bool + { + return $this->comment_is_published; + } + + public function setCommentIsPublished(?bool $comment_is_published): void + { + $this->comment_is_published = $comment_is_published; + } + + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + if($user_user_id<=0) throw new Exception("ID non valide"); + $this->user_user_id = $user_user_id; + } + + + + public function getArticleArticleId(): ?int + { + return $this->article_article_id; + } + + public function setArticleArticleId(?int $article_article_id): void + { + if($article_article_id<=0) throw new Exception("ID non valide"); + $this->article_article_id = $article_article_id; + } + + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/model/Mapping/FileMapping.php b/test/Charly/01-begin/06-manager/model/Mapping/FileMapping.php new file mode 100644 index 0000000..e26665b --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Mapping/FileMapping.php @@ -0,0 +1,64 @@ +file_id; + } + + public function setFileId(?int $file_id): void + { + if ($file_id <= 0) { + throw new Exception("ID non valide"); + } + $this->file_id = $file_id; + } + + public function getFileUrl(): ?string + { + return html_entity_decode($this->file_url); + } + + public function setFileUrl(?string $file_url): void + { + $text = trim(strip_tags($file_url)); + $this->file_url = $text; + } + + public function getFileDescription(): ?string + { + return $this->file_description; + } + + public function setFileDescription(?string $file_description): void + { + $this->file_description = $file_description; + } + + public function getFileType(): ?string + { + return $this->file_type; + } + + public function setFileType(?string $file_type): void + { + $this->file_type = $file_type; + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/01-begin/06-manager/model/Mapping/PermissionMapping.php b/test/Charly/01-begin/06-manager/model/Mapping/PermissionMapping.php new file mode 100644 index 0000000..a17e27a --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Mapping/PermissionMapping.php @@ -0,0 +1,49 @@ +permission_id; + } + + public function setPermissionId(?int $permission_id): void + { + $this->permission_id = $permission_id; + } + + public function getPermissionName(): ?string + { + return $this->permission_name; + } + + public function setPermissionName(?string $permission_name): void + { + $this->permission_name = trim(strip_tags($permission_name)); + } + + public function getPermissionDescription(): ?string + { + return $this->permission_description; + } + + public function setPermissionDescription(?string $permission_description): void + { + $this->permission_description = trim(strip_tags($permission_description)); + } + +} + \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/model/Mapping/TagMapping.php b/test/Charly/01-begin/06-manager/model/Mapping/TagMapping.php new file mode 100644 index 0000000..798f6b9 --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Mapping/TagMapping.php @@ -0,0 +1,44 @@ +tag_id; + } + + public function setTagId(?int $tag_id): void + { + if ($tag_id <= 0) { + throw new Exception("ID non valide"); + } + $this->tag_id = $tag_id; + } + + public function getTagSlug(): ?string + { + + return $this->tag_slug; + } + + public function setTagSlug(?string $tag_slug): void + { + + $this->tag_slug = $this->slugify($tag_slug); + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/01-begin/06-manager/model/Mapping/UserMapping.php b/test/Charly/01-begin/06-manager/model/Mapping/UserMapping.php new file mode 100644 index 0000000..400ecea --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Mapping/UserMapping.php @@ -0,0 +1,87 @@ +user_id; + } + public function getUserLogin():string{ + return $this->user_login; + } + public function getUserPassword():string{ + return $this->user_password; + } + public function getUserFullName():?string{ + return $this->user_full_name; + } + public function getUserMail():string{ + return $this->user_mail; + } + public function getUserStatus():?int{ + return $this->user_status; + } + public function getUserSecretKey():string{ + return $this->user_secret_key; + } + public function getPermissionPermissionId():?int{ + return $this->permission_permission_id; + } + //setters + public function setUserId(?int $user_id){ + if ($user_id < 0)throw new Exception("ID non valide"); + $this->user_id = $user_id; + } + public function setUserLogin(?string $user_login){ + $this->user_login = trim(strip_tags($user_login)); + } + public function setUserPassword(?string $user_password){ + $this->user_password = trim(strip_tags($user_password)); + } + public function setUserFullName(?string $user_full_name){ + $this->user_full_name = trim(strip_tags($user_full_name)); + } + public function setUserMail(?string $user_mail){ + $this->user_mail = trim(strip_tags($user_mail)); + } + public function setUserStatus(?int $user_status){ + $this->user_status = $user_status; + } + public function setUserSecretKey(?string $user_secret_key){ + $this->user_secret_key = trim(strip_tags($user_secret_key)); + } + public function setPermissionPermissionId(?int $permission_permission_id){ + $this->permission_permission_id = $permission_permission_id; + } + + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/model/README.md b/test/Charly/01-begin/06-manager/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/01-begin/06-manager/model/Trait/README.md b/test/Charly/01-begin/06-manager/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/model/Trait/TraitDateTime.php b/test/Charly/01-begin/06-manager/model/Trait/TraitDateTime.php new file mode 100644 index 0000000..6b56182 --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Trait/TraitDateTime.php @@ -0,0 +1,34 @@ +$paramName = $date->format("Y-m-d H:i:s"); + } catch (Exception $e) { + // en cas d'échec, on met la date à null + $this->$paramName = null; + } + // si c'est un objet (DateTime seul possible) + }elseif (is_object($date)){ + // on formate la date en string en DATETIME + $this->$paramName = $date->format("Y-m-d H:i:s"); + }else{ + $this->$paramName = null; + } + } + +} \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/model/Trait/TraitSlugify.php b/test/Charly/01-begin/06-manager/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/01-begin/06-manager/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ +PyA07*naRCr$Oy?K;mXL;uNyK8K@XDykvuc}h1w3K!%v;q3 zGkvE2oO7iArrXBGHnuU??mq1~LH8jeEc6d$;F(UZYwoN490t{4fj?FlPO(^`DFB3Pk7mWKUij zbKkMGdKP~Rj9C{iA`AmweDS9|^w2}R^2#e1m1;3^Y-biITOeKh1zrx%Om1?dkdfT+ z^99rdehnDPJL&gsJmj2OKwaGGm<4AM#|vTO@exw!h#vZM=N*yZpHeREG? zITcvr``LW53mMoZRLy;=Sj)NZX4CpZ@Gc9+H?; z5=SkNF8MuqS8v#SLnRgzT!e;>LZc>YCRmx3M=~Ico#Rshwf>s<+~g+sCs>qsm-8|8 zo9nOUJ)#wmF6v${3ZxQ~TBg;CNf&iVFWi%6-%Nv0Tu=i70V+@<#PfVCO!XxeE^$K> z3<-#mpUpWSvf{Kv@_YFng*q>#z6_Amg}j#nC=pf!PU7y)${gwI)NE1bdH@&hN-nQ= zZh>@p-H&&5HjSI9O;%`Vp!z@+`5qBAS<|`I?o$!S zu4O8KrXsMzNVWyZI@YsQ2|#Br!jsE2@9Ltw2VT4&NK2)Hib-3R^y0YN%E47u%}{{! z4GqxYnMr2KWqjAdOSyPvY(?wVRLo-HEotaQQADUrWT<{_!8E9*U24jAjlov;J9X5VDmb5jTx%?f_cpQzZo$Ow~&kQy)=MErdJe%=}zrJPDrH647hf?^vbsbnZ8 zwW+46<5kc=jzXOVmS<>>)lkVGTUkc^2#kopmRI<=wF*5E+_d#lws&>W7Jw^aNY4hG}4i0z5+{h7?FmsKp>ndj(d65w~vM$*#^$ z+GCK0mVjA5U*0{{0_ma_(}I?CdU`TyYirXnND}n7Ea{>y?uB?#Gf2g*RWTWk;HU2h zNXIFpGn8x>->~8gthlp2h5~2|(nz@40@T?cl_XTNC3V9FNPQDLTP&+b#+zY95OVwG zom|%0MZ2$)N7zyhl6R3LQk?Z|HsCFHcittlAV{aCCZhKC_7+Gl1me!>Jym5?#g77o zihvY&;hlrLGBHj*lclUcYN{lU8HG4zMC6Oj4dU9V_@x43QzxOsk|uRj10)s|cUM5F zYM`+tRUkDyQnfrQLk-g1T|IPGCH@ruILQ>v_rdggs4`9y1@){h!F%jQiw0@KiYlAh zYE@gN3qfahRrE+?SdjE#hj@8nfIxW>~z|=XZPiplNG7U=nz-V z&kG?8!7(B2f@`Y3i7PBw>A5t**=ui^UikBPS}l;C$BTO*4sFCG6YZCplud&Z0@8s) z{CaXyxw}=vR`IHU)CmI|-=jD=%FxkwXmc!#a!tjWs;(J7l!db-*`y!Jl1faflD{!X zZDAONSmiR^m4IDtJ0IPB4ej{~xgbIk%Cg`BFT}G=QfpRXZ|sLQm(Vfr#KXqGmJOnr z9aRsrF2ohR@b9@Okal!*%sJDRCB5*sZvHb+AQh{n93GRhWiSXlcjOQ+O-`xAQ4nc& zR=cbr*&yJhpFGPmk39_I!%(YW2SIE}^`SIKCEYUzq_I0J_1Kyvqy<4Tg_FScSk> z?rp=AYInEJ0hISp;jg%^@!!Oq4Ggk@%}Nh0GdlU$rPr`6O4C&faSemOFqrZ@!oD6h z-hDG$?!OZ@tt85t6l0L4FcsL7$8UO!x}YU(fpodT@idmyk5{;9P_iuz(!&Q8NK5G~ z0Zwd54bnkCN6q8)r=H>mfBQEuG6-HlWqca|Z9>fKO}*)VVrq4{wGERF&u1q&?p?c^ zySg{gGviU2oF?1RLD8`|mWfz>?=5Wq;=h7b?U1u5IP!9Xw79(Ww>09a!f!4ce?gE+ zowO~dOE4`|#UBA(||ZN@pn8CMVi0QXjmUUBCYsSl0t> z4kcF?f#$cQEs(~6$I0$)3#5x(p3CETYS*n>(kQm12}q|JAT=aQqe0qMDskYMXEaEM z1*D~S1yXTq)4tDoEcVdDXSQC=E~}GlzDmk)C=fB;m8QIB6W9FjpNH*hpxvS3=nSup zN$0w|Es!Q46=jB>{PZWPpY*lYUd3pEba{Ypv1g${npo0>Kx!&?x4oEv^lSLTgW#9z zAl2O5*&U{*OXR3zlwsidJ}ZIUbo22oS8`oPKfTi)ZY`t|8BBGinB2CC8~@`MVb=!e zO5??32Wg{A>aX&-f79i9=2K>P;e{7?=%ELB{q@&dAYCjtmdo=_57OzAENR*gX)hIH zODZ5eLFCP~q`DT`NaW16YR#Y(a0y?@5%2>W$#C!1J-n}T4Vwy(&U+Y^!(`fIY<(9u z{onr{cCCY+ERn5S>*j*81=87x08tBk?z!g_NZ)+(O^jCJXt}^|ap!R|NF}=~?(P6D zO$tbJ1lWq`Ahf@wk?uGDuWwwxlsY1*CK8l?gcK1F4j7(!fe=Zd|dM zn|n8KquE8rjE`+NOt}WbD>K~uAHD!LUk)pBI(sagHL4!l*a%u6oefga-F@bnrW8#)*h*8nX^DD1p5}_XmJ2p4$nFpkakzA?0xD94bs75ipY>y()p}uv*i>k zEB{ZvtC&<7;Rw%)RJ~JrOE=>3@zs0y$lA;3I5LH6S{zRYSl4dj%K!7A7Z$J5CzW3Fy5DG}6;EX^T z`^CytReh#fe1)p?mqySNnyiWp-k;sded{l0citxJMNGBZOs((W@_+wn(zos*vO`Kn zs0a^<>U}G_8%xa8m%u!hw3RqoJV2JiGv|V|7=u)CcTWM*Uf<*GCw|PMfA#051nKEM zTXW1h7o>7NU0AdQ0lVqtp1$3DFte6iIiT9^Fqn(z|JW^T`~3Z|aV7b}B)K-p3%6p@ zdQ85MyW0Zka)93A&!G-d`N0gB3(`_5hc8_)P1)UZ3R2Y_6HADyVSEwohE2N%Ye;jA zy_yHsT+Rlk4N+>yXHBf#8@c8WJ_CEU;5i|dtr|~TiKF-mEa>jG$P9}I$Z~k5x}l2E z7ZFKzH?gFLrBy9Y@hm{P7%MtACY93=cUSsEh31zFO*(y(HCTMC=W?!Hxsfh2g>OWZ zJ5${Bd!NGk_$`ow(3bwv*6g80TT&4sYt}f@FKl(eEC)c&cMh{aDlw_4W76lEKpGg* z^xdeFCYJP(zx*>I$?ndHNzW9dk}MKZf+#g4QoC*dnZTeoGT6gPZd$#StGd_Gm+NG@ zRAA!=ZlLdTABG)kkPh@PQR1G%IBM3{Uat4xT%Xs1mb3-ZbA8Fr@A2v&H6lW>q^8Nx z0w9&d(Y~jj>#dRHJ#fTJ{#6oV*M236k-QUT;V*k*Kad*?>(ShJIr zp2b8^VfXJpz{(F@2Rk=8rv>fppqS5-U0+L6VeYL?^#H zu-IvJazod8uJ2e!fA31njVrm~cRm3-*TU9*ZH0XiGJvIep))k+aNm#ORZD#QFPG>?)6e=z~I1=5QGdW%0v0jUg% zP?l7=yV{bT4x~a09C+bbzWvAl874;0IY^b{O7aleplOhfOfr!{FBX^CE4gCLX4dwu zqJQfquDJVl*4=so^!HGuN|;S44_+mUl~T*uL#zeT#jmB-Gtbi%NI)vHSp=ja=~)Nq zcwWn=%yDA(HD-h8aQ8&aw6!g#b(E{n&Ub)um&e;`E@nY=m&IRc!<2oh{tl2T?c?W6J zr_(cJBrerJllU}^$x1S8%5<}3Wj{N2?Bx9)xs%=Z+=jiek7>W8_`GSu!WQ9dHOHp$ zI1|veKzh!WTI)b(dj<4}!iKvmmUKiE>?I~$1|SuX$Oy!G7FZ>tL)viYC&Rj27rmKw zZoK^#uK(CwyzirTQZWOSDRwOz%d!ZqIho!waDUbNHogDZUgxEJT`MMC%B#Hu@1>OH z)xZcDMc8n6f3i$KDwiM`Qz63IGXKppBqI&oIP{tstk7fU)=RnZ&fB^3zK?R{)q5~A zDcuzAYLJFaEBDNFdE*VD38<&a5-*qOZVQ66#ob*3WSzseP-7s(lEyJX7{u=a$IL0`kuo(x`-~A$;t7kvs2o3n;$J&;5oeu=kQ<` z1xVw?ucj`>>iCiYmdW7~tBMerBg6+x+S}Us;vf7keDM$dE&W?IQ!M1MOcUF-FolRO z^J$u8$KeY#9@sBgx{X(}Gx3xafXY&h!e>1}~@8QiSJ zoWex`(o=nqghnWn)k2wRYN}FAA*iu&-FiNB-#y&*v3uEd-PO3+EV)!xHJ6KPtSqC< zkpbEg(;9qR%=8_#d$YyhN zc6ZU$-A%Tw4cmtmc7_aE#zh{Unk%KDD#y|xaY*F(M7~dZCabKeIL_i)E*EenH+n&L zw*}IR1fB6|o-IfZKK~5g`IA39KeWKbUc$uPjX|1<=haBb#+NVGB5*B8J8a%_B{$!8 z8<+373OAR<$)-uSx6{?$Nl&VSb~jBXoziOhVp$sIg<~5N|2fgq%wF|YNSRwMHKq1 z+_sggZ@Q6d-v2(@R`o(#hRAT}&i0UVvt&{(Y0D<(q{uocT-(O zAZx(J!^lHvjGOal;tVgfrJV~>5yuuu&j%lTh<*F^VzeyjnXIx4|J<_$>HcS);^9C0 z5{wRCSdb={P-4>9l1d#^7)O4SXm;d#3Q^f@o7r{k9;S3BKVF1lo2+GR54s zaczf`63-UPYZ;h*E9qIYnmyND$2IS}nYL9M z@$EE`ZBY|)zGdK>sGl7I(&ZA}VZ`oLYq@IU7CJ2hH!jntfm1T@DhSl1^!f*FUh*=r ze93%b9Va)}h@vp$>8BC}`xZ!-D;7_AUS|tZkx%*VU;OF3@+l{cnNW@8rvPbO?l|3r zTc}xkF3rzY>VdHZla!B=XNiF#Kuy`u)<&kSou2-6eBk5%nx6HW=vmW8#e|9(QL_xH zDl6oZ@+)+Qu%~w|H*VQPn-6JQCz!eCr+_{5XPcK$3gWHzHa82^%X*Kcf>fW`yZ{sG~Lr9x?gpM59i6TsK zdFK-Mmts?B_G>n^sY+E|s&kjbR5GHJX_ih^z6 ztm@&?Ti*v)?t+v-=o)y^Ef?zxpX+WmpkbA-v}9`AHY3v&gsWhF`v zssg?ti65yECkY=Nxi&Th0iu99Vl!#(>)Foz8!w}OszPTaP`?ihL(R__P8pb2Y~za0 zKLGFF16fmz&5-dIOAAs>Rh;z*quG{paPU~PdUan5q-Tzo3-XHP4pLRBoV)1euC4_% zixQwF7QImt5r8JvbpFe4g^}uz*^0~ko!fX|<8IbWlS1=6Lt5$Eb%mIFu|?(qDKhXoAj$@R$v zF3wyX-c#@_)KSD*N*#174)=F$52xsE%&UcZ{M2M^bQk(m`w)4P-%UCm6p{wH057OWL6ue(7sYTVXi7Z2d^mIGH zIk}UKgDeQrW5u;KzfcZ{P{ZEQh-#rqq83|11DDflLai#P@1}~OCa-HL{VRf zq@n7Wr>muk!1w7NvkS532c)sPt3bL3a*lF$qq-$s=p4`89X>rs2QXS7o$q3w+Z&X` zXbUg4g~@0a0;J6T+RQI7S)nh@Bw%pyhw<5VYI!Pgq#zkD*jaw*j(&XrrwMs2HNMlk#^68||pTnfTvxn8~U1V&B@ySVMN(E-TA~m3_ z1hF;QAQ1=?pd~nLc6T+ysOjU^FJvNetw{}weVmmg6_92fe6gg<5v0Glb<&2#Y%Bnc zJPpM-zN&xM8aa~nlUOY2g;aeNiY+75?YM4N*P5Ii+a-TZOokNURU>kuXcwE4y1-Ub z|7CKHDlwyC!g#70Fhax&0|UG=KBI>SThdjj+nh6g$cn({?I$$BJ{&xzq_xesOrkar zi6u`PCpI=KDQ~o6u$C=7{Tq1g?Kc=J=Q&&$V}ugZM3lv%+Nkz1U)483#IcRI zS2eMo&BE3V&qV{Yv7t5j!V94FJqgm^+@|mOL8=#u2C3fE^%QCi-9#obF0RMZsRL=i z*3wt8eN3!?HW6xmi!vkP%4%Dz++3v(8)^3{jHNx~iB0m9^7AZL@qB<(n#fOE+nf#3 z4h%Mv<&*37aMjB7xM`PT6Qk@KKf&7*gX|9{m=U0w2A*qCj(q$;N+9~=)uz^DJ)8ZN z`p@-iprt$)8zR0ZLHe6b3!LrFCLU)3P+ew7#udbVSyP8_;?4RkKIiH0vkS;bbxJaK@cdt|o6cLJGm0>E^HgUgn461=9)>8nQ2&&8XxsT*^N$pTA z!uUzzkSeFt_sLk6O2`PgS{q$$b#*M;6yGZBC$nIDN*Ii)Sug{<9J{+3q{=B@oV&XS zkS1p!F{$)wZX?6L>AQ;G>fV5puaGh=4A-WTbvPIld1G>rH%5+f&>vxjK*g%^*{ej9 zfSQzZ=FDkHK$?)}^|fwJsx7>*gs`9)NAuN5wH0rW8Mbk$lwevh>B1NG!at({0$CHv z6_dD6GM8b5bZHo}=3{`#f~&^h%!g13pccv?+z3zVg~;oqb|{(80N?ZCeo3*)2DV|T zMV*nc^@Oa*rs;HS(qdgCQyO=CD7Raza#M*TNnNQJ*zhSDFea9CV1Sn=bWG}-);R@f zGjTyDj!+=|-0D5t(y@W=N<><8gXFqc2BTq>$yCHxCgRt_hk0%MIOUYZbgjgABr$8C zwQ`%LMI@VFqR5c^KS{35UL&UvQBqz>LJOP=Qq4FLZ>D0J3@cjTHg-0FG-yg3or0cD&>GULhD zNyMw?lWHNdq7gBM$xj9j@$!ToB781Es<*F(Fqy=aSztS9zQ_H-$^ZZ$07*naRIq9f zw{~n`MJXaz)9!3!o0J@}?lp?tX^w_PCNma?^J5$y8RE#q2$R$(;88_tt=hVZN1}k6 z3}0$a=+^5q2{=!Eel@RWnGFKFVge zG=p>kOAisA$WuyXsTt-hOWNysO5^DJfBhAF$?k@F!K&lQ?lH&RZFa94Al1(okY*wQ zX^PLUzKYx0H?XQ~D3D5)T2%Y|oXdz;V#Q_KXy3e!ePcr$96rI=)FhMDB1fmk7%WUN zT$~_}Pl13Ufr?!Pu+q~hpgo(1oS%$b+=>;`0xyqgff7bYPF#ajENN}eR(3VJyS7af zmtdBaCB3-G3@7iXD(#|HR&00Trz96$rGgA8!pCJwm0xY#5^=XAPMi#3I3F-pDKS*c zGwIiusFo>s9yO(AXA#Jv#L#i6DRekf55JAIb4-!<5Ri#>j>NX|<%gJ+8kr!XLzF+F zkUOrtj6N4Sl`^az|7PXHQ#4sVw4k;qYM|O7^xPS3@S`g zA+G=%Dnf+PI!d^}aZ~u*`f*}#6VktGRRgwQ^6{=6Jh1U{`o=4CR%4JFQWnx6t?t>% zWxpo``?yZ3MlI^i=7NHBRu{}gO$(fr1JzccPAX`24CgS0l#HXUc#3=Fg<>@$GLEHS zF%iMO$s)&RW*D29q2T)z0-vg6B*jV!z%5(t$e|)97z9yVT2aP0ib0iFsz!N3K&zUQ z&4^SG&|dTDta{va#g(jcWfC?-RUa#36UDGK*UXGeE(Q7@eHqcs|cSxyV!)Q1*QS!&KlDKiDs*S zRdL`N<@bjCPDB`lDiLJa7BW4|5W%akhE=Q4QT6Gmc-(*WRcvrj(vwsYwnVJ=6US*u zy;MbqF~L0nsUkBRY=AU$W@mRhD-{LO$G-lT_``!3e(fB9)K(z9r9(h!(oxmPBXRd< zG8O|VkM=vSXZvSA4%;_ExeOCU7|C<+2TzedbexGJ$FaOXCDNvgd5V!o-UukBOh!sG z3{OokUdmGw>+DyU@k$h^QWin%*jJMK+nD>(kkDO&!JXDd?pb#!oBb5os;_qI21ucD z%~p0dCyqpsFxJbykd{<7uOCXQnt)VV)h=F;He6b5zmm@Vcw#_(h-?hdqy}Od%vcdc zg$Gl89hsV7C|_WBdWPwmPr;NfeNDFZBSQgMmt1s0DM|I#`zj?VR3H5wDVkqhrcrtr z<7}-d6NBU!k&o+p$_48!``ml^)oip=q~#n-Rj3y0?1sRKu)5m8m0m}2sV$<&RF-71 zmQ+A`;F+iDAjPYm7Nm(q)mdfP5n`v)09)pYhLYX2_#LsNo$KkZ*>#YLJ1U8zfs{|~ z?i<+jxsSunO~S(0u1GC}qsN(iYd@o}?`LZ70Of%}%$W*Z=^Qe3{`knSBIzqtdNX2h zYMg>!Wu{spAJ&+Xtajv4u9d09<0z!_MmB1>!qr-l61>#F1Fi7D&&hg^gXyWK=Qfo z3wcttn#wq?Cc+Gzqr#Pswe?LoxV>3*(VxqYkyb4xJq zF-w|UA)P)*vZ-~#K}^T{u`&PJ}fErY1Q&GR|LEXdSQSbBgt};MhY>OWNJj7V_4HE97u5g9hKCqDae|SNVPcv8VH7r%LoyB0hP=b!@RRtny9lQiYz54ytBItusTkx|7w{?qcg5H^GWFwazWK zEe0tR2pKaB?e3~NX(o|;2haxa6TOpXjexuk~!h4SU=pM!w37t!aN^wk1BbNP*IHM8{j7EYl`M>@l_ zS79P!knhQ`}!Y z&KRVtui%!>b*!#X2dOOYk{NL{hXU#5FMbL(_d$CG<(|l9DsH=KAeZYZH_n04DHxrG z!y^=4-bXMv$@tL|c$0amqf@xm0NV>lVX9Gvs=d#YjaN3{xa6gd9T8d~u8=Njs05Xz zSX^3!Of0DaX&Oq`ZPFl>?5-s1WR%5n1nGOH>Dv%vryi0Rl?7b3pk%wM+VW?VS zN)kg=*?C=%#bHRfLrN-UEW8}5o!BsZY$3kO3{2n06`+PvW(X+^4s&eZeqR5@FFCw# zAO1{%XlfcN745?Lfts1=*d~GR)k`vA=o1989fY(;usSqZ5B%HRx3PmP{Q}aN8fM8? zB=ll;mcsfTQaA5r<0n518&^RlO=x8lc_Oi-OA1mMeiX&-u4H#R*EU&FVL`#94M*Cb z^P@MhT|g=xKwDN@(jLt3I&W}k>cnW2Y&f$ z4*&9HrjHLYIW!o%v9YfmX(o@vtyJp69Nn=ae`O){+Eos!2B~l5tS*;3M zOLy)(P~l4_EC#uRivCrBLJ{&+q65ds9~tD>z5`4iJ3*=%Vw9>x<*Fizq`Z(+Xef`z z4GmICK~Q8-i(_A0 zAf3zI)EyG4`%~@E5uTJ)EQ6tv$KK%~_D_y8VusAPHU&rGP74cL0aF%?Daz)ugG)cB zN;Cz8ZiFT7SUyi}e4O!j-r@M$Z}ZNpuQIiFKg^VIWAUvfJq86zbuI!_MbOu^84c1H z2=R}y(1pApApJjf-p=kI!@8P|NiEw^qzQ?W1*F;gZ)Tg63RZSOCIhyv-7YOiWzlMP zzX4LQq!N=xbXEnV(ul4>dNgMsAl(|fyJ1^aS8@_6iMmEg_My(9SNVXXbe0TFirH4; z0!oJ5s(83gJ4_W}d;+Em>MIA3v{$e8#_cUQ*3EHOw`LZz`O)ZN`=%*4e5(!|lN^ZXR+M=^d>c|>RT zCH;S(SmNO11ji?*7%mm@GHJ@TP1V-Pp~z60=n9zfWyh|p%G5>yY1^bWGtKa!LyR1J zho3(FIF(~ZVRST(H3PL+6VgH*j7oJN2C2ALazgJ4q&COfZ4J`jjX|1CtKmY+52V2? zODZ7k{>b~;EFj(5uRH*uQ6^kq#du0GeQ`J1ydag^Ef-pv#TDl`X*i9ibt~$X4l$^C zAoE~`#}qijVwtF1qcWW*ELHJKRlI7AVx>e`q&wHHX8ko+klwjPd0*NCVTl#&=buli z$P5WcFCH?3cDM9SETN6W7rHPl-6@I@BpoWij|L8Nw3uh6T%qLqIPL8UoPPWz99xm0 zly)&&N-6Rj6@Nyg{E*uCBzu4LD}Mdc7a2Zu5XY-h9UD=s8CSGfJ&7yDbJgdhNoui` zNR$|2v!N6ZRF3^@ENL@HKcy|H0;$eiFAqy9G3i`Oin642kZ$Q$F=+#&+H27ujU{W6 z?w7fiG_f!$P@L5oqe&L3K_FCpxN^LDIU{jiRJtIRcf}4yS87A0S_Hn zAG+AIv|}a~0n#H!2BLNAB*)nNSdO$neM1xOywp9V+e27%1G|yG9y}BgH8G=-@owA`w?e;{wP3~hiYq#-2f;9F+WmD7ct{cas z2}lFdfu;pc*-ao7+MQTZad(?sI%N@02hv2{LcMPcP95m0YoEmV%CI)iGi|DGC)!bs z%ioBw72u^Vs&`v814fzy~6s0#Z} zjIeKPjB(eYY{z-@L~>nI-?cKGlu>Mpv}mk)6?$Ehp@Rqb)$`Bu){DPj>Wu@CFGH=S zxVCmE>gNGM#*@XNdLESPk%71X6K#+XSSt*oAd; zp)6^9`gSBSX*36s&u2jbU+-bSX4?h%Mzpq4;_d$ZQQi1Kw8(lX-XvM6O7#%QJiZ!IEU@Gv8L8`hsgNW`-2FI^Z85?GD;2qxl`HTGO`4h#<38axN-8f6^?k)tHN1nJF+{ z_VAoEo@uM>sN!lWPG^7-Q~jJ!YLo#zjzf8TjG+Vj_|dn%!ST1=gy9jaR8~>SqMCYGf$AwEk>Dj+@HX4BCO(p;KInxdB_NSiIG zsbkV}4AR7kCb|ufs6@3f_;?vdW2iUwpN6j2mZo>x6~byLxPJ&p0MkWCq)2u-&Hf-kY^WTHOULkj?_B z3WDP1hhz~aiMzxdu1_3D(iEpq#7`KDOJ_yn5N=MLR6zQ@M<3;(2Os44@#D)2r1kW9 zoJo`WhrW(v{(pPL1Gle>l6zpH&Mv# zktm2wF#fAw@ZA)TaLMBy(FY{mgT7&nrkB9g}t?AnntMBNdaz zk}XTdI9gOpdj8$r#F8d}(y5BsWPn+~tv~kb5 zC9PpeKdWg{bZiFOY`X8gnN4Cz-{T;aI6H|o>!UZ+FPi=kySwKLqzdy(YD(vEcb79r z)%|GBaw$Tz&a_EAR0s>BVU5=YCpk1-;DmJQi?EdAD7v2%L}hS;@QH*GD(9h$XE_-=q*0{Apf2ew?>Q zD@++KW!Iu&2@zeAL>i>xCP_b`8~8Y-0xN8jgFk22%|vaGAxstd+8gzRlmh~3@Z`)*~O zh&cCkDusjhVhN@N(%IH)R!q9Qvb#;bu3~~1iUlI|(6KONpfthHq&+D}Q+6_x9X-}S zIG5rSE5f{J3>hJgsPXw8m1D>FhcEvL#RCVRP*DAaM%5$oByX(KeVX(jWzQyc-o#&u zHCV;%RcZh_bD`_Dv50jtCr$lMeKi!{XSFxPmRhz30cj5)I*tGClH0g6%F$mjNf$j_ z!@{=&q?XF=_TGCdYn3I{AQg#-CFky*=fqJnNR>uZ^WHWmCY|lK#59$rr874ux#->9 zjvJOfPj&k)IG&QQ-5lBS(3Aa0EBotzyuMEo$dlpi1Zk(&#J6qKs`K?I?b$MT~$yTPyW)K|4IQM7GQQ%^s6)k zm9$D0i!?SarsjVtK1?FLtp^K>ev;@Hd0v?=U^6K`d&$jg@>8s+Kvw8=SV|SY;7Uwt zvGQZLu_m#kZ7Ib?RvGB1t(TS@1r7Wecqa$;iZuYh6+_&JFBEl zspPX|72rooFpc#IeR(jD4#D*n3 z;m=0n=wh;@=NmdpclU$M(mVsNVlJR}U4!px-|M*XgKJ~2b1XoSLwOH$>i7qC7V-rY|8>6gd(kg?v#z6LJK9S=ZY`*nZ1k*AQL&RTi5^}Qk;l5JFwZ9 z?O{)MKilk1w%Z-_lcLMl`nyUWM>4k}?%dQosj|SyczG4pCJ8G2c_k~Y8TEeb?s;MEu=Rhs61=8gKQt5(u^brB+LmH%e_r4Wv-@bjG z@Ow#V7x4m>MQadLL;RG(kP-0aa-xo2^OX3Q#G7Jq#U)l!lJR~ZZf}FdBqaS|gLn%SPey_@lM-H;DSR`+|cu@*Z;?YQhR40r)T(3fV6mj&` z*ZB40Kjxk9{}8+8D_Il)sC2;uMnIt4V=acH7)G&jof=mdFA!x##jTatGt}b{v!a@;`W`lS@4=Zn@$GqDD)?u-(uql`!tZ$RtRDmfQ5 z2ugS0xI!gX+1&)BH?dtbj`}(YvT5nGQvIxF0@A%tKEZeY;!lZ2PAoW|w0SWuWp=j( zQhnt`h-?{yRFlG@$Y92RSEnZV_1F*tG8fcz2?U@r2Spg>$}bFXLXS+fLc3Svl_#I( z@xTB7;KVQ~v2L-(t$|QzAQ=+Ud{!&j=2K3t9LiouieVVOebw) zMf#?+0=<}68OJB!l-EnSR_WPcGl83+YWf&c7f%N>C#Iro= zA}r}!Z@&@kxMasNaCa5zRA^QWV8VoFj~?cg@eyWHDK!p4Wp$OS8xQA=d@_N@8rx>_ zt+)B_U-~i=`wtKnWgd&r{gU=t+Qkb4Cdx&^_B3Hpl07*naREnB!>Fb5}^pQjC%}C43!#X;TNy& zCc9B&F*6h@6&xu;DUe1=nsP*j2p>Fj+JQ|6pMQpL|H&W1_(%(+=Lcr4L+Opcv$(swIybe1@KS1(%xNZ)wlwdm4IFI_eum9h6yQh0N6hUX3+WWup2 z+FBOH4m8nDM&Aj0sDqG>T9vn+dWuKB{xyuLX&kRctz3%Nyav87hZ=6Kc6YV=+h~mv zhLB`*dm^}}dz%92ZljalLP&c}n#My)jvj0)z!ZQwl>pat6exs8Jd-k*Ov8qouA=Lz z9dO-l*suz6Hl!`p8W%_w*b|U~Ww}_Ug`u-pT9Zde4k8~aB^-G(v9xZi*A$m;+cZHrMdhsGa`ugjyM!RlTJ~#9L0`x z154$76cw;qqC*rFMuz$3SN@!_mwu^uyD~H>5RR@Ye`sscAh~ORianOhumT*Kppf$Q z*oUoT`0edCa;4G5nvzLZB~rp{XQ&aQ4X+4^8{0(D4U7FfsD`uudgMmCO$q3fp^)nFMBI$EJZ=Z>|A zumwv@}zy39X*WZAwt2nhXNy+#X%w4oK_vGUnK>kRw0u8SrhmH9REgLH~wT1FpUSW7zXm>kKX z)dIgDLxk7NBaVGC!M;_3(J(xz1oP^vFGss~?_M?_6(zu5&E$Fh@F9+e9_4g8&g@#G zd{ZTXJgTh7rm+Tx`SxG_6^9>v6lxU}+sTN4P(+$#1mQd&m8GtdxTdI<>y_UnQ_gB| zWxA6Ot=Y*fnRWE#p{*7v4z3Ih7EFm16{U0ehi&0I7Wu4=vAv(Qw_k_xf$L$*YCQ^D zSVk(t+*Fp4K31iUu47qc6%{_4`m9W-n!1kbD(#qv(ABCG@`==|RC9Z5NexM|!3zUN zd3j=zQaY`a{V$}uDU}-jkNTRPEKkvd;OxEY)MsYnh@R%q3=O& z1nmL5-(AHgwqMK6N}AphxN4x2CO;%44@Ej4VmkB**L0KFv4Q>%+z7W_2isOdc?#On zir^>_v}PS>8z=xzdRUcE+B}w2ULqsq6<0X!Ne^Q&Y_0FG{6RXCvN)PSgH)JO+t;=% z=_!G_2#~(~%1hA|mtV1@mb6a6YogI6%77z5#IuJFvbUJ$L>N%ZWEDt--P(tMuvO)F6I60>sVVb z$yIfns7VOgYH6Svgs#nim&dvG60ZE6kHfb0uznS!q>LkUCDHwjGr#pK8&_sy!h?pJ ze$3W&N+^nr;X~qTC*wMmEtQ(lX)LMq+NxS|JfF0)QeohQXZiLY{U?|jQx;w}yZU3! zeA4<1o8%mu6!#>Y$f_|DX+GO`xf&w8svOMfC(WmAj-;anK&rijc;C^<>=rF>es_1N zLE7ZlHAJZ6#V_97NEoTC?%VkphN4h`)Keg}NPEKT^f8PoRx!^D|M(4Fd*pj?Vn`*7 zv@;p1nx_V-zUwEe{GrCR%hc{R#mhChA-jhAR$RiBRyVzc2uFFU(o`;`m3U5wlsqhh zDJvv%#a33_eFJTG+^A=?ID&ksj@TGt`Ri8lnf}GEU~EFUr2;&a5Hf^IdwP&sF-V1*+Yfwn z)n(k%yOm9~6geR-$Rxekbr!{Rse_7Dok|-N*LJb#o?FP>eG_b1qvv0UOX>7?LD~#fwGBz)NR57!OmGsD9^>W7aY`vYX5&IyQUU4VbVS>oH|WNI7D!JM zl`cbfcOgqU97a4P1C(Z_851Rgbe6zyutHO*7Ni0nml{KR-{c>^^d}$#mI_7eKvE@o z_<#m!!=aqdk_t%OFr+hr-Q>7u{Vs0F_OsDXV;5^`PKba>Tv4f^iV{T8f#EiT{(Enx z_x5XG&kk)xMfJfEITziAmKFh()5r&$DM%A5t8Hx3MRQ?6x_yqj+fkK@d%3Sr~B(4uG7Chd;k{ppo_`jTt8teU2;YGGC+X45X1 zfHW1FOxG$*WDGJlT*~^-e*~`HrpG?mI#?CUUA46?Q%V>??_rSUnqtyhJJzzQ5}-gT z8b`93wLp5>eD3T&UL=-OK$=YI-d8B_{R8_rYD5%WY4VnAjE(CXw0Qwp-@~68rx~G>10vUxsVPQVFpQ~xR5SR-H-e3EvaTC&vti@ z^YY|q?Cy%Z%=t?k2}qSCUEN3=btFP$Es&l8K;@|y2}nh6PtP_n**i1Cx8Hu9v2>bp zDx)T)8IhwTM%rpZsQ0Li4)XV3{xTDhve+QdppwF|g$^v*O+X8lzbYwFeRPe9b#OD9?({SfC1UZp!(KSz3(vo6L zrH(57q(bF8&4kN$2hv#CLDfQ=W6~I;GCj@^kjlwRMm*qLXLnm5JwqIx_UR{sRFoOM z``z!VrthJ_L5!tN9BE>^b|ZD^!Jrlf+LBr}d#9)Q&i*$T&t#}L8GJ*MMmBB`k@I{- zsGr=ok8gbSt4!?M2jio-qT+{75Q9_?nLRy7l>#6ks{;7#6+5}7cMF^IuqJddD>ZeF zMaNV?ltfLbw+;K|-Sq#5&%?$pY8ib5OL)AJPHu1~gp_+)kj|B)oNaSwXLp{Ji@8=zx_B7R57LJpeprn@93CFJ zFd&s?ZLOfGV>oF&tAr6%!{F`dDZcm4+e`{b%`}1GVuU7c7?JgBbku4L{N!gm{I`Ec z>G*M?nF$e8QM1>yFqu{xRO9aEvu3d+l{%rotS^M$UAddPyEd{V551uSm8zRt?`<*Xlb6z{c1q&~{2Ksp$~3x|&K z%ESo8behmkoi~t*=F==oI!{bmXo2($?*9BjWdHK*Z!3_Fj*eUikP2l^Q)#43p<^qP za->1}*3=Z=k3m{9G8&|ji5rAuf~o@P{wJQ{(f{&asSFPh6=!hc0f{w9!zz&KnJ^21 zRASP;NQ3mA?#*nSiRhAcxN1eoEC@)a(k3(QY3wVvvEkDnB7MjER3;ZIChsSiux8_} zx^B+)adMqhU#wGu^h7BAq(^vVQiC*d(lJO4mCWg^lo@#8xpP8h5Rf)o(&ofbDoGsW zTn?o|a(CXqwpMm`frT)?r02K)`JdJ3!}0O)#t3UN2xO}??sj`+yGirPv66(;h0BM{!3IaOI2}u9*yJj2-NZXN~ zTVWhs!7UwYSXuT}cDEU%2c-ma*9~m@`~z^w258S}c4Yj}A{i~l(R_&`p~QXro8MF* zot&Iljv$@pher-DYT62t-k8B~&ufFwNp8W6s1k+QPl@gA0m>RwsIiZL? zNi+7mF0bb9>d}ay(lGjT|K;4(vx%K~lRjxVDHRp|N{-2R#$sws7nlC)k7D0;HLPC= zxm*)So2!_yZ@R=FJs!aG?+ozT^qA@z!p+9nU4yg&sn7z&k_t%2Rd>$W(gNoL>58Jq ztn6+s#i4XaZXS>(4o3^5$#ylrCH>YnzNvI~CnuH(NULE;4N20NNS*YtL;D%RMBH5g zsnASQMnr}x?(`Ht`^SIgr{DS)j6#8^Tu_!Y#8(P~iE(SVyK}8+1ElFNQd&m0r2F~Q zwyU|Kk zclU4&p53>P{k0-_$BErtv7~cB`iDxHK@=3<4M;mN8kV$k4ZVfhEK6EyOL1@>kR~(i zl=yhdlE!y-{+RTizwr&FySqF=nlJMBz&l8sr9f(EOX?aSS)+zMInJ~H?H~B{!;dPy zF0s3NYLK2B5(o!ghz!zECPR~M$n^1vEmv}NCCdh>lNL&<_A2Cr;haU`%1vDM`A@(t zR}tl0jFe1(IYrE?gYB~oNM|*G&pJp`caLh!F@#@*8fbN(81USIy&S=3#<2-Z$?obM zOP65E3_Sll-~J;3={SV7a|Y5|JJ--XBe{aa-Gy>{W;RH-uZNCYy(hLl#k=M1&RZvy z63jn;Q!ME+2I&(=4sp~AshW~FaxnamlnFV@BN`pyhhO_U_I>X$rA}|wD)YFzNyfE_ zwl3mhl8ucO>c!m^;cMaUUg@sj{;gMWZ6(9Tib=LyQ(ZCwQc;i(-oKk|pS=%m*oBw2 zaGYk4#-qra5p~`{s^_>V3Z4OPO_lk{p?5eT`btt?mgaz1^T{o~@Vp0WC$uDTB(-ugZ7t8!5m%jDj9Tp!bXZH+oqaoW_@4}n|}LVxPBLY z%F;uKo3qEs{LH#*dVVaa?#t2bsnXLPnl>Ug^XhnkpB_HMaLS_Sy3_)pDe5v%+V|1A zyHE3-FaHUQORHM5B~AKW8w=-jt!l#m>cL%`^3wZDUJ}yVKcqsy)Fh>-Yp341-#zU+=UDjHvgKHpvC%GSTNGB-K?n{)W(v6-+wkahzsLH! z?^7UkQj*5$2Wg=JttvC(pLG0={V!!AcqtmPJ66UZm6FvpHkJV8XCI9NKJh+a;%J~UE^%eP=e{JVZX!Im5$uiYHP|!m z-Qy@Yx@?ZyRo#8_L0T}`H1kG*)P?QXXfeaMcl8>qOk~jHhS<~)5yxa(UBE~pvwaH| z{r<05bJx8w}0V4P`*g75zne5z-#F|ijT*66%#SjF2U#=JDia_Y+!qt z31{8`nELVaf#VL9I!X?kK=nfV6Zi3;x8mMDkNqK%lq|$V&OzD zoL4moGpuq%Sqs>qHp9A6209I3bE$#ychASPPrV-)I|8UG>la9QWtA5^xGley4es!_ zN7@ zl*Z8-iy>i{a9GMg-aIS(XE4mR@zPy)GN3Kq*eEnS?XT#-ToK zpxki~awyrAB+W#^0@8|i&&Nc9bY!)tyXl%rq--N<}@6s~Lw0b_it|M+$zmMNQZTj>klLcTbvwY-Q9V&=+9&=7E%n z=O$X5EOKT9J8cIm8yfM%aMqdAY-x0KUv9CKeH&wWrSe=>b>{jk>C8*11VcZ z>H35Hut|Lm>spwYg9@BAVj512k49}<8kMYs=%|kCtYndmMy1A4)p^HZ+$Y};3@h&) zq+Tggsi@(ZA^Wo=WwpRt$vFDK53x^yRIU3qIuOFkjcs^oMup-EY z=?%9a2?jzc&LU=KP}0(hCvUz5FaPs4puG*Cx+~TA`)QNvoFc=(2!|kz;Y0O@<6V&& zls6|)5wfHz22~7tcatGYY|;Zh_kNU|cM4EjrWi+F%SLUJ`fV{1#3Y$$2&7Us`nFqd z#See^thNcrD?g114T?PvONaJFq5^LMB=wT->yqMgr}KCp+={b$`XO+wXzN zBG{=;xVc2WB7K3(;PDN7>@y9kd}R|4%n{Q-dB(*I#BuDf@i?ZY9`%_phNtPSvXH2& z!uSuI37mT*FkzVFkQM_e|0-+49#MBSH%DJdIrCDcfz5VSdgZ*)(1_(*cOVf_$q39C zV)+(jL>545?c9lnZu$e(J@7C>$s}^A4j57^$}>27bsQB|J3iJZ$HJ+hQ8;((4ADMH zTazfWELg5Bv1Nj^!!)q9B7_-V{2;7%p8yQ25L=$U2T7#Y&LjVIS%}QnQDA?Tq`6E6 zx88aye*EJf?|UHSbm)YEO%CwfhHZGgr45}djBSOHb~8vC9VkyGu=FlL6TQJ+v{Tbj!v7<2wf zi2V1lFlJ56TXT9MQQg(^U2z-+@7?tZq$p&{&1z4(`pJ;XCIBm1Tk*=~t=OKq~ z5mTHPVr@y3va6h{`tz`*BfYyVb>*1y#SZ}|9S+phNUID2lt9gc)YoX4eX$Cp@pYdNJJmE%>KZ6Z+o)qvvYG>N zeC8axD77<4tXYdcFSs1;>no)D zIrRgAlznGJn&!dc!P4tGrxrUV(W@#k3|&q5zeV&@wTIyN^0BCAHK+C@N-PCZs;_Cw zKwHE>TYU`<_`(N)W9F(lP$30UuZV@JE8GJ}cPG*Bo#5T=rtZEKAPuYtd8VpViHCtE z#`Ri~cy|3}Y-sO*RauF&X(MAK5zD2p`N?PS$hE%)8k&G)3dj+p4AB&9QooYu7YO;3 zFTJmqU&;x{wuht%&O#YZte%WhYo}mbv4h?8BI3fgE6i{x*0f%Xt&Y@XY&73*8u(CHdTha*TBv{lJKQq!BH z0xOq>mFz@)ycCcB{qIv*LJ@CRmavZ(wJch4mFCPPy#c02^0Tm5T|$_p5=*^U`VO z&xBz`#-NfPoGX3(`<(#Nu8yM?7>gG_=^lCHk#DLb?QNi$Q`!PxL(0X=TO08D&Rs~d ziExPS{S+d(G@4#pj=Qe87Fe@c_3@-6b$bD+FU}{j!KX_V$lmI%N~I1jD+pHMwCZV? zS2qb^*Fv*lW9qplVmL!FqsxI3b|hD2T8w<-CGW|4u}Q`DE~?A17%2;OyD-_`P}f*7 zEu_K*S}kB(4p`sOftS{ALI*6Vugk9CY0E^G($?#9YS}hQ92?O@C!%d_`1fyqgN@HW z541K(u56gawsTnlqtZ0GDw!IjbOz~LB}hqPI3hX{pBOm{)16WYQ?X(OsS}C~Wk_ea zZ50+;#@FE3AAA{@K2iFrN@|~1z=HQ#45WSl_XWnDzJDixRC9Of-EC%9hJ6jBS;IgF zfL&~V*qFi#8#bcJQ1ym#p)_KQ@ojIwpD(=vsiiA{W>RkDNRSh!YtI{@KIARbL?cawRd9Vfm3kk=RXF_84pxOC9Wg&eGN;OlTvZoUJR<9 zLCWwLt3^)-eRJza6Z6+iugtNc|BZ`wpOu+?JQ&Hb(Ai^9{ zuf7JKi{NXG8rWQBpyY@dIQVOy0>;+?v8V#6Dw?6Xqf?Sf5elzylP6^d%hbwiH3buT zusDCykL#Vx&J)+MBOZE(iz5om{d0w z(P$L2&pZ)zO#U8KrO;@4)sonL!gGo!$QIvv2dR>1l&CqwM4E-h02z-pi45M@x)mE5 zTab&!kufaUhrr~d=f^gciW*8Kr3qDX^JYAC*Iiip$iqNevxHudO$#s>2GN}+x~RJ{ zc*+UH=is7MSrSGhnH3Vl+2anz3DME0>u{ww9NAl>GV<9orXj_{H}VLzBQ0*xHLLCWa5B`S&(huaPgFyBnw2_dxoeg^#<(%s*zI0jW|SRgcm)5~{$~ zde-1IvdBepC^2%V=tyGG&Huu4H{Ss?>=fgMa>ueMdsL64eA%HQE2}?(;+M2~67eK4 z7^rr_7-7axAFaaV+EJKZKLO(oISB9i_ywq#H$&-cIn~yJUQH#*)WjC2h`0HRa~A_C z?O7^|LY((10MdcRz)~w6MJ>(Pu&WV`ok?lAk#cE&vP!)wDXP>&1r#!Wtj-RM2!-&< zLl0rm9k-)(?P?&|A!dQpGqedpwR8nlUMUbKHmQ>8lH_dyWe#w3s1|3|AB;JuLTysT zmlZ)?MAO}o%&WRaq} z3ma9PDXe(p2|W6Tn~~bEQ9=!-oAp5IN`{E6%HE`)!1J%H#gbP1-!n`=>R>5MR3MBp z*TgV0j>)6Opnl3kob|bnn`CyP}(8?dFl9lJUba7~7znDY~Y!}?GR_2eTpggL8CqCyIAN`bAkOB2AN4I8l&8MM2dh#4+wl3BFBz8ZJ^>IQ6k{dKt6gh&aC&LhX^ znndCObs!++V2ERb)$3s*W<`**(0ON zrjEDtsLn6~e?*)tDx54{y#IbY^7}smT*Sn-%)+s3mBFK{DY90um%^t>_2NkLyt}+@ zK1&?HyGp8YZrwpRJU$9l%^8$uS^xC0wA9cVGqFzhTU zlR3ni+i~-iKgar)UV@Ws1#)Sry=#y|ng@u-*$pf~lv@6+tKnWKt1VK6_GxuBTAEvs zhKtH*6!EfhoO#w+_`-!3V&=TL61yZo8LHs^oRaxW4o-SMNIfCuBjt&T%cA*-R2J<{ z4lA2>U|TkcO`RRsnMorZ4guj9!d46hD^;)>q8AjFgaLAxsh+wj>!oAWDm-?}Kd|Qh z2PAEdiSdk^<}B6JSi(hlADilg?guH=T}woy3cHMhiDRn9;k4?BI5=E`csn`4x@;<7 zI}Vbrjchz3y>e>Lo{zETo+LeBvJn&EIJ0*1Z3RR%7D}cUTlK#SWtZ-rMY(%N2PVs# z@Xw&*h;hzun2|8z zDFZ(j8biwc26qn_GI2l?gb=7Di!1YYN=tG2I}g^;@Fc< z!nq&#Z;YQl9c9CY!3aeVvBGe&HX^2l2#X3*P%xt6b!lV1IR8dq(&kLLz^>LLcDA&j zp|u$aIOs5KBq^Eb-POKpmt+9uiiY5tB+)B%lx1MZ_%X6+Ni@i8-ipP4_#4(d^)wRA zjR-R#K9h#Y3>6(qChtQAp}Wsp2UDcPjO${!4IGX#oHKd`j;b7k>JA&R3`0d6r9xBW z=41k>DMRDvGEDsZ1t>dqHc(v-gu_52sq(s9P>&UWFgr{2Sa+Zvql~ zxkM18qy_%#pZ~&-$lYyiRg!d{11V=PS5ym9n0mwi^=o;4%Qn2;-iS`=hGrttnZov$ zUd3O2_ETWzHXxglObjJSZKd)SF>Lfp3=T}!UA6kCMm9(*q=Uzbg)qE+Easnb3g*tA zkEt_eB3@CASiBqvMPP-(h=d{tk&WYBR2(cW(3x@3mQ0{Ekw9xQfsRZDNjry>Yr|%D zHq%DdVCxNbP}77U>0See>NUd|(&~{ORvV?ZgSg>h%bJyV=FYpY@u7uqb~eH=sruWn zvuPPmTd0C66)Hatd2?AwI)kJG5*Zu^Wrm4~b{MCXjK)c|6L3(Z67kNQ*rLo3l0J5Z ziFj!o+uB-?tcap>+6Wx{-H*eVQ4f@s0#Ttlcpqi76QKN0x~v9S9eGLmc7)sDz#g27 z*;HC2sc?4*(#IZqq?=9pmP%3yxOuC*2_!5Pj(M%U6EAPyip}k9QV7gUXJGAW!fn6# zEjB#)AAotK>|kx%$hk}*SKdpR2f-xfBDKN>3R3dqLZu}bUSE$nN6*KhM;wj%NmG#t zN0BOt!3jqZ3P)jC5y_gN|5;*$j)PP-izI=WO(UJl3h0b*2yV!dFbZ2Y@(EPC46h}J zr!LYmj7xqS$vNGDU01w)Xwx3%qSAobKtnVSk^bl0=m09z@% zx^+8V-MSea(XeYCHzSIHwC6QXDSZBQJa4c0 z{>byY;V`VyQW&Li9DB;?IP&&t^wIm^na0c6vdh!BpB)#LQhQ!zdpLQU2{IjwD%fLHB7_{q4g zFpb(rSKy!zo{jK%#{e}YKqL%EITzKL+*@+;J!;o&2&DTuNL3g?GFoIFiSH5_+eOl}(3o+sytNrm?c9ns7TKbN+O-3Z{Ozw; z{nXP)Z`_JdMoWpp+t+Gie=G(iEQ>fayfjhmRAP*h)%sW|fzlEoa_3?wnJ@{5oP09I zOg{hA%7 zg{|vWW5x5&;f-gXLt@=}#bHjQrNf*YEz+(KD^{Mcz=tNHdMDq4-_5K{V) z0%)Gd;D0egAl|jjvsn8GY;HH6bTbp-I2zV4Gmb|)-2Tp*dONgr=P?l zx7>o(XO@Wf(_#pLQbbb(z2El~NQF|zsb+?RKkHZwk&vHi0Sq^=g2Bugm^t@Q%$R#9 zDo58L7q(!BO>~+r+QSBH%Y^Be;w9xrIS-W0W(%>M&Kr^mEJR4SPo$7;ZAG@T9WN|i zh%IYZV%zeiKvSdY0%sVA89b+p92+NzB=zeJK7e{6Eblz>sqxfChW}qH#ZxLKW?{0~aVDdx7nYSP z@l_T_s639*lO|%u+_|WqG8q%5O_5qZ?9|3$VosJo)F355H6?+B17#mZY@m75Hf&$B z9;;qmimmI`prfe)nXMavY!b1`3Z!;6$f72$84Y%CAt{7eJdo<(uSdZX_^{WGPzr$x z7nqJX&aa=1Q%lBRL`w!0G?!`Dnu>bJ1%`Gg9Y>w4^*f>rHOI|G%_q+VYD<9XI2g*)H$~z=UyGzoC9)7?*>BN)v0g!4K33=4Zj__g@(o#XK+>9S?%>b|O zY{v42jo6iJLA)%2WzRo{JAeO2IIGqH?HPnAeRK+ymZUyzXirkLH;{V%;=FoDX-a8f zSRrI{OqCM@&-+Q@YY3rO47o%SWh3e^W9BT>&zO#~spEmNQk0dJAr^_jV(inK(44O< zh}_)Ri0vCUqix47Y<*)5+PCjSmONz%r!Yn(z0sxl5*$TR2(CnaTT|P)L~-7dAgT#a zR%CR58pFUCH-z&>9fBiDM`2<*B(^BqaqtG+kPBPlNd_{mBLBBm#bD2yf+-(73plVI z7&A4Oj5@1A_p$@>UMeLxkv&?|23Rc)uN zppBEVfXxYDY2y~W(Xbf_Cyn-&COmQX-FW?;2Y?-|u+o%qN_uD#xpvtGeH8(ds7IT$ zpdM-{7l=Flay{Z&G7Xs0!;}>?ZCK$LLZK*1YO4_*H4JV^4ADpo;cx_|NiMFI{46rx zh)gntOlLyWTy!LWR0haqMKDs$Cpkgxv4^g)<#;rI=XQRr#yUhKpSz;u!v4Ct}q5PE*a5 z%S)7s>s?wB;(Z{^k6|!lMZc6GkiH#2+Ep@;C+{gP+XSwCQ0=Xc}EM`bzUx}-#OJKsob<+S|K=O z=n!OdFi8S5%c78yj}R8zA`L& zZ1te$xQ~ph!C4HXd3BR?K7!Tzh(YH;Y!sBp8+RB;d!9F zQkn!sw?!m>zux{{mX0`YJWg?0ju|c%=0u0%xatX*9UqCBv?&C7dUNS4lK3v$wtDMH zBxwUR67Ej%IH(q~okyIfN#tTUfKA?7$)m;aupvd;D z6q7pV-~6g-aE({apnR+&Ptp)KPhS622B|L2MenpMCgL+w3?#M6_&ACpu9R+}09v?T zE$Isq-y1tG_DY9T*ijiSW6cO=Myheb$SIgtG6I#YS(MwBIIQTr6P8qnq!QL3R^b;r zlS87q6rrPMUY!h%oH<(&a{xrg;Zt#XaIJTroMq10%_M-lT0RX+rMtZC7R5z zuS?PbNLi{xg=bhIgp)sIT2iOCA(h4U)(&jgx&u45ZNW2-Jb))3c@WL3RtX!(rEQlh zNYk#$U@_H6FABxgs)2x1RCT#vP{H%5be^=){ApD0e+aNY^MsfwHI;i~z{I7KeEUkBCffpFBv5Q0lxJGd%{AfHg0s z3LVaw^gRY94vy4fUe##4tE>)V>@bGeA;dBTas>e@^hY7xt3`!1j2i3W7;(~J7)vS2 z-lMdOLnhK;#ViWBI;p^;R}QJWy@K`~22%DLDS%WJ`3NIrTS(g`I#LdHwKQV&#$|Z< zrRQ<$KmLjJFTbLQ21$B5Sf9ie+mM?C)4Od&Vi~;+agnf2x6}Iek)(FdwpORrJYg?1 z;)!`#Cc5Z~-dT0VcwXHt*n3)5n_7*|tK}*!Ojf@+`Nxfn=qr6j%hVsx~&!MOkad)-q{J$0X!q*4UvKbjbXsD9Yo+@I6|0? zN}Moy3XZNAgNZ0XtR;yE3zwP78y=N>QFU>GGaU_~HRPhRGz??*1k`=(bd=6L0A?ji zqcBeFv5P$WTkKKo+!_=__8)-yheyvDI*#6^Anp3LwWKMyloUw$Y0Gw^VdqXPS+WH8 z+MLF_B^wKBo%~CqG1T*fKV-tsvV2Dv_XwBRJ3PMLS_P7 zWEclETtsNUdv$*^Ap>o(5LTyJ5Ib-@roI0(l%97CvLnkBQNcA~>XN1&QQs>SJ}7wZ zuLt=Tb-&|CBMOD;J@Ld7NbPDw zX=N1>Ep4htsc&R-NtL`c>MiDZB7}E&4Jf~~^+y8t2uOo7)dQ&(viW<^@lF-*@SIah zJ)k6vIR;9ZdIlS#QHlfOqi{&gC>$86!Z;&_@|2Bu#zjd^5l3{KiWxd0g<+sGVq!Q6ZmV=g!aIA|=gF|`EHOHK7!Re4lgqWx12?%whe1nI5+{1<+5$xoEJd-pwe zx@Vqo=GzXWd0_g>Kzb@;iqtvUP>zGf#zs8$_~W?cmYea+Q%@t8N+Xv{=Uc)D>m3!d zNd1zozaZ_R#tc-F2HtnxTkElO^a3H8gI0&7B%-=|ER$};3voZSQqkto3N?J}f zq(RA{Rz=ae(hzrV((Z3Z2SNI;fBX}d{^U}$vtiR+cirKhb=FyLOOX13%HK7iKozr6 ztQT&bi3A>h>~Z}5rkim8op&P=iR1(BI^R+=Wb{A;?M&u==D!Q7r$JB^QFr~j^r`L^ z0jXAPb>K$DQAu(K9ELtj16Cv?xu;G?3e^Bc!NL?&;ppL0F}b7)Ih?C=(YA1vR?bR9r=wJcr zpTnZe7zS>-;YM73*#fk&IQAWP{M$X}oO6O}cNgyG?p*xMI#x-}?h~96vZJFDRh5-! zX>G+5RDEy08P6Y*Fv%^!wDMs%uzD2Y%w%Ew(^V;a z%xWPkh@Nt)%an?&qM8#G7f6LIbPg*;?C66r>FncS95h)0RQhNb5)*YT#miOO5I}c# zo(CoA4cFg*D;He;&H|~dMm?yZ4$G7<3=s-Ry`SaFmf?>#+=R#Pdk{?x4QOMJQ_tl= zsX{V2TSvGagC-v!q20#3N*`@6FSUKsHE-woil9knKwp^>?P$q!lcgu9T2uYxhOVly zSFM4?x1|LH+Xk!Os}VtMs2pR>5}Z725+)jP)F6y1BZN|VU`1Vbg&xUpjIIVjshFl6 z8gh|}80d%?=!}O^f5PDycJ|T0%t>%+%8)ipM02L9v&7009${j4C+E=dg%Qv|<@~wv z`WtY?g3HlPNqWmIe|O*azW2TDC26sjt-~c!=h@?-N>6UXz{^iRiwFOG7nVHvG&ZkT zg^spnk)gH~LWA9jPRo@dXf{dZ;$2mh60Dqy5OY;kj3eJ-KA)Q9OTO;HMOqOU zl(hA#==0>ZEs5sr#li9|EOC-!9MsJs8MBb7t3cKKSr~r8JYd!&xFaj1_Az_bNtFng zLRKhF1Q~+do)`fx%mk@O(x&|gq#QiyCQ6CMJkO34Hm+EW=O29nuPuBUt6y1$bVsKo zH7{@4h&JTV0SB2d>-Z=V1>=yGO^_-|p61pn`kWU9Q5Wi(b>lJk@+yrdg+#HX#P-tC z2+{&UL6;iwJhq;S%PO|CJBQQmv??&lD#47}(HI*oM_nY2+Khp^q=^!nLZbeY(hA;{-jEz>HzOn{mODZtFqzV-|1996xNzz6|MwMQXtQDrM zvV#omP_LK+FG#|CN7z71iHVl#D6Gk&F!8v*tUEXq8S@IckROZ<_2u&*oh`&(1r{; zkwp@=bivTo2mBx!jnJ;5cqNEO<*Xw#%-b-yss6f@8e zH!<~`6Hq?q07Pa_0ftuqG<-^H>O&wfy64#dV5J>klGz;e=NN>3AdQo@xUr9;_ zkjIx5w6!IqfLYth4OqK)2^wBl1~ZXCBAZ61ox!?>E$DDE*xuHJ?WtC5MJJM~cnN!z zi87cKUNOsDvT>7}FTxcpv=CzX5mObtmhNQ)si(^FCqb!f%^0deF;o~KOsF0%fE-a) zflAxLuv`dbSwn17*2yiknV_v|6?y5_5(A}8P2nkRF=S@7Rd9!uArVnU-*|tl+Mrq_diHlnJ)h?0zB6^Ly$8O5ocV_9uJdft7UekFU({VC z6uhhq52R8>G?N87(?EL?XzIkK2Nt1y^=9nYxEY!DPPmMrlAvG$&2|#Y8@Hg%$)F>Z zL@JlT&bCG*kwK1?6r?-1E#TEQXyG>n$gngpG!cOz(vqrdsS!qbv=nhGjEYbM72z0$ zm6W3s1QP?EQ<8V zN>t67in=3a!#sF0Fnv4_w~(}4xpykHQCM9;>V;`o<48EdeWafaWI_(@+jRu!qqzRM z>u~kuSD>wFKLV+C(&WpWNb3e&pjjE2Ica5|19r5bbLm<%yu1QiUVIJau69@*DPi*@ zQ%RK6R-hxBMlzj3GMhn1x>Eql-_wSJt!+(W$K?y36jUR{uY@YAtwJ#LHtF)6v|$+^&DXwWsS}2d7&mnkSlLgf zEo{ITJsjbw;}AdO0F)m*1(-1fsEPw6Y=F#CEvo8Z$h6csbww81;@UQ)B-QeI2&j8y zeIdK;#v5)Bkam!9w7*DFKS-5Cb)@Q@#3ZSv3iF1O6EJA6?&<)xw*f0RVf7=6(e%bT zBpMn~5ss=h^b*%ppp!yfxt#pokxQe~biC4+UO_IYSg6v#xOb|fQ<@@G#!3aKW+p2n z1A2~i0!+T{u470sFn%vp`#i^2A%x=*3_M~1i3#bDA#q-IJ|lxDTTzN+WeKY19E4#< z&r_0f%y6KhR2p))5ycu(S+<_R9RMh^V|0UGKLaW_ONUh8-N&u%*b;)d=8CJ(-rNG? zh8wPPKmF-X?-$2jZl|UVInrYwX*3OCEVFl#vmbHH87^LhaO#eqm9ZqIt>@$5!D!X*ld(f zn+O~*Nx~|qECouUKscgez=fva1(5n@gw6=kAtT>+#XuRXG_m{BcKlfC?mC$NS`y=22JWCp{W&UZbf?iHf&wA1c`N9(6Vte zqRA{G?I{V3kQ>YTKDm4|CRM3Wq^=Y~D*#l$>Rni~>++>o^4=zotLvx)bwQ{!U{V3T zIzhz_At?@KvF?y5{bktOG{N#FQ5#iL$D@AcbkrU+6__wus{6@@l@!7u>2oR-9Q5nv z>GP{Z@9$kQZ+h6Jz?$0s=FaXsv41?-u96_V=BlgF*)jyuuH!1{T8h~ts;o?4dP*1& zWwrR60&B{Jy<#19u3Ur8bz9J}Y9ri+7GxWm5l!YWqO?NPQ*o|11UySK6>MNtXsoal zYU*EJSOzOO2zr%T%@QVA))QhU^pGkHmX3uHsw_vWwhGx{Wf*tbk#I*=Av9(rP*x(< z^2Mdhu5Qx9MTt%_j=F3^Al)6D?bfk=klJ<*zrXP&0coPGy{jZGa9{UNNvfDX{#IlZ zT&zr}yHf*hI*S;?Hi@i~vg@}XwPqt))^0-6y3MfKQfOPZS)4s|@(4r8 zHlcCzHY9d7p=I+nX~}4%ZA7!K#5hA)rpMVr`1j|slKjpZLv%v18hkDmLW&YF9z&?2 z6m~@koM9Cx8#4lo)WJgf?+j05!}fp`=sk4v9ZiIqqzS2jwb1IgnO%RMq&!IXQ-!@s z4!V=Cm*OUewzLD8T%m%Y%4744RIe*rCjqcpI6dIjlkfA?$mv;Xtiz!~>HN$MW} zot2{GP=WkjDB`EGVpM%0kAzNYppz3@vy2&@D!oOVO*vQPa)#J!SZe+<$BkZNI-_j0 zU*0bDBsD`LY-dl9GHXT(glh@Ub1CUam03HXBn?ln=%*j44sXgOrnau7!gOt-{!c1h zo~EZGhC(p?AImQD&ihA(l9Z04Ydo9uH^2Rr`?=44ZV05l5eOD5?kSmEPgcz_5TWH| zuc&OBJoljM_~tvPDVm}JmJg`@*i60^pue=If`P8|sY`r{4ejNm7A~mRLWQk+WHVTE zX>e1_dkk3xdJ53&&Y9o2#|DRs>aMm)JKEb}{QB3wbpQ8%|91$ay@1rO{uY}mnyatB z3l=Ttt?(FaQiV~rChQ6z-7Z3(H(0JDA79lt_jR5th|R7tv{*~I0s4*lM2jw9-sg@( zJ1EU2u%>C7^cs413DRHv>KE?kKmYk5koGcRdXl925Z#us0Mf2t>#I7T25RB>K>X7C zB6yyBeAORU)oQlCRD{1&cagr2Lm+)?SBu_2Dw6bc(+zY>W;Sfl7V4611s1Mfwah|4uQ1$p!8=<_NPT_ zcfi=wvE9fswvFqryIw%r%C2g(N#Bl=)E~C!E9BANfelVbeT_YJ{{G&_zO-L|yw5`* z-Mu$f45T;Qa04#C{BpFjGQ&03T;+c4YhUZPx~m->d@*_w_Y`E`y<0DSw6u%xnkVT! z_7sTr6_6HVAMK5??9VxaW6fjs)Oh#j`uoE^-B^^4i|enyPC(j5NqY6wSGr&S`qu{p zQoS=@U?!6hM*^u#+@jH_^#AN>Be471ovhe7n8L;DvGA7^|1!<|CpdxlJ@?lOOHcR2 zXW+i2rKMu1S5{W$j|qB_dF}qFfV(rfcz%v&Nl8f;x?nb&h2;_Jg9Hfw_4#1Aie6U zE8K5<;~N74sRo)phy%pI;1&*t`<%qPGs*cvczsSBP9%L@{cnD!fy?{RFNxpx1TZbR z_&ov3<9Qxli=VQxGI=&mVD78WHJBID*D+cv(F+johk)f66STY^j&WaGF$Z5?$LR0* z?0V8C5(&BP-Y_rvdq4fz&#%pKyeKTV`G4n_baZs&-)Dc$`)2IZCrGcja)JA;Z+>e) zAZ0^du2uvjAWkN3T(SCE$@}`gw}Fw|Nl(?*VAX%)dG)H#NzT7(N!r^A%KaJ} z8}pzqFE7snl*bViot>R>?y9P){5AI03)Ef3InMeScpn_|9Xoa)9*-Bjw4SK?=U~TK zYbktQ0+c`ZWsq|2Q3E0f`R)irKS()lynoJ3t)1+xcQ=^x_GFV@dBqjVadi0=mvsZF zN&@cLt*#}{vSrKg&_fT&p!g-4mO{ZB){{nqYOoFmUZ0>DIdUXs%$R{g4?R@C!}IYP z8#ZjfOE0~I_3PIQNRK@7NQ@aXMm~Ofk6_>gT(V>d{_~&z$cyGn=Ckk_I9c^Vz!mwR zgAT$er<{Ue!-fs!UG)1HKF6j_oACJKkIPRj-A9ZVfz6vY=OPS9RR)rN^eS(OE0|??|tuk1$+e6 z0}niaJMOqcKuRD}8cm!y5%cEF!v{b3LA>i-@5-xk1S4PIAOHAAc@6?xOR?a+ala{3 zrr_WI{x|CC>biVA*u|!&=jZuWuU?Jse)qcqRKMo1JNA5k9ef-|jx7@}KK}8K%i`9P zr<>2Pr=NeI^WwGFUc*HfU4%u87Rh~T?Ma_UYk3D8Z~%VvqaWeSGtV68CHCt6L6G{% z48l0N?6RM918Go_7JCT<#lsIjER&lnnBGU*ar&wJQd8S{{BE$TJdf4t*HK3uB_O4w zD+Q#FKKiIEG=6aQ<}~VUHucvl%SkQv#5o_gx3UDW$xD)d_o z(&wIgPC&YN@nRXL;Qi=#I(_RW;Y(lo5b-9usq7cNex|_uCV=`1iBVJ{!OI#V;^^ z{CLq&xbt*)-duYUC_8E~%rTqyYa+O=y%Wu-byJ48EP2r_QR z9d{gl{_~%UWTgsAY5M!$|Grmsm*=M>B}l1G(>4rleckgw-W>0L#flYqNvgwJ`W%D3 zR&cy~0$o{IIamnbo8SC~grjn-#Uvmt?x)yOAT4Gx^=I5@k5cQ|Nu~aWznWb4m*ZD=moHylRFd{*fCsX|>wO8B!w)}PR{EJUXNnYE zx^yW{KKW#kjM@g#`xDgs@Vf&KJP}L#N{Q>PyRKJtSBG5)(gz=WunR~B z3z)vfhKmlhghw8EBp-v`(;)SmD21^KVf5(HxbAn?;rQc^N30|U+jhLhRK@R_o$6R8 zm>k|>wCUi&tv&EsYtgZ9|JesJuFpREY#yXRb4zOgen}csclXpH)7Lxg>H9t<>4HnU z+oV#R?kxbRR+0O9*ouk@eC%T%!?(WmEwK+d30{8rWn6H<1=zlQdtN=$=g~GCB`59J zKmYm9qO$4$_b-3>O93e-kB(3J??J20^zPCQe>1$h8l=45-jbw#M;@P7V$GI?V~;%! zS6p!=rXMgJ@lt}cd;KL{Oq`%(#Zhj$z8VECK}Ly2(9r(pril{T^Q!-*ug#ym%>g}` zRfU*B#R=M^T9Uq#K&oug4j5M~xYYe-Fi!d=gH(q_I7xc43H_j%Jb5yH_`@HH13(iC z2+nVQ^P3`hnwy)u;G8d>=cNn&BOm#QfSc+tHv*Ru*$>j-%F6rWYEMZ@&}e(Muf=4r z-}Cx!7D%E`v;k^AuK9qaKOC`ive_uMY8CdjB7?0XyR zaXm>=f>bIqyxAZv21E@~PLg8Y)!@S)ee}`d)uqZyY1q=zB5~4R|N7Us_S$Q)X3d%| zhfuBM%jf>z|Ni$ynrbP+Sg1#s4y%b!_FGIw671e*-RSQbOz~E3b}L|Elo{mZEitB z!wz{jl&F-Rd=JrZ1T__vD36z+rn*{wlF=0jhY=!6h}9FLk*uz6<`_~9ru|JVg0Wt{2THGEAmw62pnU36 zpAx$~zezX6LjObl{+{#C#qePx5cUcOOA&B(aRbl_Tm6@_;byXEZrFvE#$8yqdJUE> zeGSW(zJ~3aH=}7+6Pg+uWfsND;?nO%7NMMj3AH1of%5pV^_Vz*0uDQLF2>i7!|>t5 zQB^-y^>$?=9qxZb$J>4WJ$DCtNLJP-9 zbGeJD-@FFLpK3h!*Xq2M$OE%+b>rv)P+2}j@=3408tp8fvO6HSnBxzw%2PNr1 zLCX1~sjeJ9jxQN#BuQ`q^uH614FSqy_~H8@IFCK{SaGz`UosG<7mWy6ihROUgY-(4 zPYHrlCV#$SdU5ZrKcu2xbYC1%4gl3ms-oP2Akp4aP9%C=Nf;nli%C*_eLn++_pL#~ zb5p|TK_}oi!8y?>O?1`{??bDXL6G)zf3s)L7IJ}>X8QSgPQCiBTenWiG2U{^E!ets zYd&7<2ZffNd|pZq7AL0)MiB8lnkUR>;yr6MR%;yk-t{@Ts8QV`sf7CnH5DGu3B`qv z;U|(hy53I#q^c>EcyMGcWKE#W%_41C*y$$F)Y6R2tJY!diZ}4$)6Zhvs?~VyrI%p2 z2JBQC$mXPt1)D$-=u}_XK9V4%aZ8z49W6t|HQ;2j$RdRrs}iGzkHF}?F-T&baf56}V z_BXup$}93Nf*_@aq@^k6!U-pwAS4;G+Bo-m;#PNC+2s$tgS4%+6~;y1`L=t>Pn5cw zmrzW{>OtKt22$-}_n*VRnsDMUobc11{*oF0f~uafVPQ4?FCzJUI81B)#HF zk6{1ZZ-2|B6Q*l`E6}hh5XA23ruC==S27L)XxrYmUyQ~V)FgNz5-hj~GG48(7aU&=(yOn& zT0&JtLCW4v>>x)Y)BsW;s<$@QHSNHf9b2$r$2M$PzX6Zlb{AH?vJCdFCgtb}g<*Q_ zA(gb#tus7|UOslBq@l!AJ&DalfyYw9()Jt?j$>v;9j1&JgGm!7Vf2itnE$a05Sug_ zHhUr)E-c#cI^F{y2-2XrqRl4FIHK0VvDWrG=LT(l3J1;wdW-!V_v1U`eA4VSF4T-J zFwK+a^=|{VNdxL`Hl4-|*I$n-u4MU?78n1VeJrYQ96kX2Rl;jcy;YcY--qsSC+nt zXBIBP`j?l(ZfI12QA$UGj1rFj)FAbmRf)*+K$`FB=1Ewp)#_NaI1s4iurMt)43jE` zVN7K$YU)N{_9@3=&gsXaeEN7~!X~VcG?>h9+9q8j++F3=@^3+qzWd$p&YKb3kMn>8 z7skt}jRXP8f9r)^LQT0GKKjv*$|8Hj5l3|M1MD4;UUpfR8|&)-_ILAAyX}r7-5Ve! z0H|jE&;R_7IBoo%TP-d5H#&Ss=_4qa4a2`tqB3-&9Y@6^y$-=>Nvf+)(C(!TO8b)w z1SJ^(98__&^N7bW#!E>?4l(1cykDJE9(V~w%arscNe2Z|X{qQpZ&ueJ+f4B8FgS7?y0Aq5-mwP>GU}WOg<}ZP1>MLI{4%#KPf4aI%8<>OVYPFNC`Ho zC{!KkjnglM(vAa8b%ucAATu|T5|1mOmN0$ANwuWcAk{8+UW@1Y-S2*v_at)>(kr(H zly*$eCj7)FJ|P5uIg&a=f5G_|2#Dy=5rB#$6&VcMFp#ue>`HWE zebWwX*|h`Pwr|Bl_uhx+9{&$gTerio!iX3q9Cj+tvL~y=aq?aahFd&%s=4cdRI`+H z&qfijt^%lGyRZxcmII8atdd5{Q;bR+J81@{Rn=kYoS7JT>S3rmVit@M)j-&UEnU)G zyx=*Go_uPtG*#w(`8O_-1aAt13%GN6zNPxV!p2}UxuyQw_(esO|U{?#Ho2ClcJ`w2{P?XdVwntMs3Ex zG@}w{jh~5eqsE|o)?^&<(F=e>CaaF;v@0D4FTA(}-?`|!pd_^!>S2RsUrRw9d#1Wi zKvI$tptR+gq@gtsJ*IkpdU474;lH^sGsaF<8^d}2t=MAPZ4&nQ2Y+iyrNgFEY20wb z^|2D9z3Q$ASHk}Nw2x;YMg(;1xku~)IK3Az?4tQ z02%?TY2AetZ>+$^)obwJZMS3jQ_lbm%_w7_-zao!<)q4HG6LM%npzxw_+dEx^wTlp z;2HAVls-}h#x&5<+KO%4w+m~Fq!T7ZkX=(6SHRCdm*b$sHBse;QRf)AVB{Q3sv3b2 z(l0tN%hHE*D!sTq&ob3Y!v_1{RXT#IndMJbEUg#lYRfMp{v;_)(^=GkgT z9&tq8o36uNlBn-xDAAL8?|t{;KaW3wd+xmlq!s4u930QK4donBp(BQc;cgg*g+^k| z$O)J-VG`=+9gLYDdk-*W3=m<3KpW4#^di2)$_$jGwu;9FB`LKU+K^1aql9FK`p3r2*rbtog$b5mi`SF+l^=e;rC+0+gQQ_rL%B z0#NNh3No_#0_&az>AB~fE9$P6qy!wu(S-rZ{->I@V#ymT5Y9Nb{SSY}E4SYbw09zI zga9W8Ct||!QeSv)B_*YJ?|U!6r$7A}NkWK(LkL-_^eQ*b4{di#rj2Pzb_dn-Yp%H( z_uYS=l8QMSmhB*%vt%0e&Ip{DX>4SBxxY0L2)?9Go`(rqdrB)bbp%muE1$l3SG@VT0 z#v9pY;wrSYwZi!3SHI$3cKHIYh?fN;p8?~`Ast|=k05CIvcC7d@8#p9J&^_aYm*k6 z)TD9IaTLse3GPdfQq9pI<-O4^`N~(ml229B$M8FCU-EDMJV>t0e&>RJRpm?M%jY?1 zhidg#OBJ;s_R*TmcjJDL4#vAH&mod@9GF?bV7?!u4r>>~l(5S#xcK*LFJi;a287zv z`1Qq?A-QY?kaJK+oE>326U zY1!K{+|?%Ko~cAa<|xBuk_GdPuYB3PY{3Gt8JGp}b_OXOBD%C=v6sYw)smDFQO7#_ z0x6HvAHHb5L>)@fo?QOape41DETYeR<}e(?Pt;KLvO5Xws9g3Vkm z+bc*35G_#&)Qd0qF@F2o-@wkfs3?iSOsYcb$q*2+fsw9-S=MlzHDNYJ)(peMQ;xzx z?>ie9TMH-R;!K17&K9I6u_?u_~$}z@ax}q-9eh{ z>=bG#K`QyAU;WaBF3Z`QUaHc*08&=uBiTR~9P7`-rX(c;gey-^>Nf|MDi7_+{({s$ z(7X@50`nUBzVxc9|4ol3y}oo5>0)O(*4Dol*LAPGElCMds=A%o47R6|SiE@yHt%S_ zvv)s)2mkgDpsf|Kvk;bpX&~gdC@(2Rdq=wzf&1kzekp2hh;dWNEzJeZto#G{r5eYJ zC0Xu&;C_7UqaQ^}YYUv5i*g~7j-x+v0WiHDsEpy6 zS6{;aBS;sj5R4s&qYiY;=_n$fn(bF;rf3G!;Idr$x_ZwbW%QsMNNGnDsxo*w?f_L? zQFj9QaRXI%2Mf~k&O1+R#UL$A-w!7RLCUx$Gh_Oaq(SM$=is^YYOKK%1Sx?@N5fBk z@)NOZ)MQkjp0ZSWdzEhnNGT&bQYmcgXvd>#R-m;#fhYcY8(w;BArcMS>BG%~G-{X# z8>TqM=v4XMMc+f+s5&(+F4;Muet}d%Zy`&(!}I3N1?%T#QfW|;W{xGj&S3|LF~*5X zoH1$!#?_2O_0;h=^^+ffHD@YN6UTEezaWkyvY~|TrxViq!bcC^6PWZ&vp4|f37t#+ zcf99RT|rAAogUDVG!N3RU3j5OBClkeu+IpMeP+%Kvd3q!=jKECuI3+UsUj=@%p@f)-$HsOI6A5 z+V2af!SfXZssEn(3c&i}+rMV3YZ~O;deDE>k677JK z5s(^|i3mFgwdV4SW-bJ|i?|%oK zCMtVW0X{^!plf5YQH9g%XJCBgaEzHc38#JH11erRyc{n)|1AFBMHk_zMT^8~r=$#mt9d^Od9*0+W6VYMFeOyw~7++cRJ-Zj(~o?E+Hft6d7p{qT%5QX^KY7Yq@52vjq6(j zQWL3+jm@b9?jlHATCwPcf8eDD9z!PC4%iux4n)ZZTag(E(rlYKNXdg` zxPvcOC)gHq1o>A+N>Z|UbcZzm{(g|sUL=uvZ-P{(K2g=BT}n0(B{)}ShHZ3xr8f(t zvM2=Nq<-&i4kR{&@*ur;<*R6JX~h#a{sT)MdJImo6K*y|ktWlGQZ&LGOvjP9}r;Zm% zYRpyY?vm%96PuKA(i|mep5|CEy@J|Mf6WV0LCI3$e9`YO*fntXz}gQ<`lZkRuY2va zzvv=Gm8LuhW3-1SAE+c9EJ#WB(#g2RK*|+TJ9X$@@2@1)Dz4u~EvD{jiNS@1&Ie9N zzF1CVei)X~s&9WM3HRGwbvFo7I@p93=-F?Wpa5AAN%;naQT7-0#brA7EwjXdjo0ETw#&|t3{9~AF?cj7-=9# zZ6HdCiX5h*8fTB0iTaumsG2qor+(%`Fy~ALs!D`4q(Lg`Zr4HwGSvM6sn(GAlXHXb zk`D<*h-FXiHar0+Ld-QAZ!s$YP%r8pLpl&qpa ziTK7FZ{#!g^*+IuMsPCohSV}HB2;~Q^H}d`b+;Qx&pTfc>@`rOW{`n&&c&`=77x7s zDt5NE;A->%_zTv_Q5qO@d11SXsNvtNRaE*?X*msJr+wAV4h{?f|!xFjV= zeUem3R0BE3K#S|(p=GaPb7Lb`zPuE7{P8d7T)P2bHiH?lORaIrniu*_m{u?Wtq&B!n!<4u@}3iC21G$?p0UeymQYh3Q`Hf0C;Bo z1}xjKUNTi~|I=Tv^|_Z2PN!hHIT)r3*Kox-#KvCyFyPP0JOAjT1ptw7q#H={`J^7( zD(B>|X~RZooyltXuPt4gFIN%{TVjtAr0m2x3T2pCG92fPKLlgzMq|pkC!qYaBZ0b7 zWGkY0F#u90Qvj(}bvcLlA=pkj=_GMfQIaw-0m-IdkdsGHper z8h~_W(PpF6p%aNVAys7^I}HN$tpsTTz>208EM312TN@kj@4x&N%kO>=Rw{+ClY>d3 zfayY5JyOWe0?U2;_Xj?RFMRO}m^E`I%Hm~3L8_fq*<2Q#oe3;nya+d3cRlXE=UxFf zom&jYghQ6ZM*wxYjIHNaGWvu5R4cz8V7&u9E6TI2yS&0si=u1FD=3U`>t{v zNt&9IF9wmfM|DLE#?nbqWkn2K5|xF=2vn-Qy5Vq8no?8ZcU+uly72vJjc8A+yMFGj zkQqMp(T}*aDfXngTP%**Tbxw0cjz@^Di>40G~=ikjjN|P>D~q@JDwq`w$Y)4t71UZwmb|zel14ATdBoY=6C^LSJIP7pqu&3ss z9W7dt@_OqxZNwdS-hq4Xxfic2c?s<;tt#=Gp!b6NA=^O=E=D4RIjFUcYo?&+xwmNaFXOiC@%L$zN)ND<7a z@s8J0mG!8!Baq|DXAI8AfvLUSC8gc)_*7)wgIh}27&e5Z1ith#KOR9?PVZhPpbQgYi3l3Y?Lg~dLJwP{kF zs+Jss>>=%CeWBSviYwC5(V-fWK2s}PFpydyjG4~(vNTUn-)ryX22A(U*+JUa*d&94 zvlOIgq+HknSyaoDVwQw?lq^r0Ed`UUz}}Y9%-w97lj*qpqe_p4_@sHg4FcHMkZ$GEK_arpO)|?xTsM{Og1N$eA;v za-eOG{Bg%l={@*g89Q}K3X2O>?<${ez=9Bu=j)h>f`URV^TRbj2*F}uIenRWecIIl*aQe_dYRn9qHf>5;DVhB z>j0rJ9WpY;Wf(}a`8G3c?%o}cLsJH7xl+tsj5{d2=s_7cdrl7abxZ%ifE@bdfV92+ zPkH;b*X7j5`z2O9PYP4yw}91Cuo84BD=U@0o?cB`uoswvCbX2Mh3lU^qpfeeN{dUB zuQ!jhi#E)8f(V!|F{zhQx$7IZO6{V{rT*Hh3C$qy!>fPyOL{_q;2= zqL`r-`V_8foK60!o4E@}nWS*xL^cVNvryz}4!?zNnYUSj#HTe1Zq`88WMI>-TKn95z)}-dwW&&wyhC`RSHcsj?SQAGMk^uGY#vWBK7Nn2hn4u41qDpOZt7Pe6u`WB9b^Qb+JlW zb6LHts#z|}RxXztZogHQfA>boUtZ0ZMB*fO{qYs;ZS83w)ikZMK~|0lr!(4*Cj3m6 z3;W1GZ1#^cNT7)5DlhKc+!qr%Of;ZAn_!Z~75p0JY>jf6Ae9}YO{Pg7yl<2D!j2tZ zdXPeC0>=?y^h{0VEb@f}sR0L|GL#q-nrLCBCIQ~#KJk$_Fqpko&0@_4+05TewWv`b z4X0oXr1=E}K2yB|(gX|%fmTJ?4UCLPXJ3yT>^iIincCibOFn7+w~TamYosTSj+fv? zA%do5bTKCId!&$Kb7lZ3-829-kvOCJuR@BXHeN1YySzqLRxXj+`a1d6h95}HO*crv z%4(7Fc|JqF(>v1M?$0MhldAR$jiLZRtQ#Q3(t#YnUaXA;g?Nv%vuoEb4J2Vk8$GLi z&cF&#u@>;VadTjNKsgXFvy|P`wA@6HQqlFhXP;FfvO&g7TuLBi@d*Ot3R0IGI}^R8 z`6qPfn#dV{)YHb2;?ke(Ct@8}i{hZF009psLywzi~XE=p?=x z2C4IJoi`KspbU44GmHt^l>E3X&M%gmms}y&FR7PRwaewo)z{04jkk-`E)=i4NPA4R z=sr+Z{Fo|8X~qYn2y@ep?oShd)K}B}^3qE$>Ci2=-q>=cW(xCfa^Fy_kYckG4%ap9 zI=N<@2vTaJTbf(^rf&jAvl*n;jgZOwbfpxFfhNrrq}rYri)mEPCC3g+z+6CT8kPAh z_?*myF*C`2AD?jvv`HOtcnCtchsKrm1%*2$Awx5(N%*Q#0Sg491M zK1lIT)f^4{(|!U;XGi4N@#Au=t49vK*CD&#dQ$2kT`Z7tv)Jx{!Dh3#K)@HXQY)%JFgM7Pns$l;DT@L~ZT2V;Q}=~g z!h84&T$cqUr^j_!WGaRr48wN6AZD)E%)e#>Rn*L&Oo^v z&CCQBcy@rweeiqu{l>vdlQ?`jXwyt(g)T@Fzor?QOfIwe@Z3{J2xj z4h>0h*?iTA!i-SL^Yl+bwQ7D|zIM(O=EWrsQth(|DTxO zH+}mSS#|YQvf`R+L>4XZ!@j|YQl;|_OjJvUk{^BK(MM$W?lvDJ=gy`1q?|w2oc%>Z zx<09Uw#@7`%ZHH@FfH0!!CfA1L zfR-)N7Vazj{9%wH)To5&?Ci`qYLWXv*sNZ?THDIjtzG8_cw%`9LVZrnPx=gkDM6!% zB{%~kg%93@mz3e;sPy#rN_SV696o$VKIqsh9q+#{`}gga{@z}V(gGBsl*WO}HPM!U zw7`q$kfySt5?M6ALawU2LI(-o)NrFLs$L>>U%yt0%1b4$tjxa^BNj6f%Yekq?v)W3 zk3RO8f{A?z3u*S4Gsu~usD^?Ivsm0cb_Jo82vVX-v=?SW&WF+G*q(50)|WHP=m|7B z!rZEn!WK~4z8Xlwj7(#m{N|~rmC0#z3$r zfGJZkLnevDA!m*U<#|L?!+s?jXPO#mN`w!GpKGysB(N#+w&~ei&qfGXp#k@Y)}si) zdR=Y7!yWr>%`wxuxi4ya*<_oKYMaP+d7n+^x&)E}$0Em+!aexF z11ijXs+^dnPr{Z;3Zy|ti&`{Lkm+a&PtGLI`Vn1kOom5BXvhSmPa^&#m zvTyHRWmp&*8kW(~)2dbZeMNyLt*@?8j-=Y9)l$23nOt+_N~x)?*1%4zs8D1P$9 zmB4vaa0W!b`gdQr1O-nztP7e}N;Cmzc(#u1J(XezLJJ&a({$_+LXG{V8i^nvu?VAN zb!XhN)|@F=D#?H2Hj!4dK;^VR`hVWvtxr6m?QvSnkfup#79`I!!ypATB>UkvWnsdH z$cpG$Omc=uB8u0|lr*qrbHMpNnhMQj01IncGfCM%s$kHz)L*igEHGNgMjF}>CCl>x zUNkYLDCSsLN`{{YLBs}gZ8SU2j%4OKR_LvT)9}g$eWyG-!i0N6Q|AIw?hRIbp3%w@ z-R~P28f!zYa9&A?mI>NHH;`sZx&ca}w$^{@4_xvYJd$2gg^s3`;sr7^I4DQ^`ej~m zv5X9l=#*-h7D&e!NDK1fQXG#yyi!?EStX@aO!QWjuD~1{ONd7SJCS3T^VxtI z(xm1?+5qNo1sD4aczK^Fx^Wg|v(VTJn;&F_5DepD@3@vS@&`V#X;${TySrN>_9&Y3 z0%dvl8q(x2UPkGJE69WoEof`x6$zYo;z8{3ZCBY0#42r4$bT6VWsvQp$e*B9074rwtV%n$Ub<%TN-d9IJcSEV z14+2hBK3Yir;-AxF;VJIPZChF1nD2Ht5rxg>_kZ(CRXscl}irnBlk`}8^MH`38ZP3 zMKH!9{L5w>q%F-dOmz1rcW?A|?%XM*6nS&=v&h_?(u#ipANneTl;utV#2p6gxG@SU z7gs@BN*YLmU=Zdq1^$4PukbcBES9I$-{*AOOwdN@x_L^cVfKO4T~$9w=9|0E$S|q8 zA8*{?5qT}Gs7PznJ)hd$DXr8c{GqVq45ta0^Im-MMJcPCGk0@d%&+Jdq7LyK zNYC$JBohhQ($uJ$bae2f#5Ue_r}u}KU!DW$`K{|$>f3W5%@EC+!4m*Tn;JLEbK9Hc zG(PEuJAdfC{K_kHAf3TQzSJ)j2~s~jF#eh|cc*kDY{}>#LX!g0GlM7Pf2nysEeiU~ QjQ{`u07*qoM6N<$g88?WF8}}l literal 0 HcmV?d00001 diff --git a/test/Charly/01-begin/06-manager/public/index.php b/test/Charly/01-begin/06-manager/public/index.php new file mode 100644 index 0000000..019426a --- /dev/null +++ b/test/Charly/01-begin/06-manager/public/index.php @@ -0,0 +1,26 @@ + + + + + + + Erreur 404 + + +

Erreur 404

+ +

La page demandée n'existe pas

+ + diff --git a/test/Charly/01-begin/06-manager/view/README.md b/test/Charly/01-begin/06-manager/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/01-begin/06-manager/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/01-begin/06-manager/view/comment/insertComment.view.php b/test/Charly/01-begin/06-manager/view/comment/insertComment.view.php new file mode 100644 index 0000000..fa6b761 --- /dev/null +++ b/test/Charly/01-begin/06-manager/view/comment/insertComment.view.php @@ -0,0 +1,25 @@ + + + + + + Exemple du CommentManager::insert() + + +

Exemple du CommentManager::insert()

+
+ $error"; + ?> +

Insertion d'un commentaire

+
+ + + +
+ +
+ + + \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/view/comment/selectAllComment.view.php b/test/Charly/01-begin/06-manager/view/comment/selectAllComment.view.php new file mode 100644 index 0000000..ddf10d5 --- /dev/null +++ b/test/Charly/01-begin/06-manager/view/comment/selectAllComment.view.php @@ -0,0 +1,33 @@ + + + + + + Exemple du CommentManager::selectAll() + + + +

Exemple du CommentManager::selectAll()

+
+ +

Pas encore de commentaire !

+ +

ID : getCommentId()?> Voir ce commentaire via son id | Mettre à jour | Supprimer

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/view/comment/selectOneComment.view.php b/test/Charly/01-begin/06-manager/view/comment/selectOneComment.view.php new file mode 100644 index 0000000..e7b9ed5 --- /dev/null +++ b/test/Charly/01-begin/06-manager/view/comment/selectOneComment.view.php @@ -0,0 +1,34 @@ + + + + + + Exemple du CommentManager::selectOneComment() + + +

Exemple du CommentManager::selectOneComment()

+
+ +

Commentaire inexistant

+ + +

ID : getCommentId()?> Voir ce commentaire via son id

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + + \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/view/comment/updateComment.view.php b/test/Charly/01-begin/06-manager/view/comment/updateComment.view.php new file mode 100644 index 0000000..17116fa --- /dev/null +++ b/test/Charly/01-begin/06-manager/view/comment/updateComment.view.php @@ -0,0 +1,35 @@ + + + + + + Exemple du CommentManager::update() + + +

Exemple du CommentManager::update()

+
+ +

Commentaire inexistant

+ + $error"; + ?> +

Modification d'un commentaire

+
+ + + +
+ + +
+ + + \ No newline at end of file diff --git a/test/Charly/01-begin/06-manager/view/homepage.view.php b/test/Charly/01-begin/06-manager/view/homepage.view.php new file mode 100644 index 0000000..0b6e57f --- /dev/null +++ b/test/Charly/01-begin/06-manager/view/homepage.view.php @@ -0,0 +1,30 @@ + + + + + + + Accueil + + +

Accueil

+ +

Bienvenue sur la page d'accueil

+

CRUD des tables de la DB

+

Comment - + Insert Comment

+

Article - + Insert Article

+

Category - + Insert Category

+

File - +Insert File

+

Permission - +Insert Permission

+

Tag - +Insert Tag

+

User - +Insert User

+ + diff --git a/test/Charly/01-begin/06-manager/view/menu.homepage.view.php b/test/Charly/01-begin/06-manager/view/menu.homepage.view.php new file mode 100644 index 0000000..c452a7f --- /dev/null +++ b/test/Charly/01-begin/06-manager/view/menu.homepage.view.php @@ -0,0 +1,17 @@ + diff --git a/test/Charly/01-begin/model/Abstract/AbstractMapping.php b/test/Charly/01-begin/model/Abstract/AbstractMapping.php index 7f5a051..2da5be5 100644 --- a/test/Charly/01-begin/model/Abstract/AbstractMapping.php +++ b/test/Charly/01-begin/model/Abstract/AbstractMapping.php @@ -37,5 +37,8 @@ protected function hydrate(array $assoc): void } } + // Méthode abstraite à déclarer dans tous les enfants de AbstractMapping + abstract public function __toString():string; + } \ No newline at end of file diff --git a/test/Charly/01-begin/model/Mapping/MappingTag.php b/test/Charly/01-begin/model/Mapping/MappingTag.php index 62c486b..a73fb1a 100644 --- a/test/Charly/01-begin/model/Mapping/MappingTag.php +++ b/test/Charly/01-begin/model/Mapping/MappingTag.php @@ -5,7 +5,14 @@ // on veut utiliser AbstractMapping, donc on peut utiliser // use suivi du chemin vers la classe (namespace) + +use Exception; +// appel de la classe abstraite use model\Abstract\AbstractMapping; +// appel du trait +use model\Trait\TraitSlugify; + + class MappingTag extends AbstractMapping{ // propriétées @@ -16,11 +23,27 @@ class MappingTag extends AbstractMapping{ // appelées lors de la création d'un objet // via l'hydratation public function setTagId(int $id){ + if($id<1) throw new Exception("Id du tag non valide"); $this->tag_id = $id; } + + // Appel du trait DANS la classe où on souhaite + // l'utiliser (le chemin complet est en haut du fichier) + use TraitSlugify; public function setTagSlug(string $slug) { - $this->tag_slug = $slug; + // utilisation de slugify() qui vient du Trait + // model\Trait\TraitSlugify; + $this->tag_slug = $this->slugify($slug); + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; } + } \ No newline at end of file diff --git a/test/Charly/01-begin/public/index.php b/test/Charly/01-begin/public/index.php index 2ccc8bc..8a8dfe6 100644 --- a/test/Charly/01-begin/public/index.php +++ b/test/Charly/01-begin/public/index.php @@ -16,8 +16,8 @@ // on peut utiliser l'écriture longue pour appeler une classe // via l'autoload en utilisant son namespace -$tag1 = new \model\Mapping\MappingTag([ - 'tag_id' => 7, +$tag1 = new model\Mapping\MappingTag([ + 'tag_id' => 1, 'tag_slug' => "php-8", "Je m'amuse beaucoup !"=>"14", "Nimporte_Quoi"=>"yep", @@ -40,4 +40,12 @@ 'Argggg_ho_tempo' => 164862, ]); -var_dump($tag1,$tag2,$tag3); +// on voudrait un 'vrai' slug +$tag4 = new MappingTag([ + 'tag_id'=>15, + 'tag_slug'=> "J'aimerais que ceci soit un slug ù$^*ùµùm^m, non?|ééç!è", +]); + +echo $tag4."
"; + +var_dump($tag1,$tag2,$tag3,$tag4); diff --git a/test/Charly/02-mapping/01-begin/.gitignore b/test/Charly/02-mapping/01-begin/.gitignore new file mode 100644 index 0000000..63052b7 --- /dev/null +++ b/test/Charly/02-mapping/01-begin/.gitignore @@ -0,0 +1,7 @@ +# fichers non envoyés +config.php +# vendor contient les libairies externes en php +/vendor +# PHPStorm +.idea + diff --git a/test/Charly/02-mapping/01-begin/config.php.ini b/test/Charly/02-mapping/01-begin/config.php.ini new file mode 100644 index 0000000..5515502 --- /dev/null +++ b/test/Charly/02-mapping/01-begin/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/02-mapping/01-begin/controller/README.md b/test/Charly/02-mapping/01-begin/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/02-mapping/01-begin/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/02-mapping/01-begin/model/Abstract/AbstractMapping.php b/test/Charly/02-mapping/01-begin/model/Abstract/AbstractMapping.php new file mode 100644 index 0000000..2da5be5 --- /dev/null +++ b/test/Charly/02-mapping/01-begin/model/Abstract/AbstractMapping.php @@ -0,0 +1,44 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst',$tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + }else{ + echo "$methodeName n'est pas un setter valide
"; + } + } + } + + // Méthode abstraite à déclarer dans tous les enfants de AbstractMapping + abstract public function __toString():string; + + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/01-begin/model/Abstract/README.md b/test/Charly/02-mapping/01-begin/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/02-mapping/01-begin/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/02-mapping/01-begin/model/Interface/InterfaceManager.php b/test/Charly/02-mapping/01-begin/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..4406a64 --- /dev/null +++ b/test/Charly/02-mapping/01-begin/model/Interface/InterfaceManager.php @@ -0,0 +1,16 @@ +tag_id = $id; + } + + // Appel du trait DANS la classe où on souhaite + // l'utiliser (le chemin complet est en haut du fichier) + use TraitSlugify; + + public function setTagSlug(string $slug) + { + // utilisation de slugify() qui vient du Trait + // model\Trait\TraitSlugify; + $this->tag_slug = $this->slugify($slug); + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/01-begin/model/README.md b/test/Charly/02-mapping/01-begin/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/02-mapping/01-begin/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/02-mapping/01-begin/model/Trait/README.md b/test/Charly/02-mapping/01-begin/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/02-mapping/01-begin/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/02-mapping/01-begin/model/Trait/TraitSlugify.php b/test/Charly/02-mapping/01-begin/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/02-mapping/01-begin/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ +"; + +// on peut utiliser l'écriture longue pour appeler une classe +// via l'autoload en utilisant son namespace +$tag1 = new model\Mapping\MappingTag([ + 'tag_id' => 1, + 'tag_slug' => "php-8", + "Je m'amuse beaucoup !"=>"14", + "Nimporte_Quoi"=>"yep", +]); + +// manière courte l'alias n'est créé que si on a 2 classes +// qui portent le même nom +use model\Mapping\MappingTag as lulu; + +$tag2 = new lulu([ + 'tag_id' => 8, + 'tag_slug' => "php-8.4", +]); + +use model\Mapping\MappingTag; + +$tag3 = new MappingTag([ + 'tag_id' => 13, + 'tag_slug' => "php-9", + 'Argggg_ho_tempo' => 164862, +]); + +// on voudrait un 'vrai' slug +$tag4 = new MappingTag([ + 'tag_id'=>15, + 'tag_slug'=> "J'aimerais que ceci soit un slug ù$^*ùµùm^m, non?|ééç!è", +]); + +echo $tag4."
"; + +var_dump($tag1,$tag2,$tag3,$tag4); diff --git a/test/Charly/02-mapping/01-begin/view/README.md b/test/Charly/02-mapping/01-begin/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/02-mapping/01-begin/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/02-mapping/02-mapping/.gitignore b/test/Charly/02-mapping/02-mapping/.gitignore new file mode 100644 index 0000000..63052b7 --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/.gitignore @@ -0,0 +1,7 @@ +# fichers non envoyés +config.php +# vendor contient les libairies externes en php +/vendor +# PHPStorm +.idea + diff --git a/test/Charly/02-mapping/02-mapping/config.php.ini b/test/Charly/02-mapping/02-mapping/config.php.ini new file mode 100644 index 0000000..5515502 --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/02-mapping/02-mapping/controller/README.md b/test/Charly/02-mapping/02-mapping/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/02-mapping/02-mapping/model/Abstract/AbstractMapping.php b/test/Charly/02-mapping/02-mapping/model/Abstract/AbstractMapping.php new file mode 100644 index 0000000..b6d1d39 --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/model/Abstract/AbstractMapping.php @@ -0,0 +1,40 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst',$tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + } + } + } + + // Méthode abstraite à déclarer dans tous les enfants de AbstractMapping + abstract public function __toString():string; +} \ No newline at end of file diff --git a/test/Charly/02-mapping/02-mapping/model/Abstract/README.md b/test/Charly/02-mapping/02-mapping/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/02-mapping/02-mapping/model/Interface/InterfaceManager.php b/test/Charly/02-mapping/02-mapping/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..dd39141 --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/model/Interface/InterfaceManager.php @@ -0,0 +1,28 @@ +exemple_id; + } + + public function setExempleId(?int $exemple_id): void + { + if($exemple_id<=0) throw new Exception("ID non valide"); + $this->exemple_id = $exemple_id; + } + + public function getExempleName(): ?string + { + // décryptage + return html_entity_decode($this->exemple_name); + // return $this->exemple_name; + } + + public function setExempleName(?string $exemple_name): void + { + // cryptage + $text = htmlspecialchars(trim(strip_tags($exemple_name)),ENT_QUOTES); + $this->exemple_name = $text; + } + + public function getExempleDescription(): ?string + { + return $this->exemple_description; + } + + public function setExempleDescription(?string $exemple_description): void + { + $this->exemple_description = $exemple_description; + } + + public function getExempleNumber(): ?int + { + return $this->exemple_number; + } + + public function setExempleNumber(?int $exemple_number): void + { + $this->exemple_number = $exemple_number; + } + + public function getExempleDate(): null|string|DateTime + { + return $this->exemple_date; + } + + public function setExempleDate(null|string|DateTime $exemple_date): void + { + // on utilise le trait pour les dates + $this->formatDateTime($exemple_date, "exemple_date"); + + } + + public function getExempleBoolean(): ?bool + { + return $this->exemple_boolean; + } + + public function setExempleBoolean(?bool $exemple_boolean): void + { + $this->exemple_boolean = $exemple_boolean; + } + + public function getExempleFloat(): ?float + { + return $this->exemple_float; + } + + public function setExempleFloat(?float $exemple_float): void + { + $this->exemple_float = $exemple_float; + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/02-mapping/model/OurPDO.php b/test/Charly/02-mapping/02-mapping/model/OurPDO.php new file mode 100644 index 0000000..f8a6507 --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/model/OurPDO.php @@ -0,0 +1,50 @@ +getMessage()); + } + } + return self::$instance; + } +} \ No newline at end of file diff --git a/test/Charly/02-mapping/02-mapping/model/README.md b/test/Charly/02-mapping/02-mapping/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/02-mapping/02-mapping/model/Trait/README.md b/test/Charly/02-mapping/02-mapping/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/02-mapping/02-mapping/model/Trait/TraitDateTime.php b/test/Charly/02-mapping/02-mapping/model/Trait/TraitDateTime.php new file mode 100644 index 0000000..e9d2946 --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/model/Trait/TraitDateTime.php @@ -0,0 +1,35 @@ +$paramName = $date->format("Y-m-d H:i:s"); + } catch (Exception $e) { + // en cas d'échec, on met la date à null + $this->$paramName = null; + } + // si c'est un objet (DateTime seul possible) + }elseif (is_object($date)){ + // on formate la date en string en DATETIME + $this->$paramName = $date->format("Y-m-d H:i:s"); + }else{ + $this->$paramName = null; + } + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/02-mapping/model/Trait/TraitSlugify.php b/test/Charly/02-mapping/02-mapping/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ + 1, + "exemple_name" => " exemple1 ", + "exemple_description" => "description1", + "exemple_number" => 1, + "exemple_date" => new DateTime(), + "exemple_boolean" => true, + "exemple_float" => 1.1, + "je_suis_un_champ_inexistant" => "je suis un champ inexistant", +]); + +$exemple2 = new ExempleMapping([ + "exemple_id" => 2, + "exemple_name" => "

Un autre exemple

", + "exemple_description" => "Voici une description d'un être aimé", + "exemple_number" => 83, + "exemple_date" => "2024-03-01 12:17:00", + "exemple_boolean" => false, + "exemple_float" => -82, + "je_suis_un_champ_inexistant" => "je suis un champ inexistant", +]); + +$exemple3 = new ExempleMapping([ + "exemple_id" => 3, + "exemple_name" => "Encore un \"autre\" exemple", + "exemple_description" => "Voici une description d'un être aimé,
, ou non", + "exemple_number" => 21, + "exemple_date" => "Miam", + "exemple_boolean" => false, + "exemple_float" => -82.3465, + "je_suis_un_champ_inexistant" => "je suis un champ inexistant", +]); + +echo $exemple3->getExempleName(); + +var_dump($date, $exemple1,$exemple2,$exemple3); diff --git a/test/Charly/02-mapping/02-mapping/view/README.md b/test/Charly/02-mapping/02-mapping/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/02-mapping/02-mapping/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/02-mapping/03-test-mapping/index.php b/test/Charly/02-mapping/03-test-mapping/index.php new file mode 100644 index 0000000..78a6b06 --- /dev/null +++ b/test/Charly/02-mapping/03-test-mapping/index.php @@ -0,0 +1,207 @@ + + + + + + + + Test des Mappings stagiaires G2 + + +

Test des Mappings stagiaires G2

+

Table Article

+

Test de model/Mapping/ArticleMapping.php

+ 1, + "article_title" => "Titre de l'article", + "article_slug" => "titre-de-l-article", + "article_text" => "Texte de l'article", + "article_date_create" => "2021-09-01 12:00:00", + "article_date_update" => "2023-09-01 12:00:00", + "article_date_publish" => new DateTime(), + "article_is_published" => true, + "user_user_id" => 1 + ]); + echo "

getters de article

"; + echo $article1->getArticleId(); + echo "
"; + echo $article1->getArticleTitle(); + echo "
"; + echo $article1->getArticleSlug(); + echo "
"; + echo $article1->getArticleText(); + echo "
"; + echo $article1->getArticleDateCreate(); + echo "
"; + echo $article1->getArticleDateUpdate(); + echo "
"; + echo $article1->getArticleDatePublish(); + echo "
"; + echo $article1->getArticleIsPublished(); + echo "
"; + echo $article1->getUserUserId(); + echo "

"; + + var_dump($article1); + ?> +

Table Category

+

Test de model/Mapping/CategoryMapping.php

+ 1, + "category_name" => "Nom de la catégorie", + "category_slug" => "nom-de-la-categorie", + "category_description" => "Description de la catégorie", + "category_parent" => 0 + ]); + echo "

getters de category

"; + echo $category1->getCategoryId(); + echo "
"; + echo $category1->getCategoryName(); + echo "
"; + echo $category1->getCategorySlug(); + echo "
"; + echo $category1->getCategoryDescription(); + echo "
"; + echo $category1->getCategoryParent(); + echo "

"; + var_dump($category1); + ?> +

Table Comment

+

Test de model/Mapping/CommentMapping.php

+ 1, + "comment_text" => "Texte du commentaire", + "comment_parent" => 0, + "comment_date_create" => "2021-09-01 12:00:00", + "comment_date_update" => "2023-09-01 12:00:00", + "comment_date_publish" => new DateTime(), + "comment_is_published" => true, + "user_user_id" => 1, + "article_article_id" => 1 + ]); + echo "

getters de comment

"; + echo $comment1->getCommentId(); + echo "
"; + echo $comment1->getCommentText(); + echo "
"; + echo $comment1->getCommentParent(); + echo "
"; + echo $comment1->getCommentDateCreate(); + echo "
"; + echo $comment1->getCommentDateUpdate(); + echo "
"; + echo $comment1->getCommentDatePublish(); + echo "
"; + echo $comment1->getCommentIsPublished(); + echo "
"; + echo $comment1->getUserUserId(); + echo "
"; + echo $comment1->getArticleArticleId(); + echo "

"; + var_dump($comment1); + ?> +

Table File

+

Test de model/Mapping/FileMapping.php

+ 1, + "file_url" => "https://trello-logos.s3.amazonaws.com/c3f2bef1693561dfb24e0f00aa592c80/30.png", + "file_description" => "Description du fichier", + "file_type" => "png", + ]); + echo "

getters de file

"; + echo $file1->getFileId(); + echo "
"; + echo $file1->getFileUrl(); + echo "
"; + echo $file1->getFileDescription(); + echo "
"; + echo $file1->getFileType(); + echo "

"; + var_dump($file1); + ?> +

Table Permission

+

Test de model/Mapping/PermissionMapping.php

+ 1, + "permission_name" => "Nom de la permission", + "permission_description" => "Description de la permission", + ]); + echo "

getters de permission

"; + echo $permission1->getPermissionId(); + echo "
"; + echo $permission1->getPermissionName(); + echo "
"; + echo $permission1->getPermissionDescription(); + echo "

"; + var_dump($permission1); + ?> +

Table Tag

+

Test de model/Mapping/TagMapping.php

+ 1, + "tag_slug" => "nom du tag", + ]); + echo "

getters de tag

"; + echo $tag1->getTagId(); + echo "
"; + echo $tag1->getTagSlug(); + echo "

"; + var_dump($tag1); + ?> +

Table User

+

Test de model/Mapping/UserMapping.php

+ 1, + "user_login" => "MikeTyson", + "user_password" => "password", + "user_full_name" => "Mike Tyson", + "user_mail" => "test@cf2m.be", + "user_status" => 1, + "user_secret_key" => "secret 123", + "permission_permission_id" => 1 + ]); + echo "

getters de user

"; + echo $user1->getUserId(); + echo "
"; + echo $user1->getUserLogin(); + echo "
"; + echo $user1->getUserPassword(); + echo "
"; + echo $user1->getUserFullName(); + echo "
"; + echo $user1->getUserMail(); + echo "
"; + echo $user1->getUserStatus(); + echo "
"; + echo $user1->getUserSecretKey(); + echo "
"; + echo $user1->getPermissionPermissionId(); + echo "

"; + var_dump($user1); + ?> + + diff --git a/test/Charly/02-mapping/04-manager/.gitignore b/test/Charly/02-mapping/04-manager/.gitignore new file mode 100644 index 0000000..d11ccf2 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/.gitignore @@ -0,0 +1,11 @@ +# Ignore config file +config.php +# vendor contient les librairies externes en PHP +/vendor +# fichers non envoyés +# PHPStorm +.idea +# VSCODE +.vscode +# Charly +.history diff --git a/test/Charly/02-mapping/04-manager/config.php.ini b/test/Charly/02-mapping/04-manager/config.php.ini new file mode 100644 index 0000000..ae92c13 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/02-mapping/04-manager/controller/README.md b/test/Charly/02-mapping/04-manager/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/02-mapping/04-manager/model/Abstract/AbstractMapping.php b/test/Charly/02-mapping/04-manager/model/Abstract/AbstractMapping.php new file mode 100644 index 0000000..6c5f9c1 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Abstract/AbstractMapping.php @@ -0,0 +1,42 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst', $tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + } else { + // sinon, on affiche un message d'erreur (à commenter en prod) + echo "$methodeName n'est pas un setter valide
"; + } + } + } +} + + diff --git a/test/Charly/02-mapping/04-manager/model/Abstract/README.md b/test/Charly/02-mapping/04-manager/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/02-mapping/04-manager/model/Interface/InterfaceManager.php b/test/Charly/02-mapping/04-manager/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..421a87f --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Interface/InterfaceManager.php @@ -0,0 +1,16 @@ +connect = $db; + } + + // sélection de tous les articles + public function selectAll(): ?array + { + // requête SQL + $sql = "SELECT * FROM `comment` -- WHERE `comment_id`=999 + ORDER BY `comment_date_create` DESC"; + // query car pas d'entrées d'utilisateur + $select = $this->connect->query($sql); + + // si on ne récupère rien, on quitte avec un message d'erreur + if($select->rowCount()===0) return null; + + // on transforme nos résultats en tableau associatif + $array = $select->fetchAll(PDO::FETCH_ASSOC); + + // on ferme le curseur + $select->closeCursor(); + + // on va stocker les commentaires dans un tableau + $arrayComment = []; + + /* pour chaque valeur, on va créer une instance de classe + CommentMapping, liée à la table qu'on va manager + */ + foreach($array as $value){ + // on remplit un nouveau tableau contenant les commentaires + $arrayComment[] = new CommentMapping($value); + } + + // on retourne le tableau + return $arrayComment; + } + + // récupération d'un commentaire via son id + public function selectOneById(int $id): null|string|CommentMapping + { + + // requête préparée + $sql = "SELECT * FROM `comment` WHERE `comment_id`= ?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + $prepare->execute(); + + // pas de résultat = null + if($prepare->rowCount()===0) return null; + + // récupération des valeurs en tableau associatif + $result = $prepare->fetch(PDO::FETCH_ASSOC); + + // création de l'instance CommentMapping + $result = new CommentMapping($result); + + $prepare->closeCursor(); + + return $result; + + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + // mise à jour d'un commentaire + public function update(AbstractMapping $mapping): bool|string + { + + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + // requête préparée + $sql = "UPDATE `comment` SET `comment_text`=?, `comment_date_update`=? WHERE `comment_id`=?"; + // mise à jour de la date de modification + $mapping->setCommentDateUpdate(date("Y-m-d H:i:s")); + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + $prepare->bindValue(2,$mapping->getCommentDateUpdate()); + $prepare->bindValue(3,$mapping->getCommentId(), PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + + // insertion d'un commentaire - À modifier ! + public function insert(AbstractMapping $mapping): bool|string + { + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + + // requête préparée + $sql = "INSERT INTO `comment`(`comment_text`, `user_user_id`, `article_article_id` ) VALUES (?,1,1)"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + } + + // suppression d'un commentaire + public function delete(int $id): bool|string + { + // requête préparée + $sql = "DELETE FROM `comment` WHERE `comment_id`=?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/model/Mapping/ArticleMapping.php b/test/Charly/02-mapping/04-manager/model/Mapping/ArticleMapping.php new file mode 100644 index 0000000..7a2fc92 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Mapping/ArticleMapping.php @@ -0,0 +1,124 @@ +article_date_create; + } + + public function setArticleDateCreate(null|string|DateTime $article_date_create): void + { + $this->formatDateTime($article_date_create, "article_date_create"); + } + + public function getArticleDateUpdate(): null|string|DateTime + { + return $this->article_date_update; + } + + public function setArticleDateUpdate(null|string|DateTime $article_date_update): void + { + $this->formatDateTime($article_date_update, "article_date_update"); + } + + public function getArticleDatePublish(): null|string|DateTime + { + return $this->article_date_publish; + } + + public function setArticleDatePublish(null|string|DateTime $article_date_publish): void + { + $this->formatDateTime($article_date_publish, "article_date_publish"); + } + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + $this->user_user_id = $user_user_id; + } + + public function getArticleIsPublished(): ?bool + { + return $this->article_is_published; + } + + public function setArticleIsPublished(?bool $article_is_published): void + { + $this->article_is_published = $article_is_published; + } + + public function getArticleTitle(): ?string + { + return $this->article_title; + } + + public function setArticleTitle(?string $article_title): void + { + $article_title = trim(strip_tags($article_title)); + $this->article_title = $article_title; + } + + public function getArticleSlug(): ?string + { + return $this->article_slug; + } + + public function setArticleSlug(?string $article_slug): void + { + $this->article_slug = $this->slugify($article_slug === null ? $this->getArticleTitle() : $article_slug); + } + + public function getArticleId(): ?int + { + return $this->article_id; + } + + public function setArticleId(?int $article_id): void + { + if($article_id<=0 && $article_id !== null) throw new Exception("ID non valide"); + $this->article_id = $article_id; + } + + public function getArticleText(): ?string + { + return $this->article_text; + } + + public function setArticleText(?string $article_text): void + { + $this->article_text = $article_text; + } + + public function __toString(): string + { + return "article_title"; + } + + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/model/Mapping/CategoryMapping.php b/test/Charly/02-mapping/04-manager/model/Mapping/CategoryMapping.php new file mode 100644 index 0000000..cbb3d1b --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Mapping/CategoryMapping.php @@ -0,0 +1,89 @@ +category_id; + } + + public function setCategoryId(?int $category_id): void + { + if($category_id<=0) throw new Exception("ID non valide"); + $this->category_id = $category_id; + } + + public function getCategoryName(): ?string + { + + return $this->category_name; + + } + + public function setCategoryName(?string $category_name): void + { + + $text = trim(strip_tags($category_name)); + $this->category_name = $text; + } + + public function getCategorySlug(): ?string + { + return $this->category_slug; + } + + public function setCategorySlug(?string $category_slug): void + { + $this->category_slug = $this->slugify($category_slug); + } + + public function getCategoryDescription(): ?string + { + return $this->category_description; + } + + public function setCategoryDescription(?string $category_description): void + { + $this->category_description = $category_description; + } + + public function getCategoryParent(): ?int + { + return $this->category_parent; + } + + public function setCategoryParent(?float $category_parent): void + { + $this->category_parent = $category_parent; + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/model/Mapping/CommentMapping.php b/test/Charly/02-mapping/04-manager/model/Mapping/CommentMapping.php new file mode 100644 index 0000000..c3de343 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Mapping/CommentMapping.php @@ -0,0 +1,152 @@ +comment_id; + } + + public function setCommentId(?int $comment_id): void + { + if($comment_id<=0) throw new Exception("ID non valide"); + $this->comment_id = $comment_id; + } + + public function getCommentText(): ?string + { + + return $this->comment_text; + + } + + public function setCommentText(?string $comment_text): void + { + // cryptage + $text = trim(strip_tags($comment_text)); + $this->comment_text = $text; + } + + public function getCommentParent(): ?int + { + return $this->comment_parent; + } + + public function setCommentParent(?int $comment_parent): void + { + $this->comment_parent = $comment_parent; + } + + + + public function getCommentDateCreate(): null|string|DateTime + { + return $this->comment_date_create; + } + + public function setCommentDateCreate(null|string|DateTime $comment_date_create): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_create, "comment_date_create"); + + } + + + public function getCommentDateUpdate(): null|string|DateTime + { + return $this->comment_date_update; + } + + public function setCommentDateUpdate(null|string|DateTime $comment_date_update): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_update, "comment_date_update"); + + } + + + public function getCommentDatePublish(): null|string|DateTime + { + return $this->comment_date_publish; + } + + public function setCommentDatePublish(null|string|DateTime $comment_date_publish): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_publish, "comment_date_publish"); + + } + + + public function getCommentIsPublished(): ?bool + { + return $this->comment_is_published; + } + + public function setCommentIsPublished(?bool $comment_is_published): void + { + $this->comment_is_published = $comment_is_published; + } + + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + if($user_user_id<=0) throw new Exception("ID non valide"); + $this->user_user_id = $user_user_id; + } + + + + public function getArticleArticleId(): ?int + { + return $this->article_article_id; + } + + public function setArticleArticleId(?int $article_article_id): void + { + if($article_article_id<=0) throw new Exception("ID non valide"); + $this->article_article_id = $article_article_id; + } + + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/model/Mapping/FileMapping.php b/test/Charly/02-mapping/04-manager/model/Mapping/FileMapping.php new file mode 100644 index 0000000..e26665b --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Mapping/FileMapping.php @@ -0,0 +1,64 @@ +file_id; + } + + public function setFileId(?int $file_id): void + { + if ($file_id <= 0) { + throw new Exception("ID non valide"); + } + $this->file_id = $file_id; + } + + public function getFileUrl(): ?string + { + return html_entity_decode($this->file_url); + } + + public function setFileUrl(?string $file_url): void + { + $text = trim(strip_tags($file_url)); + $this->file_url = $text; + } + + public function getFileDescription(): ?string + { + return $this->file_description; + } + + public function setFileDescription(?string $file_description): void + { + $this->file_description = $file_description; + } + + public function getFileType(): ?string + { + return $this->file_type; + } + + public function setFileType(?string $file_type): void + { + $this->file_type = $file_type; + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/02-mapping/04-manager/model/Mapping/PermissionMapping.php b/test/Charly/02-mapping/04-manager/model/Mapping/PermissionMapping.php new file mode 100644 index 0000000..a17e27a --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Mapping/PermissionMapping.php @@ -0,0 +1,49 @@ +permission_id; + } + + public function setPermissionId(?int $permission_id): void + { + $this->permission_id = $permission_id; + } + + public function getPermissionName(): ?string + { + return $this->permission_name; + } + + public function setPermissionName(?string $permission_name): void + { + $this->permission_name = trim(strip_tags($permission_name)); + } + + public function getPermissionDescription(): ?string + { + return $this->permission_description; + } + + public function setPermissionDescription(?string $permission_description): void + { + $this->permission_description = trim(strip_tags($permission_description)); + } + +} + \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/model/Mapping/TagMapping.php b/test/Charly/02-mapping/04-manager/model/Mapping/TagMapping.php new file mode 100644 index 0000000..798f6b9 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Mapping/TagMapping.php @@ -0,0 +1,44 @@ +tag_id; + } + + public function setTagId(?int $tag_id): void + { + if ($tag_id <= 0) { + throw new Exception("ID non valide"); + } + $this->tag_id = $tag_id; + } + + public function getTagSlug(): ?string + { + + return $this->tag_slug; + } + + public function setTagSlug(?string $tag_slug): void + { + + $this->tag_slug = $this->slugify($tag_slug); + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/02-mapping/04-manager/model/Mapping/UserMapping.php b/test/Charly/02-mapping/04-manager/model/Mapping/UserMapping.php new file mode 100644 index 0000000..400ecea --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Mapping/UserMapping.php @@ -0,0 +1,87 @@ +user_id; + } + public function getUserLogin():string{ + return $this->user_login; + } + public function getUserPassword():string{ + return $this->user_password; + } + public function getUserFullName():?string{ + return $this->user_full_name; + } + public function getUserMail():string{ + return $this->user_mail; + } + public function getUserStatus():?int{ + return $this->user_status; + } + public function getUserSecretKey():string{ + return $this->user_secret_key; + } + public function getPermissionPermissionId():?int{ + return $this->permission_permission_id; + } + //setters + public function setUserId(?int $user_id){ + if ($user_id < 0)throw new Exception("ID non valide"); + $this->user_id = $user_id; + } + public function setUserLogin(?string $user_login){ + $this->user_login = trim(strip_tags($user_login)); + } + public function setUserPassword(?string $user_password){ + $this->user_password = trim(strip_tags($user_password)); + } + public function setUserFullName(?string $user_full_name){ + $this->user_full_name = trim(strip_tags($user_full_name)); + } + public function setUserMail(?string $user_mail){ + $this->user_mail = trim(strip_tags($user_mail)); + } + public function setUserStatus(?int $user_status){ + $this->user_status = $user_status; + } + public function setUserSecretKey(?string $user_secret_key){ + $this->user_secret_key = trim(strip_tags($user_secret_key)); + } + public function setPermissionPermissionId(?int $permission_permission_id){ + $this->permission_permission_id = $permission_permission_id; + } + + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/model/README.md b/test/Charly/02-mapping/04-manager/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/02-mapping/04-manager/model/Trait/README.md b/test/Charly/02-mapping/04-manager/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/model/Trait/TraitDateTime.php b/test/Charly/02-mapping/04-manager/model/Trait/TraitDateTime.php new file mode 100644 index 0000000..6b56182 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Trait/TraitDateTime.php @@ -0,0 +1,34 @@ +$paramName = $date->format("Y-m-d H:i:s"); + } catch (Exception $e) { + // en cas d'échec, on met la date à null + $this->$paramName = null; + } + // si c'est un objet (DateTime seul possible) + }elseif (is_object($date)){ + // on formate la date en string en DATETIME + $this->$paramName = $date->format("Y-m-d H:i:s"); + }else{ + $this->$paramName = null; + } + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/model/Trait/TraitSlugify.php b/test/Charly/02-mapping/04-manager/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/02-mapping/04-manager/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ +PyA07*naRCr$Oy?K;mXL;uNyK8K@XDykvuc}h1w3K!%v;q3 zGkvE2oO7iArrXBGHnuU??mq1~LH8jeEc6d$;F(UZYwoN490t{4fj?FlPO(^`DFB3Pk7mWKUij zbKkMGdKP~Rj9C{iA`AmweDS9|^w2}R^2#e1m1;3^Y-biITOeKh1zrx%Om1?dkdfT+ z^99rdehnDPJL&gsJmj2OKwaGGm<4AM#|vTO@exw!h#vZM=N*yZpHeREG? zITcvr``LW53mMoZRLy;=Sj)NZX4CpZ@Gc9+H?; z5=SkNF8MuqS8v#SLnRgzT!e;>LZc>YCRmx3M=~Ico#Rshwf>s<+~g+sCs>qsm-8|8 zo9nOUJ)#wmF6v${3ZxQ~TBg;CNf&iVFWi%6-%Nv0Tu=i70V+@<#PfVCO!XxeE^$K> z3<-#mpUpWSvf{Kv@_YFng*q>#z6_Amg}j#nC=pf!PU7y)${gwI)NE1bdH@&hN-nQ= zZh>@p-H&&5HjSI9O;%`Vp!z@+`5qBAS<|`I?o$!S zu4O8KrXsMzNVWyZI@YsQ2|#Br!jsE2@9Ltw2VT4&NK2)Hib-3R^y0YN%E47u%}{{! z4GqxYnMr2KWqjAdOSyPvY(?wVRLo-HEotaQQADUrWT<{_!8E9*U24jAjlov;J9X5VDmb5jTx%?f_cpQzZo$Ow~&kQy)=MErdJe%=}zrJPDrH647hf?^vbsbnZ8 zwW+46<5kc=jzXOVmS<>>)lkVGTUkc^2#kopmRI<=wF*5E+_d#lws&>W7Jw^aNY4hG}4i0z5+{h7?FmsKp>ndj(d65w~vM$*#^$ z+GCK0mVjA5U*0{{0_ma_(}I?CdU`TyYirXnND}n7Ea{>y?uB?#Gf2g*RWTWk;HU2h zNXIFpGn8x>->~8gthlp2h5~2|(nz@40@T?cl_XTNC3V9FNPQDLTP&+b#+zY95OVwG zom|%0MZ2$)N7zyhl6R3LQk?Z|HsCFHcittlAV{aCCZhKC_7+Gl1me!>Jym5?#g77o zihvY&;hlrLGBHj*lclUcYN{lU8HG4zMC6Oj4dU9V_@x43QzxOsk|uRj10)s|cUM5F zYM`+tRUkDyQnfrQLk-g1T|IPGCH@ruILQ>v_rdggs4`9y1@){h!F%jQiw0@KiYlAh zYE@gN3qfahRrE+?SdjE#hj@8nfIxW>~z|=XZPiplNG7U=nz-V z&kG?8!7(B2f@`Y3i7PBw>A5t**=ui^UikBPS}l;C$BTO*4sFCG6YZCplud&Z0@8s) z{CaXyxw}=vR`IHU)CmI|-=jD=%FxkwXmc!#a!tjWs;(J7l!db-*`y!Jl1faflD{!X zZDAONSmiR^m4IDtJ0IPB4ej{~xgbIk%Cg`BFT}G=QfpRXZ|sLQm(Vfr#KXqGmJOnr z9aRsrF2ohR@b9@Okal!*%sJDRCB5*sZvHb+AQh{n93GRhWiSXlcjOQ+O-`xAQ4nc& zR=cbr*&yJhpFGPmk39_I!%(YW2SIE}^`SIKCEYUzq_I0J_1Kyvqy<4Tg_FScSk> z?rp=AYInEJ0hISp;jg%^@!!Oq4Ggk@%}Nh0GdlU$rPr`6O4C&faSemOFqrZ@!oD6h z-hDG$?!OZ@tt85t6l0L4FcsL7$8UO!x}YU(fpodT@idmyk5{;9P_iuz(!&Q8NK5G~ z0Zwd54bnkCN6q8)r=H>mfBQEuG6-HlWqca|Z9>fKO}*)VVrq4{wGERF&u1q&?p?c^ zySg{gGviU2oF?1RLD8`|mWfz>?=5Wq;=h7b?U1u5IP!9Xw79(Ww>09a!f!4ce?gE+ zowO~dOE4`|#UBA(||ZN@pn8CMVi0QXjmUUBCYsSl0t> z4kcF?f#$cQEs(~6$I0$)3#5x(p3CETYS*n>(kQm12}q|JAT=aQqe0qMDskYMXEaEM z1*D~S1yXTq)4tDoEcVdDXSQC=E~}GlzDmk)C=fB;m8QIB6W9FjpNH*hpxvS3=nSup zN$0w|Es!Q46=jB>{PZWPpY*lYUd3pEba{Ypv1g${npo0>Kx!&?x4oEv^lSLTgW#9z zAl2O5*&U{*OXR3zlwsidJ}ZIUbo22oS8`oPKfTi)ZY`t|8BBGinB2CC8~@`MVb=!e zO5??32Wg{A>aX&-f79i9=2K>P;e{7?=%ELB{q@&dAYCjtmdo=_57OzAENR*gX)hIH zODZ5eLFCP~q`DT`NaW16YR#Y(a0y?@5%2>W$#C!1J-n}T4Vwy(&U+Y^!(`fIY<(9u z{onr{cCCY+ERn5S>*j*81=87x08tBk?z!g_NZ)+(O^jCJXt}^|ap!R|NF}=~?(P6D zO$tbJ1lWq`Ahf@wk?uGDuWwwxlsY1*CK8l?gcK1F4j7(!fe=Zd|dM zn|n8KquE8rjE`+NOt}WbD>K~uAHD!LUk)pBI(sagHL4!l*a%u6oefga-F@bnrW8#)*h*8nX^DD1p5}_XmJ2p4$nFpkakzA?0xD94bs75ipY>y()p}uv*i>k zEB{ZvtC&<7;Rw%)RJ~JrOE=>3@zs0y$lA;3I5LH6S{zRYSl4dj%K!7A7Z$J5CzW3Fy5DG}6;EX^T z`^CytReh#fe1)p?mqySNnyiWp-k;sded{l0citxJMNGBZOs((W@_+wn(zos*vO`Kn zs0a^<>U}G_8%xa8m%u!hw3RqoJV2JiGv|V|7=u)CcTWM*Uf<*GCw|PMfA#051nKEM zTXW1h7o>7NU0AdQ0lVqtp1$3DFte6iIiT9^Fqn(z|JW^T`~3Z|aV7b}B)K-p3%6p@ zdQ85MyW0Zka)93A&!G-d`N0gB3(`_5hc8_)P1)UZ3R2Y_6HADyVSEwohE2N%Ye;jA zy_yHsT+Rlk4N+>yXHBf#8@c8WJ_CEU;5i|dtr|~TiKF-mEa>jG$P9}I$Z~k5x}l2E z7ZFKzH?gFLrBy9Y@hm{P7%MtACY93=cUSsEh31zFO*(y(HCTMC=W?!Hxsfh2g>OWZ zJ5${Bd!NGk_$`ow(3bwv*6g80TT&4sYt}f@FKl(eEC)c&cMh{aDlw_4W76lEKpGg* z^xdeFCYJP(zx*>I$?ndHNzW9dk}MKZf+#g4QoC*dnZTeoGT6gPZd$#StGd_Gm+NG@ zRAA!=ZlLdTABG)kkPh@PQR1G%IBM3{Uat4xT%Xs1mb3-ZbA8Fr@A2v&H6lW>q^8Nx z0w9&d(Y~jj>#dRHJ#fTJ{#6oV*M236k-QUT;V*k*Kad*?>(ShJIr zp2b8^VfXJpz{(F@2Rk=8rv>fppqS5-U0+L6VeYL?^#H zu-IvJazod8uJ2e!fA31njVrm~cRm3-*TU9*ZH0XiGJvIep))k+aNm#ORZD#QFPG>?)6e=z~I1=5QGdW%0v0jUg% zP?l7=yV{bT4x~a09C+bbzWvAl874;0IY^b{O7aleplOhfOfr!{FBX^CE4gCLX4dwu zqJQfquDJVl*4=so^!HGuN|;S44_+mUl~T*uL#zeT#jmB-Gtbi%NI)vHSp=ja=~)Nq zcwWn=%yDA(HD-h8aQ8&aw6!g#b(E{n&Ub)um&e;`E@nY=m&IRc!<2oh{tl2T?c?W6J zr_(cJBrerJllU}^$x1S8%5<}3Wj{N2?Bx9)xs%=Z+=jiek7>W8_`GSu!WQ9dHOHp$ zI1|veKzh!WTI)b(dj<4}!iKvmmUKiE>?I~$1|SuX$Oy!G7FZ>tL)viYC&Rj27rmKw zZoK^#uK(CwyzirTQZWOSDRwOz%d!ZqIho!waDUbNHogDZUgxEJT`MMC%B#Hu@1>OH z)xZcDMc8n6f3i$KDwiM`Qz63IGXKppBqI&oIP{tstk7fU)=RnZ&fB^3zK?R{)q5~A zDcuzAYLJFaEBDNFdE*VD38<&a5-*qOZVQ66#ob*3WSzseP-7s(lEyJX7{u=a$IL0`kuo(x`-~A$;t7kvs2o3n;$J&;5oeu=kQ<` z1xVw?ucj`>>iCiYmdW7~tBMerBg6+x+S}Us;vf7keDM$dE&W?IQ!M1MOcUF-FolRO z^J$u8$KeY#9@sBgx{X(}Gx3xafXY&h!e>1}~@8QiSJ zoWex`(o=nqghnWn)k2wRYN}FAA*iu&-FiNB-#y&*v3uEd-PO3+EV)!xHJ6KPtSqC< zkpbEg(;9qR%=8_#d$YyhN zc6ZU$-A%Tw4cmtmc7_aE#zh{Unk%KDD#y|xaY*F(M7~dZCabKeIL_i)E*EenH+n&L zw*}IR1fB6|o-IfZKK~5g`IA39KeWKbUc$uPjX|1<=haBb#+NVGB5*B8J8a%_B{$!8 z8<+373OAR<$)-uSx6{?$Nl&VSb~jBXoziOhVp$sIg<~5N|2fgq%wF|YNSRwMHKq1 z+_sggZ@Q6d-v2(@R`o(#hRAT}&i0UVvt&{(Y0D<(q{uocT-(O zAZx(J!^lHvjGOal;tVgfrJV~>5yuuu&j%lTh<*F^VzeyjnXIx4|J<_$>HcS);^9C0 z5{wRCSdb={P-4>9l1d#^7)O4SXm;d#3Q^f@o7r{k9;S3BKVF1lo2+GR54s zaczf`63-UPYZ;h*E9qIYnmyND$2IS}nYL9M z@$EE`ZBY|)zGdK>sGl7I(&ZA}VZ`oLYq@IU7CJ2hH!jntfm1T@DhSl1^!f*FUh*=r ze93%b9Va)}h@vp$>8BC}`xZ!-D;7_AUS|tZkx%*VU;OF3@+l{cnNW@8rvPbO?l|3r zTc}xkF3rzY>VdHZla!B=XNiF#Kuy`u)<&kSou2-6eBk5%nx6HW=vmW8#e|9(QL_xH zDl6oZ@+)+Qu%~w|H*VQPn-6JQCz!eCr+_{5XPcK$3gWHzHa82^%X*Kcf>fW`yZ{sG~Lr9x?gpM59i6TsK zdFK-Mmts?B_G>n^sY+E|s&kjbR5GHJX_ih^z6 ztm@&?Ti*v)?t+v-=o)y^Ef?zxpX+WmpkbA-v}9`AHY3v&gsWhF`v zssg?ti65yECkY=Nxi&Th0iu99Vl!#(>)Foz8!w}OszPTaP`?ihL(R__P8pb2Y~za0 zKLGFF16fmz&5-dIOAAs>Rh;z*quG{paPU~PdUan5q-Tzo3-XHP4pLRBoV)1euC4_% zixQwF7QImt5r8JvbpFe4g^}uz*^0~ko!fX|<8IbWlS1=6Lt5$Eb%mIFu|?(qDKhXoAj$@R$v zF3wyX-c#@_)KSD*N*#174)=F$52xsE%&UcZ{M2M^bQk(m`w)4P-%UCm6p{wH057OWL6ue(7sYTVXi7Z2d^mIGH zIk}UKgDeQrW5u;KzfcZ{P{ZEQh-#rqq83|11DDflLai#P@1}~OCa-HL{VRf zq@n7Wr>muk!1w7NvkS532c)sPt3bL3a*lF$qq-$s=p4`89X>rs2QXS7o$q3w+Z&X` zXbUg4g~@0a0;J6T+RQI7S)nh@Bw%pyhw<5VYI!Pgq#zkD*jaw*j(&XrrwMs2HNMlk#^68||pTnfTvxn8~U1V&B@ySVMN(E-TA~m3_ z1hF;QAQ1=?pd~nLc6T+ysOjU^FJvNetw{}weVmmg6_92fe6gg<5v0Glb<&2#Y%Bnc zJPpM-zN&xM8aa~nlUOY2g;aeNiY+75?YM4N*P5Ii+a-TZOokNURU>kuXcwE4y1-Ub z|7CKHDlwyC!g#70Fhax&0|UG=KBI>SThdjj+nh6g$cn({?I$$BJ{&xzq_xesOrkar zi6u`PCpI=KDQ~o6u$C=7{Tq1g?Kc=J=Q&&$V}ugZM3lv%+Nkz1U)483#IcRI zS2eMo&BE3V&qV{Yv7t5j!V94FJqgm^+@|mOL8=#u2C3fE^%QCi-9#obF0RMZsRL=i z*3wt8eN3!?HW6xmi!vkP%4%Dz++3v(8)^3{jHNx~iB0m9^7AZL@qB<(n#fOE+nf#3 z4h%Mv<&*37aMjB7xM`PT6Qk@KKf&7*gX|9{m=U0w2A*qCj(q$;N+9~=)uz^DJ)8ZN z`p@-iprt$)8zR0ZLHe6b3!LrFCLU)3P+ew7#udbVSyP8_;?4RkKIiH0vkS;bbxJaK@cdt|o6cLJGm0>E^HgUgn461=9)>8nQ2&&8XxsT*^N$pTA z!uUzzkSeFt_sLk6O2`PgS{q$$b#*M;6yGZBC$nIDN*Ii)Sug{<9J{+3q{=B@oV&XS zkS1p!F{$)wZX?6L>AQ;G>fV5puaGh=4A-WTbvPIld1G>rH%5+f&>vxjK*g%^*{ej9 zfSQzZ=FDkHK$?)}^|fwJsx7>*gs`9)NAuN5wH0rW8Mbk$lwevh>B1NG!at({0$CHv z6_dD6GM8b5bZHo}=3{`#f~&^h%!g13pccv?+z3zVg~;oqb|{(80N?ZCeo3*)2DV|T zMV*nc^@Oa*rs;HS(qdgCQyO=CD7Raza#M*TNnNQJ*zhSDFea9CV1Sn=bWG}-);R@f zGjTyDj!+=|-0D5t(y@W=N<><8gXFqc2BTq>$yCHxCgRt_hk0%MIOUYZbgjgABr$8C zwQ`%LMI@VFqR5c^KS{35UL&UvQBqz>LJOP=Qq4FLZ>D0J3@cjTHg-0FG-yg3or0cD&>GULhD zNyMw?lWHNdq7gBM$xj9j@$!ToB781Es<*F(Fqy=aSztS9zQ_H-$^ZZ$07*naRIq9f zw{~n`MJXaz)9!3!o0J@}?lp?tX^w_PCNma?^J5$y8RE#q2$R$(;88_tt=hVZN1}k6 z3}0$a=+^5q2{=!Eel@RWnGFKFVge zG=p>kOAisA$WuyXsTt-hOWNysO5^DJfBhAF$?k@F!K&lQ?lH&RZFa94Al1(okY*wQ zX^PLUzKYx0H?XQ~D3D5)T2%Y|oXdz;V#Q_KXy3e!ePcr$96rI=)FhMDB1fmk7%WUN zT$~_}Pl13Ufr?!Pu+q~hpgo(1oS%$b+=>;`0xyqgff7bYPF#ajENN}eR(3VJyS7af zmtdBaCB3-G3@7iXD(#|HR&00Trz96$rGgA8!pCJwm0xY#5^=XAPMi#3I3F-pDKS*c zGwIiusFo>s9yO(AXA#Jv#L#i6DRekf55JAIb4-!<5Ri#>j>NX|<%gJ+8kr!XLzF+F zkUOrtj6N4Sl`^az|7PXHQ#4sVw4k;qYM|O7^xPS3@S`g zA+G=%Dnf+PI!d^}aZ~u*`f*}#6VktGRRgwQ^6{=6Jh1U{`o=4CR%4JFQWnx6t?t>% zWxpo``?yZ3MlI^i=7NHBRu{}gO$(fr1JzccPAX`24CgS0l#HXUc#3=Fg<>@$GLEHS zF%iMO$s)&RW*D29q2T)z0-vg6B*jV!z%5(t$e|)97z9yVT2aP0ib0iFsz!N3K&zUQ z&4^SG&|dTDta{va#g(jcWfC?-RUa#36UDGK*UXGeE(Q7@eHqcs|cSxyV!)Q1*QS!&KlDKiDs*S zRdL`N<@bjCPDB`lDiLJa7BW4|5W%akhE=Q4QT6Gmc-(*WRcvrj(vwsYwnVJ=6US*u zy;MbqF~L0nsUkBRY=AU$W@mRhD-{LO$G-lT_``!3e(fB9)K(z9r9(h!(oxmPBXRd< zG8O|VkM=vSXZvSA4%;_ExeOCU7|C<+2TzedbexGJ$FaOXCDNvgd5V!o-UukBOh!sG z3{OokUdmGw>+DyU@k$h^QWin%*jJMK+nD>(kkDO&!JXDd?pb#!oBb5os;_qI21ucD z%~p0dCyqpsFxJbykd{<7uOCXQnt)VV)h=F;He6b5zmm@Vcw#_(h-?hdqy}Od%vcdc zg$Gl89hsV7C|_WBdWPwmPr;NfeNDFZBSQgMmt1s0DM|I#`zj?VR3H5wDVkqhrcrtr z<7}-d6NBU!k&o+p$_48!``ml^)oip=q~#n-Rj3y0?1sRKu)5m8m0m}2sV$<&RF-71 zmQ+A`;F+iDAjPYm7Nm(q)mdfP5n`v)09)pYhLYX2_#LsNo$KkZ*>#YLJ1U8zfs{|~ z?i<+jxsSunO~S(0u1GC}qsN(iYd@o}?`LZ70Of%}%$W*Z=^Qe3{`knSBIzqtdNX2h zYMg>!Wu{spAJ&+Xtajv4u9d09<0z!_MmB1>!qr-l61>#F1Fi7D&&hg^gXyWK=Qfo z3wcttn#wq?Cc+Gzqr#Pswe?LoxV>3*(VxqYkyb4xJq zF-w|UA)P)*vZ-~#K}^T{u`&PJ}fErY1Q&GR|LEXdSQSbBgt};MhY>OWNJj7V_4HE97u5g9hKCqDae|SNVPcv8VH7r%LoyB0hP=b!@RRtny9lQiYz54ytBItusTkx|7w{?qcg5H^GWFwazWK zEe0tR2pKaB?e3~NX(o|;2haxa6TOpXjexuk~!h4SU=pM!w37t!aN^wk1BbNP*IHM8{j7EYl`M>@l_ zS79P!knhQ`}!Y z&KRVtui%!>b*!#X2dOOYk{NL{hXU#5FMbL(_d$CG<(|l9DsH=KAeZYZH_n04DHxrG z!y^=4-bXMv$@tL|c$0amqf@xm0NV>lVX9Gvs=d#YjaN3{xa6gd9T8d~u8=Njs05Xz zSX^3!Of0DaX&Oq`ZPFl>?5-s1WR%5n1nGOH>Dv%vryi0Rl?7b3pk%wM+VW?VS zN)kg=*?C=%#bHRfLrN-UEW8}5o!BsZY$3kO3{2n06`+PvW(X+^4s&eZeqR5@FFCw# zAO1{%XlfcN745?Lfts1=*d~GR)k`vA=o1989fY(;usSqZ5B%HRx3PmP{Q}aN8fM8? zB=ll;mcsfTQaA5r<0n518&^RlO=x8lc_Oi-OA1mMeiX&-u4H#R*EU&FVL`#94M*Cb z^P@MhT|g=xKwDN@(jLt3I&W}k>cnW2Y&f$ z4*&9HrjHLYIW!o%v9YfmX(o@vtyJp69Nn=ae`O){+Eos!2B~l5tS*;3M zOLy)(P~l4_EC#uRivCrBLJ{&+q65ds9~tD>z5`4iJ3*=%Vw9>x<*Fizq`Z(+Xef`z z4GmICK~Q8-i(_A0 zAf3zI)EyG4`%~@E5uTJ)EQ6tv$KK%~_D_y8VusAPHU&rGP74cL0aF%?Daz)ugG)cB zN;Cz8ZiFT7SUyi}e4O!j-r@M$Z}ZNpuQIiFKg^VIWAUvfJq86zbuI!_MbOu^84c1H z2=R}y(1pApApJjf-p=kI!@8P|NiEw^qzQ?W1*F;gZ)Tg63RZSOCIhyv-7YOiWzlMP zzX4LQq!N=xbXEnV(ul4>dNgMsAl(|fyJ1^aS8@_6iMmEg_My(9SNVXXbe0TFirH4; z0!oJ5s(83gJ4_W}d;+Em>MIA3v{$e8#_cUQ*3EHOw`LZz`O)ZN`=%*4e5(!|lN^ZXR+M=^d>c|>RT zCH;S(SmNO11ji?*7%mm@GHJ@TP1V-Pp~z60=n9zfWyh|p%G5>yY1^bWGtKa!LyR1J zho3(FIF(~ZVRST(H3PL+6VgH*j7oJN2C2ALazgJ4q&COfZ4J`jjX|1CtKmY+52V2? zODZ7k{>b~;EFj(5uRH*uQ6^kq#du0GeQ`J1ydag^Ef-pv#TDl`X*i9ibt~$X4l$^C zAoE~`#}qijVwtF1qcWW*ELHJKRlI7AVx>e`q&wHHX8ko+klwjPd0*NCVTl#&=buli z$P5WcFCH?3cDM9SETN6W7rHPl-6@I@BpoWij|L8Nw3uh6T%qLqIPL8UoPPWz99xm0 zly)&&N-6Rj6@Nyg{E*uCBzu4LD}Mdc7a2Zu5XY-h9UD=s8CSGfJ&7yDbJgdhNoui` zNR$|2v!N6ZRF3^@ENL@HKcy|H0;$eiFAqy9G3i`Oin642kZ$Q$F=+#&+H27ujU{W6 z?w7fiG_f!$P@L5oqe&L3K_FCpxN^LDIU{jiRJtIRcf}4yS87A0S_Hn zAG+AIv|}a~0n#H!2BLNAB*)nNSdO$neM1xOywp9V+e27%1G|yG9y}BgH8G=-@owA`w?e;{wP3~hiYq#-2f;9F+WmD7ct{cas z2}lFdfu;pc*-ao7+MQTZad(?sI%N@02hv2{LcMPcP95m0YoEmV%CI)iGi|DGC)!bs z%ioBw72u^Vs&`v814fzy~6s0#Z} zjIeKPjB(eYY{z-@L~>nI-?cKGlu>Mpv}mk)6?$Ehp@Rqb)$`Bu){DPj>Wu@CFGH=S zxVCmE>gNGM#*@XNdLESPk%71X6K#+XSSt*oAd; zp)6^9`gSBSX*36s&u2jbU+-bSX4?h%Mzpq4;_d$ZQQi1Kw8(lX-XvM6O7#%QJiZ!IEU@Gv8L8`hsgNW`-2FI^Z85?GD;2qxl`HTGO`4h#<38axN-8f6^?k)tHN1nJF+{ z_VAoEo@uM>sN!lWPG^7-Q~jJ!YLo#zjzf8TjG+Vj_|dn%!ST1=gy9jaR8~>SqMCYGf$AwEk>Dj+@HX4BCO(p;KInxdB_NSiIG zsbkV}4AR7kCb|ufs6@3f_;?vdW2iUwpN6j2mZo>x6~byLxPJ&p0MkWCq)2u-&Hf-kY^WTHOULkj?_B z3WDP1hhz~aiMzxdu1_3D(iEpq#7`KDOJ_yn5N=MLR6zQ@M<3;(2Os44@#D)2r1kW9 zoJo`WhrW(v{(pPL1Gle>l6zpH&Mv# zktm2wF#fAw@ZA)TaLMBy(FY{mgT7&nrkB9g}t?AnntMBNdaz zk}XTdI9gOpdj8$r#F8d}(y5BsWPn+~tv~kb5 zC9PpeKdWg{bZiFOY`X8gnN4Cz-{T;aI6H|o>!UZ+FPi=kySwKLqzdy(YD(vEcb79r z)%|GBaw$Tz&a_EAR0s>BVU5=YCpk1-;DmJQi?EdAD7v2%L}hS;@QH*GD(9h$XE_-=q*0{Apf2ew?>Q zD@++KW!Iu&2@zeAL>i>xCP_b`8~8Y-0xN8jgFk22%|vaGAxstd+8gzRlmh~3@Z`)*~O zh&cCkDusjhVhN@N(%IH)R!q9Qvb#;bu3~~1iUlI|(6KONpfthHq&+D}Q+6_x9X-}S zIG5rSE5f{J3>hJgsPXw8m1D>FhcEvL#RCVRP*DAaM%5$oByX(KeVX(jWzQyc-o#&u zHCV;%RcZh_bD`_Dv50jtCr$lMeKi!{XSFxPmRhz30cj5)I*tGClH0g6%F$mjNf$j_ z!@{=&q?XF=_TGCdYn3I{AQg#-CFky*=fqJnNR>uZ^WHWmCY|lK#59$rr874ux#->9 zjvJOfPj&k)IG&QQ-5lBS(3Aa0EBotzyuMEo$dlpi1Zk(&#J6qKs`K?I?b$MT~$yTPyW)K|4IQM7GQQ%^s6)k zm9$D0i!?SarsjVtK1?FLtp^K>ev;@Hd0v?=U^6K`d&$jg@>8s+Kvw8=SV|SY;7Uwt zvGQZLu_m#kZ7Ib?RvGB1t(TS@1r7Wecqa$;iZuYh6+_&JFBEl zspPX|72rooFpc#IeR(jD4#D*n3 z;m=0n=wh;@=NmdpclU$M(mVsNVlJR}U4!px-|M*XgKJ~2b1XoSLwOH$>i7qC7V-rY|8>6gd(kg?v#z6LJK9S=ZY`*nZ1k*AQL&RTi5^}Qk;l5JFwZ9 z?O{)MKilk1w%Z-_lcLMl`nyUWM>4k}?%dQosj|SyczG4pCJ8G2c_k~Y8TEeb?s;MEu=Rhs61=8gKQt5(u^brB+LmH%e_r4Wv-@bjG z@Ow#V7x4m>MQadLL;RG(kP-0aa-xo2^OX3Q#G7Jq#U)l!lJR~ZZf}FdBqaS|gLn%SPey_@lM-H;DSR`+|cu@*Z;?YQhR40r)T(3fV6mj&` z*ZB40Kjxk9{}8+8D_Il)sC2;uMnIt4V=acH7)G&jof=mdFA!x##jTatGt}b{v!a@;`W`lS@4=Zn@$GqDD)?u-(uql`!tZ$RtRDmfQ5 z2ugS0xI!gX+1&)BH?dtbj`}(YvT5nGQvIxF0@A%tKEZeY;!lZ2PAoW|w0SWuWp=j( zQhnt`h-?{yRFlG@$Y92RSEnZV_1F*tG8fcz2?U@r2Spg>$}bFXLXS+fLc3Svl_#I( z@xTB7;KVQ~v2L-(t$|QzAQ=+Ud{!&j=2K3t9LiouieVVOebw) zMf#?+0=<}68OJB!l-EnSR_WPcGl83+YWf&c7f%N>C#Iro= zA}r}!Z@&@kxMasNaCa5zRA^QWV8VoFj~?cg@eyWHDK!p4Wp$OS8xQA=d@_N@8rx>_ zt+)B_U-~i=`wtKnWgd&r{gU=t+Qkb4Cdx&^_B3Hpl07*naREnB!>Fb5}^pQjC%}C43!#X;TNy& zCc9B&F*6h@6&xu;DUe1=nsP*j2p>Fj+JQ|6pMQpL|H&W1_(%(+=Lcr4L+Opcv$(swIybe1@KS1(%xNZ)wlwdm4IFI_eum9h6yQh0N6hUX3+WWup2 z+FBOH4m8nDM&Aj0sDqG>T9vn+dWuKB{xyuLX&kRctz3%Nyav87hZ=6Kc6YV=+h~mv zhLB`*dm^}}dz%92ZljalLP&c}n#My)jvj0)z!ZQwl>pat6exs8Jd-k*Ov8qouA=Lz z9dO-l*suz6Hl!`p8W%_w*b|U~Ww}_Ug`u-pT9Zde4k8~aB^-G(v9xZi*A$m;+cZHrMdhsGa`ugjyM!RlTJ~#9L0`x z154$76cw;qqC*rFMuz$3SN@!_mwu^uyD~H>5RR@Ye`sscAh~ORianOhumT*Kppf$Q z*oUoT`0edCa;4G5nvzLZB~rp{XQ&aQ4X+4^8{0(D4U7FfsD`uudgMmCO$q3fp^)nFMBI$EJZ=Z>|A zumwv@}zy39X*WZAwt2nhXNy+#X%w4oK_vGUnK>kRw0u8SrhmH9REgLH~wT1FpUSW7zXm>kKX z)dIgDLxk7NBaVGC!M;_3(J(xz1oP^vFGss~?_M?_6(zu5&E$Fh@F9+e9_4g8&g@#G zd{ZTXJgTh7rm+Tx`SxG_6^9>v6lxU}+sTN4P(+$#1mQd&m8GtdxTdI<>y_UnQ_gB| zWxA6Ot=Y*fnRWE#p{*7v4z3Ih7EFm16{U0ehi&0I7Wu4=vAv(Qw_k_xf$L$*YCQ^D zSVk(t+*Fp4K31iUu47qc6%{_4`m9W-n!1kbD(#qv(ABCG@`==|RC9Z5NexM|!3zUN zd3j=zQaY`a{V$}uDU}-jkNTRPEKkvd;OxEY)MsYnh@R%q3=O& z1nmL5-(AHgwqMK6N}AphxN4x2CO;%44@Ej4VmkB**L0KFv4Q>%+z7W_2isOdc?#On zir^>_v}PS>8z=xzdRUcE+B}w2ULqsq6<0X!Ne^Q&Y_0FG{6RXCvN)PSgH)JO+t;=% z=_!G_2#~(~%1hA|mtV1@mb6a6YogI6%77z5#IuJFvbUJ$L>N%ZWEDt--P(tMuvO)F6I60>sVVb z$yIfns7VOgYH6Svgs#nim&dvG60ZE6kHfb0uznS!q>LkUCDHwjGr#pK8&_sy!h?pJ ze$3W&N+^nr;X~qTC*wMmEtQ(lX)LMq+NxS|JfF0)QeohQXZiLY{U?|jQx;w}yZU3! zeA4<1o8%mu6!#>Y$f_|DX+GO`xf&w8svOMfC(WmAj-;anK&rijc;C^<>=rF>es_1N zLE7ZlHAJZ6#V_97NEoTC?%VkphN4h`)Keg}NPEKT^f8PoRx!^D|M(4Fd*pj?Vn`*7 zv@;p1nx_V-zUwEe{GrCR%hc{R#mhChA-jhAR$RiBRyVzc2uFFU(o`;`m3U5wlsqhh zDJvv%#a33_eFJTG+^A=?ID&ksj@TGt`Ri8lnf}GEU~EFUr2;&a5Hf^IdwP&sF-V1*+Yfwn z)n(k%yOm9~6geR-$Rxekbr!{Rse_7Dok|-N*LJb#o?FP>eG_b1qvv0UOX>7?LD~#fwGBz)NR57!OmGsD9^>W7aY`vYX5&IyQUU4VbVS>oH|WNI7D!JM zl`cbfcOgqU97a4P1C(Z_851Rgbe6zyutHO*7Ni0nml{KR-{c>^^d}$#mI_7eKvE@o z_<#m!!=aqdk_t%OFr+hr-Q>7u{Vs0F_OsDXV;5^`PKba>Tv4f^iV{T8f#EiT{(Enx z_x5XG&kk)xMfJfEITziAmKFh()5r&$DM%A5t8Hx3MRQ?6x_yqj+fkK@d%3Sr~B(4uG7Chd;k{ppo_`jTt8teU2;YGGC+X45X1 zfHW1FOxG$*WDGJlT*~^-e*~`HrpG?mI#?CUUA46?Q%V>??_rSUnqtyhJJzzQ5}-gT z8b`93wLp5>eD3T&UL=-OK$=YI-d8B_{R8_rYD5%WY4VnAjE(CXw0Qwp-@~68rx~G>10vUxsVPQVFpQ~xR5SR-H-e3EvaTC&vti@ z^YY|q?Cy%Z%=t?k2}qSCUEN3=btFP$Es&l8K;@|y2}nh6PtP_n**i1Cx8Hu9v2>bp zDx)T)8IhwTM%rpZsQ0Li4)XV3{xTDhve+QdppwF|g$^v*O+X8lzbYwFeRPe9b#OD9?({SfC1UZp!(KSz3(vo6L zrH(57q(bF8&4kN$2hv#CLDfQ=W6~I;GCj@^kjlwRMm*qLXLnm5JwqIx_UR{sRFoOM z``z!VrthJ_L5!tN9BE>^b|ZD^!Jrlf+LBr}d#9)Q&i*$T&t#}L8GJ*MMmBB`k@I{- zsGr=ok8gbSt4!?M2jio-qT+{75Q9_?nLRy7l>#6ks{;7#6+5}7cMF^IuqJddD>ZeF zMaNV?ltfLbw+;K|-Sq#5&%?$pY8ib5OL)AJPHu1~gp_+)kj|B)oNaSwXLp{Ji@8=zx_B7R57LJpeprn@93CFJ zFd&s?ZLOfGV>oF&tAr6%!{F`dDZcm4+e`{b%`}1GVuU7c7?JgBbku4L{N!gm{I`Ec z>G*M?nF$e8QM1>yFqu{xRO9aEvu3d+l{%rotS^M$UAddPyEd{V551uSm8zRt?`<*Xlb6z{c1q&~{2Ksp$~3x|&K z%ESo8behmkoi~t*=F==oI!{bmXo2($?*9BjWdHK*Z!3_Fj*eUikP2l^Q)#43p<^qP za->1}*3=Z=k3m{9G8&|ji5rAuf~o@P{wJQ{(f{&asSFPh6=!hc0f{w9!zz&KnJ^21 zRASP;NQ3mA?#*nSiRhAcxN1eoEC@)a(k3(QY3wVvvEkDnB7MjER3;ZIChsSiux8_} zx^B+)adMqhU#wGu^h7BAq(^vVQiC*d(lJO4mCWg^lo@#8xpP8h5Rf)o(&ofbDoGsW zTn?o|a(CXqwpMm`frT)?r02K)`JdJ3!}0O)#t3UN2xO}??sj`+yGirPv66(;h0BM{!3IaOI2}u9*yJj2-NZXN~ zTVWhs!7UwYSXuT}cDEU%2c-ma*9~m@`~z^w258S}c4Yj}A{i~l(R_&`p~QXro8MF* zot&Iljv$@pher-DYT62t-k8B~&ufFwNp8W6s1k+QPl@gA0m>RwsIiZL? zNi+7mF0bb9>d}ay(lGjT|K;4(vx%K~lRjxVDHRp|N{-2R#$sws7nlC)k7D0;HLPC= zxm*)So2!_yZ@R=FJs!aG?+ozT^qA@z!p+9nU4yg&sn7z&k_t%2Rd>$W(gNoL>58Jq ztn6+s#i4XaZXS>(4o3^5$#ylrCH>YnzNvI~CnuH(NULE;4N20NNS*YtL;D%RMBH5g zsnASQMnr}x?(`Ht`^SIgr{DS)j6#8^Tu_!Y#8(P~iE(SVyK}8+1ElFNQd&m0r2F~Q zwyU|Kk zclU4&p53>P{k0-_$BErtv7~cB`iDxHK@=3<4M;mN8kV$k4ZVfhEK6EyOL1@>kR~(i zl=yhdlE!y-{+RTizwr&FySqF=nlJMBz&l8sr9f(EOX?aSS)+zMInJ~H?H~B{!;dPy zF0s3NYLK2B5(o!ghz!zECPR~M$n^1vEmv}NCCdh>lNL&<_A2Cr;haU`%1vDM`A@(t zR}tl0jFe1(IYrE?gYB~oNM|*G&pJp`caLh!F@#@*8fbN(81USIy&S=3#<2-Z$?obM zOP65E3_Sll-~J;3={SV7a|Y5|JJ--XBe{aa-Gy>{W;RH-uZNCYy(hLl#k=M1&RZvy z63jn;Q!ME+2I&(=4sp~AshW~FaxnamlnFV@BN`pyhhO_U_I>X$rA}|wD)YFzNyfE_ zwl3mhl8ucO>c!m^;cMaUUg@sj{;gMWZ6(9Tib=LyQ(ZCwQc;i(-oKk|pS=%m*oBw2 zaGYk4#-qra5p~`{s^_>V3Z4OPO_lk{p?5eT`btt?mgaz1^T{o~@Vp0WC$uDTB(-ugZ7t8!5m%jDj9Tp!bXZH+oqaoW_@4}n|}LVxPBLY z%F;uKo3qEs{LH#*dVVaa?#t2bsnXLPnl>Ug^XhnkpB_HMaLS_Sy3_)pDe5v%+V|1A zyHE3-FaHUQORHM5B~AKW8w=-jt!l#m>cL%`^3wZDUJ}yVKcqsy)Fh>-Yp341-#zU+=UDjHvgKHpvC%GSTNGB-K?n{)W(v6-+wkahzsLH! z?^7UkQj*5$2Wg=JttvC(pLG0={V!!AcqtmPJ66UZm6FvpHkJV8XCI9NKJh+a;%J~UE^%eP=e{JVZX!Im5$uiYHP|!m z-Qy@Yx@?ZyRo#8_L0T}`H1kG*)P?QXXfeaMcl8>qOk~jHhS<~)5yxa(UBE~pvwaH| z{r<05bJx8w}0V4P`*g75zne5z-#F|ijT*66%#SjF2U#=JDia_Y+!qt z31{8`nELVaf#VL9I!X?kK=nfV6Zi3;x8mMDkNqK%lq|$V&OzD zoL4moGpuq%Sqs>qHp9A6209I3bE$#ychASPPrV-)I|8UG>la9QWtA5^xGley4es!_ zN7@ zl*Z8-iy>i{a9GMg-aIS(XE4mR@zPy)GN3Kq*eEnS?XT#-ToK zpxki~awyrAB+W#^0@8|i&&Nc9bY!)tyXl%rq--N<}@6s~Lw0b_it|M+$zmMNQZTj>klLcTbvwY-Q9V&=+9&=7E%n z=O$X5EOKT9J8cIm8yfM%aMqdAY-x0KUv9CKeH&wWrSe=>b>{jk>C8*11VcZ z>H35Hut|Lm>spwYg9@BAVj512k49}<8kMYs=%|kCtYndmMy1A4)p^HZ+$Y};3@h&) zq+Tggsi@(ZA^Wo=WwpRt$vFDK53x^yRIU3qIuOFkjcs^oMup-EY z=?%9a2?jzc&LU=KP}0(hCvUz5FaPs4puG*Cx+~TA`)QNvoFc=(2!|kz;Y0O@<6V&& zls6|)5wfHz22~7tcatGYY|;Zh_kNU|cM4EjrWi+F%SLUJ`fV{1#3Y$$2&7Us`nFqd z#See^thNcrD?g114T?PvONaJFq5^LMB=wT->yqMgr}KCp+={b$`XO+wXzN zBG{=;xVc2WB7K3(;PDN7>@y9kd}R|4%n{Q-dB(*I#BuDf@i?ZY9`%_phNtPSvXH2& z!uSuI37mT*FkzVFkQM_e|0-+49#MBSH%DJdIrCDcfz5VSdgZ*)(1_(*cOVf_$q39C zV)+(jL>545?c9lnZu$e(J@7C>$s}^A4j57^$}>27bsQB|J3iJZ$HJ+hQ8;((4ADMH zTazfWELg5Bv1Nj^!!)q9B7_-V{2;7%p8yQ25L=$U2T7#Y&LjVIS%}QnQDA?Tq`6E6 zx88aye*EJf?|UHSbm)YEO%CwfhHZGgr45}djBSOHb~8vC9VkyGu=FlL6TQJ+v{Tbj!v7<2wf zi2V1lFlJ56TXT9MQQg(^U2z-+@7?tZq$p&{&1z4(`pJ;XCIBm1Tk*=~t=OKq~ z5mTHPVr@y3va6h{`tz`*BfYyVb>*1y#SZ}|9S+phNUID2lt9gc)YoX4eX$Cp@pYdNJJmE%>KZ6Z+o)qvvYG>N zeC8axD77<4tXYdcFSs1;>no)D zIrRgAlznGJn&!dc!P4tGrxrUV(W@#k3|&q5zeV&@wTIyN^0BCAHK+C@N-PCZs;_Cw zKwHE>TYU`<_`(N)W9F(lP$30UuZV@JE8GJ}cPG*Bo#5T=rtZEKAPuYtd8VpViHCtE z#`Ri~cy|3}Y-sO*RauF&X(MAK5zD2p`N?PS$hE%)8k&G)3dj+p4AB&9QooYu7YO;3 zFTJmqU&;x{wuht%&O#YZte%WhYo}mbv4h?8BI3fgE6i{x*0f%Xt&Y@XY&73*8u(CHdTha*TBv{lJKQq!BH z0xOq>mFz@)ycCcB{qIv*LJ@CRmavZ(wJch4mFCPPy#c02^0Tm5T|$_p5=*^U`VO z&xBz`#-NfPoGX3(`<(#Nu8yM?7>gG_=^lCHk#DLb?QNi$Q`!PxL(0X=TO08D&Rs~d ziExPS{S+d(G@4#pj=Qe87Fe@c_3@-6b$bD+FU}{j!KX_V$lmI%N~I1jD+pHMwCZV? zS2qb^*Fv*lW9qplVmL!FqsxI3b|hD2T8w<-CGW|4u}Q`DE~?A17%2;OyD-_`P}f*7 zEu_K*S}kB(4p`sOftS{ALI*6Vugk9CY0E^G($?#9YS}hQ92?O@C!%d_`1fyqgN@HW z541K(u56gawsTnlqtZ0GDw!IjbOz~LB}hqPI3hX{pBOm{)16WYQ?X(OsS}C~Wk_ea zZ50+;#@FE3AAA{@K2iFrN@|~1z=HQ#45WSl_XWnDzJDixRC9Of-EC%9hJ6jBS;IgF zfL&~V*qFi#8#bcJQ1ym#p)_KQ@ojIwpD(=vsiiA{W>RkDNRSh!YtI{@KIARbL?cawRd9Vfm3kk=RXF_84pxOC9Wg&eGN;OlTvZoUJR<9 zLCWwLt3^)-eRJza6Z6+iugtNc|BZ`wpOu+?JQ&Hb(Ai^9{ zuf7JKi{NXG8rWQBpyY@dIQVOy0>;+?v8V#6Dw?6Xqf?Sf5elzylP6^d%hbwiH3buT zusDCykL#Vx&J)+MBOZE(iz5om{d0w z(P$L2&pZ)zO#U8KrO;@4)sonL!gGo!$QIvv2dR>1l&CqwM4E-h02z-pi45M@x)mE5 zTab&!kufaUhrr~d=f^gciW*8Kr3qDX^JYAC*Iiip$iqNevxHudO$#s>2GN}+x~RJ{ zc*+UH=is7MSrSGhnH3Vl+2anz3DME0>u{ww9NAl>GV<9orXj_{H}VLzBQ0*xHLLCWa5B`S&(huaPgFyBnw2_dxoeg^#<(%s*zI0jW|SRgcm)5~{$~ zde-1IvdBepC^2%V=tyGG&Huu4H{Ss?>=fgMa>ueMdsL64eA%HQE2}?(;+M2~67eK4 z7^rr_7-7axAFaaV+EJKZKLO(oISB9i_ywq#H$&-cIn~yJUQH#*)WjC2h`0HRa~A_C z?O7^|LY((10MdcRz)~w6MJ>(Pu&WV`ok?lAk#cE&vP!)wDXP>&1r#!Wtj-RM2!-&< zLl0rm9k-)(?P?&|A!dQpGqedpwR8nlUMUbKHmQ>8lH_dyWe#w3s1|3|AB;JuLTysT zmlZ)?MAO}o%&WRaq} z3ma9PDXe(p2|W6Tn~~bEQ9=!-oAp5IN`{E6%HE`)!1J%H#gbP1-!n`=>R>5MR3MBp z*TgV0j>)6Opnl3kob|bnn`CyP}(8?dFl9lJUba7~7znDY~Y!}?GR_2eTpggL8CqCyIAN`bAkOB2AN4I8l&8MM2dh#4+wl3BFBz8ZJ^>IQ6k{dKt6gh&aC&LhX^ znndCObs!++V2ERb)$3s*W<`**(0ON zrjEDtsLn6~e?*)tDx54{y#IbY^7}smT*Sn-%)+s3mBFK{DY90um%^t>_2NkLyt}+@ zK1&?HyGp8YZrwpRJU$9l%^8$uS^xC0wA9cVGqFzhTU zlR3ni+i~-iKgar)UV@Ws1#)Sry=#y|ng@u-*$pf~lv@6+tKnWKt1VK6_GxuBTAEvs zhKtH*6!EfhoO#w+_`-!3V&=TL61yZo8LHs^oRaxW4o-SMNIfCuBjt&T%cA*-R2J<{ z4lA2>U|TkcO`RRsnMorZ4guj9!d46hD^;)>q8AjFgaLAxsh+wj>!oAWDm-?}Kd|Qh z2PAEdiSdk^<}B6JSi(hlADilg?guH=T}woy3cHMhiDRn9;k4?BI5=E`csn`4x@;<7 zI}Vbrjchz3y>e>Lo{zETo+LeBvJn&EIJ0*1Z3RR%7D}cUTlK#SWtZ-rMY(%N2PVs# z@Xw&*h;hzun2|8z zDFZ(j8biwc26qn_GI2l?gb=7Di!1YYN=tG2I}g^;@Fc< z!nq&#Z;YQl9c9CY!3aeVvBGe&HX^2l2#X3*P%xt6b!lV1IR8dq(&kLLz^>LLcDA&j zp|u$aIOs5KBq^Eb-POKpmt+9uiiY5tB+)B%lx1MZ_%X6+Ni@i8-ipP4_#4(d^)wRA zjR-R#K9h#Y3>6(qChtQAp}Wsp2UDcPjO${!4IGX#oHKd`j;b7k>JA&R3`0d6r9xBW z=41k>DMRDvGEDsZ1t>dqHc(v-gu_52sq(s9P>&UWFgr{2Sa+Zvql~ zxkM18qy_%#pZ~&-$lYyiRg!d{11V=PS5ym9n0mwi^=o;4%Qn2;-iS`=hGrttnZov$ zUd3O2_ETWzHXxglObjJSZKd)SF>Lfp3=T}!UA6kCMm9(*q=Uzbg)qE+Easnb3g*tA zkEt_eB3@CASiBqvMPP-(h=d{tk&WYBR2(cW(3x@3mQ0{Ekw9xQfsRZDNjry>Yr|%D zHq%DdVCxNbP}77U>0See>NUd|(&~{ORvV?ZgSg>h%bJyV=FYpY@u7uqb~eH=sruWn zvuPPmTd0C66)Hatd2?AwI)kJG5*Zu^Wrm4~b{MCXjK)c|6L3(Z67kNQ*rLo3l0J5Z ziFj!o+uB-?tcap>+6Wx{-H*eVQ4f@s0#Ttlcpqi76QKN0x~v9S9eGLmc7)sDz#g27 z*;HC2sc?4*(#IZqq?=9pmP%3yxOuC*2_!5Pj(M%U6EAPyip}k9QV7gUXJGAW!fn6# zEjB#)AAotK>|kx%$hk}*SKdpR2f-xfBDKN>3R3dqLZu}bUSE$nN6*KhM;wj%NmG#t zN0BOt!3jqZ3P)jC5y_gN|5;*$j)PP-izI=WO(UJl3h0b*2yV!dFbZ2Y@(EPC46h}J zr!LYmj7xqS$vNGDU01w)Xwx3%qSAobKtnVSk^bl0=m09z@% zx^+8V-MSea(XeYCHzSIHwC6QXDSZBQJa4c0 z{>byY;V`VyQW&Li9DB;?IP&&t^wIm^na0c6vdh!BpB)#LQhQ!zdpLQU2{IjwD%fLHB7_{q4g zFpb(rSKy!zo{jK%#{e}YKqL%EITzKL+*@+;J!;o&2&DTuNL3g?GFoIFiSH5_+eOl}(3o+sytNrm?c9ns7TKbN+O-3Z{Ozw; z{nXP)Z`_JdMoWpp+t+Gie=G(iEQ>fayfjhmRAP*h)%sW|fzlEoa_3?wnJ@{5oP09I zOg{hA%7 zg{|vWW5x5&;f-gXLt@=}#bHjQrNf*YEz+(KD^{Mcz=tNHdMDq4-_5K{V) z0%)Gd;D0egAl|jjvsn8GY;HH6bTbp-I2zV4Gmb|)-2Tp*dONgr=P?l zx7>o(XO@Wf(_#pLQbbb(z2El~NQF|zsb+?RKkHZwk&vHi0Sq^=g2Bugm^t@Q%$R#9 zDo58L7q(!BO>~+r+QSBH%Y^Be;w9xrIS-W0W(%>M&Kr^mEJR4SPo$7;ZAG@T9WN|i zh%IYZV%zeiKvSdY0%sVA89b+p92+NzB=zeJK7e{6Eblz>sqxfChW}qH#ZxLKW?{0~aVDdx7nYSP z@l_T_s639*lO|%u+_|WqG8q%5O_5qZ?9|3$VosJo)F355H6?+B17#mZY@m75Hf&$B z9;;qmimmI`prfe)nXMavY!b1`3Z!;6$f72$84Y%CAt{7eJdo<(uSdZX_^{WGPzr$x z7nqJX&aa=1Q%lBRL`w!0G?!`Dnu>bJ1%`Gg9Y>w4^*f>rHOI|G%_q+VYD<9XI2g*)H$~z=UyGzoC9)7?*>BN)v0g!4K33=4Zj__g@(o#XK+>9S?%>b|O zY{v42jo6iJLA)%2WzRo{JAeO2IIGqH?HPnAeRK+ymZUyzXirkLH;{V%;=FoDX-a8f zSRrI{OqCM@&-+Q@YY3rO47o%SWh3e^W9BT>&zO#~spEmNQk0dJAr^_jV(inK(44O< zh}_)Ri0vCUqix47Y<*)5+PCjSmONz%r!Yn(z0sxl5*$TR2(CnaTT|P)L~-7dAgT#a zR%CR58pFUCH-z&>9fBiDM`2<*B(^BqaqtG+kPBPlNd_{mBLBBm#bD2yf+-(73plVI z7&A4Oj5@1A_p$@>UMeLxkv&?|23Rc)uN zppBEVfXxYDY2y~W(Xbf_Cyn-&COmQX-FW?;2Y?-|u+o%qN_uD#xpvtGeH8(ds7IT$ zpdM-{7l=Flay{Z&G7Xs0!;}>?ZCK$LLZK*1YO4_*H4JV^4ADpo;cx_|NiMFI{46rx zh)gntOlLyWTy!LWR0haqMKDs$Cpkgxv4^g)<#;rI=XQRr#yUhKpSz;u!v4Ct}q5PE*a5 z%S)7s>s?wB;(Z{^k6|!lMZc6GkiH#2+Ep@;C+{gP+XSwCQ0=Xc}EM`bzUx}-#OJKsob<+S|K=O z=n!OdFi8S5%c78yj}R8zA`L& zZ1te$xQ~ph!C4HXd3BR?K7!Tzh(YH;Y!sBp8+RB;d!9F zQkn!sw?!m>zux{{mX0`YJWg?0ju|c%=0u0%xatX*9UqCBv?&C7dUNS4lK3v$wtDMH zBxwUR67Ej%IH(q~okyIfN#tTUfKA?7$)m;aupvd;D z6q7pV-~6g-aE({apnR+&Ptp)KPhS622B|L2MenpMCgL+w3?#M6_&ACpu9R+}09v?T zE$Isq-y1tG_DY9T*ijiSW6cO=Myheb$SIgtG6I#YS(MwBIIQTr6P8qnq!QL3R^b;r zlS87q6rrPMUY!h%oH<(&a{xrg;Zt#XaIJTroMq10%_M-lT0RX+rMtZC7R5z zuS?PbNLi{xg=bhIgp)sIT2iOCA(h4U)(&jgx&u45ZNW2-Jb))3c@WL3RtX!(rEQlh zNYk#$U@_H6FABxgs)2x1RCT#vP{H%5be^=){ApD0e+aNY^MsfwHI;i~z{I7KeEUkBCffpFBv5Q0lxJGd%{AfHg0s z3LVaw^gRY94vy4fUe##4tE>)V>@bGeA;dBTas>e@^hY7xt3`!1j2i3W7;(~J7)vS2 z-lMdOLnhK;#ViWBI;p^;R}QJWy@K`~22%DLDS%WJ`3NIrTS(g`I#LdHwKQV&#$|Z< zrRQ<$KmLjJFTbLQ21$B5Sf9ie+mM?C)4Od&Vi~;+agnf2x6}Iek)(FdwpORrJYg?1 z;)!`#Cc5Z~-dT0VcwXHt*n3)5n_7*|tK}*!Ojf@+`Nxfn=qr6j%hVsx~&!MOkad)-q{J$0X!q*4UvKbjbXsD9Yo+@I6|0? zN}Moy3XZNAgNZ0XtR;yE3zwP78y=N>QFU>GGaU_~HRPhRGz??*1k`=(bd=6L0A?ji zqcBeFv5P$WTkKKo+!_=__8)-yheyvDI*#6^Anp3LwWKMyloUw$Y0Gw^VdqXPS+WH8 z+MLF_B^wKBo%~CqG1T*fKV-tsvV2Dv_XwBRJ3PMLS_P7 zWEclETtsNUdv$*^Ap>o(5LTyJ5Ib-@roI0(l%97CvLnkBQNcA~>XN1&QQs>SJ}7wZ zuLt=Tb-&|CBMOD;J@Ld7NbPDw zX=N1>Ep4htsc&R-NtL`c>MiDZB7}E&4Jf~~^+y8t2uOo7)dQ&(viW<^@lF-*@SIah zJ)k6vIR;9ZdIlS#QHlfOqi{&gC>$86!Z;&_@|2Bu#zjd^5l3{KiWxd0g<+sGVq!Q6ZmV=g!aIA|=gF|`EHOHK7!Re4lgqWx12?%whe1nI5+{1<+5$xoEJd-pwe zx@Vqo=GzXWd0_g>Kzb@;iqtvUP>zGf#zs8$_~W?cmYea+Q%@t8N+Xv{=Uc)D>m3!d zNd1zozaZ_R#tc-F2HtnxTkElO^a3H8gI0&7B%-=|ER$};3voZSQqkto3N?J}f zq(RA{Rz=ae(hzrV((Z3Z2SNI;fBX}d{^U}$vtiR+cirKhb=FyLOOX13%HK7iKozr6 ztQT&bi3A>h>~Z}5rkim8op&P=iR1(BI^R+=Wb{A;?M&u==D!Q7r$JB^QFr~j^r`L^ z0jXAPb>K$DQAu(K9ELtj16Cv?xu;G?3e^Bc!NL?&;ppL0F}b7)Ih?C=(YA1vR?bR9r=wJcr zpTnZe7zS>-;YM73*#fk&IQAWP{M$X}oO6O}cNgyG?p*xMI#x-}?h~96vZJFDRh5-! zX>G+5RDEy08P6Y*Fv%^!wDMs%uzD2Y%w%Ew(^V;a z%xWPkh@Nt)%an?&qM8#G7f6LIbPg*;?C66r>FncS95h)0RQhNb5)*YT#miOO5I}c# zo(CoA4cFg*D;He;&H|~dMm?yZ4$G7<3=s-Ry`SaFmf?>#+=R#Pdk{?x4QOMJQ_tl= zsX{V2TSvGagC-v!q20#3N*`@6FSUKsHE-woil9knKwp^>?P$q!lcgu9T2uYxhOVly zSFM4?x1|LH+Xk!Os}VtMs2pR>5}Z725+)jP)F6y1BZN|VU`1Vbg&xUpjIIVjshFl6 z8gh|}80d%?=!}O^f5PDycJ|T0%t>%+%8)ipM02L9v&7009${j4C+E=dg%Qv|<@~wv z`WtY?g3HlPNqWmIe|O*azW2TDC26sjt-~c!=h@?-N>6UXz{^iRiwFOG7nVHvG&ZkT zg^spnk)gH~LWA9jPRo@dXf{dZ;$2mh60Dqy5OY;kj3eJ-KA)Q9OTO;HMOqOU zl(hA#==0>ZEs5sr#li9|EOC-!9MsJs8MBb7t3cKKSr~r8JYd!&xFaj1_Az_bNtFng zLRKhF1Q~+do)`fx%mk@O(x&|gq#QiyCQ6CMJkO34Hm+EW=O29nuPuBUt6y1$bVsKo zH7{@4h&JTV0SB2d>-Z=V1>=yGO^_-|p61pn`kWU9Q5Wi(b>lJk@+yrdg+#HX#P-tC z2+{&UL6;iwJhq;S%PO|CJBQQmv??&lD#47}(HI*oM_nY2+Khp^q=^!nLZbeY(hA;{-jEz>HzOn{mODZtFqzV-|1996xNzz6|MwMQXtQDrM zvV#omP_LK+FG#|CN7z71iHVl#D6Gk&F!8v*tUEXq8S@IckROZ<_2u&*oh`&(1r{; zkwp@=bivTo2mBx!jnJ;5cqNEO<*Xw#%-b-yss6f@8e zH!<~`6Hq?q07Pa_0ftuqG<-^H>O&wfy64#dV5J>klGz;e=NN>3AdQo@xUr9;_ zkjIx5w6!IqfLYth4OqK)2^wBl1~ZXCBAZ61ox!?>E$DDE*xuHJ?WtC5MJJM~cnN!z zi87cKUNOsDvT>7}FTxcpv=CzX5mObtmhNQ)si(^FCqb!f%^0deF;o~KOsF0%fE-a) zflAxLuv`dbSwn17*2yiknV_v|6?y5_5(A}8P2nkRF=S@7Rd9!uArVnU-*|tl+Mrq_diHlnJ)h?0zB6^Ly$8O5ocV_9uJdft7UekFU({VC z6uhhq52R8>G?N87(?EL?XzIkK2Nt1y^=9nYxEY!DPPmMrlAvG$&2|#Y8@Hg%$)F>Z zL@JlT&bCG*kwK1?6r?-1E#TEQXyG>n$gngpG!cOz(vqrdsS!qbv=nhGjEYbM72z0$ zm6W3s1QP?EQ<8V zN>t67in=3a!#sF0Fnv4_w~(}4xpykHQCM9;>V;`o<48EdeWafaWI_(@+jRu!qqzRM z>u~kuSD>wFKLV+C(&WpWNb3e&pjjE2Ica5|19r5bbLm<%yu1QiUVIJau69@*DPi*@ zQ%RK6R-hxBMlzj3GMhn1x>Eql-_wSJt!+(W$K?y36jUR{uY@YAtwJ#LHtF)6v|$+^&DXwWsS}2d7&mnkSlLgf zEo{ITJsjbw;}AdO0F)m*1(-1fsEPw6Y=F#CEvo8Z$h6csbww81;@UQ)B-QeI2&j8y zeIdK;#v5)Bkam!9w7*DFKS-5Cb)@Q@#3ZSv3iF1O6EJA6?&<)xw*f0RVf7=6(e%bT zBpMn~5ss=h^b*%ppp!yfxt#pokxQe~biC4+UO_IYSg6v#xOb|fQ<@@G#!3aKW+p2n z1A2~i0!+T{u470sFn%vp`#i^2A%x=*3_M~1i3#bDA#q-IJ|lxDTTzN+WeKY19E4#< z&r_0f%y6KhR2p))5ycu(S+<_R9RMh^V|0UGKLaW_ONUh8-N&u%*b;)d=8CJ(-rNG? zh8wPPKmF-X?-$2jZl|UVInrYwX*3OCEVFl#vmbHH87^LhaO#eqm9ZqIt>@$5!D!X*ld(f zn+O~*Nx~|qECouUKscgez=fva1(5n@gw6=kAtT>+#XuRXG_m{BcKlfC?mC$NS`y=22JWCp{W&UZbf?iHf&wA1c`N9(6Vte zqRA{G?I{V3kQ>YTKDm4|CRM3Wq^=Y~D*#l$>Rni~>++>o^4=zotLvx)bwQ{!U{V3T zIzhz_At?@KvF?y5{bktOG{N#FQ5#iL$D@AcbkrU+6__wus{6@@l@!7u>2oR-9Q5nv z>GP{Z@9$kQZ+h6Jz?$0s=FaXsv41?-u96_V=BlgF*)jyuuH!1{T8h~ts;o?4dP*1& zWwrR60&B{Jy<#19u3Ur8bz9J}Y9ri+7GxWm5l!YWqO?NPQ*o|11UySK6>MNtXsoal zYU*EJSOzOO2zr%T%@QVA))QhU^pGkHmX3uHsw_vWwhGx{Wf*tbk#I*=Av9(rP*x(< z^2Mdhu5Qx9MTt%_j=F3^Al)6D?bfk=klJ<*zrXP&0coPGy{jZGa9{UNNvfDX{#IlZ zT&zr}yHf*hI*S;?Hi@i~vg@}XwPqt))^0-6y3MfKQfOPZS)4s|@(4r8 zHlcCzHY9d7p=I+nX~}4%ZA7!K#5hA)rpMVr`1j|slKjpZLv%v18hkDmLW&YF9z&?2 z6m~@koM9Cx8#4lo)WJgf?+j05!}fp`=sk4v9ZiIqqzS2jwb1IgnO%RMq&!IXQ-!@s z4!V=Cm*OUewzLD8T%m%Y%4744RIe*rCjqcpI6dIjlkfA?$mv;Xtiz!~>HN$MW} zot2{GP=WkjDB`EGVpM%0kAzNYppz3@vy2&@D!oOVO*vQPa)#J!SZe+<$BkZNI-_j0 zU*0bDBsD`LY-dl9GHXT(glh@Ub1CUam03HXBn?ln=%*j44sXgOrnau7!gOt-{!c1h zo~EZGhC(p?AImQD&ihA(l9Z04Ydo9uH^2Rr`?=44ZV05l5eOD5?kSmEPgcz_5TWH| zuc&OBJoljM_~tvPDVm}JmJg`@*i60^pue=If`P8|sY`r{4ejNm7A~mRLWQk+WHVTE zX>e1_dkk3xdJ53&&Y9o2#|DRs>aMm)JKEb}{QB3wbpQ8%|91$ay@1rO{uY}mnyatB z3l=Ttt?(FaQiV~rChQ6z-7Z3(H(0JDA79lt_jR5th|R7tv{*~I0s4*lM2jw9-sg@( zJ1EU2u%>C7^cs413DRHv>KE?kKmYk5koGcRdXl925Z#us0Mf2t>#I7T25RB>K>X7C zB6yyBeAORU)oQlCRD{1&cagr2Lm+)?SBu_2Dw6bc(+zY>W;Sfl7V4611s1Mfwah|4uQ1$p!8=<_NPT_ zcfi=wvE9fswvFqryIw%r%C2g(N#Bl=)E~C!E9BANfelVbeT_YJ{{G&_zO-L|yw5`* z-Mu$f45T;Qa04#C{BpFjGQ&03T;+c4YhUZPx~m->d@*_w_Y`E`y<0DSw6u%xnkVT! z_7sTr6_6HVAMK5??9VxaW6fjs)Oh#j`uoE^-B^^4i|enyPC(j5NqY6wSGr&S`qu{p zQoS=@U?!6hM*^u#+@jH_^#AN>Be471ovhe7n8L;DvGA7^|1!<|CpdxlJ@?lOOHcR2 zXW+i2rKMu1S5{W$j|qB_dF}qFfV(rfcz%v&Nl8f;x?nb&h2;_Jg9Hfw_4#1Aie6U zE8K5<;~N74sRo)phy%pI;1&*t`<%qPGs*cvczsSBP9%L@{cnD!fy?{RFNxpx1TZbR z_&ov3<9Qxli=VQxGI=&mVD78WHJBID*D+cv(F+johk)f66STY^j&WaGF$Z5?$LR0* z?0V8C5(&BP-Y_rvdq4fz&#%pKyeKTV`G4n_baZs&-)Dc$`)2IZCrGcja)JA;Z+>e) zAZ0^du2uvjAWkN3T(SCE$@}`gw}Fw|Nl(?*VAX%)dG)H#NzT7(N!r^A%KaJ} z8}pzqFE7snl*bViot>R>?y9P){5AI03)Ef3InMeScpn_|9Xoa)9*-Bjw4SK?=U~TK zYbktQ0+c`ZWsq|2Q3E0f`R)irKS()lynoJ3t)1+xcQ=^x_GFV@dBqjVadi0=mvsZF zN&@cLt*#}{vSrKg&_fT&p!g-4mO{ZB){{nqYOoFmUZ0>DIdUXs%$R{g4?R@C!}IYP z8#ZjfOE0~I_3PIQNRK@7NQ@aXMm~Ofk6_>gT(V>d{_~&z$cyGn=Ckk_I9c^Vz!mwR zgAT$er<{Ue!-fs!UG)1HKF6j_oACJKkIPRj-A9ZVfz6vY=OPS9RR)rN^eS(OE0|??|tuk1$+e6 z0}niaJMOqcKuRD}8cm!y5%cEF!v{b3LA>i-@5-xk1S4PIAOHAAc@6?xOR?a+ala{3 zrr_WI{x|CC>biVA*u|!&=jZuWuU?Jse)qcqRKMo1JNA5k9ef-|jx7@}KK}8K%i`9P zr<>2Pr=NeI^WwGFUc*HfU4%u87Rh~T?Ma_UYk3D8Z~%VvqaWeSGtV68CHCt6L6G{% z48l0N?6RM918Go_7JCT<#lsIjER&lnnBGU*ar&wJQd8S{{BE$TJdf4t*HK3uB_O4w zD+Q#FKKiIEG=6aQ<}~VUHucvl%SkQv#5o_gx3UDW$xD)d_o z(&wIgPC&YN@nRXL;Qi=#I(_RW;Y(lo5b-9usq7cNex|_uCV=`1iBVJ{!OI#V;^^ z{CLq&xbt*)-duYUC_8E~%rTqyYa+O=y%Wu-byJ48EP2r_QR z9d{gl{_~%UWTgsAY5M!$|Grmsm*=M>B}l1G(>4rleckgw-W>0L#flYqNvgwJ`W%D3 zR&cy~0$o{IIamnbo8SC~grjn-#Uvmt?x)yOAT4Gx^=I5@k5cQ|Nu~aWznWb4m*ZD=moHylRFd{*fCsX|>wO8B!w)}PR{EJUXNnYE zx^yW{KKW#kjM@g#`xDgs@Vf&KJP}L#N{Q>PyRKJtSBG5)(gz=WunR~B z3z)vfhKmlhghw8EBp-v`(;)SmD21^KVf5(HxbAn?;rQc^N30|U+jhLhRK@R_o$6R8 zm>k|>wCUi&tv&EsYtgZ9|JesJuFpREY#yXRb4zOgen}csclXpH)7Lxg>H9t<>4HnU z+oV#R?kxbRR+0O9*ouk@eC%T%!?(WmEwK+d30{8rWn6H<1=zlQdtN=$=g~GCB`59J zKmYm9qO$4$_b-3>O93e-kB(3J??J20^zPCQe>1$h8l=45-jbw#M;@P7V$GI?V~;%! zS6p!=rXMgJ@lt}cd;KL{Oq`%(#Zhj$z8VECK}Ly2(9r(pril{T^Q!-*ug#ym%>g}` zRfU*B#R=M^T9Uq#K&oug4j5M~xYYe-Fi!d=gH(q_I7xc43H_j%Jb5yH_`@HH13(iC z2+nVQ^P3`hnwy)u;G8d>=cNn&BOm#QfSc+tHv*Ru*$>j-%F6rWYEMZ@&}e(Muf=4r z-}Cx!7D%E`v;k^AuK9qaKOC`ive_uMY8CdjB7?0XyR zaXm>=f>bIqyxAZv21E@~PLg8Y)!@S)ee}`d)uqZyY1q=zB5~4R|N7Us_S$Q)X3d%| zhfuBM%jf>z|Ni$ynrbP+Sg1#s4y%b!_FGIw671e*-RSQbOz~E3b}L|Elo{mZEitB z!wz{jl&F-Rd=JrZ1T__vD36z+rn*{wlF=0jhY=!6h}9FLk*uz6<`_~9ru|JVg0Wt{2THGEAmw62pnU36 zpAx$~zezX6LjObl{+{#C#qePx5cUcOOA&B(aRbl_Tm6@_;byXEZrFvE#$8yqdJUE> zeGSW(zJ~3aH=}7+6Pg+uWfsND;?nO%7NMMj3AH1of%5pV^_Vz*0uDQLF2>i7!|>t5 zQB^-y^>$?=9qxZb$J>4WJ$DCtNLJP-9 zbGeJD-@FFLpK3h!*Xq2M$OE%+b>rv)P+2}j@=3408tp8fvO6HSnBxzw%2PNr1 zLCX1~sjeJ9jxQN#BuQ`q^uH614FSqy_~H8@IFCK{SaGz`UosG<7mWy6ihROUgY-(4 zPYHrlCV#$SdU5ZrKcu2xbYC1%4gl3ms-oP2Akp4aP9%C=Nf;nli%C*_eLn++_pL#~ zb5p|TK_}oi!8y?>O?1`{??bDXL6G)zf3s)L7IJ}>X8QSgPQCiBTenWiG2U{^E!ets zYd&7<2ZffNd|pZq7AL0)MiB8lnkUR>;yr6MR%;yk-t{@Ts8QV`sf7CnH5DGu3B`qv z;U|(hy53I#q^c>EcyMGcWKE#W%_41C*y$$F)Y6R2tJY!diZ}4$)6Zhvs?~VyrI%p2 z2JBQC$mXPt1)D$-=u}_XK9V4%aZ8z49W6t|HQ;2j$RdRrs}iGzkHF}?F-T&baf56}V z_BXup$}93Nf*_@aq@^k6!U-pwAS4;G+Bo-m;#PNC+2s$tgS4%+6~;y1`L=t>Pn5cw zmrzW{>OtKt22$-}_n*VRnsDMUobc11{*oF0f~uafVPQ4?FCzJUI81B)#HF zk6{1ZZ-2|B6Q*l`E6}hh5XA23ruC==S27L)XxrYmUyQ~V)FgNz5-hj~GG48(7aU&=(yOn& zT0&JtLCW4v>>x)Y)BsW;s<$@QHSNHf9b2$r$2M$PzX6Zlb{AH?vJCdFCgtb}g<*Q_ zA(gb#tus7|UOslBq@l!AJ&DalfyYw9()Jt?j$>v;9j1&JgGm!7Vf2itnE$a05Sug_ zHhUr)E-c#cI^F{y2-2XrqRl4FIHK0VvDWrG=LT(l3J1;wdW-!V_v1U`eA4VSF4T-J zFwK+a^=|{VNdxL`Hl4-|*I$n-u4MU?78n1VeJrYQ96kX2Rl;jcy;YcY--qsSC+nt zXBIBP`j?l(ZfI12QA$UGj1rFj)FAbmRf)*+K$`FB=1Ewp)#_NaI1s4iurMt)43jE` zVN7K$YU)N{_9@3=&gsXaeEN7~!X~VcG?>h9+9q8j++F3=@^3+qzWd$p&YKb3kMn>8 z7skt}jRXP8f9r)^LQT0GKKjv*$|8Hj5l3|M1MD4;UUpfR8|&)-_ILAAyX}r7-5Ve! z0H|jE&;R_7IBoo%TP-d5H#&Ss=_4qa4a2`tqB3-&9Y@6^y$-=>Nvf+)(C(!TO8b)w z1SJ^(98__&^N7bW#!E>?4l(1cykDJE9(V~w%arscNe2Z|X{qQpZ&ueJ+f4B8FgS7?y0Aq5-mwP>GU}WOg<}ZP1>MLI{4%#KPf4aI%8<>OVYPFNC`Ho zC{!KkjnglM(vAa8b%ucAATu|T5|1mOmN0$ANwuWcAk{8+UW@1Y-S2*v_at)>(kr(H zly*$eCj7)FJ|P5uIg&a=f5G_|2#Dy=5rB#$6&VcMFp#ue>`HWE zebWwX*|h`Pwr|Bl_uhx+9{&$gTerio!iX3q9Cj+tvL~y=aq?aahFd&%s=4cdRI`+H z&qfijt^%lGyRZxcmII8atdd5{Q;bR+J81@{Rn=kYoS7JT>S3rmVit@M)j-&UEnU)G zyx=*Go_uPtG*#w(`8O_-1aAt13%GN6zNPxV!p2}UxuyQw_(esO|U{?#Ho2ClcJ`w2{P?XdVwntMs3Ex zG@}w{jh~5eqsE|o)?^&<(F=e>CaaF;v@0D4FTA(}-?`|!pd_^!>S2RsUrRw9d#1Wi zKvI$tptR+gq@gtsJ*IkpdU474;lH^sGsaF<8^d}2t=MAPZ4&nQ2Y+iyrNgFEY20wb z^|2D9z3Q$ASHk}Nw2x;YMg(;1xku~)IK3Az?4tQ z02%?TY2AetZ>+$^)obwJZMS3jQ_lbm%_w7_-zao!<)q4HG6LM%npzxw_+dEx^wTlp z;2HAVls-}h#x&5<+KO%4w+m~Fq!T7ZkX=(6SHRCdm*b$sHBse;QRf)AVB{Q3sv3b2 z(l0tN%hHE*D!sTq&ob3Y!v_1{RXT#IndMJbEUg#lYRfMp{v;_)(^=GkgT z9&tq8o36uNlBn-xDAAL8?|t{;KaW3wd+xmlq!s4u930QK4donBp(BQc;cgg*g+^k| z$O)J-VG`=+9gLYDdk-*W3=m<3KpW4#^di2)$_$jGwu;9FB`LKU+K^1aql9FK`p3r2*rbtog$b5mi`SF+l^=e;rC+0+gQQ_rL%B z0#NNh3No_#0_&az>AB~fE9$P6qy!wu(S-rZ{->I@V#ymT5Y9Nb{SSY}E4SYbw09zI zga9W8Ct||!QeSv)B_*YJ?|U!6r$7A}NkWK(LkL-_^eQ*b4{di#rj2Pzb_dn-Yp%H( z_uYS=l8QMSmhB*%vt%0e&Ip{DX>4SBxxY0L2)?9Go`(rqdrB)bbp%muE1$l3SG@VT0 z#v9pY;wrSYwZi!3SHI$3cKHIYh?fN;p8?~`Ast|=k05CIvcC7d@8#p9J&^_aYm*k6 z)TD9IaTLse3GPdfQq9pI<-O4^`N~(ml229B$M8FCU-EDMJV>t0e&>RJRpm?M%jY?1 zhidg#OBJ;s_R*TmcjJDL4#vAH&mod@9GF?bV7?!u4r>>~l(5S#xcK*LFJi;a287zv z`1Qq?A-QY?kaJK+oE>326U zY1!K{+|?%Ko~cAa<|xBuk_GdPuYB3PY{3Gt8JGp}b_OXOBD%C=v6sYw)smDFQO7#_ z0x6HvAHHb5L>)@fo?QOape41DETYeR<}e(?Pt;KLvO5Xws9g3Vkm z+bc*35G_#&)Qd0qF@F2o-@wkfs3?iSOsYcb$q*2+fsw9-S=MlzHDNYJ)(peMQ;xzx z?>ie9TMH-R;!K17&K9I6u_?u_~$}z@ax}q-9eh{ z>=bG#K`QyAU;WaBF3Z`QUaHc*08&=uBiTR~9P7`-rX(c;gey-^>Nf|MDi7_+{({s$ z(7X@50`nUBzVxc9|4ol3y}oo5>0)O(*4Dol*LAPGElCMds=A%o47R6|SiE@yHt%S_ zvv)s)2mkgDpsf|Kvk;bpX&~gdC@(2Rdq=wzf&1kzekp2hh;dWNEzJeZto#G{r5eYJ zC0Xu&;C_7UqaQ^}YYUv5i*g~7j-x+v0WiHDsEpy6 zS6{;aBS;sj5R4s&qYiY;=_n$fn(bF;rf3G!;Idr$x_ZwbW%QsMNNGnDsxo*w?f_L? zQFj9QaRXI%2Mf~k&O1+R#UL$A-w!7RLCUx$Gh_Oaq(SM$=is^YYOKK%1Sx?@N5fBk z@)NOZ)MQkjp0ZSWdzEhnNGT&bQYmcgXvd>#R-m;#fhYcY8(w;BArcMS>BG%~G-{X# z8>TqM=v4XMMc+f+s5&(+F4;Muet}d%Zy`&(!}I3N1?%T#QfW|;W{xGj&S3|LF~*5X zoH1$!#?_2O_0;h=^^+ffHD@YN6UTEezaWkyvY~|TrxViq!bcC^6PWZ&vp4|f37t#+ zcf99RT|rAAogUDVG!N3RU3j5OBClkeu+IpMeP+%Kvd3q!=jKECuI3+UsUj=@%p@f)-$HsOI6A5 z+V2af!SfXZssEn(3c&i}+rMV3YZ~O;deDE>k677JK z5s(^|i3mFgwdV4SW-bJ|i?|%oK zCMtVW0X{^!plf5YQH9g%XJCBgaEzHc38#JH11erRyc{n)|1AFBMHk_zMT^8~r=$#mt9d^Od9*0+W6VYMFeOyw~7++cRJ-Zj(~o?E+Hft6d7p{qT%5QX^KY7Yq@52vjq6(j zQWL3+jm@b9?jlHATCwPcf8eDD9z!PC4%iux4n)ZZTag(E(rlYKNXdg` zxPvcOC)gHq1o>A+N>Z|UbcZzm{(g|sUL=uvZ-P{(K2g=BT}n0(B{)}ShHZ3xr8f(t zvM2=Nq<-&i4kR{&@*ur;<*R6JX~h#a{sT)MdJImo6K*y|ktWlGQZ&LGOvjP9}r;Zm% zYRpyY?vm%96PuKA(i|mep5|CEy@J|Mf6WV0LCI3$e9`YO*fntXz}gQ<`lZkRuY2va zzvv=Gm8LuhW3-1SAE+c9EJ#WB(#g2RK*|+TJ9X$@@2@1)Dz4u~EvD{jiNS@1&Ie9N zzF1CVei)X~s&9WM3HRGwbvFo7I@p93=-F?Wpa5AAN%;naQT7-0#brA7EwjXdjo0ETw#&|t3{9~AF?cj7-=9# zZ6HdCiX5h*8fTB0iTaumsG2qor+(%`Fy~ALs!D`4q(Lg`Zr4HwGSvM6sn(GAlXHXb zk`D<*h-FXiHar0+Ld-QAZ!s$YP%r8pLpl&qpa ziTK7FZ{#!g^*+IuMsPCohSV}HB2;~Q^H}d`b+;Qx&pTfc>@`rOW{`n&&c&`=77x7s zDt5NE;A->%_zTv_Q5qO@d11SXsNvtNRaE*?X*msJr+wAV4h{?f|!xFjV= zeUem3R0BE3K#S|(p=GaPb7Lb`zPuE7{P8d7T)P2bHiH?lORaIrniu*_m{u?Wtq&B!n!<4u@}3iC21G$?p0UeymQYh3Q`Hf0C;Bo z1}xjKUNTi~|I=Tv^|_Z2PN!hHIT)r3*Kox-#KvCyFyPP0JOAjT1ptw7q#H={`J^7( zD(B>|X~RZooyltXuPt4gFIN%{TVjtAr0m2x3T2pCG92fPKLlgzMq|pkC!qYaBZ0b7 zWGkY0F#u90Qvj(}bvcLlA=pkj=_GMfQIaw-0m-IdkdsGHper z8h~_W(PpF6p%aNVAys7^I}HN$tpsTTz>208EM312TN@kj@4x&N%kO>=Rw{+ClY>d3 zfayY5JyOWe0?U2;_Xj?RFMRO}m^E`I%Hm~3L8_fq*<2Q#oe3;nya+d3cRlXE=UxFf zom&jYghQ6ZM*wxYjIHNaGWvu5R4cz8V7&u9E6TI2yS&0si=u1FD=3U`>t{v zNt&9IF9wmfM|DLE#?nbqWkn2K5|xF=2vn-Qy5Vq8no?8ZcU+uly72vJjc8A+yMFGj zkQqMp(T}*aDfXngTP%**Tbxw0cjz@^Di>40G~=ikjjN|P>D~q@JDwq`w$Y)4t71UZwmb|zel14ATdBoY=6C^LSJIP7pqu&3ss z9W7dt@_OqxZNwdS-hq4Xxfic2c?s<;tt#=Gp!b6NA=^O=E=D4RIjFUcYo?&+xwmNaFXOiC@%L$zN)ND<7a z@s8J0mG!8!Baq|DXAI8AfvLUSC8gc)_*7)wgIh}27&e5Z1ith#KOR9?PVZhPpbQgYi3l3Y?Lg~dLJwP{kF zs+Jss>>=%CeWBSviYwC5(V-fWK2s}PFpydyjG4~(vNTUn-)ryX22A(U*+JUa*d&94 zvlOIgq+HknSyaoDVwQw?lq^r0Ed`UUz}}Y9%-w97lj*qpqe_p4_@sHg4FcHMkZ$GEK_arpO)|?xTsM{Og1N$eA;v za-eOG{Bg%l={@*g89Q}K3X2O>?<${ez=9Bu=j)h>f`URV^TRbj2*F}uIenRWecIIl*aQe_dYRn9qHf>5;DVhB z>j0rJ9WpY;Wf(}a`8G3c?%o}cLsJH7xl+tsj5{d2=s_7cdrl7abxZ%ifE@bdfV92+ zPkH;b*X7j5`z2O9PYP4yw}91Cuo84BD=U@0o?cB`uoswvCbX2Mh3lU^qpfeeN{dUB zuQ!jhi#E)8f(V!|F{zhQx$7IZO6{V{rT*Hh3C$qy!>fPyOL{_q;2= zqL`r-`V_8foK60!o4E@}nWS*xL^cVNvryz}4!?zNnYUSj#HTe1Zq`88WMI>-TKn95z)}-dwW&&wyhC`RSHcsj?SQAGMk^uGY#vWBK7Nn2hn4u41qDpOZt7Pe6u`WB9b^Qb+JlW zb6LHts#z|}RxXztZogHQfA>boUtZ0ZMB*fO{qYs;ZS83w)ikZMK~|0lr!(4*Cj3m6 z3;W1GZ1#^cNT7)5DlhKc+!qr%Of;ZAn_!Z~75p0JY>jf6Ae9}YO{Pg7yl<2D!j2tZ zdXPeC0>=?y^h{0VEb@f}sR0L|GL#q-nrLCBCIQ~#KJk$_Fqpko&0@_4+05TewWv`b z4X0oXr1=E}K2yB|(gX|%fmTJ?4UCLPXJ3yT>^iIincCibOFn7+w~TamYosTSj+fv? zA%do5bTKCId!&$Kb7lZ3-829-kvOCJuR@BXHeN1YySzqLRxXj+`a1d6h95}HO*crv z%4(7Fc|JqF(>v1M?$0MhldAR$jiLZRtQ#Q3(t#YnUaXA;g?Nv%vuoEb4J2Vk8$GLi z&cF&#u@>;VadTjNKsgXFvy|P`wA@6HQqlFhXP;FfvO&g7TuLBi@d*Ot3R0IGI}^R8 z`6qPfn#dV{)YHb2;?ke(Ct@8}i{hZF009psLywzi~XE=p?=x z2C4IJoi`KspbU44GmHt^l>E3X&M%gmms}y&FR7PRwaewo)z{04jkk-`E)=i4NPA4R z=sr+Z{Fo|8X~qYn2y@ep?oShd)K}B}^3qE$>Ci2=-q>=cW(xCfa^Fy_kYckG4%ap9 zI=N<@2vTaJTbf(^rf&jAvl*n;jgZOwbfpxFfhNrrq}rYri)mEPCC3g+z+6CT8kPAh z_?*myF*C`2AD?jvv`HOtcnCtchsKrm1%*2$Awx5(N%*Q#0Sg491M zK1lIT)f^4{(|!U;XGi4N@#Au=t49vK*CD&#dQ$2kT`Z7tv)Jx{!Dh3#K)@HXQY)%JFgM7Pns$l;DT@L~ZT2V;Q}=~g z!h84&T$cqUr^j_!WGaRr48wN6AZD)E%)e#>Rn*L&Oo^v z&CCQBcy@rweeiqu{l>vdlQ?`jXwyt(g)T@Fzor?QOfIwe@Z3{J2xj z4h>0h*?iTA!i-SL^Yl+bwQ7D|zIM(O=EWrsQth(|DTxO zH+}mSS#|YQvf`R+L>4XZ!@j|YQl;|_OjJvUk{^BK(MM$W?lvDJ=gy`1q?|w2oc%>Z zx<09Uw#@7`%ZHH@FfH0!!CfA1L zfR-)N7Vazj{9%wH)To5&?Ci`qYLWXv*sNZ?THDIjtzG8_cw%`9LVZrnPx=gkDM6!% zB{%~kg%93@mz3e;sPy#rN_SV696o$VKIqsh9q+#{`}gga{@z}V(gGBsl*WO}HPM!U zw7`q$kfySt5?M6ALawU2LI(-o)NrFLs$L>>U%yt0%1b4$tjxa^BNj6f%Yekq?v)W3 zk3RO8f{A?z3u*S4Gsu~usD^?Ivsm0cb_Jo82vVX-v=?SW&WF+G*q(50)|WHP=m|7B z!rZEn!WK~4z8Xlwj7(#m{N|~rmC0#z3$r zfGJZkLnevDA!m*U<#|L?!+s?jXPO#mN`w!GpKGysB(N#+w&~ei&qfGXp#k@Y)}si) zdR=Y7!yWr>%`wxuxi4ya*<_oKYMaP+d7n+^x&)E}$0Em+!aexF z11ijXs+^dnPr{Z;3Zy|ti&`{Lkm+a&PtGLI`Vn1kOom5BXvhSmPa^&#m zvTyHRWmp&*8kW(~)2dbZeMNyLt*@?8j-=Y9)l$23nOt+_N~x)?*1%4zs8D1P$9 zmB4vaa0W!b`gdQr1O-nztP7e}N;Cmzc(#u1J(XezLJJ&a({$_+LXG{V8i^nvu?VAN zb!XhN)|@F=D#?H2Hj!4dK;^VR`hVWvtxr6m?QvSnkfup#79`I!!ypATB>UkvWnsdH z$cpG$Omc=uB8u0|lr*qrbHMpNnhMQj01IncGfCM%s$kHz)L*igEHGNgMjF}>CCl>x zUNkYLDCSsLN`{{YLBs}gZ8SU2j%4OKR_LvT)9}g$eWyG-!i0N6Q|AIw?hRIbp3%w@ z-R~P28f!zYa9&A?mI>NHH;`sZx&ca}w$^{@4_xvYJd$2gg^s3`;sr7^I4DQ^`ej~m zv5X9l=#*-h7D&e!NDK1fQXG#yyi!?EStX@aO!QWjuD~1{ONd7SJCS3T^VxtI z(xm1?+5qNo1sD4aczK^Fx^Wg|v(VTJn;&F_5DepD@3@vS@&`V#X;${TySrN>_9&Y3 z0%dvl8q(x2UPkGJE69WoEof`x6$zYo;z8{3ZCBY0#42r4$bT6VWsvQp$e*B9074rwtV%n$Ub<%TN-d9IJcSEV z14+2hBK3Yir;-AxF;VJIPZChF1nD2Ht5rxg>_kZ(CRXscl}irnBlk`}8^MH`38ZP3 zMKH!9{L5w>q%F-dOmz1rcW?A|?%XM*6nS&=v&h_?(u#ipANneTl;utV#2p6gxG@SU z7gs@BN*YLmU=Zdq1^$4PukbcBES9I$-{*AOOwdN@x_L^cVfKO4T~$9w=9|0E$S|q8 zA8*{?5qT}Gs7PznJ)hd$DXr8c{GqVq45ta0^Im-MMJcPCGk0@d%&+Jdq7LyK zNYC$JBohhQ($uJ$bae2f#5Ue_r}u}KU!DW$`K{|$>f3W5%@EC+!4m*Tn;JLEbK9Hc zG(PEuJAdfC{K_kHAf3TQzSJ)j2~s~jF#eh|cc*kDY{}>#LX!g0GlM7Pf2nysEeiU~ QjQ{`u07*qoM6N<$g88?WF8}}l literal 0 HcmV?d00001 diff --git a/test/Charly/02-mapping/04-manager/public/index.php b/test/Charly/02-mapping/04-manager/public/index.php new file mode 100644 index 0000000..bbcd2b5 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/public/index.php @@ -0,0 +1,114 @@ +selectOneById($idComment); + // view + require "../view/comment/selectOneComment.view.php"; + +// insert comment page +}elseif(isset($_GET['insert'])){ + +// real insert comment + if(isset($_POST['comment_text'])) { + try{ + // create comment + $comment = new CommentMapping($_POST); + // set date + $comment->setCommentDatePublish(new DateTime()); + // insert comment + $insertComment = $commentManager->insert($comment); + + if($insertComment===true) { + header("Location: ./"); + exit(); + }else{ + $error = $insertComment; + } + }catch(Exception $e){ + $error = $e->getMessage(); + } + //var_dump($comment); + + } + // view + require "../view/comment/insertComment.view.php"; + +// delete comment +}elseif (isset($_GET['update'])&&ctype_digit($_GET['update'])) { + $idComment = (int)$_GET['update']; + + // update comment + if (isset($_POST['comment_text'])) { + try { + // create comment + $comment = new CommentMapping($_POST); + $comment->setCommentId($idComment); + // update comment + $updateComment = $commentManager->update($comment); + if($updateComment===true) { + header("Location: ./"); + exit(); + }else{ + $error = $updateComment; + } + }catch (Exception $e) { + $error = $e->getMessage(); + } + + } + // select one comment + $selectOneComment = $commentManager->selectOneById($idComment); + // view + require "../view/comment/updateComment.view.php"; + +// delete comment +}elseif(isset($_GET['delete'])&&ctype_digit($_GET['delete'])){ + $idComment = (int) $_GET['delete']; + // delete comment + $deleteComment = $commentManager->delete($idComment); + if($deleteComment===true) { + header("Location: ./"); + exit(); + }else{ + $error = $deleteComment; + } + +// homepage +}else{ + // select all comments + $selectAllComments = $commentManager->selectAll(); + // view + require "../view/comment/selectAllComment.view.php"; +} + +$dbConnect = null; \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/view/README.md b/test/Charly/02-mapping/04-manager/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/02-mapping/04-manager/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/02-mapping/04-manager/view/comment/insertComment.view.php b/test/Charly/02-mapping/04-manager/view/comment/insertComment.view.php new file mode 100644 index 0000000..cda81f6 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/view/comment/insertComment.view.php @@ -0,0 +1,25 @@ + + + + + + Exemple du CommentManager::insert() + + +

Exemple du CommentManager::insert()

+
+ $error"; + ?> +

Insertion d'un commentaire

+
+ + + +
+ +
+ + + \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/view/comment/menu.comment.view.php b/test/Charly/02-mapping/04-manager/view/comment/menu.comment.view.php new file mode 100644 index 0000000..bc39b5e --- /dev/null +++ b/test/Charly/02-mapping/04-manager/view/comment/menu.comment.view.php @@ -0,0 +1,8 @@ + diff --git a/test/Charly/02-mapping/04-manager/view/comment/selectAllComment.view.php b/test/Charly/02-mapping/04-manager/view/comment/selectAllComment.view.php new file mode 100644 index 0000000..41a6d19 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/view/comment/selectAllComment.view.php @@ -0,0 +1,33 @@ + + + + + + Exemple du CommentManager::selectAll() + + + +

Exemple du CommentManager::selectAll()

+
+ +

Pas encore de commentaire !

+ +

ID : getCommentId()?> Voir ce commentaire via son id | Mettre à jour | Supprimer

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/view/comment/selectOneComment.view.php b/test/Charly/02-mapping/04-manager/view/comment/selectOneComment.view.php new file mode 100644 index 0000000..faa9e50 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/view/comment/selectOneComment.view.php @@ -0,0 +1,34 @@ + + + + + + Exemple du CommentManager::selectOneComment() + + +

Exemple du CommentManager::selectOneComment()

+
+ +

Commentaire inexistant

+ + +

ID : getCommentId()?> Voir ce commentaire via son id

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + + \ No newline at end of file diff --git a/test/Charly/02-mapping/04-manager/view/comment/updateComment.view.php b/test/Charly/02-mapping/04-manager/view/comment/updateComment.view.php new file mode 100644 index 0000000..a561f15 --- /dev/null +++ b/test/Charly/02-mapping/04-manager/view/comment/updateComment.view.php @@ -0,0 +1,34 @@ + + + + + + Exemple du CommentManager::update() + + +

Exemple du CommentManager::update()

+
+ +

Commentaire inexistant

+ + $error"; + ?> +

Modification d'un commentaire

+
+ + + +
+ + +
+ + + \ No newline at end of file diff --git a/test/Charly/02-mapping/05-together/.gitignore b/test/Charly/02-mapping/05-together/.gitignore new file mode 100644 index 0000000..d11ccf2 --- /dev/null +++ b/test/Charly/02-mapping/05-together/.gitignore @@ -0,0 +1,11 @@ +# Ignore config file +config.php +# vendor contient les librairies externes en PHP +/vendor +# fichers non envoyés +# PHPStorm +.idea +# VSCODE +.vscode +# Charly +.history diff --git a/test/Charly/02-mapping/05-together/config.php.ini b/test/Charly/02-mapping/05-together/config.php.ini new file mode 100644 index 0000000..ae92c13 --- /dev/null +++ b/test/Charly/02-mapping/05-together/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/02-mapping/05-together/controller/README.md b/test/Charly/02-mapping/05-together/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/02-mapping/05-together/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/02-mapping/05-together/model/Abstract/AbstractMapping.php b/test/Charly/02-mapping/05-together/model/Abstract/AbstractMapping.php new file mode 100644 index 0000000..6c5f9c1 --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Abstract/AbstractMapping.php @@ -0,0 +1,42 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst', $tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + } else { + // sinon, on affiche un message d'erreur (à commenter en prod) + echo "$methodeName n'est pas un setter valide
"; + } + } + } +} + + diff --git a/test/Charly/02-mapping/05-together/model/Abstract/README.md b/test/Charly/02-mapping/05-together/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/02-mapping/05-together/model/Interface/InterfaceManager.php b/test/Charly/02-mapping/05-together/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..2d70ae1 --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Interface/InterfaceManager.php @@ -0,0 +1,18 @@ +db = $pdo; + } + + public function selectAll(): ?array + { + $query = $this->db->query("SELECT * FROM `permission` + -- WHERE `permission_id`=999 + "); + // si pas de résultats + if($query->rowCount()===0) return null; + + // récupération des résultats au format tableau associatif + $result = $query->fetchAll(PDO::FETCH_ASSOC); + // on ferme le curseur + $query->closeCursor(); + // initialisation du tableau de sortie + $arrayPermission = []; + // Pour chaque élément du tableau + foreach($result as $value){ + // hydratation de PermissionMapping + $arrayPermission[]= new PermissionMapping($value); + } + // autre manière de faire le foreach avec fonction fléchée + // return array_map(fn($value)=> new PermissionMapping($value),$result); + return $arrayPermission; + + } + public function selectOneById(int $id){ + + } + // insérera uniquement des enfants de AbstractMapping + public function insert(AbstractMapping $mapping){ + + } + public function update(AbstractMapping $mapping){ + + } + public function delete(int $id){ + + } +} \ No newline at end of file diff --git a/test/Charly/02-mapping/05-together/model/Mapping/ArticleMapping.php b/test/Charly/02-mapping/05-together/model/Mapping/ArticleMapping.php new file mode 100644 index 0000000..7a2fc92 --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Mapping/ArticleMapping.php @@ -0,0 +1,124 @@ +article_date_create; + } + + public function setArticleDateCreate(null|string|DateTime $article_date_create): void + { + $this->formatDateTime($article_date_create, "article_date_create"); + } + + public function getArticleDateUpdate(): null|string|DateTime + { + return $this->article_date_update; + } + + public function setArticleDateUpdate(null|string|DateTime $article_date_update): void + { + $this->formatDateTime($article_date_update, "article_date_update"); + } + + public function getArticleDatePublish(): null|string|DateTime + { + return $this->article_date_publish; + } + + public function setArticleDatePublish(null|string|DateTime $article_date_publish): void + { + $this->formatDateTime($article_date_publish, "article_date_publish"); + } + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + $this->user_user_id = $user_user_id; + } + + public function getArticleIsPublished(): ?bool + { + return $this->article_is_published; + } + + public function setArticleIsPublished(?bool $article_is_published): void + { + $this->article_is_published = $article_is_published; + } + + public function getArticleTitle(): ?string + { + return $this->article_title; + } + + public function setArticleTitle(?string $article_title): void + { + $article_title = trim(strip_tags($article_title)); + $this->article_title = $article_title; + } + + public function getArticleSlug(): ?string + { + return $this->article_slug; + } + + public function setArticleSlug(?string $article_slug): void + { + $this->article_slug = $this->slugify($article_slug === null ? $this->getArticleTitle() : $article_slug); + } + + public function getArticleId(): ?int + { + return $this->article_id; + } + + public function setArticleId(?int $article_id): void + { + if($article_id<=0 && $article_id !== null) throw new Exception("ID non valide"); + $this->article_id = $article_id; + } + + public function getArticleText(): ?string + { + return $this->article_text; + } + + public function setArticleText(?string $article_text): void + { + $this->article_text = $article_text; + } + + public function __toString(): string + { + return "article_title"; + } + + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/05-together/model/Mapping/CategoryMapping.php b/test/Charly/02-mapping/05-together/model/Mapping/CategoryMapping.php new file mode 100644 index 0000000..cbb3d1b --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Mapping/CategoryMapping.php @@ -0,0 +1,89 @@ +category_id; + } + + public function setCategoryId(?int $category_id): void + { + if($category_id<=0) throw new Exception("ID non valide"); + $this->category_id = $category_id; + } + + public function getCategoryName(): ?string + { + + return $this->category_name; + + } + + public function setCategoryName(?string $category_name): void + { + + $text = trim(strip_tags($category_name)); + $this->category_name = $text; + } + + public function getCategorySlug(): ?string + { + return $this->category_slug; + } + + public function setCategorySlug(?string $category_slug): void + { + $this->category_slug = $this->slugify($category_slug); + } + + public function getCategoryDescription(): ?string + { + return $this->category_description; + } + + public function setCategoryDescription(?string $category_description): void + { + $this->category_description = $category_description; + } + + public function getCategoryParent(): ?int + { + return $this->category_parent; + } + + public function setCategoryParent(?float $category_parent): void + { + $this->category_parent = $category_parent; + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/05-together/model/Mapping/CommentMapping.php b/test/Charly/02-mapping/05-together/model/Mapping/CommentMapping.php new file mode 100644 index 0000000..c3de343 --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Mapping/CommentMapping.php @@ -0,0 +1,152 @@ +comment_id; + } + + public function setCommentId(?int $comment_id): void + { + if($comment_id<=0) throw new Exception("ID non valide"); + $this->comment_id = $comment_id; + } + + public function getCommentText(): ?string + { + + return $this->comment_text; + + } + + public function setCommentText(?string $comment_text): void + { + // cryptage + $text = trim(strip_tags($comment_text)); + $this->comment_text = $text; + } + + public function getCommentParent(): ?int + { + return $this->comment_parent; + } + + public function setCommentParent(?int $comment_parent): void + { + $this->comment_parent = $comment_parent; + } + + + + public function getCommentDateCreate(): null|string|DateTime + { + return $this->comment_date_create; + } + + public function setCommentDateCreate(null|string|DateTime $comment_date_create): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_create, "comment_date_create"); + + } + + + public function getCommentDateUpdate(): null|string|DateTime + { + return $this->comment_date_update; + } + + public function setCommentDateUpdate(null|string|DateTime $comment_date_update): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_update, "comment_date_update"); + + } + + + public function getCommentDatePublish(): null|string|DateTime + { + return $this->comment_date_publish; + } + + public function setCommentDatePublish(null|string|DateTime $comment_date_publish): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_publish, "comment_date_publish"); + + } + + + public function getCommentIsPublished(): ?bool + { + return $this->comment_is_published; + } + + public function setCommentIsPublished(?bool $comment_is_published): void + { + $this->comment_is_published = $comment_is_published; + } + + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + if($user_user_id<=0) throw new Exception("ID non valide"); + $this->user_user_id = $user_user_id; + } + + + + public function getArticleArticleId(): ?int + { + return $this->article_article_id; + } + + public function setArticleArticleId(?int $article_article_id): void + { + if($article_article_id<=0) throw new Exception("ID non valide"); + $this->article_article_id = $article_article_id; + } + + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/05-together/model/Mapping/FileMapping.php b/test/Charly/02-mapping/05-together/model/Mapping/FileMapping.php new file mode 100644 index 0000000..e26665b --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Mapping/FileMapping.php @@ -0,0 +1,64 @@ +file_id; + } + + public function setFileId(?int $file_id): void + { + if ($file_id <= 0) { + throw new Exception("ID non valide"); + } + $this->file_id = $file_id; + } + + public function getFileUrl(): ?string + { + return html_entity_decode($this->file_url); + } + + public function setFileUrl(?string $file_url): void + { + $text = trim(strip_tags($file_url)); + $this->file_url = $text; + } + + public function getFileDescription(): ?string + { + return $this->file_description; + } + + public function setFileDescription(?string $file_description): void + { + $this->file_description = $file_description; + } + + public function getFileType(): ?string + { + return $this->file_type; + } + + public function setFileType(?string $file_type): void + { + $this->file_type = $file_type; + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/02-mapping/05-together/model/Mapping/PermissionMapping.php b/test/Charly/02-mapping/05-together/model/Mapping/PermissionMapping.php new file mode 100644 index 0000000..db0a4fd --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Mapping/PermissionMapping.php @@ -0,0 +1,48 @@ +permission_id; + } + + public function setPermissionId(?int $permission_id): void + { + $this->permission_id = $permission_id; + } + + public function getPermissionName(): ?string + { + return $this->permission_name; + } + + public function setPermissionName(?string $permission_name): void + { + $this->permission_name = trim(strip_tags($permission_name)); + } + + public function getPermissionDescription(): ?string + { + return $this->permission_description; + } + + public function setPermissionDescription(?string $permission_description): void + { + $this->permission_description = trim(strip_tags($permission_description)); + } + +} + \ No newline at end of file diff --git a/test/Charly/02-mapping/05-together/model/Mapping/TagMapping.php b/test/Charly/02-mapping/05-together/model/Mapping/TagMapping.php new file mode 100644 index 0000000..798f6b9 --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Mapping/TagMapping.php @@ -0,0 +1,44 @@ +tag_id; + } + + public function setTagId(?int $tag_id): void + { + if ($tag_id <= 0) { + throw new Exception("ID non valide"); + } + $this->tag_id = $tag_id; + } + + public function getTagSlug(): ?string + { + + return $this->tag_slug; + } + + public function setTagSlug(?string $tag_slug): void + { + + $this->tag_slug = $this->slugify($tag_slug); + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/02-mapping/05-together/model/Mapping/UserMapping.php b/test/Charly/02-mapping/05-together/model/Mapping/UserMapping.php new file mode 100644 index 0000000..400ecea --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Mapping/UserMapping.php @@ -0,0 +1,87 @@ +user_id; + } + public function getUserLogin():string{ + return $this->user_login; + } + public function getUserPassword():string{ + return $this->user_password; + } + public function getUserFullName():?string{ + return $this->user_full_name; + } + public function getUserMail():string{ + return $this->user_mail; + } + public function getUserStatus():?int{ + return $this->user_status; + } + public function getUserSecretKey():string{ + return $this->user_secret_key; + } + public function getPermissionPermissionId():?int{ + return $this->permission_permission_id; + } + //setters + public function setUserId(?int $user_id){ + if ($user_id < 0)throw new Exception("ID non valide"); + $this->user_id = $user_id; + } + public function setUserLogin(?string $user_login){ + $this->user_login = trim(strip_tags($user_login)); + } + public function setUserPassword(?string $user_password){ + $this->user_password = trim(strip_tags($user_password)); + } + public function setUserFullName(?string $user_full_name){ + $this->user_full_name = trim(strip_tags($user_full_name)); + } + public function setUserMail(?string $user_mail){ + $this->user_mail = trim(strip_tags($user_mail)); + } + public function setUserStatus(?int $user_status){ + $this->user_status = $user_status; + } + public function setUserSecretKey(?string $user_secret_key){ + $this->user_secret_key = trim(strip_tags($user_secret_key)); + } + public function setPermissionPermissionId(?int $permission_permission_id){ + $this->permission_permission_id = $permission_permission_id; + } + + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/05-together/model/README.md b/test/Charly/02-mapping/05-together/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/02-mapping/05-together/model/Trait/README.md b/test/Charly/02-mapping/05-together/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/02-mapping/05-together/model/Trait/TraitDateTime.php b/test/Charly/02-mapping/05-together/model/Trait/TraitDateTime.php new file mode 100644 index 0000000..6b56182 --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Trait/TraitDateTime.php @@ -0,0 +1,34 @@ +$paramName = $date->format("Y-m-d H:i:s"); + } catch (Exception $e) { + // en cas d'échec, on met la date à null + $this->$paramName = null; + } + // si c'est un objet (DateTime seul possible) + }elseif (is_object($date)){ + // on formate la date en string en DATETIME + $this->$paramName = $date->format("Y-m-d H:i:s"); + }else{ + $this->$paramName = null; + } + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/05-together/model/Trait/TraitSlugify.php b/test/Charly/02-mapping/05-together/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/02-mapping/05-together/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ +PyA07*naRCr$Oy?K;mXL;uNyK8K@XDykvuc}h1w3K!%v;q3 zGkvE2oO7iArrXBGHnuU??mq1~LH8jeEc6d$;F(UZYwoN490t{4fj?FlPO(^`DFB3Pk7mWKUij zbKkMGdKP~Rj9C{iA`AmweDS9|^w2}R^2#e1m1;3^Y-biITOeKh1zrx%Om1?dkdfT+ z^99rdehnDPJL&gsJmj2OKwaGGm<4AM#|vTO@exw!h#vZM=N*yZpHeREG? zITcvr``LW53mMoZRLy;=Sj)NZX4CpZ@Gc9+H?; z5=SkNF8MuqS8v#SLnRgzT!e;>LZc>YCRmx3M=~Ico#Rshwf>s<+~g+sCs>qsm-8|8 zo9nOUJ)#wmF6v${3ZxQ~TBg;CNf&iVFWi%6-%Nv0Tu=i70V+@<#PfVCO!XxeE^$K> z3<-#mpUpWSvf{Kv@_YFng*q>#z6_Amg}j#nC=pf!PU7y)${gwI)NE1bdH@&hN-nQ= zZh>@p-H&&5HjSI9O;%`Vp!z@+`5qBAS<|`I?o$!S zu4O8KrXsMzNVWyZI@YsQ2|#Br!jsE2@9Ltw2VT4&NK2)Hib-3R^y0YN%E47u%}{{! z4GqxYnMr2KWqjAdOSyPvY(?wVRLo-HEotaQQADUrWT<{_!8E9*U24jAjlov;J9X5VDmb5jTx%?f_cpQzZo$Ow~&kQy)=MErdJe%=}zrJPDrH647hf?^vbsbnZ8 zwW+46<5kc=jzXOVmS<>>)lkVGTUkc^2#kopmRI<=wF*5E+_d#lws&>W7Jw^aNY4hG}4i0z5+{h7?FmsKp>ndj(d65w~vM$*#^$ z+GCK0mVjA5U*0{{0_ma_(}I?CdU`TyYirXnND}n7Ea{>y?uB?#Gf2g*RWTWk;HU2h zNXIFpGn8x>->~8gthlp2h5~2|(nz@40@T?cl_XTNC3V9FNPQDLTP&+b#+zY95OVwG zom|%0MZ2$)N7zyhl6R3LQk?Z|HsCFHcittlAV{aCCZhKC_7+Gl1me!>Jym5?#g77o zihvY&;hlrLGBHj*lclUcYN{lU8HG4zMC6Oj4dU9V_@x43QzxOsk|uRj10)s|cUM5F zYM`+tRUkDyQnfrQLk-g1T|IPGCH@ruILQ>v_rdggs4`9y1@){h!F%jQiw0@KiYlAh zYE@gN3qfahRrE+?SdjE#hj@8nfIxW>~z|=XZPiplNG7U=nz-V z&kG?8!7(B2f@`Y3i7PBw>A5t**=ui^UikBPS}l;C$BTO*4sFCG6YZCplud&Z0@8s) z{CaXyxw}=vR`IHU)CmI|-=jD=%FxkwXmc!#a!tjWs;(J7l!db-*`y!Jl1faflD{!X zZDAONSmiR^m4IDtJ0IPB4ej{~xgbIk%Cg`BFT}G=QfpRXZ|sLQm(Vfr#KXqGmJOnr z9aRsrF2ohR@b9@Okal!*%sJDRCB5*sZvHb+AQh{n93GRhWiSXlcjOQ+O-`xAQ4nc& zR=cbr*&yJhpFGPmk39_I!%(YW2SIE}^`SIKCEYUzq_I0J_1Kyvqy<4Tg_FScSk> z?rp=AYInEJ0hISp;jg%^@!!Oq4Ggk@%}Nh0GdlU$rPr`6O4C&faSemOFqrZ@!oD6h z-hDG$?!OZ@tt85t6l0L4FcsL7$8UO!x}YU(fpodT@idmyk5{;9P_iuz(!&Q8NK5G~ z0Zwd54bnkCN6q8)r=H>mfBQEuG6-HlWqca|Z9>fKO}*)VVrq4{wGERF&u1q&?p?c^ zySg{gGviU2oF?1RLD8`|mWfz>?=5Wq;=h7b?U1u5IP!9Xw79(Ww>09a!f!4ce?gE+ zowO~dOE4`|#UBA(||ZN@pn8CMVi0QXjmUUBCYsSl0t> z4kcF?f#$cQEs(~6$I0$)3#5x(p3CETYS*n>(kQm12}q|JAT=aQqe0qMDskYMXEaEM z1*D~S1yXTq)4tDoEcVdDXSQC=E~}GlzDmk)C=fB;m8QIB6W9FjpNH*hpxvS3=nSup zN$0w|Es!Q46=jB>{PZWPpY*lYUd3pEba{Ypv1g${npo0>Kx!&?x4oEv^lSLTgW#9z zAl2O5*&U{*OXR3zlwsidJ}ZIUbo22oS8`oPKfTi)ZY`t|8BBGinB2CC8~@`MVb=!e zO5??32Wg{A>aX&-f79i9=2K>P;e{7?=%ELB{q@&dAYCjtmdo=_57OzAENR*gX)hIH zODZ5eLFCP~q`DT`NaW16YR#Y(a0y?@5%2>W$#C!1J-n}T4Vwy(&U+Y^!(`fIY<(9u z{onr{cCCY+ERn5S>*j*81=87x08tBk?z!g_NZ)+(O^jCJXt}^|ap!R|NF}=~?(P6D zO$tbJ1lWq`Ahf@wk?uGDuWwwxlsY1*CK8l?gcK1F4j7(!fe=Zd|dM zn|n8KquE8rjE`+NOt}WbD>K~uAHD!LUk)pBI(sagHL4!l*a%u6oefga-F@bnrW8#)*h*8nX^DD1p5}_XmJ2p4$nFpkakzA?0xD94bs75ipY>y()p}uv*i>k zEB{ZvtC&<7;Rw%)RJ~JrOE=>3@zs0y$lA;3I5LH6S{zRYSl4dj%K!7A7Z$J5CzW3Fy5DG}6;EX^T z`^CytReh#fe1)p?mqySNnyiWp-k;sded{l0citxJMNGBZOs((W@_+wn(zos*vO`Kn zs0a^<>U}G_8%xa8m%u!hw3RqoJV2JiGv|V|7=u)CcTWM*Uf<*GCw|PMfA#051nKEM zTXW1h7o>7NU0AdQ0lVqtp1$3DFte6iIiT9^Fqn(z|JW^T`~3Z|aV7b}B)K-p3%6p@ zdQ85MyW0Zka)93A&!G-d`N0gB3(`_5hc8_)P1)UZ3R2Y_6HADyVSEwohE2N%Ye;jA zy_yHsT+Rlk4N+>yXHBf#8@c8WJ_CEU;5i|dtr|~TiKF-mEa>jG$P9}I$Z~k5x}l2E z7ZFKzH?gFLrBy9Y@hm{P7%MtACY93=cUSsEh31zFO*(y(HCTMC=W?!Hxsfh2g>OWZ zJ5${Bd!NGk_$`ow(3bwv*6g80TT&4sYt}f@FKl(eEC)c&cMh{aDlw_4W76lEKpGg* z^xdeFCYJP(zx*>I$?ndHNzW9dk}MKZf+#g4QoC*dnZTeoGT6gPZd$#StGd_Gm+NG@ zRAA!=ZlLdTABG)kkPh@PQR1G%IBM3{Uat4xT%Xs1mb3-ZbA8Fr@A2v&H6lW>q^8Nx z0w9&d(Y~jj>#dRHJ#fTJ{#6oV*M236k-QUT;V*k*Kad*?>(ShJIr zp2b8^VfXJpz{(F@2Rk=8rv>fppqS5-U0+L6VeYL?^#H zu-IvJazod8uJ2e!fA31njVrm~cRm3-*TU9*ZH0XiGJvIep))k+aNm#ORZD#QFPG>?)6e=z~I1=5QGdW%0v0jUg% zP?l7=yV{bT4x~a09C+bbzWvAl874;0IY^b{O7aleplOhfOfr!{FBX^CE4gCLX4dwu zqJQfquDJVl*4=so^!HGuN|;S44_+mUl~T*uL#zeT#jmB-Gtbi%NI)vHSp=ja=~)Nq zcwWn=%yDA(HD-h8aQ8&aw6!g#b(E{n&Ub)um&e;`E@nY=m&IRc!<2oh{tl2T?c?W6J zr_(cJBrerJllU}^$x1S8%5<}3Wj{N2?Bx9)xs%=Z+=jiek7>W8_`GSu!WQ9dHOHp$ zI1|veKzh!WTI)b(dj<4}!iKvmmUKiE>?I~$1|SuX$Oy!G7FZ>tL)viYC&Rj27rmKw zZoK^#uK(CwyzirTQZWOSDRwOz%d!ZqIho!waDUbNHogDZUgxEJT`MMC%B#Hu@1>OH z)xZcDMc8n6f3i$KDwiM`Qz63IGXKppBqI&oIP{tstk7fU)=RnZ&fB^3zK?R{)q5~A zDcuzAYLJFaEBDNFdE*VD38<&a5-*qOZVQ66#ob*3WSzseP-7s(lEyJX7{u=a$IL0`kuo(x`-~A$;t7kvs2o3n;$J&;5oeu=kQ<` z1xVw?ucj`>>iCiYmdW7~tBMerBg6+x+S}Us;vf7keDM$dE&W?IQ!M1MOcUF-FolRO z^J$u8$KeY#9@sBgx{X(}Gx3xafXY&h!e>1}~@8QiSJ zoWex`(o=nqghnWn)k2wRYN}FAA*iu&-FiNB-#y&*v3uEd-PO3+EV)!xHJ6KPtSqC< zkpbEg(;9qR%=8_#d$YyhN zc6ZU$-A%Tw4cmtmc7_aE#zh{Unk%KDD#y|xaY*F(M7~dZCabKeIL_i)E*EenH+n&L zw*}IR1fB6|o-IfZKK~5g`IA39KeWKbUc$uPjX|1<=haBb#+NVGB5*B8J8a%_B{$!8 z8<+373OAR<$)-uSx6{?$Nl&VSb~jBXoziOhVp$sIg<~5N|2fgq%wF|YNSRwMHKq1 z+_sggZ@Q6d-v2(@R`o(#hRAT}&i0UVvt&{(Y0D<(q{uocT-(O zAZx(J!^lHvjGOal;tVgfrJV~>5yuuu&j%lTh<*F^VzeyjnXIx4|J<_$>HcS);^9C0 z5{wRCSdb={P-4>9l1d#^7)O4SXm;d#3Q^f@o7r{k9;S3BKVF1lo2+GR54s zaczf`63-UPYZ;h*E9qIYnmyND$2IS}nYL9M z@$EE`ZBY|)zGdK>sGl7I(&ZA}VZ`oLYq@IU7CJ2hH!jntfm1T@DhSl1^!f*FUh*=r ze93%b9Va)}h@vp$>8BC}`xZ!-D;7_AUS|tZkx%*VU;OF3@+l{cnNW@8rvPbO?l|3r zTc}xkF3rzY>VdHZla!B=XNiF#Kuy`u)<&kSou2-6eBk5%nx6HW=vmW8#e|9(QL_xH zDl6oZ@+)+Qu%~w|H*VQPn-6JQCz!eCr+_{5XPcK$3gWHzHa82^%X*Kcf>fW`yZ{sG~Lr9x?gpM59i6TsK zdFK-Mmts?B_G>n^sY+E|s&kjbR5GHJX_ih^z6 ztm@&?Ti*v)?t+v-=o)y^Ef?zxpX+WmpkbA-v}9`AHY3v&gsWhF`v zssg?ti65yECkY=Nxi&Th0iu99Vl!#(>)Foz8!w}OszPTaP`?ihL(R__P8pb2Y~za0 zKLGFF16fmz&5-dIOAAs>Rh;z*quG{paPU~PdUan5q-Tzo3-XHP4pLRBoV)1euC4_% zixQwF7QImt5r8JvbpFe4g^}uz*^0~ko!fX|<8IbWlS1=6Lt5$Eb%mIFu|?(qDKhXoAj$@R$v zF3wyX-c#@_)KSD*N*#174)=F$52xsE%&UcZ{M2M^bQk(m`w)4P-%UCm6p{wH057OWL6ue(7sYTVXi7Z2d^mIGH zIk}UKgDeQrW5u;KzfcZ{P{ZEQh-#rqq83|11DDflLai#P@1}~OCa-HL{VRf zq@n7Wr>muk!1w7NvkS532c)sPt3bL3a*lF$qq-$s=p4`89X>rs2QXS7o$q3w+Z&X` zXbUg4g~@0a0;J6T+RQI7S)nh@Bw%pyhw<5VYI!Pgq#zkD*jaw*j(&XrrwMs2HNMlk#^68||pTnfTvxn8~U1V&B@ySVMN(E-TA~m3_ z1hF;QAQ1=?pd~nLc6T+ysOjU^FJvNetw{}weVmmg6_92fe6gg<5v0Glb<&2#Y%Bnc zJPpM-zN&xM8aa~nlUOY2g;aeNiY+75?YM4N*P5Ii+a-TZOokNURU>kuXcwE4y1-Ub z|7CKHDlwyC!g#70Fhax&0|UG=KBI>SThdjj+nh6g$cn({?I$$BJ{&xzq_xesOrkar zi6u`PCpI=KDQ~o6u$C=7{Tq1g?Kc=J=Q&&$V}ugZM3lv%+Nkz1U)483#IcRI zS2eMo&BE3V&qV{Yv7t5j!V94FJqgm^+@|mOL8=#u2C3fE^%QCi-9#obF0RMZsRL=i z*3wt8eN3!?HW6xmi!vkP%4%Dz++3v(8)^3{jHNx~iB0m9^7AZL@qB<(n#fOE+nf#3 z4h%Mv<&*37aMjB7xM`PT6Qk@KKf&7*gX|9{m=U0w2A*qCj(q$;N+9~=)uz^DJ)8ZN z`p@-iprt$)8zR0ZLHe6b3!LrFCLU)3P+ew7#udbVSyP8_;?4RkKIiH0vkS;bbxJaK@cdt|o6cLJGm0>E^HgUgn461=9)>8nQ2&&8XxsT*^N$pTA z!uUzzkSeFt_sLk6O2`PgS{q$$b#*M;6yGZBC$nIDN*Ii)Sug{<9J{+3q{=B@oV&XS zkS1p!F{$)wZX?6L>AQ;G>fV5puaGh=4A-WTbvPIld1G>rH%5+f&>vxjK*g%^*{ej9 zfSQzZ=FDkHK$?)}^|fwJsx7>*gs`9)NAuN5wH0rW8Mbk$lwevh>B1NG!at({0$CHv z6_dD6GM8b5bZHo}=3{`#f~&^h%!g13pccv?+z3zVg~;oqb|{(80N?ZCeo3*)2DV|T zMV*nc^@Oa*rs;HS(qdgCQyO=CD7Raza#M*TNnNQJ*zhSDFea9CV1Sn=bWG}-);R@f zGjTyDj!+=|-0D5t(y@W=N<><8gXFqc2BTq>$yCHxCgRt_hk0%MIOUYZbgjgABr$8C zwQ`%LMI@VFqR5c^KS{35UL&UvQBqz>LJOP=Qq4FLZ>D0J3@cjTHg-0FG-yg3or0cD&>GULhD zNyMw?lWHNdq7gBM$xj9j@$!ToB781Es<*F(Fqy=aSztS9zQ_H-$^ZZ$07*naRIq9f zw{~n`MJXaz)9!3!o0J@}?lp?tX^w_PCNma?^J5$y8RE#q2$R$(;88_tt=hVZN1}k6 z3}0$a=+^5q2{=!Eel@RWnGFKFVge zG=p>kOAisA$WuyXsTt-hOWNysO5^DJfBhAF$?k@F!K&lQ?lH&RZFa94Al1(okY*wQ zX^PLUzKYx0H?XQ~D3D5)T2%Y|oXdz;V#Q_KXy3e!ePcr$96rI=)FhMDB1fmk7%WUN zT$~_}Pl13Ufr?!Pu+q~hpgo(1oS%$b+=>;`0xyqgff7bYPF#ajENN}eR(3VJyS7af zmtdBaCB3-G3@7iXD(#|HR&00Trz96$rGgA8!pCJwm0xY#5^=XAPMi#3I3F-pDKS*c zGwIiusFo>s9yO(AXA#Jv#L#i6DRekf55JAIb4-!<5Ri#>j>NX|<%gJ+8kr!XLzF+F zkUOrtj6N4Sl`^az|7PXHQ#4sVw4k;qYM|O7^xPS3@S`g zA+G=%Dnf+PI!d^}aZ~u*`f*}#6VktGRRgwQ^6{=6Jh1U{`o=4CR%4JFQWnx6t?t>% zWxpo``?yZ3MlI^i=7NHBRu{}gO$(fr1JzccPAX`24CgS0l#HXUc#3=Fg<>@$GLEHS zF%iMO$s)&RW*D29q2T)z0-vg6B*jV!z%5(t$e|)97z9yVT2aP0ib0iFsz!N3K&zUQ z&4^SG&|dTDta{va#g(jcWfC?-RUa#36UDGK*UXGeE(Q7@eHqcs|cSxyV!)Q1*QS!&KlDKiDs*S zRdL`N<@bjCPDB`lDiLJa7BW4|5W%akhE=Q4QT6Gmc-(*WRcvrj(vwsYwnVJ=6US*u zy;MbqF~L0nsUkBRY=AU$W@mRhD-{LO$G-lT_``!3e(fB9)K(z9r9(h!(oxmPBXRd< zG8O|VkM=vSXZvSA4%;_ExeOCU7|C<+2TzedbexGJ$FaOXCDNvgd5V!o-UukBOh!sG z3{OokUdmGw>+DyU@k$h^QWin%*jJMK+nD>(kkDO&!JXDd?pb#!oBb5os;_qI21ucD z%~p0dCyqpsFxJbykd{<7uOCXQnt)VV)h=F;He6b5zmm@Vcw#_(h-?hdqy}Od%vcdc zg$Gl89hsV7C|_WBdWPwmPr;NfeNDFZBSQgMmt1s0DM|I#`zj?VR3H5wDVkqhrcrtr z<7}-d6NBU!k&o+p$_48!``ml^)oip=q~#n-Rj3y0?1sRKu)5m8m0m}2sV$<&RF-71 zmQ+A`;F+iDAjPYm7Nm(q)mdfP5n`v)09)pYhLYX2_#LsNo$KkZ*>#YLJ1U8zfs{|~ z?i<+jxsSunO~S(0u1GC}qsN(iYd@o}?`LZ70Of%}%$W*Z=^Qe3{`knSBIzqtdNX2h zYMg>!Wu{spAJ&+Xtajv4u9d09<0z!_MmB1>!qr-l61>#F1Fi7D&&hg^gXyWK=Qfo z3wcttn#wq?Cc+Gzqr#Pswe?LoxV>3*(VxqYkyb4xJq zF-w|UA)P)*vZ-~#K}^T{u`&PJ}fErY1Q&GR|LEXdSQSbBgt};MhY>OWNJj7V_4HE97u5g9hKCqDae|SNVPcv8VH7r%LoyB0hP=b!@RRtny9lQiYz54ytBItusTkx|7w{?qcg5H^GWFwazWK zEe0tR2pKaB?e3~NX(o|;2haxa6TOpXjexuk~!h4SU=pM!w37t!aN^wk1BbNP*IHM8{j7EYl`M>@l_ zS79P!knhQ`}!Y z&KRVtui%!>b*!#X2dOOYk{NL{hXU#5FMbL(_d$CG<(|l9DsH=KAeZYZH_n04DHxrG z!y^=4-bXMv$@tL|c$0amqf@xm0NV>lVX9Gvs=d#YjaN3{xa6gd9T8d~u8=Njs05Xz zSX^3!Of0DaX&Oq`ZPFl>?5-s1WR%5n1nGOH>Dv%vryi0Rl?7b3pk%wM+VW?VS zN)kg=*?C=%#bHRfLrN-UEW8}5o!BsZY$3kO3{2n06`+PvW(X+^4s&eZeqR5@FFCw# zAO1{%XlfcN745?Lfts1=*d~GR)k`vA=o1989fY(;usSqZ5B%HRx3PmP{Q}aN8fM8? zB=ll;mcsfTQaA5r<0n518&^RlO=x8lc_Oi-OA1mMeiX&-u4H#R*EU&FVL`#94M*Cb z^P@MhT|g=xKwDN@(jLt3I&W}k>cnW2Y&f$ z4*&9HrjHLYIW!o%v9YfmX(o@vtyJp69Nn=ae`O){+Eos!2B~l5tS*;3M zOLy)(P~l4_EC#uRivCrBLJ{&+q65ds9~tD>z5`4iJ3*=%Vw9>x<*Fizq`Z(+Xef`z z4GmICK~Q8-i(_A0 zAf3zI)EyG4`%~@E5uTJ)EQ6tv$KK%~_D_y8VusAPHU&rGP74cL0aF%?Daz)ugG)cB zN;Cz8ZiFT7SUyi}e4O!j-r@M$Z}ZNpuQIiFKg^VIWAUvfJq86zbuI!_MbOu^84c1H z2=R}y(1pApApJjf-p=kI!@8P|NiEw^qzQ?W1*F;gZ)Tg63RZSOCIhyv-7YOiWzlMP zzX4LQq!N=xbXEnV(ul4>dNgMsAl(|fyJ1^aS8@_6iMmEg_My(9SNVXXbe0TFirH4; z0!oJ5s(83gJ4_W}d;+Em>MIA3v{$e8#_cUQ*3EHOw`LZz`O)ZN`=%*4e5(!|lN^ZXR+M=^d>c|>RT zCH;S(SmNO11ji?*7%mm@GHJ@TP1V-Pp~z60=n9zfWyh|p%G5>yY1^bWGtKa!LyR1J zho3(FIF(~ZVRST(H3PL+6VgH*j7oJN2C2ALazgJ4q&COfZ4J`jjX|1CtKmY+52V2? zODZ7k{>b~;EFj(5uRH*uQ6^kq#du0GeQ`J1ydag^Ef-pv#TDl`X*i9ibt~$X4l$^C zAoE~`#}qijVwtF1qcWW*ELHJKRlI7AVx>e`q&wHHX8ko+klwjPd0*NCVTl#&=buli z$P5WcFCH?3cDM9SETN6W7rHPl-6@I@BpoWij|L8Nw3uh6T%qLqIPL8UoPPWz99xm0 zly)&&N-6Rj6@Nyg{E*uCBzu4LD}Mdc7a2Zu5XY-h9UD=s8CSGfJ&7yDbJgdhNoui` zNR$|2v!N6ZRF3^@ENL@HKcy|H0;$eiFAqy9G3i`Oin642kZ$Q$F=+#&+H27ujU{W6 z?w7fiG_f!$P@L5oqe&L3K_FCpxN^LDIU{jiRJtIRcf}4yS87A0S_Hn zAG+AIv|}a~0n#H!2BLNAB*)nNSdO$neM1xOywp9V+e27%1G|yG9y}BgH8G=-@owA`w?e;{wP3~hiYq#-2f;9F+WmD7ct{cas z2}lFdfu;pc*-ao7+MQTZad(?sI%N@02hv2{LcMPcP95m0YoEmV%CI)iGi|DGC)!bs z%ioBw72u^Vs&`v814fzy~6s0#Z} zjIeKPjB(eYY{z-@L~>nI-?cKGlu>Mpv}mk)6?$Ehp@Rqb)$`Bu){DPj>Wu@CFGH=S zxVCmE>gNGM#*@XNdLESPk%71X6K#+XSSt*oAd; zp)6^9`gSBSX*36s&u2jbU+-bSX4?h%Mzpq4;_d$ZQQi1Kw8(lX-XvM6O7#%QJiZ!IEU@Gv8L8`hsgNW`-2FI^Z85?GD;2qxl`HTGO`4h#<38axN-8f6^?k)tHN1nJF+{ z_VAoEo@uM>sN!lWPG^7-Q~jJ!YLo#zjzf8TjG+Vj_|dn%!ST1=gy9jaR8~>SqMCYGf$AwEk>Dj+@HX4BCO(p;KInxdB_NSiIG zsbkV}4AR7kCb|ufs6@3f_;?vdW2iUwpN6j2mZo>x6~byLxPJ&p0MkWCq)2u-&Hf-kY^WTHOULkj?_B z3WDP1hhz~aiMzxdu1_3D(iEpq#7`KDOJ_yn5N=MLR6zQ@M<3;(2Os44@#D)2r1kW9 zoJo`WhrW(v{(pPL1Gle>l6zpH&Mv# zktm2wF#fAw@ZA)TaLMBy(FY{mgT7&nrkB9g}t?AnntMBNdaz zk}XTdI9gOpdj8$r#F8d}(y5BsWPn+~tv~kb5 zC9PpeKdWg{bZiFOY`X8gnN4Cz-{T;aI6H|o>!UZ+FPi=kySwKLqzdy(YD(vEcb79r z)%|GBaw$Tz&a_EAR0s>BVU5=YCpk1-;DmJQi?EdAD7v2%L}hS;@QH*GD(9h$XE_-=q*0{Apf2ew?>Q zD@++KW!Iu&2@zeAL>i>xCP_b`8~8Y-0xN8jgFk22%|vaGAxstd+8gzRlmh~3@Z`)*~O zh&cCkDusjhVhN@N(%IH)R!q9Qvb#;bu3~~1iUlI|(6KONpfthHq&+D}Q+6_x9X-}S zIG5rSE5f{J3>hJgsPXw8m1D>FhcEvL#RCVRP*DAaM%5$oByX(KeVX(jWzQyc-o#&u zHCV;%RcZh_bD`_Dv50jtCr$lMeKi!{XSFxPmRhz30cj5)I*tGClH0g6%F$mjNf$j_ z!@{=&q?XF=_TGCdYn3I{AQg#-CFky*=fqJnNR>uZ^WHWmCY|lK#59$rr874ux#->9 zjvJOfPj&k)IG&QQ-5lBS(3Aa0EBotzyuMEo$dlpi1Zk(&#J6qKs`K?I?b$MT~$yTPyW)K|4IQM7GQQ%^s6)k zm9$D0i!?SarsjVtK1?FLtp^K>ev;@Hd0v?=U^6K`d&$jg@>8s+Kvw8=SV|SY;7Uwt zvGQZLu_m#kZ7Ib?RvGB1t(TS@1r7Wecqa$;iZuYh6+_&JFBEl zspPX|72rooFpc#IeR(jD4#D*n3 z;m=0n=wh;@=NmdpclU$M(mVsNVlJR}U4!px-|M*XgKJ~2b1XoSLwOH$>i7qC7V-rY|8>6gd(kg?v#z6LJK9S=ZY`*nZ1k*AQL&RTi5^}Qk;l5JFwZ9 z?O{)MKilk1w%Z-_lcLMl`nyUWM>4k}?%dQosj|SyczG4pCJ8G2c_k~Y8TEeb?s;MEu=Rhs61=8gKQt5(u^brB+LmH%e_r4Wv-@bjG z@Ow#V7x4m>MQadLL;RG(kP-0aa-xo2^OX3Q#G7Jq#U)l!lJR~ZZf}FdBqaS|gLn%SPey_@lM-H;DSR`+|cu@*Z;?YQhR40r)T(3fV6mj&` z*ZB40Kjxk9{}8+8D_Il)sC2;uMnIt4V=acH7)G&jof=mdFA!x##jTatGt}b{v!a@;`W`lS@4=Zn@$GqDD)?u-(uql`!tZ$RtRDmfQ5 z2ugS0xI!gX+1&)BH?dtbj`}(YvT5nGQvIxF0@A%tKEZeY;!lZ2PAoW|w0SWuWp=j( zQhnt`h-?{yRFlG@$Y92RSEnZV_1F*tG8fcz2?U@r2Spg>$}bFXLXS+fLc3Svl_#I( z@xTB7;KVQ~v2L-(t$|QzAQ=+Ud{!&j=2K3t9LiouieVVOebw) zMf#?+0=<}68OJB!l-EnSR_WPcGl83+YWf&c7f%N>C#Iro= zA}r}!Z@&@kxMasNaCa5zRA^QWV8VoFj~?cg@eyWHDK!p4Wp$OS8xQA=d@_N@8rx>_ zt+)B_U-~i=`wtKnWgd&r{gU=t+Qkb4Cdx&^_B3Hpl07*naREnB!>Fb5}^pQjC%}C43!#X;TNy& zCc9B&F*6h@6&xu;DUe1=nsP*j2p>Fj+JQ|6pMQpL|H&W1_(%(+=Lcr4L+Opcv$(swIybe1@KS1(%xNZ)wlwdm4IFI_eum9h6yQh0N6hUX3+WWup2 z+FBOH4m8nDM&Aj0sDqG>T9vn+dWuKB{xyuLX&kRctz3%Nyav87hZ=6Kc6YV=+h~mv zhLB`*dm^}}dz%92ZljalLP&c}n#My)jvj0)z!ZQwl>pat6exs8Jd-k*Ov8qouA=Lz z9dO-l*suz6Hl!`p8W%_w*b|U~Ww}_Ug`u-pT9Zde4k8~aB^-G(v9xZi*A$m;+cZHrMdhsGa`ugjyM!RlTJ~#9L0`x z154$76cw;qqC*rFMuz$3SN@!_mwu^uyD~H>5RR@Ye`sscAh~ORianOhumT*Kppf$Q z*oUoT`0edCa;4G5nvzLZB~rp{XQ&aQ4X+4^8{0(D4U7FfsD`uudgMmCO$q3fp^)nFMBI$EJZ=Z>|A zumwv@}zy39X*WZAwt2nhXNy+#X%w4oK_vGUnK>kRw0u8SrhmH9REgLH~wT1FpUSW7zXm>kKX z)dIgDLxk7NBaVGC!M;_3(J(xz1oP^vFGss~?_M?_6(zu5&E$Fh@F9+e9_4g8&g@#G zd{ZTXJgTh7rm+Tx`SxG_6^9>v6lxU}+sTN4P(+$#1mQd&m8GtdxTdI<>y_UnQ_gB| zWxA6Ot=Y*fnRWE#p{*7v4z3Ih7EFm16{U0ehi&0I7Wu4=vAv(Qw_k_xf$L$*YCQ^D zSVk(t+*Fp4K31iUu47qc6%{_4`m9W-n!1kbD(#qv(ABCG@`==|RC9Z5NexM|!3zUN zd3j=zQaY`a{V$}uDU}-jkNTRPEKkvd;OxEY)MsYnh@R%q3=O& z1nmL5-(AHgwqMK6N}AphxN4x2CO;%44@Ej4VmkB**L0KFv4Q>%+z7W_2isOdc?#On zir^>_v}PS>8z=xzdRUcE+B}w2ULqsq6<0X!Ne^Q&Y_0FG{6RXCvN)PSgH)JO+t;=% z=_!G_2#~(~%1hA|mtV1@mb6a6YogI6%77z5#IuJFvbUJ$L>N%ZWEDt--P(tMuvO)F6I60>sVVb z$yIfns7VOgYH6Svgs#nim&dvG60ZE6kHfb0uznS!q>LkUCDHwjGr#pK8&_sy!h?pJ ze$3W&N+^nr;X~qTC*wMmEtQ(lX)LMq+NxS|JfF0)QeohQXZiLY{U?|jQx;w}yZU3! zeA4<1o8%mu6!#>Y$f_|DX+GO`xf&w8svOMfC(WmAj-;anK&rijc;C^<>=rF>es_1N zLE7ZlHAJZ6#V_97NEoTC?%VkphN4h`)Keg}NPEKT^f8PoRx!^D|M(4Fd*pj?Vn`*7 zv@;p1nx_V-zUwEe{GrCR%hc{R#mhChA-jhAR$RiBRyVzc2uFFU(o`;`m3U5wlsqhh zDJvv%#a33_eFJTG+^A=?ID&ksj@TGt`Ri8lnf}GEU~EFUr2;&a5Hf^IdwP&sF-V1*+Yfwn z)n(k%yOm9~6geR-$Rxekbr!{Rse_7Dok|-N*LJb#o?FP>eG_b1qvv0UOX>7?LD~#fwGBz)NR57!OmGsD9^>W7aY`vYX5&IyQUU4VbVS>oH|WNI7D!JM zl`cbfcOgqU97a4P1C(Z_851Rgbe6zyutHO*7Ni0nml{KR-{c>^^d}$#mI_7eKvE@o z_<#m!!=aqdk_t%OFr+hr-Q>7u{Vs0F_OsDXV;5^`PKba>Tv4f^iV{T8f#EiT{(Enx z_x5XG&kk)xMfJfEITziAmKFh()5r&$DM%A5t8Hx3MRQ?6x_yqj+fkK@d%3Sr~B(4uG7Chd;k{ppo_`jTt8teU2;YGGC+X45X1 zfHW1FOxG$*WDGJlT*~^-e*~`HrpG?mI#?CUUA46?Q%V>??_rSUnqtyhJJzzQ5}-gT z8b`93wLp5>eD3T&UL=-OK$=YI-d8B_{R8_rYD5%WY4VnAjE(CXw0Qwp-@~68rx~G>10vUxsVPQVFpQ~xR5SR-H-e3EvaTC&vti@ z^YY|q?Cy%Z%=t?k2}qSCUEN3=btFP$Es&l8K;@|y2}nh6PtP_n**i1Cx8Hu9v2>bp zDx)T)8IhwTM%rpZsQ0Li4)XV3{xTDhve+QdppwF|g$^v*O+X8lzbYwFeRPe9b#OD9?({SfC1UZp!(KSz3(vo6L zrH(57q(bF8&4kN$2hv#CLDfQ=W6~I;GCj@^kjlwRMm*qLXLnm5JwqIx_UR{sRFoOM z``z!VrthJ_L5!tN9BE>^b|ZD^!Jrlf+LBr}d#9)Q&i*$T&t#}L8GJ*MMmBB`k@I{- zsGr=ok8gbSt4!?M2jio-qT+{75Q9_?nLRy7l>#6ks{;7#6+5}7cMF^IuqJddD>ZeF zMaNV?ltfLbw+;K|-Sq#5&%?$pY8ib5OL)AJPHu1~gp_+)kj|B)oNaSwXLp{Ji@8=zx_B7R57LJpeprn@93CFJ zFd&s?ZLOfGV>oF&tAr6%!{F`dDZcm4+e`{b%`}1GVuU7c7?JgBbku4L{N!gm{I`Ec z>G*M?nF$e8QM1>yFqu{xRO9aEvu3d+l{%rotS^M$UAddPyEd{V551uSm8zRt?`<*Xlb6z{c1q&~{2Ksp$~3x|&K z%ESo8behmkoi~t*=F==oI!{bmXo2($?*9BjWdHK*Z!3_Fj*eUikP2l^Q)#43p<^qP za->1}*3=Z=k3m{9G8&|ji5rAuf~o@P{wJQ{(f{&asSFPh6=!hc0f{w9!zz&KnJ^21 zRASP;NQ3mA?#*nSiRhAcxN1eoEC@)a(k3(QY3wVvvEkDnB7MjER3;ZIChsSiux8_} zx^B+)adMqhU#wGu^h7BAq(^vVQiC*d(lJO4mCWg^lo@#8xpP8h5Rf)o(&ofbDoGsW zTn?o|a(CXqwpMm`frT)?r02K)`JdJ3!}0O)#t3UN2xO}??sj`+yGirPv66(;h0BM{!3IaOI2}u9*yJj2-NZXN~ zTVWhs!7UwYSXuT}cDEU%2c-ma*9~m@`~z^w258S}c4Yj}A{i~l(R_&`p~QXro8MF* zot&Iljv$@pher-DYT62t-k8B~&ufFwNp8W6s1k+QPl@gA0m>RwsIiZL? zNi+7mF0bb9>d}ay(lGjT|K;4(vx%K~lRjxVDHRp|N{-2R#$sws7nlC)k7D0;HLPC= zxm*)So2!_yZ@R=FJs!aG?+ozT^qA@z!p+9nU4yg&sn7z&k_t%2Rd>$W(gNoL>58Jq ztn6+s#i4XaZXS>(4o3^5$#ylrCH>YnzNvI~CnuH(NULE;4N20NNS*YtL;D%RMBH5g zsnASQMnr}x?(`Ht`^SIgr{DS)j6#8^Tu_!Y#8(P~iE(SVyK}8+1ElFNQd&m0r2F~Q zwyU|Kk zclU4&p53>P{k0-_$BErtv7~cB`iDxHK@=3<4M;mN8kV$k4ZVfhEK6EyOL1@>kR~(i zl=yhdlE!y-{+RTizwr&FySqF=nlJMBz&l8sr9f(EOX?aSS)+zMInJ~H?H~B{!;dPy zF0s3NYLK2B5(o!ghz!zECPR~M$n^1vEmv}NCCdh>lNL&<_A2Cr;haU`%1vDM`A@(t zR}tl0jFe1(IYrE?gYB~oNM|*G&pJp`caLh!F@#@*8fbN(81USIy&S=3#<2-Z$?obM zOP65E3_Sll-~J;3={SV7a|Y5|JJ--XBe{aa-Gy>{W;RH-uZNCYy(hLl#k=M1&RZvy z63jn;Q!ME+2I&(=4sp~AshW~FaxnamlnFV@BN`pyhhO_U_I>X$rA}|wD)YFzNyfE_ zwl3mhl8ucO>c!m^;cMaUUg@sj{;gMWZ6(9Tib=LyQ(ZCwQc;i(-oKk|pS=%m*oBw2 zaGYk4#-qra5p~`{s^_>V3Z4OPO_lk{p?5eT`btt?mgaz1^T{o~@Vp0WC$uDTB(-ugZ7t8!5m%jDj9Tp!bXZH+oqaoW_@4}n|}LVxPBLY z%F;uKo3qEs{LH#*dVVaa?#t2bsnXLPnl>Ug^XhnkpB_HMaLS_Sy3_)pDe5v%+V|1A zyHE3-FaHUQORHM5B~AKW8w=-jt!l#m>cL%`^3wZDUJ}yVKcqsy)Fh>-Yp341-#zU+=UDjHvgKHpvC%GSTNGB-K?n{)W(v6-+wkahzsLH! z?^7UkQj*5$2Wg=JttvC(pLG0={V!!AcqtmPJ66UZm6FvpHkJV8XCI9NKJh+a;%J~UE^%eP=e{JVZX!Im5$uiYHP|!m z-Qy@Yx@?ZyRo#8_L0T}`H1kG*)P?QXXfeaMcl8>qOk~jHhS<~)5yxa(UBE~pvwaH| z{r<05bJx8w}0V4P`*g75zne5z-#F|ijT*66%#SjF2U#=JDia_Y+!qt z31{8`nELVaf#VL9I!X?kK=nfV6Zi3;x8mMDkNqK%lq|$V&OzD zoL4moGpuq%Sqs>qHp9A6209I3bE$#ychASPPrV-)I|8UG>la9QWtA5^xGley4es!_ zN7@ zl*Z8-iy>i{a9GMg-aIS(XE4mR@zPy)GN3Kq*eEnS?XT#-ToK zpxki~awyrAB+W#^0@8|i&&Nc9bY!)tyXl%rq--N<}@6s~Lw0b_it|M+$zmMNQZTj>klLcTbvwY-Q9V&=+9&=7E%n z=O$X5EOKT9J8cIm8yfM%aMqdAY-x0KUv9CKeH&wWrSe=>b>{jk>C8*11VcZ z>H35Hut|Lm>spwYg9@BAVj512k49}<8kMYs=%|kCtYndmMy1A4)p^HZ+$Y};3@h&) zq+Tggsi@(ZA^Wo=WwpRt$vFDK53x^yRIU3qIuOFkjcs^oMup-EY z=?%9a2?jzc&LU=KP}0(hCvUz5FaPs4puG*Cx+~TA`)QNvoFc=(2!|kz;Y0O@<6V&& zls6|)5wfHz22~7tcatGYY|;Zh_kNU|cM4EjrWi+F%SLUJ`fV{1#3Y$$2&7Us`nFqd z#See^thNcrD?g114T?PvONaJFq5^LMB=wT->yqMgr}KCp+={b$`XO+wXzN zBG{=;xVc2WB7K3(;PDN7>@y9kd}R|4%n{Q-dB(*I#BuDf@i?ZY9`%_phNtPSvXH2& z!uSuI37mT*FkzVFkQM_e|0-+49#MBSH%DJdIrCDcfz5VSdgZ*)(1_(*cOVf_$q39C zV)+(jL>545?c9lnZu$e(J@7C>$s}^A4j57^$}>27bsQB|J3iJZ$HJ+hQ8;((4ADMH zTazfWELg5Bv1Nj^!!)q9B7_-V{2;7%p8yQ25L=$U2T7#Y&LjVIS%}QnQDA?Tq`6E6 zx88aye*EJf?|UHSbm)YEO%CwfhHZGgr45}djBSOHb~8vC9VkyGu=FlL6TQJ+v{Tbj!v7<2wf zi2V1lFlJ56TXT9MQQg(^U2z-+@7?tZq$p&{&1z4(`pJ;XCIBm1Tk*=~t=OKq~ z5mTHPVr@y3va6h{`tz`*BfYyVb>*1y#SZ}|9S+phNUID2lt9gc)YoX4eX$Cp@pYdNJJmE%>KZ6Z+o)qvvYG>N zeC8axD77<4tXYdcFSs1;>no)D zIrRgAlznGJn&!dc!P4tGrxrUV(W@#k3|&q5zeV&@wTIyN^0BCAHK+C@N-PCZs;_Cw zKwHE>TYU`<_`(N)W9F(lP$30UuZV@JE8GJ}cPG*Bo#5T=rtZEKAPuYtd8VpViHCtE z#`Ri~cy|3}Y-sO*RauF&X(MAK5zD2p`N?PS$hE%)8k&G)3dj+p4AB&9QooYu7YO;3 zFTJmqU&;x{wuht%&O#YZte%WhYo}mbv4h?8BI3fgE6i{x*0f%Xt&Y@XY&73*8u(CHdTha*TBv{lJKQq!BH z0xOq>mFz@)ycCcB{qIv*LJ@CRmavZ(wJch4mFCPPy#c02^0Tm5T|$_p5=*^U`VO z&xBz`#-NfPoGX3(`<(#Nu8yM?7>gG_=^lCHk#DLb?QNi$Q`!PxL(0X=TO08D&Rs~d ziExPS{S+d(G@4#pj=Qe87Fe@c_3@-6b$bD+FU}{j!KX_V$lmI%N~I1jD+pHMwCZV? zS2qb^*Fv*lW9qplVmL!FqsxI3b|hD2T8w<-CGW|4u}Q`DE~?A17%2;OyD-_`P}f*7 zEu_K*S}kB(4p`sOftS{ALI*6Vugk9CY0E^G($?#9YS}hQ92?O@C!%d_`1fyqgN@HW z541K(u56gawsTnlqtZ0GDw!IjbOz~LB}hqPI3hX{pBOm{)16WYQ?X(OsS}C~Wk_ea zZ50+;#@FE3AAA{@K2iFrN@|~1z=HQ#45WSl_XWnDzJDixRC9Of-EC%9hJ6jBS;IgF zfL&~V*qFi#8#bcJQ1ym#p)_KQ@ojIwpD(=vsiiA{W>RkDNRSh!YtI{@KIARbL?cawRd9Vfm3kk=RXF_84pxOC9Wg&eGN;OlTvZoUJR<9 zLCWwLt3^)-eRJza6Z6+iugtNc|BZ`wpOu+?JQ&Hb(Ai^9{ zuf7JKi{NXG8rWQBpyY@dIQVOy0>;+?v8V#6Dw?6Xqf?Sf5elzylP6^d%hbwiH3buT zusDCykL#Vx&J)+MBOZE(iz5om{d0w z(P$L2&pZ)zO#U8KrO;@4)sonL!gGo!$QIvv2dR>1l&CqwM4E-h02z-pi45M@x)mE5 zTab&!kufaUhrr~d=f^gciW*8Kr3qDX^JYAC*Iiip$iqNevxHudO$#s>2GN}+x~RJ{ zc*+UH=is7MSrSGhnH3Vl+2anz3DME0>u{ww9NAl>GV<9orXj_{H}VLzBQ0*xHLLCWa5B`S&(huaPgFyBnw2_dxoeg^#<(%s*zI0jW|SRgcm)5~{$~ zde-1IvdBepC^2%V=tyGG&Huu4H{Ss?>=fgMa>ueMdsL64eA%HQE2}?(;+M2~67eK4 z7^rr_7-7axAFaaV+EJKZKLO(oISB9i_ywq#H$&-cIn~yJUQH#*)WjC2h`0HRa~A_C z?O7^|LY((10MdcRz)~w6MJ>(Pu&WV`ok?lAk#cE&vP!)wDXP>&1r#!Wtj-RM2!-&< zLl0rm9k-)(?P?&|A!dQpGqedpwR8nlUMUbKHmQ>8lH_dyWe#w3s1|3|AB;JuLTysT zmlZ)?MAO}o%&WRaq} z3ma9PDXe(p2|W6Tn~~bEQ9=!-oAp5IN`{E6%HE`)!1J%H#gbP1-!n`=>R>5MR3MBp z*TgV0j>)6Opnl3kob|bnn`CyP}(8?dFl9lJUba7~7znDY~Y!}?GR_2eTpggL8CqCyIAN`bAkOB2AN4I8l&8MM2dh#4+wl3BFBz8ZJ^>IQ6k{dKt6gh&aC&LhX^ znndCObs!++V2ERb)$3s*W<`**(0ON zrjEDtsLn6~e?*)tDx54{y#IbY^7}smT*Sn-%)+s3mBFK{DY90um%^t>_2NkLyt}+@ zK1&?HyGp8YZrwpRJU$9l%^8$uS^xC0wA9cVGqFzhTU zlR3ni+i~-iKgar)UV@Ws1#)Sry=#y|ng@u-*$pf~lv@6+tKnWKt1VK6_GxuBTAEvs zhKtH*6!EfhoO#w+_`-!3V&=TL61yZo8LHs^oRaxW4o-SMNIfCuBjt&T%cA*-R2J<{ z4lA2>U|TkcO`RRsnMorZ4guj9!d46hD^;)>q8AjFgaLAxsh+wj>!oAWDm-?}Kd|Qh z2PAEdiSdk^<}B6JSi(hlADilg?guH=T}woy3cHMhiDRn9;k4?BI5=E`csn`4x@;<7 zI}Vbrjchz3y>e>Lo{zETo+LeBvJn&EIJ0*1Z3RR%7D}cUTlK#SWtZ-rMY(%N2PVs# z@Xw&*h;hzun2|8z zDFZ(j8biwc26qn_GI2l?gb=7Di!1YYN=tG2I}g^;@Fc< z!nq&#Z;YQl9c9CY!3aeVvBGe&HX^2l2#X3*P%xt6b!lV1IR8dq(&kLLz^>LLcDA&j zp|u$aIOs5KBq^Eb-POKpmt+9uiiY5tB+)B%lx1MZ_%X6+Ni@i8-ipP4_#4(d^)wRA zjR-R#K9h#Y3>6(qChtQAp}Wsp2UDcPjO${!4IGX#oHKd`j;b7k>JA&R3`0d6r9xBW z=41k>DMRDvGEDsZ1t>dqHc(v-gu_52sq(s9P>&UWFgr{2Sa+Zvql~ zxkM18qy_%#pZ~&-$lYyiRg!d{11V=PS5ym9n0mwi^=o;4%Qn2;-iS`=hGrttnZov$ zUd3O2_ETWzHXxglObjJSZKd)SF>Lfp3=T}!UA6kCMm9(*q=Uzbg)qE+Easnb3g*tA zkEt_eB3@CASiBqvMPP-(h=d{tk&WYBR2(cW(3x@3mQ0{Ekw9xQfsRZDNjry>Yr|%D zHq%DdVCxNbP}77U>0See>NUd|(&~{ORvV?ZgSg>h%bJyV=FYpY@u7uqb~eH=sruWn zvuPPmTd0C66)Hatd2?AwI)kJG5*Zu^Wrm4~b{MCXjK)c|6L3(Z67kNQ*rLo3l0J5Z ziFj!o+uB-?tcap>+6Wx{-H*eVQ4f@s0#Ttlcpqi76QKN0x~v9S9eGLmc7)sDz#g27 z*;HC2sc?4*(#IZqq?=9pmP%3yxOuC*2_!5Pj(M%U6EAPyip}k9QV7gUXJGAW!fn6# zEjB#)AAotK>|kx%$hk}*SKdpR2f-xfBDKN>3R3dqLZu}bUSE$nN6*KhM;wj%NmG#t zN0BOt!3jqZ3P)jC5y_gN|5;*$j)PP-izI=WO(UJl3h0b*2yV!dFbZ2Y@(EPC46h}J zr!LYmj7xqS$vNGDU01w)Xwx3%qSAobKtnVSk^bl0=m09z@% zx^+8V-MSea(XeYCHzSIHwC6QXDSZBQJa4c0 z{>byY;V`VyQW&Li9DB;?IP&&t^wIm^na0c6vdh!BpB)#LQhQ!zdpLQU2{IjwD%fLHB7_{q4g zFpb(rSKy!zo{jK%#{e}YKqL%EITzKL+*@+;J!;o&2&DTuNL3g?GFoIFiSH5_+eOl}(3o+sytNrm?c9ns7TKbN+O-3Z{Ozw; z{nXP)Z`_JdMoWpp+t+Gie=G(iEQ>fayfjhmRAP*h)%sW|fzlEoa_3?wnJ@{5oP09I zOg{hA%7 zg{|vWW5x5&;f-gXLt@=}#bHjQrNf*YEz+(KD^{Mcz=tNHdMDq4-_5K{V) z0%)Gd;D0egAl|jjvsn8GY;HH6bTbp-I2zV4Gmb|)-2Tp*dONgr=P?l zx7>o(XO@Wf(_#pLQbbb(z2El~NQF|zsb+?RKkHZwk&vHi0Sq^=g2Bugm^t@Q%$R#9 zDo58L7q(!BO>~+r+QSBH%Y^Be;w9xrIS-W0W(%>M&Kr^mEJR4SPo$7;ZAG@T9WN|i zh%IYZV%zeiKvSdY0%sVA89b+p92+NzB=zeJK7e{6Eblz>sqxfChW}qH#ZxLKW?{0~aVDdx7nYSP z@l_T_s639*lO|%u+_|WqG8q%5O_5qZ?9|3$VosJo)F355H6?+B17#mZY@m75Hf&$B z9;;qmimmI`prfe)nXMavY!b1`3Z!;6$f72$84Y%CAt{7eJdo<(uSdZX_^{WGPzr$x z7nqJX&aa=1Q%lBRL`w!0G?!`Dnu>bJ1%`Gg9Y>w4^*f>rHOI|G%_q+VYD<9XI2g*)H$~z=UyGzoC9)7?*>BN)v0g!4K33=4Zj__g@(o#XK+>9S?%>b|O zY{v42jo6iJLA)%2WzRo{JAeO2IIGqH?HPnAeRK+ymZUyzXirkLH;{V%;=FoDX-a8f zSRrI{OqCM@&-+Q@YY3rO47o%SWh3e^W9BT>&zO#~spEmNQk0dJAr^_jV(inK(44O< zh}_)Ri0vCUqix47Y<*)5+PCjSmONz%r!Yn(z0sxl5*$TR2(CnaTT|P)L~-7dAgT#a zR%CR58pFUCH-z&>9fBiDM`2<*B(^BqaqtG+kPBPlNd_{mBLBBm#bD2yf+-(73plVI z7&A4Oj5@1A_p$@>UMeLxkv&?|23Rc)uN zppBEVfXxYDY2y~W(Xbf_Cyn-&COmQX-FW?;2Y?-|u+o%qN_uD#xpvtGeH8(ds7IT$ zpdM-{7l=Flay{Z&G7Xs0!;}>?ZCK$LLZK*1YO4_*H4JV^4ADpo;cx_|NiMFI{46rx zh)gntOlLyWTy!LWR0haqMKDs$Cpkgxv4^g)<#;rI=XQRr#yUhKpSz;u!v4Ct}q5PE*a5 z%S)7s>s?wB;(Z{^k6|!lMZc6GkiH#2+Ep@;C+{gP+XSwCQ0=Xc}EM`bzUx}-#OJKsob<+S|K=O z=n!OdFi8S5%c78yj}R8zA`L& zZ1te$xQ~ph!C4HXd3BR?K7!Tzh(YH;Y!sBp8+RB;d!9F zQkn!sw?!m>zux{{mX0`YJWg?0ju|c%=0u0%xatX*9UqCBv?&C7dUNS4lK3v$wtDMH zBxwUR67Ej%IH(q~okyIfN#tTUfKA?7$)m;aupvd;D z6q7pV-~6g-aE({apnR+&Ptp)KPhS622B|L2MenpMCgL+w3?#M6_&ACpu9R+}09v?T zE$Isq-y1tG_DY9T*ijiSW6cO=Myheb$SIgtG6I#YS(MwBIIQTr6P8qnq!QL3R^b;r zlS87q6rrPMUY!h%oH<(&a{xrg;Zt#XaIJTroMq10%_M-lT0RX+rMtZC7R5z zuS?PbNLi{xg=bhIgp)sIT2iOCA(h4U)(&jgx&u45ZNW2-Jb))3c@WL3RtX!(rEQlh zNYk#$U@_H6FABxgs)2x1RCT#vP{H%5be^=){ApD0e+aNY^MsfwHI;i~z{I7KeEUkBCffpFBv5Q0lxJGd%{AfHg0s z3LVaw^gRY94vy4fUe##4tE>)V>@bGeA;dBTas>e@^hY7xt3`!1j2i3W7;(~J7)vS2 z-lMdOLnhK;#ViWBI;p^;R}QJWy@K`~22%DLDS%WJ`3NIrTS(g`I#LdHwKQV&#$|Z< zrRQ<$KmLjJFTbLQ21$B5Sf9ie+mM?C)4Od&Vi~;+agnf2x6}Iek)(FdwpORrJYg?1 z;)!`#Cc5Z~-dT0VcwXHt*n3)5n_7*|tK}*!Ojf@+`Nxfn=qr6j%hVsx~&!MOkad)-q{J$0X!q*4UvKbjbXsD9Yo+@I6|0? zN}Moy3XZNAgNZ0XtR;yE3zwP78y=N>QFU>GGaU_~HRPhRGz??*1k`=(bd=6L0A?ji zqcBeFv5P$WTkKKo+!_=__8)-yheyvDI*#6^Anp3LwWKMyloUw$Y0Gw^VdqXPS+WH8 z+MLF_B^wKBo%~CqG1T*fKV-tsvV2Dv_XwBRJ3PMLS_P7 zWEclETtsNUdv$*^Ap>o(5LTyJ5Ib-@roI0(l%97CvLnkBQNcA~>XN1&QQs>SJ}7wZ zuLt=Tb-&|CBMOD;J@Ld7NbPDw zX=N1>Ep4htsc&R-NtL`c>MiDZB7}E&4Jf~~^+y8t2uOo7)dQ&(viW<^@lF-*@SIah zJ)k6vIR;9ZdIlS#QHlfOqi{&gC>$86!Z;&_@|2Bu#zjd^5l3{KiWxd0g<+sGVq!Q6ZmV=g!aIA|=gF|`EHOHK7!Re4lgqWx12?%whe1nI5+{1<+5$xoEJd-pwe zx@Vqo=GzXWd0_g>Kzb@;iqtvUP>zGf#zs8$_~W?cmYea+Q%@t8N+Xv{=Uc)D>m3!d zNd1zozaZ_R#tc-F2HtnxTkElO^a3H8gI0&7B%-=|ER$};3voZSQqkto3N?J}f zq(RA{Rz=ae(hzrV((Z3Z2SNI;fBX}d{^U}$vtiR+cirKhb=FyLOOX13%HK7iKozr6 ztQT&bi3A>h>~Z}5rkim8op&P=iR1(BI^R+=Wb{A;?M&u==D!Q7r$JB^QFr~j^r`L^ z0jXAPb>K$DQAu(K9ELtj16Cv?xu;G?3e^Bc!NL?&;ppL0F}b7)Ih?C=(YA1vR?bR9r=wJcr zpTnZe7zS>-;YM73*#fk&IQAWP{M$X}oO6O}cNgyG?p*xMI#x-}?h~96vZJFDRh5-! zX>G+5RDEy08P6Y*Fv%^!wDMs%uzD2Y%w%Ew(^V;a z%xWPkh@Nt)%an?&qM8#G7f6LIbPg*;?C66r>FncS95h)0RQhNb5)*YT#miOO5I}c# zo(CoA4cFg*D;He;&H|~dMm?yZ4$G7<3=s-Ry`SaFmf?>#+=R#Pdk{?x4QOMJQ_tl= zsX{V2TSvGagC-v!q20#3N*`@6FSUKsHE-woil9knKwp^>?P$q!lcgu9T2uYxhOVly zSFM4?x1|LH+Xk!Os}VtMs2pR>5}Z725+)jP)F6y1BZN|VU`1Vbg&xUpjIIVjshFl6 z8gh|}80d%?=!}O^f5PDycJ|T0%t>%+%8)ipM02L9v&7009${j4C+E=dg%Qv|<@~wv z`WtY?g3HlPNqWmIe|O*azW2TDC26sjt-~c!=h@?-N>6UXz{^iRiwFOG7nVHvG&ZkT zg^spnk)gH~LWA9jPRo@dXf{dZ;$2mh60Dqy5OY;kj3eJ-KA)Q9OTO;HMOqOU zl(hA#==0>ZEs5sr#li9|EOC-!9MsJs8MBb7t3cKKSr~r8JYd!&xFaj1_Az_bNtFng zLRKhF1Q~+do)`fx%mk@O(x&|gq#QiyCQ6CMJkO34Hm+EW=O29nuPuBUt6y1$bVsKo zH7{@4h&JTV0SB2d>-Z=V1>=yGO^_-|p61pn`kWU9Q5Wi(b>lJk@+yrdg+#HX#P-tC z2+{&UL6;iwJhq;S%PO|CJBQQmv??&lD#47}(HI*oM_nY2+Khp^q=^!nLZbeY(hA;{-jEz>HzOn{mODZtFqzV-|1996xNzz6|MwMQXtQDrM zvV#omP_LK+FG#|CN7z71iHVl#D6Gk&F!8v*tUEXq8S@IckROZ<_2u&*oh`&(1r{; zkwp@=bivTo2mBx!jnJ;5cqNEO<*Xw#%-b-yss6f@8e zH!<~`6Hq?q07Pa_0ftuqG<-^H>O&wfy64#dV5J>klGz;e=NN>3AdQo@xUr9;_ zkjIx5w6!IqfLYth4OqK)2^wBl1~ZXCBAZ61ox!?>E$DDE*xuHJ?WtC5MJJM~cnN!z zi87cKUNOsDvT>7}FTxcpv=CzX5mObtmhNQ)si(^FCqb!f%^0deF;o~KOsF0%fE-a) zflAxLuv`dbSwn17*2yiknV_v|6?y5_5(A}8P2nkRF=S@7Rd9!uArVnU-*|tl+Mrq_diHlnJ)h?0zB6^Ly$8O5ocV_9uJdft7UekFU({VC z6uhhq52R8>G?N87(?EL?XzIkK2Nt1y^=9nYxEY!DPPmMrlAvG$&2|#Y8@Hg%$)F>Z zL@JlT&bCG*kwK1?6r?-1E#TEQXyG>n$gngpG!cOz(vqrdsS!qbv=nhGjEYbM72z0$ zm6W3s1QP?EQ<8V zN>t67in=3a!#sF0Fnv4_w~(}4xpykHQCM9;>V;`o<48EdeWafaWI_(@+jRu!qqzRM z>u~kuSD>wFKLV+C(&WpWNb3e&pjjE2Ica5|19r5bbLm<%yu1QiUVIJau69@*DPi*@ zQ%RK6R-hxBMlzj3GMhn1x>Eql-_wSJt!+(W$K?y36jUR{uY@YAtwJ#LHtF)6v|$+^&DXwWsS}2d7&mnkSlLgf zEo{ITJsjbw;}AdO0F)m*1(-1fsEPw6Y=F#CEvo8Z$h6csbww81;@UQ)B-QeI2&j8y zeIdK;#v5)Bkam!9w7*DFKS-5Cb)@Q@#3ZSv3iF1O6EJA6?&<)xw*f0RVf7=6(e%bT zBpMn~5ss=h^b*%ppp!yfxt#pokxQe~biC4+UO_IYSg6v#xOb|fQ<@@G#!3aKW+p2n z1A2~i0!+T{u470sFn%vp`#i^2A%x=*3_M~1i3#bDA#q-IJ|lxDTTzN+WeKY19E4#< z&r_0f%y6KhR2p))5ycu(S+<_R9RMh^V|0UGKLaW_ONUh8-N&u%*b;)d=8CJ(-rNG? zh8wPPKmF-X?-$2jZl|UVInrYwX*3OCEVFl#vmbHH87^LhaO#eqm9ZqIt>@$5!D!X*ld(f zn+O~*Nx~|qECouUKscgez=fva1(5n@gw6=kAtT>+#XuRXG_m{BcKlfC?mC$NS`y=22JWCp{W&UZbf?iHf&wA1c`N9(6Vte zqRA{G?I{V3kQ>YTKDm4|CRM3Wq^=Y~D*#l$>Rni~>++>o^4=zotLvx)bwQ{!U{V3T zIzhz_At?@KvF?y5{bktOG{N#FQ5#iL$D@AcbkrU+6__wus{6@@l@!7u>2oR-9Q5nv z>GP{Z@9$kQZ+h6Jz?$0s=FaXsv41?-u96_V=BlgF*)jyuuH!1{T8h~ts;o?4dP*1& zWwrR60&B{Jy<#19u3Ur8bz9J}Y9ri+7GxWm5l!YWqO?NPQ*o|11UySK6>MNtXsoal zYU*EJSOzOO2zr%T%@QVA))QhU^pGkHmX3uHsw_vWwhGx{Wf*tbk#I*=Av9(rP*x(< z^2Mdhu5Qx9MTt%_j=F3^Al)6D?bfk=klJ<*zrXP&0coPGy{jZGa9{UNNvfDX{#IlZ zT&zr}yHf*hI*S;?Hi@i~vg@}XwPqt))^0-6y3MfKQfOPZS)4s|@(4r8 zHlcCzHY9d7p=I+nX~}4%ZA7!K#5hA)rpMVr`1j|slKjpZLv%v18hkDmLW&YF9z&?2 z6m~@koM9Cx8#4lo)WJgf?+j05!}fp`=sk4v9ZiIqqzS2jwb1IgnO%RMq&!IXQ-!@s z4!V=Cm*OUewzLD8T%m%Y%4744RIe*rCjqcpI6dIjlkfA?$mv;Xtiz!~>HN$MW} zot2{GP=WkjDB`EGVpM%0kAzNYppz3@vy2&@D!oOVO*vQPa)#J!SZe+<$BkZNI-_j0 zU*0bDBsD`LY-dl9GHXT(glh@Ub1CUam03HXBn?ln=%*j44sXgOrnau7!gOt-{!c1h zo~EZGhC(p?AImQD&ihA(l9Z04Ydo9uH^2Rr`?=44ZV05l5eOD5?kSmEPgcz_5TWH| zuc&OBJoljM_~tvPDVm}JmJg`@*i60^pue=If`P8|sY`r{4ejNm7A~mRLWQk+WHVTE zX>e1_dkk3xdJ53&&Y9o2#|DRs>aMm)JKEb}{QB3wbpQ8%|91$ay@1rO{uY}mnyatB z3l=Ttt?(FaQiV~rChQ6z-7Z3(H(0JDA79lt_jR5th|R7tv{*~I0s4*lM2jw9-sg@( zJ1EU2u%>C7^cs413DRHv>KE?kKmYk5koGcRdXl925Z#us0Mf2t>#I7T25RB>K>X7C zB6yyBeAORU)oQlCRD{1&cagr2Lm+)?SBu_2Dw6bc(+zY>W;Sfl7V4611s1Mfwah|4uQ1$p!8=<_NPT_ zcfi=wvE9fswvFqryIw%r%C2g(N#Bl=)E~C!E9BANfelVbeT_YJ{{G&_zO-L|yw5`* z-Mu$f45T;Qa04#C{BpFjGQ&03T;+c4YhUZPx~m->d@*_w_Y`E`y<0DSw6u%xnkVT! z_7sTr6_6HVAMK5??9VxaW6fjs)Oh#j`uoE^-B^^4i|enyPC(j5NqY6wSGr&S`qu{p zQoS=@U?!6hM*^u#+@jH_^#AN>Be471ovhe7n8L;DvGA7^|1!<|CpdxlJ@?lOOHcR2 zXW+i2rKMu1S5{W$j|qB_dF}qFfV(rfcz%v&Nl8f;x?nb&h2;_Jg9Hfw_4#1Aie6U zE8K5<;~N74sRo)phy%pI;1&*t`<%qPGs*cvczsSBP9%L@{cnD!fy?{RFNxpx1TZbR z_&ov3<9Qxli=VQxGI=&mVD78WHJBID*D+cv(F+johk)f66STY^j&WaGF$Z5?$LR0* z?0V8C5(&BP-Y_rvdq4fz&#%pKyeKTV`G4n_baZs&-)Dc$`)2IZCrGcja)JA;Z+>e) zAZ0^du2uvjAWkN3T(SCE$@}`gw}Fw|Nl(?*VAX%)dG)H#NzT7(N!r^A%KaJ} z8}pzqFE7snl*bViot>R>?y9P){5AI03)Ef3InMeScpn_|9Xoa)9*-Bjw4SK?=U~TK zYbktQ0+c`ZWsq|2Q3E0f`R)irKS()lynoJ3t)1+xcQ=^x_GFV@dBqjVadi0=mvsZF zN&@cLt*#}{vSrKg&_fT&p!g-4mO{ZB){{nqYOoFmUZ0>DIdUXs%$R{g4?R@C!}IYP z8#ZjfOE0~I_3PIQNRK@7NQ@aXMm~Ofk6_>gT(V>d{_~&z$cyGn=Ckk_I9c^Vz!mwR zgAT$er<{Ue!-fs!UG)1HKF6j_oACJKkIPRj-A9ZVfz6vY=OPS9RR)rN^eS(OE0|??|tuk1$+e6 z0}niaJMOqcKuRD}8cm!y5%cEF!v{b3LA>i-@5-xk1S4PIAOHAAc@6?xOR?a+ala{3 zrr_WI{x|CC>biVA*u|!&=jZuWuU?Jse)qcqRKMo1JNA5k9ef-|jx7@}KK}8K%i`9P zr<>2Pr=NeI^WwGFUc*HfU4%u87Rh~T?Ma_UYk3D8Z~%VvqaWeSGtV68CHCt6L6G{% z48l0N?6RM918Go_7JCT<#lsIjER&lnnBGU*ar&wJQd8S{{BE$TJdf4t*HK3uB_O4w zD+Q#FKKiIEG=6aQ<}~VUHucvl%SkQv#5o_gx3UDW$xD)d_o z(&wIgPC&YN@nRXL;Qi=#I(_RW;Y(lo5b-9usq7cNex|_uCV=`1iBVJ{!OI#V;^^ z{CLq&xbt*)-duYUC_8E~%rTqyYa+O=y%Wu-byJ48EP2r_QR z9d{gl{_~%UWTgsAY5M!$|Grmsm*=M>B}l1G(>4rleckgw-W>0L#flYqNvgwJ`W%D3 zR&cy~0$o{IIamnbo8SC~grjn-#Uvmt?x)yOAT4Gx^=I5@k5cQ|Nu~aWznWb4m*ZD=moHylRFd{*fCsX|>wO8B!w)}PR{EJUXNnYE zx^yW{KKW#kjM@g#`xDgs@Vf&KJP}L#N{Q>PyRKJtSBG5)(gz=WunR~B z3z)vfhKmlhghw8EBp-v`(;)SmD21^KVf5(HxbAn?;rQc^N30|U+jhLhRK@R_o$6R8 zm>k|>wCUi&tv&EsYtgZ9|JesJuFpREY#yXRb4zOgen}csclXpH)7Lxg>H9t<>4HnU z+oV#R?kxbRR+0O9*ouk@eC%T%!?(WmEwK+d30{8rWn6H<1=zlQdtN=$=g~GCB`59J zKmYm9qO$4$_b-3>O93e-kB(3J??J20^zPCQe>1$h8l=45-jbw#M;@P7V$GI?V~;%! zS6p!=rXMgJ@lt}cd;KL{Oq`%(#Zhj$z8VECK}Ly2(9r(pril{T^Q!-*ug#ym%>g}` zRfU*B#R=M^T9Uq#K&oug4j5M~xYYe-Fi!d=gH(q_I7xc43H_j%Jb5yH_`@HH13(iC z2+nVQ^P3`hnwy)u;G8d>=cNn&BOm#QfSc+tHv*Ru*$>j-%F6rWYEMZ@&}e(Muf=4r z-}Cx!7D%E`v;k^AuK9qaKOC`ive_uMY8CdjB7?0XyR zaXm>=f>bIqyxAZv21E@~PLg8Y)!@S)ee}`d)uqZyY1q=zB5~4R|N7Us_S$Q)X3d%| zhfuBM%jf>z|Ni$ynrbP+Sg1#s4y%b!_FGIw671e*-RSQbOz~E3b}L|Elo{mZEitB z!wz{jl&F-Rd=JrZ1T__vD36z+rn*{wlF=0jhY=!6h}9FLk*uz6<`_~9ru|JVg0Wt{2THGEAmw62pnU36 zpAx$~zezX6LjObl{+{#C#qePx5cUcOOA&B(aRbl_Tm6@_;byXEZrFvE#$8yqdJUE> zeGSW(zJ~3aH=}7+6Pg+uWfsND;?nO%7NMMj3AH1of%5pV^_Vz*0uDQLF2>i7!|>t5 zQB^-y^>$?=9qxZb$J>4WJ$DCtNLJP-9 zbGeJD-@FFLpK3h!*Xq2M$OE%+b>rv)P+2}j@=3408tp8fvO6HSnBxzw%2PNr1 zLCX1~sjeJ9jxQN#BuQ`q^uH614FSqy_~H8@IFCK{SaGz`UosG<7mWy6ihROUgY-(4 zPYHrlCV#$SdU5ZrKcu2xbYC1%4gl3ms-oP2Akp4aP9%C=Nf;nli%C*_eLn++_pL#~ zb5p|TK_}oi!8y?>O?1`{??bDXL6G)zf3s)L7IJ}>X8QSgPQCiBTenWiG2U{^E!ets zYd&7<2ZffNd|pZq7AL0)MiB8lnkUR>;yr6MR%;yk-t{@Ts8QV`sf7CnH5DGu3B`qv z;U|(hy53I#q^c>EcyMGcWKE#W%_41C*y$$F)Y6R2tJY!diZ}4$)6Zhvs?~VyrI%p2 z2JBQC$mXPt1)D$-=u}_XK9V4%aZ8z49W6t|HQ;2j$RdRrs}iGzkHF}?F-T&baf56}V z_BXup$}93Nf*_@aq@^k6!U-pwAS4;G+Bo-m;#PNC+2s$tgS4%+6~;y1`L=t>Pn5cw zmrzW{>OtKt22$-}_n*VRnsDMUobc11{*oF0f~uafVPQ4?FCzJUI81B)#HF zk6{1ZZ-2|B6Q*l`E6}hh5XA23ruC==S27L)XxrYmUyQ~V)FgNz5-hj~GG48(7aU&=(yOn& zT0&JtLCW4v>>x)Y)BsW;s<$@QHSNHf9b2$r$2M$PzX6Zlb{AH?vJCdFCgtb}g<*Q_ zA(gb#tus7|UOslBq@l!AJ&DalfyYw9()Jt?j$>v;9j1&JgGm!7Vf2itnE$a05Sug_ zHhUr)E-c#cI^F{y2-2XrqRl4FIHK0VvDWrG=LT(l3J1;wdW-!V_v1U`eA4VSF4T-J zFwK+a^=|{VNdxL`Hl4-|*I$n-u4MU?78n1VeJrYQ96kX2Rl;jcy;YcY--qsSC+nt zXBIBP`j?l(ZfI12QA$UGj1rFj)FAbmRf)*+K$`FB=1Ewp)#_NaI1s4iurMt)43jE` zVN7K$YU)N{_9@3=&gsXaeEN7~!X~VcG?>h9+9q8j++F3=@^3+qzWd$p&YKb3kMn>8 z7skt}jRXP8f9r)^LQT0GKKjv*$|8Hj5l3|M1MD4;UUpfR8|&)-_ILAAyX}r7-5Ve! z0H|jE&;R_7IBoo%TP-d5H#&Ss=_4qa4a2`tqB3-&9Y@6^y$-=>Nvf+)(C(!TO8b)w z1SJ^(98__&^N7bW#!E>?4l(1cykDJE9(V~w%arscNe2Z|X{qQpZ&ueJ+f4B8FgS7?y0Aq5-mwP>GU}WOg<}ZP1>MLI{4%#KPf4aI%8<>OVYPFNC`Ho zC{!KkjnglM(vAa8b%ucAATu|T5|1mOmN0$ANwuWcAk{8+UW@1Y-S2*v_at)>(kr(H zly*$eCj7)FJ|P5uIg&a=f5G_|2#Dy=5rB#$6&VcMFp#ue>`HWE zebWwX*|h`Pwr|Bl_uhx+9{&$gTerio!iX3q9Cj+tvL~y=aq?aahFd&%s=4cdRI`+H z&qfijt^%lGyRZxcmII8atdd5{Q;bR+J81@{Rn=kYoS7JT>S3rmVit@M)j-&UEnU)G zyx=*Go_uPtG*#w(`8O_-1aAt13%GN6zNPxV!p2}UxuyQw_(esO|U{?#Ho2ClcJ`w2{P?XdVwntMs3Ex zG@}w{jh~5eqsE|o)?^&<(F=e>CaaF;v@0D4FTA(}-?`|!pd_^!>S2RsUrRw9d#1Wi zKvI$tptR+gq@gtsJ*IkpdU474;lH^sGsaF<8^d}2t=MAPZ4&nQ2Y+iyrNgFEY20wb z^|2D9z3Q$ASHk}Nw2x;YMg(;1xku~)IK3Az?4tQ z02%?TY2AetZ>+$^)obwJZMS3jQ_lbm%_w7_-zao!<)q4HG6LM%npzxw_+dEx^wTlp z;2HAVls-}h#x&5<+KO%4w+m~Fq!T7ZkX=(6SHRCdm*b$sHBse;QRf)AVB{Q3sv3b2 z(l0tN%hHE*D!sTq&ob3Y!v_1{RXT#IndMJbEUg#lYRfMp{v;_)(^=GkgT z9&tq8o36uNlBn-xDAAL8?|t{;KaW3wd+xmlq!s4u930QK4donBp(BQc;cgg*g+^k| z$O)J-VG`=+9gLYDdk-*W3=m<3KpW4#^di2)$_$jGwu;9FB`LKU+K^1aql9FK`p3r2*rbtog$b5mi`SF+l^=e;rC+0+gQQ_rL%B z0#NNh3No_#0_&az>AB~fE9$P6qy!wu(S-rZ{->I@V#ymT5Y9Nb{SSY}E4SYbw09zI zga9W8Ct||!QeSv)B_*YJ?|U!6r$7A}NkWK(LkL-_^eQ*b4{di#rj2Pzb_dn-Yp%H( z_uYS=l8QMSmhB*%vt%0e&Ip{DX>4SBxxY0L2)?9Go`(rqdrB)bbp%muE1$l3SG@VT0 z#v9pY;wrSYwZi!3SHI$3cKHIYh?fN;p8?~`Ast|=k05CIvcC7d@8#p9J&^_aYm*k6 z)TD9IaTLse3GPdfQq9pI<-O4^`N~(ml229B$M8FCU-EDMJV>t0e&>RJRpm?M%jY?1 zhidg#OBJ;s_R*TmcjJDL4#vAH&mod@9GF?bV7?!u4r>>~l(5S#xcK*LFJi;a287zv z`1Qq?A-QY?kaJK+oE>326U zY1!K{+|?%Ko~cAa<|xBuk_GdPuYB3PY{3Gt8JGp}b_OXOBD%C=v6sYw)smDFQO7#_ z0x6HvAHHb5L>)@fo?QOape41DETYeR<}e(?Pt;KLvO5Xws9g3Vkm z+bc*35G_#&)Qd0qF@F2o-@wkfs3?iSOsYcb$q*2+fsw9-S=MlzHDNYJ)(peMQ;xzx z?>ie9TMH-R;!K17&K9I6u_?u_~$}z@ax}q-9eh{ z>=bG#K`QyAU;WaBF3Z`QUaHc*08&=uBiTR~9P7`-rX(c;gey-^>Nf|MDi7_+{({s$ z(7X@50`nUBzVxc9|4ol3y}oo5>0)O(*4Dol*LAPGElCMds=A%o47R6|SiE@yHt%S_ zvv)s)2mkgDpsf|Kvk;bpX&~gdC@(2Rdq=wzf&1kzekp2hh;dWNEzJeZto#G{r5eYJ zC0Xu&;C_7UqaQ^}YYUv5i*g~7j-x+v0WiHDsEpy6 zS6{;aBS;sj5R4s&qYiY;=_n$fn(bF;rf3G!;Idr$x_ZwbW%QsMNNGnDsxo*w?f_L? zQFj9QaRXI%2Mf~k&O1+R#UL$A-w!7RLCUx$Gh_Oaq(SM$=is^YYOKK%1Sx?@N5fBk z@)NOZ)MQkjp0ZSWdzEhnNGT&bQYmcgXvd>#R-m;#fhYcY8(w;BArcMS>BG%~G-{X# z8>TqM=v4XMMc+f+s5&(+F4;Muet}d%Zy`&(!}I3N1?%T#QfW|;W{xGj&S3|LF~*5X zoH1$!#?_2O_0;h=^^+ffHD@YN6UTEezaWkyvY~|TrxViq!bcC^6PWZ&vp4|f37t#+ zcf99RT|rAAogUDVG!N3RU3j5OBClkeu+IpMeP+%Kvd3q!=jKECuI3+UsUj=@%p@f)-$HsOI6A5 z+V2af!SfXZssEn(3c&i}+rMV3YZ~O;deDE>k677JK z5s(^|i3mFgwdV4SW-bJ|i?|%oK zCMtVW0X{^!plf5YQH9g%XJCBgaEzHc38#JH11erRyc{n)|1AFBMHk_zMT^8~r=$#mt9d^Od9*0+W6VYMFeOyw~7++cRJ-Zj(~o?E+Hft6d7p{qT%5QX^KY7Yq@52vjq6(j zQWL3+jm@b9?jlHATCwPcf8eDD9z!PC4%iux4n)ZZTag(E(rlYKNXdg` zxPvcOC)gHq1o>A+N>Z|UbcZzm{(g|sUL=uvZ-P{(K2g=BT}n0(B{)}ShHZ3xr8f(t zvM2=Nq<-&i4kR{&@*ur;<*R6JX~h#a{sT)MdJImo6K*y|ktWlGQZ&LGOvjP9}r;Zm% zYRpyY?vm%96PuKA(i|mep5|CEy@J|Mf6WV0LCI3$e9`YO*fntXz}gQ<`lZkRuY2va zzvv=Gm8LuhW3-1SAE+c9EJ#WB(#g2RK*|+TJ9X$@@2@1)Dz4u~EvD{jiNS@1&Ie9N zzF1CVei)X~s&9WM3HRGwbvFo7I@p93=-F?Wpa5AAN%;naQT7-0#brA7EwjXdjo0ETw#&|t3{9~AF?cj7-=9# zZ6HdCiX5h*8fTB0iTaumsG2qor+(%`Fy~ALs!D`4q(Lg`Zr4HwGSvM6sn(GAlXHXb zk`D<*h-FXiHar0+Ld-QAZ!s$YP%r8pLpl&qpa ziTK7FZ{#!g^*+IuMsPCohSV}HB2;~Q^H}d`b+;Qx&pTfc>@`rOW{`n&&c&`=77x7s zDt5NE;A->%_zTv_Q5qO@d11SXsNvtNRaE*?X*msJr+wAV4h{?f|!xFjV= zeUem3R0BE3K#S|(p=GaPb7Lb`zPuE7{P8d7T)P2bHiH?lORaIrniu*_m{u?Wtq&B!n!<4u@}3iC21G$?p0UeymQYh3Q`Hf0C;Bo z1}xjKUNTi~|I=Tv^|_Z2PN!hHIT)r3*Kox-#KvCyFyPP0JOAjT1ptw7q#H={`J^7( zD(B>|X~RZooyltXuPt4gFIN%{TVjtAr0m2x3T2pCG92fPKLlgzMq|pkC!qYaBZ0b7 zWGkY0F#u90Qvj(}bvcLlA=pkj=_GMfQIaw-0m-IdkdsGHper z8h~_W(PpF6p%aNVAys7^I}HN$tpsTTz>208EM312TN@kj@4x&N%kO>=Rw{+ClY>d3 zfayY5JyOWe0?U2;_Xj?RFMRO}m^E`I%Hm~3L8_fq*<2Q#oe3;nya+d3cRlXE=UxFf zom&jYghQ6ZM*wxYjIHNaGWvu5R4cz8V7&u9E6TI2yS&0si=u1FD=3U`>t{v zNt&9IF9wmfM|DLE#?nbqWkn2K5|xF=2vn-Qy5Vq8no?8ZcU+uly72vJjc8A+yMFGj zkQqMp(T}*aDfXngTP%**Tbxw0cjz@^Di>40G~=ikjjN|P>D~q@JDwq`w$Y)4t71UZwmb|zel14ATdBoY=6C^LSJIP7pqu&3ss z9W7dt@_OqxZNwdS-hq4Xxfic2c?s<;tt#=Gp!b6NA=^O=E=D4RIjFUcYo?&+xwmNaFXOiC@%L$zN)ND<7a z@s8J0mG!8!Baq|DXAI8AfvLUSC8gc)_*7)wgIh}27&e5Z1ith#KOR9?PVZhPpbQgYi3l3Y?Lg~dLJwP{kF zs+Jss>>=%CeWBSviYwC5(V-fWK2s}PFpydyjG4~(vNTUn-)ryX22A(U*+JUa*d&94 zvlOIgq+HknSyaoDVwQw?lq^r0Ed`UUz}}Y9%-w97lj*qpqe_p4_@sHg4FcHMkZ$GEK_arpO)|?xTsM{Og1N$eA;v za-eOG{Bg%l={@*g89Q}K3X2O>?<${ez=9Bu=j)h>f`URV^TRbj2*F}uIenRWecIIl*aQe_dYRn9qHf>5;DVhB z>j0rJ9WpY;Wf(}a`8G3c?%o}cLsJH7xl+tsj5{d2=s_7cdrl7abxZ%ifE@bdfV92+ zPkH;b*X7j5`z2O9PYP4yw}91Cuo84BD=U@0o?cB`uoswvCbX2Mh3lU^qpfeeN{dUB zuQ!jhi#E)8f(V!|F{zhQx$7IZO6{V{rT*Hh3C$qy!>fPyOL{_q;2= zqL`r-`V_8foK60!o4E@}nWS*xL^cVNvryz}4!?zNnYUSj#HTe1Zq`88WMI>-TKn95z)}-dwW&&wyhC`RSHcsj?SQAGMk^uGY#vWBK7Nn2hn4u41qDpOZt7Pe6u`WB9b^Qb+JlW zb6LHts#z|}RxXztZogHQfA>boUtZ0ZMB*fO{qYs;ZS83w)ikZMK~|0lr!(4*Cj3m6 z3;W1GZ1#^cNT7)5DlhKc+!qr%Of;ZAn_!Z~75p0JY>jf6Ae9}YO{Pg7yl<2D!j2tZ zdXPeC0>=?y^h{0VEb@f}sR0L|GL#q-nrLCBCIQ~#KJk$_Fqpko&0@_4+05TewWv`b z4X0oXr1=E}K2yB|(gX|%fmTJ?4UCLPXJ3yT>^iIincCibOFn7+w~TamYosTSj+fv? zA%do5bTKCId!&$Kb7lZ3-829-kvOCJuR@BXHeN1YySzqLRxXj+`a1d6h95}HO*crv z%4(7Fc|JqF(>v1M?$0MhldAR$jiLZRtQ#Q3(t#YnUaXA;g?Nv%vuoEb4J2Vk8$GLi z&cF&#u@>;VadTjNKsgXFvy|P`wA@6HQqlFhXP;FfvO&g7TuLBi@d*Ot3R0IGI}^R8 z`6qPfn#dV{)YHb2;?ke(Ct@8}i{hZF009psLywzi~XE=p?=x z2C4IJoi`KspbU44GmHt^l>E3X&M%gmms}y&FR7PRwaewo)z{04jkk-`E)=i4NPA4R z=sr+Z{Fo|8X~qYn2y@ep?oShd)K}B}^3qE$>Ci2=-q>=cW(xCfa^Fy_kYckG4%ap9 zI=N<@2vTaJTbf(^rf&jAvl*n;jgZOwbfpxFfhNrrq}rYri)mEPCC3g+z+6CT8kPAh z_?*myF*C`2AD?jvv`HOtcnCtchsKrm1%*2$Awx5(N%*Q#0Sg491M zK1lIT)f^4{(|!U;XGi4N@#Au=t49vK*CD&#dQ$2kT`Z7tv)Jx{!Dh3#K)@HXQY)%JFgM7Pns$l;DT@L~ZT2V;Q}=~g z!h84&T$cqUr^j_!WGaRr48wN6AZD)E%)e#>Rn*L&Oo^v z&CCQBcy@rweeiqu{l>vdlQ?`jXwyt(g)T@Fzor?QOfIwe@Z3{J2xj z4h>0h*?iTA!i-SL^Yl+bwQ7D|zIM(O=EWrsQth(|DTxO zH+}mSS#|YQvf`R+L>4XZ!@j|YQl;|_OjJvUk{^BK(MM$W?lvDJ=gy`1q?|w2oc%>Z zx<09Uw#@7`%ZHH@FfH0!!CfA1L zfR-)N7Vazj{9%wH)To5&?Ci`qYLWXv*sNZ?THDIjtzG8_cw%`9LVZrnPx=gkDM6!% zB{%~kg%93@mz3e;sPy#rN_SV696o$VKIqsh9q+#{`}gga{@z}V(gGBsl*WO}HPM!U zw7`q$kfySt5?M6ALawU2LI(-o)NrFLs$L>>U%yt0%1b4$tjxa^BNj6f%Yekq?v)W3 zk3RO8f{A?z3u*S4Gsu~usD^?Ivsm0cb_Jo82vVX-v=?SW&WF+G*q(50)|WHP=m|7B z!rZEn!WK~4z8Xlwj7(#m{N|~rmC0#z3$r zfGJZkLnevDA!m*U<#|L?!+s?jXPO#mN`w!GpKGysB(N#+w&~ei&qfGXp#k@Y)}si) zdR=Y7!yWr>%`wxuxi4ya*<_oKYMaP+d7n+^x&)E}$0Em+!aexF z11ijXs+^dnPr{Z;3Zy|ti&`{Lkm+a&PtGLI`Vn1kOom5BXvhSmPa^&#m zvTyHRWmp&*8kW(~)2dbZeMNyLt*@?8j-=Y9)l$23nOt+_N~x)?*1%4zs8D1P$9 zmB4vaa0W!b`gdQr1O-nztP7e}N;Cmzc(#u1J(XezLJJ&a({$_+LXG{V8i^nvu?VAN zb!XhN)|@F=D#?H2Hj!4dK;^VR`hVWvtxr6m?QvSnkfup#79`I!!ypATB>UkvWnsdH z$cpG$Omc=uB8u0|lr*qrbHMpNnhMQj01IncGfCM%s$kHz)L*igEHGNgMjF}>CCl>x zUNkYLDCSsLN`{{YLBs}gZ8SU2j%4OKR_LvT)9}g$eWyG-!i0N6Q|AIw?hRIbp3%w@ z-R~P28f!zYa9&A?mI>NHH;`sZx&ca}w$^{@4_xvYJd$2gg^s3`;sr7^I4DQ^`ej~m zv5X9l=#*-h7D&e!NDK1fQXG#yyi!?EStX@aO!QWjuD~1{ONd7SJCS3T^VxtI z(xm1?+5qNo1sD4aczK^Fx^Wg|v(VTJn;&F_5DepD@3@vS@&`V#X;${TySrN>_9&Y3 z0%dvl8q(x2UPkGJE69WoEof`x6$zYo;z8{3ZCBY0#42r4$bT6VWsvQp$e*B9074rwtV%n$Ub<%TN-d9IJcSEV z14+2hBK3Yir;-AxF;VJIPZChF1nD2Ht5rxg>_kZ(CRXscl}irnBlk`}8^MH`38ZP3 zMKH!9{L5w>q%F-dOmz1rcW?A|?%XM*6nS&=v&h_?(u#ipANneTl;utV#2p6gxG@SU z7gs@BN*YLmU=Zdq1^$4PukbcBES9I$-{*AOOwdN@x_L^cVfKO4T~$9w=9|0E$S|q8 zA8*{?5qT}Gs7PznJ)hd$DXr8c{GqVq45ta0^Im-MMJcPCGk0@d%&+Jdq7LyK zNYC$JBohhQ($uJ$bae2f#5Ue_r}u}KU!DW$`K{|$>f3W5%@EC+!4m*Tn;JLEbK9Hc zG(PEuJAdfC{K_kHAf3TQzSJ)j2~s~jF#eh|cc*kDY{}>#LX!g0GlM7Pf2nysEeiU~ QjQ{`u07*qoM6N<$g88?WF8}}l literal 0 HcmV?d00001 diff --git a/test/Charly/02-mapping/05-together/public/index.php b/test/Charly/02-mapping/05-together/public/index.php new file mode 100644 index 0000000..9c1b38d --- /dev/null +++ b/test/Charly/02-mapping/05-together/public/index.php @@ -0,0 +1,37 @@ +selectAll(); + +// vue +require PROJECT_DIRECTORY."/view/permission/permission.homepage.view.php"; + +//var_dump($allPermission,$permissionManager); \ No newline at end of file diff --git a/test/Charly/02-mapping/05-together/view/README.md b/test/Charly/02-mapping/05-together/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/02-mapping/05-together/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/02-mapping/05-together/view/permission/permission.homepage.view.php b/test/Charly/02-mapping/05-together/view/permission/permission.homepage.view.php new file mode 100644 index 0000000..68d3233 --- /dev/null +++ b/test/Charly/02-mapping/05-together/view/permission/permission.homepage.view.php @@ -0,0 +1,25 @@ + + + + + + CRUD Permission Homepage + + +

CRUD Permission Homepage

+ +

Pas encore de permission

+ +

Id :getPermissionId()?> Intitulé : getPermissionName()?>

+

getPermissionDescription()?>

+ + + \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/.gitignore b/test/Charly/02-mapping/06-manager/.gitignore new file mode 100644 index 0000000..d11ccf2 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/.gitignore @@ -0,0 +1,11 @@ +# Ignore config file +config.php +# vendor contient les librairies externes en PHP +/vendor +# fichers non envoyés +# PHPStorm +.idea +# VSCODE +.vscode +# Charly +.history diff --git a/test/Charly/02-mapping/06-manager/config.php.ini b/test/Charly/02-mapping/06-manager/config.php.ini new file mode 100644 index 0000000..ae92c13 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/02-mapping/06-manager/controller/README.md b/test/Charly/02-mapping/06-manager/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/02-mapping/06-manager/controller/commentController.php b/test/Charly/02-mapping/06-manager/controller/commentController.php new file mode 100644 index 0000000..a238191 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/controller/commentController.php @@ -0,0 +1,95 @@ +selectOneById($idComment); + // view + require "../view/comment/selectOneComment.view.php"; + +// insert comment page +}elseif(isset($_GET['insert'])){ + +// real insert comment + if(isset($_POST['comment_text'])) { + try{ + // create comment + $comment = new CommentMapping($_POST); + // set date + $comment->setCommentDatePublish(new DateTime()); + // insert comment + $insertComment = $commentManager->insert($comment); + + if($insertComment===true) { + header("Location: ./?route=comment"); + exit(); + }else{ + $error = $insertComment; + } + }catch(Exception $e){ + $error = $e->getMessage(); + } + //var_dump($comment); + + } + // view + require "../view/comment/insertComment.view.php"; + +// delete comment +}elseif (isset($_GET['update'])&&ctype_digit($_GET['update'])) { + $idComment = (int)$_GET['update']; + + // update comment + if (isset($_POST['comment_text'])) { + try { + // create comment + $comment = new CommentMapping($_POST); + $comment->setCommentId($idComment); + // update comment + $updateComment = $commentManager->update($comment); + if($updateComment===true) { + header("Location: ./?route=comment"); + exit(); + }else{ + $error = $updateComment; + } + }catch (Exception $e) { + $error = $e->getMessage(); + } + + } + // select one comment + $selectOneComment = $commentManager->selectOneById($idComment); + // view + require "../view/comment/updateComment.view.php"; + +// delete comment +}elseif(isset($_GET['delete'])&&ctype_digit($_GET['delete'])){ + $idComment = (int) $_GET['delete']; + // delete comment + $deleteComment = $commentManager->delete($idComment); + if($deleteComment===true) { + header("Location: ./?route=comment"); + exit(); + }else{ + $error = $deleteComment; + } + +// homepage +}else{ + // select all comments + $selectAllComments = $commentManager->selectAll(); + // view + require "../view/comment/selectAllComment.view.php"; +} \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/controller/routerController.php b/test/Charly/02-mapping/06-manager/controller/routerController.php new file mode 100644 index 0000000..49e1a9e --- /dev/null +++ b/test/Charly/02-mapping/06-manager/controller/routerController.php @@ -0,0 +1,46 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst', $tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + } else { + // sinon, on affiche un message d'erreur (à commenter en prod) + echo "$methodeName n'est pas un setter valide
"; + } + } + } +} + + diff --git a/test/Charly/02-mapping/06-manager/model/Abstract/README.md b/test/Charly/02-mapping/06-manager/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/02-mapping/06-manager/model/Interface/InterfaceManager.php b/test/Charly/02-mapping/06-manager/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..421a87f --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Interface/InterfaceManager.php @@ -0,0 +1,16 @@ +connect = $db; + } + + // sélection de tous les articles + public function selectAll(): ?array + { + // requête SQL + $sql = "SELECT * FROM `comment` -- WHERE `comment_id`=999 + ORDER BY `comment_date_create` DESC"; + // query car pas d'entrées d'utilisateur + $select = $this->connect->query($sql); + + // si on ne récupère rien, on quitte avec un message d'erreur + if($select->rowCount()===0) return null; + + // on transforme nos résultats en tableau associatif + $array = $select->fetchAll(PDO::FETCH_ASSOC); + + // on ferme le curseur + $select->closeCursor(); + + // on va stocker les commentaires dans un tableau + $arrayComment = []; + + /* pour chaque valeur, on va créer une instance de classe + CommentMapping, liée à la table qu'on va manager + */ + foreach($array as $value){ + // on remplit un nouveau tableau contenant les commentaires + $arrayComment[] = new CommentMapping($value); + } + + // on retourne le tableau + return $arrayComment; + } + + // récupération d'un commentaire via son id + public function selectOneById(int $id): null|string|CommentMapping + { + + // requête préparée + $sql = "SELECT * FROM `comment` WHERE `comment_id`= ?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + $prepare->execute(); + + // pas de résultat = null + if($prepare->rowCount()===0) return null; + + // récupération des valeurs en tableau associatif + $result = $prepare->fetch(PDO::FETCH_ASSOC); + + // création de l'instance CommentMapping + $result = new CommentMapping($result); + + $prepare->closeCursor(); + + return $result; + + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + // mise à jour d'un commentaire + public function update(AbstractMapping $mapping): bool|string + { + + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + // requête préparée + $sql = "UPDATE `comment` SET `comment_text`=?, `comment_date_update`=? WHERE `comment_id`=?"; + // mise à jour de la date de modification + $mapping->setCommentDateUpdate(date("Y-m-d H:i:s")); + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + $prepare->bindValue(2,$mapping->getCommentDateUpdate()); + $prepare->bindValue(3,$mapping->getCommentId(), PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + + // insertion d'un commentaire - À modifier ! + public function insert(AbstractMapping $mapping): bool|string + { + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + + // requête préparée + $sql = "INSERT INTO `comment`(`comment_text`, `user_user_id`, `article_article_id` ) VALUES (?,1,1)"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + } + + // suppression d'un commentaire + public function delete(int $id): bool|string + { + // requête préparée + $sql = "DELETE FROM `comment` WHERE `comment_id`=?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/model/Mapping/ArticleMapping.php b/test/Charly/02-mapping/06-manager/model/Mapping/ArticleMapping.php new file mode 100644 index 0000000..7a2fc92 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Mapping/ArticleMapping.php @@ -0,0 +1,124 @@ +article_date_create; + } + + public function setArticleDateCreate(null|string|DateTime $article_date_create): void + { + $this->formatDateTime($article_date_create, "article_date_create"); + } + + public function getArticleDateUpdate(): null|string|DateTime + { + return $this->article_date_update; + } + + public function setArticleDateUpdate(null|string|DateTime $article_date_update): void + { + $this->formatDateTime($article_date_update, "article_date_update"); + } + + public function getArticleDatePublish(): null|string|DateTime + { + return $this->article_date_publish; + } + + public function setArticleDatePublish(null|string|DateTime $article_date_publish): void + { + $this->formatDateTime($article_date_publish, "article_date_publish"); + } + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + $this->user_user_id = $user_user_id; + } + + public function getArticleIsPublished(): ?bool + { + return $this->article_is_published; + } + + public function setArticleIsPublished(?bool $article_is_published): void + { + $this->article_is_published = $article_is_published; + } + + public function getArticleTitle(): ?string + { + return $this->article_title; + } + + public function setArticleTitle(?string $article_title): void + { + $article_title = trim(strip_tags($article_title)); + $this->article_title = $article_title; + } + + public function getArticleSlug(): ?string + { + return $this->article_slug; + } + + public function setArticleSlug(?string $article_slug): void + { + $this->article_slug = $this->slugify($article_slug === null ? $this->getArticleTitle() : $article_slug); + } + + public function getArticleId(): ?int + { + return $this->article_id; + } + + public function setArticleId(?int $article_id): void + { + if($article_id<=0 && $article_id !== null) throw new Exception("ID non valide"); + $this->article_id = $article_id; + } + + public function getArticleText(): ?string + { + return $this->article_text; + } + + public function setArticleText(?string $article_text): void + { + $this->article_text = $article_text; + } + + public function __toString(): string + { + return "article_title"; + } + + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/model/Mapping/CategoryMapping.php b/test/Charly/02-mapping/06-manager/model/Mapping/CategoryMapping.php new file mode 100644 index 0000000..cbb3d1b --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Mapping/CategoryMapping.php @@ -0,0 +1,89 @@ +category_id; + } + + public function setCategoryId(?int $category_id): void + { + if($category_id<=0) throw new Exception("ID non valide"); + $this->category_id = $category_id; + } + + public function getCategoryName(): ?string + { + + return $this->category_name; + + } + + public function setCategoryName(?string $category_name): void + { + + $text = trim(strip_tags($category_name)); + $this->category_name = $text; + } + + public function getCategorySlug(): ?string + { + return $this->category_slug; + } + + public function setCategorySlug(?string $category_slug): void + { + $this->category_slug = $this->slugify($category_slug); + } + + public function getCategoryDescription(): ?string + { + return $this->category_description; + } + + public function setCategoryDescription(?string $category_description): void + { + $this->category_description = $category_description; + } + + public function getCategoryParent(): ?int + { + return $this->category_parent; + } + + public function setCategoryParent(?float $category_parent): void + { + $this->category_parent = $category_parent; + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/model/Mapping/CommentMapping.php b/test/Charly/02-mapping/06-manager/model/Mapping/CommentMapping.php new file mode 100644 index 0000000..c3de343 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Mapping/CommentMapping.php @@ -0,0 +1,152 @@ +comment_id; + } + + public function setCommentId(?int $comment_id): void + { + if($comment_id<=0) throw new Exception("ID non valide"); + $this->comment_id = $comment_id; + } + + public function getCommentText(): ?string + { + + return $this->comment_text; + + } + + public function setCommentText(?string $comment_text): void + { + // cryptage + $text = trim(strip_tags($comment_text)); + $this->comment_text = $text; + } + + public function getCommentParent(): ?int + { + return $this->comment_parent; + } + + public function setCommentParent(?int $comment_parent): void + { + $this->comment_parent = $comment_parent; + } + + + + public function getCommentDateCreate(): null|string|DateTime + { + return $this->comment_date_create; + } + + public function setCommentDateCreate(null|string|DateTime $comment_date_create): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_create, "comment_date_create"); + + } + + + public function getCommentDateUpdate(): null|string|DateTime + { + return $this->comment_date_update; + } + + public function setCommentDateUpdate(null|string|DateTime $comment_date_update): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_update, "comment_date_update"); + + } + + + public function getCommentDatePublish(): null|string|DateTime + { + return $this->comment_date_publish; + } + + public function setCommentDatePublish(null|string|DateTime $comment_date_publish): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_publish, "comment_date_publish"); + + } + + + public function getCommentIsPublished(): ?bool + { + return $this->comment_is_published; + } + + public function setCommentIsPublished(?bool $comment_is_published): void + { + $this->comment_is_published = $comment_is_published; + } + + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + if($user_user_id<=0) throw new Exception("ID non valide"); + $this->user_user_id = $user_user_id; + } + + + + public function getArticleArticleId(): ?int + { + return $this->article_article_id; + } + + public function setArticleArticleId(?int $article_article_id): void + { + if($article_article_id<=0) throw new Exception("ID non valide"); + $this->article_article_id = $article_article_id; + } + + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/model/Mapping/FileMapping.php b/test/Charly/02-mapping/06-manager/model/Mapping/FileMapping.php new file mode 100644 index 0000000..e26665b --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Mapping/FileMapping.php @@ -0,0 +1,64 @@ +file_id; + } + + public function setFileId(?int $file_id): void + { + if ($file_id <= 0) { + throw new Exception("ID non valide"); + } + $this->file_id = $file_id; + } + + public function getFileUrl(): ?string + { + return html_entity_decode($this->file_url); + } + + public function setFileUrl(?string $file_url): void + { + $text = trim(strip_tags($file_url)); + $this->file_url = $text; + } + + public function getFileDescription(): ?string + { + return $this->file_description; + } + + public function setFileDescription(?string $file_description): void + { + $this->file_description = $file_description; + } + + public function getFileType(): ?string + { + return $this->file_type; + } + + public function setFileType(?string $file_type): void + { + $this->file_type = $file_type; + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/02-mapping/06-manager/model/Mapping/PermissionMapping.php b/test/Charly/02-mapping/06-manager/model/Mapping/PermissionMapping.php new file mode 100644 index 0000000..a17e27a --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Mapping/PermissionMapping.php @@ -0,0 +1,49 @@ +permission_id; + } + + public function setPermissionId(?int $permission_id): void + { + $this->permission_id = $permission_id; + } + + public function getPermissionName(): ?string + { + return $this->permission_name; + } + + public function setPermissionName(?string $permission_name): void + { + $this->permission_name = trim(strip_tags($permission_name)); + } + + public function getPermissionDescription(): ?string + { + return $this->permission_description; + } + + public function setPermissionDescription(?string $permission_description): void + { + $this->permission_description = trim(strip_tags($permission_description)); + } + +} + \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/model/Mapping/TagMapping.php b/test/Charly/02-mapping/06-manager/model/Mapping/TagMapping.php new file mode 100644 index 0000000..798f6b9 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Mapping/TagMapping.php @@ -0,0 +1,44 @@ +tag_id; + } + + public function setTagId(?int $tag_id): void + { + if ($tag_id <= 0) { + throw new Exception("ID non valide"); + } + $this->tag_id = $tag_id; + } + + public function getTagSlug(): ?string + { + + return $this->tag_slug; + } + + public function setTagSlug(?string $tag_slug): void + { + + $this->tag_slug = $this->slugify($tag_slug); + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/02-mapping/06-manager/model/Mapping/UserMapping.php b/test/Charly/02-mapping/06-manager/model/Mapping/UserMapping.php new file mode 100644 index 0000000..400ecea --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Mapping/UserMapping.php @@ -0,0 +1,87 @@ +user_id; + } + public function getUserLogin():string{ + return $this->user_login; + } + public function getUserPassword():string{ + return $this->user_password; + } + public function getUserFullName():?string{ + return $this->user_full_name; + } + public function getUserMail():string{ + return $this->user_mail; + } + public function getUserStatus():?int{ + return $this->user_status; + } + public function getUserSecretKey():string{ + return $this->user_secret_key; + } + public function getPermissionPermissionId():?int{ + return $this->permission_permission_id; + } + //setters + public function setUserId(?int $user_id){ + if ($user_id < 0)throw new Exception("ID non valide"); + $this->user_id = $user_id; + } + public function setUserLogin(?string $user_login){ + $this->user_login = trim(strip_tags($user_login)); + } + public function setUserPassword(?string $user_password){ + $this->user_password = trim(strip_tags($user_password)); + } + public function setUserFullName(?string $user_full_name){ + $this->user_full_name = trim(strip_tags($user_full_name)); + } + public function setUserMail(?string $user_mail){ + $this->user_mail = trim(strip_tags($user_mail)); + } + public function setUserStatus(?int $user_status){ + $this->user_status = $user_status; + } + public function setUserSecretKey(?string $user_secret_key){ + $this->user_secret_key = trim(strip_tags($user_secret_key)); + } + public function setPermissionPermissionId(?int $permission_permission_id){ + $this->permission_permission_id = $permission_permission_id; + } + + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/model/README.md b/test/Charly/02-mapping/06-manager/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/02-mapping/06-manager/model/Trait/README.md b/test/Charly/02-mapping/06-manager/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/model/Trait/TraitDateTime.php b/test/Charly/02-mapping/06-manager/model/Trait/TraitDateTime.php new file mode 100644 index 0000000..6b56182 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Trait/TraitDateTime.php @@ -0,0 +1,34 @@ +$paramName = $date->format("Y-m-d H:i:s"); + } catch (Exception $e) { + // en cas d'échec, on met la date à null + $this->$paramName = null; + } + // si c'est un objet (DateTime seul possible) + }elseif (is_object($date)){ + // on formate la date en string en DATETIME + $this->$paramName = $date->format("Y-m-d H:i:s"); + }else{ + $this->$paramName = null; + } + } + +} \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/model/Trait/TraitSlugify.php b/test/Charly/02-mapping/06-manager/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/02-mapping/06-manager/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ +PyA07*naRCr$Oy?K;mXL;uNyK8K@XDykvuc}h1w3K!%v;q3 zGkvE2oO7iArrXBGHnuU??mq1~LH8jeEc6d$;F(UZYwoN490t{4fj?FlPO(^`DFB3Pk7mWKUij zbKkMGdKP~Rj9C{iA`AmweDS9|^w2}R^2#e1m1;3^Y-biITOeKh1zrx%Om1?dkdfT+ z^99rdehnDPJL&gsJmj2OKwaGGm<4AM#|vTO@exw!h#vZM=N*yZpHeREG? zITcvr``LW53mMoZRLy;=Sj)NZX4CpZ@Gc9+H?; z5=SkNF8MuqS8v#SLnRgzT!e;>LZc>YCRmx3M=~Ico#Rshwf>s<+~g+sCs>qsm-8|8 zo9nOUJ)#wmF6v${3ZxQ~TBg;CNf&iVFWi%6-%Nv0Tu=i70V+@<#PfVCO!XxeE^$K> z3<-#mpUpWSvf{Kv@_YFng*q>#z6_Amg}j#nC=pf!PU7y)${gwI)NE1bdH@&hN-nQ= zZh>@p-H&&5HjSI9O;%`Vp!z@+`5qBAS<|`I?o$!S zu4O8KrXsMzNVWyZI@YsQ2|#Br!jsE2@9Ltw2VT4&NK2)Hib-3R^y0YN%E47u%}{{! z4GqxYnMr2KWqjAdOSyPvY(?wVRLo-HEotaQQADUrWT<{_!8E9*U24jAjlov;J9X5VDmb5jTx%?f_cpQzZo$Ow~&kQy)=MErdJe%=}zrJPDrH647hf?^vbsbnZ8 zwW+46<5kc=jzXOVmS<>>)lkVGTUkc^2#kopmRI<=wF*5E+_d#lws&>W7Jw^aNY4hG}4i0z5+{h7?FmsKp>ndj(d65w~vM$*#^$ z+GCK0mVjA5U*0{{0_ma_(}I?CdU`TyYirXnND}n7Ea{>y?uB?#Gf2g*RWTWk;HU2h zNXIFpGn8x>->~8gthlp2h5~2|(nz@40@T?cl_XTNC3V9FNPQDLTP&+b#+zY95OVwG zom|%0MZ2$)N7zyhl6R3LQk?Z|HsCFHcittlAV{aCCZhKC_7+Gl1me!>Jym5?#g77o zihvY&;hlrLGBHj*lclUcYN{lU8HG4zMC6Oj4dU9V_@x43QzxOsk|uRj10)s|cUM5F zYM`+tRUkDyQnfrQLk-g1T|IPGCH@ruILQ>v_rdggs4`9y1@){h!F%jQiw0@KiYlAh zYE@gN3qfahRrE+?SdjE#hj@8nfIxW>~z|=XZPiplNG7U=nz-V z&kG?8!7(B2f@`Y3i7PBw>A5t**=ui^UikBPS}l;C$BTO*4sFCG6YZCplud&Z0@8s) z{CaXyxw}=vR`IHU)CmI|-=jD=%FxkwXmc!#a!tjWs;(J7l!db-*`y!Jl1faflD{!X zZDAONSmiR^m4IDtJ0IPB4ej{~xgbIk%Cg`BFT}G=QfpRXZ|sLQm(Vfr#KXqGmJOnr z9aRsrF2ohR@b9@Okal!*%sJDRCB5*sZvHb+AQh{n93GRhWiSXlcjOQ+O-`xAQ4nc& zR=cbr*&yJhpFGPmk39_I!%(YW2SIE}^`SIKCEYUzq_I0J_1Kyvqy<4Tg_FScSk> z?rp=AYInEJ0hISp;jg%^@!!Oq4Ggk@%}Nh0GdlU$rPr`6O4C&faSemOFqrZ@!oD6h z-hDG$?!OZ@tt85t6l0L4FcsL7$8UO!x}YU(fpodT@idmyk5{;9P_iuz(!&Q8NK5G~ z0Zwd54bnkCN6q8)r=H>mfBQEuG6-HlWqca|Z9>fKO}*)VVrq4{wGERF&u1q&?p?c^ zySg{gGviU2oF?1RLD8`|mWfz>?=5Wq;=h7b?U1u5IP!9Xw79(Ww>09a!f!4ce?gE+ zowO~dOE4`|#UBA(||ZN@pn8CMVi0QXjmUUBCYsSl0t> z4kcF?f#$cQEs(~6$I0$)3#5x(p3CETYS*n>(kQm12}q|JAT=aQqe0qMDskYMXEaEM z1*D~S1yXTq)4tDoEcVdDXSQC=E~}GlzDmk)C=fB;m8QIB6W9FjpNH*hpxvS3=nSup zN$0w|Es!Q46=jB>{PZWPpY*lYUd3pEba{Ypv1g${npo0>Kx!&?x4oEv^lSLTgW#9z zAl2O5*&U{*OXR3zlwsidJ}ZIUbo22oS8`oPKfTi)ZY`t|8BBGinB2CC8~@`MVb=!e zO5??32Wg{A>aX&-f79i9=2K>P;e{7?=%ELB{q@&dAYCjtmdo=_57OzAENR*gX)hIH zODZ5eLFCP~q`DT`NaW16YR#Y(a0y?@5%2>W$#C!1J-n}T4Vwy(&U+Y^!(`fIY<(9u z{onr{cCCY+ERn5S>*j*81=87x08tBk?z!g_NZ)+(O^jCJXt}^|ap!R|NF}=~?(P6D zO$tbJ1lWq`Ahf@wk?uGDuWwwxlsY1*CK8l?gcK1F4j7(!fe=Zd|dM zn|n8KquE8rjE`+NOt}WbD>K~uAHD!LUk)pBI(sagHL4!l*a%u6oefga-F@bnrW8#)*h*8nX^DD1p5}_XmJ2p4$nFpkakzA?0xD94bs75ipY>y()p}uv*i>k zEB{ZvtC&<7;Rw%)RJ~JrOE=>3@zs0y$lA;3I5LH6S{zRYSl4dj%K!7A7Z$J5CzW3Fy5DG}6;EX^T z`^CytReh#fe1)p?mqySNnyiWp-k;sded{l0citxJMNGBZOs((W@_+wn(zos*vO`Kn zs0a^<>U}G_8%xa8m%u!hw3RqoJV2JiGv|V|7=u)CcTWM*Uf<*GCw|PMfA#051nKEM zTXW1h7o>7NU0AdQ0lVqtp1$3DFte6iIiT9^Fqn(z|JW^T`~3Z|aV7b}B)K-p3%6p@ zdQ85MyW0Zka)93A&!G-d`N0gB3(`_5hc8_)P1)UZ3R2Y_6HADyVSEwohE2N%Ye;jA zy_yHsT+Rlk4N+>yXHBf#8@c8WJ_CEU;5i|dtr|~TiKF-mEa>jG$P9}I$Z~k5x}l2E z7ZFKzH?gFLrBy9Y@hm{P7%MtACY93=cUSsEh31zFO*(y(HCTMC=W?!Hxsfh2g>OWZ zJ5${Bd!NGk_$`ow(3bwv*6g80TT&4sYt}f@FKl(eEC)c&cMh{aDlw_4W76lEKpGg* z^xdeFCYJP(zx*>I$?ndHNzW9dk}MKZf+#g4QoC*dnZTeoGT6gPZd$#StGd_Gm+NG@ zRAA!=ZlLdTABG)kkPh@PQR1G%IBM3{Uat4xT%Xs1mb3-ZbA8Fr@A2v&H6lW>q^8Nx z0w9&d(Y~jj>#dRHJ#fTJ{#6oV*M236k-QUT;V*k*Kad*?>(ShJIr zp2b8^VfXJpz{(F@2Rk=8rv>fppqS5-U0+L6VeYL?^#H zu-IvJazod8uJ2e!fA31njVrm~cRm3-*TU9*ZH0XiGJvIep))k+aNm#ORZD#QFPG>?)6e=z~I1=5QGdW%0v0jUg% zP?l7=yV{bT4x~a09C+bbzWvAl874;0IY^b{O7aleplOhfOfr!{FBX^CE4gCLX4dwu zqJQfquDJVl*4=so^!HGuN|;S44_+mUl~T*uL#zeT#jmB-Gtbi%NI)vHSp=ja=~)Nq zcwWn=%yDA(HD-h8aQ8&aw6!g#b(E{n&Ub)um&e;`E@nY=m&IRc!<2oh{tl2T?c?W6J zr_(cJBrerJllU}^$x1S8%5<}3Wj{N2?Bx9)xs%=Z+=jiek7>W8_`GSu!WQ9dHOHp$ zI1|veKzh!WTI)b(dj<4}!iKvmmUKiE>?I~$1|SuX$Oy!G7FZ>tL)viYC&Rj27rmKw zZoK^#uK(CwyzirTQZWOSDRwOz%d!ZqIho!waDUbNHogDZUgxEJT`MMC%B#Hu@1>OH z)xZcDMc8n6f3i$KDwiM`Qz63IGXKppBqI&oIP{tstk7fU)=RnZ&fB^3zK?R{)q5~A zDcuzAYLJFaEBDNFdE*VD38<&a5-*qOZVQ66#ob*3WSzseP-7s(lEyJX7{u=a$IL0`kuo(x`-~A$;t7kvs2o3n;$J&;5oeu=kQ<` z1xVw?ucj`>>iCiYmdW7~tBMerBg6+x+S}Us;vf7keDM$dE&W?IQ!M1MOcUF-FolRO z^J$u8$KeY#9@sBgx{X(}Gx3xafXY&h!e>1}~@8QiSJ zoWex`(o=nqghnWn)k2wRYN}FAA*iu&-FiNB-#y&*v3uEd-PO3+EV)!xHJ6KPtSqC< zkpbEg(;9qR%=8_#d$YyhN zc6ZU$-A%Tw4cmtmc7_aE#zh{Unk%KDD#y|xaY*F(M7~dZCabKeIL_i)E*EenH+n&L zw*}IR1fB6|o-IfZKK~5g`IA39KeWKbUc$uPjX|1<=haBb#+NVGB5*B8J8a%_B{$!8 z8<+373OAR<$)-uSx6{?$Nl&VSb~jBXoziOhVp$sIg<~5N|2fgq%wF|YNSRwMHKq1 z+_sggZ@Q6d-v2(@R`o(#hRAT}&i0UVvt&{(Y0D<(q{uocT-(O zAZx(J!^lHvjGOal;tVgfrJV~>5yuuu&j%lTh<*F^VzeyjnXIx4|J<_$>HcS);^9C0 z5{wRCSdb={P-4>9l1d#^7)O4SXm;d#3Q^f@o7r{k9;S3BKVF1lo2+GR54s zaczf`63-UPYZ;h*E9qIYnmyND$2IS}nYL9M z@$EE`ZBY|)zGdK>sGl7I(&ZA}VZ`oLYq@IU7CJ2hH!jntfm1T@DhSl1^!f*FUh*=r ze93%b9Va)}h@vp$>8BC}`xZ!-D;7_AUS|tZkx%*VU;OF3@+l{cnNW@8rvPbO?l|3r zTc}xkF3rzY>VdHZla!B=XNiF#Kuy`u)<&kSou2-6eBk5%nx6HW=vmW8#e|9(QL_xH zDl6oZ@+)+Qu%~w|H*VQPn-6JQCz!eCr+_{5XPcK$3gWHzHa82^%X*Kcf>fW`yZ{sG~Lr9x?gpM59i6TsK zdFK-Mmts?B_G>n^sY+E|s&kjbR5GHJX_ih^z6 ztm@&?Ti*v)?t+v-=o)y^Ef?zxpX+WmpkbA-v}9`AHY3v&gsWhF`v zssg?ti65yECkY=Nxi&Th0iu99Vl!#(>)Foz8!w}OszPTaP`?ihL(R__P8pb2Y~za0 zKLGFF16fmz&5-dIOAAs>Rh;z*quG{paPU~PdUan5q-Tzo3-XHP4pLRBoV)1euC4_% zixQwF7QImt5r8JvbpFe4g^}uz*^0~ko!fX|<8IbWlS1=6Lt5$Eb%mIFu|?(qDKhXoAj$@R$v zF3wyX-c#@_)KSD*N*#174)=F$52xsE%&UcZ{M2M^bQk(m`w)4P-%UCm6p{wH057OWL6ue(7sYTVXi7Z2d^mIGH zIk}UKgDeQrW5u;KzfcZ{P{ZEQh-#rqq83|11DDflLai#P@1}~OCa-HL{VRf zq@n7Wr>muk!1w7NvkS532c)sPt3bL3a*lF$qq-$s=p4`89X>rs2QXS7o$q3w+Z&X` zXbUg4g~@0a0;J6T+RQI7S)nh@Bw%pyhw<5VYI!Pgq#zkD*jaw*j(&XrrwMs2HNMlk#^68||pTnfTvxn8~U1V&B@ySVMN(E-TA~m3_ z1hF;QAQ1=?pd~nLc6T+ysOjU^FJvNetw{}weVmmg6_92fe6gg<5v0Glb<&2#Y%Bnc zJPpM-zN&xM8aa~nlUOY2g;aeNiY+75?YM4N*P5Ii+a-TZOokNURU>kuXcwE4y1-Ub z|7CKHDlwyC!g#70Fhax&0|UG=KBI>SThdjj+nh6g$cn({?I$$BJ{&xzq_xesOrkar zi6u`PCpI=KDQ~o6u$C=7{Tq1g?Kc=J=Q&&$V}ugZM3lv%+Nkz1U)483#IcRI zS2eMo&BE3V&qV{Yv7t5j!V94FJqgm^+@|mOL8=#u2C3fE^%QCi-9#obF0RMZsRL=i z*3wt8eN3!?HW6xmi!vkP%4%Dz++3v(8)^3{jHNx~iB0m9^7AZL@qB<(n#fOE+nf#3 z4h%Mv<&*37aMjB7xM`PT6Qk@KKf&7*gX|9{m=U0w2A*qCj(q$;N+9~=)uz^DJ)8ZN z`p@-iprt$)8zR0ZLHe6b3!LrFCLU)3P+ew7#udbVSyP8_;?4RkKIiH0vkS;bbxJaK@cdt|o6cLJGm0>E^HgUgn461=9)>8nQ2&&8XxsT*^N$pTA z!uUzzkSeFt_sLk6O2`PgS{q$$b#*M;6yGZBC$nIDN*Ii)Sug{<9J{+3q{=B@oV&XS zkS1p!F{$)wZX?6L>AQ;G>fV5puaGh=4A-WTbvPIld1G>rH%5+f&>vxjK*g%^*{ej9 zfSQzZ=FDkHK$?)}^|fwJsx7>*gs`9)NAuN5wH0rW8Mbk$lwevh>B1NG!at({0$CHv z6_dD6GM8b5bZHo}=3{`#f~&^h%!g13pccv?+z3zVg~;oqb|{(80N?ZCeo3*)2DV|T zMV*nc^@Oa*rs;HS(qdgCQyO=CD7Raza#M*TNnNQJ*zhSDFea9CV1Sn=bWG}-);R@f zGjTyDj!+=|-0D5t(y@W=N<><8gXFqc2BTq>$yCHxCgRt_hk0%MIOUYZbgjgABr$8C zwQ`%LMI@VFqR5c^KS{35UL&UvQBqz>LJOP=Qq4FLZ>D0J3@cjTHg-0FG-yg3or0cD&>GULhD zNyMw?lWHNdq7gBM$xj9j@$!ToB781Es<*F(Fqy=aSztS9zQ_H-$^ZZ$07*naRIq9f zw{~n`MJXaz)9!3!o0J@}?lp?tX^w_PCNma?^J5$y8RE#q2$R$(;88_tt=hVZN1}k6 z3}0$a=+^5q2{=!Eel@RWnGFKFVge zG=p>kOAisA$WuyXsTt-hOWNysO5^DJfBhAF$?k@F!K&lQ?lH&RZFa94Al1(okY*wQ zX^PLUzKYx0H?XQ~D3D5)T2%Y|oXdz;V#Q_KXy3e!ePcr$96rI=)FhMDB1fmk7%WUN zT$~_}Pl13Ufr?!Pu+q~hpgo(1oS%$b+=>;`0xyqgff7bYPF#ajENN}eR(3VJyS7af zmtdBaCB3-G3@7iXD(#|HR&00Trz96$rGgA8!pCJwm0xY#5^=XAPMi#3I3F-pDKS*c zGwIiusFo>s9yO(AXA#Jv#L#i6DRekf55JAIb4-!<5Ri#>j>NX|<%gJ+8kr!XLzF+F zkUOrtj6N4Sl`^az|7PXHQ#4sVw4k;qYM|O7^xPS3@S`g zA+G=%Dnf+PI!d^}aZ~u*`f*}#6VktGRRgwQ^6{=6Jh1U{`o=4CR%4JFQWnx6t?t>% zWxpo``?yZ3MlI^i=7NHBRu{}gO$(fr1JzccPAX`24CgS0l#HXUc#3=Fg<>@$GLEHS zF%iMO$s)&RW*D29q2T)z0-vg6B*jV!z%5(t$e|)97z9yVT2aP0ib0iFsz!N3K&zUQ z&4^SG&|dTDta{va#g(jcWfC?-RUa#36UDGK*UXGeE(Q7@eHqcs|cSxyV!)Q1*QS!&KlDKiDs*S zRdL`N<@bjCPDB`lDiLJa7BW4|5W%akhE=Q4QT6Gmc-(*WRcvrj(vwsYwnVJ=6US*u zy;MbqF~L0nsUkBRY=AU$W@mRhD-{LO$G-lT_``!3e(fB9)K(z9r9(h!(oxmPBXRd< zG8O|VkM=vSXZvSA4%;_ExeOCU7|C<+2TzedbexGJ$FaOXCDNvgd5V!o-UukBOh!sG z3{OokUdmGw>+DyU@k$h^QWin%*jJMK+nD>(kkDO&!JXDd?pb#!oBb5os;_qI21ucD z%~p0dCyqpsFxJbykd{<7uOCXQnt)VV)h=F;He6b5zmm@Vcw#_(h-?hdqy}Od%vcdc zg$Gl89hsV7C|_WBdWPwmPr;NfeNDFZBSQgMmt1s0DM|I#`zj?VR3H5wDVkqhrcrtr z<7}-d6NBU!k&o+p$_48!``ml^)oip=q~#n-Rj3y0?1sRKu)5m8m0m}2sV$<&RF-71 zmQ+A`;F+iDAjPYm7Nm(q)mdfP5n`v)09)pYhLYX2_#LsNo$KkZ*>#YLJ1U8zfs{|~ z?i<+jxsSunO~S(0u1GC}qsN(iYd@o}?`LZ70Of%}%$W*Z=^Qe3{`knSBIzqtdNX2h zYMg>!Wu{spAJ&+Xtajv4u9d09<0z!_MmB1>!qr-l61>#F1Fi7D&&hg^gXyWK=Qfo z3wcttn#wq?Cc+Gzqr#Pswe?LoxV>3*(VxqYkyb4xJq zF-w|UA)P)*vZ-~#K}^T{u`&PJ}fErY1Q&GR|LEXdSQSbBgt};MhY>OWNJj7V_4HE97u5g9hKCqDae|SNVPcv8VH7r%LoyB0hP=b!@RRtny9lQiYz54ytBItusTkx|7w{?qcg5H^GWFwazWK zEe0tR2pKaB?e3~NX(o|;2haxa6TOpXjexuk~!h4SU=pM!w37t!aN^wk1BbNP*IHM8{j7EYl`M>@l_ zS79P!knhQ`}!Y z&KRVtui%!>b*!#X2dOOYk{NL{hXU#5FMbL(_d$CG<(|l9DsH=KAeZYZH_n04DHxrG z!y^=4-bXMv$@tL|c$0amqf@xm0NV>lVX9Gvs=d#YjaN3{xa6gd9T8d~u8=Njs05Xz zSX^3!Of0DaX&Oq`ZPFl>?5-s1WR%5n1nGOH>Dv%vryi0Rl?7b3pk%wM+VW?VS zN)kg=*?C=%#bHRfLrN-UEW8}5o!BsZY$3kO3{2n06`+PvW(X+^4s&eZeqR5@FFCw# zAO1{%XlfcN745?Lfts1=*d~GR)k`vA=o1989fY(;usSqZ5B%HRx3PmP{Q}aN8fM8? zB=ll;mcsfTQaA5r<0n518&^RlO=x8lc_Oi-OA1mMeiX&-u4H#R*EU&FVL`#94M*Cb z^P@MhT|g=xKwDN@(jLt3I&W}k>cnW2Y&f$ z4*&9HrjHLYIW!o%v9YfmX(o@vtyJp69Nn=ae`O){+Eos!2B~l5tS*;3M zOLy)(P~l4_EC#uRivCrBLJ{&+q65ds9~tD>z5`4iJ3*=%Vw9>x<*Fizq`Z(+Xef`z z4GmICK~Q8-i(_A0 zAf3zI)EyG4`%~@E5uTJ)EQ6tv$KK%~_D_y8VusAPHU&rGP74cL0aF%?Daz)ugG)cB zN;Cz8ZiFT7SUyi}e4O!j-r@M$Z}ZNpuQIiFKg^VIWAUvfJq86zbuI!_MbOu^84c1H z2=R}y(1pApApJjf-p=kI!@8P|NiEw^qzQ?W1*F;gZ)Tg63RZSOCIhyv-7YOiWzlMP zzX4LQq!N=xbXEnV(ul4>dNgMsAl(|fyJ1^aS8@_6iMmEg_My(9SNVXXbe0TFirH4; z0!oJ5s(83gJ4_W}d;+Em>MIA3v{$e8#_cUQ*3EHOw`LZz`O)ZN`=%*4e5(!|lN^ZXR+M=^d>c|>RT zCH;S(SmNO11ji?*7%mm@GHJ@TP1V-Pp~z60=n9zfWyh|p%G5>yY1^bWGtKa!LyR1J zho3(FIF(~ZVRST(H3PL+6VgH*j7oJN2C2ALazgJ4q&COfZ4J`jjX|1CtKmY+52V2? zODZ7k{>b~;EFj(5uRH*uQ6^kq#du0GeQ`J1ydag^Ef-pv#TDl`X*i9ibt~$X4l$^C zAoE~`#}qijVwtF1qcWW*ELHJKRlI7AVx>e`q&wHHX8ko+klwjPd0*NCVTl#&=buli z$P5WcFCH?3cDM9SETN6W7rHPl-6@I@BpoWij|L8Nw3uh6T%qLqIPL8UoPPWz99xm0 zly)&&N-6Rj6@Nyg{E*uCBzu4LD}Mdc7a2Zu5XY-h9UD=s8CSGfJ&7yDbJgdhNoui` zNR$|2v!N6ZRF3^@ENL@HKcy|H0;$eiFAqy9G3i`Oin642kZ$Q$F=+#&+H27ujU{W6 z?w7fiG_f!$P@L5oqe&L3K_FCpxN^LDIU{jiRJtIRcf}4yS87A0S_Hn zAG+AIv|}a~0n#H!2BLNAB*)nNSdO$neM1xOywp9V+e27%1G|yG9y}BgH8G=-@owA`w?e;{wP3~hiYq#-2f;9F+WmD7ct{cas z2}lFdfu;pc*-ao7+MQTZad(?sI%N@02hv2{LcMPcP95m0YoEmV%CI)iGi|DGC)!bs z%ioBw72u^Vs&`v814fzy~6s0#Z} zjIeKPjB(eYY{z-@L~>nI-?cKGlu>Mpv}mk)6?$Ehp@Rqb)$`Bu){DPj>Wu@CFGH=S zxVCmE>gNGM#*@XNdLESPk%71X6K#+XSSt*oAd; zp)6^9`gSBSX*36s&u2jbU+-bSX4?h%Mzpq4;_d$ZQQi1Kw8(lX-XvM6O7#%QJiZ!IEU@Gv8L8`hsgNW`-2FI^Z85?GD;2qxl`HTGO`4h#<38axN-8f6^?k)tHN1nJF+{ z_VAoEo@uM>sN!lWPG^7-Q~jJ!YLo#zjzf8TjG+Vj_|dn%!ST1=gy9jaR8~>SqMCYGf$AwEk>Dj+@HX4BCO(p;KInxdB_NSiIG zsbkV}4AR7kCb|ufs6@3f_;?vdW2iUwpN6j2mZo>x6~byLxPJ&p0MkWCq)2u-&Hf-kY^WTHOULkj?_B z3WDP1hhz~aiMzxdu1_3D(iEpq#7`KDOJ_yn5N=MLR6zQ@M<3;(2Os44@#D)2r1kW9 zoJo`WhrW(v{(pPL1Gle>l6zpH&Mv# zktm2wF#fAw@ZA)TaLMBy(FY{mgT7&nrkB9g}t?AnntMBNdaz zk}XTdI9gOpdj8$r#F8d}(y5BsWPn+~tv~kb5 zC9PpeKdWg{bZiFOY`X8gnN4Cz-{T;aI6H|o>!UZ+FPi=kySwKLqzdy(YD(vEcb79r z)%|GBaw$Tz&a_EAR0s>BVU5=YCpk1-;DmJQi?EdAD7v2%L}hS;@QH*GD(9h$XE_-=q*0{Apf2ew?>Q zD@++KW!Iu&2@zeAL>i>xCP_b`8~8Y-0xN8jgFk22%|vaGAxstd+8gzRlmh~3@Z`)*~O zh&cCkDusjhVhN@N(%IH)R!q9Qvb#;bu3~~1iUlI|(6KONpfthHq&+D}Q+6_x9X-}S zIG5rSE5f{J3>hJgsPXw8m1D>FhcEvL#RCVRP*DAaM%5$oByX(KeVX(jWzQyc-o#&u zHCV;%RcZh_bD`_Dv50jtCr$lMeKi!{XSFxPmRhz30cj5)I*tGClH0g6%F$mjNf$j_ z!@{=&q?XF=_TGCdYn3I{AQg#-CFky*=fqJnNR>uZ^WHWmCY|lK#59$rr874ux#->9 zjvJOfPj&k)IG&QQ-5lBS(3Aa0EBotzyuMEo$dlpi1Zk(&#J6qKs`K?I?b$MT~$yTPyW)K|4IQM7GQQ%^s6)k zm9$D0i!?SarsjVtK1?FLtp^K>ev;@Hd0v?=U^6K`d&$jg@>8s+Kvw8=SV|SY;7Uwt zvGQZLu_m#kZ7Ib?RvGB1t(TS@1r7Wecqa$;iZuYh6+_&JFBEl zspPX|72rooFpc#IeR(jD4#D*n3 z;m=0n=wh;@=NmdpclU$M(mVsNVlJR}U4!px-|M*XgKJ~2b1XoSLwOH$>i7qC7V-rY|8>6gd(kg?v#z6LJK9S=ZY`*nZ1k*AQL&RTi5^}Qk;l5JFwZ9 z?O{)MKilk1w%Z-_lcLMl`nyUWM>4k}?%dQosj|SyczG4pCJ8G2c_k~Y8TEeb?s;MEu=Rhs61=8gKQt5(u^brB+LmH%e_r4Wv-@bjG z@Ow#V7x4m>MQadLL;RG(kP-0aa-xo2^OX3Q#G7Jq#U)l!lJR~ZZf}FdBqaS|gLn%SPey_@lM-H;DSR`+|cu@*Z;?YQhR40r)T(3fV6mj&` z*ZB40Kjxk9{}8+8D_Il)sC2;uMnIt4V=acH7)G&jof=mdFA!x##jTatGt}b{v!a@;`W`lS@4=Zn@$GqDD)?u-(uql`!tZ$RtRDmfQ5 z2ugS0xI!gX+1&)BH?dtbj`}(YvT5nGQvIxF0@A%tKEZeY;!lZ2PAoW|w0SWuWp=j( zQhnt`h-?{yRFlG@$Y92RSEnZV_1F*tG8fcz2?U@r2Spg>$}bFXLXS+fLc3Svl_#I( z@xTB7;KVQ~v2L-(t$|QzAQ=+Ud{!&j=2K3t9LiouieVVOebw) zMf#?+0=<}68OJB!l-EnSR_WPcGl83+YWf&c7f%N>C#Iro= zA}r}!Z@&@kxMasNaCa5zRA^QWV8VoFj~?cg@eyWHDK!p4Wp$OS8xQA=d@_N@8rx>_ zt+)B_U-~i=`wtKnWgd&r{gU=t+Qkb4Cdx&^_B3Hpl07*naREnB!>Fb5}^pQjC%}C43!#X;TNy& zCc9B&F*6h@6&xu;DUe1=nsP*j2p>Fj+JQ|6pMQpL|H&W1_(%(+=Lcr4L+Opcv$(swIybe1@KS1(%xNZ)wlwdm4IFI_eum9h6yQh0N6hUX3+WWup2 z+FBOH4m8nDM&Aj0sDqG>T9vn+dWuKB{xyuLX&kRctz3%Nyav87hZ=6Kc6YV=+h~mv zhLB`*dm^}}dz%92ZljalLP&c}n#My)jvj0)z!ZQwl>pat6exs8Jd-k*Ov8qouA=Lz z9dO-l*suz6Hl!`p8W%_w*b|U~Ww}_Ug`u-pT9Zde4k8~aB^-G(v9xZi*A$m;+cZHrMdhsGa`ugjyM!RlTJ~#9L0`x z154$76cw;qqC*rFMuz$3SN@!_mwu^uyD~H>5RR@Ye`sscAh~ORianOhumT*Kppf$Q z*oUoT`0edCa;4G5nvzLZB~rp{XQ&aQ4X+4^8{0(D4U7FfsD`uudgMmCO$q3fp^)nFMBI$EJZ=Z>|A zumwv@}zy39X*WZAwt2nhXNy+#X%w4oK_vGUnK>kRw0u8SrhmH9REgLH~wT1FpUSW7zXm>kKX z)dIgDLxk7NBaVGC!M;_3(J(xz1oP^vFGss~?_M?_6(zu5&E$Fh@F9+e9_4g8&g@#G zd{ZTXJgTh7rm+Tx`SxG_6^9>v6lxU}+sTN4P(+$#1mQd&m8GtdxTdI<>y_UnQ_gB| zWxA6Ot=Y*fnRWE#p{*7v4z3Ih7EFm16{U0ehi&0I7Wu4=vAv(Qw_k_xf$L$*YCQ^D zSVk(t+*Fp4K31iUu47qc6%{_4`m9W-n!1kbD(#qv(ABCG@`==|RC9Z5NexM|!3zUN zd3j=zQaY`a{V$}uDU}-jkNTRPEKkvd;OxEY)MsYnh@R%q3=O& z1nmL5-(AHgwqMK6N}AphxN4x2CO;%44@Ej4VmkB**L0KFv4Q>%+z7W_2isOdc?#On zir^>_v}PS>8z=xzdRUcE+B}w2ULqsq6<0X!Ne^Q&Y_0FG{6RXCvN)PSgH)JO+t;=% z=_!G_2#~(~%1hA|mtV1@mb6a6YogI6%77z5#IuJFvbUJ$L>N%ZWEDt--P(tMuvO)F6I60>sVVb z$yIfns7VOgYH6Svgs#nim&dvG60ZE6kHfb0uznS!q>LkUCDHwjGr#pK8&_sy!h?pJ ze$3W&N+^nr;X~qTC*wMmEtQ(lX)LMq+NxS|JfF0)QeohQXZiLY{U?|jQx;w}yZU3! zeA4<1o8%mu6!#>Y$f_|DX+GO`xf&w8svOMfC(WmAj-;anK&rijc;C^<>=rF>es_1N zLE7ZlHAJZ6#V_97NEoTC?%VkphN4h`)Keg}NPEKT^f8PoRx!^D|M(4Fd*pj?Vn`*7 zv@;p1nx_V-zUwEe{GrCR%hc{R#mhChA-jhAR$RiBRyVzc2uFFU(o`;`m3U5wlsqhh zDJvv%#a33_eFJTG+^A=?ID&ksj@TGt`Ri8lnf}GEU~EFUr2;&a5Hf^IdwP&sF-V1*+Yfwn z)n(k%yOm9~6geR-$Rxekbr!{Rse_7Dok|-N*LJb#o?FP>eG_b1qvv0UOX>7?LD~#fwGBz)NR57!OmGsD9^>W7aY`vYX5&IyQUU4VbVS>oH|WNI7D!JM zl`cbfcOgqU97a4P1C(Z_851Rgbe6zyutHO*7Ni0nml{KR-{c>^^d}$#mI_7eKvE@o z_<#m!!=aqdk_t%OFr+hr-Q>7u{Vs0F_OsDXV;5^`PKba>Tv4f^iV{T8f#EiT{(Enx z_x5XG&kk)xMfJfEITziAmKFh()5r&$DM%A5t8Hx3MRQ?6x_yqj+fkK@d%3Sr~B(4uG7Chd;k{ppo_`jTt8teU2;YGGC+X45X1 zfHW1FOxG$*WDGJlT*~^-e*~`HrpG?mI#?CUUA46?Q%V>??_rSUnqtyhJJzzQ5}-gT z8b`93wLp5>eD3T&UL=-OK$=YI-d8B_{R8_rYD5%WY4VnAjE(CXw0Qwp-@~68rx~G>10vUxsVPQVFpQ~xR5SR-H-e3EvaTC&vti@ z^YY|q?Cy%Z%=t?k2}qSCUEN3=btFP$Es&l8K;@|y2}nh6PtP_n**i1Cx8Hu9v2>bp zDx)T)8IhwTM%rpZsQ0Li4)XV3{xTDhve+QdppwF|g$^v*O+X8lzbYwFeRPe9b#OD9?({SfC1UZp!(KSz3(vo6L zrH(57q(bF8&4kN$2hv#CLDfQ=W6~I;GCj@^kjlwRMm*qLXLnm5JwqIx_UR{sRFoOM z``z!VrthJ_L5!tN9BE>^b|ZD^!Jrlf+LBr}d#9)Q&i*$T&t#}L8GJ*MMmBB`k@I{- zsGr=ok8gbSt4!?M2jio-qT+{75Q9_?nLRy7l>#6ks{;7#6+5}7cMF^IuqJddD>ZeF zMaNV?ltfLbw+;K|-Sq#5&%?$pY8ib5OL)AJPHu1~gp_+)kj|B)oNaSwXLp{Ji@8=zx_B7R57LJpeprn@93CFJ zFd&s?ZLOfGV>oF&tAr6%!{F`dDZcm4+e`{b%`}1GVuU7c7?JgBbku4L{N!gm{I`Ec z>G*M?nF$e8QM1>yFqu{xRO9aEvu3d+l{%rotS^M$UAddPyEd{V551uSm8zRt?`<*Xlb6z{c1q&~{2Ksp$~3x|&K z%ESo8behmkoi~t*=F==oI!{bmXo2($?*9BjWdHK*Z!3_Fj*eUikP2l^Q)#43p<^qP za->1}*3=Z=k3m{9G8&|ji5rAuf~o@P{wJQ{(f{&asSFPh6=!hc0f{w9!zz&KnJ^21 zRASP;NQ3mA?#*nSiRhAcxN1eoEC@)a(k3(QY3wVvvEkDnB7MjER3;ZIChsSiux8_} zx^B+)adMqhU#wGu^h7BAq(^vVQiC*d(lJO4mCWg^lo@#8xpP8h5Rf)o(&ofbDoGsW zTn?o|a(CXqwpMm`frT)?r02K)`JdJ3!}0O)#t3UN2xO}??sj`+yGirPv66(;h0BM{!3IaOI2}u9*yJj2-NZXN~ zTVWhs!7UwYSXuT}cDEU%2c-ma*9~m@`~z^w258S}c4Yj}A{i~l(R_&`p~QXro8MF* zot&Iljv$@pher-DYT62t-k8B~&ufFwNp8W6s1k+QPl@gA0m>RwsIiZL? zNi+7mF0bb9>d}ay(lGjT|K;4(vx%K~lRjxVDHRp|N{-2R#$sws7nlC)k7D0;HLPC= zxm*)So2!_yZ@R=FJs!aG?+ozT^qA@z!p+9nU4yg&sn7z&k_t%2Rd>$W(gNoL>58Jq ztn6+s#i4XaZXS>(4o3^5$#ylrCH>YnzNvI~CnuH(NULE;4N20NNS*YtL;D%RMBH5g zsnASQMnr}x?(`Ht`^SIgr{DS)j6#8^Tu_!Y#8(P~iE(SVyK}8+1ElFNQd&m0r2F~Q zwyU|Kk zclU4&p53>P{k0-_$BErtv7~cB`iDxHK@=3<4M;mN8kV$k4ZVfhEK6EyOL1@>kR~(i zl=yhdlE!y-{+RTizwr&FySqF=nlJMBz&l8sr9f(EOX?aSS)+zMInJ~H?H~B{!;dPy zF0s3NYLK2B5(o!ghz!zECPR~M$n^1vEmv}NCCdh>lNL&<_A2Cr;haU`%1vDM`A@(t zR}tl0jFe1(IYrE?gYB~oNM|*G&pJp`caLh!F@#@*8fbN(81USIy&S=3#<2-Z$?obM zOP65E3_Sll-~J;3={SV7a|Y5|JJ--XBe{aa-Gy>{W;RH-uZNCYy(hLl#k=M1&RZvy z63jn;Q!ME+2I&(=4sp~AshW~FaxnamlnFV@BN`pyhhO_U_I>X$rA}|wD)YFzNyfE_ zwl3mhl8ucO>c!m^;cMaUUg@sj{;gMWZ6(9Tib=LyQ(ZCwQc;i(-oKk|pS=%m*oBw2 zaGYk4#-qra5p~`{s^_>V3Z4OPO_lk{p?5eT`btt?mgaz1^T{o~@Vp0WC$uDTB(-ugZ7t8!5m%jDj9Tp!bXZH+oqaoW_@4}n|}LVxPBLY z%F;uKo3qEs{LH#*dVVaa?#t2bsnXLPnl>Ug^XhnkpB_HMaLS_Sy3_)pDe5v%+V|1A zyHE3-FaHUQORHM5B~AKW8w=-jt!l#m>cL%`^3wZDUJ}yVKcqsy)Fh>-Yp341-#zU+=UDjHvgKHpvC%GSTNGB-K?n{)W(v6-+wkahzsLH! z?^7UkQj*5$2Wg=JttvC(pLG0={V!!AcqtmPJ66UZm6FvpHkJV8XCI9NKJh+a;%J~UE^%eP=e{JVZX!Im5$uiYHP|!m z-Qy@Yx@?ZyRo#8_L0T}`H1kG*)P?QXXfeaMcl8>qOk~jHhS<~)5yxa(UBE~pvwaH| z{r<05bJx8w}0V4P`*g75zne5z-#F|ijT*66%#SjF2U#=JDia_Y+!qt z31{8`nELVaf#VL9I!X?kK=nfV6Zi3;x8mMDkNqK%lq|$V&OzD zoL4moGpuq%Sqs>qHp9A6209I3bE$#ychASPPrV-)I|8UG>la9QWtA5^xGley4es!_ zN7@ zl*Z8-iy>i{a9GMg-aIS(XE4mR@zPy)GN3Kq*eEnS?XT#-ToK zpxki~awyrAB+W#^0@8|i&&Nc9bY!)tyXl%rq--N<}@6s~Lw0b_it|M+$zmMNQZTj>klLcTbvwY-Q9V&=+9&=7E%n z=O$X5EOKT9J8cIm8yfM%aMqdAY-x0KUv9CKeH&wWrSe=>b>{jk>C8*11VcZ z>H35Hut|Lm>spwYg9@BAVj512k49}<8kMYs=%|kCtYndmMy1A4)p^HZ+$Y};3@h&) zq+Tggsi@(ZA^Wo=WwpRt$vFDK53x^yRIU3qIuOFkjcs^oMup-EY z=?%9a2?jzc&LU=KP}0(hCvUz5FaPs4puG*Cx+~TA`)QNvoFc=(2!|kz;Y0O@<6V&& zls6|)5wfHz22~7tcatGYY|;Zh_kNU|cM4EjrWi+F%SLUJ`fV{1#3Y$$2&7Us`nFqd z#See^thNcrD?g114T?PvONaJFq5^LMB=wT->yqMgr}KCp+={b$`XO+wXzN zBG{=;xVc2WB7K3(;PDN7>@y9kd}R|4%n{Q-dB(*I#BuDf@i?ZY9`%_phNtPSvXH2& z!uSuI37mT*FkzVFkQM_e|0-+49#MBSH%DJdIrCDcfz5VSdgZ*)(1_(*cOVf_$q39C zV)+(jL>545?c9lnZu$e(J@7C>$s}^A4j57^$}>27bsQB|J3iJZ$HJ+hQ8;((4ADMH zTazfWELg5Bv1Nj^!!)q9B7_-V{2;7%p8yQ25L=$U2T7#Y&LjVIS%}QnQDA?Tq`6E6 zx88aye*EJf?|UHSbm)YEO%CwfhHZGgr45}djBSOHb~8vC9VkyGu=FlL6TQJ+v{Tbj!v7<2wf zi2V1lFlJ56TXT9MQQg(^U2z-+@7?tZq$p&{&1z4(`pJ;XCIBm1Tk*=~t=OKq~ z5mTHPVr@y3va6h{`tz`*BfYyVb>*1y#SZ}|9S+phNUID2lt9gc)YoX4eX$Cp@pYdNJJmE%>KZ6Z+o)qvvYG>N zeC8axD77<4tXYdcFSs1;>no)D zIrRgAlznGJn&!dc!P4tGrxrUV(W@#k3|&q5zeV&@wTIyN^0BCAHK+C@N-PCZs;_Cw zKwHE>TYU`<_`(N)W9F(lP$30UuZV@JE8GJ}cPG*Bo#5T=rtZEKAPuYtd8VpViHCtE z#`Ri~cy|3}Y-sO*RauF&X(MAK5zD2p`N?PS$hE%)8k&G)3dj+p4AB&9QooYu7YO;3 zFTJmqU&;x{wuht%&O#YZte%WhYo}mbv4h?8BI3fgE6i{x*0f%Xt&Y@XY&73*8u(CHdTha*TBv{lJKQq!BH z0xOq>mFz@)ycCcB{qIv*LJ@CRmavZ(wJch4mFCPPy#c02^0Tm5T|$_p5=*^U`VO z&xBz`#-NfPoGX3(`<(#Nu8yM?7>gG_=^lCHk#DLb?QNi$Q`!PxL(0X=TO08D&Rs~d ziExPS{S+d(G@4#pj=Qe87Fe@c_3@-6b$bD+FU}{j!KX_V$lmI%N~I1jD+pHMwCZV? zS2qb^*Fv*lW9qplVmL!FqsxI3b|hD2T8w<-CGW|4u}Q`DE~?A17%2;OyD-_`P}f*7 zEu_K*S}kB(4p`sOftS{ALI*6Vugk9CY0E^G($?#9YS}hQ92?O@C!%d_`1fyqgN@HW z541K(u56gawsTnlqtZ0GDw!IjbOz~LB}hqPI3hX{pBOm{)16WYQ?X(OsS}C~Wk_ea zZ50+;#@FE3AAA{@K2iFrN@|~1z=HQ#45WSl_XWnDzJDixRC9Of-EC%9hJ6jBS;IgF zfL&~V*qFi#8#bcJQ1ym#p)_KQ@ojIwpD(=vsiiA{W>RkDNRSh!YtI{@KIARbL?cawRd9Vfm3kk=RXF_84pxOC9Wg&eGN;OlTvZoUJR<9 zLCWwLt3^)-eRJza6Z6+iugtNc|BZ`wpOu+?JQ&Hb(Ai^9{ zuf7JKi{NXG8rWQBpyY@dIQVOy0>;+?v8V#6Dw?6Xqf?Sf5elzylP6^d%hbwiH3buT zusDCykL#Vx&J)+MBOZE(iz5om{d0w z(P$L2&pZ)zO#U8KrO;@4)sonL!gGo!$QIvv2dR>1l&CqwM4E-h02z-pi45M@x)mE5 zTab&!kufaUhrr~d=f^gciW*8Kr3qDX^JYAC*Iiip$iqNevxHudO$#s>2GN}+x~RJ{ zc*+UH=is7MSrSGhnH3Vl+2anz3DME0>u{ww9NAl>GV<9orXj_{H}VLzBQ0*xHLLCWa5B`S&(huaPgFyBnw2_dxoeg^#<(%s*zI0jW|SRgcm)5~{$~ zde-1IvdBepC^2%V=tyGG&Huu4H{Ss?>=fgMa>ueMdsL64eA%HQE2}?(;+M2~67eK4 z7^rr_7-7axAFaaV+EJKZKLO(oISB9i_ywq#H$&-cIn~yJUQH#*)WjC2h`0HRa~A_C z?O7^|LY((10MdcRz)~w6MJ>(Pu&WV`ok?lAk#cE&vP!)wDXP>&1r#!Wtj-RM2!-&< zLl0rm9k-)(?P?&|A!dQpGqedpwR8nlUMUbKHmQ>8lH_dyWe#w3s1|3|AB;JuLTysT zmlZ)?MAO}o%&WRaq} z3ma9PDXe(p2|W6Tn~~bEQ9=!-oAp5IN`{E6%HE`)!1J%H#gbP1-!n`=>R>5MR3MBp z*TgV0j>)6Opnl3kob|bnn`CyP}(8?dFl9lJUba7~7znDY~Y!}?GR_2eTpggL8CqCyIAN`bAkOB2AN4I8l&8MM2dh#4+wl3BFBz8ZJ^>IQ6k{dKt6gh&aC&LhX^ znndCObs!++V2ERb)$3s*W<`**(0ON zrjEDtsLn6~e?*)tDx54{y#IbY^7}smT*Sn-%)+s3mBFK{DY90um%^t>_2NkLyt}+@ zK1&?HyGp8YZrwpRJU$9l%^8$uS^xC0wA9cVGqFzhTU zlR3ni+i~-iKgar)UV@Ws1#)Sry=#y|ng@u-*$pf~lv@6+tKnWKt1VK6_GxuBTAEvs zhKtH*6!EfhoO#w+_`-!3V&=TL61yZo8LHs^oRaxW4o-SMNIfCuBjt&T%cA*-R2J<{ z4lA2>U|TkcO`RRsnMorZ4guj9!d46hD^;)>q8AjFgaLAxsh+wj>!oAWDm-?}Kd|Qh z2PAEdiSdk^<}B6JSi(hlADilg?guH=T}woy3cHMhiDRn9;k4?BI5=E`csn`4x@;<7 zI}Vbrjchz3y>e>Lo{zETo+LeBvJn&EIJ0*1Z3RR%7D}cUTlK#SWtZ-rMY(%N2PVs# z@Xw&*h;hzun2|8z zDFZ(j8biwc26qn_GI2l?gb=7Di!1YYN=tG2I}g^;@Fc< z!nq&#Z;YQl9c9CY!3aeVvBGe&HX^2l2#X3*P%xt6b!lV1IR8dq(&kLLz^>LLcDA&j zp|u$aIOs5KBq^Eb-POKpmt+9uiiY5tB+)B%lx1MZ_%X6+Ni@i8-ipP4_#4(d^)wRA zjR-R#K9h#Y3>6(qChtQAp}Wsp2UDcPjO${!4IGX#oHKd`j;b7k>JA&R3`0d6r9xBW z=41k>DMRDvGEDsZ1t>dqHc(v-gu_52sq(s9P>&UWFgr{2Sa+Zvql~ zxkM18qy_%#pZ~&-$lYyiRg!d{11V=PS5ym9n0mwi^=o;4%Qn2;-iS`=hGrttnZov$ zUd3O2_ETWzHXxglObjJSZKd)SF>Lfp3=T}!UA6kCMm9(*q=Uzbg)qE+Easnb3g*tA zkEt_eB3@CASiBqvMPP-(h=d{tk&WYBR2(cW(3x@3mQ0{Ekw9xQfsRZDNjry>Yr|%D zHq%DdVCxNbP}77U>0See>NUd|(&~{ORvV?ZgSg>h%bJyV=FYpY@u7uqb~eH=sruWn zvuPPmTd0C66)Hatd2?AwI)kJG5*Zu^Wrm4~b{MCXjK)c|6L3(Z67kNQ*rLo3l0J5Z ziFj!o+uB-?tcap>+6Wx{-H*eVQ4f@s0#Ttlcpqi76QKN0x~v9S9eGLmc7)sDz#g27 z*;HC2sc?4*(#IZqq?=9pmP%3yxOuC*2_!5Pj(M%U6EAPyip}k9QV7gUXJGAW!fn6# zEjB#)AAotK>|kx%$hk}*SKdpR2f-xfBDKN>3R3dqLZu}bUSE$nN6*KhM;wj%NmG#t zN0BOt!3jqZ3P)jC5y_gN|5;*$j)PP-izI=WO(UJl3h0b*2yV!dFbZ2Y@(EPC46h}J zr!LYmj7xqS$vNGDU01w)Xwx3%qSAobKtnVSk^bl0=m09z@% zx^+8V-MSea(XeYCHzSIHwC6QXDSZBQJa4c0 z{>byY;V`VyQW&Li9DB;?IP&&t^wIm^na0c6vdh!BpB)#LQhQ!zdpLQU2{IjwD%fLHB7_{q4g zFpb(rSKy!zo{jK%#{e}YKqL%EITzKL+*@+;J!;o&2&DTuNL3g?GFoIFiSH5_+eOl}(3o+sytNrm?c9ns7TKbN+O-3Z{Ozw; z{nXP)Z`_JdMoWpp+t+Gie=G(iEQ>fayfjhmRAP*h)%sW|fzlEoa_3?wnJ@{5oP09I zOg{hA%7 zg{|vWW5x5&;f-gXLt@=}#bHjQrNf*YEz+(KD^{Mcz=tNHdMDq4-_5K{V) z0%)Gd;D0egAl|jjvsn8GY;HH6bTbp-I2zV4Gmb|)-2Tp*dONgr=P?l zx7>o(XO@Wf(_#pLQbbb(z2El~NQF|zsb+?RKkHZwk&vHi0Sq^=g2Bugm^t@Q%$R#9 zDo58L7q(!BO>~+r+QSBH%Y^Be;w9xrIS-W0W(%>M&Kr^mEJR4SPo$7;ZAG@T9WN|i zh%IYZV%zeiKvSdY0%sVA89b+p92+NzB=zeJK7e{6Eblz>sqxfChW}qH#ZxLKW?{0~aVDdx7nYSP z@l_T_s639*lO|%u+_|WqG8q%5O_5qZ?9|3$VosJo)F355H6?+B17#mZY@m75Hf&$B z9;;qmimmI`prfe)nXMavY!b1`3Z!;6$f72$84Y%CAt{7eJdo<(uSdZX_^{WGPzr$x z7nqJX&aa=1Q%lBRL`w!0G?!`Dnu>bJ1%`Gg9Y>w4^*f>rHOI|G%_q+VYD<9XI2g*)H$~z=UyGzoC9)7?*>BN)v0g!4K33=4Zj__g@(o#XK+>9S?%>b|O zY{v42jo6iJLA)%2WzRo{JAeO2IIGqH?HPnAeRK+ymZUyzXirkLH;{V%;=FoDX-a8f zSRrI{OqCM@&-+Q@YY3rO47o%SWh3e^W9BT>&zO#~spEmNQk0dJAr^_jV(inK(44O< zh}_)Ri0vCUqix47Y<*)5+PCjSmONz%r!Yn(z0sxl5*$TR2(CnaTT|P)L~-7dAgT#a zR%CR58pFUCH-z&>9fBiDM`2<*B(^BqaqtG+kPBPlNd_{mBLBBm#bD2yf+-(73plVI z7&A4Oj5@1A_p$@>UMeLxkv&?|23Rc)uN zppBEVfXxYDY2y~W(Xbf_Cyn-&COmQX-FW?;2Y?-|u+o%qN_uD#xpvtGeH8(ds7IT$ zpdM-{7l=Flay{Z&G7Xs0!;}>?ZCK$LLZK*1YO4_*H4JV^4ADpo;cx_|NiMFI{46rx zh)gntOlLyWTy!LWR0haqMKDs$Cpkgxv4^g)<#;rI=XQRr#yUhKpSz;u!v4Ct}q5PE*a5 z%S)7s>s?wB;(Z{^k6|!lMZc6GkiH#2+Ep@;C+{gP+XSwCQ0=Xc}EM`bzUx}-#OJKsob<+S|K=O z=n!OdFi8S5%c78yj}R8zA`L& zZ1te$xQ~ph!C4HXd3BR?K7!Tzh(YH;Y!sBp8+RB;d!9F zQkn!sw?!m>zux{{mX0`YJWg?0ju|c%=0u0%xatX*9UqCBv?&C7dUNS4lK3v$wtDMH zBxwUR67Ej%IH(q~okyIfN#tTUfKA?7$)m;aupvd;D z6q7pV-~6g-aE({apnR+&Ptp)KPhS622B|L2MenpMCgL+w3?#M6_&ACpu9R+}09v?T zE$Isq-y1tG_DY9T*ijiSW6cO=Myheb$SIgtG6I#YS(MwBIIQTr6P8qnq!QL3R^b;r zlS87q6rrPMUY!h%oH<(&a{xrg;Zt#XaIJTroMq10%_M-lT0RX+rMtZC7R5z zuS?PbNLi{xg=bhIgp)sIT2iOCA(h4U)(&jgx&u45ZNW2-Jb))3c@WL3RtX!(rEQlh zNYk#$U@_H6FABxgs)2x1RCT#vP{H%5be^=){ApD0e+aNY^MsfwHI;i~z{I7KeEUkBCffpFBv5Q0lxJGd%{AfHg0s z3LVaw^gRY94vy4fUe##4tE>)V>@bGeA;dBTas>e@^hY7xt3`!1j2i3W7;(~J7)vS2 z-lMdOLnhK;#ViWBI;p^;R}QJWy@K`~22%DLDS%WJ`3NIrTS(g`I#LdHwKQV&#$|Z< zrRQ<$KmLjJFTbLQ21$B5Sf9ie+mM?C)4Od&Vi~;+agnf2x6}Iek)(FdwpORrJYg?1 z;)!`#Cc5Z~-dT0VcwXHt*n3)5n_7*|tK}*!Ojf@+`Nxfn=qr6j%hVsx~&!MOkad)-q{J$0X!q*4UvKbjbXsD9Yo+@I6|0? zN}Moy3XZNAgNZ0XtR;yE3zwP78y=N>QFU>GGaU_~HRPhRGz??*1k`=(bd=6L0A?ji zqcBeFv5P$WTkKKo+!_=__8)-yheyvDI*#6^Anp3LwWKMyloUw$Y0Gw^VdqXPS+WH8 z+MLF_B^wKBo%~CqG1T*fKV-tsvV2Dv_XwBRJ3PMLS_P7 zWEclETtsNUdv$*^Ap>o(5LTyJ5Ib-@roI0(l%97CvLnkBQNcA~>XN1&QQs>SJ}7wZ zuLt=Tb-&|CBMOD;J@Ld7NbPDw zX=N1>Ep4htsc&R-NtL`c>MiDZB7}E&4Jf~~^+y8t2uOo7)dQ&(viW<^@lF-*@SIah zJ)k6vIR;9ZdIlS#QHlfOqi{&gC>$86!Z;&_@|2Bu#zjd^5l3{KiWxd0g<+sGVq!Q6ZmV=g!aIA|=gF|`EHOHK7!Re4lgqWx12?%whe1nI5+{1<+5$xoEJd-pwe zx@Vqo=GzXWd0_g>Kzb@;iqtvUP>zGf#zs8$_~W?cmYea+Q%@t8N+Xv{=Uc)D>m3!d zNd1zozaZ_R#tc-F2HtnxTkElO^a3H8gI0&7B%-=|ER$};3voZSQqkto3N?J}f zq(RA{Rz=ae(hzrV((Z3Z2SNI;fBX}d{^U}$vtiR+cirKhb=FyLOOX13%HK7iKozr6 ztQT&bi3A>h>~Z}5rkim8op&P=iR1(BI^R+=Wb{A;?M&u==D!Q7r$JB^QFr~j^r`L^ z0jXAPb>K$DQAu(K9ELtj16Cv?xu;G?3e^Bc!NL?&;ppL0F}b7)Ih?C=(YA1vR?bR9r=wJcr zpTnZe7zS>-;YM73*#fk&IQAWP{M$X}oO6O}cNgyG?p*xMI#x-}?h~96vZJFDRh5-! zX>G+5RDEy08P6Y*Fv%^!wDMs%uzD2Y%w%Ew(^V;a z%xWPkh@Nt)%an?&qM8#G7f6LIbPg*;?C66r>FncS95h)0RQhNb5)*YT#miOO5I}c# zo(CoA4cFg*D;He;&H|~dMm?yZ4$G7<3=s-Ry`SaFmf?>#+=R#Pdk{?x4QOMJQ_tl= zsX{V2TSvGagC-v!q20#3N*`@6FSUKsHE-woil9knKwp^>?P$q!lcgu9T2uYxhOVly zSFM4?x1|LH+Xk!Os}VtMs2pR>5}Z725+)jP)F6y1BZN|VU`1Vbg&xUpjIIVjshFl6 z8gh|}80d%?=!}O^f5PDycJ|T0%t>%+%8)ipM02L9v&7009${j4C+E=dg%Qv|<@~wv z`WtY?g3HlPNqWmIe|O*azW2TDC26sjt-~c!=h@?-N>6UXz{^iRiwFOG7nVHvG&ZkT zg^spnk)gH~LWA9jPRo@dXf{dZ;$2mh60Dqy5OY;kj3eJ-KA)Q9OTO;HMOqOU zl(hA#==0>ZEs5sr#li9|EOC-!9MsJs8MBb7t3cKKSr~r8JYd!&xFaj1_Az_bNtFng zLRKhF1Q~+do)`fx%mk@O(x&|gq#QiyCQ6CMJkO34Hm+EW=O29nuPuBUt6y1$bVsKo zH7{@4h&JTV0SB2d>-Z=V1>=yGO^_-|p61pn`kWU9Q5Wi(b>lJk@+yrdg+#HX#P-tC z2+{&UL6;iwJhq;S%PO|CJBQQmv??&lD#47}(HI*oM_nY2+Khp^q=^!nLZbeY(hA;{-jEz>HzOn{mODZtFqzV-|1996xNzz6|MwMQXtQDrM zvV#omP_LK+FG#|CN7z71iHVl#D6Gk&F!8v*tUEXq8S@IckROZ<_2u&*oh`&(1r{; zkwp@=bivTo2mBx!jnJ;5cqNEO<*Xw#%-b-yss6f@8e zH!<~`6Hq?q07Pa_0ftuqG<-^H>O&wfy64#dV5J>klGz;e=NN>3AdQo@xUr9;_ zkjIx5w6!IqfLYth4OqK)2^wBl1~ZXCBAZ61ox!?>E$DDE*xuHJ?WtC5MJJM~cnN!z zi87cKUNOsDvT>7}FTxcpv=CzX5mObtmhNQ)si(^FCqb!f%^0deF;o~KOsF0%fE-a) zflAxLuv`dbSwn17*2yiknV_v|6?y5_5(A}8P2nkRF=S@7Rd9!uArVnU-*|tl+Mrq_diHlnJ)h?0zB6^Ly$8O5ocV_9uJdft7UekFU({VC z6uhhq52R8>G?N87(?EL?XzIkK2Nt1y^=9nYxEY!DPPmMrlAvG$&2|#Y8@Hg%$)F>Z zL@JlT&bCG*kwK1?6r?-1E#TEQXyG>n$gngpG!cOz(vqrdsS!qbv=nhGjEYbM72z0$ zm6W3s1QP?EQ<8V zN>t67in=3a!#sF0Fnv4_w~(}4xpykHQCM9;>V;`o<48EdeWafaWI_(@+jRu!qqzRM z>u~kuSD>wFKLV+C(&WpWNb3e&pjjE2Ica5|19r5bbLm<%yu1QiUVIJau69@*DPi*@ zQ%RK6R-hxBMlzj3GMhn1x>Eql-_wSJt!+(W$K?y36jUR{uY@YAtwJ#LHtF)6v|$+^&DXwWsS}2d7&mnkSlLgf zEo{ITJsjbw;}AdO0F)m*1(-1fsEPw6Y=F#CEvo8Z$h6csbww81;@UQ)B-QeI2&j8y zeIdK;#v5)Bkam!9w7*DFKS-5Cb)@Q@#3ZSv3iF1O6EJA6?&<)xw*f0RVf7=6(e%bT zBpMn~5ss=h^b*%ppp!yfxt#pokxQe~biC4+UO_IYSg6v#xOb|fQ<@@G#!3aKW+p2n z1A2~i0!+T{u470sFn%vp`#i^2A%x=*3_M~1i3#bDA#q-IJ|lxDTTzN+WeKY19E4#< z&r_0f%y6KhR2p))5ycu(S+<_R9RMh^V|0UGKLaW_ONUh8-N&u%*b;)d=8CJ(-rNG? zh8wPPKmF-X?-$2jZl|UVInrYwX*3OCEVFl#vmbHH87^LhaO#eqm9ZqIt>@$5!D!X*ld(f zn+O~*Nx~|qECouUKscgez=fva1(5n@gw6=kAtT>+#XuRXG_m{BcKlfC?mC$NS`y=22JWCp{W&UZbf?iHf&wA1c`N9(6Vte zqRA{G?I{V3kQ>YTKDm4|CRM3Wq^=Y~D*#l$>Rni~>++>o^4=zotLvx)bwQ{!U{V3T zIzhz_At?@KvF?y5{bktOG{N#FQ5#iL$D@AcbkrU+6__wus{6@@l@!7u>2oR-9Q5nv z>GP{Z@9$kQZ+h6Jz?$0s=FaXsv41?-u96_V=BlgF*)jyuuH!1{T8h~ts;o?4dP*1& zWwrR60&B{Jy<#19u3Ur8bz9J}Y9ri+7GxWm5l!YWqO?NPQ*o|11UySK6>MNtXsoal zYU*EJSOzOO2zr%T%@QVA))QhU^pGkHmX3uHsw_vWwhGx{Wf*tbk#I*=Av9(rP*x(< z^2Mdhu5Qx9MTt%_j=F3^Al)6D?bfk=klJ<*zrXP&0coPGy{jZGa9{UNNvfDX{#IlZ zT&zr}yHf*hI*S;?Hi@i~vg@}XwPqt))^0-6y3MfKQfOPZS)4s|@(4r8 zHlcCzHY9d7p=I+nX~}4%ZA7!K#5hA)rpMVr`1j|slKjpZLv%v18hkDmLW&YF9z&?2 z6m~@koM9Cx8#4lo)WJgf?+j05!}fp`=sk4v9ZiIqqzS2jwb1IgnO%RMq&!IXQ-!@s z4!V=Cm*OUewzLD8T%m%Y%4744RIe*rCjqcpI6dIjlkfA?$mv;Xtiz!~>HN$MW} zot2{GP=WkjDB`EGVpM%0kAzNYppz3@vy2&@D!oOVO*vQPa)#J!SZe+<$BkZNI-_j0 zU*0bDBsD`LY-dl9GHXT(glh@Ub1CUam03HXBn?ln=%*j44sXgOrnau7!gOt-{!c1h zo~EZGhC(p?AImQD&ihA(l9Z04Ydo9uH^2Rr`?=44ZV05l5eOD5?kSmEPgcz_5TWH| zuc&OBJoljM_~tvPDVm}JmJg`@*i60^pue=If`P8|sY`r{4ejNm7A~mRLWQk+WHVTE zX>e1_dkk3xdJ53&&Y9o2#|DRs>aMm)JKEb}{QB3wbpQ8%|91$ay@1rO{uY}mnyatB z3l=Ttt?(FaQiV~rChQ6z-7Z3(H(0JDA79lt_jR5th|R7tv{*~I0s4*lM2jw9-sg@( zJ1EU2u%>C7^cs413DRHv>KE?kKmYk5koGcRdXl925Z#us0Mf2t>#I7T25RB>K>X7C zB6yyBeAORU)oQlCRD{1&cagr2Lm+)?SBu_2Dw6bc(+zY>W;Sfl7V4611s1Mfwah|4uQ1$p!8=<_NPT_ zcfi=wvE9fswvFqryIw%r%C2g(N#Bl=)E~C!E9BANfelVbeT_YJ{{G&_zO-L|yw5`* z-Mu$f45T;Qa04#C{BpFjGQ&03T;+c4YhUZPx~m->d@*_w_Y`E`y<0DSw6u%xnkVT! z_7sTr6_6HVAMK5??9VxaW6fjs)Oh#j`uoE^-B^^4i|enyPC(j5NqY6wSGr&S`qu{p zQoS=@U?!6hM*^u#+@jH_^#AN>Be471ovhe7n8L;DvGA7^|1!<|CpdxlJ@?lOOHcR2 zXW+i2rKMu1S5{W$j|qB_dF}qFfV(rfcz%v&Nl8f;x?nb&h2;_Jg9Hfw_4#1Aie6U zE8K5<;~N74sRo)phy%pI;1&*t`<%qPGs*cvczsSBP9%L@{cnD!fy?{RFNxpx1TZbR z_&ov3<9Qxli=VQxGI=&mVD78WHJBID*D+cv(F+johk)f66STY^j&WaGF$Z5?$LR0* z?0V8C5(&BP-Y_rvdq4fz&#%pKyeKTV`G4n_baZs&-)Dc$`)2IZCrGcja)JA;Z+>e) zAZ0^du2uvjAWkN3T(SCE$@}`gw}Fw|Nl(?*VAX%)dG)H#NzT7(N!r^A%KaJ} z8}pzqFE7snl*bViot>R>?y9P){5AI03)Ef3InMeScpn_|9Xoa)9*-Bjw4SK?=U~TK zYbktQ0+c`ZWsq|2Q3E0f`R)irKS()lynoJ3t)1+xcQ=^x_GFV@dBqjVadi0=mvsZF zN&@cLt*#}{vSrKg&_fT&p!g-4mO{ZB){{nqYOoFmUZ0>DIdUXs%$R{g4?R@C!}IYP z8#ZjfOE0~I_3PIQNRK@7NQ@aXMm~Ofk6_>gT(V>d{_~&z$cyGn=Ckk_I9c^Vz!mwR zgAT$er<{Ue!-fs!UG)1HKF6j_oACJKkIPRj-A9ZVfz6vY=OPS9RR)rN^eS(OE0|??|tuk1$+e6 z0}niaJMOqcKuRD}8cm!y5%cEF!v{b3LA>i-@5-xk1S4PIAOHAAc@6?xOR?a+ala{3 zrr_WI{x|CC>biVA*u|!&=jZuWuU?Jse)qcqRKMo1JNA5k9ef-|jx7@}KK}8K%i`9P zr<>2Pr=NeI^WwGFUc*HfU4%u87Rh~T?Ma_UYk3D8Z~%VvqaWeSGtV68CHCt6L6G{% z48l0N?6RM918Go_7JCT<#lsIjER&lnnBGU*ar&wJQd8S{{BE$TJdf4t*HK3uB_O4w zD+Q#FKKiIEG=6aQ<}~VUHucvl%SkQv#5o_gx3UDW$xD)d_o z(&wIgPC&YN@nRXL;Qi=#I(_RW;Y(lo5b-9usq7cNex|_uCV=`1iBVJ{!OI#V;^^ z{CLq&xbt*)-duYUC_8E~%rTqyYa+O=y%Wu-byJ48EP2r_QR z9d{gl{_~%UWTgsAY5M!$|Grmsm*=M>B}l1G(>4rleckgw-W>0L#flYqNvgwJ`W%D3 zR&cy~0$o{IIamnbo8SC~grjn-#Uvmt?x)yOAT4Gx^=I5@k5cQ|Nu~aWznWb4m*ZD=moHylRFd{*fCsX|>wO8B!w)}PR{EJUXNnYE zx^yW{KKW#kjM@g#`xDgs@Vf&KJP}L#N{Q>PyRKJtSBG5)(gz=WunR~B z3z)vfhKmlhghw8EBp-v`(;)SmD21^KVf5(HxbAn?;rQc^N30|U+jhLhRK@R_o$6R8 zm>k|>wCUi&tv&EsYtgZ9|JesJuFpREY#yXRb4zOgen}csclXpH)7Lxg>H9t<>4HnU z+oV#R?kxbRR+0O9*ouk@eC%T%!?(WmEwK+d30{8rWn6H<1=zlQdtN=$=g~GCB`59J zKmYm9qO$4$_b-3>O93e-kB(3J??J20^zPCQe>1$h8l=45-jbw#M;@P7V$GI?V~;%! zS6p!=rXMgJ@lt}cd;KL{Oq`%(#Zhj$z8VECK}Ly2(9r(pril{T^Q!-*ug#ym%>g}` zRfU*B#R=M^T9Uq#K&oug4j5M~xYYe-Fi!d=gH(q_I7xc43H_j%Jb5yH_`@HH13(iC z2+nVQ^P3`hnwy)u;G8d>=cNn&BOm#QfSc+tHv*Ru*$>j-%F6rWYEMZ@&}e(Muf=4r z-}Cx!7D%E`v;k^AuK9qaKOC`ive_uMY8CdjB7?0XyR zaXm>=f>bIqyxAZv21E@~PLg8Y)!@S)ee}`d)uqZyY1q=zB5~4R|N7Us_S$Q)X3d%| zhfuBM%jf>z|Ni$ynrbP+Sg1#s4y%b!_FGIw671e*-RSQbOz~E3b}L|Elo{mZEitB z!wz{jl&F-Rd=JrZ1T__vD36z+rn*{wlF=0jhY=!6h}9FLk*uz6<`_~9ru|JVg0Wt{2THGEAmw62pnU36 zpAx$~zezX6LjObl{+{#C#qePx5cUcOOA&B(aRbl_Tm6@_;byXEZrFvE#$8yqdJUE> zeGSW(zJ~3aH=}7+6Pg+uWfsND;?nO%7NMMj3AH1of%5pV^_Vz*0uDQLF2>i7!|>t5 zQB^-y^>$?=9qxZb$J>4WJ$DCtNLJP-9 zbGeJD-@FFLpK3h!*Xq2M$OE%+b>rv)P+2}j@=3408tp8fvO6HSnBxzw%2PNr1 zLCX1~sjeJ9jxQN#BuQ`q^uH614FSqy_~H8@IFCK{SaGz`UosG<7mWy6ihROUgY-(4 zPYHrlCV#$SdU5ZrKcu2xbYC1%4gl3ms-oP2Akp4aP9%C=Nf;nli%C*_eLn++_pL#~ zb5p|TK_}oi!8y?>O?1`{??bDXL6G)zf3s)L7IJ}>X8QSgPQCiBTenWiG2U{^E!ets zYd&7<2ZffNd|pZq7AL0)MiB8lnkUR>;yr6MR%;yk-t{@Ts8QV`sf7CnH5DGu3B`qv z;U|(hy53I#q^c>EcyMGcWKE#W%_41C*y$$F)Y6R2tJY!diZ}4$)6Zhvs?~VyrI%p2 z2JBQC$mXPt1)D$-=u}_XK9V4%aZ8z49W6t|HQ;2j$RdRrs}iGzkHF}?F-T&baf56}V z_BXup$}93Nf*_@aq@^k6!U-pwAS4;G+Bo-m;#PNC+2s$tgS4%+6~;y1`L=t>Pn5cw zmrzW{>OtKt22$-}_n*VRnsDMUobc11{*oF0f~uafVPQ4?FCzJUI81B)#HF zk6{1ZZ-2|B6Q*l`E6}hh5XA23ruC==S27L)XxrYmUyQ~V)FgNz5-hj~GG48(7aU&=(yOn& zT0&JtLCW4v>>x)Y)BsW;s<$@QHSNHf9b2$r$2M$PzX6Zlb{AH?vJCdFCgtb}g<*Q_ zA(gb#tus7|UOslBq@l!AJ&DalfyYw9()Jt?j$>v;9j1&JgGm!7Vf2itnE$a05Sug_ zHhUr)E-c#cI^F{y2-2XrqRl4FIHK0VvDWrG=LT(l3J1;wdW-!V_v1U`eA4VSF4T-J zFwK+a^=|{VNdxL`Hl4-|*I$n-u4MU?78n1VeJrYQ96kX2Rl;jcy;YcY--qsSC+nt zXBIBP`j?l(ZfI12QA$UGj1rFj)FAbmRf)*+K$`FB=1Ewp)#_NaI1s4iurMt)43jE` zVN7K$YU)N{_9@3=&gsXaeEN7~!X~VcG?>h9+9q8j++F3=@^3+qzWd$p&YKb3kMn>8 z7skt}jRXP8f9r)^LQT0GKKjv*$|8Hj5l3|M1MD4;UUpfR8|&)-_ILAAyX}r7-5Ve! z0H|jE&;R_7IBoo%TP-d5H#&Ss=_4qa4a2`tqB3-&9Y@6^y$-=>Nvf+)(C(!TO8b)w z1SJ^(98__&^N7bW#!E>?4l(1cykDJE9(V~w%arscNe2Z|X{qQpZ&ueJ+f4B8FgS7?y0Aq5-mwP>GU}WOg<}ZP1>MLI{4%#KPf4aI%8<>OVYPFNC`Ho zC{!KkjnglM(vAa8b%ucAATu|T5|1mOmN0$ANwuWcAk{8+UW@1Y-S2*v_at)>(kr(H zly*$eCj7)FJ|P5uIg&a=f5G_|2#Dy=5rB#$6&VcMFp#ue>`HWE zebWwX*|h`Pwr|Bl_uhx+9{&$gTerio!iX3q9Cj+tvL~y=aq?aahFd&%s=4cdRI`+H z&qfijt^%lGyRZxcmII8atdd5{Q;bR+J81@{Rn=kYoS7JT>S3rmVit@M)j-&UEnU)G zyx=*Go_uPtG*#w(`8O_-1aAt13%GN6zNPxV!p2}UxuyQw_(esO|U{?#Ho2ClcJ`w2{P?XdVwntMs3Ex zG@}w{jh~5eqsE|o)?^&<(F=e>CaaF;v@0D4FTA(}-?`|!pd_^!>S2RsUrRw9d#1Wi zKvI$tptR+gq@gtsJ*IkpdU474;lH^sGsaF<8^d}2t=MAPZ4&nQ2Y+iyrNgFEY20wb z^|2D9z3Q$ASHk}Nw2x;YMg(;1xku~)IK3Az?4tQ z02%?TY2AetZ>+$^)obwJZMS3jQ_lbm%_w7_-zao!<)q4HG6LM%npzxw_+dEx^wTlp z;2HAVls-}h#x&5<+KO%4w+m~Fq!T7ZkX=(6SHRCdm*b$sHBse;QRf)AVB{Q3sv3b2 z(l0tN%hHE*D!sTq&ob3Y!v_1{RXT#IndMJbEUg#lYRfMp{v;_)(^=GkgT z9&tq8o36uNlBn-xDAAL8?|t{;KaW3wd+xmlq!s4u930QK4donBp(BQc;cgg*g+^k| z$O)J-VG`=+9gLYDdk-*W3=m<3KpW4#^di2)$_$jGwu;9FB`LKU+K^1aql9FK`p3r2*rbtog$b5mi`SF+l^=e;rC+0+gQQ_rL%B z0#NNh3No_#0_&az>AB~fE9$P6qy!wu(S-rZ{->I@V#ymT5Y9Nb{SSY}E4SYbw09zI zga9W8Ct||!QeSv)B_*YJ?|U!6r$7A}NkWK(LkL-_^eQ*b4{di#rj2Pzb_dn-Yp%H( z_uYS=l8QMSmhB*%vt%0e&Ip{DX>4SBxxY0L2)?9Go`(rqdrB)bbp%muE1$l3SG@VT0 z#v9pY;wrSYwZi!3SHI$3cKHIYh?fN;p8?~`Ast|=k05CIvcC7d@8#p9J&^_aYm*k6 z)TD9IaTLse3GPdfQq9pI<-O4^`N~(ml229B$M8FCU-EDMJV>t0e&>RJRpm?M%jY?1 zhidg#OBJ;s_R*TmcjJDL4#vAH&mod@9GF?bV7?!u4r>>~l(5S#xcK*LFJi;a287zv z`1Qq?A-QY?kaJK+oE>326U zY1!K{+|?%Ko~cAa<|xBuk_GdPuYB3PY{3Gt8JGp}b_OXOBD%C=v6sYw)smDFQO7#_ z0x6HvAHHb5L>)@fo?QOape41DETYeR<}e(?Pt;KLvO5Xws9g3Vkm z+bc*35G_#&)Qd0qF@F2o-@wkfs3?iSOsYcb$q*2+fsw9-S=MlzHDNYJ)(peMQ;xzx z?>ie9TMH-R;!K17&K9I6u_?u_~$}z@ax}q-9eh{ z>=bG#K`QyAU;WaBF3Z`QUaHc*08&=uBiTR~9P7`-rX(c;gey-^>Nf|MDi7_+{({s$ z(7X@50`nUBzVxc9|4ol3y}oo5>0)O(*4Dol*LAPGElCMds=A%o47R6|SiE@yHt%S_ zvv)s)2mkgDpsf|Kvk;bpX&~gdC@(2Rdq=wzf&1kzekp2hh;dWNEzJeZto#G{r5eYJ zC0Xu&;C_7UqaQ^}YYUv5i*g~7j-x+v0WiHDsEpy6 zS6{;aBS;sj5R4s&qYiY;=_n$fn(bF;rf3G!;Idr$x_ZwbW%QsMNNGnDsxo*w?f_L? zQFj9QaRXI%2Mf~k&O1+R#UL$A-w!7RLCUx$Gh_Oaq(SM$=is^YYOKK%1Sx?@N5fBk z@)NOZ)MQkjp0ZSWdzEhnNGT&bQYmcgXvd>#R-m;#fhYcY8(w;BArcMS>BG%~G-{X# z8>TqM=v4XMMc+f+s5&(+F4;Muet}d%Zy`&(!}I3N1?%T#QfW|;W{xGj&S3|LF~*5X zoH1$!#?_2O_0;h=^^+ffHD@YN6UTEezaWkyvY~|TrxViq!bcC^6PWZ&vp4|f37t#+ zcf99RT|rAAogUDVG!N3RU3j5OBClkeu+IpMeP+%Kvd3q!=jKECuI3+UsUj=@%p@f)-$HsOI6A5 z+V2af!SfXZssEn(3c&i}+rMV3YZ~O;deDE>k677JK z5s(^|i3mFgwdV4SW-bJ|i?|%oK zCMtVW0X{^!plf5YQH9g%XJCBgaEzHc38#JH11erRyc{n)|1AFBMHk_zMT^8~r=$#mt9d^Od9*0+W6VYMFeOyw~7++cRJ-Zj(~o?E+Hft6d7p{qT%5QX^KY7Yq@52vjq6(j zQWL3+jm@b9?jlHATCwPcf8eDD9z!PC4%iux4n)ZZTag(E(rlYKNXdg` zxPvcOC)gHq1o>A+N>Z|UbcZzm{(g|sUL=uvZ-P{(K2g=BT}n0(B{)}ShHZ3xr8f(t zvM2=Nq<-&i4kR{&@*ur;<*R6JX~h#a{sT)MdJImo6K*y|ktWlGQZ&LGOvjP9}r;Zm% zYRpyY?vm%96PuKA(i|mep5|CEy@J|Mf6WV0LCI3$e9`YO*fntXz}gQ<`lZkRuY2va zzvv=Gm8LuhW3-1SAE+c9EJ#WB(#g2RK*|+TJ9X$@@2@1)Dz4u~EvD{jiNS@1&Ie9N zzF1CVei)X~s&9WM3HRGwbvFo7I@p93=-F?Wpa5AAN%;naQT7-0#brA7EwjXdjo0ETw#&|t3{9~AF?cj7-=9# zZ6HdCiX5h*8fTB0iTaumsG2qor+(%`Fy~ALs!D`4q(Lg`Zr4HwGSvM6sn(GAlXHXb zk`D<*h-FXiHar0+Ld-QAZ!s$YP%r8pLpl&qpa ziTK7FZ{#!g^*+IuMsPCohSV}HB2;~Q^H}d`b+;Qx&pTfc>@`rOW{`n&&c&`=77x7s zDt5NE;A->%_zTv_Q5qO@d11SXsNvtNRaE*?X*msJr+wAV4h{?f|!xFjV= zeUem3R0BE3K#S|(p=GaPb7Lb`zPuE7{P8d7T)P2bHiH?lORaIrniu*_m{u?Wtq&B!n!<4u@}3iC21G$?p0UeymQYh3Q`Hf0C;Bo z1}xjKUNTi~|I=Tv^|_Z2PN!hHIT)r3*Kox-#KvCyFyPP0JOAjT1ptw7q#H={`J^7( zD(B>|X~RZooyltXuPt4gFIN%{TVjtAr0m2x3T2pCG92fPKLlgzMq|pkC!qYaBZ0b7 zWGkY0F#u90Qvj(}bvcLlA=pkj=_GMfQIaw-0m-IdkdsGHper z8h~_W(PpF6p%aNVAys7^I}HN$tpsTTz>208EM312TN@kj@4x&N%kO>=Rw{+ClY>d3 zfayY5JyOWe0?U2;_Xj?RFMRO}m^E`I%Hm~3L8_fq*<2Q#oe3;nya+d3cRlXE=UxFf zom&jYghQ6ZM*wxYjIHNaGWvu5R4cz8V7&u9E6TI2yS&0si=u1FD=3U`>t{v zNt&9IF9wmfM|DLE#?nbqWkn2K5|xF=2vn-Qy5Vq8no?8ZcU+uly72vJjc8A+yMFGj zkQqMp(T}*aDfXngTP%**Tbxw0cjz@^Di>40G~=ikjjN|P>D~q@JDwq`w$Y)4t71UZwmb|zel14ATdBoY=6C^LSJIP7pqu&3ss z9W7dt@_OqxZNwdS-hq4Xxfic2c?s<;tt#=Gp!b6NA=^O=E=D4RIjFUcYo?&+xwmNaFXOiC@%L$zN)ND<7a z@s8J0mG!8!Baq|DXAI8AfvLUSC8gc)_*7)wgIh}27&e5Z1ith#KOR9?PVZhPpbQgYi3l3Y?Lg~dLJwP{kF zs+Jss>>=%CeWBSviYwC5(V-fWK2s}PFpydyjG4~(vNTUn-)ryX22A(U*+JUa*d&94 zvlOIgq+HknSyaoDVwQw?lq^r0Ed`UUz}}Y9%-w97lj*qpqe_p4_@sHg4FcHMkZ$GEK_arpO)|?xTsM{Og1N$eA;v za-eOG{Bg%l={@*g89Q}K3X2O>?<${ez=9Bu=j)h>f`URV^TRbj2*F}uIenRWecIIl*aQe_dYRn9qHf>5;DVhB z>j0rJ9WpY;Wf(}a`8G3c?%o}cLsJH7xl+tsj5{d2=s_7cdrl7abxZ%ifE@bdfV92+ zPkH;b*X7j5`z2O9PYP4yw}91Cuo84BD=U@0o?cB`uoswvCbX2Mh3lU^qpfeeN{dUB zuQ!jhi#E)8f(V!|F{zhQx$7IZO6{V{rT*Hh3C$qy!>fPyOL{_q;2= zqL`r-`V_8foK60!o4E@}nWS*xL^cVNvryz}4!?zNnYUSj#HTe1Zq`88WMI>-TKn95z)}-dwW&&wyhC`RSHcsj?SQAGMk^uGY#vWBK7Nn2hn4u41qDpOZt7Pe6u`WB9b^Qb+JlW zb6LHts#z|}RxXztZogHQfA>boUtZ0ZMB*fO{qYs;ZS83w)ikZMK~|0lr!(4*Cj3m6 z3;W1GZ1#^cNT7)5DlhKc+!qr%Of;ZAn_!Z~75p0JY>jf6Ae9}YO{Pg7yl<2D!j2tZ zdXPeC0>=?y^h{0VEb@f}sR0L|GL#q-nrLCBCIQ~#KJk$_Fqpko&0@_4+05TewWv`b z4X0oXr1=E}K2yB|(gX|%fmTJ?4UCLPXJ3yT>^iIincCibOFn7+w~TamYosTSj+fv? zA%do5bTKCId!&$Kb7lZ3-829-kvOCJuR@BXHeN1YySzqLRxXj+`a1d6h95}HO*crv z%4(7Fc|JqF(>v1M?$0MhldAR$jiLZRtQ#Q3(t#YnUaXA;g?Nv%vuoEb4J2Vk8$GLi z&cF&#u@>;VadTjNKsgXFvy|P`wA@6HQqlFhXP;FfvO&g7TuLBi@d*Ot3R0IGI}^R8 z`6qPfn#dV{)YHb2;?ke(Ct@8}i{hZF009psLywzi~XE=p?=x z2C4IJoi`KspbU44GmHt^l>E3X&M%gmms}y&FR7PRwaewo)z{04jkk-`E)=i4NPA4R z=sr+Z{Fo|8X~qYn2y@ep?oShd)K}B}^3qE$>Ci2=-q>=cW(xCfa^Fy_kYckG4%ap9 zI=N<@2vTaJTbf(^rf&jAvl*n;jgZOwbfpxFfhNrrq}rYri)mEPCC3g+z+6CT8kPAh z_?*myF*C`2AD?jvv`HOtcnCtchsKrm1%*2$Awx5(N%*Q#0Sg491M zK1lIT)f^4{(|!U;XGi4N@#Au=t49vK*CD&#dQ$2kT`Z7tv)Jx{!Dh3#K)@HXQY)%JFgM7Pns$l;DT@L~ZT2V;Q}=~g z!h84&T$cqUr^j_!WGaRr48wN6AZD)E%)e#>Rn*L&Oo^v z&CCQBcy@rweeiqu{l>vdlQ?`jXwyt(g)T@Fzor?QOfIwe@Z3{J2xj z4h>0h*?iTA!i-SL^Yl+bwQ7D|zIM(O=EWrsQth(|DTxO zH+}mSS#|YQvf`R+L>4XZ!@j|YQl;|_OjJvUk{^BK(MM$W?lvDJ=gy`1q?|w2oc%>Z zx<09Uw#@7`%ZHH@FfH0!!CfA1L zfR-)N7Vazj{9%wH)To5&?Ci`qYLWXv*sNZ?THDIjtzG8_cw%`9LVZrnPx=gkDM6!% zB{%~kg%93@mz3e;sPy#rN_SV696o$VKIqsh9q+#{`}gga{@z}V(gGBsl*WO}HPM!U zw7`q$kfySt5?M6ALawU2LI(-o)NrFLs$L>>U%yt0%1b4$tjxa^BNj6f%Yekq?v)W3 zk3RO8f{A?z3u*S4Gsu~usD^?Ivsm0cb_Jo82vVX-v=?SW&WF+G*q(50)|WHP=m|7B z!rZEn!WK~4z8Xlwj7(#m{N|~rmC0#z3$r zfGJZkLnevDA!m*U<#|L?!+s?jXPO#mN`w!GpKGysB(N#+w&~ei&qfGXp#k@Y)}si) zdR=Y7!yWr>%`wxuxi4ya*<_oKYMaP+d7n+^x&)E}$0Em+!aexF z11ijXs+^dnPr{Z;3Zy|ti&`{Lkm+a&PtGLI`Vn1kOom5BXvhSmPa^&#m zvTyHRWmp&*8kW(~)2dbZeMNyLt*@?8j-=Y9)l$23nOt+_N~x)?*1%4zs8D1P$9 zmB4vaa0W!b`gdQr1O-nztP7e}N;Cmzc(#u1J(XezLJJ&a({$_+LXG{V8i^nvu?VAN zb!XhN)|@F=D#?H2Hj!4dK;^VR`hVWvtxr6m?QvSnkfup#79`I!!ypATB>UkvWnsdH z$cpG$Omc=uB8u0|lr*qrbHMpNnhMQj01IncGfCM%s$kHz)L*igEHGNgMjF}>CCl>x zUNkYLDCSsLN`{{YLBs}gZ8SU2j%4OKR_LvT)9}g$eWyG-!i0N6Q|AIw?hRIbp3%w@ z-R~P28f!zYa9&A?mI>NHH;`sZx&ca}w$^{@4_xvYJd$2gg^s3`;sr7^I4DQ^`ej~m zv5X9l=#*-h7D&e!NDK1fQXG#yyi!?EStX@aO!QWjuD~1{ONd7SJCS3T^VxtI z(xm1?+5qNo1sD4aczK^Fx^Wg|v(VTJn;&F_5DepD@3@vS@&`V#X;${TySrN>_9&Y3 z0%dvl8q(x2UPkGJE69WoEof`x6$zYo;z8{3ZCBY0#42r4$bT6VWsvQp$e*B9074rwtV%n$Ub<%TN-d9IJcSEV z14+2hBK3Yir;-AxF;VJIPZChF1nD2Ht5rxg>_kZ(CRXscl}irnBlk`}8^MH`38ZP3 zMKH!9{L5w>q%F-dOmz1rcW?A|?%XM*6nS&=v&h_?(u#ipANneTl;utV#2p6gxG@SU z7gs@BN*YLmU=Zdq1^$4PukbcBES9I$-{*AOOwdN@x_L^cVfKO4T~$9w=9|0E$S|q8 zA8*{?5qT}Gs7PznJ)hd$DXr8c{GqVq45ta0^Im-MMJcPCGk0@d%&+Jdq7LyK zNYC$JBohhQ($uJ$bae2f#5Ue_r}u}KU!DW$`K{|$>f3W5%@EC+!4m*Tn;JLEbK9Hc zG(PEuJAdfC{K_kHAf3TQzSJ)j2~s~jF#eh|cc*kDY{}>#LX!g0GlM7Pf2nysEeiU~ QjQ{`u07*qoM6N<$g88?WF8}}l literal 0 HcmV?d00001 diff --git a/test/Charly/02-mapping/06-manager/public/index.php b/test/Charly/02-mapping/06-manager/public/index.php new file mode 100644 index 0000000..019426a --- /dev/null +++ b/test/Charly/02-mapping/06-manager/public/index.php @@ -0,0 +1,26 @@ + + + + + + + Erreur 404 + + +

Erreur 404

+ +

La page demandée n'existe pas

+ + diff --git a/test/Charly/02-mapping/06-manager/view/README.md b/test/Charly/02-mapping/06-manager/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/02-mapping/06-manager/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/02-mapping/06-manager/view/comment/insertComment.view.php b/test/Charly/02-mapping/06-manager/view/comment/insertComment.view.php new file mode 100644 index 0000000..fa6b761 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/view/comment/insertComment.view.php @@ -0,0 +1,25 @@ + + + + + + Exemple du CommentManager::insert() + + +

Exemple du CommentManager::insert()

+
+ $error"; + ?> +

Insertion d'un commentaire

+
+ + + +
+ +
+ + + \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/view/comment/selectAllComment.view.php b/test/Charly/02-mapping/06-manager/view/comment/selectAllComment.view.php new file mode 100644 index 0000000..ddf10d5 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/view/comment/selectAllComment.view.php @@ -0,0 +1,33 @@ + + + + + + Exemple du CommentManager::selectAll() + + + +

Exemple du CommentManager::selectAll()

+
+ +

Pas encore de commentaire !

+ +

ID : getCommentId()?> Voir ce commentaire via son id | Mettre à jour | Supprimer

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/view/comment/selectOneComment.view.php b/test/Charly/02-mapping/06-manager/view/comment/selectOneComment.view.php new file mode 100644 index 0000000..e7b9ed5 --- /dev/null +++ b/test/Charly/02-mapping/06-manager/view/comment/selectOneComment.view.php @@ -0,0 +1,34 @@ + + + + + + Exemple du CommentManager::selectOneComment() + + +

Exemple du CommentManager::selectOneComment()

+
+ +

Commentaire inexistant

+ + +

ID : getCommentId()?> Voir ce commentaire via son id

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + + \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/view/comment/updateComment.view.php b/test/Charly/02-mapping/06-manager/view/comment/updateComment.view.php new file mode 100644 index 0000000..17116fa --- /dev/null +++ b/test/Charly/02-mapping/06-manager/view/comment/updateComment.view.php @@ -0,0 +1,35 @@ + + + + + + Exemple du CommentManager::update() + + +

Exemple du CommentManager::update()

+
+ +

Commentaire inexistant

+ + $error"; + ?> +

Modification d'un commentaire

+
+ + + +
+ + +
+ + + \ No newline at end of file diff --git a/test/Charly/02-mapping/06-manager/view/homepage.view.php b/test/Charly/02-mapping/06-manager/view/homepage.view.php new file mode 100644 index 0000000..0b6e57f --- /dev/null +++ b/test/Charly/02-mapping/06-manager/view/homepage.view.php @@ -0,0 +1,30 @@ + + + + + + + Accueil + + +

Accueil

+ +

Bienvenue sur la page d'accueil

+

CRUD des tables de la DB

+

Comment - + Insert Comment

+

Article - + Insert Article

+

Category - + Insert Category

+

File - +Insert File

+

Permission - +Insert Permission

+

Tag - +Insert Tag

+

User - +Insert User

+ + diff --git a/test/Charly/02-mapping/06-manager/view/menu.homepage.view.php b/test/Charly/02-mapping/06-manager/view/menu.homepage.view.php new file mode 100644 index 0000000..c452a7f --- /dev/null +++ b/test/Charly/02-mapping/06-manager/view/menu.homepage.view.php @@ -0,0 +1,17 @@ + diff --git a/test/Charly/03-test-mapping/index.php b/test/Charly/03-test-mapping/index.php new file mode 100644 index 0000000..78a6b06 --- /dev/null +++ b/test/Charly/03-test-mapping/index.php @@ -0,0 +1,207 @@ + + + + + + + + Test des Mappings stagiaires G2 + + +

Test des Mappings stagiaires G2

+

Table Article

+

Test de model/Mapping/ArticleMapping.php

+ 1, + "article_title" => "Titre de l'article", + "article_slug" => "titre-de-l-article", + "article_text" => "Texte de l'article", + "article_date_create" => "2021-09-01 12:00:00", + "article_date_update" => "2023-09-01 12:00:00", + "article_date_publish" => new DateTime(), + "article_is_published" => true, + "user_user_id" => 1 + ]); + echo "

getters de article

"; + echo $article1->getArticleId(); + echo "
"; + echo $article1->getArticleTitle(); + echo "
"; + echo $article1->getArticleSlug(); + echo "
"; + echo $article1->getArticleText(); + echo "
"; + echo $article1->getArticleDateCreate(); + echo "
"; + echo $article1->getArticleDateUpdate(); + echo "
"; + echo $article1->getArticleDatePublish(); + echo "
"; + echo $article1->getArticleIsPublished(); + echo "
"; + echo $article1->getUserUserId(); + echo "

"; + + var_dump($article1); + ?> +

Table Category

+

Test de model/Mapping/CategoryMapping.php

+ 1, + "category_name" => "Nom de la catégorie", + "category_slug" => "nom-de-la-categorie", + "category_description" => "Description de la catégorie", + "category_parent" => 0 + ]); + echo "

getters de category

"; + echo $category1->getCategoryId(); + echo "
"; + echo $category1->getCategoryName(); + echo "
"; + echo $category1->getCategorySlug(); + echo "
"; + echo $category1->getCategoryDescription(); + echo "
"; + echo $category1->getCategoryParent(); + echo "

"; + var_dump($category1); + ?> +

Table Comment

+

Test de model/Mapping/CommentMapping.php

+ 1, + "comment_text" => "Texte du commentaire", + "comment_parent" => 0, + "comment_date_create" => "2021-09-01 12:00:00", + "comment_date_update" => "2023-09-01 12:00:00", + "comment_date_publish" => new DateTime(), + "comment_is_published" => true, + "user_user_id" => 1, + "article_article_id" => 1 + ]); + echo "

getters de comment

"; + echo $comment1->getCommentId(); + echo "
"; + echo $comment1->getCommentText(); + echo "
"; + echo $comment1->getCommentParent(); + echo "
"; + echo $comment1->getCommentDateCreate(); + echo "
"; + echo $comment1->getCommentDateUpdate(); + echo "
"; + echo $comment1->getCommentDatePublish(); + echo "
"; + echo $comment1->getCommentIsPublished(); + echo "
"; + echo $comment1->getUserUserId(); + echo "
"; + echo $comment1->getArticleArticleId(); + echo "

"; + var_dump($comment1); + ?> +

Table File

+

Test de model/Mapping/FileMapping.php

+ 1, + "file_url" => "https://trello-logos.s3.amazonaws.com/c3f2bef1693561dfb24e0f00aa592c80/30.png", + "file_description" => "Description du fichier", + "file_type" => "png", + ]); + echo "

getters de file

"; + echo $file1->getFileId(); + echo "
"; + echo $file1->getFileUrl(); + echo "
"; + echo $file1->getFileDescription(); + echo "
"; + echo $file1->getFileType(); + echo "

"; + var_dump($file1); + ?> +

Table Permission

+

Test de model/Mapping/PermissionMapping.php

+ 1, + "permission_name" => "Nom de la permission", + "permission_description" => "Description de la permission", + ]); + echo "

getters de permission

"; + echo $permission1->getPermissionId(); + echo "
"; + echo $permission1->getPermissionName(); + echo "
"; + echo $permission1->getPermissionDescription(); + echo "

"; + var_dump($permission1); + ?> +

Table Tag

+

Test de model/Mapping/TagMapping.php

+ 1, + "tag_slug" => "nom du tag", + ]); + echo "

getters de tag

"; + echo $tag1->getTagId(); + echo "
"; + echo $tag1->getTagSlug(); + echo "

"; + var_dump($tag1); + ?> +

Table User

+

Test de model/Mapping/UserMapping.php

+ 1, + "user_login" => "MikeTyson", + "user_password" => "password", + "user_full_name" => "Mike Tyson", + "user_mail" => "test@cf2m.be", + "user_status" => 1, + "user_secret_key" => "secret 123", + "permission_permission_id" => 1 + ]); + echo "

getters de user

"; + echo $user1->getUserId(); + echo "
"; + echo $user1->getUserLogin(); + echo "
"; + echo $user1->getUserPassword(); + echo "
"; + echo $user1->getUserFullName(); + echo "
"; + echo $user1->getUserMail(); + echo "
"; + echo $user1->getUserStatus(); + echo "
"; + echo $user1->getUserSecretKey(); + echo "
"; + echo $user1->getPermissionPermissionId(); + echo "

"; + var_dump($user1); + ?> + + diff --git a/test/Charly/04-manager/.gitignore b/test/Charly/04-manager/.gitignore new file mode 100644 index 0000000..d11ccf2 --- /dev/null +++ b/test/Charly/04-manager/.gitignore @@ -0,0 +1,11 @@ +# Ignore config file +config.php +# vendor contient les librairies externes en PHP +/vendor +# fichers non envoyés +# PHPStorm +.idea +# VSCODE +.vscode +# Charly +.history diff --git a/test/Charly/04-manager/config.php.ini b/test/Charly/04-manager/config.php.ini new file mode 100644 index 0000000..ae92c13 --- /dev/null +++ b/test/Charly/04-manager/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/04-manager/controller/README.md b/test/Charly/04-manager/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/04-manager/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/04-manager/model/Abstract/AbstractMapping.php b/test/Charly/04-manager/model/Abstract/AbstractMapping.php new file mode 100644 index 0000000..6c5f9c1 --- /dev/null +++ b/test/Charly/04-manager/model/Abstract/AbstractMapping.php @@ -0,0 +1,42 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst', $tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + } else { + // sinon, on affiche un message d'erreur (à commenter en prod) + echo "$methodeName n'est pas un setter valide
"; + } + } + } +} + + diff --git a/test/Charly/04-manager/model/Abstract/README.md b/test/Charly/04-manager/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/04-manager/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/04-manager/model/Interface/InterfaceManager.php b/test/Charly/04-manager/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..421a87f --- /dev/null +++ b/test/Charly/04-manager/model/Interface/InterfaceManager.php @@ -0,0 +1,16 @@ +connect = $db; + } + + // sélection de tous les articles + public function selectAll(): ?array + { + // requête SQL + $sql = "SELECT * FROM `comment` -- WHERE `comment_id`=999 + ORDER BY `comment_date_create` DESC"; + // query car pas d'entrées d'utilisateur + $select = $this->connect->query($sql); + + // si on ne récupère rien, on quitte avec un message d'erreur + if($select->rowCount()===0) return null; + + // on transforme nos résultats en tableau associatif + $array = $select->fetchAll(PDO::FETCH_ASSOC); + + // on ferme le curseur + $select->closeCursor(); + + // on va stocker les commentaires dans un tableau + $arrayComment = []; + + /* pour chaque valeur, on va créer une instance de classe + CommentMapping, liée à la table qu'on va manager + */ + foreach($array as $value){ + // on remplit un nouveau tableau contenant les commentaires + $arrayComment[] = new CommentMapping($value); + } + + // on retourne le tableau + return $arrayComment; + } + + // récupération d'un commentaire via son id + public function selectOneById(int $id): null|string|CommentMapping + { + + // requête préparée + $sql = "SELECT * FROM `comment` WHERE `comment_id`= ?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + $prepare->execute(); + + // pas de résultat = null + if($prepare->rowCount()===0) return null; + + // récupération des valeurs en tableau associatif + $result = $prepare->fetch(PDO::FETCH_ASSOC); + + // création de l'instance CommentMapping + $result = new CommentMapping($result); + + $prepare->closeCursor(); + + return $result; + + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + // mise à jour d'un commentaire + public function update(AbstractMapping $mapping): bool|string + { + + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + // requête préparée + $sql = "UPDATE `comment` SET `comment_text`=?, `comment_date_update`=? WHERE `comment_id`=?"; + // mise à jour de la date de modification + $mapping->setCommentDateUpdate(date("Y-m-d H:i:s")); + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + $prepare->bindValue(2,$mapping->getCommentDateUpdate()); + $prepare->bindValue(3,$mapping->getCommentId(), PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + + // insertion d'un commentaire - À modifier ! + public function insert(AbstractMapping $mapping): bool|string + { + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + + // requête préparée + $sql = "INSERT INTO `comment`(`comment_text`, `user_user_id`, `article_article_id` ) VALUES (?,1,1)"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + } + + // suppression d'un commentaire + public function delete(int $id): bool|string + { + // requête préparée + $sql = "DELETE FROM `comment` WHERE `comment_id`=?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + +} \ No newline at end of file diff --git a/test/Charly/04-manager/model/Mapping/ArticleMapping.php b/test/Charly/04-manager/model/Mapping/ArticleMapping.php new file mode 100644 index 0000000..7a2fc92 --- /dev/null +++ b/test/Charly/04-manager/model/Mapping/ArticleMapping.php @@ -0,0 +1,124 @@ +article_date_create; + } + + public function setArticleDateCreate(null|string|DateTime $article_date_create): void + { + $this->formatDateTime($article_date_create, "article_date_create"); + } + + public function getArticleDateUpdate(): null|string|DateTime + { + return $this->article_date_update; + } + + public function setArticleDateUpdate(null|string|DateTime $article_date_update): void + { + $this->formatDateTime($article_date_update, "article_date_update"); + } + + public function getArticleDatePublish(): null|string|DateTime + { + return $this->article_date_publish; + } + + public function setArticleDatePublish(null|string|DateTime $article_date_publish): void + { + $this->formatDateTime($article_date_publish, "article_date_publish"); + } + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + $this->user_user_id = $user_user_id; + } + + public function getArticleIsPublished(): ?bool + { + return $this->article_is_published; + } + + public function setArticleIsPublished(?bool $article_is_published): void + { + $this->article_is_published = $article_is_published; + } + + public function getArticleTitle(): ?string + { + return $this->article_title; + } + + public function setArticleTitle(?string $article_title): void + { + $article_title = trim(strip_tags($article_title)); + $this->article_title = $article_title; + } + + public function getArticleSlug(): ?string + { + return $this->article_slug; + } + + public function setArticleSlug(?string $article_slug): void + { + $this->article_slug = $this->slugify($article_slug === null ? $this->getArticleTitle() : $article_slug); + } + + public function getArticleId(): ?int + { + return $this->article_id; + } + + public function setArticleId(?int $article_id): void + { + if($article_id<=0 && $article_id !== null) throw new Exception("ID non valide"); + $this->article_id = $article_id; + } + + public function getArticleText(): ?string + { + return $this->article_text; + } + + public function setArticleText(?string $article_text): void + { + $this->article_text = $article_text; + } + + public function __toString(): string + { + return "article_title"; + } + + +} \ No newline at end of file diff --git a/test/Charly/04-manager/model/Mapping/CategoryMapping.php b/test/Charly/04-manager/model/Mapping/CategoryMapping.php new file mode 100644 index 0000000..cbb3d1b --- /dev/null +++ b/test/Charly/04-manager/model/Mapping/CategoryMapping.php @@ -0,0 +1,89 @@ +category_id; + } + + public function setCategoryId(?int $category_id): void + { + if($category_id<=0) throw new Exception("ID non valide"); + $this->category_id = $category_id; + } + + public function getCategoryName(): ?string + { + + return $this->category_name; + + } + + public function setCategoryName(?string $category_name): void + { + + $text = trim(strip_tags($category_name)); + $this->category_name = $text; + } + + public function getCategorySlug(): ?string + { + return $this->category_slug; + } + + public function setCategorySlug(?string $category_slug): void + { + $this->category_slug = $this->slugify($category_slug); + } + + public function getCategoryDescription(): ?string + { + return $this->category_description; + } + + public function setCategoryDescription(?string $category_description): void + { + $this->category_description = $category_description; + } + + public function getCategoryParent(): ?int + { + return $this->category_parent; + } + + public function setCategoryParent(?float $category_parent): void + { + $this->category_parent = $category_parent; + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/04-manager/model/Mapping/CommentMapping.php b/test/Charly/04-manager/model/Mapping/CommentMapping.php new file mode 100644 index 0000000..c3de343 --- /dev/null +++ b/test/Charly/04-manager/model/Mapping/CommentMapping.php @@ -0,0 +1,152 @@ +comment_id; + } + + public function setCommentId(?int $comment_id): void + { + if($comment_id<=0) throw new Exception("ID non valide"); + $this->comment_id = $comment_id; + } + + public function getCommentText(): ?string + { + + return $this->comment_text; + + } + + public function setCommentText(?string $comment_text): void + { + // cryptage + $text = trim(strip_tags($comment_text)); + $this->comment_text = $text; + } + + public function getCommentParent(): ?int + { + return $this->comment_parent; + } + + public function setCommentParent(?int $comment_parent): void + { + $this->comment_parent = $comment_parent; + } + + + + public function getCommentDateCreate(): null|string|DateTime + { + return $this->comment_date_create; + } + + public function setCommentDateCreate(null|string|DateTime $comment_date_create): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_create, "comment_date_create"); + + } + + + public function getCommentDateUpdate(): null|string|DateTime + { + return $this->comment_date_update; + } + + public function setCommentDateUpdate(null|string|DateTime $comment_date_update): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_update, "comment_date_update"); + + } + + + public function getCommentDatePublish(): null|string|DateTime + { + return $this->comment_date_publish; + } + + public function setCommentDatePublish(null|string|DateTime $comment_date_publish): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_publish, "comment_date_publish"); + + } + + + public function getCommentIsPublished(): ?bool + { + return $this->comment_is_published; + } + + public function setCommentIsPublished(?bool $comment_is_published): void + { + $this->comment_is_published = $comment_is_published; + } + + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + if($user_user_id<=0) throw new Exception("ID non valide"); + $this->user_user_id = $user_user_id; + } + + + + public function getArticleArticleId(): ?int + { + return $this->article_article_id; + } + + public function setArticleArticleId(?int $article_article_id): void + { + if($article_article_id<=0) throw new Exception("ID non valide"); + $this->article_article_id = $article_article_id; + } + + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/04-manager/model/Mapping/FileMapping.php b/test/Charly/04-manager/model/Mapping/FileMapping.php new file mode 100644 index 0000000..e26665b --- /dev/null +++ b/test/Charly/04-manager/model/Mapping/FileMapping.php @@ -0,0 +1,64 @@ +file_id; + } + + public function setFileId(?int $file_id): void + { + if ($file_id <= 0) { + throw new Exception("ID non valide"); + } + $this->file_id = $file_id; + } + + public function getFileUrl(): ?string + { + return html_entity_decode($this->file_url); + } + + public function setFileUrl(?string $file_url): void + { + $text = trim(strip_tags($file_url)); + $this->file_url = $text; + } + + public function getFileDescription(): ?string + { + return $this->file_description; + } + + public function setFileDescription(?string $file_description): void + { + $this->file_description = $file_description; + } + + public function getFileType(): ?string + { + return $this->file_type; + } + + public function setFileType(?string $file_type): void + { + $this->file_type = $file_type; + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/04-manager/model/Mapping/PermissionMapping.php b/test/Charly/04-manager/model/Mapping/PermissionMapping.php new file mode 100644 index 0000000..a17e27a --- /dev/null +++ b/test/Charly/04-manager/model/Mapping/PermissionMapping.php @@ -0,0 +1,49 @@ +permission_id; + } + + public function setPermissionId(?int $permission_id): void + { + $this->permission_id = $permission_id; + } + + public function getPermissionName(): ?string + { + return $this->permission_name; + } + + public function setPermissionName(?string $permission_name): void + { + $this->permission_name = trim(strip_tags($permission_name)); + } + + public function getPermissionDescription(): ?string + { + return $this->permission_description; + } + + public function setPermissionDescription(?string $permission_description): void + { + $this->permission_description = trim(strip_tags($permission_description)); + } + +} + \ No newline at end of file diff --git a/test/Charly/04-manager/model/Mapping/TagMapping.php b/test/Charly/04-manager/model/Mapping/TagMapping.php new file mode 100644 index 0000000..798f6b9 --- /dev/null +++ b/test/Charly/04-manager/model/Mapping/TagMapping.php @@ -0,0 +1,44 @@ +tag_id; + } + + public function setTagId(?int $tag_id): void + { + if ($tag_id <= 0) { + throw new Exception("ID non valide"); + } + $this->tag_id = $tag_id; + } + + public function getTagSlug(): ?string + { + + return $this->tag_slug; + } + + public function setTagSlug(?string $tag_slug): void + { + + $this->tag_slug = $this->slugify($tag_slug); + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/04-manager/model/Mapping/UserMapping.php b/test/Charly/04-manager/model/Mapping/UserMapping.php new file mode 100644 index 0000000..400ecea --- /dev/null +++ b/test/Charly/04-manager/model/Mapping/UserMapping.php @@ -0,0 +1,87 @@ +user_id; + } + public function getUserLogin():string{ + return $this->user_login; + } + public function getUserPassword():string{ + return $this->user_password; + } + public function getUserFullName():?string{ + return $this->user_full_name; + } + public function getUserMail():string{ + return $this->user_mail; + } + public function getUserStatus():?int{ + return $this->user_status; + } + public function getUserSecretKey():string{ + return $this->user_secret_key; + } + public function getPermissionPermissionId():?int{ + return $this->permission_permission_id; + } + //setters + public function setUserId(?int $user_id){ + if ($user_id < 0)throw new Exception("ID non valide"); + $this->user_id = $user_id; + } + public function setUserLogin(?string $user_login){ + $this->user_login = trim(strip_tags($user_login)); + } + public function setUserPassword(?string $user_password){ + $this->user_password = trim(strip_tags($user_password)); + } + public function setUserFullName(?string $user_full_name){ + $this->user_full_name = trim(strip_tags($user_full_name)); + } + public function setUserMail(?string $user_mail){ + $this->user_mail = trim(strip_tags($user_mail)); + } + public function setUserStatus(?int $user_status){ + $this->user_status = $user_status; + } + public function setUserSecretKey(?string $user_secret_key){ + $this->user_secret_key = trim(strip_tags($user_secret_key)); + } + public function setPermissionPermissionId(?int $permission_permission_id){ + $this->permission_permission_id = $permission_permission_id; + } + + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/04-manager/model/README.md b/test/Charly/04-manager/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/04-manager/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/04-manager/model/Trait/README.md b/test/Charly/04-manager/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/04-manager/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/04-manager/model/Trait/TraitDateTime.php b/test/Charly/04-manager/model/Trait/TraitDateTime.php new file mode 100644 index 0000000..6b56182 --- /dev/null +++ b/test/Charly/04-manager/model/Trait/TraitDateTime.php @@ -0,0 +1,34 @@ +$paramName = $date->format("Y-m-d H:i:s"); + } catch (Exception $e) { + // en cas d'échec, on met la date à null + $this->$paramName = null; + } + // si c'est un objet (DateTime seul possible) + }elseif (is_object($date)){ + // on formate la date en string en DATETIME + $this->$paramName = $date->format("Y-m-d H:i:s"); + }else{ + $this->$paramName = null; + } + } + +} \ No newline at end of file diff --git a/test/Charly/04-manager/model/Trait/TraitSlugify.php b/test/Charly/04-manager/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/04-manager/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ +PyA07*naRCr$Oy?K;mXL;uNyK8K@XDykvuc}h1w3K!%v;q3 zGkvE2oO7iArrXBGHnuU??mq1~LH8jeEc6d$;F(UZYwoN490t{4fj?FlPO(^`DFB3Pk7mWKUij zbKkMGdKP~Rj9C{iA`AmweDS9|^w2}R^2#e1m1;3^Y-biITOeKh1zrx%Om1?dkdfT+ z^99rdehnDPJL&gsJmj2OKwaGGm<4AM#|vTO@exw!h#vZM=N*yZpHeREG? zITcvr``LW53mMoZRLy;=Sj)NZX4CpZ@Gc9+H?; z5=SkNF8MuqS8v#SLnRgzT!e;>LZc>YCRmx3M=~Ico#Rshwf>s<+~g+sCs>qsm-8|8 zo9nOUJ)#wmF6v${3ZxQ~TBg;CNf&iVFWi%6-%Nv0Tu=i70V+@<#PfVCO!XxeE^$K> z3<-#mpUpWSvf{Kv@_YFng*q>#z6_Amg}j#nC=pf!PU7y)${gwI)NE1bdH@&hN-nQ= zZh>@p-H&&5HjSI9O;%`Vp!z@+`5qBAS<|`I?o$!S zu4O8KrXsMzNVWyZI@YsQ2|#Br!jsE2@9Ltw2VT4&NK2)Hib-3R^y0YN%E47u%}{{! z4GqxYnMr2KWqjAdOSyPvY(?wVRLo-HEotaQQADUrWT<{_!8E9*U24jAjlov;J9X5VDmb5jTx%?f_cpQzZo$Ow~&kQy)=MErdJe%=}zrJPDrH647hf?^vbsbnZ8 zwW+46<5kc=jzXOVmS<>>)lkVGTUkc^2#kopmRI<=wF*5E+_d#lws&>W7Jw^aNY4hG}4i0z5+{h7?FmsKp>ndj(d65w~vM$*#^$ z+GCK0mVjA5U*0{{0_ma_(}I?CdU`TyYirXnND}n7Ea{>y?uB?#Gf2g*RWTWk;HU2h zNXIFpGn8x>->~8gthlp2h5~2|(nz@40@T?cl_XTNC3V9FNPQDLTP&+b#+zY95OVwG zom|%0MZ2$)N7zyhl6R3LQk?Z|HsCFHcittlAV{aCCZhKC_7+Gl1me!>Jym5?#g77o zihvY&;hlrLGBHj*lclUcYN{lU8HG4zMC6Oj4dU9V_@x43QzxOsk|uRj10)s|cUM5F zYM`+tRUkDyQnfrQLk-g1T|IPGCH@ruILQ>v_rdggs4`9y1@){h!F%jQiw0@KiYlAh zYE@gN3qfahRrE+?SdjE#hj@8nfIxW>~z|=XZPiplNG7U=nz-V z&kG?8!7(B2f@`Y3i7PBw>A5t**=ui^UikBPS}l;C$BTO*4sFCG6YZCplud&Z0@8s) z{CaXyxw}=vR`IHU)CmI|-=jD=%FxkwXmc!#a!tjWs;(J7l!db-*`y!Jl1faflD{!X zZDAONSmiR^m4IDtJ0IPB4ej{~xgbIk%Cg`BFT}G=QfpRXZ|sLQm(Vfr#KXqGmJOnr z9aRsrF2ohR@b9@Okal!*%sJDRCB5*sZvHb+AQh{n93GRhWiSXlcjOQ+O-`xAQ4nc& zR=cbr*&yJhpFGPmk39_I!%(YW2SIE}^`SIKCEYUzq_I0J_1Kyvqy<4Tg_FScSk> z?rp=AYInEJ0hISp;jg%^@!!Oq4Ggk@%}Nh0GdlU$rPr`6O4C&faSemOFqrZ@!oD6h z-hDG$?!OZ@tt85t6l0L4FcsL7$8UO!x}YU(fpodT@idmyk5{;9P_iuz(!&Q8NK5G~ z0Zwd54bnkCN6q8)r=H>mfBQEuG6-HlWqca|Z9>fKO}*)VVrq4{wGERF&u1q&?p?c^ zySg{gGviU2oF?1RLD8`|mWfz>?=5Wq;=h7b?U1u5IP!9Xw79(Ww>09a!f!4ce?gE+ zowO~dOE4`|#UBA(||ZN@pn8CMVi0QXjmUUBCYsSl0t> z4kcF?f#$cQEs(~6$I0$)3#5x(p3CETYS*n>(kQm12}q|JAT=aQqe0qMDskYMXEaEM z1*D~S1yXTq)4tDoEcVdDXSQC=E~}GlzDmk)C=fB;m8QIB6W9FjpNH*hpxvS3=nSup zN$0w|Es!Q46=jB>{PZWPpY*lYUd3pEba{Ypv1g${npo0>Kx!&?x4oEv^lSLTgW#9z zAl2O5*&U{*OXR3zlwsidJ}ZIUbo22oS8`oPKfTi)ZY`t|8BBGinB2CC8~@`MVb=!e zO5??32Wg{A>aX&-f79i9=2K>P;e{7?=%ELB{q@&dAYCjtmdo=_57OzAENR*gX)hIH zODZ5eLFCP~q`DT`NaW16YR#Y(a0y?@5%2>W$#C!1J-n}T4Vwy(&U+Y^!(`fIY<(9u z{onr{cCCY+ERn5S>*j*81=87x08tBk?z!g_NZ)+(O^jCJXt}^|ap!R|NF}=~?(P6D zO$tbJ1lWq`Ahf@wk?uGDuWwwxlsY1*CK8l?gcK1F4j7(!fe=Zd|dM zn|n8KquE8rjE`+NOt}WbD>K~uAHD!LUk)pBI(sagHL4!l*a%u6oefga-F@bnrW8#)*h*8nX^DD1p5}_XmJ2p4$nFpkakzA?0xD94bs75ipY>y()p}uv*i>k zEB{ZvtC&<7;Rw%)RJ~JrOE=>3@zs0y$lA;3I5LH6S{zRYSl4dj%K!7A7Z$J5CzW3Fy5DG}6;EX^T z`^CytReh#fe1)p?mqySNnyiWp-k;sded{l0citxJMNGBZOs((W@_+wn(zos*vO`Kn zs0a^<>U}G_8%xa8m%u!hw3RqoJV2JiGv|V|7=u)CcTWM*Uf<*GCw|PMfA#051nKEM zTXW1h7o>7NU0AdQ0lVqtp1$3DFte6iIiT9^Fqn(z|JW^T`~3Z|aV7b}B)K-p3%6p@ zdQ85MyW0Zka)93A&!G-d`N0gB3(`_5hc8_)P1)UZ3R2Y_6HADyVSEwohE2N%Ye;jA zy_yHsT+Rlk4N+>yXHBf#8@c8WJ_CEU;5i|dtr|~TiKF-mEa>jG$P9}I$Z~k5x}l2E z7ZFKzH?gFLrBy9Y@hm{P7%MtACY93=cUSsEh31zFO*(y(HCTMC=W?!Hxsfh2g>OWZ zJ5${Bd!NGk_$`ow(3bwv*6g80TT&4sYt}f@FKl(eEC)c&cMh{aDlw_4W76lEKpGg* z^xdeFCYJP(zx*>I$?ndHNzW9dk}MKZf+#g4QoC*dnZTeoGT6gPZd$#StGd_Gm+NG@ zRAA!=ZlLdTABG)kkPh@PQR1G%IBM3{Uat4xT%Xs1mb3-ZbA8Fr@A2v&H6lW>q^8Nx z0w9&d(Y~jj>#dRHJ#fTJ{#6oV*M236k-QUT;V*k*Kad*?>(ShJIr zp2b8^VfXJpz{(F@2Rk=8rv>fppqS5-U0+L6VeYL?^#H zu-IvJazod8uJ2e!fA31njVrm~cRm3-*TU9*ZH0XiGJvIep))k+aNm#ORZD#QFPG>?)6e=z~I1=5QGdW%0v0jUg% zP?l7=yV{bT4x~a09C+bbzWvAl874;0IY^b{O7aleplOhfOfr!{FBX^CE4gCLX4dwu zqJQfquDJVl*4=so^!HGuN|;S44_+mUl~T*uL#zeT#jmB-Gtbi%NI)vHSp=ja=~)Nq zcwWn=%yDA(HD-h8aQ8&aw6!g#b(E{n&Ub)um&e;`E@nY=m&IRc!<2oh{tl2T?c?W6J zr_(cJBrerJllU}^$x1S8%5<}3Wj{N2?Bx9)xs%=Z+=jiek7>W8_`GSu!WQ9dHOHp$ zI1|veKzh!WTI)b(dj<4}!iKvmmUKiE>?I~$1|SuX$Oy!G7FZ>tL)viYC&Rj27rmKw zZoK^#uK(CwyzirTQZWOSDRwOz%d!ZqIho!waDUbNHogDZUgxEJT`MMC%B#Hu@1>OH z)xZcDMc8n6f3i$KDwiM`Qz63IGXKppBqI&oIP{tstk7fU)=RnZ&fB^3zK?R{)q5~A zDcuzAYLJFaEBDNFdE*VD38<&a5-*qOZVQ66#ob*3WSzseP-7s(lEyJX7{u=a$IL0`kuo(x`-~A$;t7kvs2o3n;$J&;5oeu=kQ<` z1xVw?ucj`>>iCiYmdW7~tBMerBg6+x+S}Us;vf7keDM$dE&W?IQ!M1MOcUF-FolRO z^J$u8$KeY#9@sBgx{X(}Gx3xafXY&h!e>1}~@8QiSJ zoWex`(o=nqghnWn)k2wRYN}FAA*iu&-FiNB-#y&*v3uEd-PO3+EV)!xHJ6KPtSqC< zkpbEg(;9qR%=8_#d$YyhN zc6ZU$-A%Tw4cmtmc7_aE#zh{Unk%KDD#y|xaY*F(M7~dZCabKeIL_i)E*EenH+n&L zw*}IR1fB6|o-IfZKK~5g`IA39KeWKbUc$uPjX|1<=haBb#+NVGB5*B8J8a%_B{$!8 z8<+373OAR<$)-uSx6{?$Nl&VSb~jBXoziOhVp$sIg<~5N|2fgq%wF|YNSRwMHKq1 z+_sggZ@Q6d-v2(@R`o(#hRAT}&i0UVvt&{(Y0D<(q{uocT-(O zAZx(J!^lHvjGOal;tVgfrJV~>5yuuu&j%lTh<*F^VzeyjnXIx4|J<_$>HcS);^9C0 z5{wRCSdb={P-4>9l1d#^7)O4SXm;d#3Q^f@o7r{k9;S3BKVF1lo2+GR54s zaczf`63-UPYZ;h*E9qIYnmyND$2IS}nYL9M z@$EE`ZBY|)zGdK>sGl7I(&ZA}VZ`oLYq@IU7CJ2hH!jntfm1T@DhSl1^!f*FUh*=r ze93%b9Va)}h@vp$>8BC}`xZ!-D;7_AUS|tZkx%*VU;OF3@+l{cnNW@8rvPbO?l|3r zTc}xkF3rzY>VdHZla!B=XNiF#Kuy`u)<&kSou2-6eBk5%nx6HW=vmW8#e|9(QL_xH zDl6oZ@+)+Qu%~w|H*VQPn-6JQCz!eCr+_{5XPcK$3gWHzHa82^%X*Kcf>fW`yZ{sG~Lr9x?gpM59i6TsK zdFK-Mmts?B_G>n^sY+E|s&kjbR5GHJX_ih^z6 ztm@&?Ti*v)?t+v-=o)y^Ef?zxpX+WmpkbA-v}9`AHY3v&gsWhF`v zssg?ti65yECkY=Nxi&Th0iu99Vl!#(>)Foz8!w}OszPTaP`?ihL(R__P8pb2Y~za0 zKLGFF16fmz&5-dIOAAs>Rh;z*quG{paPU~PdUan5q-Tzo3-XHP4pLRBoV)1euC4_% zixQwF7QImt5r8JvbpFe4g^}uz*^0~ko!fX|<8IbWlS1=6Lt5$Eb%mIFu|?(qDKhXoAj$@R$v zF3wyX-c#@_)KSD*N*#174)=F$52xsE%&UcZ{M2M^bQk(m`w)4P-%UCm6p{wH057OWL6ue(7sYTVXi7Z2d^mIGH zIk}UKgDeQrW5u;KzfcZ{P{ZEQh-#rqq83|11DDflLai#P@1}~OCa-HL{VRf zq@n7Wr>muk!1w7NvkS532c)sPt3bL3a*lF$qq-$s=p4`89X>rs2QXS7o$q3w+Z&X` zXbUg4g~@0a0;J6T+RQI7S)nh@Bw%pyhw<5VYI!Pgq#zkD*jaw*j(&XrrwMs2HNMlk#^68||pTnfTvxn8~U1V&B@ySVMN(E-TA~m3_ z1hF;QAQ1=?pd~nLc6T+ysOjU^FJvNetw{}weVmmg6_92fe6gg<5v0Glb<&2#Y%Bnc zJPpM-zN&xM8aa~nlUOY2g;aeNiY+75?YM4N*P5Ii+a-TZOokNURU>kuXcwE4y1-Ub z|7CKHDlwyC!g#70Fhax&0|UG=KBI>SThdjj+nh6g$cn({?I$$BJ{&xzq_xesOrkar zi6u`PCpI=KDQ~o6u$C=7{Tq1g?Kc=J=Q&&$V}ugZM3lv%+Nkz1U)483#IcRI zS2eMo&BE3V&qV{Yv7t5j!V94FJqgm^+@|mOL8=#u2C3fE^%QCi-9#obF0RMZsRL=i z*3wt8eN3!?HW6xmi!vkP%4%Dz++3v(8)^3{jHNx~iB0m9^7AZL@qB<(n#fOE+nf#3 z4h%Mv<&*37aMjB7xM`PT6Qk@KKf&7*gX|9{m=U0w2A*qCj(q$;N+9~=)uz^DJ)8ZN z`p@-iprt$)8zR0ZLHe6b3!LrFCLU)3P+ew7#udbVSyP8_;?4RkKIiH0vkS;bbxJaK@cdt|o6cLJGm0>E^HgUgn461=9)>8nQ2&&8XxsT*^N$pTA z!uUzzkSeFt_sLk6O2`PgS{q$$b#*M;6yGZBC$nIDN*Ii)Sug{<9J{+3q{=B@oV&XS zkS1p!F{$)wZX?6L>AQ;G>fV5puaGh=4A-WTbvPIld1G>rH%5+f&>vxjK*g%^*{ej9 zfSQzZ=FDkHK$?)}^|fwJsx7>*gs`9)NAuN5wH0rW8Mbk$lwevh>B1NG!at({0$CHv z6_dD6GM8b5bZHo}=3{`#f~&^h%!g13pccv?+z3zVg~;oqb|{(80N?ZCeo3*)2DV|T zMV*nc^@Oa*rs;HS(qdgCQyO=CD7Raza#M*TNnNQJ*zhSDFea9CV1Sn=bWG}-);R@f zGjTyDj!+=|-0D5t(y@W=N<><8gXFqc2BTq>$yCHxCgRt_hk0%MIOUYZbgjgABr$8C zwQ`%LMI@VFqR5c^KS{35UL&UvQBqz>LJOP=Qq4FLZ>D0J3@cjTHg-0FG-yg3or0cD&>GULhD zNyMw?lWHNdq7gBM$xj9j@$!ToB781Es<*F(Fqy=aSztS9zQ_H-$^ZZ$07*naRIq9f zw{~n`MJXaz)9!3!o0J@}?lp?tX^w_PCNma?^J5$y8RE#q2$R$(;88_tt=hVZN1}k6 z3}0$a=+^5q2{=!Eel@RWnGFKFVge zG=p>kOAisA$WuyXsTt-hOWNysO5^DJfBhAF$?k@F!K&lQ?lH&RZFa94Al1(okY*wQ zX^PLUzKYx0H?XQ~D3D5)T2%Y|oXdz;V#Q_KXy3e!ePcr$96rI=)FhMDB1fmk7%WUN zT$~_}Pl13Ufr?!Pu+q~hpgo(1oS%$b+=>;`0xyqgff7bYPF#ajENN}eR(3VJyS7af zmtdBaCB3-G3@7iXD(#|HR&00Trz96$rGgA8!pCJwm0xY#5^=XAPMi#3I3F-pDKS*c zGwIiusFo>s9yO(AXA#Jv#L#i6DRekf55JAIb4-!<5Ri#>j>NX|<%gJ+8kr!XLzF+F zkUOrtj6N4Sl`^az|7PXHQ#4sVw4k;qYM|O7^xPS3@S`g zA+G=%Dnf+PI!d^}aZ~u*`f*}#6VktGRRgwQ^6{=6Jh1U{`o=4CR%4JFQWnx6t?t>% zWxpo``?yZ3MlI^i=7NHBRu{}gO$(fr1JzccPAX`24CgS0l#HXUc#3=Fg<>@$GLEHS zF%iMO$s)&RW*D29q2T)z0-vg6B*jV!z%5(t$e|)97z9yVT2aP0ib0iFsz!N3K&zUQ z&4^SG&|dTDta{va#g(jcWfC?-RUa#36UDGK*UXGeE(Q7@eHqcs|cSxyV!)Q1*QS!&KlDKiDs*S zRdL`N<@bjCPDB`lDiLJa7BW4|5W%akhE=Q4QT6Gmc-(*WRcvrj(vwsYwnVJ=6US*u zy;MbqF~L0nsUkBRY=AU$W@mRhD-{LO$G-lT_``!3e(fB9)K(z9r9(h!(oxmPBXRd< zG8O|VkM=vSXZvSA4%;_ExeOCU7|C<+2TzedbexGJ$FaOXCDNvgd5V!o-UukBOh!sG z3{OokUdmGw>+DyU@k$h^QWin%*jJMK+nD>(kkDO&!JXDd?pb#!oBb5os;_qI21ucD z%~p0dCyqpsFxJbykd{<7uOCXQnt)VV)h=F;He6b5zmm@Vcw#_(h-?hdqy}Od%vcdc zg$Gl89hsV7C|_WBdWPwmPr;NfeNDFZBSQgMmt1s0DM|I#`zj?VR3H5wDVkqhrcrtr z<7}-d6NBU!k&o+p$_48!``ml^)oip=q~#n-Rj3y0?1sRKu)5m8m0m}2sV$<&RF-71 zmQ+A`;F+iDAjPYm7Nm(q)mdfP5n`v)09)pYhLYX2_#LsNo$KkZ*>#YLJ1U8zfs{|~ z?i<+jxsSunO~S(0u1GC}qsN(iYd@o}?`LZ70Of%}%$W*Z=^Qe3{`knSBIzqtdNX2h zYMg>!Wu{spAJ&+Xtajv4u9d09<0z!_MmB1>!qr-l61>#F1Fi7D&&hg^gXyWK=Qfo z3wcttn#wq?Cc+Gzqr#Pswe?LoxV>3*(VxqYkyb4xJq zF-w|UA)P)*vZ-~#K}^T{u`&PJ}fErY1Q&GR|LEXdSQSbBgt};MhY>OWNJj7V_4HE97u5g9hKCqDae|SNVPcv8VH7r%LoyB0hP=b!@RRtny9lQiYz54ytBItusTkx|7w{?qcg5H^GWFwazWK zEe0tR2pKaB?e3~NX(o|;2haxa6TOpXjexuk~!h4SU=pM!w37t!aN^wk1BbNP*IHM8{j7EYl`M>@l_ zS79P!knhQ`}!Y z&KRVtui%!>b*!#X2dOOYk{NL{hXU#5FMbL(_d$CG<(|l9DsH=KAeZYZH_n04DHxrG z!y^=4-bXMv$@tL|c$0amqf@xm0NV>lVX9Gvs=d#YjaN3{xa6gd9T8d~u8=Njs05Xz zSX^3!Of0DaX&Oq`ZPFl>?5-s1WR%5n1nGOH>Dv%vryi0Rl?7b3pk%wM+VW?VS zN)kg=*?C=%#bHRfLrN-UEW8}5o!BsZY$3kO3{2n06`+PvW(X+^4s&eZeqR5@FFCw# zAO1{%XlfcN745?Lfts1=*d~GR)k`vA=o1989fY(;usSqZ5B%HRx3PmP{Q}aN8fM8? zB=ll;mcsfTQaA5r<0n518&^RlO=x8lc_Oi-OA1mMeiX&-u4H#R*EU&FVL`#94M*Cb z^P@MhT|g=xKwDN@(jLt3I&W}k>cnW2Y&f$ z4*&9HrjHLYIW!o%v9YfmX(o@vtyJp69Nn=ae`O){+Eos!2B~l5tS*;3M zOLy)(P~l4_EC#uRivCrBLJ{&+q65ds9~tD>z5`4iJ3*=%Vw9>x<*Fizq`Z(+Xef`z z4GmICK~Q8-i(_A0 zAf3zI)EyG4`%~@E5uTJ)EQ6tv$KK%~_D_y8VusAPHU&rGP74cL0aF%?Daz)ugG)cB zN;Cz8ZiFT7SUyi}e4O!j-r@M$Z}ZNpuQIiFKg^VIWAUvfJq86zbuI!_MbOu^84c1H z2=R}y(1pApApJjf-p=kI!@8P|NiEw^qzQ?W1*F;gZ)Tg63RZSOCIhyv-7YOiWzlMP zzX4LQq!N=xbXEnV(ul4>dNgMsAl(|fyJ1^aS8@_6iMmEg_My(9SNVXXbe0TFirH4; z0!oJ5s(83gJ4_W}d;+Em>MIA3v{$e8#_cUQ*3EHOw`LZz`O)ZN`=%*4e5(!|lN^ZXR+M=^d>c|>RT zCH;S(SmNO11ji?*7%mm@GHJ@TP1V-Pp~z60=n9zfWyh|p%G5>yY1^bWGtKa!LyR1J zho3(FIF(~ZVRST(H3PL+6VgH*j7oJN2C2ALazgJ4q&COfZ4J`jjX|1CtKmY+52V2? zODZ7k{>b~;EFj(5uRH*uQ6^kq#du0GeQ`J1ydag^Ef-pv#TDl`X*i9ibt~$X4l$^C zAoE~`#}qijVwtF1qcWW*ELHJKRlI7AVx>e`q&wHHX8ko+klwjPd0*NCVTl#&=buli z$P5WcFCH?3cDM9SETN6W7rHPl-6@I@BpoWij|L8Nw3uh6T%qLqIPL8UoPPWz99xm0 zly)&&N-6Rj6@Nyg{E*uCBzu4LD}Mdc7a2Zu5XY-h9UD=s8CSGfJ&7yDbJgdhNoui` zNR$|2v!N6ZRF3^@ENL@HKcy|H0;$eiFAqy9G3i`Oin642kZ$Q$F=+#&+H27ujU{W6 z?w7fiG_f!$P@L5oqe&L3K_FCpxN^LDIU{jiRJtIRcf}4yS87A0S_Hn zAG+AIv|}a~0n#H!2BLNAB*)nNSdO$neM1xOywp9V+e27%1G|yG9y}BgH8G=-@owA`w?e;{wP3~hiYq#-2f;9F+WmD7ct{cas z2}lFdfu;pc*-ao7+MQTZad(?sI%N@02hv2{LcMPcP95m0YoEmV%CI)iGi|DGC)!bs z%ioBw72u^Vs&`v814fzy~6s0#Z} zjIeKPjB(eYY{z-@L~>nI-?cKGlu>Mpv}mk)6?$Ehp@Rqb)$`Bu){DPj>Wu@CFGH=S zxVCmE>gNGM#*@XNdLESPk%71X6K#+XSSt*oAd; zp)6^9`gSBSX*36s&u2jbU+-bSX4?h%Mzpq4;_d$ZQQi1Kw8(lX-XvM6O7#%QJiZ!IEU@Gv8L8`hsgNW`-2FI^Z85?GD;2qxl`HTGO`4h#<38axN-8f6^?k)tHN1nJF+{ z_VAoEo@uM>sN!lWPG^7-Q~jJ!YLo#zjzf8TjG+Vj_|dn%!ST1=gy9jaR8~>SqMCYGf$AwEk>Dj+@HX4BCO(p;KInxdB_NSiIG zsbkV}4AR7kCb|ufs6@3f_;?vdW2iUwpN6j2mZo>x6~byLxPJ&p0MkWCq)2u-&Hf-kY^WTHOULkj?_B z3WDP1hhz~aiMzxdu1_3D(iEpq#7`KDOJ_yn5N=MLR6zQ@M<3;(2Os44@#D)2r1kW9 zoJo`WhrW(v{(pPL1Gle>l6zpH&Mv# zktm2wF#fAw@ZA)TaLMBy(FY{mgT7&nrkB9g}t?AnntMBNdaz zk}XTdI9gOpdj8$r#F8d}(y5BsWPn+~tv~kb5 zC9PpeKdWg{bZiFOY`X8gnN4Cz-{T;aI6H|o>!UZ+FPi=kySwKLqzdy(YD(vEcb79r z)%|GBaw$Tz&a_EAR0s>BVU5=YCpk1-;DmJQi?EdAD7v2%L}hS;@QH*GD(9h$XE_-=q*0{Apf2ew?>Q zD@++KW!Iu&2@zeAL>i>xCP_b`8~8Y-0xN8jgFk22%|vaGAxstd+8gzRlmh~3@Z`)*~O zh&cCkDusjhVhN@N(%IH)R!q9Qvb#;bu3~~1iUlI|(6KONpfthHq&+D}Q+6_x9X-}S zIG5rSE5f{J3>hJgsPXw8m1D>FhcEvL#RCVRP*DAaM%5$oByX(KeVX(jWzQyc-o#&u zHCV;%RcZh_bD`_Dv50jtCr$lMeKi!{XSFxPmRhz30cj5)I*tGClH0g6%F$mjNf$j_ z!@{=&q?XF=_TGCdYn3I{AQg#-CFky*=fqJnNR>uZ^WHWmCY|lK#59$rr874ux#->9 zjvJOfPj&k)IG&QQ-5lBS(3Aa0EBotzyuMEo$dlpi1Zk(&#J6qKs`K?I?b$MT~$yTPyW)K|4IQM7GQQ%^s6)k zm9$D0i!?SarsjVtK1?FLtp^K>ev;@Hd0v?=U^6K`d&$jg@>8s+Kvw8=SV|SY;7Uwt zvGQZLu_m#kZ7Ib?RvGB1t(TS@1r7Wecqa$;iZuYh6+_&JFBEl zspPX|72rooFpc#IeR(jD4#D*n3 z;m=0n=wh;@=NmdpclU$M(mVsNVlJR}U4!px-|M*XgKJ~2b1XoSLwOH$>i7qC7V-rY|8>6gd(kg?v#z6LJK9S=ZY`*nZ1k*AQL&RTi5^}Qk;l5JFwZ9 z?O{)MKilk1w%Z-_lcLMl`nyUWM>4k}?%dQosj|SyczG4pCJ8G2c_k~Y8TEeb?s;MEu=Rhs61=8gKQt5(u^brB+LmH%e_r4Wv-@bjG z@Ow#V7x4m>MQadLL;RG(kP-0aa-xo2^OX3Q#G7Jq#U)l!lJR~ZZf}FdBqaS|gLn%SPey_@lM-H;DSR`+|cu@*Z;?YQhR40r)T(3fV6mj&` z*ZB40Kjxk9{}8+8D_Il)sC2;uMnIt4V=acH7)G&jof=mdFA!x##jTatGt}b{v!a@;`W`lS@4=Zn@$GqDD)?u-(uql`!tZ$RtRDmfQ5 z2ugS0xI!gX+1&)BH?dtbj`}(YvT5nGQvIxF0@A%tKEZeY;!lZ2PAoW|w0SWuWp=j( zQhnt`h-?{yRFlG@$Y92RSEnZV_1F*tG8fcz2?U@r2Spg>$}bFXLXS+fLc3Svl_#I( z@xTB7;KVQ~v2L-(t$|QzAQ=+Ud{!&j=2K3t9LiouieVVOebw) zMf#?+0=<}68OJB!l-EnSR_WPcGl83+YWf&c7f%N>C#Iro= zA}r}!Z@&@kxMasNaCa5zRA^QWV8VoFj~?cg@eyWHDK!p4Wp$OS8xQA=d@_N@8rx>_ zt+)B_U-~i=`wtKnWgd&r{gU=t+Qkb4Cdx&^_B3Hpl07*naREnB!>Fb5}^pQjC%}C43!#X;TNy& zCc9B&F*6h@6&xu;DUe1=nsP*j2p>Fj+JQ|6pMQpL|H&W1_(%(+=Lcr4L+Opcv$(swIybe1@KS1(%xNZ)wlwdm4IFI_eum9h6yQh0N6hUX3+WWup2 z+FBOH4m8nDM&Aj0sDqG>T9vn+dWuKB{xyuLX&kRctz3%Nyav87hZ=6Kc6YV=+h~mv zhLB`*dm^}}dz%92ZljalLP&c}n#My)jvj0)z!ZQwl>pat6exs8Jd-k*Ov8qouA=Lz z9dO-l*suz6Hl!`p8W%_w*b|U~Ww}_Ug`u-pT9Zde4k8~aB^-G(v9xZi*A$m;+cZHrMdhsGa`ugjyM!RlTJ~#9L0`x z154$76cw;qqC*rFMuz$3SN@!_mwu^uyD~H>5RR@Ye`sscAh~ORianOhumT*Kppf$Q z*oUoT`0edCa;4G5nvzLZB~rp{XQ&aQ4X+4^8{0(D4U7FfsD`uudgMmCO$q3fp^)nFMBI$EJZ=Z>|A zumwv@}zy39X*WZAwt2nhXNy+#X%w4oK_vGUnK>kRw0u8SrhmH9REgLH~wT1FpUSW7zXm>kKX z)dIgDLxk7NBaVGC!M;_3(J(xz1oP^vFGss~?_M?_6(zu5&E$Fh@F9+e9_4g8&g@#G zd{ZTXJgTh7rm+Tx`SxG_6^9>v6lxU}+sTN4P(+$#1mQd&m8GtdxTdI<>y_UnQ_gB| zWxA6Ot=Y*fnRWE#p{*7v4z3Ih7EFm16{U0ehi&0I7Wu4=vAv(Qw_k_xf$L$*YCQ^D zSVk(t+*Fp4K31iUu47qc6%{_4`m9W-n!1kbD(#qv(ABCG@`==|RC9Z5NexM|!3zUN zd3j=zQaY`a{V$}uDU}-jkNTRPEKkvd;OxEY)MsYnh@R%q3=O& z1nmL5-(AHgwqMK6N}AphxN4x2CO;%44@Ej4VmkB**L0KFv4Q>%+z7W_2isOdc?#On zir^>_v}PS>8z=xzdRUcE+B}w2ULqsq6<0X!Ne^Q&Y_0FG{6RXCvN)PSgH)JO+t;=% z=_!G_2#~(~%1hA|mtV1@mb6a6YogI6%77z5#IuJFvbUJ$L>N%ZWEDt--P(tMuvO)F6I60>sVVb z$yIfns7VOgYH6Svgs#nim&dvG60ZE6kHfb0uznS!q>LkUCDHwjGr#pK8&_sy!h?pJ ze$3W&N+^nr;X~qTC*wMmEtQ(lX)LMq+NxS|JfF0)QeohQXZiLY{U?|jQx;w}yZU3! zeA4<1o8%mu6!#>Y$f_|DX+GO`xf&w8svOMfC(WmAj-;anK&rijc;C^<>=rF>es_1N zLE7ZlHAJZ6#V_97NEoTC?%VkphN4h`)Keg}NPEKT^f8PoRx!^D|M(4Fd*pj?Vn`*7 zv@;p1nx_V-zUwEe{GrCR%hc{R#mhChA-jhAR$RiBRyVzc2uFFU(o`;`m3U5wlsqhh zDJvv%#a33_eFJTG+^A=?ID&ksj@TGt`Ri8lnf}GEU~EFUr2;&a5Hf^IdwP&sF-V1*+Yfwn z)n(k%yOm9~6geR-$Rxekbr!{Rse_7Dok|-N*LJb#o?FP>eG_b1qvv0UOX>7?LD~#fwGBz)NR57!OmGsD9^>W7aY`vYX5&IyQUU4VbVS>oH|WNI7D!JM zl`cbfcOgqU97a4P1C(Z_851Rgbe6zyutHO*7Ni0nml{KR-{c>^^d}$#mI_7eKvE@o z_<#m!!=aqdk_t%OFr+hr-Q>7u{Vs0F_OsDXV;5^`PKba>Tv4f^iV{T8f#EiT{(Enx z_x5XG&kk)xMfJfEITziAmKFh()5r&$DM%A5t8Hx3MRQ?6x_yqj+fkK@d%3Sr~B(4uG7Chd;k{ppo_`jTt8teU2;YGGC+X45X1 zfHW1FOxG$*WDGJlT*~^-e*~`HrpG?mI#?CUUA46?Q%V>??_rSUnqtyhJJzzQ5}-gT z8b`93wLp5>eD3T&UL=-OK$=YI-d8B_{R8_rYD5%WY4VnAjE(CXw0Qwp-@~68rx~G>10vUxsVPQVFpQ~xR5SR-H-e3EvaTC&vti@ z^YY|q?Cy%Z%=t?k2}qSCUEN3=btFP$Es&l8K;@|y2}nh6PtP_n**i1Cx8Hu9v2>bp zDx)T)8IhwTM%rpZsQ0Li4)XV3{xTDhve+QdppwF|g$^v*O+X8lzbYwFeRPe9b#OD9?({SfC1UZp!(KSz3(vo6L zrH(57q(bF8&4kN$2hv#CLDfQ=W6~I;GCj@^kjlwRMm*qLXLnm5JwqIx_UR{sRFoOM z``z!VrthJ_L5!tN9BE>^b|ZD^!Jrlf+LBr}d#9)Q&i*$T&t#}L8GJ*MMmBB`k@I{- zsGr=ok8gbSt4!?M2jio-qT+{75Q9_?nLRy7l>#6ks{;7#6+5}7cMF^IuqJddD>ZeF zMaNV?ltfLbw+;K|-Sq#5&%?$pY8ib5OL)AJPHu1~gp_+)kj|B)oNaSwXLp{Ji@8=zx_B7R57LJpeprn@93CFJ zFd&s?ZLOfGV>oF&tAr6%!{F`dDZcm4+e`{b%`}1GVuU7c7?JgBbku4L{N!gm{I`Ec z>G*M?nF$e8QM1>yFqu{xRO9aEvu3d+l{%rotS^M$UAddPyEd{V551uSm8zRt?`<*Xlb6z{c1q&~{2Ksp$~3x|&K z%ESo8behmkoi~t*=F==oI!{bmXo2($?*9BjWdHK*Z!3_Fj*eUikP2l^Q)#43p<^qP za->1}*3=Z=k3m{9G8&|ji5rAuf~o@P{wJQ{(f{&asSFPh6=!hc0f{w9!zz&KnJ^21 zRASP;NQ3mA?#*nSiRhAcxN1eoEC@)a(k3(QY3wVvvEkDnB7MjER3;ZIChsSiux8_} zx^B+)adMqhU#wGu^h7BAq(^vVQiC*d(lJO4mCWg^lo@#8xpP8h5Rf)o(&ofbDoGsW zTn?o|a(CXqwpMm`frT)?r02K)`JdJ3!}0O)#t3UN2xO}??sj`+yGirPv66(;h0BM{!3IaOI2}u9*yJj2-NZXN~ zTVWhs!7UwYSXuT}cDEU%2c-ma*9~m@`~z^w258S}c4Yj}A{i~l(R_&`p~QXro8MF* zot&Iljv$@pher-DYT62t-k8B~&ufFwNp8W6s1k+QPl@gA0m>RwsIiZL? zNi+7mF0bb9>d}ay(lGjT|K;4(vx%K~lRjxVDHRp|N{-2R#$sws7nlC)k7D0;HLPC= zxm*)So2!_yZ@R=FJs!aG?+ozT^qA@z!p+9nU4yg&sn7z&k_t%2Rd>$W(gNoL>58Jq ztn6+s#i4XaZXS>(4o3^5$#ylrCH>YnzNvI~CnuH(NULE;4N20NNS*YtL;D%RMBH5g zsnASQMnr}x?(`Ht`^SIgr{DS)j6#8^Tu_!Y#8(P~iE(SVyK}8+1ElFNQd&m0r2F~Q zwyU|Kk zclU4&p53>P{k0-_$BErtv7~cB`iDxHK@=3<4M;mN8kV$k4ZVfhEK6EyOL1@>kR~(i zl=yhdlE!y-{+RTizwr&FySqF=nlJMBz&l8sr9f(EOX?aSS)+zMInJ~H?H~B{!;dPy zF0s3NYLK2B5(o!ghz!zECPR~M$n^1vEmv}NCCdh>lNL&<_A2Cr;haU`%1vDM`A@(t zR}tl0jFe1(IYrE?gYB~oNM|*G&pJp`caLh!F@#@*8fbN(81USIy&S=3#<2-Z$?obM zOP65E3_Sll-~J;3={SV7a|Y5|JJ--XBe{aa-Gy>{W;RH-uZNCYy(hLl#k=M1&RZvy z63jn;Q!ME+2I&(=4sp~AshW~FaxnamlnFV@BN`pyhhO_U_I>X$rA}|wD)YFzNyfE_ zwl3mhl8ucO>c!m^;cMaUUg@sj{;gMWZ6(9Tib=LyQ(ZCwQc;i(-oKk|pS=%m*oBw2 zaGYk4#-qra5p~`{s^_>V3Z4OPO_lk{p?5eT`btt?mgaz1^T{o~@Vp0WC$uDTB(-ugZ7t8!5m%jDj9Tp!bXZH+oqaoW_@4}n|}LVxPBLY z%F;uKo3qEs{LH#*dVVaa?#t2bsnXLPnl>Ug^XhnkpB_HMaLS_Sy3_)pDe5v%+V|1A zyHE3-FaHUQORHM5B~AKW8w=-jt!l#m>cL%`^3wZDUJ}yVKcqsy)Fh>-Yp341-#zU+=UDjHvgKHpvC%GSTNGB-K?n{)W(v6-+wkahzsLH! z?^7UkQj*5$2Wg=JttvC(pLG0={V!!AcqtmPJ66UZm6FvpHkJV8XCI9NKJh+a;%J~UE^%eP=e{JVZX!Im5$uiYHP|!m z-Qy@Yx@?ZyRo#8_L0T}`H1kG*)P?QXXfeaMcl8>qOk~jHhS<~)5yxa(UBE~pvwaH| z{r<05bJx8w}0V4P`*g75zne5z-#F|ijT*66%#SjF2U#=JDia_Y+!qt z31{8`nELVaf#VL9I!X?kK=nfV6Zi3;x8mMDkNqK%lq|$V&OzD zoL4moGpuq%Sqs>qHp9A6209I3bE$#ychASPPrV-)I|8UG>la9QWtA5^xGley4es!_ zN7@ zl*Z8-iy>i{a9GMg-aIS(XE4mR@zPy)GN3Kq*eEnS?XT#-ToK zpxki~awyrAB+W#^0@8|i&&Nc9bY!)tyXl%rq--N<}@6s~Lw0b_it|M+$zmMNQZTj>klLcTbvwY-Q9V&=+9&=7E%n z=O$X5EOKT9J8cIm8yfM%aMqdAY-x0KUv9CKeH&wWrSe=>b>{jk>C8*11VcZ z>H35Hut|Lm>spwYg9@BAVj512k49}<8kMYs=%|kCtYndmMy1A4)p^HZ+$Y};3@h&) zq+Tggsi@(ZA^Wo=WwpRt$vFDK53x^yRIU3qIuOFkjcs^oMup-EY z=?%9a2?jzc&LU=KP}0(hCvUz5FaPs4puG*Cx+~TA`)QNvoFc=(2!|kz;Y0O@<6V&& zls6|)5wfHz22~7tcatGYY|;Zh_kNU|cM4EjrWi+F%SLUJ`fV{1#3Y$$2&7Us`nFqd z#See^thNcrD?g114T?PvONaJFq5^LMB=wT->yqMgr}KCp+={b$`XO+wXzN zBG{=;xVc2WB7K3(;PDN7>@y9kd}R|4%n{Q-dB(*I#BuDf@i?ZY9`%_phNtPSvXH2& z!uSuI37mT*FkzVFkQM_e|0-+49#MBSH%DJdIrCDcfz5VSdgZ*)(1_(*cOVf_$q39C zV)+(jL>545?c9lnZu$e(J@7C>$s}^A4j57^$}>27bsQB|J3iJZ$HJ+hQ8;((4ADMH zTazfWELg5Bv1Nj^!!)q9B7_-V{2;7%p8yQ25L=$U2T7#Y&LjVIS%}QnQDA?Tq`6E6 zx88aye*EJf?|UHSbm)YEO%CwfhHZGgr45}djBSOHb~8vC9VkyGu=FlL6TQJ+v{Tbj!v7<2wf zi2V1lFlJ56TXT9MQQg(^U2z-+@7?tZq$p&{&1z4(`pJ;XCIBm1Tk*=~t=OKq~ z5mTHPVr@y3va6h{`tz`*BfYyVb>*1y#SZ}|9S+phNUID2lt9gc)YoX4eX$Cp@pYdNJJmE%>KZ6Z+o)qvvYG>N zeC8axD77<4tXYdcFSs1;>no)D zIrRgAlznGJn&!dc!P4tGrxrUV(W@#k3|&q5zeV&@wTIyN^0BCAHK+C@N-PCZs;_Cw zKwHE>TYU`<_`(N)W9F(lP$30UuZV@JE8GJ}cPG*Bo#5T=rtZEKAPuYtd8VpViHCtE z#`Ri~cy|3}Y-sO*RauF&X(MAK5zD2p`N?PS$hE%)8k&G)3dj+p4AB&9QooYu7YO;3 zFTJmqU&;x{wuht%&O#YZte%WhYo}mbv4h?8BI3fgE6i{x*0f%Xt&Y@XY&73*8u(CHdTha*TBv{lJKQq!BH z0xOq>mFz@)ycCcB{qIv*LJ@CRmavZ(wJch4mFCPPy#c02^0Tm5T|$_p5=*^U`VO z&xBz`#-NfPoGX3(`<(#Nu8yM?7>gG_=^lCHk#DLb?QNi$Q`!PxL(0X=TO08D&Rs~d ziExPS{S+d(G@4#pj=Qe87Fe@c_3@-6b$bD+FU}{j!KX_V$lmI%N~I1jD+pHMwCZV? zS2qb^*Fv*lW9qplVmL!FqsxI3b|hD2T8w<-CGW|4u}Q`DE~?A17%2;OyD-_`P}f*7 zEu_K*S}kB(4p`sOftS{ALI*6Vugk9CY0E^G($?#9YS}hQ92?O@C!%d_`1fyqgN@HW z541K(u56gawsTnlqtZ0GDw!IjbOz~LB}hqPI3hX{pBOm{)16WYQ?X(OsS}C~Wk_ea zZ50+;#@FE3AAA{@K2iFrN@|~1z=HQ#45WSl_XWnDzJDixRC9Of-EC%9hJ6jBS;IgF zfL&~V*qFi#8#bcJQ1ym#p)_KQ@ojIwpD(=vsiiA{W>RkDNRSh!YtI{@KIARbL?cawRd9Vfm3kk=RXF_84pxOC9Wg&eGN;OlTvZoUJR<9 zLCWwLt3^)-eRJza6Z6+iugtNc|BZ`wpOu+?JQ&Hb(Ai^9{ zuf7JKi{NXG8rWQBpyY@dIQVOy0>;+?v8V#6Dw?6Xqf?Sf5elzylP6^d%hbwiH3buT zusDCykL#Vx&J)+MBOZE(iz5om{d0w z(P$L2&pZ)zO#U8KrO;@4)sonL!gGo!$QIvv2dR>1l&CqwM4E-h02z-pi45M@x)mE5 zTab&!kufaUhrr~d=f^gciW*8Kr3qDX^JYAC*Iiip$iqNevxHudO$#s>2GN}+x~RJ{ zc*+UH=is7MSrSGhnH3Vl+2anz3DME0>u{ww9NAl>GV<9orXj_{H}VLzBQ0*xHLLCWa5B`S&(huaPgFyBnw2_dxoeg^#<(%s*zI0jW|SRgcm)5~{$~ zde-1IvdBepC^2%V=tyGG&Huu4H{Ss?>=fgMa>ueMdsL64eA%HQE2}?(;+M2~67eK4 z7^rr_7-7axAFaaV+EJKZKLO(oISB9i_ywq#H$&-cIn~yJUQH#*)WjC2h`0HRa~A_C z?O7^|LY((10MdcRz)~w6MJ>(Pu&WV`ok?lAk#cE&vP!)wDXP>&1r#!Wtj-RM2!-&< zLl0rm9k-)(?P?&|A!dQpGqedpwR8nlUMUbKHmQ>8lH_dyWe#w3s1|3|AB;JuLTysT zmlZ)?MAO}o%&WRaq} z3ma9PDXe(p2|W6Tn~~bEQ9=!-oAp5IN`{E6%HE`)!1J%H#gbP1-!n`=>R>5MR3MBp z*TgV0j>)6Opnl3kob|bnn`CyP}(8?dFl9lJUba7~7znDY~Y!}?GR_2eTpggL8CqCyIAN`bAkOB2AN4I8l&8MM2dh#4+wl3BFBz8ZJ^>IQ6k{dKt6gh&aC&LhX^ znndCObs!++V2ERb)$3s*W<`**(0ON zrjEDtsLn6~e?*)tDx54{y#IbY^7}smT*Sn-%)+s3mBFK{DY90um%^t>_2NkLyt}+@ zK1&?HyGp8YZrwpRJU$9l%^8$uS^xC0wA9cVGqFzhTU zlR3ni+i~-iKgar)UV@Ws1#)Sry=#y|ng@u-*$pf~lv@6+tKnWKt1VK6_GxuBTAEvs zhKtH*6!EfhoO#w+_`-!3V&=TL61yZo8LHs^oRaxW4o-SMNIfCuBjt&T%cA*-R2J<{ z4lA2>U|TkcO`RRsnMorZ4guj9!d46hD^;)>q8AjFgaLAxsh+wj>!oAWDm-?}Kd|Qh z2PAEdiSdk^<}B6JSi(hlADilg?guH=T}woy3cHMhiDRn9;k4?BI5=E`csn`4x@;<7 zI}Vbrjchz3y>e>Lo{zETo+LeBvJn&EIJ0*1Z3RR%7D}cUTlK#SWtZ-rMY(%N2PVs# z@Xw&*h;hzun2|8z zDFZ(j8biwc26qn_GI2l?gb=7Di!1YYN=tG2I}g^;@Fc< z!nq&#Z;YQl9c9CY!3aeVvBGe&HX^2l2#X3*P%xt6b!lV1IR8dq(&kLLz^>LLcDA&j zp|u$aIOs5KBq^Eb-POKpmt+9uiiY5tB+)B%lx1MZ_%X6+Ni@i8-ipP4_#4(d^)wRA zjR-R#K9h#Y3>6(qChtQAp}Wsp2UDcPjO${!4IGX#oHKd`j;b7k>JA&R3`0d6r9xBW z=41k>DMRDvGEDsZ1t>dqHc(v-gu_52sq(s9P>&UWFgr{2Sa+Zvql~ zxkM18qy_%#pZ~&-$lYyiRg!d{11V=PS5ym9n0mwi^=o;4%Qn2;-iS`=hGrttnZov$ zUd3O2_ETWzHXxglObjJSZKd)SF>Lfp3=T}!UA6kCMm9(*q=Uzbg)qE+Easnb3g*tA zkEt_eB3@CASiBqvMPP-(h=d{tk&WYBR2(cW(3x@3mQ0{Ekw9xQfsRZDNjry>Yr|%D zHq%DdVCxNbP}77U>0See>NUd|(&~{ORvV?ZgSg>h%bJyV=FYpY@u7uqb~eH=sruWn zvuPPmTd0C66)Hatd2?AwI)kJG5*Zu^Wrm4~b{MCXjK)c|6L3(Z67kNQ*rLo3l0J5Z ziFj!o+uB-?tcap>+6Wx{-H*eVQ4f@s0#Ttlcpqi76QKN0x~v9S9eGLmc7)sDz#g27 z*;HC2sc?4*(#IZqq?=9pmP%3yxOuC*2_!5Pj(M%U6EAPyip}k9QV7gUXJGAW!fn6# zEjB#)AAotK>|kx%$hk}*SKdpR2f-xfBDKN>3R3dqLZu}bUSE$nN6*KhM;wj%NmG#t zN0BOt!3jqZ3P)jC5y_gN|5;*$j)PP-izI=WO(UJl3h0b*2yV!dFbZ2Y@(EPC46h}J zr!LYmj7xqS$vNGDU01w)Xwx3%qSAobKtnVSk^bl0=m09z@% zx^+8V-MSea(XeYCHzSIHwC6QXDSZBQJa4c0 z{>byY;V`VyQW&Li9DB;?IP&&t^wIm^na0c6vdh!BpB)#LQhQ!zdpLQU2{IjwD%fLHB7_{q4g zFpb(rSKy!zo{jK%#{e}YKqL%EITzKL+*@+;J!;o&2&DTuNL3g?GFoIFiSH5_+eOl}(3o+sytNrm?c9ns7TKbN+O-3Z{Ozw; z{nXP)Z`_JdMoWpp+t+Gie=G(iEQ>fayfjhmRAP*h)%sW|fzlEoa_3?wnJ@{5oP09I zOg{hA%7 zg{|vWW5x5&;f-gXLt@=}#bHjQrNf*YEz+(KD^{Mcz=tNHdMDq4-_5K{V) z0%)Gd;D0egAl|jjvsn8GY;HH6bTbp-I2zV4Gmb|)-2Tp*dONgr=P?l zx7>o(XO@Wf(_#pLQbbb(z2El~NQF|zsb+?RKkHZwk&vHi0Sq^=g2Bugm^t@Q%$R#9 zDo58L7q(!BO>~+r+QSBH%Y^Be;w9xrIS-W0W(%>M&Kr^mEJR4SPo$7;ZAG@T9WN|i zh%IYZV%zeiKvSdY0%sVA89b+p92+NzB=zeJK7e{6Eblz>sqxfChW}qH#ZxLKW?{0~aVDdx7nYSP z@l_T_s639*lO|%u+_|WqG8q%5O_5qZ?9|3$VosJo)F355H6?+B17#mZY@m75Hf&$B z9;;qmimmI`prfe)nXMavY!b1`3Z!;6$f72$84Y%CAt{7eJdo<(uSdZX_^{WGPzr$x z7nqJX&aa=1Q%lBRL`w!0G?!`Dnu>bJ1%`Gg9Y>w4^*f>rHOI|G%_q+VYD<9XI2g*)H$~z=UyGzoC9)7?*>BN)v0g!4K33=4Zj__g@(o#XK+>9S?%>b|O zY{v42jo6iJLA)%2WzRo{JAeO2IIGqH?HPnAeRK+ymZUyzXirkLH;{V%;=FoDX-a8f zSRrI{OqCM@&-+Q@YY3rO47o%SWh3e^W9BT>&zO#~spEmNQk0dJAr^_jV(inK(44O< zh}_)Ri0vCUqix47Y<*)5+PCjSmONz%r!Yn(z0sxl5*$TR2(CnaTT|P)L~-7dAgT#a zR%CR58pFUCH-z&>9fBiDM`2<*B(^BqaqtG+kPBPlNd_{mBLBBm#bD2yf+-(73plVI z7&A4Oj5@1A_p$@>UMeLxkv&?|23Rc)uN zppBEVfXxYDY2y~W(Xbf_Cyn-&COmQX-FW?;2Y?-|u+o%qN_uD#xpvtGeH8(ds7IT$ zpdM-{7l=Flay{Z&G7Xs0!;}>?ZCK$LLZK*1YO4_*H4JV^4ADpo;cx_|NiMFI{46rx zh)gntOlLyWTy!LWR0haqMKDs$Cpkgxv4^g)<#;rI=XQRr#yUhKpSz;u!v4Ct}q5PE*a5 z%S)7s>s?wB;(Z{^k6|!lMZc6GkiH#2+Ep@;C+{gP+XSwCQ0=Xc}EM`bzUx}-#OJKsob<+S|K=O z=n!OdFi8S5%c78yj}R8zA`L& zZ1te$xQ~ph!C4HXd3BR?K7!Tzh(YH;Y!sBp8+RB;d!9F zQkn!sw?!m>zux{{mX0`YJWg?0ju|c%=0u0%xatX*9UqCBv?&C7dUNS4lK3v$wtDMH zBxwUR67Ej%IH(q~okyIfN#tTUfKA?7$)m;aupvd;D z6q7pV-~6g-aE({apnR+&Ptp)KPhS622B|L2MenpMCgL+w3?#M6_&ACpu9R+}09v?T zE$Isq-y1tG_DY9T*ijiSW6cO=Myheb$SIgtG6I#YS(MwBIIQTr6P8qnq!QL3R^b;r zlS87q6rrPMUY!h%oH<(&a{xrg;Zt#XaIJTroMq10%_M-lT0RX+rMtZC7R5z zuS?PbNLi{xg=bhIgp)sIT2iOCA(h4U)(&jgx&u45ZNW2-Jb))3c@WL3RtX!(rEQlh zNYk#$U@_H6FABxgs)2x1RCT#vP{H%5be^=){ApD0e+aNY^MsfwHI;i~z{I7KeEUkBCffpFBv5Q0lxJGd%{AfHg0s z3LVaw^gRY94vy4fUe##4tE>)V>@bGeA;dBTas>e@^hY7xt3`!1j2i3W7;(~J7)vS2 z-lMdOLnhK;#ViWBI;p^;R}QJWy@K`~22%DLDS%WJ`3NIrTS(g`I#LdHwKQV&#$|Z< zrRQ<$KmLjJFTbLQ21$B5Sf9ie+mM?C)4Od&Vi~;+agnf2x6}Iek)(FdwpORrJYg?1 z;)!`#Cc5Z~-dT0VcwXHt*n3)5n_7*|tK}*!Ojf@+`Nxfn=qr6j%hVsx~&!MOkad)-q{J$0X!q*4UvKbjbXsD9Yo+@I6|0? zN}Moy3XZNAgNZ0XtR;yE3zwP78y=N>QFU>GGaU_~HRPhRGz??*1k`=(bd=6L0A?ji zqcBeFv5P$WTkKKo+!_=__8)-yheyvDI*#6^Anp3LwWKMyloUw$Y0Gw^VdqXPS+WH8 z+MLF_B^wKBo%~CqG1T*fKV-tsvV2Dv_XwBRJ3PMLS_P7 zWEclETtsNUdv$*^Ap>o(5LTyJ5Ib-@roI0(l%97CvLnkBQNcA~>XN1&QQs>SJ}7wZ zuLt=Tb-&|CBMOD;J@Ld7NbPDw zX=N1>Ep4htsc&R-NtL`c>MiDZB7}E&4Jf~~^+y8t2uOo7)dQ&(viW<^@lF-*@SIah zJ)k6vIR;9ZdIlS#QHlfOqi{&gC>$86!Z;&_@|2Bu#zjd^5l3{KiWxd0g<+sGVq!Q6ZmV=g!aIA|=gF|`EHOHK7!Re4lgqWx12?%whe1nI5+{1<+5$xoEJd-pwe zx@Vqo=GzXWd0_g>Kzb@;iqtvUP>zGf#zs8$_~W?cmYea+Q%@t8N+Xv{=Uc)D>m3!d zNd1zozaZ_R#tc-F2HtnxTkElO^a3H8gI0&7B%-=|ER$};3voZSQqkto3N?J}f zq(RA{Rz=ae(hzrV((Z3Z2SNI;fBX}d{^U}$vtiR+cirKhb=FyLOOX13%HK7iKozr6 ztQT&bi3A>h>~Z}5rkim8op&P=iR1(BI^R+=Wb{A;?M&u==D!Q7r$JB^QFr~j^r`L^ z0jXAPb>K$DQAu(K9ELtj16Cv?xu;G?3e^Bc!NL?&;ppL0F}b7)Ih?C=(YA1vR?bR9r=wJcr zpTnZe7zS>-;YM73*#fk&IQAWP{M$X}oO6O}cNgyG?p*xMI#x-}?h~96vZJFDRh5-! zX>G+5RDEy08P6Y*Fv%^!wDMs%uzD2Y%w%Ew(^V;a z%xWPkh@Nt)%an?&qM8#G7f6LIbPg*;?C66r>FncS95h)0RQhNb5)*YT#miOO5I}c# zo(CoA4cFg*D;He;&H|~dMm?yZ4$G7<3=s-Ry`SaFmf?>#+=R#Pdk{?x4QOMJQ_tl= zsX{V2TSvGagC-v!q20#3N*`@6FSUKsHE-woil9knKwp^>?P$q!lcgu9T2uYxhOVly zSFM4?x1|LH+Xk!Os}VtMs2pR>5}Z725+)jP)F6y1BZN|VU`1Vbg&xUpjIIVjshFl6 z8gh|}80d%?=!}O^f5PDycJ|T0%t>%+%8)ipM02L9v&7009${j4C+E=dg%Qv|<@~wv z`WtY?g3HlPNqWmIe|O*azW2TDC26sjt-~c!=h@?-N>6UXz{^iRiwFOG7nVHvG&ZkT zg^spnk)gH~LWA9jPRo@dXf{dZ;$2mh60Dqy5OY;kj3eJ-KA)Q9OTO;HMOqOU zl(hA#==0>ZEs5sr#li9|EOC-!9MsJs8MBb7t3cKKSr~r8JYd!&xFaj1_Az_bNtFng zLRKhF1Q~+do)`fx%mk@O(x&|gq#QiyCQ6CMJkO34Hm+EW=O29nuPuBUt6y1$bVsKo zH7{@4h&JTV0SB2d>-Z=V1>=yGO^_-|p61pn`kWU9Q5Wi(b>lJk@+yrdg+#HX#P-tC z2+{&UL6;iwJhq;S%PO|CJBQQmv??&lD#47}(HI*oM_nY2+Khp^q=^!nLZbeY(hA;{-jEz>HzOn{mODZtFqzV-|1996xNzz6|MwMQXtQDrM zvV#omP_LK+FG#|CN7z71iHVl#D6Gk&F!8v*tUEXq8S@IckROZ<_2u&*oh`&(1r{; zkwp@=bivTo2mBx!jnJ;5cqNEO<*Xw#%-b-yss6f@8e zH!<~`6Hq?q07Pa_0ftuqG<-^H>O&wfy64#dV5J>klGz;e=NN>3AdQo@xUr9;_ zkjIx5w6!IqfLYth4OqK)2^wBl1~ZXCBAZ61ox!?>E$DDE*xuHJ?WtC5MJJM~cnN!z zi87cKUNOsDvT>7}FTxcpv=CzX5mObtmhNQ)si(^FCqb!f%^0deF;o~KOsF0%fE-a) zflAxLuv`dbSwn17*2yiknV_v|6?y5_5(A}8P2nkRF=S@7Rd9!uArVnU-*|tl+Mrq_diHlnJ)h?0zB6^Ly$8O5ocV_9uJdft7UekFU({VC z6uhhq52R8>G?N87(?EL?XzIkK2Nt1y^=9nYxEY!DPPmMrlAvG$&2|#Y8@Hg%$)F>Z zL@JlT&bCG*kwK1?6r?-1E#TEQXyG>n$gngpG!cOz(vqrdsS!qbv=nhGjEYbM72z0$ zm6W3s1QP?EQ<8V zN>t67in=3a!#sF0Fnv4_w~(}4xpykHQCM9;>V;`o<48EdeWafaWI_(@+jRu!qqzRM z>u~kuSD>wFKLV+C(&WpWNb3e&pjjE2Ica5|19r5bbLm<%yu1QiUVIJau69@*DPi*@ zQ%RK6R-hxBMlzj3GMhn1x>Eql-_wSJt!+(W$K?y36jUR{uY@YAtwJ#LHtF)6v|$+^&DXwWsS}2d7&mnkSlLgf zEo{ITJsjbw;}AdO0F)m*1(-1fsEPw6Y=F#CEvo8Z$h6csbww81;@UQ)B-QeI2&j8y zeIdK;#v5)Bkam!9w7*DFKS-5Cb)@Q@#3ZSv3iF1O6EJA6?&<)xw*f0RVf7=6(e%bT zBpMn~5ss=h^b*%ppp!yfxt#pokxQe~biC4+UO_IYSg6v#xOb|fQ<@@G#!3aKW+p2n z1A2~i0!+T{u470sFn%vp`#i^2A%x=*3_M~1i3#bDA#q-IJ|lxDTTzN+WeKY19E4#< z&r_0f%y6KhR2p))5ycu(S+<_R9RMh^V|0UGKLaW_ONUh8-N&u%*b;)d=8CJ(-rNG? zh8wPPKmF-X?-$2jZl|UVInrYwX*3OCEVFl#vmbHH87^LhaO#eqm9ZqIt>@$5!D!X*ld(f zn+O~*Nx~|qECouUKscgez=fva1(5n@gw6=kAtT>+#XuRXG_m{BcKlfC?mC$NS`y=22JWCp{W&UZbf?iHf&wA1c`N9(6Vte zqRA{G?I{V3kQ>YTKDm4|CRM3Wq^=Y~D*#l$>Rni~>++>o^4=zotLvx)bwQ{!U{V3T zIzhz_At?@KvF?y5{bktOG{N#FQ5#iL$D@AcbkrU+6__wus{6@@l@!7u>2oR-9Q5nv z>GP{Z@9$kQZ+h6Jz?$0s=FaXsv41?-u96_V=BlgF*)jyuuH!1{T8h~ts;o?4dP*1& zWwrR60&B{Jy<#19u3Ur8bz9J}Y9ri+7GxWm5l!YWqO?NPQ*o|11UySK6>MNtXsoal zYU*EJSOzOO2zr%T%@QVA))QhU^pGkHmX3uHsw_vWwhGx{Wf*tbk#I*=Av9(rP*x(< z^2Mdhu5Qx9MTt%_j=F3^Al)6D?bfk=klJ<*zrXP&0coPGy{jZGa9{UNNvfDX{#IlZ zT&zr}yHf*hI*S;?Hi@i~vg@}XwPqt))^0-6y3MfKQfOPZS)4s|@(4r8 zHlcCzHY9d7p=I+nX~}4%ZA7!K#5hA)rpMVr`1j|slKjpZLv%v18hkDmLW&YF9z&?2 z6m~@koM9Cx8#4lo)WJgf?+j05!}fp`=sk4v9ZiIqqzS2jwb1IgnO%RMq&!IXQ-!@s z4!V=Cm*OUewzLD8T%m%Y%4744RIe*rCjqcpI6dIjlkfA?$mv;Xtiz!~>HN$MW} zot2{GP=WkjDB`EGVpM%0kAzNYppz3@vy2&@D!oOVO*vQPa)#J!SZe+<$BkZNI-_j0 zU*0bDBsD`LY-dl9GHXT(glh@Ub1CUam03HXBn?ln=%*j44sXgOrnau7!gOt-{!c1h zo~EZGhC(p?AImQD&ihA(l9Z04Ydo9uH^2Rr`?=44ZV05l5eOD5?kSmEPgcz_5TWH| zuc&OBJoljM_~tvPDVm}JmJg`@*i60^pue=If`P8|sY`r{4ejNm7A~mRLWQk+WHVTE zX>e1_dkk3xdJ53&&Y9o2#|DRs>aMm)JKEb}{QB3wbpQ8%|91$ay@1rO{uY}mnyatB z3l=Ttt?(FaQiV~rChQ6z-7Z3(H(0JDA79lt_jR5th|R7tv{*~I0s4*lM2jw9-sg@( zJ1EU2u%>C7^cs413DRHv>KE?kKmYk5koGcRdXl925Z#us0Mf2t>#I7T25RB>K>X7C zB6yyBeAORU)oQlCRD{1&cagr2Lm+)?SBu_2Dw6bc(+zY>W;Sfl7V4611s1Mfwah|4uQ1$p!8=<_NPT_ zcfi=wvE9fswvFqryIw%r%C2g(N#Bl=)E~C!E9BANfelVbeT_YJ{{G&_zO-L|yw5`* z-Mu$f45T;Qa04#C{BpFjGQ&03T;+c4YhUZPx~m->d@*_w_Y`E`y<0DSw6u%xnkVT! z_7sTr6_6HVAMK5??9VxaW6fjs)Oh#j`uoE^-B^^4i|enyPC(j5NqY6wSGr&S`qu{p zQoS=@U?!6hM*^u#+@jH_^#AN>Be471ovhe7n8L;DvGA7^|1!<|CpdxlJ@?lOOHcR2 zXW+i2rKMu1S5{W$j|qB_dF}qFfV(rfcz%v&Nl8f;x?nb&h2;_Jg9Hfw_4#1Aie6U zE8K5<;~N74sRo)phy%pI;1&*t`<%qPGs*cvczsSBP9%L@{cnD!fy?{RFNxpx1TZbR z_&ov3<9Qxli=VQxGI=&mVD78WHJBID*D+cv(F+johk)f66STY^j&WaGF$Z5?$LR0* z?0V8C5(&BP-Y_rvdq4fz&#%pKyeKTV`G4n_baZs&-)Dc$`)2IZCrGcja)JA;Z+>e) zAZ0^du2uvjAWkN3T(SCE$@}`gw}Fw|Nl(?*VAX%)dG)H#NzT7(N!r^A%KaJ} z8}pzqFE7snl*bViot>R>?y9P){5AI03)Ef3InMeScpn_|9Xoa)9*-Bjw4SK?=U~TK zYbktQ0+c`ZWsq|2Q3E0f`R)irKS()lynoJ3t)1+xcQ=^x_GFV@dBqjVadi0=mvsZF zN&@cLt*#}{vSrKg&_fT&p!g-4mO{ZB){{nqYOoFmUZ0>DIdUXs%$R{g4?R@C!}IYP z8#ZjfOE0~I_3PIQNRK@7NQ@aXMm~Ofk6_>gT(V>d{_~&z$cyGn=Ckk_I9c^Vz!mwR zgAT$er<{Ue!-fs!UG)1HKF6j_oACJKkIPRj-A9ZVfz6vY=OPS9RR)rN^eS(OE0|??|tuk1$+e6 z0}niaJMOqcKuRD}8cm!y5%cEF!v{b3LA>i-@5-xk1S4PIAOHAAc@6?xOR?a+ala{3 zrr_WI{x|CC>biVA*u|!&=jZuWuU?Jse)qcqRKMo1JNA5k9ef-|jx7@}KK}8K%i`9P zr<>2Pr=NeI^WwGFUc*HfU4%u87Rh~T?Ma_UYk3D8Z~%VvqaWeSGtV68CHCt6L6G{% z48l0N?6RM918Go_7JCT<#lsIjER&lnnBGU*ar&wJQd8S{{BE$TJdf4t*HK3uB_O4w zD+Q#FKKiIEG=6aQ<}~VUHucvl%SkQv#5o_gx3UDW$xD)d_o z(&wIgPC&YN@nRXL;Qi=#I(_RW;Y(lo5b-9usq7cNex|_uCV=`1iBVJ{!OI#V;^^ z{CLq&xbt*)-duYUC_8E~%rTqyYa+O=y%Wu-byJ48EP2r_QR z9d{gl{_~%UWTgsAY5M!$|Grmsm*=M>B}l1G(>4rleckgw-W>0L#flYqNvgwJ`W%D3 zR&cy~0$o{IIamnbo8SC~grjn-#Uvmt?x)yOAT4Gx^=I5@k5cQ|Nu~aWznWb4m*ZD=moHylRFd{*fCsX|>wO8B!w)}PR{EJUXNnYE zx^yW{KKW#kjM@g#`xDgs@Vf&KJP}L#N{Q>PyRKJtSBG5)(gz=WunR~B z3z)vfhKmlhghw8EBp-v`(;)SmD21^KVf5(HxbAn?;rQc^N30|U+jhLhRK@R_o$6R8 zm>k|>wCUi&tv&EsYtgZ9|JesJuFpREY#yXRb4zOgen}csclXpH)7Lxg>H9t<>4HnU z+oV#R?kxbRR+0O9*ouk@eC%T%!?(WmEwK+d30{8rWn6H<1=zlQdtN=$=g~GCB`59J zKmYm9qO$4$_b-3>O93e-kB(3J??J20^zPCQe>1$h8l=45-jbw#M;@P7V$GI?V~;%! zS6p!=rXMgJ@lt}cd;KL{Oq`%(#Zhj$z8VECK}Ly2(9r(pril{T^Q!-*ug#ym%>g}` zRfU*B#R=M^T9Uq#K&oug4j5M~xYYe-Fi!d=gH(q_I7xc43H_j%Jb5yH_`@HH13(iC z2+nVQ^P3`hnwy)u;G8d>=cNn&BOm#QfSc+tHv*Ru*$>j-%F6rWYEMZ@&}e(Muf=4r z-}Cx!7D%E`v;k^AuK9qaKOC`ive_uMY8CdjB7?0XyR zaXm>=f>bIqyxAZv21E@~PLg8Y)!@S)ee}`d)uqZyY1q=zB5~4R|N7Us_S$Q)X3d%| zhfuBM%jf>z|Ni$ynrbP+Sg1#s4y%b!_FGIw671e*-RSQbOz~E3b}L|Elo{mZEitB z!wz{jl&F-Rd=JrZ1T__vD36z+rn*{wlF=0jhY=!6h}9FLk*uz6<`_~9ru|JVg0Wt{2THGEAmw62pnU36 zpAx$~zezX6LjObl{+{#C#qePx5cUcOOA&B(aRbl_Tm6@_;byXEZrFvE#$8yqdJUE> zeGSW(zJ~3aH=}7+6Pg+uWfsND;?nO%7NMMj3AH1of%5pV^_Vz*0uDQLF2>i7!|>t5 zQB^-y^>$?=9qxZb$J>4WJ$DCtNLJP-9 zbGeJD-@FFLpK3h!*Xq2M$OE%+b>rv)P+2}j@=3408tp8fvO6HSnBxzw%2PNr1 zLCX1~sjeJ9jxQN#BuQ`q^uH614FSqy_~H8@IFCK{SaGz`UosG<7mWy6ihROUgY-(4 zPYHrlCV#$SdU5ZrKcu2xbYC1%4gl3ms-oP2Akp4aP9%C=Nf;nli%C*_eLn++_pL#~ zb5p|TK_}oi!8y?>O?1`{??bDXL6G)zf3s)L7IJ}>X8QSgPQCiBTenWiG2U{^E!ets zYd&7<2ZffNd|pZq7AL0)MiB8lnkUR>;yr6MR%;yk-t{@Ts8QV`sf7CnH5DGu3B`qv z;U|(hy53I#q^c>EcyMGcWKE#W%_41C*y$$F)Y6R2tJY!diZ}4$)6Zhvs?~VyrI%p2 z2JBQC$mXPt1)D$-=u}_XK9V4%aZ8z49W6t|HQ;2j$RdRrs}iGzkHF}?F-T&baf56}V z_BXup$}93Nf*_@aq@^k6!U-pwAS4;G+Bo-m;#PNC+2s$tgS4%+6~;y1`L=t>Pn5cw zmrzW{>OtKt22$-}_n*VRnsDMUobc11{*oF0f~uafVPQ4?FCzJUI81B)#HF zk6{1ZZ-2|B6Q*l`E6}hh5XA23ruC==S27L)XxrYmUyQ~V)FgNz5-hj~GG48(7aU&=(yOn& zT0&JtLCW4v>>x)Y)BsW;s<$@QHSNHf9b2$r$2M$PzX6Zlb{AH?vJCdFCgtb}g<*Q_ zA(gb#tus7|UOslBq@l!AJ&DalfyYw9()Jt?j$>v;9j1&JgGm!7Vf2itnE$a05Sug_ zHhUr)E-c#cI^F{y2-2XrqRl4FIHK0VvDWrG=LT(l3J1;wdW-!V_v1U`eA4VSF4T-J zFwK+a^=|{VNdxL`Hl4-|*I$n-u4MU?78n1VeJrYQ96kX2Rl;jcy;YcY--qsSC+nt zXBIBP`j?l(ZfI12QA$UGj1rFj)FAbmRf)*+K$`FB=1Ewp)#_NaI1s4iurMt)43jE` zVN7K$YU)N{_9@3=&gsXaeEN7~!X~VcG?>h9+9q8j++F3=@^3+qzWd$p&YKb3kMn>8 z7skt}jRXP8f9r)^LQT0GKKjv*$|8Hj5l3|M1MD4;UUpfR8|&)-_ILAAyX}r7-5Ve! z0H|jE&;R_7IBoo%TP-d5H#&Ss=_4qa4a2`tqB3-&9Y@6^y$-=>Nvf+)(C(!TO8b)w z1SJ^(98__&^N7bW#!E>?4l(1cykDJE9(V~w%arscNe2Z|X{qQpZ&ueJ+f4B8FgS7?y0Aq5-mwP>GU}WOg<}ZP1>MLI{4%#KPf4aI%8<>OVYPFNC`Ho zC{!KkjnglM(vAa8b%ucAATu|T5|1mOmN0$ANwuWcAk{8+UW@1Y-S2*v_at)>(kr(H zly*$eCj7)FJ|P5uIg&a=f5G_|2#Dy=5rB#$6&VcMFp#ue>`HWE zebWwX*|h`Pwr|Bl_uhx+9{&$gTerio!iX3q9Cj+tvL~y=aq?aahFd&%s=4cdRI`+H z&qfijt^%lGyRZxcmII8atdd5{Q;bR+J81@{Rn=kYoS7JT>S3rmVit@M)j-&UEnU)G zyx=*Go_uPtG*#w(`8O_-1aAt13%GN6zNPxV!p2}UxuyQw_(esO|U{?#Ho2ClcJ`w2{P?XdVwntMs3Ex zG@}w{jh~5eqsE|o)?^&<(F=e>CaaF;v@0D4FTA(}-?`|!pd_^!>S2RsUrRw9d#1Wi zKvI$tptR+gq@gtsJ*IkpdU474;lH^sGsaF<8^d}2t=MAPZ4&nQ2Y+iyrNgFEY20wb z^|2D9z3Q$ASHk}Nw2x;YMg(;1xku~)IK3Az?4tQ z02%?TY2AetZ>+$^)obwJZMS3jQ_lbm%_w7_-zao!<)q4HG6LM%npzxw_+dEx^wTlp z;2HAVls-}h#x&5<+KO%4w+m~Fq!T7ZkX=(6SHRCdm*b$sHBse;QRf)AVB{Q3sv3b2 z(l0tN%hHE*D!sTq&ob3Y!v_1{RXT#IndMJbEUg#lYRfMp{v;_)(^=GkgT z9&tq8o36uNlBn-xDAAL8?|t{;KaW3wd+xmlq!s4u930QK4donBp(BQc;cgg*g+^k| z$O)J-VG`=+9gLYDdk-*W3=m<3KpW4#^di2)$_$jGwu;9FB`LKU+K^1aql9FK`p3r2*rbtog$b5mi`SF+l^=e;rC+0+gQQ_rL%B z0#NNh3No_#0_&az>AB~fE9$P6qy!wu(S-rZ{->I@V#ymT5Y9Nb{SSY}E4SYbw09zI zga9W8Ct||!QeSv)B_*YJ?|U!6r$7A}NkWK(LkL-_^eQ*b4{di#rj2Pzb_dn-Yp%H( z_uYS=l8QMSmhB*%vt%0e&Ip{DX>4SBxxY0L2)?9Go`(rqdrB)bbp%muE1$l3SG@VT0 z#v9pY;wrSYwZi!3SHI$3cKHIYh?fN;p8?~`Ast|=k05CIvcC7d@8#p9J&^_aYm*k6 z)TD9IaTLse3GPdfQq9pI<-O4^`N~(ml229B$M8FCU-EDMJV>t0e&>RJRpm?M%jY?1 zhidg#OBJ;s_R*TmcjJDL4#vAH&mod@9GF?bV7?!u4r>>~l(5S#xcK*LFJi;a287zv z`1Qq?A-QY?kaJK+oE>326U zY1!K{+|?%Ko~cAa<|xBuk_GdPuYB3PY{3Gt8JGp}b_OXOBD%C=v6sYw)smDFQO7#_ z0x6HvAHHb5L>)@fo?QOape41DETYeR<}e(?Pt;KLvO5Xws9g3Vkm z+bc*35G_#&)Qd0qF@F2o-@wkfs3?iSOsYcb$q*2+fsw9-S=MlzHDNYJ)(peMQ;xzx z?>ie9TMH-R;!K17&K9I6u_?u_~$}z@ax}q-9eh{ z>=bG#K`QyAU;WaBF3Z`QUaHc*08&=uBiTR~9P7`-rX(c;gey-^>Nf|MDi7_+{({s$ z(7X@50`nUBzVxc9|4ol3y}oo5>0)O(*4Dol*LAPGElCMds=A%o47R6|SiE@yHt%S_ zvv)s)2mkgDpsf|Kvk;bpX&~gdC@(2Rdq=wzf&1kzekp2hh;dWNEzJeZto#G{r5eYJ zC0Xu&;C_7UqaQ^}YYUv5i*g~7j-x+v0WiHDsEpy6 zS6{;aBS;sj5R4s&qYiY;=_n$fn(bF;rf3G!;Idr$x_ZwbW%QsMNNGnDsxo*w?f_L? zQFj9QaRXI%2Mf~k&O1+R#UL$A-w!7RLCUx$Gh_Oaq(SM$=is^YYOKK%1Sx?@N5fBk z@)NOZ)MQkjp0ZSWdzEhnNGT&bQYmcgXvd>#R-m;#fhYcY8(w;BArcMS>BG%~G-{X# z8>TqM=v4XMMc+f+s5&(+F4;Muet}d%Zy`&(!}I3N1?%T#QfW|;W{xGj&S3|LF~*5X zoH1$!#?_2O_0;h=^^+ffHD@YN6UTEezaWkyvY~|TrxViq!bcC^6PWZ&vp4|f37t#+ zcf99RT|rAAogUDVG!N3RU3j5OBClkeu+IpMeP+%Kvd3q!=jKECuI3+UsUj=@%p@f)-$HsOI6A5 z+V2af!SfXZssEn(3c&i}+rMV3YZ~O;deDE>k677JK z5s(^|i3mFgwdV4SW-bJ|i?|%oK zCMtVW0X{^!plf5YQH9g%XJCBgaEzHc38#JH11erRyc{n)|1AFBMHk_zMT^8~r=$#mt9d^Od9*0+W6VYMFeOyw~7++cRJ-Zj(~o?E+Hft6d7p{qT%5QX^KY7Yq@52vjq6(j zQWL3+jm@b9?jlHATCwPcf8eDD9z!PC4%iux4n)ZZTag(E(rlYKNXdg` zxPvcOC)gHq1o>A+N>Z|UbcZzm{(g|sUL=uvZ-P{(K2g=BT}n0(B{)}ShHZ3xr8f(t zvM2=Nq<-&i4kR{&@*ur;<*R6JX~h#a{sT)MdJImo6K*y|ktWlGQZ&LGOvjP9}r;Zm% zYRpyY?vm%96PuKA(i|mep5|CEy@J|Mf6WV0LCI3$e9`YO*fntXz}gQ<`lZkRuY2va zzvv=Gm8LuhW3-1SAE+c9EJ#WB(#g2RK*|+TJ9X$@@2@1)Dz4u~EvD{jiNS@1&Ie9N zzF1CVei)X~s&9WM3HRGwbvFo7I@p93=-F?Wpa5AAN%;naQT7-0#brA7EwjXdjo0ETw#&|t3{9~AF?cj7-=9# zZ6HdCiX5h*8fTB0iTaumsG2qor+(%`Fy~ALs!D`4q(Lg`Zr4HwGSvM6sn(GAlXHXb zk`D<*h-FXiHar0+Ld-QAZ!s$YP%r8pLpl&qpa ziTK7FZ{#!g^*+IuMsPCohSV}HB2;~Q^H}d`b+;Qx&pTfc>@`rOW{`n&&c&`=77x7s zDt5NE;A->%_zTv_Q5qO@d11SXsNvtNRaE*?X*msJr+wAV4h{?f|!xFjV= zeUem3R0BE3K#S|(p=GaPb7Lb`zPuE7{P8d7T)P2bHiH?lORaIrniu*_m{u?Wtq&B!n!<4u@}3iC21G$?p0UeymQYh3Q`Hf0C;Bo z1}xjKUNTi~|I=Tv^|_Z2PN!hHIT)r3*Kox-#KvCyFyPP0JOAjT1ptw7q#H={`J^7( zD(B>|X~RZooyltXuPt4gFIN%{TVjtAr0m2x3T2pCG92fPKLlgzMq|pkC!qYaBZ0b7 zWGkY0F#u90Qvj(}bvcLlA=pkj=_GMfQIaw-0m-IdkdsGHper z8h~_W(PpF6p%aNVAys7^I}HN$tpsTTz>208EM312TN@kj@4x&N%kO>=Rw{+ClY>d3 zfayY5JyOWe0?U2;_Xj?RFMRO}m^E`I%Hm~3L8_fq*<2Q#oe3;nya+d3cRlXE=UxFf zom&jYghQ6ZM*wxYjIHNaGWvu5R4cz8V7&u9E6TI2yS&0si=u1FD=3U`>t{v zNt&9IF9wmfM|DLE#?nbqWkn2K5|xF=2vn-Qy5Vq8no?8ZcU+uly72vJjc8A+yMFGj zkQqMp(T}*aDfXngTP%**Tbxw0cjz@^Di>40G~=ikjjN|P>D~q@JDwq`w$Y)4t71UZwmb|zel14ATdBoY=6C^LSJIP7pqu&3ss z9W7dt@_OqxZNwdS-hq4Xxfic2c?s<;tt#=Gp!b6NA=^O=E=D4RIjFUcYo?&+xwmNaFXOiC@%L$zN)ND<7a z@s8J0mG!8!Baq|DXAI8AfvLUSC8gc)_*7)wgIh}27&e5Z1ith#KOR9?PVZhPpbQgYi3l3Y?Lg~dLJwP{kF zs+Jss>>=%CeWBSviYwC5(V-fWK2s}PFpydyjG4~(vNTUn-)ryX22A(U*+JUa*d&94 zvlOIgq+HknSyaoDVwQw?lq^r0Ed`UUz}}Y9%-w97lj*qpqe_p4_@sHg4FcHMkZ$GEK_arpO)|?xTsM{Og1N$eA;v za-eOG{Bg%l={@*g89Q}K3X2O>?<${ez=9Bu=j)h>f`URV^TRbj2*F}uIenRWecIIl*aQe_dYRn9qHf>5;DVhB z>j0rJ9WpY;Wf(}a`8G3c?%o}cLsJH7xl+tsj5{d2=s_7cdrl7abxZ%ifE@bdfV92+ zPkH;b*X7j5`z2O9PYP4yw}91Cuo84BD=U@0o?cB`uoswvCbX2Mh3lU^qpfeeN{dUB zuQ!jhi#E)8f(V!|F{zhQx$7IZO6{V{rT*Hh3C$qy!>fPyOL{_q;2= zqL`r-`V_8foK60!o4E@}nWS*xL^cVNvryz}4!?zNnYUSj#HTe1Zq`88WMI>-TKn95z)}-dwW&&wyhC`RSHcsj?SQAGMk^uGY#vWBK7Nn2hn4u41qDpOZt7Pe6u`WB9b^Qb+JlW zb6LHts#z|}RxXztZogHQfA>boUtZ0ZMB*fO{qYs;ZS83w)ikZMK~|0lr!(4*Cj3m6 z3;W1GZ1#^cNT7)5DlhKc+!qr%Of;ZAn_!Z~75p0JY>jf6Ae9}YO{Pg7yl<2D!j2tZ zdXPeC0>=?y^h{0VEb@f}sR0L|GL#q-nrLCBCIQ~#KJk$_Fqpko&0@_4+05TewWv`b z4X0oXr1=E}K2yB|(gX|%fmTJ?4UCLPXJ3yT>^iIincCibOFn7+w~TamYosTSj+fv? zA%do5bTKCId!&$Kb7lZ3-829-kvOCJuR@BXHeN1YySzqLRxXj+`a1d6h95}HO*crv z%4(7Fc|JqF(>v1M?$0MhldAR$jiLZRtQ#Q3(t#YnUaXA;g?Nv%vuoEb4J2Vk8$GLi z&cF&#u@>;VadTjNKsgXFvy|P`wA@6HQqlFhXP;FfvO&g7TuLBi@d*Ot3R0IGI}^R8 z`6qPfn#dV{)YHb2;?ke(Ct@8}i{hZF009psLywzi~XE=p?=x z2C4IJoi`KspbU44GmHt^l>E3X&M%gmms}y&FR7PRwaewo)z{04jkk-`E)=i4NPA4R z=sr+Z{Fo|8X~qYn2y@ep?oShd)K}B}^3qE$>Ci2=-q>=cW(xCfa^Fy_kYckG4%ap9 zI=N<@2vTaJTbf(^rf&jAvl*n;jgZOwbfpxFfhNrrq}rYri)mEPCC3g+z+6CT8kPAh z_?*myF*C`2AD?jvv`HOtcnCtchsKrm1%*2$Awx5(N%*Q#0Sg491M zK1lIT)f^4{(|!U;XGi4N@#Au=t49vK*CD&#dQ$2kT`Z7tv)Jx{!Dh3#K)@HXQY)%JFgM7Pns$l;DT@L~ZT2V;Q}=~g z!h84&T$cqUr^j_!WGaRr48wN6AZD)E%)e#>Rn*L&Oo^v z&CCQBcy@rweeiqu{l>vdlQ?`jXwyt(g)T@Fzor?QOfIwe@Z3{J2xj z4h>0h*?iTA!i-SL^Yl+bwQ7D|zIM(O=EWrsQth(|DTxO zH+}mSS#|YQvf`R+L>4XZ!@j|YQl;|_OjJvUk{^BK(MM$W?lvDJ=gy`1q?|w2oc%>Z zx<09Uw#@7`%ZHH@FfH0!!CfA1L zfR-)N7Vazj{9%wH)To5&?Ci`qYLWXv*sNZ?THDIjtzG8_cw%`9LVZrnPx=gkDM6!% zB{%~kg%93@mz3e;sPy#rN_SV696o$VKIqsh9q+#{`}gga{@z}V(gGBsl*WO}HPM!U zw7`q$kfySt5?M6ALawU2LI(-o)NrFLs$L>>U%yt0%1b4$tjxa^BNj6f%Yekq?v)W3 zk3RO8f{A?z3u*S4Gsu~usD^?Ivsm0cb_Jo82vVX-v=?SW&WF+G*q(50)|WHP=m|7B z!rZEn!WK~4z8Xlwj7(#m{N|~rmC0#z3$r zfGJZkLnevDA!m*U<#|L?!+s?jXPO#mN`w!GpKGysB(N#+w&~ei&qfGXp#k@Y)}si) zdR=Y7!yWr>%`wxuxi4ya*<_oKYMaP+d7n+^x&)E}$0Em+!aexF z11ijXs+^dnPr{Z;3Zy|ti&`{Lkm+a&PtGLI`Vn1kOom5BXvhSmPa^&#m zvTyHRWmp&*8kW(~)2dbZeMNyLt*@?8j-=Y9)l$23nOt+_N~x)?*1%4zs8D1P$9 zmB4vaa0W!b`gdQr1O-nztP7e}N;Cmzc(#u1J(XezLJJ&a({$_+LXG{V8i^nvu?VAN zb!XhN)|@F=D#?H2Hj!4dK;^VR`hVWvtxr6m?QvSnkfup#79`I!!ypATB>UkvWnsdH z$cpG$Omc=uB8u0|lr*qrbHMpNnhMQj01IncGfCM%s$kHz)L*igEHGNgMjF}>CCl>x zUNkYLDCSsLN`{{YLBs}gZ8SU2j%4OKR_LvT)9}g$eWyG-!i0N6Q|AIw?hRIbp3%w@ z-R~P28f!zYa9&A?mI>NHH;`sZx&ca}w$^{@4_xvYJd$2gg^s3`;sr7^I4DQ^`ej~m zv5X9l=#*-h7D&e!NDK1fQXG#yyi!?EStX@aO!QWjuD~1{ONd7SJCS3T^VxtI z(xm1?+5qNo1sD4aczK^Fx^Wg|v(VTJn;&F_5DepD@3@vS@&`V#X;${TySrN>_9&Y3 z0%dvl8q(x2UPkGJE69WoEof`x6$zYo;z8{3ZCBY0#42r4$bT6VWsvQp$e*B9074rwtV%n$Ub<%TN-d9IJcSEV z14+2hBK3Yir;-AxF;VJIPZChF1nD2Ht5rxg>_kZ(CRXscl}irnBlk`}8^MH`38ZP3 zMKH!9{L5w>q%F-dOmz1rcW?A|?%XM*6nS&=v&h_?(u#ipANneTl;utV#2p6gxG@SU z7gs@BN*YLmU=Zdq1^$4PukbcBES9I$-{*AOOwdN@x_L^cVfKO4T~$9w=9|0E$S|q8 zA8*{?5qT}Gs7PznJ)hd$DXr8c{GqVq45ta0^Im-MMJcPCGk0@d%&+Jdq7LyK zNYC$JBohhQ($uJ$bae2f#5Ue_r}u}KU!DW$`K{|$>f3W5%@EC+!4m*Tn;JLEbK9Hc zG(PEuJAdfC{K_kHAf3TQzSJ)j2~s~jF#eh|cc*kDY{}>#LX!g0GlM7Pf2nysEeiU~ QjQ{`u07*qoM6N<$g88?WF8}}l literal 0 HcmV?d00001 diff --git a/test/Charly/04-manager/public/index.php b/test/Charly/04-manager/public/index.php new file mode 100644 index 0000000..bbcd2b5 --- /dev/null +++ b/test/Charly/04-manager/public/index.php @@ -0,0 +1,114 @@ +selectOneById($idComment); + // view + require "../view/comment/selectOneComment.view.php"; + +// insert comment page +}elseif(isset($_GET['insert'])){ + +// real insert comment + if(isset($_POST['comment_text'])) { + try{ + // create comment + $comment = new CommentMapping($_POST); + // set date + $comment->setCommentDatePublish(new DateTime()); + // insert comment + $insertComment = $commentManager->insert($comment); + + if($insertComment===true) { + header("Location: ./"); + exit(); + }else{ + $error = $insertComment; + } + }catch(Exception $e){ + $error = $e->getMessage(); + } + //var_dump($comment); + + } + // view + require "../view/comment/insertComment.view.php"; + +// delete comment +}elseif (isset($_GET['update'])&&ctype_digit($_GET['update'])) { + $idComment = (int)$_GET['update']; + + // update comment + if (isset($_POST['comment_text'])) { + try { + // create comment + $comment = new CommentMapping($_POST); + $comment->setCommentId($idComment); + // update comment + $updateComment = $commentManager->update($comment); + if($updateComment===true) { + header("Location: ./"); + exit(); + }else{ + $error = $updateComment; + } + }catch (Exception $e) { + $error = $e->getMessage(); + } + + } + // select one comment + $selectOneComment = $commentManager->selectOneById($idComment); + // view + require "../view/comment/updateComment.view.php"; + +// delete comment +}elseif(isset($_GET['delete'])&&ctype_digit($_GET['delete'])){ + $idComment = (int) $_GET['delete']; + // delete comment + $deleteComment = $commentManager->delete($idComment); + if($deleteComment===true) { + header("Location: ./"); + exit(); + }else{ + $error = $deleteComment; + } + +// homepage +}else{ + // select all comments + $selectAllComments = $commentManager->selectAll(); + // view + require "../view/comment/selectAllComment.view.php"; +} + +$dbConnect = null; \ No newline at end of file diff --git a/test/Charly/04-manager/view/README.md b/test/Charly/04-manager/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/04-manager/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/04-manager/view/comment/insertComment.view.php b/test/Charly/04-manager/view/comment/insertComment.view.php new file mode 100644 index 0000000..cda81f6 --- /dev/null +++ b/test/Charly/04-manager/view/comment/insertComment.view.php @@ -0,0 +1,25 @@ + + + + + + Exemple du CommentManager::insert() + + +

Exemple du CommentManager::insert()

+
+ $error"; + ?> +

Insertion d'un commentaire

+
+ + + +
+ +
+ + + \ No newline at end of file diff --git a/test/Charly/04-manager/view/comment/menu.comment.view.php b/test/Charly/04-manager/view/comment/menu.comment.view.php new file mode 100644 index 0000000..bc39b5e --- /dev/null +++ b/test/Charly/04-manager/view/comment/menu.comment.view.php @@ -0,0 +1,8 @@ + diff --git a/test/Charly/04-manager/view/comment/selectAllComment.view.php b/test/Charly/04-manager/view/comment/selectAllComment.view.php new file mode 100644 index 0000000..41a6d19 --- /dev/null +++ b/test/Charly/04-manager/view/comment/selectAllComment.view.php @@ -0,0 +1,33 @@ + + + + + + Exemple du CommentManager::selectAll() + + + +

Exemple du CommentManager::selectAll()

+
+ +

Pas encore de commentaire !

+ +

ID : getCommentId()?> Voir ce commentaire via son id | Mettre à jour | Supprimer

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + \ No newline at end of file diff --git a/test/Charly/04-manager/view/comment/selectOneComment.view.php b/test/Charly/04-manager/view/comment/selectOneComment.view.php new file mode 100644 index 0000000..faa9e50 --- /dev/null +++ b/test/Charly/04-manager/view/comment/selectOneComment.view.php @@ -0,0 +1,34 @@ + + + + + + Exemple du CommentManager::selectOneComment() + + +

Exemple du CommentManager::selectOneComment()

+
+ +

Commentaire inexistant

+ + +

ID : getCommentId()?> Voir ce commentaire via son id

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + + \ No newline at end of file diff --git a/test/Charly/04-manager/view/comment/updateComment.view.php b/test/Charly/04-manager/view/comment/updateComment.view.php new file mode 100644 index 0000000..a561f15 --- /dev/null +++ b/test/Charly/04-manager/view/comment/updateComment.view.php @@ -0,0 +1,34 @@ + + + + + + Exemple du CommentManager::update() + + +

Exemple du CommentManager::update()

+
+ +

Commentaire inexistant

+ + $error"; + ?> +

Modification d'un commentaire

+
+ + + +
+ + +
+ + + \ No newline at end of file diff --git a/test/Charly/05-together/.gitignore b/test/Charly/05-together/.gitignore new file mode 100644 index 0000000..d11ccf2 --- /dev/null +++ b/test/Charly/05-together/.gitignore @@ -0,0 +1,11 @@ +# Ignore config file +config.php +# vendor contient les librairies externes en PHP +/vendor +# fichers non envoyés +# PHPStorm +.idea +# VSCODE +.vscode +# Charly +.history diff --git a/test/Charly/05-together/config.php.ini b/test/Charly/05-together/config.php.ini new file mode 100644 index 0000000..ae92c13 --- /dev/null +++ b/test/Charly/05-together/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/05-together/controller/README.md b/test/Charly/05-together/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/05-together/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/05-together/model/Abstract/AbstractMapping.php b/test/Charly/05-together/model/Abstract/AbstractMapping.php new file mode 100644 index 0000000..6c5f9c1 --- /dev/null +++ b/test/Charly/05-together/model/Abstract/AbstractMapping.php @@ -0,0 +1,42 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst', $tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + } else { + // sinon, on affiche un message d'erreur (à commenter en prod) + echo "$methodeName n'est pas un setter valide
"; + } + } + } +} + + diff --git a/test/Charly/05-together/model/Abstract/README.md b/test/Charly/05-together/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/05-together/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/05-together/model/Interface/InterfaceManager.php b/test/Charly/05-together/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..2d70ae1 --- /dev/null +++ b/test/Charly/05-together/model/Interface/InterfaceManager.php @@ -0,0 +1,18 @@ +db = $pdo; + } + + public function selectAll(): ?array + { + $query = $this->db->query("SELECT * FROM `permission` + -- WHERE `permission_id`=999 + "); + // si pas de résultats + if($query->rowCount()===0) return null; + + // récupération des résultats au format tableau associatif + $result = $query->fetchAll(PDO::FETCH_ASSOC); + // on ferme le curseur + $query->closeCursor(); + // initialisation du tableau de sortie + $arrayPermission = []; + // Pour chaque élément du tableau + foreach($result as $value){ + // hydratation de PermissionMapping + $arrayPermission[]= new PermissionMapping($value); + } + // autre manière de faire le foreach avec fonction fléchée + // return array_map(fn($value)=> new PermissionMapping($value),$result); + return $arrayPermission; + + } + public function selectOneById(int $id){ + + } + // insérera uniquement des enfants de AbstractMapping + public function insert(AbstractMapping $mapping){ + + } + public function update(AbstractMapping $mapping){ + + } + public function delete(int $id){ + + } +} \ No newline at end of file diff --git a/test/Charly/05-together/model/Mapping/ArticleMapping.php b/test/Charly/05-together/model/Mapping/ArticleMapping.php new file mode 100644 index 0000000..7a2fc92 --- /dev/null +++ b/test/Charly/05-together/model/Mapping/ArticleMapping.php @@ -0,0 +1,124 @@ +article_date_create; + } + + public function setArticleDateCreate(null|string|DateTime $article_date_create): void + { + $this->formatDateTime($article_date_create, "article_date_create"); + } + + public function getArticleDateUpdate(): null|string|DateTime + { + return $this->article_date_update; + } + + public function setArticleDateUpdate(null|string|DateTime $article_date_update): void + { + $this->formatDateTime($article_date_update, "article_date_update"); + } + + public function getArticleDatePublish(): null|string|DateTime + { + return $this->article_date_publish; + } + + public function setArticleDatePublish(null|string|DateTime $article_date_publish): void + { + $this->formatDateTime($article_date_publish, "article_date_publish"); + } + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + $this->user_user_id = $user_user_id; + } + + public function getArticleIsPublished(): ?bool + { + return $this->article_is_published; + } + + public function setArticleIsPublished(?bool $article_is_published): void + { + $this->article_is_published = $article_is_published; + } + + public function getArticleTitle(): ?string + { + return $this->article_title; + } + + public function setArticleTitle(?string $article_title): void + { + $article_title = trim(strip_tags($article_title)); + $this->article_title = $article_title; + } + + public function getArticleSlug(): ?string + { + return $this->article_slug; + } + + public function setArticleSlug(?string $article_slug): void + { + $this->article_slug = $this->slugify($article_slug === null ? $this->getArticleTitle() : $article_slug); + } + + public function getArticleId(): ?int + { + return $this->article_id; + } + + public function setArticleId(?int $article_id): void + { + if($article_id<=0 && $article_id !== null) throw new Exception("ID non valide"); + $this->article_id = $article_id; + } + + public function getArticleText(): ?string + { + return $this->article_text; + } + + public function setArticleText(?string $article_text): void + { + $this->article_text = $article_text; + } + + public function __toString(): string + { + return "article_title"; + } + + +} \ No newline at end of file diff --git a/test/Charly/05-together/model/Mapping/CategoryMapping.php b/test/Charly/05-together/model/Mapping/CategoryMapping.php new file mode 100644 index 0000000..cbb3d1b --- /dev/null +++ b/test/Charly/05-together/model/Mapping/CategoryMapping.php @@ -0,0 +1,89 @@ +category_id; + } + + public function setCategoryId(?int $category_id): void + { + if($category_id<=0) throw new Exception("ID non valide"); + $this->category_id = $category_id; + } + + public function getCategoryName(): ?string + { + + return $this->category_name; + + } + + public function setCategoryName(?string $category_name): void + { + + $text = trim(strip_tags($category_name)); + $this->category_name = $text; + } + + public function getCategorySlug(): ?string + { + return $this->category_slug; + } + + public function setCategorySlug(?string $category_slug): void + { + $this->category_slug = $this->slugify($category_slug); + } + + public function getCategoryDescription(): ?string + { + return $this->category_description; + } + + public function setCategoryDescription(?string $category_description): void + { + $this->category_description = $category_description; + } + + public function getCategoryParent(): ?int + { + return $this->category_parent; + } + + public function setCategoryParent(?float $category_parent): void + { + $this->category_parent = $category_parent; + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/05-together/model/Mapping/CommentMapping.php b/test/Charly/05-together/model/Mapping/CommentMapping.php new file mode 100644 index 0000000..c3de343 --- /dev/null +++ b/test/Charly/05-together/model/Mapping/CommentMapping.php @@ -0,0 +1,152 @@ +comment_id; + } + + public function setCommentId(?int $comment_id): void + { + if($comment_id<=0) throw new Exception("ID non valide"); + $this->comment_id = $comment_id; + } + + public function getCommentText(): ?string + { + + return $this->comment_text; + + } + + public function setCommentText(?string $comment_text): void + { + // cryptage + $text = trim(strip_tags($comment_text)); + $this->comment_text = $text; + } + + public function getCommentParent(): ?int + { + return $this->comment_parent; + } + + public function setCommentParent(?int $comment_parent): void + { + $this->comment_parent = $comment_parent; + } + + + + public function getCommentDateCreate(): null|string|DateTime + { + return $this->comment_date_create; + } + + public function setCommentDateCreate(null|string|DateTime $comment_date_create): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_create, "comment_date_create"); + + } + + + public function getCommentDateUpdate(): null|string|DateTime + { + return $this->comment_date_update; + } + + public function setCommentDateUpdate(null|string|DateTime $comment_date_update): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_update, "comment_date_update"); + + } + + + public function getCommentDatePublish(): null|string|DateTime + { + return $this->comment_date_publish; + } + + public function setCommentDatePublish(null|string|DateTime $comment_date_publish): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_publish, "comment_date_publish"); + + } + + + public function getCommentIsPublished(): ?bool + { + return $this->comment_is_published; + } + + public function setCommentIsPublished(?bool $comment_is_published): void + { + $this->comment_is_published = $comment_is_published; + } + + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + if($user_user_id<=0) throw new Exception("ID non valide"); + $this->user_user_id = $user_user_id; + } + + + + public function getArticleArticleId(): ?int + { + return $this->article_article_id; + } + + public function setArticleArticleId(?int $article_article_id): void + { + if($article_article_id<=0) throw new Exception("ID non valide"); + $this->article_article_id = $article_article_id; + } + + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/05-together/model/Mapping/FileMapping.php b/test/Charly/05-together/model/Mapping/FileMapping.php new file mode 100644 index 0000000..e26665b --- /dev/null +++ b/test/Charly/05-together/model/Mapping/FileMapping.php @@ -0,0 +1,64 @@ +file_id; + } + + public function setFileId(?int $file_id): void + { + if ($file_id <= 0) { + throw new Exception("ID non valide"); + } + $this->file_id = $file_id; + } + + public function getFileUrl(): ?string + { + return html_entity_decode($this->file_url); + } + + public function setFileUrl(?string $file_url): void + { + $text = trim(strip_tags($file_url)); + $this->file_url = $text; + } + + public function getFileDescription(): ?string + { + return $this->file_description; + } + + public function setFileDescription(?string $file_description): void + { + $this->file_description = $file_description; + } + + public function getFileType(): ?string + { + return $this->file_type; + } + + public function setFileType(?string $file_type): void + { + $this->file_type = $file_type; + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/05-together/model/Mapping/PermissionMapping.php b/test/Charly/05-together/model/Mapping/PermissionMapping.php new file mode 100644 index 0000000..db0a4fd --- /dev/null +++ b/test/Charly/05-together/model/Mapping/PermissionMapping.php @@ -0,0 +1,48 @@ +permission_id; + } + + public function setPermissionId(?int $permission_id): void + { + $this->permission_id = $permission_id; + } + + public function getPermissionName(): ?string + { + return $this->permission_name; + } + + public function setPermissionName(?string $permission_name): void + { + $this->permission_name = trim(strip_tags($permission_name)); + } + + public function getPermissionDescription(): ?string + { + return $this->permission_description; + } + + public function setPermissionDescription(?string $permission_description): void + { + $this->permission_description = trim(strip_tags($permission_description)); + } + +} + \ No newline at end of file diff --git a/test/Charly/05-together/model/Mapping/TagMapping.php b/test/Charly/05-together/model/Mapping/TagMapping.php new file mode 100644 index 0000000..798f6b9 --- /dev/null +++ b/test/Charly/05-together/model/Mapping/TagMapping.php @@ -0,0 +1,44 @@ +tag_id; + } + + public function setTagId(?int $tag_id): void + { + if ($tag_id <= 0) { + throw new Exception("ID non valide"); + } + $this->tag_id = $tag_id; + } + + public function getTagSlug(): ?string + { + + return $this->tag_slug; + } + + public function setTagSlug(?string $tag_slug): void + { + + $this->tag_slug = $this->slugify($tag_slug); + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/05-together/model/Mapping/UserMapping.php b/test/Charly/05-together/model/Mapping/UserMapping.php new file mode 100644 index 0000000..400ecea --- /dev/null +++ b/test/Charly/05-together/model/Mapping/UserMapping.php @@ -0,0 +1,87 @@ +user_id; + } + public function getUserLogin():string{ + return $this->user_login; + } + public function getUserPassword():string{ + return $this->user_password; + } + public function getUserFullName():?string{ + return $this->user_full_name; + } + public function getUserMail():string{ + return $this->user_mail; + } + public function getUserStatus():?int{ + return $this->user_status; + } + public function getUserSecretKey():string{ + return $this->user_secret_key; + } + public function getPermissionPermissionId():?int{ + return $this->permission_permission_id; + } + //setters + public function setUserId(?int $user_id){ + if ($user_id < 0)throw new Exception("ID non valide"); + $this->user_id = $user_id; + } + public function setUserLogin(?string $user_login){ + $this->user_login = trim(strip_tags($user_login)); + } + public function setUserPassword(?string $user_password){ + $this->user_password = trim(strip_tags($user_password)); + } + public function setUserFullName(?string $user_full_name){ + $this->user_full_name = trim(strip_tags($user_full_name)); + } + public function setUserMail(?string $user_mail){ + $this->user_mail = trim(strip_tags($user_mail)); + } + public function setUserStatus(?int $user_status){ + $this->user_status = $user_status; + } + public function setUserSecretKey(?string $user_secret_key){ + $this->user_secret_key = trim(strip_tags($user_secret_key)); + } + public function setPermissionPermissionId(?int $permission_permission_id){ + $this->permission_permission_id = $permission_permission_id; + } + + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/05-together/model/README.md b/test/Charly/05-together/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/05-together/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/05-together/model/Trait/README.md b/test/Charly/05-together/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/05-together/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/05-together/model/Trait/TraitDateTime.php b/test/Charly/05-together/model/Trait/TraitDateTime.php new file mode 100644 index 0000000..6b56182 --- /dev/null +++ b/test/Charly/05-together/model/Trait/TraitDateTime.php @@ -0,0 +1,34 @@ +$paramName = $date->format("Y-m-d H:i:s"); + } catch (Exception $e) { + // en cas d'échec, on met la date à null + $this->$paramName = null; + } + // si c'est un objet (DateTime seul possible) + }elseif (is_object($date)){ + // on formate la date en string en DATETIME + $this->$paramName = $date->format("Y-m-d H:i:s"); + }else{ + $this->$paramName = null; + } + } + +} \ No newline at end of file diff --git a/test/Charly/05-together/model/Trait/TraitSlugify.php b/test/Charly/05-together/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/05-together/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ +PyA07*naRCr$Oy?K;mXL;uNyK8K@XDykvuc}h1w3K!%v;q3 zGkvE2oO7iArrXBGHnuU??mq1~LH8jeEc6d$;F(UZYwoN490t{4fj?FlPO(^`DFB3Pk7mWKUij zbKkMGdKP~Rj9C{iA`AmweDS9|^w2}R^2#e1m1;3^Y-biITOeKh1zrx%Om1?dkdfT+ z^99rdehnDPJL&gsJmj2OKwaGGm<4AM#|vTO@exw!h#vZM=N*yZpHeREG? zITcvr``LW53mMoZRLy;=Sj)NZX4CpZ@Gc9+H?; z5=SkNF8MuqS8v#SLnRgzT!e;>LZc>YCRmx3M=~Ico#Rshwf>s<+~g+sCs>qsm-8|8 zo9nOUJ)#wmF6v${3ZxQ~TBg;CNf&iVFWi%6-%Nv0Tu=i70V+@<#PfVCO!XxeE^$K> z3<-#mpUpWSvf{Kv@_YFng*q>#z6_Amg}j#nC=pf!PU7y)${gwI)NE1bdH@&hN-nQ= zZh>@p-H&&5HjSI9O;%`Vp!z@+`5qBAS<|`I?o$!S zu4O8KrXsMzNVWyZI@YsQ2|#Br!jsE2@9Ltw2VT4&NK2)Hib-3R^y0YN%E47u%}{{! z4GqxYnMr2KWqjAdOSyPvY(?wVRLo-HEotaQQADUrWT<{_!8E9*U24jAjlov;J9X5VDmb5jTx%?f_cpQzZo$Ow~&kQy)=MErdJe%=}zrJPDrH647hf?^vbsbnZ8 zwW+46<5kc=jzXOVmS<>>)lkVGTUkc^2#kopmRI<=wF*5E+_d#lws&>W7Jw^aNY4hG}4i0z5+{h7?FmsKp>ndj(d65w~vM$*#^$ z+GCK0mVjA5U*0{{0_ma_(}I?CdU`TyYirXnND}n7Ea{>y?uB?#Gf2g*RWTWk;HU2h zNXIFpGn8x>->~8gthlp2h5~2|(nz@40@T?cl_XTNC3V9FNPQDLTP&+b#+zY95OVwG zom|%0MZ2$)N7zyhl6R3LQk?Z|HsCFHcittlAV{aCCZhKC_7+Gl1me!>Jym5?#g77o zihvY&;hlrLGBHj*lclUcYN{lU8HG4zMC6Oj4dU9V_@x43QzxOsk|uRj10)s|cUM5F zYM`+tRUkDyQnfrQLk-g1T|IPGCH@ruILQ>v_rdggs4`9y1@){h!F%jQiw0@KiYlAh zYE@gN3qfahRrE+?SdjE#hj@8nfIxW>~z|=XZPiplNG7U=nz-V z&kG?8!7(B2f@`Y3i7PBw>A5t**=ui^UikBPS}l;C$BTO*4sFCG6YZCplud&Z0@8s) z{CaXyxw}=vR`IHU)CmI|-=jD=%FxkwXmc!#a!tjWs;(J7l!db-*`y!Jl1faflD{!X zZDAONSmiR^m4IDtJ0IPB4ej{~xgbIk%Cg`BFT}G=QfpRXZ|sLQm(Vfr#KXqGmJOnr z9aRsrF2ohR@b9@Okal!*%sJDRCB5*sZvHb+AQh{n93GRhWiSXlcjOQ+O-`xAQ4nc& zR=cbr*&yJhpFGPmk39_I!%(YW2SIE}^`SIKCEYUzq_I0J_1Kyvqy<4Tg_FScSk> z?rp=AYInEJ0hISp;jg%^@!!Oq4Ggk@%}Nh0GdlU$rPr`6O4C&faSemOFqrZ@!oD6h z-hDG$?!OZ@tt85t6l0L4FcsL7$8UO!x}YU(fpodT@idmyk5{;9P_iuz(!&Q8NK5G~ z0Zwd54bnkCN6q8)r=H>mfBQEuG6-HlWqca|Z9>fKO}*)VVrq4{wGERF&u1q&?p?c^ zySg{gGviU2oF?1RLD8`|mWfz>?=5Wq;=h7b?U1u5IP!9Xw79(Ww>09a!f!4ce?gE+ zowO~dOE4`|#UBA(||ZN@pn8CMVi0QXjmUUBCYsSl0t> z4kcF?f#$cQEs(~6$I0$)3#5x(p3CETYS*n>(kQm12}q|JAT=aQqe0qMDskYMXEaEM z1*D~S1yXTq)4tDoEcVdDXSQC=E~}GlzDmk)C=fB;m8QIB6W9FjpNH*hpxvS3=nSup zN$0w|Es!Q46=jB>{PZWPpY*lYUd3pEba{Ypv1g${npo0>Kx!&?x4oEv^lSLTgW#9z zAl2O5*&U{*OXR3zlwsidJ}ZIUbo22oS8`oPKfTi)ZY`t|8BBGinB2CC8~@`MVb=!e zO5??32Wg{A>aX&-f79i9=2K>P;e{7?=%ELB{q@&dAYCjtmdo=_57OzAENR*gX)hIH zODZ5eLFCP~q`DT`NaW16YR#Y(a0y?@5%2>W$#C!1J-n}T4Vwy(&U+Y^!(`fIY<(9u z{onr{cCCY+ERn5S>*j*81=87x08tBk?z!g_NZ)+(O^jCJXt}^|ap!R|NF}=~?(P6D zO$tbJ1lWq`Ahf@wk?uGDuWwwxlsY1*CK8l?gcK1F4j7(!fe=Zd|dM zn|n8KquE8rjE`+NOt}WbD>K~uAHD!LUk)pBI(sagHL4!l*a%u6oefga-F@bnrW8#)*h*8nX^DD1p5}_XmJ2p4$nFpkakzA?0xD94bs75ipY>y()p}uv*i>k zEB{ZvtC&<7;Rw%)RJ~JrOE=>3@zs0y$lA;3I5LH6S{zRYSl4dj%K!7A7Z$J5CzW3Fy5DG}6;EX^T z`^CytReh#fe1)p?mqySNnyiWp-k;sded{l0citxJMNGBZOs((W@_+wn(zos*vO`Kn zs0a^<>U}G_8%xa8m%u!hw3RqoJV2JiGv|V|7=u)CcTWM*Uf<*GCw|PMfA#051nKEM zTXW1h7o>7NU0AdQ0lVqtp1$3DFte6iIiT9^Fqn(z|JW^T`~3Z|aV7b}B)K-p3%6p@ zdQ85MyW0Zka)93A&!G-d`N0gB3(`_5hc8_)P1)UZ3R2Y_6HADyVSEwohE2N%Ye;jA zy_yHsT+Rlk4N+>yXHBf#8@c8WJ_CEU;5i|dtr|~TiKF-mEa>jG$P9}I$Z~k5x}l2E z7ZFKzH?gFLrBy9Y@hm{P7%MtACY93=cUSsEh31zFO*(y(HCTMC=W?!Hxsfh2g>OWZ zJ5${Bd!NGk_$`ow(3bwv*6g80TT&4sYt}f@FKl(eEC)c&cMh{aDlw_4W76lEKpGg* z^xdeFCYJP(zx*>I$?ndHNzW9dk}MKZf+#g4QoC*dnZTeoGT6gPZd$#StGd_Gm+NG@ zRAA!=ZlLdTABG)kkPh@PQR1G%IBM3{Uat4xT%Xs1mb3-ZbA8Fr@A2v&H6lW>q^8Nx z0w9&d(Y~jj>#dRHJ#fTJ{#6oV*M236k-QUT;V*k*Kad*?>(ShJIr zp2b8^VfXJpz{(F@2Rk=8rv>fppqS5-U0+L6VeYL?^#H zu-IvJazod8uJ2e!fA31njVrm~cRm3-*TU9*ZH0XiGJvIep))k+aNm#ORZD#QFPG>?)6e=z~I1=5QGdW%0v0jUg% zP?l7=yV{bT4x~a09C+bbzWvAl874;0IY^b{O7aleplOhfOfr!{FBX^CE4gCLX4dwu zqJQfquDJVl*4=so^!HGuN|;S44_+mUl~T*uL#zeT#jmB-Gtbi%NI)vHSp=ja=~)Nq zcwWn=%yDA(HD-h8aQ8&aw6!g#b(E{n&Ub)um&e;`E@nY=m&IRc!<2oh{tl2T?c?W6J zr_(cJBrerJllU}^$x1S8%5<}3Wj{N2?Bx9)xs%=Z+=jiek7>W8_`GSu!WQ9dHOHp$ zI1|veKzh!WTI)b(dj<4}!iKvmmUKiE>?I~$1|SuX$Oy!G7FZ>tL)viYC&Rj27rmKw zZoK^#uK(CwyzirTQZWOSDRwOz%d!ZqIho!waDUbNHogDZUgxEJT`MMC%B#Hu@1>OH z)xZcDMc8n6f3i$KDwiM`Qz63IGXKppBqI&oIP{tstk7fU)=RnZ&fB^3zK?R{)q5~A zDcuzAYLJFaEBDNFdE*VD38<&a5-*qOZVQ66#ob*3WSzseP-7s(lEyJX7{u=a$IL0`kuo(x`-~A$;t7kvs2o3n;$J&;5oeu=kQ<` z1xVw?ucj`>>iCiYmdW7~tBMerBg6+x+S}Us;vf7keDM$dE&W?IQ!M1MOcUF-FolRO z^J$u8$KeY#9@sBgx{X(}Gx3xafXY&h!e>1}~@8QiSJ zoWex`(o=nqghnWn)k2wRYN}FAA*iu&-FiNB-#y&*v3uEd-PO3+EV)!xHJ6KPtSqC< zkpbEg(;9qR%=8_#d$YyhN zc6ZU$-A%Tw4cmtmc7_aE#zh{Unk%KDD#y|xaY*F(M7~dZCabKeIL_i)E*EenH+n&L zw*}IR1fB6|o-IfZKK~5g`IA39KeWKbUc$uPjX|1<=haBb#+NVGB5*B8J8a%_B{$!8 z8<+373OAR<$)-uSx6{?$Nl&VSb~jBXoziOhVp$sIg<~5N|2fgq%wF|YNSRwMHKq1 z+_sggZ@Q6d-v2(@R`o(#hRAT}&i0UVvt&{(Y0D<(q{uocT-(O zAZx(J!^lHvjGOal;tVgfrJV~>5yuuu&j%lTh<*F^VzeyjnXIx4|J<_$>HcS);^9C0 z5{wRCSdb={P-4>9l1d#^7)O4SXm;d#3Q^f@o7r{k9;S3BKVF1lo2+GR54s zaczf`63-UPYZ;h*E9qIYnmyND$2IS}nYL9M z@$EE`ZBY|)zGdK>sGl7I(&ZA}VZ`oLYq@IU7CJ2hH!jntfm1T@DhSl1^!f*FUh*=r ze93%b9Va)}h@vp$>8BC}`xZ!-D;7_AUS|tZkx%*VU;OF3@+l{cnNW@8rvPbO?l|3r zTc}xkF3rzY>VdHZla!B=XNiF#Kuy`u)<&kSou2-6eBk5%nx6HW=vmW8#e|9(QL_xH zDl6oZ@+)+Qu%~w|H*VQPn-6JQCz!eCr+_{5XPcK$3gWHzHa82^%X*Kcf>fW`yZ{sG~Lr9x?gpM59i6TsK zdFK-Mmts?B_G>n^sY+E|s&kjbR5GHJX_ih^z6 ztm@&?Ti*v)?t+v-=o)y^Ef?zxpX+WmpkbA-v}9`AHY3v&gsWhF`v zssg?ti65yECkY=Nxi&Th0iu99Vl!#(>)Foz8!w}OszPTaP`?ihL(R__P8pb2Y~za0 zKLGFF16fmz&5-dIOAAs>Rh;z*quG{paPU~PdUan5q-Tzo3-XHP4pLRBoV)1euC4_% zixQwF7QImt5r8JvbpFe4g^}uz*^0~ko!fX|<8IbWlS1=6Lt5$Eb%mIFu|?(qDKhXoAj$@R$v zF3wyX-c#@_)KSD*N*#174)=F$52xsE%&UcZ{M2M^bQk(m`w)4P-%UCm6p{wH057OWL6ue(7sYTVXi7Z2d^mIGH zIk}UKgDeQrW5u;KzfcZ{P{ZEQh-#rqq83|11DDflLai#P@1}~OCa-HL{VRf zq@n7Wr>muk!1w7NvkS532c)sPt3bL3a*lF$qq-$s=p4`89X>rs2QXS7o$q3w+Z&X` zXbUg4g~@0a0;J6T+RQI7S)nh@Bw%pyhw<5VYI!Pgq#zkD*jaw*j(&XrrwMs2HNMlk#^68||pTnfTvxn8~U1V&B@ySVMN(E-TA~m3_ z1hF;QAQ1=?pd~nLc6T+ysOjU^FJvNetw{}weVmmg6_92fe6gg<5v0Glb<&2#Y%Bnc zJPpM-zN&xM8aa~nlUOY2g;aeNiY+75?YM4N*P5Ii+a-TZOokNURU>kuXcwE4y1-Ub z|7CKHDlwyC!g#70Fhax&0|UG=KBI>SThdjj+nh6g$cn({?I$$BJ{&xzq_xesOrkar zi6u`PCpI=KDQ~o6u$C=7{Tq1g?Kc=J=Q&&$V}ugZM3lv%+Nkz1U)483#IcRI zS2eMo&BE3V&qV{Yv7t5j!V94FJqgm^+@|mOL8=#u2C3fE^%QCi-9#obF0RMZsRL=i z*3wt8eN3!?HW6xmi!vkP%4%Dz++3v(8)^3{jHNx~iB0m9^7AZL@qB<(n#fOE+nf#3 z4h%Mv<&*37aMjB7xM`PT6Qk@KKf&7*gX|9{m=U0w2A*qCj(q$;N+9~=)uz^DJ)8ZN z`p@-iprt$)8zR0ZLHe6b3!LrFCLU)3P+ew7#udbVSyP8_;?4RkKIiH0vkS;bbxJaK@cdt|o6cLJGm0>E^HgUgn461=9)>8nQ2&&8XxsT*^N$pTA z!uUzzkSeFt_sLk6O2`PgS{q$$b#*M;6yGZBC$nIDN*Ii)Sug{<9J{+3q{=B@oV&XS zkS1p!F{$)wZX?6L>AQ;G>fV5puaGh=4A-WTbvPIld1G>rH%5+f&>vxjK*g%^*{ej9 zfSQzZ=FDkHK$?)}^|fwJsx7>*gs`9)NAuN5wH0rW8Mbk$lwevh>B1NG!at({0$CHv z6_dD6GM8b5bZHo}=3{`#f~&^h%!g13pccv?+z3zVg~;oqb|{(80N?ZCeo3*)2DV|T zMV*nc^@Oa*rs;HS(qdgCQyO=CD7Raza#M*TNnNQJ*zhSDFea9CV1Sn=bWG}-);R@f zGjTyDj!+=|-0D5t(y@W=N<><8gXFqc2BTq>$yCHxCgRt_hk0%MIOUYZbgjgABr$8C zwQ`%LMI@VFqR5c^KS{35UL&UvQBqz>LJOP=Qq4FLZ>D0J3@cjTHg-0FG-yg3or0cD&>GULhD zNyMw?lWHNdq7gBM$xj9j@$!ToB781Es<*F(Fqy=aSztS9zQ_H-$^ZZ$07*naRIq9f zw{~n`MJXaz)9!3!o0J@}?lp?tX^w_PCNma?^J5$y8RE#q2$R$(;88_tt=hVZN1}k6 z3}0$a=+^5q2{=!Eel@RWnGFKFVge zG=p>kOAisA$WuyXsTt-hOWNysO5^DJfBhAF$?k@F!K&lQ?lH&RZFa94Al1(okY*wQ zX^PLUzKYx0H?XQ~D3D5)T2%Y|oXdz;V#Q_KXy3e!ePcr$96rI=)FhMDB1fmk7%WUN zT$~_}Pl13Ufr?!Pu+q~hpgo(1oS%$b+=>;`0xyqgff7bYPF#ajENN}eR(3VJyS7af zmtdBaCB3-G3@7iXD(#|HR&00Trz96$rGgA8!pCJwm0xY#5^=XAPMi#3I3F-pDKS*c zGwIiusFo>s9yO(AXA#Jv#L#i6DRekf55JAIb4-!<5Ri#>j>NX|<%gJ+8kr!XLzF+F zkUOrtj6N4Sl`^az|7PXHQ#4sVw4k;qYM|O7^xPS3@S`g zA+G=%Dnf+PI!d^}aZ~u*`f*}#6VktGRRgwQ^6{=6Jh1U{`o=4CR%4JFQWnx6t?t>% zWxpo``?yZ3MlI^i=7NHBRu{}gO$(fr1JzccPAX`24CgS0l#HXUc#3=Fg<>@$GLEHS zF%iMO$s)&RW*D29q2T)z0-vg6B*jV!z%5(t$e|)97z9yVT2aP0ib0iFsz!N3K&zUQ z&4^SG&|dTDta{va#g(jcWfC?-RUa#36UDGK*UXGeE(Q7@eHqcs|cSxyV!)Q1*QS!&KlDKiDs*S zRdL`N<@bjCPDB`lDiLJa7BW4|5W%akhE=Q4QT6Gmc-(*WRcvrj(vwsYwnVJ=6US*u zy;MbqF~L0nsUkBRY=AU$W@mRhD-{LO$G-lT_``!3e(fB9)K(z9r9(h!(oxmPBXRd< zG8O|VkM=vSXZvSA4%;_ExeOCU7|C<+2TzedbexGJ$FaOXCDNvgd5V!o-UukBOh!sG z3{OokUdmGw>+DyU@k$h^QWin%*jJMK+nD>(kkDO&!JXDd?pb#!oBb5os;_qI21ucD z%~p0dCyqpsFxJbykd{<7uOCXQnt)VV)h=F;He6b5zmm@Vcw#_(h-?hdqy}Od%vcdc zg$Gl89hsV7C|_WBdWPwmPr;NfeNDFZBSQgMmt1s0DM|I#`zj?VR3H5wDVkqhrcrtr z<7}-d6NBU!k&o+p$_48!``ml^)oip=q~#n-Rj3y0?1sRKu)5m8m0m}2sV$<&RF-71 zmQ+A`;F+iDAjPYm7Nm(q)mdfP5n`v)09)pYhLYX2_#LsNo$KkZ*>#YLJ1U8zfs{|~ z?i<+jxsSunO~S(0u1GC}qsN(iYd@o}?`LZ70Of%}%$W*Z=^Qe3{`knSBIzqtdNX2h zYMg>!Wu{spAJ&+Xtajv4u9d09<0z!_MmB1>!qr-l61>#F1Fi7D&&hg^gXyWK=Qfo z3wcttn#wq?Cc+Gzqr#Pswe?LoxV>3*(VxqYkyb4xJq zF-w|UA)P)*vZ-~#K}^T{u`&PJ}fErY1Q&GR|LEXdSQSbBgt};MhY>OWNJj7V_4HE97u5g9hKCqDae|SNVPcv8VH7r%LoyB0hP=b!@RRtny9lQiYz54ytBItusTkx|7w{?qcg5H^GWFwazWK zEe0tR2pKaB?e3~NX(o|;2haxa6TOpXjexuk~!h4SU=pM!w37t!aN^wk1BbNP*IHM8{j7EYl`M>@l_ zS79P!knhQ`}!Y z&KRVtui%!>b*!#X2dOOYk{NL{hXU#5FMbL(_d$CG<(|l9DsH=KAeZYZH_n04DHxrG z!y^=4-bXMv$@tL|c$0amqf@xm0NV>lVX9Gvs=d#YjaN3{xa6gd9T8d~u8=Njs05Xz zSX^3!Of0DaX&Oq`ZPFl>?5-s1WR%5n1nGOH>Dv%vryi0Rl?7b3pk%wM+VW?VS zN)kg=*?C=%#bHRfLrN-UEW8}5o!BsZY$3kO3{2n06`+PvW(X+^4s&eZeqR5@FFCw# zAO1{%XlfcN745?Lfts1=*d~GR)k`vA=o1989fY(;usSqZ5B%HRx3PmP{Q}aN8fM8? zB=ll;mcsfTQaA5r<0n518&^RlO=x8lc_Oi-OA1mMeiX&-u4H#R*EU&FVL`#94M*Cb z^P@MhT|g=xKwDN@(jLt3I&W}k>cnW2Y&f$ z4*&9HrjHLYIW!o%v9YfmX(o@vtyJp69Nn=ae`O){+Eos!2B~l5tS*;3M zOLy)(P~l4_EC#uRivCrBLJ{&+q65ds9~tD>z5`4iJ3*=%Vw9>x<*Fizq`Z(+Xef`z z4GmICK~Q8-i(_A0 zAf3zI)EyG4`%~@E5uTJ)EQ6tv$KK%~_D_y8VusAPHU&rGP74cL0aF%?Daz)ugG)cB zN;Cz8ZiFT7SUyi}e4O!j-r@M$Z}ZNpuQIiFKg^VIWAUvfJq86zbuI!_MbOu^84c1H z2=R}y(1pApApJjf-p=kI!@8P|NiEw^qzQ?W1*F;gZ)Tg63RZSOCIhyv-7YOiWzlMP zzX4LQq!N=xbXEnV(ul4>dNgMsAl(|fyJ1^aS8@_6iMmEg_My(9SNVXXbe0TFirH4; z0!oJ5s(83gJ4_W}d;+Em>MIA3v{$e8#_cUQ*3EHOw`LZz`O)ZN`=%*4e5(!|lN^ZXR+M=^d>c|>RT zCH;S(SmNO11ji?*7%mm@GHJ@TP1V-Pp~z60=n9zfWyh|p%G5>yY1^bWGtKa!LyR1J zho3(FIF(~ZVRST(H3PL+6VgH*j7oJN2C2ALazgJ4q&COfZ4J`jjX|1CtKmY+52V2? zODZ7k{>b~;EFj(5uRH*uQ6^kq#du0GeQ`J1ydag^Ef-pv#TDl`X*i9ibt~$X4l$^C zAoE~`#}qijVwtF1qcWW*ELHJKRlI7AVx>e`q&wHHX8ko+klwjPd0*NCVTl#&=buli z$P5WcFCH?3cDM9SETN6W7rHPl-6@I@BpoWij|L8Nw3uh6T%qLqIPL8UoPPWz99xm0 zly)&&N-6Rj6@Nyg{E*uCBzu4LD}Mdc7a2Zu5XY-h9UD=s8CSGfJ&7yDbJgdhNoui` zNR$|2v!N6ZRF3^@ENL@HKcy|H0;$eiFAqy9G3i`Oin642kZ$Q$F=+#&+H27ujU{W6 z?w7fiG_f!$P@L5oqe&L3K_FCpxN^LDIU{jiRJtIRcf}4yS87A0S_Hn zAG+AIv|}a~0n#H!2BLNAB*)nNSdO$neM1xOywp9V+e27%1G|yG9y}BgH8G=-@owA`w?e;{wP3~hiYq#-2f;9F+WmD7ct{cas z2}lFdfu;pc*-ao7+MQTZad(?sI%N@02hv2{LcMPcP95m0YoEmV%CI)iGi|DGC)!bs z%ioBw72u^Vs&`v814fzy~6s0#Z} zjIeKPjB(eYY{z-@L~>nI-?cKGlu>Mpv}mk)6?$Ehp@Rqb)$`Bu){DPj>Wu@CFGH=S zxVCmE>gNGM#*@XNdLESPk%71X6K#+XSSt*oAd; zp)6^9`gSBSX*36s&u2jbU+-bSX4?h%Mzpq4;_d$ZQQi1Kw8(lX-XvM6O7#%QJiZ!IEU@Gv8L8`hsgNW`-2FI^Z85?GD;2qxl`HTGO`4h#<38axN-8f6^?k)tHN1nJF+{ z_VAoEo@uM>sN!lWPG^7-Q~jJ!YLo#zjzf8TjG+Vj_|dn%!ST1=gy9jaR8~>SqMCYGf$AwEk>Dj+@HX4BCO(p;KInxdB_NSiIG zsbkV}4AR7kCb|ufs6@3f_;?vdW2iUwpN6j2mZo>x6~byLxPJ&p0MkWCq)2u-&Hf-kY^WTHOULkj?_B z3WDP1hhz~aiMzxdu1_3D(iEpq#7`KDOJ_yn5N=MLR6zQ@M<3;(2Os44@#D)2r1kW9 zoJo`WhrW(v{(pPL1Gle>l6zpH&Mv# zktm2wF#fAw@ZA)TaLMBy(FY{mgT7&nrkB9g}t?AnntMBNdaz zk}XTdI9gOpdj8$r#F8d}(y5BsWPn+~tv~kb5 zC9PpeKdWg{bZiFOY`X8gnN4Cz-{T;aI6H|o>!UZ+FPi=kySwKLqzdy(YD(vEcb79r z)%|GBaw$Tz&a_EAR0s>BVU5=YCpk1-;DmJQi?EdAD7v2%L}hS;@QH*GD(9h$XE_-=q*0{Apf2ew?>Q zD@++KW!Iu&2@zeAL>i>xCP_b`8~8Y-0xN8jgFk22%|vaGAxstd+8gzRlmh~3@Z`)*~O zh&cCkDusjhVhN@N(%IH)R!q9Qvb#;bu3~~1iUlI|(6KONpfthHq&+D}Q+6_x9X-}S zIG5rSE5f{J3>hJgsPXw8m1D>FhcEvL#RCVRP*DAaM%5$oByX(KeVX(jWzQyc-o#&u zHCV;%RcZh_bD`_Dv50jtCr$lMeKi!{XSFxPmRhz30cj5)I*tGClH0g6%F$mjNf$j_ z!@{=&q?XF=_TGCdYn3I{AQg#-CFky*=fqJnNR>uZ^WHWmCY|lK#59$rr874ux#->9 zjvJOfPj&k)IG&QQ-5lBS(3Aa0EBotzyuMEo$dlpi1Zk(&#J6qKs`K?I?b$MT~$yTPyW)K|4IQM7GQQ%^s6)k zm9$D0i!?SarsjVtK1?FLtp^K>ev;@Hd0v?=U^6K`d&$jg@>8s+Kvw8=SV|SY;7Uwt zvGQZLu_m#kZ7Ib?RvGB1t(TS@1r7Wecqa$;iZuYh6+_&JFBEl zspPX|72rooFpc#IeR(jD4#D*n3 z;m=0n=wh;@=NmdpclU$M(mVsNVlJR}U4!px-|M*XgKJ~2b1XoSLwOH$>i7qC7V-rY|8>6gd(kg?v#z6LJK9S=ZY`*nZ1k*AQL&RTi5^}Qk;l5JFwZ9 z?O{)MKilk1w%Z-_lcLMl`nyUWM>4k}?%dQosj|SyczG4pCJ8G2c_k~Y8TEeb?s;MEu=Rhs61=8gKQt5(u^brB+LmH%e_r4Wv-@bjG z@Ow#V7x4m>MQadLL;RG(kP-0aa-xo2^OX3Q#G7Jq#U)l!lJR~ZZf}FdBqaS|gLn%SPey_@lM-H;DSR`+|cu@*Z;?YQhR40r)T(3fV6mj&` z*ZB40Kjxk9{}8+8D_Il)sC2;uMnIt4V=acH7)G&jof=mdFA!x##jTatGt}b{v!a@;`W`lS@4=Zn@$GqDD)?u-(uql`!tZ$RtRDmfQ5 z2ugS0xI!gX+1&)BH?dtbj`}(YvT5nGQvIxF0@A%tKEZeY;!lZ2PAoW|w0SWuWp=j( zQhnt`h-?{yRFlG@$Y92RSEnZV_1F*tG8fcz2?U@r2Spg>$}bFXLXS+fLc3Svl_#I( z@xTB7;KVQ~v2L-(t$|QzAQ=+Ud{!&j=2K3t9LiouieVVOebw) zMf#?+0=<}68OJB!l-EnSR_WPcGl83+YWf&c7f%N>C#Iro= zA}r}!Z@&@kxMasNaCa5zRA^QWV8VoFj~?cg@eyWHDK!p4Wp$OS8xQA=d@_N@8rx>_ zt+)B_U-~i=`wtKnWgd&r{gU=t+Qkb4Cdx&^_B3Hpl07*naREnB!>Fb5}^pQjC%}C43!#X;TNy& zCc9B&F*6h@6&xu;DUe1=nsP*j2p>Fj+JQ|6pMQpL|H&W1_(%(+=Lcr4L+Opcv$(swIybe1@KS1(%xNZ)wlwdm4IFI_eum9h6yQh0N6hUX3+WWup2 z+FBOH4m8nDM&Aj0sDqG>T9vn+dWuKB{xyuLX&kRctz3%Nyav87hZ=6Kc6YV=+h~mv zhLB`*dm^}}dz%92ZljalLP&c}n#My)jvj0)z!ZQwl>pat6exs8Jd-k*Ov8qouA=Lz z9dO-l*suz6Hl!`p8W%_w*b|U~Ww}_Ug`u-pT9Zde4k8~aB^-G(v9xZi*A$m;+cZHrMdhsGa`ugjyM!RlTJ~#9L0`x z154$76cw;qqC*rFMuz$3SN@!_mwu^uyD~H>5RR@Ye`sscAh~ORianOhumT*Kppf$Q z*oUoT`0edCa;4G5nvzLZB~rp{XQ&aQ4X+4^8{0(D4U7FfsD`uudgMmCO$q3fp^)nFMBI$EJZ=Z>|A zumwv@}zy39X*WZAwt2nhXNy+#X%w4oK_vGUnK>kRw0u8SrhmH9REgLH~wT1FpUSW7zXm>kKX z)dIgDLxk7NBaVGC!M;_3(J(xz1oP^vFGss~?_M?_6(zu5&E$Fh@F9+e9_4g8&g@#G zd{ZTXJgTh7rm+Tx`SxG_6^9>v6lxU}+sTN4P(+$#1mQd&m8GtdxTdI<>y_UnQ_gB| zWxA6Ot=Y*fnRWE#p{*7v4z3Ih7EFm16{U0ehi&0I7Wu4=vAv(Qw_k_xf$L$*YCQ^D zSVk(t+*Fp4K31iUu47qc6%{_4`m9W-n!1kbD(#qv(ABCG@`==|RC9Z5NexM|!3zUN zd3j=zQaY`a{V$}uDU}-jkNTRPEKkvd;OxEY)MsYnh@R%q3=O& z1nmL5-(AHgwqMK6N}AphxN4x2CO;%44@Ej4VmkB**L0KFv4Q>%+z7W_2isOdc?#On zir^>_v}PS>8z=xzdRUcE+B}w2ULqsq6<0X!Ne^Q&Y_0FG{6RXCvN)PSgH)JO+t;=% z=_!G_2#~(~%1hA|mtV1@mb6a6YogI6%77z5#IuJFvbUJ$L>N%ZWEDt--P(tMuvO)F6I60>sVVb z$yIfns7VOgYH6Svgs#nim&dvG60ZE6kHfb0uznS!q>LkUCDHwjGr#pK8&_sy!h?pJ ze$3W&N+^nr;X~qTC*wMmEtQ(lX)LMq+NxS|JfF0)QeohQXZiLY{U?|jQx;w}yZU3! zeA4<1o8%mu6!#>Y$f_|DX+GO`xf&w8svOMfC(WmAj-;anK&rijc;C^<>=rF>es_1N zLE7ZlHAJZ6#V_97NEoTC?%VkphN4h`)Keg}NPEKT^f8PoRx!^D|M(4Fd*pj?Vn`*7 zv@;p1nx_V-zUwEe{GrCR%hc{R#mhChA-jhAR$RiBRyVzc2uFFU(o`;`m3U5wlsqhh zDJvv%#a33_eFJTG+^A=?ID&ksj@TGt`Ri8lnf}GEU~EFUr2;&a5Hf^IdwP&sF-V1*+Yfwn z)n(k%yOm9~6geR-$Rxekbr!{Rse_7Dok|-N*LJb#o?FP>eG_b1qvv0UOX>7?LD~#fwGBz)NR57!OmGsD9^>W7aY`vYX5&IyQUU4VbVS>oH|WNI7D!JM zl`cbfcOgqU97a4P1C(Z_851Rgbe6zyutHO*7Ni0nml{KR-{c>^^d}$#mI_7eKvE@o z_<#m!!=aqdk_t%OFr+hr-Q>7u{Vs0F_OsDXV;5^`PKba>Tv4f^iV{T8f#EiT{(Enx z_x5XG&kk)xMfJfEITziAmKFh()5r&$DM%A5t8Hx3MRQ?6x_yqj+fkK@d%3Sr~B(4uG7Chd;k{ppo_`jTt8teU2;YGGC+X45X1 zfHW1FOxG$*WDGJlT*~^-e*~`HrpG?mI#?CUUA46?Q%V>??_rSUnqtyhJJzzQ5}-gT z8b`93wLp5>eD3T&UL=-OK$=YI-d8B_{R8_rYD5%WY4VnAjE(CXw0Qwp-@~68rx~G>10vUxsVPQVFpQ~xR5SR-H-e3EvaTC&vti@ z^YY|q?Cy%Z%=t?k2}qSCUEN3=btFP$Es&l8K;@|y2}nh6PtP_n**i1Cx8Hu9v2>bp zDx)T)8IhwTM%rpZsQ0Li4)XV3{xTDhve+QdppwF|g$^v*O+X8lzbYwFeRPe9b#OD9?({SfC1UZp!(KSz3(vo6L zrH(57q(bF8&4kN$2hv#CLDfQ=W6~I;GCj@^kjlwRMm*qLXLnm5JwqIx_UR{sRFoOM z``z!VrthJ_L5!tN9BE>^b|ZD^!Jrlf+LBr}d#9)Q&i*$T&t#}L8GJ*MMmBB`k@I{- zsGr=ok8gbSt4!?M2jio-qT+{75Q9_?nLRy7l>#6ks{;7#6+5}7cMF^IuqJddD>ZeF zMaNV?ltfLbw+;K|-Sq#5&%?$pY8ib5OL)AJPHu1~gp_+)kj|B)oNaSwXLp{Ji@8=zx_B7R57LJpeprn@93CFJ zFd&s?ZLOfGV>oF&tAr6%!{F`dDZcm4+e`{b%`}1GVuU7c7?JgBbku4L{N!gm{I`Ec z>G*M?nF$e8QM1>yFqu{xRO9aEvu3d+l{%rotS^M$UAddPyEd{V551uSm8zRt?`<*Xlb6z{c1q&~{2Ksp$~3x|&K z%ESo8behmkoi~t*=F==oI!{bmXo2($?*9BjWdHK*Z!3_Fj*eUikP2l^Q)#43p<^qP za->1}*3=Z=k3m{9G8&|ji5rAuf~o@P{wJQ{(f{&asSFPh6=!hc0f{w9!zz&KnJ^21 zRASP;NQ3mA?#*nSiRhAcxN1eoEC@)a(k3(QY3wVvvEkDnB7MjER3;ZIChsSiux8_} zx^B+)adMqhU#wGu^h7BAq(^vVQiC*d(lJO4mCWg^lo@#8xpP8h5Rf)o(&ofbDoGsW zTn?o|a(CXqwpMm`frT)?r02K)`JdJ3!}0O)#t3UN2xO}??sj`+yGirPv66(;h0BM{!3IaOI2}u9*yJj2-NZXN~ zTVWhs!7UwYSXuT}cDEU%2c-ma*9~m@`~z^w258S}c4Yj}A{i~l(R_&`p~QXro8MF* zot&Iljv$@pher-DYT62t-k8B~&ufFwNp8W6s1k+QPl@gA0m>RwsIiZL? zNi+7mF0bb9>d}ay(lGjT|K;4(vx%K~lRjxVDHRp|N{-2R#$sws7nlC)k7D0;HLPC= zxm*)So2!_yZ@R=FJs!aG?+ozT^qA@z!p+9nU4yg&sn7z&k_t%2Rd>$W(gNoL>58Jq ztn6+s#i4XaZXS>(4o3^5$#ylrCH>YnzNvI~CnuH(NULE;4N20NNS*YtL;D%RMBH5g zsnASQMnr}x?(`Ht`^SIgr{DS)j6#8^Tu_!Y#8(P~iE(SVyK}8+1ElFNQd&m0r2F~Q zwyU|Kk zclU4&p53>P{k0-_$BErtv7~cB`iDxHK@=3<4M;mN8kV$k4ZVfhEK6EyOL1@>kR~(i zl=yhdlE!y-{+RTizwr&FySqF=nlJMBz&l8sr9f(EOX?aSS)+zMInJ~H?H~B{!;dPy zF0s3NYLK2B5(o!ghz!zECPR~M$n^1vEmv}NCCdh>lNL&<_A2Cr;haU`%1vDM`A@(t zR}tl0jFe1(IYrE?gYB~oNM|*G&pJp`caLh!F@#@*8fbN(81USIy&S=3#<2-Z$?obM zOP65E3_Sll-~J;3={SV7a|Y5|JJ--XBe{aa-Gy>{W;RH-uZNCYy(hLl#k=M1&RZvy z63jn;Q!ME+2I&(=4sp~AshW~FaxnamlnFV@BN`pyhhO_U_I>X$rA}|wD)YFzNyfE_ zwl3mhl8ucO>c!m^;cMaUUg@sj{;gMWZ6(9Tib=LyQ(ZCwQc;i(-oKk|pS=%m*oBw2 zaGYk4#-qra5p~`{s^_>V3Z4OPO_lk{p?5eT`btt?mgaz1^T{o~@Vp0WC$uDTB(-ugZ7t8!5m%jDj9Tp!bXZH+oqaoW_@4}n|}LVxPBLY z%F;uKo3qEs{LH#*dVVaa?#t2bsnXLPnl>Ug^XhnkpB_HMaLS_Sy3_)pDe5v%+V|1A zyHE3-FaHUQORHM5B~AKW8w=-jt!l#m>cL%`^3wZDUJ}yVKcqsy)Fh>-Yp341-#zU+=UDjHvgKHpvC%GSTNGB-K?n{)W(v6-+wkahzsLH! z?^7UkQj*5$2Wg=JttvC(pLG0={V!!AcqtmPJ66UZm6FvpHkJV8XCI9NKJh+a;%J~UE^%eP=e{JVZX!Im5$uiYHP|!m z-Qy@Yx@?ZyRo#8_L0T}`H1kG*)P?QXXfeaMcl8>qOk~jHhS<~)5yxa(UBE~pvwaH| z{r<05bJx8w}0V4P`*g75zne5z-#F|ijT*66%#SjF2U#=JDia_Y+!qt z31{8`nELVaf#VL9I!X?kK=nfV6Zi3;x8mMDkNqK%lq|$V&OzD zoL4moGpuq%Sqs>qHp9A6209I3bE$#ychASPPrV-)I|8UG>la9QWtA5^xGley4es!_ zN7@ zl*Z8-iy>i{a9GMg-aIS(XE4mR@zPy)GN3Kq*eEnS?XT#-ToK zpxki~awyrAB+W#^0@8|i&&Nc9bY!)tyXl%rq--N<}@6s~Lw0b_it|M+$zmMNQZTj>klLcTbvwY-Q9V&=+9&=7E%n z=O$X5EOKT9J8cIm8yfM%aMqdAY-x0KUv9CKeH&wWrSe=>b>{jk>C8*11VcZ z>H35Hut|Lm>spwYg9@BAVj512k49}<8kMYs=%|kCtYndmMy1A4)p^HZ+$Y};3@h&) zq+Tggsi@(ZA^Wo=WwpRt$vFDK53x^yRIU3qIuOFkjcs^oMup-EY z=?%9a2?jzc&LU=KP}0(hCvUz5FaPs4puG*Cx+~TA`)QNvoFc=(2!|kz;Y0O@<6V&& zls6|)5wfHz22~7tcatGYY|;Zh_kNU|cM4EjrWi+F%SLUJ`fV{1#3Y$$2&7Us`nFqd z#See^thNcrD?g114T?PvONaJFq5^LMB=wT->yqMgr}KCp+={b$`XO+wXzN zBG{=;xVc2WB7K3(;PDN7>@y9kd}R|4%n{Q-dB(*I#BuDf@i?ZY9`%_phNtPSvXH2& z!uSuI37mT*FkzVFkQM_e|0-+49#MBSH%DJdIrCDcfz5VSdgZ*)(1_(*cOVf_$q39C zV)+(jL>545?c9lnZu$e(J@7C>$s}^A4j57^$}>27bsQB|J3iJZ$HJ+hQ8;((4ADMH zTazfWELg5Bv1Nj^!!)q9B7_-V{2;7%p8yQ25L=$U2T7#Y&LjVIS%}QnQDA?Tq`6E6 zx88aye*EJf?|UHSbm)YEO%CwfhHZGgr45}djBSOHb~8vC9VkyGu=FlL6TQJ+v{Tbj!v7<2wf zi2V1lFlJ56TXT9MQQg(^U2z-+@7?tZq$p&{&1z4(`pJ;XCIBm1Tk*=~t=OKq~ z5mTHPVr@y3va6h{`tz`*BfYyVb>*1y#SZ}|9S+phNUID2lt9gc)YoX4eX$Cp@pYdNJJmE%>KZ6Z+o)qvvYG>N zeC8axD77<4tXYdcFSs1;>no)D zIrRgAlznGJn&!dc!P4tGrxrUV(W@#k3|&q5zeV&@wTIyN^0BCAHK+C@N-PCZs;_Cw zKwHE>TYU`<_`(N)W9F(lP$30UuZV@JE8GJ}cPG*Bo#5T=rtZEKAPuYtd8VpViHCtE z#`Ri~cy|3}Y-sO*RauF&X(MAK5zD2p`N?PS$hE%)8k&G)3dj+p4AB&9QooYu7YO;3 zFTJmqU&;x{wuht%&O#YZte%WhYo}mbv4h?8BI3fgE6i{x*0f%Xt&Y@XY&73*8u(CHdTha*TBv{lJKQq!BH z0xOq>mFz@)ycCcB{qIv*LJ@CRmavZ(wJch4mFCPPy#c02^0Tm5T|$_p5=*^U`VO z&xBz`#-NfPoGX3(`<(#Nu8yM?7>gG_=^lCHk#DLb?QNi$Q`!PxL(0X=TO08D&Rs~d ziExPS{S+d(G@4#pj=Qe87Fe@c_3@-6b$bD+FU}{j!KX_V$lmI%N~I1jD+pHMwCZV? zS2qb^*Fv*lW9qplVmL!FqsxI3b|hD2T8w<-CGW|4u}Q`DE~?A17%2;OyD-_`P}f*7 zEu_K*S}kB(4p`sOftS{ALI*6Vugk9CY0E^G($?#9YS}hQ92?O@C!%d_`1fyqgN@HW z541K(u56gawsTnlqtZ0GDw!IjbOz~LB}hqPI3hX{pBOm{)16WYQ?X(OsS}C~Wk_ea zZ50+;#@FE3AAA{@K2iFrN@|~1z=HQ#45WSl_XWnDzJDixRC9Of-EC%9hJ6jBS;IgF zfL&~V*qFi#8#bcJQ1ym#p)_KQ@ojIwpD(=vsiiA{W>RkDNRSh!YtI{@KIARbL?cawRd9Vfm3kk=RXF_84pxOC9Wg&eGN;OlTvZoUJR<9 zLCWwLt3^)-eRJza6Z6+iugtNc|BZ`wpOu+?JQ&Hb(Ai^9{ zuf7JKi{NXG8rWQBpyY@dIQVOy0>;+?v8V#6Dw?6Xqf?Sf5elzylP6^d%hbwiH3buT zusDCykL#Vx&J)+MBOZE(iz5om{d0w z(P$L2&pZ)zO#U8KrO;@4)sonL!gGo!$QIvv2dR>1l&CqwM4E-h02z-pi45M@x)mE5 zTab&!kufaUhrr~d=f^gciW*8Kr3qDX^JYAC*Iiip$iqNevxHudO$#s>2GN}+x~RJ{ zc*+UH=is7MSrSGhnH3Vl+2anz3DME0>u{ww9NAl>GV<9orXj_{H}VLzBQ0*xHLLCWa5B`S&(huaPgFyBnw2_dxoeg^#<(%s*zI0jW|SRgcm)5~{$~ zde-1IvdBepC^2%V=tyGG&Huu4H{Ss?>=fgMa>ueMdsL64eA%HQE2}?(;+M2~67eK4 z7^rr_7-7axAFaaV+EJKZKLO(oISB9i_ywq#H$&-cIn~yJUQH#*)WjC2h`0HRa~A_C z?O7^|LY((10MdcRz)~w6MJ>(Pu&WV`ok?lAk#cE&vP!)wDXP>&1r#!Wtj-RM2!-&< zLl0rm9k-)(?P?&|A!dQpGqedpwR8nlUMUbKHmQ>8lH_dyWe#w3s1|3|AB;JuLTysT zmlZ)?MAO}o%&WRaq} z3ma9PDXe(p2|W6Tn~~bEQ9=!-oAp5IN`{E6%HE`)!1J%H#gbP1-!n`=>R>5MR3MBp z*TgV0j>)6Opnl3kob|bnn`CyP}(8?dFl9lJUba7~7znDY~Y!}?GR_2eTpggL8CqCyIAN`bAkOB2AN4I8l&8MM2dh#4+wl3BFBz8ZJ^>IQ6k{dKt6gh&aC&LhX^ znndCObs!++V2ERb)$3s*W<`**(0ON zrjEDtsLn6~e?*)tDx54{y#IbY^7}smT*Sn-%)+s3mBFK{DY90um%^t>_2NkLyt}+@ zK1&?HyGp8YZrwpRJU$9l%^8$uS^xC0wA9cVGqFzhTU zlR3ni+i~-iKgar)UV@Ws1#)Sry=#y|ng@u-*$pf~lv@6+tKnWKt1VK6_GxuBTAEvs zhKtH*6!EfhoO#w+_`-!3V&=TL61yZo8LHs^oRaxW4o-SMNIfCuBjt&T%cA*-R2J<{ z4lA2>U|TkcO`RRsnMorZ4guj9!d46hD^;)>q8AjFgaLAxsh+wj>!oAWDm-?}Kd|Qh z2PAEdiSdk^<}B6JSi(hlADilg?guH=T}woy3cHMhiDRn9;k4?BI5=E`csn`4x@;<7 zI}Vbrjchz3y>e>Lo{zETo+LeBvJn&EIJ0*1Z3RR%7D}cUTlK#SWtZ-rMY(%N2PVs# z@Xw&*h;hzun2|8z zDFZ(j8biwc26qn_GI2l?gb=7Di!1YYN=tG2I}g^;@Fc< z!nq&#Z;YQl9c9CY!3aeVvBGe&HX^2l2#X3*P%xt6b!lV1IR8dq(&kLLz^>LLcDA&j zp|u$aIOs5KBq^Eb-POKpmt+9uiiY5tB+)B%lx1MZ_%X6+Ni@i8-ipP4_#4(d^)wRA zjR-R#K9h#Y3>6(qChtQAp}Wsp2UDcPjO${!4IGX#oHKd`j;b7k>JA&R3`0d6r9xBW z=41k>DMRDvGEDsZ1t>dqHc(v-gu_52sq(s9P>&UWFgr{2Sa+Zvql~ zxkM18qy_%#pZ~&-$lYyiRg!d{11V=PS5ym9n0mwi^=o;4%Qn2;-iS`=hGrttnZov$ zUd3O2_ETWzHXxglObjJSZKd)SF>Lfp3=T}!UA6kCMm9(*q=Uzbg)qE+Easnb3g*tA zkEt_eB3@CASiBqvMPP-(h=d{tk&WYBR2(cW(3x@3mQ0{Ekw9xQfsRZDNjry>Yr|%D zHq%DdVCxNbP}77U>0See>NUd|(&~{ORvV?ZgSg>h%bJyV=FYpY@u7uqb~eH=sruWn zvuPPmTd0C66)Hatd2?AwI)kJG5*Zu^Wrm4~b{MCXjK)c|6L3(Z67kNQ*rLo3l0J5Z ziFj!o+uB-?tcap>+6Wx{-H*eVQ4f@s0#Ttlcpqi76QKN0x~v9S9eGLmc7)sDz#g27 z*;HC2sc?4*(#IZqq?=9pmP%3yxOuC*2_!5Pj(M%U6EAPyip}k9QV7gUXJGAW!fn6# zEjB#)AAotK>|kx%$hk}*SKdpR2f-xfBDKN>3R3dqLZu}bUSE$nN6*KhM;wj%NmG#t zN0BOt!3jqZ3P)jC5y_gN|5;*$j)PP-izI=WO(UJl3h0b*2yV!dFbZ2Y@(EPC46h}J zr!LYmj7xqS$vNGDU01w)Xwx3%qSAobKtnVSk^bl0=m09z@% zx^+8V-MSea(XeYCHzSIHwC6QXDSZBQJa4c0 z{>byY;V`VyQW&Li9DB;?IP&&t^wIm^na0c6vdh!BpB)#LQhQ!zdpLQU2{IjwD%fLHB7_{q4g zFpb(rSKy!zo{jK%#{e}YKqL%EITzKL+*@+;J!;o&2&DTuNL3g?GFoIFiSH5_+eOl}(3o+sytNrm?c9ns7TKbN+O-3Z{Ozw; z{nXP)Z`_JdMoWpp+t+Gie=G(iEQ>fayfjhmRAP*h)%sW|fzlEoa_3?wnJ@{5oP09I zOg{hA%7 zg{|vWW5x5&;f-gXLt@=}#bHjQrNf*YEz+(KD^{Mcz=tNHdMDq4-_5K{V) z0%)Gd;D0egAl|jjvsn8GY;HH6bTbp-I2zV4Gmb|)-2Tp*dONgr=P?l zx7>o(XO@Wf(_#pLQbbb(z2El~NQF|zsb+?RKkHZwk&vHi0Sq^=g2Bugm^t@Q%$R#9 zDo58L7q(!BO>~+r+QSBH%Y^Be;w9xrIS-W0W(%>M&Kr^mEJR4SPo$7;ZAG@T9WN|i zh%IYZV%zeiKvSdY0%sVA89b+p92+NzB=zeJK7e{6Eblz>sqxfChW}qH#ZxLKW?{0~aVDdx7nYSP z@l_T_s639*lO|%u+_|WqG8q%5O_5qZ?9|3$VosJo)F355H6?+B17#mZY@m75Hf&$B z9;;qmimmI`prfe)nXMavY!b1`3Z!;6$f72$84Y%CAt{7eJdo<(uSdZX_^{WGPzr$x z7nqJX&aa=1Q%lBRL`w!0G?!`Dnu>bJ1%`Gg9Y>w4^*f>rHOI|G%_q+VYD<9XI2g*)H$~z=UyGzoC9)7?*>BN)v0g!4K33=4Zj__g@(o#XK+>9S?%>b|O zY{v42jo6iJLA)%2WzRo{JAeO2IIGqH?HPnAeRK+ymZUyzXirkLH;{V%;=FoDX-a8f zSRrI{OqCM@&-+Q@YY3rO47o%SWh3e^W9BT>&zO#~spEmNQk0dJAr^_jV(inK(44O< zh}_)Ri0vCUqix47Y<*)5+PCjSmONz%r!Yn(z0sxl5*$TR2(CnaTT|P)L~-7dAgT#a zR%CR58pFUCH-z&>9fBiDM`2<*B(^BqaqtG+kPBPlNd_{mBLBBm#bD2yf+-(73plVI z7&A4Oj5@1A_p$@>UMeLxkv&?|23Rc)uN zppBEVfXxYDY2y~W(Xbf_Cyn-&COmQX-FW?;2Y?-|u+o%qN_uD#xpvtGeH8(ds7IT$ zpdM-{7l=Flay{Z&G7Xs0!;}>?ZCK$LLZK*1YO4_*H4JV^4ADpo;cx_|NiMFI{46rx zh)gntOlLyWTy!LWR0haqMKDs$Cpkgxv4^g)<#;rI=XQRr#yUhKpSz;u!v4Ct}q5PE*a5 z%S)7s>s?wB;(Z{^k6|!lMZc6GkiH#2+Ep@;C+{gP+XSwCQ0=Xc}EM`bzUx}-#OJKsob<+S|K=O z=n!OdFi8S5%c78yj}R8zA`L& zZ1te$xQ~ph!C4HXd3BR?K7!Tzh(YH;Y!sBp8+RB;d!9F zQkn!sw?!m>zux{{mX0`YJWg?0ju|c%=0u0%xatX*9UqCBv?&C7dUNS4lK3v$wtDMH zBxwUR67Ej%IH(q~okyIfN#tTUfKA?7$)m;aupvd;D z6q7pV-~6g-aE({apnR+&Ptp)KPhS622B|L2MenpMCgL+w3?#M6_&ACpu9R+}09v?T zE$Isq-y1tG_DY9T*ijiSW6cO=Myheb$SIgtG6I#YS(MwBIIQTr6P8qnq!QL3R^b;r zlS87q6rrPMUY!h%oH<(&a{xrg;Zt#XaIJTroMq10%_M-lT0RX+rMtZC7R5z zuS?PbNLi{xg=bhIgp)sIT2iOCA(h4U)(&jgx&u45ZNW2-Jb))3c@WL3RtX!(rEQlh zNYk#$U@_H6FABxgs)2x1RCT#vP{H%5be^=){ApD0e+aNY^MsfwHI;i~z{I7KeEUkBCffpFBv5Q0lxJGd%{AfHg0s z3LVaw^gRY94vy4fUe##4tE>)V>@bGeA;dBTas>e@^hY7xt3`!1j2i3W7;(~J7)vS2 z-lMdOLnhK;#ViWBI;p^;R}QJWy@K`~22%DLDS%WJ`3NIrTS(g`I#LdHwKQV&#$|Z< zrRQ<$KmLjJFTbLQ21$B5Sf9ie+mM?C)4Od&Vi~;+agnf2x6}Iek)(FdwpORrJYg?1 z;)!`#Cc5Z~-dT0VcwXHt*n3)5n_7*|tK}*!Ojf@+`Nxfn=qr6j%hVsx~&!MOkad)-q{J$0X!q*4UvKbjbXsD9Yo+@I6|0? zN}Moy3XZNAgNZ0XtR;yE3zwP78y=N>QFU>GGaU_~HRPhRGz??*1k`=(bd=6L0A?ji zqcBeFv5P$WTkKKo+!_=__8)-yheyvDI*#6^Anp3LwWKMyloUw$Y0Gw^VdqXPS+WH8 z+MLF_B^wKBo%~CqG1T*fKV-tsvV2Dv_XwBRJ3PMLS_P7 zWEclETtsNUdv$*^Ap>o(5LTyJ5Ib-@roI0(l%97CvLnkBQNcA~>XN1&QQs>SJ}7wZ zuLt=Tb-&|CBMOD;J@Ld7NbPDw zX=N1>Ep4htsc&R-NtL`c>MiDZB7}E&4Jf~~^+y8t2uOo7)dQ&(viW<^@lF-*@SIah zJ)k6vIR;9ZdIlS#QHlfOqi{&gC>$86!Z;&_@|2Bu#zjd^5l3{KiWxd0g<+sGVq!Q6ZmV=g!aIA|=gF|`EHOHK7!Re4lgqWx12?%whe1nI5+{1<+5$xoEJd-pwe zx@Vqo=GzXWd0_g>Kzb@;iqtvUP>zGf#zs8$_~W?cmYea+Q%@t8N+Xv{=Uc)D>m3!d zNd1zozaZ_R#tc-F2HtnxTkElO^a3H8gI0&7B%-=|ER$};3voZSQqkto3N?J}f zq(RA{Rz=ae(hzrV((Z3Z2SNI;fBX}d{^U}$vtiR+cirKhb=FyLOOX13%HK7iKozr6 ztQT&bi3A>h>~Z}5rkim8op&P=iR1(BI^R+=Wb{A;?M&u==D!Q7r$JB^QFr~j^r`L^ z0jXAPb>K$DQAu(K9ELtj16Cv?xu;G?3e^Bc!NL?&;ppL0F}b7)Ih?C=(YA1vR?bR9r=wJcr zpTnZe7zS>-;YM73*#fk&IQAWP{M$X}oO6O}cNgyG?p*xMI#x-}?h~96vZJFDRh5-! zX>G+5RDEy08P6Y*Fv%^!wDMs%uzD2Y%w%Ew(^V;a z%xWPkh@Nt)%an?&qM8#G7f6LIbPg*;?C66r>FncS95h)0RQhNb5)*YT#miOO5I}c# zo(CoA4cFg*D;He;&H|~dMm?yZ4$G7<3=s-Ry`SaFmf?>#+=R#Pdk{?x4QOMJQ_tl= zsX{V2TSvGagC-v!q20#3N*`@6FSUKsHE-woil9knKwp^>?P$q!lcgu9T2uYxhOVly zSFM4?x1|LH+Xk!Os}VtMs2pR>5}Z725+)jP)F6y1BZN|VU`1Vbg&xUpjIIVjshFl6 z8gh|}80d%?=!}O^f5PDycJ|T0%t>%+%8)ipM02L9v&7009${j4C+E=dg%Qv|<@~wv z`WtY?g3HlPNqWmIe|O*azW2TDC26sjt-~c!=h@?-N>6UXz{^iRiwFOG7nVHvG&ZkT zg^spnk)gH~LWA9jPRo@dXf{dZ;$2mh60Dqy5OY;kj3eJ-KA)Q9OTO;HMOqOU zl(hA#==0>ZEs5sr#li9|EOC-!9MsJs8MBb7t3cKKSr~r8JYd!&xFaj1_Az_bNtFng zLRKhF1Q~+do)`fx%mk@O(x&|gq#QiyCQ6CMJkO34Hm+EW=O29nuPuBUt6y1$bVsKo zH7{@4h&JTV0SB2d>-Z=V1>=yGO^_-|p61pn`kWU9Q5Wi(b>lJk@+yrdg+#HX#P-tC z2+{&UL6;iwJhq;S%PO|CJBQQmv??&lD#47}(HI*oM_nY2+Khp^q=^!nLZbeY(hA;{-jEz>HzOn{mODZtFqzV-|1996xNzz6|MwMQXtQDrM zvV#omP_LK+FG#|CN7z71iHVl#D6Gk&F!8v*tUEXq8S@IckROZ<_2u&*oh`&(1r{; zkwp@=bivTo2mBx!jnJ;5cqNEO<*Xw#%-b-yss6f@8e zH!<~`6Hq?q07Pa_0ftuqG<-^H>O&wfy64#dV5J>klGz;e=NN>3AdQo@xUr9;_ zkjIx5w6!IqfLYth4OqK)2^wBl1~ZXCBAZ61ox!?>E$DDE*xuHJ?WtC5MJJM~cnN!z zi87cKUNOsDvT>7}FTxcpv=CzX5mObtmhNQ)si(^FCqb!f%^0deF;o~KOsF0%fE-a) zflAxLuv`dbSwn17*2yiknV_v|6?y5_5(A}8P2nkRF=S@7Rd9!uArVnU-*|tl+Mrq_diHlnJ)h?0zB6^Ly$8O5ocV_9uJdft7UekFU({VC z6uhhq52R8>G?N87(?EL?XzIkK2Nt1y^=9nYxEY!DPPmMrlAvG$&2|#Y8@Hg%$)F>Z zL@JlT&bCG*kwK1?6r?-1E#TEQXyG>n$gngpG!cOz(vqrdsS!qbv=nhGjEYbM72z0$ zm6W3s1QP?EQ<8V zN>t67in=3a!#sF0Fnv4_w~(}4xpykHQCM9;>V;`o<48EdeWafaWI_(@+jRu!qqzRM z>u~kuSD>wFKLV+C(&WpWNb3e&pjjE2Ica5|19r5bbLm<%yu1QiUVIJau69@*DPi*@ zQ%RK6R-hxBMlzj3GMhn1x>Eql-_wSJt!+(W$K?y36jUR{uY@YAtwJ#LHtF)6v|$+^&DXwWsS}2d7&mnkSlLgf zEo{ITJsjbw;}AdO0F)m*1(-1fsEPw6Y=F#CEvo8Z$h6csbww81;@UQ)B-QeI2&j8y zeIdK;#v5)Bkam!9w7*DFKS-5Cb)@Q@#3ZSv3iF1O6EJA6?&<)xw*f0RVf7=6(e%bT zBpMn~5ss=h^b*%ppp!yfxt#pokxQe~biC4+UO_IYSg6v#xOb|fQ<@@G#!3aKW+p2n z1A2~i0!+T{u470sFn%vp`#i^2A%x=*3_M~1i3#bDA#q-IJ|lxDTTzN+WeKY19E4#< z&r_0f%y6KhR2p))5ycu(S+<_R9RMh^V|0UGKLaW_ONUh8-N&u%*b;)d=8CJ(-rNG? zh8wPPKmF-X?-$2jZl|UVInrYwX*3OCEVFl#vmbHH87^LhaO#eqm9ZqIt>@$5!D!X*ld(f zn+O~*Nx~|qECouUKscgez=fva1(5n@gw6=kAtT>+#XuRXG_m{BcKlfC?mC$NS`y=22JWCp{W&UZbf?iHf&wA1c`N9(6Vte zqRA{G?I{V3kQ>YTKDm4|CRM3Wq^=Y~D*#l$>Rni~>++>o^4=zotLvx)bwQ{!U{V3T zIzhz_At?@KvF?y5{bktOG{N#FQ5#iL$D@AcbkrU+6__wus{6@@l@!7u>2oR-9Q5nv z>GP{Z@9$kQZ+h6Jz?$0s=FaXsv41?-u96_V=BlgF*)jyuuH!1{T8h~ts;o?4dP*1& zWwrR60&B{Jy<#19u3Ur8bz9J}Y9ri+7GxWm5l!YWqO?NPQ*o|11UySK6>MNtXsoal zYU*EJSOzOO2zr%T%@QVA))QhU^pGkHmX3uHsw_vWwhGx{Wf*tbk#I*=Av9(rP*x(< z^2Mdhu5Qx9MTt%_j=F3^Al)6D?bfk=klJ<*zrXP&0coPGy{jZGa9{UNNvfDX{#IlZ zT&zr}yHf*hI*S;?Hi@i~vg@}XwPqt))^0-6y3MfKQfOPZS)4s|@(4r8 zHlcCzHY9d7p=I+nX~}4%ZA7!K#5hA)rpMVr`1j|slKjpZLv%v18hkDmLW&YF9z&?2 z6m~@koM9Cx8#4lo)WJgf?+j05!}fp`=sk4v9ZiIqqzS2jwb1IgnO%RMq&!IXQ-!@s z4!V=Cm*OUewzLD8T%m%Y%4744RIe*rCjqcpI6dIjlkfA?$mv;Xtiz!~>HN$MW} zot2{GP=WkjDB`EGVpM%0kAzNYppz3@vy2&@D!oOVO*vQPa)#J!SZe+<$BkZNI-_j0 zU*0bDBsD`LY-dl9GHXT(glh@Ub1CUam03HXBn?ln=%*j44sXgOrnau7!gOt-{!c1h zo~EZGhC(p?AImQD&ihA(l9Z04Ydo9uH^2Rr`?=44ZV05l5eOD5?kSmEPgcz_5TWH| zuc&OBJoljM_~tvPDVm}JmJg`@*i60^pue=If`P8|sY`r{4ejNm7A~mRLWQk+WHVTE zX>e1_dkk3xdJ53&&Y9o2#|DRs>aMm)JKEb}{QB3wbpQ8%|91$ay@1rO{uY}mnyatB z3l=Ttt?(FaQiV~rChQ6z-7Z3(H(0JDA79lt_jR5th|R7tv{*~I0s4*lM2jw9-sg@( zJ1EU2u%>C7^cs413DRHv>KE?kKmYk5koGcRdXl925Z#us0Mf2t>#I7T25RB>K>X7C zB6yyBeAORU)oQlCRD{1&cagr2Lm+)?SBu_2Dw6bc(+zY>W;Sfl7V4611s1Mfwah|4uQ1$p!8=<_NPT_ zcfi=wvE9fswvFqryIw%r%C2g(N#Bl=)E~C!E9BANfelVbeT_YJ{{G&_zO-L|yw5`* z-Mu$f45T;Qa04#C{BpFjGQ&03T;+c4YhUZPx~m->d@*_w_Y`E`y<0DSw6u%xnkVT! z_7sTr6_6HVAMK5??9VxaW6fjs)Oh#j`uoE^-B^^4i|enyPC(j5NqY6wSGr&S`qu{p zQoS=@U?!6hM*^u#+@jH_^#AN>Be471ovhe7n8L;DvGA7^|1!<|CpdxlJ@?lOOHcR2 zXW+i2rKMu1S5{W$j|qB_dF}qFfV(rfcz%v&Nl8f;x?nb&h2;_Jg9Hfw_4#1Aie6U zE8K5<;~N74sRo)phy%pI;1&*t`<%qPGs*cvczsSBP9%L@{cnD!fy?{RFNxpx1TZbR z_&ov3<9Qxli=VQxGI=&mVD78WHJBID*D+cv(F+johk)f66STY^j&WaGF$Z5?$LR0* z?0V8C5(&BP-Y_rvdq4fz&#%pKyeKTV`G4n_baZs&-)Dc$`)2IZCrGcja)JA;Z+>e) zAZ0^du2uvjAWkN3T(SCE$@}`gw}Fw|Nl(?*VAX%)dG)H#NzT7(N!r^A%KaJ} z8}pzqFE7snl*bViot>R>?y9P){5AI03)Ef3InMeScpn_|9Xoa)9*-Bjw4SK?=U~TK zYbktQ0+c`ZWsq|2Q3E0f`R)irKS()lynoJ3t)1+xcQ=^x_GFV@dBqjVadi0=mvsZF zN&@cLt*#}{vSrKg&_fT&p!g-4mO{ZB){{nqYOoFmUZ0>DIdUXs%$R{g4?R@C!}IYP z8#ZjfOE0~I_3PIQNRK@7NQ@aXMm~Ofk6_>gT(V>d{_~&z$cyGn=Ckk_I9c^Vz!mwR zgAT$er<{Ue!-fs!UG)1HKF6j_oACJKkIPRj-A9ZVfz6vY=OPS9RR)rN^eS(OE0|??|tuk1$+e6 z0}niaJMOqcKuRD}8cm!y5%cEF!v{b3LA>i-@5-xk1S4PIAOHAAc@6?xOR?a+ala{3 zrr_WI{x|CC>biVA*u|!&=jZuWuU?Jse)qcqRKMo1JNA5k9ef-|jx7@}KK}8K%i`9P zr<>2Pr=NeI^WwGFUc*HfU4%u87Rh~T?Ma_UYk3D8Z~%VvqaWeSGtV68CHCt6L6G{% z48l0N?6RM918Go_7JCT<#lsIjER&lnnBGU*ar&wJQd8S{{BE$TJdf4t*HK3uB_O4w zD+Q#FKKiIEG=6aQ<}~VUHucvl%SkQv#5o_gx3UDW$xD)d_o z(&wIgPC&YN@nRXL;Qi=#I(_RW;Y(lo5b-9usq7cNex|_uCV=`1iBVJ{!OI#V;^^ z{CLq&xbt*)-duYUC_8E~%rTqyYa+O=y%Wu-byJ48EP2r_QR z9d{gl{_~%UWTgsAY5M!$|Grmsm*=M>B}l1G(>4rleckgw-W>0L#flYqNvgwJ`W%D3 zR&cy~0$o{IIamnbo8SC~grjn-#Uvmt?x)yOAT4Gx^=I5@k5cQ|Nu~aWznWb4m*ZD=moHylRFd{*fCsX|>wO8B!w)}PR{EJUXNnYE zx^yW{KKW#kjM@g#`xDgs@Vf&KJP}L#N{Q>PyRKJtSBG5)(gz=WunR~B z3z)vfhKmlhghw8EBp-v`(;)SmD21^KVf5(HxbAn?;rQc^N30|U+jhLhRK@R_o$6R8 zm>k|>wCUi&tv&EsYtgZ9|JesJuFpREY#yXRb4zOgen}csclXpH)7Lxg>H9t<>4HnU z+oV#R?kxbRR+0O9*ouk@eC%T%!?(WmEwK+d30{8rWn6H<1=zlQdtN=$=g~GCB`59J zKmYm9qO$4$_b-3>O93e-kB(3J??J20^zPCQe>1$h8l=45-jbw#M;@P7V$GI?V~;%! zS6p!=rXMgJ@lt}cd;KL{Oq`%(#Zhj$z8VECK}Ly2(9r(pril{T^Q!-*ug#ym%>g}` zRfU*B#R=M^T9Uq#K&oug4j5M~xYYe-Fi!d=gH(q_I7xc43H_j%Jb5yH_`@HH13(iC z2+nVQ^P3`hnwy)u;G8d>=cNn&BOm#QfSc+tHv*Ru*$>j-%F6rWYEMZ@&}e(Muf=4r z-}Cx!7D%E`v;k^AuK9qaKOC`ive_uMY8CdjB7?0XyR zaXm>=f>bIqyxAZv21E@~PLg8Y)!@S)ee}`d)uqZyY1q=zB5~4R|N7Us_S$Q)X3d%| zhfuBM%jf>z|Ni$ynrbP+Sg1#s4y%b!_FGIw671e*-RSQbOz~E3b}L|Elo{mZEitB z!wz{jl&F-Rd=JrZ1T__vD36z+rn*{wlF=0jhY=!6h}9FLk*uz6<`_~9ru|JVg0Wt{2THGEAmw62pnU36 zpAx$~zezX6LjObl{+{#C#qePx5cUcOOA&B(aRbl_Tm6@_;byXEZrFvE#$8yqdJUE> zeGSW(zJ~3aH=}7+6Pg+uWfsND;?nO%7NMMj3AH1of%5pV^_Vz*0uDQLF2>i7!|>t5 zQB^-y^>$?=9qxZb$J>4WJ$DCtNLJP-9 zbGeJD-@FFLpK3h!*Xq2M$OE%+b>rv)P+2}j@=3408tp8fvO6HSnBxzw%2PNr1 zLCX1~sjeJ9jxQN#BuQ`q^uH614FSqy_~H8@IFCK{SaGz`UosG<7mWy6ihROUgY-(4 zPYHrlCV#$SdU5ZrKcu2xbYC1%4gl3ms-oP2Akp4aP9%C=Nf;nli%C*_eLn++_pL#~ zb5p|TK_}oi!8y?>O?1`{??bDXL6G)zf3s)L7IJ}>X8QSgPQCiBTenWiG2U{^E!ets zYd&7<2ZffNd|pZq7AL0)MiB8lnkUR>;yr6MR%;yk-t{@Ts8QV`sf7CnH5DGu3B`qv z;U|(hy53I#q^c>EcyMGcWKE#W%_41C*y$$F)Y6R2tJY!diZ}4$)6Zhvs?~VyrI%p2 z2JBQC$mXPt1)D$-=u}_XK9V4%aZ8z49W6t|HQ;2j$RdRrs}iGzkHF}?F-T&baf56}V z_BXup$}93Nf*_@aq@^k6!U-pwAS4;G+Bo-m;#PNC+2s$tgS4%+6~;y1`L=t>Pn5cw zmrzW{>OtKt22$-}_n*VRnsDMUobc11{*oF0f~uafVPQ4?FCzJUI81B)#HF zk6{1ZZ-2|B6Q*l`E6}hh5XA23ruC==S27L)XxrYmUyQ~V)FgNz5-hj~GG48(7aU&=(yOn& zT0&JtLCW4v>>x)Y)BsW;s<$@QHSNHf9b2$r$2M$PzX6Zlb{AH?vJCdFCgtb}g<*Q_ zA(gb#tus7|UOslBq@l!AJ&DalfyYw9()Jt?j$>v;9j1&JgGm!7Vf2itnE$a05Sug_ zHhUr)E-c#cI^F{y2-2XrqRl4FIHK0VvDWrG=LT(l3J1;wdW-!V_v1U`eA4VSF4T-J zFwK+a^=|{VNdxL`Hl4-|*I$n-u4MU?78n1VeJrYQ96kX2Rl;jcy;YcY--qsSC+nt zXBIBP`j?l(ZfI12QA$UGj1rFj)FAbmRf)*+K$`FB=1Ewp)#_NaI1s4iurMt)43jE` zVN7K$YU)N{_9@3=&gsXaeEN7~!X~VcG?>h9+9q8j++F3=@^3+qzWd$p&YKb3kMn>8 z7skt}jRXP8f9r)^LQT0GKKjv*$|8Hj5l3|M1MD4;UUpfR8|&)-_ILAAyX}r7-5Ve! z0H|jE&;R_7IBoo%TP-d5H#&Ss=_4qa4a2`tqB3-&9Y@6^y$-=>Nvf+)(C(!TO8b)w z1SJ^(98__&^N7bW#!E>?4l(1cykDJE9(V~w%arscNe2Z|X{qQpZ&ueJ+f4B8FgS7?y0Aq5-mwP>GU}WOg<}ZP1>MLI{4%#KPf4aI%8<>OVYPFNC`Ho zC{!KkjnglM(vAa8b%ucAATu|T5|1mOmN0$ANwuWcAk{8+UW@1Y-S2*v_at)>(kr(H zly*$eCj7)FJ|P5uIg&a=f5G_|2#Dy=5rB#$6&VcMFp#ue>`HWE zebWwX*|h`Pwr|Bl_uhx+9{&$gTerio!iX3q9Cj+tvL~y=aq?aahFd&%s=4cdRI`+H z&qfijt^%lGyRZxcmII8atdd5{Q;bR+J81@{Rn=kYoS7JT>S3rmVit@M)j-&UEnU)G zyx=*Go_uPtG*#w(`8O_-1aAt13%GN6zNPxV!p2}UxuyQw_(esO|U{?#Ho2ClcJ`w2{P?XdVwntMs3Ex zG@}w{jh~5eqsE|o)?^&<(F=e>CaaF;v@0D4FTA(}-?`|!pd_^!>S2RsUrRw9d#1Wi zKvI$tptR+gq@gtsJ*IkpdU474;lH^sGsaF<8^d}2t=MAPZ4&nQ2Y+iyrNgFEY20wb z^|2D9z3Q$ASHk}Nw2x;YMg(;1xku~)IK3Az?4tQ z02%?TY2AetZ>+$^)obwJZMS3jQ_lbm%_w7_-zao!<)q4HG6LM%npzxw_+dEx^wTlp z;2HAVls-}h#x&5<+KO%4w+m~Fq!T7ZkX=(6SHRCdm*b$sHBse;QRf)AVB{Q3sv3b2 z(l0tN%hHE*D!sTq&ob3Y!v_1{RXT#IndMJbEUg#lYRfMp{v;_)(^=GkgT z9&tq8o36uNlBn-xDAAL8?|t{;KaW3wd+xmlq!s4u930QK4donBp(BQc;cgg*g+^k| z$O)J-VG`=+9gLYDdk-*W3=m<3KpW4#^di2)$_$jGwu;9FB`LKU+K^1aql9FK`p3r2*rbtog$b5mi`SF+l^=e;rC+0+gQQ_rL%B z0#NNh3No_#0_&az>AB~fE9$P6qy!wu(S-rZ{->I@V#ymT5Y9Nb{SSY}E4SYbw09zI zga9W8Ct||!QeSv)B_*YJ?|U!6r$7A}NkWK(LkL-_^eQ*b4{di#rj2Pzb_dn-Yp%H( z_uYS=l8QMSmhB*%vt%0e&Ip{DX>4SBxxY0L2)?9Go`(rqdrB)bbp%muE1$l3SG@VT0 z#v9pY;wrSYwZi!3SHI$3cKHIYh?fN;p8?~`Ast|=k05CIvcC7d@8#p9J&^_aYm*k6 z)TD9IaTLse3GPdfQq9pI<-O4^`N~(ml229B$M8FCU-EDMJV>t0e&>RJRpm?M%jY?1 zhidg#OBJ;s_R*TmcjJDL4#vAH&mod@9GF?bV7?!u4r>>~l(5S#xcK*LFJi;a287zv z`1Qq?A-QY?kaJK+oE>326U zY1!K{+|?%Ko~cAa<|xBuk_GdPuYB3PY{3Gt8JGp}b_OXOBD%C=v6sYw)smDFQO7#_ z0x6HvAHHb5L>)@fo?QOape41DETYeR<}e(?Pt;KLvO5Xws9g3Vkm z+bc*35G_#&)Qd0qF@F2o-@wkfs3?iSOsYcb$q*2+fsw9-S=MlzHDNYJ)(peMQ;xzx z?>ie9TMH-R;!K17&K9I6u_?u_~$}z@ax}q-9eh{ z>=bG#K`QyAU;WaBF3Z`QUaHc*08&=uBiTR~9P7`-rX(c;gey-^>Nf|MDi7_+{({s$ z(7X@50`nUBzVxc9|4ol3y}oo5>0)O(*4Dol*LAPGElCMds=A%o47R6|SiE@yHt%S_ zvv)s)2mkgDpsf|Kvk;bpX&~gdC@(2Rdq=wzf&1kzekp2hh;dWNEzJeZto#G{r5eYJ zC0Xu&;C_7UqaQ^}YYUv5i*g~7j-x+v0WiHDsEpy6 zS6{;aBS;sj5R4s&qYiY;=_n$fn(bF;rf3G!;Idr$x_ZwbW%QsMNNGnDsxo*w?f_L? zQFj9QaRXI%2Mf~k&O1+R#UL$A-w!7RLCUx$Gh_Oaq(SM$=is^YYOKK%1Sx?@N5fBk z@)NOZ)MQkjp0ZSWdzEhnNGT&bQYmcgXvd>#R-m;#fhYcY8(w;BArcMS>BG%~G-{X# z8>TqM=v4XMMc+f+s5&(+F4;Muet}d%Zy`&(!}I3N1?%T#QfW|;W{xGj&S3|LF~*5X zoH1$!#?_2O_0;h=^^+ffHD@YN6UTEezaWkyvY~|TrxViq!bcC^6PWZ&vp4|f37t#+ zcf99RT|rAAogUDVG!N3RU3j5OBClkeu+IpMeP+%Kvd3q!=jKECuI3+UsUj=@%p@f)-$HsOI6A5 z+V2af!SfXZssEn(3c&i}+rMV3YZ~O;deDE>k677JK z5s(^|i3mFgwdV4SW-bJ|i?|%oK zCMtVW0X{^!plf5YQH9g%XJCBgaEzHc38#JH11erRyc{n)|1AFBMHk_zMT^8~r=$#mt9d^Od9*0+W6VYMFeOyw~7++cRJ-Zj(~o?E+Hft6d7p{qT%5QX^KY7Yq@52vjq6(j zQWL3+jm@b9?jlHATCwPcf8eDD9z!PC4%iux4n)ZZTag(E(rlYKNXdg` zxPvcOC)gHq1o>A+N>Z|UbcZzm{(g|sUL=uvZ-P{(K2g=BT}n0(B{)}ShHZ3xr8f(t zvM2=Nq<-&i4kR{&@*ur;<*R6JX~h#a{sT)MdJImo6K*y|ktWlGQZ&LGOvjP9}r;Zm% zYRpyY?vm%96PuKA(i|mep5|CEy@J|Mf6WV0LCI3$e9`YO*fntXz}gQ<`lZkRuY2va zzvv=Gm8LuhW3-1SAE+c9EJ#WB(#g2RK*|+TJ9X$@@2@1)Dz4u~EvD{jiNS@1&Ie9N zzF1CVei)X~s&9WM3HRGwbvFo7I@p93=-F?Wpa5AAN%;naQT7-0#brA7EwjXdjo0ETw#&|t3{9~AF?cj7-=9# zZ6HdCiX5h*8fTB0iTaumsG2qor+(%`Fy~ALs!D`4q(Lg`Zr4HwGSvM6sn(GAlXHXb zk`D<*h-FXiHar0+Ld-QAZ!s$YP%r8pLpl&qpa ziTK7FZ{#!g^*+IuMsPCohSV}HB2;~Q^H}d`b+;Qx&pTfc>@`rOW{`n&&c&`=77x7s zDt5NE;A->%_zTv_Q5qO@d11SXsNvtNRaE*?X*msJr+wAV4h{?f|!xFjV= zeUem3R0BE3K#S|(p=GaPb7Lb`zPuE7{P8d7T)P2bHiH?lORaIrniu*_m{u?Wtq&B!n!<4u@}3iC21G$?p0UeymQYh3Q`Hf0C;Bo z1}xjKUNTi~|I=Tv^|_Z2PN!hHIT)r3*Kox-#KvCyFyPP0JOAjT1ptw7q#H={`J^7( zD(B>|X~RZooyltXuPt4gFIN%{TVjtAr0m2x3T2pCG92fPKLlgzMq|pkC!qYaBZ0b7 zWGkY0F#u90Qvj(}bvcLlA=pkj=_GMfQIaw-0m-IdkdsGHper z8h~_W(PpF6p%aNVAys7^I}HN$tpsTTz>208EM312TN@kj@4x&N%kO>=Rw{+ClY>d3 zfayY5JyOWe0?U2;_Xj?RFMRO}m^E`I%Hm~3L8_fq*<2Q#oe3;nya+d3cRlXE=UxFf zom&jYghQ6ZM*wxYjIHNaGWvu5R4cz8V7&u9E6TI2yS&0si=u1FD=3U`>t{v zNt&9IF9wmfM|DLE#?nbqWkn2K5|xF=2vn-Qy5Vq8no?8ZcU+uly72vJjc8A+yMFGj zkQqMp(T}*aDfXngTP%**Tbxw0cjz@^Di>40G~=ikjjN|P>D~q@JDwq`w$Y)4t71UZwmb|zel14ATdBoY=6C^LSJIP7pqu&3ss z9W7dt@_OqxZNwdS-hq4Xxfic2c?s<;tt#=Gp!b6NA=^O=E=D4RIjFUcYo?&+xwmNaFXOiC@%L$zN)ND<7a z@s8J0mG!8!Baq|DXAI8AfvLUSC8gc)_*7)wgIh}27&e5Z1ith#KOR9?PVZhPpbQgYi3l3Y?Lg~dLJwP{kF zs+Jss>>=%CeWBSviYwC5(V-fWK2s}PFpydyjG4~(vNTUn-)ryX22A(U*+JUa*d&94 zvlOIgq+HknSyaoDVwQw?lq^r0Ed`UUz}}Y9%-w97lj*qpqe_p4_@sHg4FcHMkZ$GEK_arpO)|?xTsM{Og1N$eA;v za-eOG{Bg%l={@*g89Q}K3X2O>?<${ez=9Bu=j)h>f`URV^TRbj2*F}uIenRWecIIl*aQe_dYRn9qHf>5;DVhB z>j0rJ9WpY;Wf(}a`8G3c?%o}cLsJH7xl+tsj5{d2=s_7cdrl7abxZ%ifE@bdfV92+ zPkH;b*X7j5`z2O9PYP4yw}91Cuo84BD=U@0o?cB`uoswvCbX2Mh3lU^qpfeeN{dUB zuQ!jhi#E)8f(V!|F{zhQx$7IZO6{V{rT*Hh3C$qy!>fPyOL{_q;2= zqL`r-`V_8foK60!o4E@}nWS*xL^cVNvryz}4!?zNnYUSj#HTe1Zq`88WMI>-TKn95z)}-dwW&&wyhC`RSHcsj?SQAGMk^uGY#vWBK7Nn2hn4u41qDpOZt7Pe6u`WB9b^Qb+JlW zb6LHts#z|}RxXztZogHQfA>boUtZ0ZMB*fO{qYs;ZS83w)ikZMK~|0lr!(4*Cj3m6 z3;W1GZ1#^cNT7)5DlhKc+!qr%Of;ZAn_!Z~75p0JY>jf6Ae9}YO{Pg7yl<2D!j2tZ zdXPeC0>=?y^h{0VEb@f}sR0L|GL#q-nrLCBCIQ~#KJk$_Fqpko&0@_4+05TewWv`b z4X0oXr1=E}K2yB|(gX|%fmTJ?4UCLPXJ3yT>^iIincCibOFn7+w~TamYosTSj+fv? zA%do5bTKCId!&$Kb7lZ3-829-kvOCJuR@BXHeN1YySzqLRxXj+`a1d6h95}HO*crv z%4(7Fc|JqF(>v1M?$0MhldAR$jiLZRtQ#Q3(t#YnUaXA;g?Nv%vuoEb4J2Vk8$GLi z&cF&#u@>;VadTjNKsgXFvy|P`wA@6HQqlFhXP;FfvO&g7TuLBi@d*Ot3R0IGI}^R8 z`6qPfn#dV{)YHb2;?ke(Ct@8}i{hZF009psLywzi~XE=p?=x z2C4IJoi`KspbU44GmHt^l>E3X&M%gmms}y&FR7PRwaewo)z{04jkk-`E)=i4NPA4R z=sr+Z{Fo|8X~qYn2y@ep?oShd)K}B}^3qE$>Ci2=-q>=cW(xCfa^Fy_kYckG4%ap9 zI=N<@2vTaJTbf(^rf&jAvl*n;jgZOwbfpxFfhNrrq}rYri)mEPCC3g+z+6CT8kPAh z_?*myF*C`2AD?jvv`HOtcnCtchsKrm1%*2$Awx5(N%*Q#0Sg491M zK1lIT)f^4{(|!U;XGi4N@#Au=t49vK*CD&#dQ$2kT`Z7tv)Jx{!Dh3#K)@HXQY)%JFgM7Pns$l;DT@L~ZT2V;Q}=~g z!h84&T$cqUr^j_!WGaRr48wN6AZD)E%)e#>Rn*L&Oo^v z&CCQBcy@rweeiqu{l>vdlQ?`jXwyt(g)T@Fzor?QOfIwe@Z3{J2xj z4h>0h*?iTA!i-SL^Yl+bwQ7D|zIM(O=EWrsQth(|DTxO zH+}mSS#|YQvf`R+L>4XZ!@j|YQl;|_OjJvUk{^BK(MM$W?lvDJ=gy`1q?|w2oc%>Z zx<09Uw#@7`%ZHH@FfH0!!CfA1L zfR-)N7Vazj{9%wH)To5&?Ci`qYLWXv*sNZ?THDIjtzG8_cw%`9LVZrnPx=gkDM6!% zB{%~kg%93@mz3e;sPy#rN_SV696o$VKIqsh9q+#{`}gga{@z}V(gGBsl*WO}HPM!U zw7`q$kfySt5?M6ALawU2LI(-o)NrFLs$L>>U%yt0%1b4$tjxa^BNj6f%Yekq?v)W3 zk3RO8f{A?z3u*S4Gsu~usD^?Ivsm0cb_Jo82vVX-v=?SW&WF+G*q(50)|WHP=m|7B z!rZEn!WK~4z8Xlwj7(#m{N|~rmC0#z3$r zfGJZkLnevDA!m*U<#|L?!+s?jXPO#mN`w!GpKGysB(N#+w&~ei&qfGXp#k@Y)}si) zdR=Y7!yWr>%`wxuxi4ya*<_oKYMaP+d7n+^x&)E}$0Em+!aexF z11ijXs+^dnPr{Z;3Zy|ti&`{Lkm+a&PtGLI`Vn1kOom5BXvhSmPa^&#m zvTyHRWmp&*8kW(~)2dbZeMNyLt*@?8j-=Y9)l$23nOt+_N~x)?*1%4zs8D1P$9 zmB4vaa0W!b`gdQr1O-nztP7e}N;Cmzc(#u1J(XezLJJ&a({$_+LXG{V8i^nvu?VAN zb!XhN)|@F=D#?H2Hj!4dK;^VR`hVWvtxr6m?QvSnkfup#79`I!!ypATB>UkvWnsdH z$cpG$Omc=uB8u0|lr*qrbHMpNnhMQj01IncGfCM%s$kHz)L*igEHGNgMjF}>CCl>x zUNkYLDCSsLN`{{YLBs}gZ8SU2j%4OKR_LvT)9}g$eWyG-!i0N6Q|AIw?hRIbp3%w@ z-R~P28f!zYa9&A?mI>NHH;`sZx&ca}w$^{@4_xvYJd$2gg^s3`;sr7^I4DQ^`ej~m zv5X9l=#*-h7D&e!NDK1fQXG#yyi!?EStX@aO!QWjuD~1{ONd7SJCS3T^VxtI z(xm1?+5qNo1sD4aczK^Fx^Wg|v(VTJn;&F_5DepD@3@vS@&`V#X;${TySrN>_9&Y3 z0%dvl8q(x2UPkGJE69WoEof`x6$zYo;z8{3ZCBY0#42r4$bT6VWsvQp$e*B9074rwtV%n$Ub<%TN-d9IJcSEV z14+2hBK3Yir;-AxF;VJIPZChF1nD2Ht5rxg>_kZ(CRXscl}irnBlk`}8^MH`38ZP3 zMKH!9{L5w>q%F-dOmz1rcW?A|?%XM*6nS&=v&h_?(u#ipANneTl;utV#2p6gxG@SU z7gs@BN*YLmU=Zdq1^$4PukbcBES9I$-{*AOOwdN@x_L^cVfKO4T~$9w=9|0E$S|q8 zA8*{?5qT}Gs7PznJ)hd$DXr8c{GqVq45ta0^Im-MMJcPCGk0@d%&+Jdq7LyK zNYC$JBohhQ($uJ$bae2f#5Ue_r}u}KU!DW$`K{|$>f3W5%@EC+!4m*Tn;JLEbK9Hc zG(PEuJAdfC{K_kHAf3TQzSJ)j2~s~jF#eh|cc*kDY{}>#LX!g0GlM7Pf2nysEeiU~ QjQ{`u07*qoM6N<$g88?WF8}}l literal 0 HcmV?d00001 diff --git a/test/Charly/05-together/public/index.php b/test/Charly/05-together/public/index.php new file mode 100644 index 0000000..9c1b38d --- /dev/null +++ b/test/Charly/05-together/public/index.php @@ -0,0 +1,37 @@ +selectAll(); + +// vue +require PROJECT_DIRECTORY."/view/permission/permission.homepage.view.php"; + +//var_dump($allPermission,$permissionManager); \ No newline at end of file diff --git a/test/Charly/05-together/view/README.md b/test/Charly/05-together/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/05-together/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/05-together/view/permission/permission.homepage.view.php b/test/Charly/05-together/view/permission/permission.homepage.view.php new file mode 100644 index 0000000..68d3233 --- /dev/null +++ b/test/Charly/05-together/view/permission/permission.homepage.view.php @@ -0,0 +1,25 @@ + + + + + + CRUD Permission Homepage + + +

CRUD Permission Homepage

+ +

Pas encore de permission

+ +

Id :getPermissionId()?> Intitulé : getPermissionName()?>

+

getPermissionDescription()?>

+ + + \ No newline at end of file diff --git a/test/Charly/06-manager/.gitignore b/test/Charly/06-manager/.gitignore new file mode 100644 index 0000000..d11ccf2 --- /dev/null +++ b/test/Charly/06-manager/.gitignore @@ -0,0 +1,11 @@ +# Ignore config file +config.php +# vendor contient les librairies externes en PHP +/vendor +# fichers non envoyés +# PHPStorm +.idea +# VSCODE +.vscode +# Charly +.history diff --git a/test/Charly/06-manager/config.php.ini b/test/Charly/06-manager/config.php.ini new file mode 100644 index 0000000..ae92c13 --- /dev/null +++ b/test/Charly/06-manager/config.php.ini @@ -0,0 +1,26 @@ + dev +production => prod +test => test +*/ +const ENV = "dev"; + +// chemin absolu du projet +const PROJECT_DIRECTORY = __DIR__ ; + +// mail pour webdev-cf2m.be +const MAIL_SERVER = "***@***.be"; diff --git a/test/Charly/06-manager/controller/README.md b/test/Charly/06-manager/controller/README.md new file mode 100644 index 0000000..cac74d4 --- /dev/null +++ b/test/Charly/06-manager/controller/README.md @@ -0,0 +1,3 @@ +# Controller + + diff --git a/test/Charly/06-manager/controller/commentController.php b/test/Charly/06-manager/controller/commentController.php new file mode 100644 index 0000000..a238191 --- /dev/null +++ b/test/Charly/06-manager/controller/commentController.php @@ -0,0 +1,95 @@ +selectOneById($idComment); + // view + require "../view/comment/selectOneComment.view.php"; + +// insert comment page +}elseif(isset($_GET['insert'])){ + +// real insert comment + if(isset($_POST['comment_text'])) { + try{ + // create comment + $comment = new CommentMapping($_POST); + // set date + $comment->setCommentDatePublish(new DateTime()); + // insert comment + $insertComment = $commentManager->insert($comment); + + if($insertComment===true) { + header("Location: ./?route=comment"); + exit(); + }else{ + $error = $insertComment; + } + }catch(Exception $e){ + $error = $e->getMessage(); + } + //var_dump($comment); + + } + // view + require "../view/comment/insertComment.view.php"; + +// delete comment +}elseif (isset($_GET['update'])&&ctype_digit($_GET['update'])) { + $idComment = (int)$_GET['update']; + + // update comment + if (isset($_POST['comment_text'])) { + try { + // create comment + $comment = new CommentMapping($_POST); + $comment->setCommentId($idComment); + // update comment + $updateComment = $commentManager->update($comment); + if($updateComment===true) { + header("Location: ./?route=comment"); + exit(); + }else{ + $error = $updateComment; + } + }catch (Exception $e) { + $error = $e->getMessage(); + } + + } + // select one comment + $selectOneComment = $commentManager->selectOneById($idComment); + // view + require "../view/comment/updateComment.view.php"; + +// delete comment +}elseif(isset($_GET['delete'])&&ctype_digit($_GET['delete'])){ + $idComment = (int) $_GET['delete']; + // delete comment + $deleteComment = $commentManager->delete($idComment); + if($deleteComment===true) { + header("Location: ./?route=comment"); + exit(); + }else{ + $error = $deleteComment; + } + +// homepage +}else{ + // select all comments + $selectAllComments = $commentManager->selectAll(); + // view + require "../view/comment/selectAllComment.view.php"; +} \ No newline at end of file diff --git a/test/Charly/06-manager/controller/routerController.php b/test/Charly/06-manager/controller/routerController.php new file mode 100644 index 0000000..49e1a9e --- /dev/null +++ b/test/Charly/06-manager/controller/routerController.php @@ -0,0 +1,46 @@ +hydrate($tab); + } + + // création de notre hydratation, en partant d'un tableau associatif et de ses clefs, + // on va régénérer le nom des setters existants dans les classes enfants + protected function hydrate(array $assoc): void + { + // tant qu'on a des éléments dans le tableau + foreach ($assoc as $key => $value) { + + // création du nom d'un setter (méthode publique de modification) + $tab = explode("_", $key); + $majuscule = array_map('ucfirst', $tab); + $newNameCamelCase = implode($majuscule); + $methodeName = "set" . $newNameCamelCase; + + // si la méthode existe + if (method_exists($this, $methodeName)) { + // on hydrate le paramètre avec la valeur + $this->$methodeName($value); + } else { + // sinon, on affiche un message d'erreur (à commenter en prod) + echo "$methodeName n'est pas un setter valide
"; + } + } + } +} + + diff --git a/test/Charly/06-manager/model/Abstract/README.md b/test/Charly/06-manager/model/Abstract/README.md new file mode 100644 index 0000000..91c3ebc --- /dev/null +++ b/test/Charly/06-manager/model/Abstract/README.md @@ -0,0 +1,8 @@ +# Abstract Model + + +Les modèles abstraits sont des classes de base pour tous les modèles. Ils fournissent une interface commune à tous les modèles à implémenter. + +On ne peut pas instancier un modèle abstrait. Les classes enfants, appelées par `extends`, doivent implémenter les méthodes abstraites. + +Les classes enfants peuvent hériter, donc surcharger ou supprimer, les méthodes non abstraites, les propriétés et les constantes. diff --git a/test/Charly/06-manager/model/Interface/InterfaceManager.php b/test/Charly/06-manager/model/Interface/InterfaceManager.php new file mode 100644 index 0000000..421a87f --- /dev/null +++ b/test/Charly/06-manager/model/Interface/InterfaceManager.php @@ -0,0 +1,16 @@ +connect = $db; + } + + // sélection de tous les articles + public function selectAll(): ?array + { + // requête SQL + $sql = "SELECT * FROM `comment` -- WHERE `comment_id`=999 + ORDER BY `comment_date_create` DESC"; + // query car pas d'entrées d'utilisateur + $select = $this->connect->query($sql); + + // si on ne récupère rien, on quitte avec un message d'erreur + if($select->rowCount()===0) return null; + + // on transforme nos résultats en tableau associatif + $array = $select->fetchAll(PDO::FETCH_ASSOC); + + // on ferme le curseur + $select->closeCursor(); + + // on va stocker les commentaires dans un tableau + $arrayComment = []; + + /* pour chaque valeur, on va créer une instance de classe + CommentMapping, liée à la table qu'on va manager + */ + foreach($array as $value){ + // on remplit un nouveau tableau contenant les commentaires + $arrayComment[] = new CommentMapping($value); + } + + // on retourne le tableau + return $arrayComment; + } + + // récupération d'un commentaire via son id + public function selectOneById(int $id): null|string|CommentMapping + { + + // requête préparée + $sql = "SELECT * FROM `comment` WHERE `comment_id`= ?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + $prepare->execute(); + + // pas de résultat = null + if($prepare->rowCount()===0) return null; + + // récupération des valeurs en tableau associatif + $result = $prepare->fetch(PDO::FETCH_ASSOC); + + // création de l'instance CommentMapping + $result = new CommentMapping($result); + + $prepare->closeCursor(); + + return $result; + + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + // mise à jour d'un commentaire + public function update(AbstractMapping $mapping): bool|string + { + + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + // requête préparée + $sql = "UPDATE `comment` SET `comment_text`=?, `comment_date_update`=? WHERE `comment_id`=?"; + // mise à jour de la date de modification + $mapping->setCommentDateUpdate(date("Y-m-d H:i:s")); + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + $prepare->bindValue(2,$mapping->getCommentDateUpdate()); + $prepare->bindValue(3,$mapping->getCommentId(), PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + + + // insertion d'un commentaire - À modifier ! + public function insert(AbstractMapping $mapping): bool|string + { + if (!($mapping instanceof CommentMapping)) { + throw new Exception('L\'objet doit être une instance de CommentMapping'); + } + + // requête préparée + $sql = "INSERT INTO `comment`(`comment_text`, `user_user_id`, `article_article_id` ) VALUES (?,1,1)"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$mapping->getCommentText()); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + } + + // suppression d'un commentaire + public function delete(int $id): bool|string + { + // requête préparée + $sql = "DELETE FROM `comment` WHERE `comment_id`=?"; + $prepare = $this->connect->prepare($sql); + + try{ + $prepare->bindValue(1,$id, PDO::PARAM_INT); + + $prepare->execute(); + + $prepare->closeCursor(); + + return true; + + }catch(Exception $e){ + return $e->getMessage(); + } + + } + +} \ No newline at end of file diff --git a/test/Charly/06-manager/model/Mapping/ArticleMapping.php b/test/Charly/06-manager/model/Mapping/ArticleMapping.php new file mode 100644 index 0000000..7a2fc92 --- /dev/null +++ b/test/Charly/06-manager/model/Mapping/ArticleMapping.php @@ -0,0 +1,124 @@ +article_date_create; + } + + public function setArticleDateCreate(null|string|DateTime $article_date_create): void + { + $this->formatDateTime($article_date_create, "article_date_create"); + } + + public function getArticleDateUpdate(): null|string|DateTime + { + return $this->article_date_update; + } + + public function setArticleDateUpdate(null|string|DateTime $article_date_update): void + { + $this->formatDateTime($article_date_update, "article_date_update"); + } + + public function getArticleDatePublish(): null|string|DateTime + { + return $this->article_date_publish; + } + + public function setArticleDatePublish(null|string|DateTime $article_date_publish): void + { + $this->formatDateTime($article_date_publish, "article_date_publish"); + } + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + $this->user_user_id = $user_user_id; + } + + public function getArticleIsPublished(): ?bool + { + return $this->article_is_published; + } + + public function setArticleIsPublished(?bool $article_is_published): void + { + $this->article_is_published = $article_is_published; + } + + public function getArticleTitle(): ?string + { + return $this->article_title; + } + + public function setArticleTitle(?string $article_title): void + { + $article_title = trim(strip_tags($article_title)); + $this->article_title = $article_title; + } + + public function getArticleSlug(): ?string + { + return $this->article_slug; + } + + public function setArticleSlug(?string $article_slug): void + { + $this->article_slug = $this->slugify($article_slug === null ? $this->getArticleTitle() : $article_slug); + } + + public function getArticleId(): ?int + { + return $this->article_id; + } + + public function setArticleId(?int $article_id): void + { + if($article_id<=0 && $article_id !== null) throw new Exception("ID non valide"); + $this->article_id = $article_id; + } + + public function getArticleText(): ?string + { + return $this->article_text; + } + + public function setArticleText(?string $article_text): void + { + $this->article_text = $article_text; + } + + public function __toString(): string + { + return "article_title"; + } + + +} \ No newline at end of file diff --git a/test/Charly/06-manager/model/Mapping/CategoryMapping.php b/test/Charly/06-manager/model/Mapping/CategoryMapping.php new file mode 100644 index 0000000..cbb3d1b --- /dev/null +++ b/test/Charly/06-manager/model/Mapping/CategoryMapping.php @@ -0,0 +1,89 @@ +category_id; + } + + public function setCategoryId(?int $category_id): void + { + if($category_id<=0) throw new Exception("ID non valide"); + $this->category_id = $category_id; + } + + public function getCategoryName(): ?string + { + + return $this->category_name; + + } + + public function setCategoryName(?string $category_name): void + { + + $text = trim(strip_tags($category_name)); + $this->category_name = $text; + } + + public function getCategorySlug(): ?string + { + return $this->category_slug; + } + + public function setCategorySlug(?string $category_slug): void + { + $this->category_slug = $this->slugify($category_slug); + } + + public function getCategoryDescription(): ?string + { + return $this->category_description; + } + + public function setCategoryDescription(?string $category_description): void + { + $this->category_description = $category_description; + } + + public function getCategoryParent(): ?int + { + return $this->category_parent; + } + + public function setCategoryParent(?float $category_parent): void + { + $this->category_parent = $category_parent; + } + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/06-manager/model/Mapping/CommentMapping.php b/test/Charly/06-manager/model/Mapping/CommentMapping.php new file mode 100644 index 0000000..c3de343 --- /dev/null +++ b/test/Charly/06-manager/model/Mapping/CommentMapping.php @@ -0,0 +1,152 @@ +comment_id; + } + + public function setCommentId(?int $comment_id): void + { + if($comment_id<=0) throw new Exception("ID non valide"); + $this->comment_id = $comment_id; + } + + public function getCommentText(): ?string + { + + return $this->comment_text; + + } + + public function setCommentText(?string $comment_text): void + { + // cryptage + $text = trim(strip_tags($comment_text)); + $this->comment_text = $text; + } + + public function getCommentParent(): ?int + { + return $this->comment_parent; + } + + public function setCommentParent(?int $comment_parent): void + { + $this->comment_parent = $comment_parent; + } + + + + public function getCommentDateCreate(): null|string|DateTime + { + return $this->comment_date_create; + } + + public function setCommentDateCreate(null|string|DateTime $comment_date_create): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_create, "comment_date_create"); + + } + + + public function getCommentDateUpdate(): null|string|DateTime + { + return $this->comment_date_update; + } + + public function setCommentDateUpdate(null|string|DateTime $comment_date_update): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_update, "comment_date_update"); + + } + + + public function getCommentDatePublish(): null|string|DateTime + { + return $this->comment_date_publish; + } + + public function setCommentDatePublish(null|string|DateTime $comment_date_publish): void + { + // on utilise le trait pour les dates + $this->formatDateTime($comment_date_publish, "comment_date_publish"); + + } + + + public function getCommentIsPublished(): ?bool + { + return $this->comment_is_published; + } + + public function setCommentIsPublished(?bool $comment_is_published): void + { + $this->comment_is_published = $comment_is_published; + } + + + public function getUserUserId(): ?int + { + return $this->user_user_id; + } + + public function setUserUserId(?int $user_user_id): void + { + if($user_user_id<=0) throw new Exception("ID non valide"); + $this->user_user_id = $user_user_id; + } + + + + public function getArticleArticleId(): ?int + { + return $this->article_article_id; + } + + public function setArticleArticleId(?int $article_article_id): void + { + if($article_article_id<=0) throw new Exception("ID non valide"); + $this->article_article_id = $article_article_id; + } + + + // on doit implémenter la classe abstraite du parent + // __toString est une méthode magique qui, si on veut + // afficher l'instance comme une chaîne de caractère + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/06-manager/model/Mapping/FileMapping.php b/test/Charly/06-manager/model/Mapping/FileMapping.php new file mode 100644 index 0000000..e26665b --- /dev/null +++ b/test/Charly/06-manager/model/Mapping/FileMapping.php @@ -0,0 +1,64 @@ +file_id; + } + + public function setFileId(?int $file_id): void + { + if ($file_id <= 0) { + throw new Exception("ID non valide"); + } + $this->file_id = $file_id; + } + + public function getFileUrl(): ?string + { + return html_entity_decode($this->file_url); + } + + public function setFileUrl(?string $file_url): void + { + $text = trim(strip_tags($file_url)); + $this->file_url = $text; + } + + public function getFileDescription(): ?string + { + return $this->file_description; + } + + public function setFileDescription(?string $file_description): void + { + $this->file_description = $file_description; + } + + public function getFileType(): ?string + { + return $this->file_type; + } + + public function setFileType(?string $file_type): void + { + $this->file_type = $file_type; + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/06-manager/model/Mapping/PermissionMapping.php b/test/Charly/06-manager/model/Mapping/PermissionMapping.php new file mode 100644 index 0000000..a17e27a --- /dev/null +++ b/test/Charly/06-manager/model/Mapping/PermissionMapping.php @@ -0,0 +1,49 @@ +permission_id; + } + + public function setPermissionId(?int $permission_id): void + { + $this->permission_id = $permission_id; + } + + public function getPermissionName(): ?string + { + return $this->permission_name; + } + + public function setPermissionName(?string $permission_name): void + { + $this->permission_name = trim(strip_tags($permission_name)); + } + + public function getPermissionDescription(): ?string + { + return $this->permission_description; + } + + public function setPermissionDescription(?string $permission_description): void + { + $this->permission_description = trim(strip_tags($permission_description)); + } + +} + \ No newline at end of file diff --git a/test/Charly/06-manager/model/Mapping/TagMapping.php b/test/Charly/06-manager/model/Mapping/TagMapping.php new file mode 100644 index 0000000..798f6b9 --- /dev/null +++ b/test/Charly/06-manager/model/Mapping/TagMapping.php @@ -0,0 +1,44 @@ +tag_id; + } + + public function setTagId(?int $tag_id): void + { + if ($tag_id <= 0) { + throw new Exception("ID non valide"); + } + $this->tag_id = $tag_id; + } + + public function getTagSlug(): ?string + { + + return $this->tag_slug; + } + + public function setTagSlug(?string $tag_slug): void + { + + $this->tag_slug = $this->slugify($tag_slug); + } + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } +} diff --git a/test/Charly/06-manager/model/Mapping/UserMapping.php b/test/Charly/06-manager/model/Mapping/UserMapping.php new file mode 100644 index 0000000..400ecea --- /dev/null +++ b/test/Charly/06-manager/model/Mapping/UserMapping.php @@ -0,0 +1,87 @@ +user_id; + } + public function getUserLogin():string{ + return $this->user_login; + } + public function getUserPassword():string{ + return $this->user_password; + } + public function getUserFullName():?string{ + return $this->user_full_name; + } + public function getUserMail():string{ + return $this->user_mail; + } + public function getUserStatus():?int{ + return $this->user_status; + } + public function getUserSecretKey():string{ + return $this->user_secret_key; + } + public function getPermissionPermissionId():?int{ + return $this->permission_permission_id; + } + //setters + public function setUserId(?int $user_id){ + if ($user_id < 0)throw new Exception("ID non valide"); + $this->user_id = $user_id; + } + public function setUserLogin(?string $user_login){ + $this->user_login = trim(strip_tags($user_login)); + } + public function setUserPassword(?string $user_password){ + $this->user_password = trim(strip_tags($user_password)); + } + public function setUserFullName(?string $user_full_name){ + $this->user_full_name = trim(strip_tags($user_full_name)); + } + public function setUserMail(?string $user_mail){ + $this->user_mail = trim(strip_tags($user_mail)); + } + public function setUserStatus(?int $user_status){ + $this->user_status = $user_status; + } + public function setUserSecretKey(?string $user_secret_key){ + $this->user_secret_key = trim(strip_tags($user_secret_key)); + } + public function setPermissionPermissionId(?int $permission_permission_id){ + $this->permission_permission_id = $permission_permission_id; + } + + public function __toString(): string + { + return "Cette instance est créée par ".self::class; + } + +} \ No newline at end of file diff --git a/test/Charly/06-manager/model/README.md b/test/Charly/06-manager/model/README.md new file mode 100644 index 0000000..50d91a6 --- /dev/null +++ b/test/Charly/06-manager/model/README.md @@ -0,0 +1 @@ +# Model diff --git a/test/Charly/06-manager/model/Trait/README.md b/test/Charly/06-manager/model/Trait/README.md new file mode 100644 index 0000000..c49aab8 --- /dev/null +++ b/test/Charly/06-manager/model/Trait/README.md @@ -0,0 +1,24 @@ +# Trait Model + +Les traits sont des éléments de code réutilisables. Ils permettent d'ajouter des méthodes à une classe sans avoir à l'hériter. Ils sont très utiles pour ajouter des fonctionnalités à une classe sans avoir à l'hériter. Ils permettent d'éviter les problèmes de l'héritage multiple impossible en PHP sans passer par plusieurs parents. + +En effet, un seul parent est possible en PHP (un extends). Par contre, on peut utiliser plusieurs traits dans une même classe. + +```php +trait A { + public function a() { + echo "a"; + } +} +trait B { + public function b() { + echo "b"; + } +} +class Test { + use A, B; +} +$test = new Test(); +$test->a(); // affiche "a" +$test->b(); // affiche "b" +``` \ No newline at end of file diff --git a/test/Charly/06-manager/model/Trait/TraitDateTime.php b/test/Charly/06-manager/model/Trait/TraitDateTime.php new file mode 100644 index 0000000..6b56182 --- /dev/null +++ b/test/Charly/06-manager/model/Trait/TraitDateTime.php @@ -0,0 +1,34 @@ +$paramName = $date->format("Y-m-d H:i:s"); + } catch (Exception $e) { + // en cas d'échec, on met la date à null + $this->$paramName = null; + } + // si c'est un objet (DateTime seul possible) + }elseif (is_object($date)){ + // on formate la date en string en DATETIME + $this->$paramName = $date->format("Y-m-d H:i:s"); + }else{ + $this->$paramName = null; + } + } + +} \ No newline at end of file diff --git a/test/Charly/06-manager/model/Trait/TraitSlugify.php b/test/Charly/06-manager/model/Trait/TraitSlugify.php new file mode 100644 index 0000000..dc7c15c --- /dev/null +++ b/test/Charly/06-manager/model/Trait/TraitSlugify.php @@ -0,0 +1,40 @@ +PyA07*naRCr$Oy?K;mXL;uNyK8K@XDykvuc}h1w3K!%v;q3 zGkvE2oO7iArrXBGHnuU??mq1~LH8jeEc6d$;F(UZYwoN490t{4fj?FlPO(^`DFB3Pk7mWKUij zbKkMGdKP~Rj9C{iA`AmweDS9|^w2}R^2#e1m1;3^Y-biITOeKh1zrx%Om1?dkdfT+ z^99rdehnDPJL&gsJmj2OKwaGGm<4AM#|vTO@exw!h#vZM=N*yZpHeREG? zITcvr``LW53mMoZRLy;=Sj)NZX4CpZ@Gc9+H?; z5=SkNF8MuqS8v#SLnRgzT!e;>LZc>YCRmx3M=~Ico#Rshwf>s<+~g+sCs>qsm-8|8 zo9nOUJ)#wmF6v${3ZxQ~TBg;CNf&iVFWi%6-%Nv0Tu=i70V+@<#PfVCO!XxeE^$K> z3<-#mpUpWSvf{Kv@_YFng*q>#z6_Amg}j#nC=pf!PU7y)${gwI)NE1bdH@&hN-nQ= zZh>@p-H&&5HjSI9O;%`Vp!z@+`5qBAS<|`I?o$!S zu4O8KrXsMzNVWyZI@YsQ2|#Br!jsE2@9Ltw2VT4&NK2)Hib-3R^y0YN%E47u%}{{! z4GqxYnMr2KWqjAdOSyPvY(?wVRLo-HEotaQQADUrWT<{_!8E9*U24jAjlov;J9X5VDmb5jTx%?f_cpQzZo$Ow~&kQy)=MErdJe%=}zrJPDrH647hf?^vbsbnZ8 zwW+46<5kc=jzXOVmS<>>)lkVGTUkc^2#kopmRI<=wF*5E+_d#lws&>W7Jw^aNY4hG}4i0z5+{h7?FmsKp>ndj(d65w~vM$*#^$ z+GCK0mVjA5U*0{{0_ma_(}I?CdU`TyYirXnND}n7Ea{>y?uB?#Gf2g*RWTWk;HU2h zNXIFpGn8x>->~8gthlp2h5~2|(nz@40@T?cl_XTNC3V9FNPQDLTP&+b#+zY95OVwG zom|%0MZ2$)N7zyhl6R3LQk?Z|HsCFHcittlAV{aCCZhKC_7+Gl1me!>Jym5?#g77o zihvY&;hlrLGBHj*lclUcYN{lU8HG4zMC6Oj4dU9V_@x43QzxOsk|uRj10)s|cUM5F zYM`+tRUkDyQnfrQLk-g1T|IPGCH@ruILQ>v_rdggs4`9y1@){h!F%jQiw0@KiYlAh zYE@gN3qfahRrE+?SdjE#hj@8nfIxW>~z|=XZPiplNG7U=nz-V z&kG?8!7(B2f@`Y3i7PBw>A5t**=ui^UikBPS}l;C$BTO*4sFCG6YZCplud&Z0@8s) z{CaXyxw}=vR`IHU)CmI|-=jD=%FxkwXmc!#a!tjWs;(J7l!db-*`y!Jl1faflD{!X zZDAONSmiR^m4IDtJ0IPB4ej{~xgbIk%Cg`BFT}G=QfpRXZ|sLQm(Vfr#KXqGmJOnr z9aRsrF2ohR@b9@Okal!*%sJDRCB5*sZvHb+AQh{n93GRhWiSXlcjOQ+O-`xAQ4nc& zR=cbr*&yJhpFGPmk39_I!%(YW2SIE}^`SIKCEYUzq_I0J_1Kyvqy<4Tg_FScSk> z?rp=AYInEJ0hISp;jg%^@!!Oq4Ggk@%}Nh0GdlU$rPr`6O4C&faSemOFqrZ@!oD6h z-hDG$?!OZ@tt85t6l0L4FcsL7$8UO!x}YU(fpodT@idmyk5{;9P_iuz(!&Q8NK5G~ z0Zwd54bnkCN6q8)r=H>mfBQEuG6-HlWqca|Z9>fKO}*)VVrq4{wGERF&u1q&?p?c^ zySg{gGviU2oF?1RLD8`|mWfz>?=5Wq;=h7b?U1u5IP!9Xw79(Ww>09a!f!4ce?gE+ zowO~dOE4`|#UBA(||ZN@pn8CMVi0QXjmUUBCYsSl0t> z4kcF?f#$cQEs(~6$I0$)3#5x(p3CETYS*n>(kQm12}q|JAT=aQqe0qMDskYMXEaEM z1*D~S1yXTq)4tDoEcVdDXSQC=E~}GlzDmk)C=fB;m8QIB6W9FjpNH*hpxvS3=nSup zN$0w|Es!Q46=jB>{PZWPpY*lYUd3pEba{Ypv1g${npo0>Kx!&?x4oEv^lSLTgW#9z zAl2O5*&U{*OXR3zlwsidJ}ZIUbo22oS8`oPKfTi)ZY`t|8BBGinB2CC8~@`MVb=!e zO5??32Wg{A>aX&-f79i9=2K>P;e{7?=%ELB{q@&dAYCjtmdo=_57OzAENR*gX)hIH zODZ5eLFCP~q`DT`NaW16YR#Y(a0y?@5%2>W$#C!1J-n}T4Vwy(&U+Y^!(`fIY<(9u z{onr{cCCY+ERn5S>*j*81=87x08tBk?z!g_NZ)+(O^jCJXt}^|ap!R|NF}=~?(P6D zO$tbJ1lWq`Ahf@wk?uGDuWwwxlsY1*CK8l?gcK1F4j7(!fe=Zd|dM zn|n8KquE8rjE`+NOt}WbD>K~uAHD!LUk)pBI(sagHL4!l*a%u6oefga-F@bnrW8#)*h*8nX^DD1p5}_XmJ2p4$nFpkakzA?0xD94bs75ipY>y()p}uv*i>k zEB{ZvtC&<7;Rw%)RJ~JrOE=>3@zs0y$lA;3I5LH6S{zRYSl4dj%K!7A7Z$J5CzW3Fy5DG}6;EX^T z`^CytReh#fe1)p?mqySNnyiWp-k;sded{l0citxJMNGBZOs((W@_+wn(zos*vO`Kn zs0a^<>U}G_8%xa8m%u!hw3RqoJV2JiGv|V|7=u)CcTWM*Uf<*GCw|PMfA#051nKEM zTXW1h7o>7NU0AdQ0lVqtp1$3DFte6iIiT9^Fqn(z|JW^T`~3Z|aV7b}B)K-p3%6p@ zdQ85MyW0Zka)93A&!G-d`N0gB3(`_5hc8_)P1)UZ3R2Y_6HADyVSEwohE2N%Ye;jA zy_yHsT+Rlk4N+>yXHBf#8@c8WJ_CEU;5i|dtr|~TiKF-mEa>jG$P9}I$Z~k5x}l2E z7ZFKzH?gFLrBy9Y@hm{P7%MtACY93=cUSsEh31zFO*(y(HCTMC=W?!Hxsfh2g>OWZ zJ5${Bd!NGk_$`ow(3bwv*6g80TT&4sYt}f@FKl(eEC)c&cMh{aDlw_4W76lEKpGg* z^xdeFCYJP(zx*>I$?ndHNzW9dk}MKZf+#g4QoC*dnZTeoGT6gPZd$#StGd_Gm+NG@ zRAA!=ZlLdTABG)kkPh@PQR1G%IBM3{Uat4xT%Xs1mb3-ZbA8Fr@A2v&H6lW>q^8Nx z0w9&d(Y~jj>#dRHJ#fTJ{#6oV*M236k-QUT;V*k*Kad*?>(ShJIr zp2b8^VfXJpz{(F@2Rk=8rv>fppqS5-U0+L6VeYL?^#H zu-IvJazod8uJ2e!fA31njVrm~cRm3-*TU9*ZH0XiGJvIep))k+aNm#ORZD#QFPG>?)6e=z~I1=5QGdW%0v0jUg% zP?l7=yV{bT4x~a09C+bbzWvAl874;0IY^b{O7aleplOhfOfr!{FBX^CE4gCLX4dwu zqJQfquDJVl*4=so^!HGuN|;S44_+mUl~T*uL#zeT#jmB-Gtbi%NI)vHSp=ja=~)Nq zcwWn=%yDA(HD-h8aQ8&aw6!g#b(E{n&Ub)um&e;`E@nY=m&IRc!<2oh{tl2T?c?W6J zr_(cJBrerJllU}^$x1S8%5<}3Wj{N2?Bx9)xs%=Z+=jiek7>W8_`GSu!WQ9dHOHp$ zI1|veKzh!WTI)b(dj<4}!iKvmmUKiE>?I~$1|SuX$Oy!G7FZ>tL)viYC&Rj27rmKw zZoK^#uK(CwyzirTQZWOSDRwOz%d!ZqIho!waDUbNHogDZUgxEJT`MMC%B#Hu@1>OH z)xZcDMc8n6f3i$KDwiM`Qz63IGXKppBqI&oIP{tstk7fU)=RnZ&fB^3zK?R{)q5~A zDcuzAYLJFaEBDNFdE*VD38<&a5-*qOZVQ66#ob*3WSzseP-7s(lEyJX7{u=a$IL0`kuo(x`-~A$;t7kvs2o3n;$J&;5oeu=kQ<` z1xVw?ucj`>>iCiYmdW7~tBMerBg6+x+S}Us;vf7keDM$dE&W?IQ!M1MOcUF-FolRO z^J$u8$KeY#9@sBgx{X(}Gx3xafXY&h!e>1}~@8QiSJ zoWex`(o=nqghnWn)k2wRYN}FAA*iu&-FiNB-#y&*v3uEd-PO3+EV)!xHJ6KPtSqC< zkpbEg(;9qR%=8_#d$YyhN zc6ZU$-A%Tw4cmtmc7_aE#zh{Unk%KDD#y|xaY*F(M7~dZCabKeIL_i)E*EenH+n&L zw*}IR1fB6|o-IfZKK~5g`IA39KeWKbUc$uPjX|1<=haBb#+NVGB5*B8J8a%_B{$!8 z8<+373OAR<$)-uSx6{?$Nl&VSb~jBXoziOhVp$sIg<~5N|2fgq%wF|YNSRwMHKq1 z+_sggZ@Q6d-v2(@R`o(#hRAT}&i0UVvt&{(Y0D<(q{uocT-(O zAZx(J!^lHvjGOal;tVgfrJV~>5yuuu&j%lTh<*F^VzeyjnXIx4|J<_$>HcS);^9C0 z5{wRCSdb={P-4>9l1d#^7)O4SXm;d#3Q^f@o7r{k9;S3BKVF1lo2+GR54s zaczf`63-UPYZ;h*E9qIYnmyND$2IS}nYL9M z@$EE`ZBY|)zGdK>sGl7I(&ZA}VZ`oLYq@IU7CJ2hH!jntfm1T@DhSl1^!f*FUh*=r ze93%b9Va)}h@vp$>8BC}`xZ!-D;7_AUS|tZkx%*VU;OF3@+l{cnNW@8rvPbO?l|3r zTc}xkF3rzY>VdHZla!B=XNiF#Kuy`u)<&kSou2-6eBk5%nx6HW=vmW8#e|9(QL_xH zDl6oZ@+)+Qu%~w|H*VQPn-6JQCz!eCr+_{5XPcK$3gWHzHa82^%X*Kcf>fW`yZ{sG~Lr9x?gpM59i6TsK zdFK-Mmts?B_G>n^sY+E|s&kjbR5GHJX_ih^z6 ztm@&?Ti*v)?t+v-=o)y^Ef?zxpX+WmpkbA-v}9`AHY3v&gsWhF`v zssg?ti65yECkY=Nxi&Th0iu99Vl!#(>)Foz8!w}OszPTaP`?ihL(R__P8pb2Y~za0 zKLGFF16fmz&5-dIOAAs>Rh;z*quG{paPU~PdUan5q-Tzo3-XHP4pLRBoV)1euC4_% zixQwF7QImt5r8JvbpFe4g^}uz*^0~ko!fX|<8IbWlS1=6Lt5$Eb%mIFu|?(qDKhXoAj$@R$v zF3wyX-c#@_)KSD*N*#174)=F$52xsE%&UcZ{M2M^bQk(m`w)4P-%UCm6p{wH057OWL6ue(7sYTVXi7Z2d^mIGH zIk}UKgDeQrW5u;KzfcZ{P{ZEQh-#rqq83|11DDflLai#P@1}~OCa-HL{VRf zq@n7Wr>muk!1w7NvkS532c)sPt3bL3a*lF$qq-$s=p4`89X>rs2QXS7o$q3w+Z&X` zXbUg4g~@0a0;J6T+RQI7S)nh@Bw%pyhw<5VYI!Pgq#zkD*jaw*j(&XrrwMs2HNMlk#^68||pTnfTvxn8~U1V&B@ySVMN(E-TA~m3_ z1hF;QAQ1=?pd~nLc6T+ysOjU^FJvNetw{}weVmmg6_92fe6gg<5v0Glb<&2#Y%Bnc zJPpM-zN&xM8aa~nlUOY2g;aeNiY+75?YM4N*P5Ii+a-TZOokNURU>kuXcwE4y1-Ub z|7CKHDlwyC!g#70Fhax&0|UG=KBI>SThdjj+nh6g$cn({?I$$BJ{&xzq_xesOrkar zi6u`PCpI=KDQ~o6u$C=7{Tq1g?Kc=J=Q&&$V}ugZM3lv%+Nkz1U)483#IcRI zS2eMo&BE3V&qV{Yv7t5j!V94FJqgm^+@|mOL8=#u2C3fE^%QCi-9#obF0RMZsRL=i z*3wt8eN3!?HW6xmi!vkP%4%Dz++3v(8)^3{jHNx~iB0m9^7AZL@qB<(n#fOE+nf#3 z4h%Mv<&*37aMjB7xM`PT6Qk@KKf&7*gX|9{m=U0w2A*qCj(q$;N+9~=)uz^DJ)8ZN z`p@-iprt$)8zR0ZLHe6b3!LrFCLU)3P+ew7#udbVSyP8_;?4RkKIiH0vkS;bbxJaK@cdt|o6cLJGm0>E^HgUgn461=9)>8nQ2&&8XxsT*^N$pTA z!uUzzkSeFt_sLk6O2`PgS{q$$b#*M;6yGZBC$nIDN*Ii)Sug{<9J{+3q{=B@oV&XS zkS1p!F{$)wZX?6L>AQ;G>fV5puaGh=4A-WTbvPIld1G>rH%5+f&>vxjK*g%^*{ej9 zfSQzZ=FDkHK$?)}^|fwJsx7>*gs`9)NAuN5wH0rW8Mbk$lwevh>B1NG!at({0$CHv z6_dD6GM8b5bZHo}=3{`#f~&^h%!g13pccv?+z3zVg~;oqb|{(80N?ZCeo3*)2DV|T zMV*nc^@Oa*rs;HS(qdgCQyO=CD7Raza#M*TNnNQJ*zhSDFea9CV1Sn=bWG}-);R@f zGjTyDj!+=|-0D5t(y@W=N<><8gXFqc2BTq>$yCHxCgRt_hk0%MIOUYZbgjgABr$8C zwQ`%LMI@VFqR5c^KS{35UL&UvQBqz>LJOP=Qq4FLZ>D0J3@cjTHg-0FG-yg3or0cD&>GULhD zNyMw?lWHNdq7gBM$xj9j@$!ToB781Es<*F(Fqy=aSztS9zQ_H-$^ZZ$07*naRIq9f zw{~n`MJXaz)9!3!o0J@}?lp?tX^w_PCNma?^J5$y8RE#q2$R$(;88_tt=hVZN1}k6 z3}0$a=+^5q2{=!Eel@RWnGFKFVge zG=p>kOAisA$WuyXsTt-hOWNysO5^DJfBhAF$?k@F!K&lQ?lH&RZFa94Al1(okY*wQ zX^PLUzKYx0H?XQ~D3D5)T2%Y|oXdz;V#Q_KXy3e!ePcr$96rI=)FhMDB1fmk7%WUN zT$~_}Pl13Ufr?!Pu+q~hpgo(1oS%$b+=>;`0xyqgff7bYPF#ajENN}eR(3VJyS7af zmtdBaCB3-G3@7iXD(#|HR&00Trz96$rGgA8!pCJwm0xY#5^=XAPMi#3I3F-pDKS*c zGwIiusFo>s9yO(AXA#Jv#L#i6DRekf55JAIb4-!<5Ri#>j>NX|<%gJ+8kr!XLzF+F zkUOrtj6N4Sl`^az|7PXHQ#4sVw4k;qYM|O7^xPS3@S`g zA+G=%Dnf+PI!d^}aZ~u*`f*}#6VktGRRgwQ^6{=6Jh1U{`o=4CR%4JFQWnx6t?t>% zWxpo``?yZ3MlI^i=7NHBRu{}gO$(fr1JzccPAX`24CgS0l#HXUc#3=Fg<>@$GLEHS zF%iMO$s)&RW*D29q2T)z0-vg6B*jV!z%5(t$e|)97z9yVT2aP0ib0iFsz!N3K&zUQ z&4^SG&|dTDta{va#g(jcWfC?-RUa#36UDGK*UXGeE(Q7@eHqcs|cSxyV!)Q1*QS!&KlDKiDs*S zRdL`N<@bjCPDB`lDiLJa7BW4|5W%akhE=Q4QT6Gmc-(*WRcvrj(vwsYwnVJ=6US*u zy;MbqF~L0nsUkBRY=AU$W@mRhD-{LO$G-lT_``!3e(fB9)K(z9r9(h!(oxmPBXRd< zG8O|VkM=vSXZvSA4%;_ExeOCU7|C<+2TzedbexGJ$FaOXCDNvgd5V!o-UukBOh!sG z3{OokUdmGw>+DyU@k$h^QWin%*jJMK+nD>(kkDO&!JXDd?pb#!oBb5os;_qI21ucD z%~p0dCyqpsFxJbykd{<7uOCXQnt)VV)h=F;He6b5zmm@Vcw#_(h-?hdqy}Od%vcdc zg$Gl89hsV7C|_WBdWPwmPr;NfeNDFZBSQgMmt1s0DM|I#`zj?VR3H5wDVkqhrcrtr z<7}-d6NBU!k&o+p$_48!``ml^)oip=q~#n-Rj3y0?1sRKu)5m8m0m}2sV$<&RF-71 zmQ+A`;F+iDAjPYm7Nm(q)mdfP5n`v)09)pYhLYX2_#LsNo$KkZ*>#YLJ1U8zfs{|~ z?i<+jxsSunO~S(0u1GC}qsN(iYd@o}?`LZ70Of%}%$W*Z=^Qe3{`knSBIzqtdNX2h zYMg>!Wu{spAJ&+Xtajv4u9d09<0z!_MmB1>!qr-l61>#F1Fi7D&&hg^gXyWK=Qfo z3wcttn#wq?Cc+Gzqr#Pswe?LoxV>3*(VxqYkyb4xJq zF-w|UA)P)*vZ-~#K}^T{u`&PJ}fErY1Q&GR|LEXdSQSbBgt};MhY>OWNJj7V_4HE97u5g9hKCqDae|SNVPcv8VH7r%LoyB0hP=b!@RRtny9lQiYz54ytBItusTkx|7w{?qcg5H^GWFwazWK zEe0tR2pKaB?e3~NX(o|;2haxa6TOpXjexuk~!h4SU=pM!w37t!aN^wk1BbNP*IHM8{j7EYl`M>@l_ zS79P!knhQ`}!Y z&KRVtui%!>b*!#X2dOOYk{NL{hXU#5FMbL(_d$CG<(|l9DsH=KAeZYZH_n04DHxrG z!y^=4-bXMv$@tL|c$0amqf@xm0NV>lVX9Gvs=d#YjaN3{xa6gd9T8d~u8=Njs05Xz zSX^3!Of0DaX&Oq`ZPFl>?5-s1WR%5n1nGOH>Dv%vryi0Rl?7b3pk%wM+VW?VS zN)kg=*?C=%#bHRfLrN-UEW8}5o!BsZY$3kO3{2n06`+PvW(X+^4s&eZeqR5@FFCw# zAO1{%XlfcN745?Lfts1=*d~GR)k`vA=o1989fY(;usSqZ5B%HRx3PmP{Q}aN8fM8? zB=ll;mcsfTQaA5r<0n518&^RlO=x8lc_Oi-OA1mMeiX&-u4H#R*EU&FVL`#94M*Cb z^P@MhT|g=xKwDN@(jLt3I&W}k>cnW2Y&f$ z4*&9HrjHLYIW!o%v9YfmX(o@vtyJp69Nn=ae`O){+Eos!2B~l5tS*;3M zOLy)(P~l4_EC#uRivCrBLJ{&+q65ds9~tD>z5`4iJ3*=%Vw9>x<*Fizq`Z(+Xef`z z4GmICK~Q8-i(_A0 zAf3zI)EyG4`%~@E5uTJ)EQ6tv$KK%~_D_y8VusAPHU&rGP74cL0aF%?Daz)ugG)cB zN;Cz8ZiFT7SUyi}e4O!j-r@M$Z}ZNpuQIiFKg^VIWAUvfJq86zbuI!_MbOu^84c1H z2=R}y(1pApApJjf-p=kI!@8P|NiEw^qzQ?W1*F;gZ)Tg63RZSOCIhyv-7YOiWzlMP zzX4LQq!N=xbXEnV(ul4>dNgMsAl(|fyJ1^aS8@_6iMmEg_My(9SNVXXbe0TFirH4; z0!oJ5s(83gJ4_W}d;+Em>MIA3v{$e8#_cUQ*3EHOw`LZz`O)ZN`=%*4e5(!|lN^ZXR+M=^d>c|>RT zCH;S(SmNO11ji?*7%mm@GHJ@TP1V-Pp~z60=n9zfWyh|p%G5>yY1^bWGtKa!LyR1J zho3(FIF(~ZVRST(H3PL+6VgH*j7oJN2C2ALazgJ4q&COfZ4J`jjX|1CtKmY+52V2? zODZ7k{>b~;EFj(5uRH*uQ6^kq#du0GeQ`J1ydag^Ef-pv#TDl`X*i9ibt~$X4l$^C zAoE~`#}qijVwtF1qcWW*ELHJKRlI7AVx>e`q&wHHX8ko+klwjPd0*NCVTl#&=buli z$P5WcFCH?3cDM9SETN6W7rHPl-6@I@BpoWij|L8Nw3uh6T%qLqIPL8UoPPWz99xm0 zly)&&N-6Rj6@Nyg{E*uCBzu4LD}Mdc7a2Zu5XY-h9UD=s8CSGfJ&7yDbJgdhNoui` zNR$|2v!N6ZRF3^@ENL@HKcy|H0;$eiFAqy9G3i`Oin642kZ$Q$F=+#&+H27ujU{W6 z?w7fiG_f!$P@L5oqe&L3K_FCpxN^LDIU{jiRJtIRcf}4yS87A0S_Hn zAG+AIv|}a~0n#H!2BLNAB*)nNSdO$neM1xOywp9V+e27%1G|yG9y}BgH8G=-@owA`w?e;{wP3~hiYq#-2f;9F+WmD7ct{cas z2}lFdfu;pc*-ao7+MQTZad(?sI%N@02hv2{LcMPcP95m0YoEmV%CI)iGi|DGC)!bs z%ioBw72u^Vs&`v814fzy~6s0#Z} zjIeKPjB(eYY{z-@L~>nI-?cKGlu>Mpv}mk)6?$Ehp@Rqb)$`Bu){DPj>Wu@CFGH=S zxVCmE>gNGM#*@XNdLESPk%71X6K#+XSSt*oAd; zp)6^9`gSBSX*36s&u2jbU+-bSX4?h%Mzpq4;_d$ZQQi1Kw8(lX-XvM6O7#%QJiZ!IEU@Gv8L8`hsgNW`-2FI^Z85?GD;2qxl`HTGO`4h#<38axN-8f6^?k)tHN1nJF+{ z_VAoEo@uM>sN!lWPG^7-Q~jJ!YLo#zjzf8TjG+Vj_|dn%!ST1=gy9jaR8~>SqMCYGf$AwEk>Dj+@HX4BCO(p;KInxdB_NSiIG zsbkV}4AR7kCb|ufs6@3f_;?vdW2iUwpN6j2mZo>x6~byLxPJ&p0MkWCq)2u-&Hf-kY^WTHOULkj?_B z3WDP1hhz~aiMzxdu1_3D(iEpq#7`KDOJ_yn5N=MLR6zQ@M<3;(2Os44@#D)2r1kW9 zoJo`WhrW(v{(pPL1Gle>l6zpH&Mv# zktm2wF#fAw@ZA)TaLMBy(FY{mgT7&nrkB9g}t?AnntMBNdaz zk}XTdI9gOpdj8$r#F8d}(y5BsWPn+~tv~kb5 zC9PpeKdWg{bZiFOY`X8gnN4Cz-{T;aI6H|o>!UZ+FPi=kySwKLqzdy(YD(vEcb79r z)%|GBaw$Tz&a_EAR0s>BVU5=YCpk1-;DmJQi?EdAD7v2%L}hS;@QH*GD(9h$XE_-=q*0{Apf2ew?>Q zD@++KW!Iu&2@zeAL>i>xCP_b`8~8Y-0xN8jgFk22%|vaGAxstd+8gzRlmh~3@Z`)*~O zh&cCkDusjhVhN@N(%IH)R!q9Qvb#;bu3~~1iUlI|(6KONpfthHq&+D}Q+6_x9X-}S zIG5rSE5f{J3>hJgsPXw8m1D>FhcEvL#RCVRP*DAaM%5$oByX(KeVX(jWzQyc-o#&u zHCV;%RcZh_bD`_Dv50jtCr$lMeKi!{XSFxPmRhz30cj5)I*tGClH0g6%F$mjNf$j_ z!@{=&q?XF=_TGCdYn3I{AQg#-CFky*=fqJnNR>uZ^WHWmCY|lK#59$rr874ux#->9 zjvJOfPj&k)IG&QQ-5lBS(3Aa0EBotzyuMEo$dlpi1Zk(&#J6qKs`K?I?b$MT~$yTPyW)K|4IQM7GQQ%^s6)k zm9$D0i!?SarsjVtK1?FLtp^K>ev;@Hd0v?=U^6K`d&$jg@>8s+Kvw8=SV|SY;7Uwt zvGQZLu_m#kZ7Ib?RvGB1t(TS@1r7Wecqa$;iZuYh6+_&JFBEl zspPX|72rooFpc#IeR(jD4#D*n3 z;m=0n=wh;@=NmdpclU$M(mVsNVlJR}U4!px-|M*XgKJ~2b1XoSLwOH$>i7qC7V-rY|8>6gd(kg?v#z6LJK9S=ZY`*nZ1k*AQL&RTi5^}Qk;l5JFwZ9 z?O{)MKilk1w%Z-_lcLMl`nyUWM>4k}?%dQosj|SyczG4pCJ8G2c_k~Y8TEeb?s;MEu=Rhs61=8gKQt5(u^brB+LmH%e_r4Wv-@bjG z@Ow#V7x4m>MQadLL;RG(kP-0aa-xo2^OX3Q#G7Jq#U)l!lJR~ZZf}FdBqaS|gLn%SPey_@lM-H;DSR`+|cu@*Z;?YQhR40r)T(3fV6mj&` z*ZB40Kjxk9{}8+8D_Il)sC2;uMnIt4V=acH7)G&jof=mdFA!x##jTatGt}b{v!a@;`W`lS@4=Zn@$GqDD)?u-(uql`!tZ$RtRDmfQ5 z2ugS0xI!gX+1&)BH?dtbj`}(YvT5nGQvIxF0@A%tKEZeY;!lZ2PAoW|w0SWuWp=j( zQhnt`h-?{yRFlG@$Y92RSEnZV_1F*tG8fcz2?U@r2Spg>$}bFXLXS+fLc3Svl_#I( z@xTB7;KVQ~v2L-(t$|QzAQ=+Ud{!&j=2K3t9LiouieVVOebw) zMf#?+0=<}68OJB!l-EnSR_WPcGl83+YWf&c7f%N>C#Iro= zA}r}!Z@&@kxMasNaCa5zRA^QWV8VoFj~?cg@eyWHDK!p4Wp$OS8xQA=d@_N@8rx>_ zt+)B_U-~i=`wtKnWgd&r{gU=t+Qkb4Cdx&^_B3Hpl07*naREnB!>Fb5}^pQjC%}C43!#X;TNy& zCc9B&F*6h@6&xu;DUe1=nsP*j2p>Fj+JQ|6pMQpL|H&W1_(%(+=Lcr4L+Opcv$(swIybe1@KS1(%xNZ)wlwdm4IFI_eum9h6yQh0N6hUX3+WWup2 z+FBOH4m8nDM&Aj0sDqG>T9vn+dWuKB{xyuLX&kRctz3%Nyav87hZ=6Kc6YV=+h~mv zhLB`*dm^}}dz%92ZljalLP&c}n#My)jvj0)z!ZQwl>pat6exs8Jd-k*Ov8qouA=Lz z9dO-l*suz6Hl!`p8W%_w*b|U~Ww}_Ug`u-pT9Zde4k8~aB^-G(v9xZi*A$m;+cZHrMdhsGa`ugjyM!RlTJ~#9L0`x z154$76cw;qqC*rFMuz$3SN@!_mwu^uyD~H>5RR@Ye`sscAh~ORianOhumT*Kppf$Q z*oUoT`0edCa;4G5nvzLZB~rp{XQ&aQ4X+4^8{0(D4U7FfsD`uudgMmCO$q3fp^)nFMBI$EJZ=Z>|A zumwv@}zy39X*WZAwt2nhXNy+#X%w4oK_vGUnK>kRw0u8SrhmH9REgLH~wT1FpUSW7zXm>kKX z)dIgDLxk7NBaVGC!M;_3(J(xz1oP^vFGss~?_M?_6(zu5&E$Fh@F9+e9_4g8&g@#G zd{ZTXJgTh7rm+Tx`SxG_6^9>v6lxU}+sTN4P(+$#1mQd&m8GtdxTdI<>y_UnQ_gB| zWxA6Ot=Y*fnRWE#p{*7v4z3Ih7EFm16{U0ehi&0I7Wu4=vAv(Qw_k_xf$L$*YCQ^D zSVk(t+*Fp4K31iUu47qc6%{_4`m9W-n!1kbD(#qv(ABCG@`==|RC9Z5NexM|!3zUN zd3j=zQaY`a{V$}uDU}-jkNTRPEKkvd;OxEY)MsYnh@R%q3=O& z1nmL5-(AHgwqMK6N}AphxN4x2CO;%44@Ej4VmkB**L0KFv4Q>%+z7W_2isOdc?#On zir^>_v}PS>8z=xzdRUcE+B}w2ULqsq6<0X!Ne^Q&Y_0FG{6RXCvN)PSgH)JO+t;=% z=_!G_2#~(~%1hA|mtV1@mb6a6YogI6%77z5#IuJFvbUJ$L>N%ZWEDt--P(tMuvO)F6I60>sVVb z$yIfns7VOgYH6Svgs#nim&dvG60ZE6kHfb0uznS!q>LkUCDHwjGr#pK8&_sy!h?pJ ze$3W&N+^nr;X~qTC*wMmEtQ(lX)LMq+NxS|JfF0)QeohQXZiLY{U?|jQx;w}yZU3! zeA4<1o8%mu6!#>Y$f_|DX+GO`xf&w8svOMfC(WmAj-;anK&rijc;C^<>=rF>es_1N zLE7ZlHAJZ6#V_97NEoTC?%VkphN4h`)Keg}NPEKT^f8PoRx!^D|M(4Fd*pj?Vn`*7 zv@;p1nx_V-zUwEe{GrCR%hc{R#mhChA-jhAR$RiBRyVzc2uFFU(o`;`m3U5wlsqhh zDJvv%#a33_eFJTG+^A=?ID&ksj@TGt`Ri8lnf}GEU~EFUr2;&a5Hf^IdwP&sF-V1*+Yfwn z)n(k%yOm9~6geR-$Rxekbr!{Rse_7Dok|-N*LJb#o?FP>eG_b1qvv0UOX>7?LD~#fwGBz)NR57!OmGsD9^>W7aY`vYX5&IyQUU4VbVS>oH|WNI7D!JM zl`cbfcOgqU97a4P1C(Z_851Rgbe6zyutHO*7Ni0nml{KR-{c>^^d}$#mI_7eKvE@o z_<#m!!=aqdk_t%OFr+hr-Q>7u{Vs0F_OsDXV;5^`PKba>Tv4f^iV{T8f#EiT{(Enx z_x5XG&kk)xMfJfEITziAmKFh()5r&$DM%A5t8Hx3MRQ?6x_yqj+fkK@d%3Sr~B(4uG7Chd;k{ppo_`jTt8teU2;YGGC+X45X1 zfHW1FOxG$*WDGJlT*~^-e*~`HrpG?mI#?CUUA46?Q%V>??_rSUnqtyhJJzzQ5}-gT z8b`93wLp5>eD3T&UL=-OK$=YI-d8B_{R8_rYD5%WY4VnAjE(CXw0Qwp-@~68rx~G>10vUxsVPQVFpQ~xR5SR-H-e3EvaTC&vti@ z^YY|q?Cy%Z%=t?k2}qSCUEN3=btFP$Es&l8K;@|y2}nh6PtP_n**i1Cx8Hu9v2>bp zDx)T)8IhwTM%rpZsQ0Li4)XV3{xTDhve+QdppwF|g$^v*O+X8lzbYwFeRPe9b#OD9?({SfC1UZp!(KSz3(vo6L zrH(57q(bF8&4kN$2hv#CLDfQ=W6~I;GCj@^kjlwRMm*qLXLnm5JwqIx_UR{sRFoOM z``z!VrthJ_L5!tN9BE>^b|ZD^!Jrlf+LBr}d#9)Q&i*$T&t#}L8GJ*MMmBB`k@I{- zsGr=ok8gbSt4!?M2jio-qT+{75Q9_?nLRy7l>#6ks{;7#6+5}7cMF^IuqJddD>ZeF zMaNV?ltfLbw+;K|-Sq#5&%?$pY8ib5OL)AJPHu1~gp_+)kj|B)oNaSwXLp{Ji@8=zx_B7R57LJpeprn@93CFJ zFd&s?ZLOfGV>oF&tAr6%!{F`dDZcm4+e`{b%`}1GVuU7c7?JgBbku4L{N!gm{I`Ec z>G*M?nF$e8QM1>yFqu{xRO9aEvu3d+l{%rotS^M$UAddPyEd{V551uSm8zRt?`<*Xlb6z{c1q&~{2Ksp$~3x|&K z%ESo8behmkoi~t*=F==oI!{bmXo2($?*9BjWdHK*Z!3_Fj*eUikP2l^Q)#43p<^qP za->1}*3=Z=k3m{9G8&|ji5rAuf~o@P{wJQ{(f{&asSFPh6=!hc0f{w9!zz&KnJ^21 zRASP;NQ3mA?#*nSiRhAcxN1eoEC@)a(k3(QY3wVvvEkDnB7MjER3;ZIChsSiux8_} zx^B+)adMqhU#wGu^h7BAq(^vVQiC*d(lJO4mCWg^lo@#8xpP8h5Rf)o(&ofbDoGsW zTn?o|a(CXqwpMm`frT)?r02K)`JdJ3!}0O)#t3UN2xO}??sj`+yGirPv66(;h0BM{!3IaOI2}u9*yJj2-NZXN~ zTVWhs!7UwYSXuT}cDEU%2c-ma*9~m@`~z^w258S}c4Yj}A{i~l(R_&`p~QXro8MF* zot&Iljv$@pher-DYT62t-k8B~&ufFwNp8W6s1k+QPl@gA0m>RwsIiZL? zNi+7mF0bb9>d}ay(lGjT|K;4(vx%K~lRjxVDHRp|N{-2R#$sws7nlC)k7D0;HLPC= zxm*)So2!_yZ@R=FJs!aG?+ozT^qA@z!p+9nU4yg&sn7z&k_t%2Rd>$W(gNoL>58Jq ztn6+s#i4XaZXS>(4o3^5$#ylrCH>YnzNvI~CnuH(NULE;4N20NNS*YtL;D%RMBH5g zsnASQMnr}x?(`Ht`^SIgr{DS)j6#8^Tu_!Y#8(P~iE(SVyK}8+1ElFNQd&m0r2F~Q zwyU|Kk zclU4&p53>P{k0-_$BErtv7~cB`iDxHK@=3<4M;mN8kV$k4ZVfhEK6EyOL1@>kR~(i zl=yhdlE!y-{+RTizwr&FySqF=nlJMBz&l8sr9f(EOX?aSS)+zMInJ~H?H~B{!;dPy zF0s3NYLK2B5(o!ghz!zECPR~M$n^1vEmv}NCCdh>lNL&<_A2Cr;haU`%1vDM`A@(t zR}tl0jFe1(IYrE?gYB~oNM|*G&pJp`caLh!F@#@*8fbN(81USIy&S=3#<2-Z$?obM zOP65E3_Sll-~J;3={SV7a|Y5|JJ--XBe{aa-Gy>{W;RH-uZNCYy(hLl#k=M1&RZvy z63jn;Q!ME+2I&(=4sp~AshW~FaxnamlnFV@BN`pyhhO_U_I>X$rA}|wD)YFzNyfE_ zwl3mhl8ucO>c!m^;cMaUUg@sj{;gMWZ6(9Tib=LyQ(ZCwQc;i(-oKk|pS=%m*oBw2 zaGYk4#-qra5p~`{s^_>V3Z4OPO_lk{p?5eT`btt?mgaz1^T{o~@Vp0WC$uDTB(-ugZ7t8!5m%jDj9Tp!bXZH+oqaoW_@4}n|}LVxPBLY z%F;uKo3qEs{LH#*dVVaa?#t2bsnXLPnl>Ug^XhnkpB_HMaLS_Sy3_)pDe5v%+V|1A zyHE3-FaHUQORHM5B~AKW8w=-jt!l#m>cL%`^3wZDUJ}yVKcqsy)Fh>-Yp341-#zU+=UDjHvgKHpvC%GSTNGB-K?n{)W(v6-+wkahzsLH! z?^7UkQj*5$2Wg=JttvC(pLG0={V!!AcqtmPJ66UZm6FvpHkJV8XCI9NKJh+a;%J~UE^%eP=e{JVZX!Im5$uiYHP|!m z-Qy@Yx@?ZyRo#8_L0T}`H1kG*)P?QXXfeaMcl8>qOk~jHhS<~)5yxa(UBE~pvwaH| z{r<05bJx8w}0V4P`*g75zne5z-#F|ijT*66%#SjF2U#=JDia_Y+!qt z31{8`nELVaf#VL9I!X?kK=nfV6Zi3;x8mMDkNqK%lq|$V&OzD zoL4moGpuq%Sqs>qHp9A6209I3bE$#ychASPPrV-)I|8UG>la9QWtA5^xGley4es!_ zN7@ zl*Z8-iy>i{a9GMg-aIS(XE4mR@zPy)GN3Kq*eEnS?XT#-ToK zpxki~awyrAB+W#^0@8|i&&Nc9bY!)tyXl%rq--N<}@6s~Lw0b_it|M+$zmMNQZTj>klLcTbvwY-Q9V&=+9&=7E%n z=O$X5EOKT9J8cIm8yfM%aMqdAY-x0KUv9CKeH&wWrSe=>b>{jk>C8*11VcZ z>H35Hut|Lm>spwYg9@BAVj512k49}<8kMYs=%|kCtYndmMy1A4)p^HZ+$Y};3@h&) zq+Tggsi@(ZA^Wo=WwpRt$vFDK53x^yRIU3qIuOFkjcs^oMup-EY z=?%9a2?jzc&LU=KP}0(hCvUz5FaPs4puG*Cx+~TA`)QNvoFc=(2!|kz;Y0O@<6V&& zls6|)5wfHz22~7tcatGYY|;Zh_kNU|cM4EjrWi+F%SLUJ`fV{1#3Y$$2&7Us`nFqd z#See^thNcrD?g114T?PvONaJFq5^LMB=wT->yqMgr}KCp+={b$`XO+wXzN zBG{=;xVc2WB7K3(;PDN7>@y9kd}R|4%n{Q-dB(*I#BuDf@i?ZY9`%_phNtPSvXH2& z!uSuI37mT*FkzVFkQM_e|0-+49#MBSH%DJdIrCDcfz5VSdgZ*)(1_(*cOVf_$q39C zV)+(jL>545?c9lnZu$e(J@7C>$s}^A4j57^$}>27bsQB|J3iJZ$HJ+hQ8;((4ADMH zTazfWELg5Bv1Nj^!!)q9B7_-V{2;7%p8yQ25L=$U2T7#Y&LjVIS%}QnQDA?Tq`6E6 zx88aye*EJf?|UHSbm)YEO%CwfhHZGgr45}djBSOHb~8vC9VkyGu=FlL6TQJ+v{Tbj!v7<2wf zi2V1lFlJ56TXT9MQQg(^U2z-+@7?tZq$p&{&1z4(`pJ;XCIBm1Tk*=~t=OKq~ z5mTHPVr@y3va6h{`tz`*BfYyVb>*1y#SZ}|9S+phNUID2lt9gc)YoX4eX$Cp@pYdNJJmE%>KZ6Z+o)qvvYG>N zeC8axD77<4tXYdcFSs1;>no)D zIrRgAlznGJn&!dc!P4tGrxrUV(W@#k3|&q5zeV&@wTIyN^0BCAHK+C@N-PCZs;_Cw zKwHE>TYU`<_`(N)W9F(lP$30UuZV@JE8GJ}cPG*Bo#5T=rtZEKAPuYtd8VpViHCtE z#`Ri~cy|3}Y-sO*RauF&X(MAK5zD2p`N?PS$hE%)8k&G)3dj+p4AB&9QooYu7YO;3 zFTJmqU&;x{wuht%&O#YZte%WhYo}mbv4h?8BI3fgE6i{x*0f%Xt&Y@XY&73*8u(CHdTha*TBv{lJKQq!BH z0xOq>mFz@)ycCcB{qIv*LJ@CRmavZ(wJch4mFCPPy#c02^0Tm5T|$_p5=*^U`VO z&xBz`#-NfPoGX3(`<(#Nu8yM?7>gG_=^lCHk#DLb?QNi$Q`!PxL(0X=TO08D&Rs~d ziExPS{S+d(G@4#pj=Qe87Fe@c_3@-6b$bD+FU}{j!KX_V$lmI%N~I1jD+pHMwCZV? zS2qb^*Fv*lW9qplVmL!FqsxI3b|hD2T8w<-CGW|4u}Q`DE~?A17%2;OyD-_`P}f*7 zEu_K*S}kB(4p`sOftS{ALI*6Vugk9CY0E^G($?#9YS}hQ92?O@C!%d_`1fyqgN@HW z541K(u56gawsTnlqtZ0GDw!IjbOz~LB}hqPI3hX{pBOm{)16WYQ?X(OsS}C~Wk_ea zZ50+;#@FE3AAA{@K2iFrN@|~1z=HQ#45WSl_XWnDzJDixRC9Of-EC%9hJ6jBS;IgF zfL&~V*qFi#8#bcJQ1ym#p)_KQ@ojIwpD(=vsiiA{W>RkDNRSh!YtI{@KIARbL?cawRd9Vfm3kk=RXF_84pxOC9Wg&eGN;OlTvZoUJR<9 zLCWwLt3^)-eRJza6Z6+iugtNc|BZ`wpOu+?JQ&Hb(Ai^9{ zuf7JKi{NXG8rWQBpyY@dIQVOy0>;+?v8V#6Dw?6Xqf?Sf5elzylP6^d%hbwiH3buT zusDCykL#Vx&J)+MBOZE(iz5om{d0w z(P$L2&pZ)zO#U8KrO;@4)sonL!gGo!$QIvv2dR>1l&CqwM4E-h02z-pi45M@x)mE5 zTab&!kufaUhrr~d=f^gciW*8Kr3qDX^JYAC*Iiip$iqNevxHudO$#s>2GN}+x~RJ{ zc*+UH=is7MSrSGhnH3Vl+2anz3DME0>u{ww9NAl>GV<9orXj_{H}VLzBQ0*xHLLCWa5B`S&(huaPgFyBnw2_dxoeg^#<(%s*zI0jW|SRgcm)5~{$~ zde-1IvdBepC^2%V=tyGG&Huu4H{Ss?>=fgMa>ueMdsL64eA%HQE2}?(;+M2~67eK4 z7^rr_7-7axAFaaV+EJKZKLO(oISB9i_ywq#H$&-cIn~yJUQH#*)WjC2h`0HRa~A_C z?O7^|LY((10MdcRz)~w6MJ>(Pu&WV`ok?lAk#cE&vP!)wDXP>&1r#!Wtj-RM2!-&< zLl0rm9k-)(?P?&|A!dQpGqedpwR8nlUMUbKHmQ>8lH_dyWe#w3s1|3|AB;JuLTysT zmlZ)?MAO}o%&WRaq} z3ma9PDXe(p2|W6Tn~~bEQ9=!-oAp5IN`{E6%HE`)!1J%H#gbP1-!n`=>R>5MR3MBp z*TgV0j>)6Opnl3kob|bnn`CyP}(8?dFl9lJUba7~7znDY~Y!}?GR_2eTpggL8CqCyIAN`bAkOB2AN4I8l&8MM2dh#4+wl3BFBz8ZJ^>IQ6k{dKt6gh&aC&LhX^ znndCObs!++V2ERb)$3s*W<`**(0ON zrjEDtsLn6~e?*)tDx54{y#IbY^7}smT*Sn-%)+s3mBFK{DY90um%^t>_2NkLyt}+@ zK1&?HyGp8YZrwpRJU$9l%^8$uS^xC0wA9cVGqFzhTU zlR3ni+i~-iKgar)UV@Ws1#)Sry=#y|ng@u-*$pf~lv@6+tKnWKt1VK6_GxuBTAEvs zhKtH*6!EfhoO#w+_`-!3V&=TL61yZo8LHs^oRaxW4o-SMNIfCuBjt&T%cA*-R2J<{ z4lA2>U|TkcO`RRsnMorZ4guj9!d46hD^;)>q8AjFgaLAxsh+wj>!oAWDm-?}Kd|Qh z2PAEdiSdk^<}B6JSi(hlADilg?guH=T}woy3cHMhiDRn9;k4?BI5=E`csn`4x@;<7 zI}Vbrjchz3y>e>Lo{zETo+LeBvJn&EIJ0*1Z3RR%7D}cUTlK#SWtZ-rMY(%N2PVs# z@Xw&*h;hzun2|8z zDFZ(j8biwc26qn_GI2l?gb=7Di!1YYN=tG2I}g^;@Fc< z!nq&#Z;YQl9c9CY!3aeVvBGe&HX^2l2#X3*P%xt6b!lV1IR8dq(&kLLz^>LLcDA&j zp|u$aIOs5KBq^Eb-POKpmt+9uiiY5tB+)B%lx1MZ_%X6+Ni@i8-ipP4_#4(d^)wRA zjR-R#K9h#Y3>6(qChtQAp}Wsp2UDcPjO${!4IGX#oHKd`j;b7k>JA&R3`0d6r9xBW z=41k>DMRDvGEDsZ1t>dqHc(v-gu_52sq(s9P>&UWFgr{2Sa+Zvql~ zxkM18qy_%#pZ~&-$lYyiRg!d{11V=PS5ym9n0mwi^=o;4%Qn2;-iS`=hGrttnZov$ zUd3O2_ETWzHXxglObjJSZKd)SF>Lfp3=T}!UA6kCMm9(*q=Uzbg)qE+Easnb3g*tA zkEt_eB3@CASiBqvMPP-(h=d{tk&WYBR2(cW(3x@3mQ0{Ekw9xQfsRZDNjry>Yr|%D zHq%DdVCxNbP}77U>0See>NUd|(&~{ORvV?ZgSg>h%bJyV=FYpY@u7uqb~eH=sruWn zvuPPmTd0C66)Hatd2?AwI)kJG5*Zu^Wrm4~b{MCXjK)c|6L3(Z67kNQ*rLo3l0J5Z ziFj!o+uB-?tcap>+6Wx{-H*eVQ4f@s0#Ttlcpqi76QKN0x~v9S9eGLmc7)sDz#g27 z*;HC2sc?4*(#IZqq?=9pmP%3yxOuC*2_!5Pj(M%U6EAPyip}k9QV7gUXJGAW!fn6# zEjB#)AAotK>|kx%$hk}*SKdpR2f-xfBDKN>3R3dqLZu}bUSE$nN6*KhM;wj%NmG#t zN0BOt!3jqZ3P)jC5y_gN|5;*$j)PP-izI=WO(UJl3h0b*2yV!dFbZ2Y@(EPC46h}J zr!LYmj7xqS$vNGDU01w)Xwx3%qSAobKtnVSk^bl0=m09z@% zx^+8V-MSea(XeYCHzSIHwC6QXDSZBQJa4c0 z{>byY;V`VyQW&Li9DB;?IP&&t^wIm^na0c6vdh!BpB)#LQhQ!zdpLQU2{IjwD%fLHB7_{q4g zFpb(rSKy!zo{jK%#{e}YKqL%EITzKL+*@+;J!;o&2&DTuNL3g?GFoIFiSH5_+eOl}(3o+sytNrm?c9ns7TKbN+O-3Z{Ozw; z{nXP)Z`_JdMoWpp+t+Gie=G(iEQ>fayfjhmRAP*h)%sW|fzlEoa_3?wnJ@{5oP09I zOg{hA%7 zg{|vWW5x5&;f-gXLt@=}#bHjQrNf*YEz+(KD^{Mcz=tNHdMDq4-_5K{V) z0%)Gd;D0egAl|jjvsn8GY;HH6bTbp-I2zV4Gmb|)-2Tp*dONgr=P?l zx7>o(XO@Wf(_#pLQbbb(z2El~NQF|zsb+?RKkHZwk&vHi0Sq^=g2Bugm^t@Q%$R#9 zDo58L7q(!BO>~+r+QSBH%Y^Be;w9xrIS-W0W(%>M&Kr^mEJR4SPo$7;ZAG@T9WN|i zh%IYZV%zeiKvSdY0%sVA89b+p92+NzB=zeJK7e{6Eblz>sqxfChW}qH#ZxLKW?{0~aVDdx7nYSP z@l_T_s639*lO|%u+_|WqG8q%5O_5qZ?9|3$VosJo)F355H6?+B17#mZY@m75Hf&$B z9;;qmimmI`prfe)nXMavY!b1`3Z!;6$f72$84Y%CAt{7eJdo<(uSdZX_^{WGPzr$x z7nqJX&aa=1Q%lBRL`w!0G?!`Dnu>bJ1%`Gg9Y>w4^*f>rHOI|G%_q+VYD<9XI2g*)H$~z=UyGzoC9)7?*>BN)v0g!4K33=4Zj__g@(o#XK+>9S?%>b|O zY{v42jo6iJLA)%2WzRo{JAeO2IIGqH?HPnAeRK+ymZUyzXirkLH;{V%;=FoDX-a8f zSRrI{OqCM@&-+Q@YY3rO47o%SWh3e^W9BT>&zO#~spEmNQk0dJAr^_jV(inK(44O< zh}_)Ri0vCUqix47Y<*)5+PCjSmONz%r!Yn(z0sxl5*$TR2(CnaTT|P)L~-7dAgT#a zR%CR58pFUCH-z&>9fBiDM`2<*B(^BqaqtG+kPBPlNd_{mBLBBm#bD2yf+-(73plVI z7&A4Oj5@1A_p$@>UMeLxkv&?|23Rc)uN zppBEVfXxYDY2y~W(Xbf_Cyn-&COmQX-FW?;2Y?-|u+o%qN_uD#xpvtGeH8(ds7IT$ zpdM-{7l=Flay{Z&G7Xs0!;}>?ZCK$LLZK*1YO4_*H4JV^4ADpo;cx_|NiMFI{46rx zh)gntOlLyWTy!LWR0haqMKDs$Cpkgxv4^g)<#;rI=XQRr#yUhKpSz;u!v4Ct}q5PE*a5 z%S)7s>s?wB;(Z{^k6|!lMZc6GkiH#2+Ep@;C+{gP+XSwCQ0=Xc}EM`bzUx}-#OJKsob<+S|K=O z=n!OdFi8S5%c78yj}R8zA`L& zZ1te$xQ~ph!C4HXd3BR?K7!Tzh(YH;Y!sBp8+RB;d!9F zQkn!sw?!m>zux{{mX0`YJWg?0ju|c%=0u0%xatX*9UqCBv?&C7dUNS4lK3v$wtDMH zBxwUR67Ej%IH(q~okyIfN#tTUfKA?7$)m;aupvd;D z6q7pV-~6g-aE({apnR+&Ptp)KPhS622B|L2MenpMCgL+w3?#M6_&ACpu9R+}09v?T zE$Isq-y1tG_DY9T*ijiSW6cO=Myheb$SIgtG6I#YS(MwBIIQTr6P8qnq!QL3R^b;r zlS87q6rrPMUY!h%oH<(&a{xrg;Zt#XaIJTroMq10%_M-lT0RX+rMtZC7R5z zuS?PbNLi{xg=bhIgp)sIT2iOCA(h4U)(&jgx&u45ZNW2-Jb))3c@WL3RtX!(rEQlh zNYk#$U@_H6FABxgs)2x1RCT#vP{H%5be^=){ApD0e+aNY^MsfwHI;i~z{I7KeEUkBCffpFBv5Q0lxJGd%{AfHg0s z3LVaw^gRY94vy4fUe##4tE>)V>@bGeA;dBTas>e@^hY7xt3`!1j2i3W7;(~J7)vS2 z-lMdOLnhK;#ViWBI;p^;R}QJWy@K`~22%DLDS%WJ`3NIrTS(g`I#LdHwKQV&#$|Z< zrRQ<$KmLjJFTbLQ21$B5Sf9ie+mM?C)4Od&Vi~;+agnf2x6}Iek)(FdwpORrJYg?1 z;)!`#Cc5Z~-dT0VcwXHt*n3)5n_7*|tK}*!Ojf@+`Nxfn=qr6j%hVsx~&!MOkad)-q{J$0X!q*4UvKbjbXsD9Yo+@I6|0? zN}Moy3XZNAgNZ0XtR;yE3zwP78y=N>QFU>GGaU_~HRPhRGz??*1k`=(bd=6L0A?ji zqcBeFv5P$WTkKKo+!_=__8)-yheyvDI*#6^Anp3LwWKMyloUw$Y0Gw^VdqXPS+WH8 z+MLF_B^wKBo%~CqG1T*fKV-tsvV2Dv_XwBRJ3PMLS_P7 zWEclETtsNUdv$*^Ap>o(5LTyJ5Ib-@roI0(l%97CvLnkBQNcA~>XN1&QQs>SJ}7wZ zuLt=Tb-&|CBMOD;J@Ld7NbPDw zX=N1>Ep4htsc&R-NtL`c>MiDZB7}E&4Jf~~^+y8t2uOo7)dQ&(viW<^@lF-*@SIah zJ)k6vIR;9ZdIlS#QHlfOqi{&gC>$86!Z;&_@|2Bu#zjd^5l3{KiWxd0g<+sGVq!Q6ZmV=g!aIA|=gF|`EHOHK7!Re4lgqWx12?%whe1nI5+{1<+5$xoEJd-pwe zx@Vqo=GzXWd0_g>Kzb@;iqtvUP>zGf#zs8$_~W?cmYea+Q%@t8N+Xv{=Uc)D>m3!d zNd1zozaZ_R#tc-F2HtnxTkElO^a3H8gI0&7B%-=|ER$};3voZSQqkto3N?J}f zq(RA{Rz=ae(hzrV((Z3Z2SNI;fBX}d{^U}$vtiR+cirKhb=FyLOOX13%HK7iKozr6 ztQT&bi3A>h>~Z}5rkim8op&P=iR1(BI^R+=Wb{A;?M&u==D!Q7r$JB^QFr~j^r`L^ z0jXAPb>K$DQAu(K9ELtj16Cv?xu;G?3e^Bc!NL?&;ppL0F}b7)Ih?C=(YA1vR?bR9r=wJcr zpTnZe7zS>-;YM73*#fk&IQAWP{M$X}oO6O}cNgyG?p*xMI#x-}?h~96vZJFDRh5-! zX>G+5RDEy08P6Y*Fv%^!wDMs%uzD2Y%w%Ew(^V;a z%xWPkh@Nt)%an?&qM8#G7f6LIbPg*;?C66r>FncS95h)0RQhNb5)*YT#miOO5I}c# zo(CoA4cFg*D;He;&H|~dMm?yZ4$G7<3=s-Ry`SaFmf?>#+=R#Pdk{?x4QOMJQ_tl= zsX{V2TSvGagC-v!q20#3N*`@6FSUKsHE-woil9knKwp^>?P$q!lcgu9T2uYxhOVly zSFM4?x1|LH+Xk!Os}VtMs2pR>5}Z725+)jP)F6y1BZN|VU`1Vbg&xUpjIIVjshFl6 z8gh|}80d%?=!}O^f5PDycJ|T0%t>%+%8)ipM02L9v&7009${j4C+E=dg%Qv|<@~wv z`WtY?g3HlPNqWmIe|O*azW2TDC26sjt-~c!=h@?-N>6UXz{^iRiwFOG7nVHvG&ZkT zg^spnk)gH~LWA9jPRo@dXf{dZ;$2mh60Dqy5OY;kj3eJ-KA)Q9OTO;HMOqOU zl(hA#==0>ZEs5sr#li9|EOC-!9MsJs8MBb7t3cKKSr~r8JYd!&xFaj1_Az_bNtFng zLRKhF1Q~+do)`fx%mk@O(x&|gq#QiyCQ6CMJkO34Hm+EW=O29nuPuBUt6y1$bVsKo zH7{@4h&JTV0SB2d>-Z=V1>=yGO^_-|p61pn`kWU9Q5Wi(b>lJk@+yrdg+#HX#P-tC z2+{&UL6;iwJhq;S%PO|CJBQQmv??&lD#47}(HI*oM_nY2+Khp^q=^!nLZbeY(hA;{-jEz>HzOn{mODZtFqzV-|1996xNzz6|MwMQXtQDrM zvV#omP_LK+FG#|CN7z71iHVl#D6Gk&F!8v*tUEXq8S@IckROZ<_2u&*oh`&(1r{; zkwp@=bivTo2mBx!jnJ;5cqNEO<*Xw#%-b-yss6f@8e zH!<~`6Hq?q07Pa_0ftuqG<-^H>O&wfy64#dV5J>klGz;e=NN>3AdQo@xUr9;_ zkjIx5w6!IqfLYth4OqK)2^wBl1~ZXCBAZ61ox!?>E$DDE*xuHJ?WtC5MJJM~cnN!z zi87cKUNOsDvT>7}FTxcpv=CzX5mObtmhNQ)si(^FCqb!f%^0deF;o~KOsF0%fE-a) zflAxLuv`dbSwn17*2yiknV_v|6?y5_5(A}8P2nkRF=S@7Rd9!uArVnU-*|tl+Mrq_diHlnJ)h?0zB6^Ly$8O5ocV_9uJdft7UekFU({VC z6uhhq52R8>G?N87(?EL?XzIkK2Nt1y^=9nYxEY!DPPmMrlAvG$&2|#Y8@Hg%$)F>Z zL@JlT&bCG*kwK1?6r?-1E#TEQXyG>n$gngpG!cOz(vqrdsS!qbv=nhGjEYbM72z0$ zm6W3s1QP?EQ<8V zN>t67in=3a!#sF0Fnv4_w~(}4xpykHQCM9;>V;`o<48EdeWafaWI_(@+jRu!qqzRM z>u~kuSD>wFKLV+C(&WpWNb3e&pjjE2Ica5|19r5bbLm<%yu1QiUVIJau69@*DPi*@ zQ%RK6R-hxBMlzj3GMhn1x>Eql-_wSJt!+(W$K?y36jUR{uY@YAtwJ#LHtF)6v|$+^&DXwWsS}2d7&mnkSlLgf zEo{ITJsjbw;}AdO0F)m*1(-1fsEPw6Y=F#CEvo8Z$h6csbww81;@UQ)B-QeI2&j8y zeIdK;#v5)Bkam!9w7*DFKS-5Cb)@Q@#3ZSv3iF1O6EJA6?&<)xw*f0RVf7=6(e%bT zBpMn~5ss=h^b*%ppp!yfxt#pokxQe~biC4+UO_IYSg6v#xOb|fQ<@@G#!3aKW+p2n z1A2~i0!+T{u470sFn%vp`#i^2A%x=*3_M~1i3#bDA#q-IJ|lxDTTzN+WeKY19E4#< z&r_0f%y6KhR2p))5ycu(S+<_R9RMh^V|0UGKLaW_ONUh8-N&u%*b;)d=8CJ(-rNG? zh8wPPKmF-X?-$2jZl|UVInrYwX*3OCEVFl#vmbHH87^LhaO#eqm9ZqIt>@$5!D!X*ld(f zn+O~*Nx~|qECouUKscgez=fva1(5n@gw6=kAtT>+#XuRXG_m{BcKlfC?mC$NS`y=22JWCp{W&UZbf?iHf&wA1c`N9(6Vte zqRA{G?I{V3kQ>YTKDm4|CRM3Wq^=Y~D*#l$>Rni~>++>o^4=zotLvx)bwQ{!U{V3T zIzhz_At?@KvF?y5{bktOG{N#FQ5#iL$D@AcbkrU+6__wus{6@@l@!7u>2oR-9Q5nv z>GP{Z@9$kQZ+h6Jz?$0s=FaXsv41?-u96_V=BlgF*)jyuuH!1{T8h~ts;o?4dP*1& zWwrR60&B{Jy<#19u3Ur8bz9J}Y9ri+7GxWm5l!YWqO?NPQ*o|11UySK6>MNtXsoal zYU*EJSOzOO2zr%T%@QVA))QhU^pGkHmX3uHsw_vWwhGx{Wf*tbk#I*=Av9(rP*x(< z^2Mdhu5Qx9MTt%_j=F3^Al)6D?bfk=klJ<*zrXP&0coPGy{jZGa9{UNNvfDX{#IlZ zT&zr}yHf*hI*S;?Hi@i~vg@}XwPqt))^0-6y3MfKQfOPZS)4s|@(4r8 zHlcCzHY9d7p=I+nX~}4%ZA7!K#5hA)rpMVr`1j|slKjpZLv%v18hkDmLW&YF9z&?2 z6m~@koM9Cx8#4lo)WJgf?+j05!}fp`=sk4v9ZiIqqzS2jwb1IgnO%RMq&!IXQ-!@s z4!V=Cm*OUewzLD8T%m%Y%4744RIe*rCjqcpI6dIjlkfA?$mv;Xtiz!~>HN$MW} zot2{GP=WkjDB`EGVpM%0kAzNYppz3@vy2&@D!oOVO*vQPa)#J!SZe+<$BkZNI-_j0 zU*0bDBsD`LY-dl9GHXT(glh@Ub1CUam03HXBn?ln=%*j44sXgOrnau7!gOt-{!c1h zo~EZGhC(p?AImQD&ihA(l9Z04Ydo9uH^2Rr`?=44ZV05l5eOD5?kSmEPgcz_5TWH| zuc&OBJoljM_~tvPDVm}JmJg`@*i60^pue=If`P8|sY`r{4ejNm7A~mRLWQk+WHVTE zX>e1_dkk3xdJ53&&Y9o2#|DRs>aMm)JKEb}{QB3wbpQ8%|91$ay@1rO{uY}mnyatB z3l=Ttt?(FaQiV~rChQ6z-7Z3(H(0JDA79lt_jR5th|R7tv{*~I0s4*lM2jw9-sg@( zJ1EU2u%>C7^cs413DRHv>KE?kKmYk5koGcRdXl925Z#us0Mf2t>#I7T25RB>K>X7C zB6yyBeAORU)oQlCRD{1&cagr2Lm+)?SBu_2Dw6bc(+zY>W;Sfl7V4611s1Mfwah|4uQ1$p!8=<_NPT_ zcfi=wvE9fswvFqryIw%r%C2g(N#Bl=)E~C!E9BANfelVbeT_YJ{{G&_zO-L|yw5`* z-Mu$f45T;Qa04#C{BpFjGQ&03T;+c4YhUZPx~m->d@*_w_Y`E`y<0DSw6u%xnkVT! z_7sTr6_6HVAMK5??9VxaW6fjs)Oh#j`uoE^-B^^4i|enyPC(j5NqY6wSGr&S`qu{p zQoS=@U?!6hM*^u#+@jH_^#AN>Be471ovhe7n8L;DvGA7^|1!<|CpdxlJ@?lOOHcR2 zXW+i2rKMu1S5{W$j|qB_dF}qFfV(rfcz%v&Nl8f;x?nb&h2;_Jg9Hfw_4#1Aie6U zE8K5<;~N74sRo)phy%pI;1&*t`<%qPGs*cvczsSBP9%L@{cnD!fy?{RFNxpx1TZbR z_&ov3<9Qxli=VQxGI=&mVD78WHJBID*D+cv(F+johk)f66STY^j&WaGF$Z5?$LR0* z?0V8C5(&BP-Y_rvdq4fz&#%pKyeKTV`G4n_baZs&-)Dc$`)2IZCrGcja)JA;Z+>e) zAZ0^du2uvjAWkN3T(SCE$@}`gw}Fw|Nl(?*VAX%)dG)H#NzT7(N!r^A%KaJ} z8}pzqFE7snl*bViot>R>?y9P){5AI03)Ef3InMeScpn_|9Xoa)9*-Bjw4SK?=U~TK zYbktQ0+c`ZWsq|2Q3E0f`R)irKS()lynoJ3t)1+xcQ=^x_GFV@dBqjVadi0=mvsZF zN&@cLt*#}{vSrKg&_fT&p!g-4mO{ZB){{nqYOoFmUZ0>DIdUXs%$R{g4?R@C!}IYP z8#ZjfOE0~I_3PIQNRK@7NQ@aXMm~Ofk6_>gT(V>d{_~&z$cyGn=Ckk_I9c^Vz!mwR zgAT$er<{Ue!-fs!UG)1HKF6j_oACJKkIPRj-A9ZVfz6vY=OPS9RR)rN^eS(OE0|??|tuk1$+e6 z0}niaJMOqcKuRD}8cm!y5%cEF!v{b3LA>i-@5-xk1S4PIAOHAAc@6?xOR?a+ala{3 zrr_WI{x|CC>biVA*u|!&=jZuWuU?Jse)qcqRKMo1JNA5k9ef-|jx7@}KK}8K%i`9P zr<>2Pr=NeI^WwGFUc*HfU4%u87Rh~T?Ma_UYk3D8Z~%VvqaWeSGtV68CHCt6L6G{% z48l0N?6RM918Go_7JCT<#lsIjER&lnnBGU*ar&wJQd8S{{BE$TJdf4t*HK3uB_O4w zD+Q#FKKiIEG=6aQ<}~VUHucvl%SkQv#5o_gx3UDW$xD)d_o z(&wIgPC&YN@nRXL;Qi=#I(_RW;Y(lo5b-9usq7cNex|_uCV=`1iBVJ{!OI#V;^^ z{CLq&xbt*)-duYUC_8E~%rTqyYa+O=y%Wu-byJ48EP2r_QR z9d{gl{_~%UWTgsAY5M!$|Grmsm*=M>B}l1G(>4rleckgw-W>0L#flYqNvgwJ`W%D3 zR&cy~0$o{IIamnbo8SC~grjn-#Uvmt?x)yOAT4Gx^=I5@k5cQ|Nu~aWznWb4m*ZD=moHylRFd{*fCsX|>wO8B!w)}PR{EJUXNnYE zx^yW{KKW#kjM@g#`xDgs@Vf&KJP}L#N{Q>PyRKJtSBG5)(gz=WunR~B z3z)vfhKmlhghw8EBp-v`(;)SmD21^KVf5(HxbAn?;rQc^N30|U+jhLhRK@R_o$6R8 zm>k|>wCUi&tv&EsYtgZ9|JesJuFpREY#yXRb4zOgen}csclXpH)7Lxg>H9t<>4HnU z+oV#R?kxbRR+0O9*ouk@eC%T%!?(WmEwK+d30{8rWn6H<1=zlQdtN=$=g~GCB`59J zKmYm9qO$4$_b-3>O93e-kB(3J??J20^zPCQe>1$h8l=45-jbw#M;@P7V$GI?V~;%! zS6p!=rXMgJ@lt}cd;KL{Oq`%(#Zhj$z8VECK}Ly2(9r(pril{T^Q!-*ug#ym%>g}` zRfU*B#R=M^T9Uq#K&oug4j5M~xYYe-Fi!d=gH(q_I7xc43H_j%Jb5yH_`@HH13(iC z2+nVQ^P3`hnwy)u;G8d>=cNn&BOm#QfSc+tHv*Ru*$>j-%F6rWYEMZ@&}e(Muf=4r z-}Cx!7D%E`v;k^AuK9qaKOC`ive_uMY8CdjB7?0XyR zaXm>=f>bIqyxAZv21E@~PLg8Y)!@S)ee}`d)uqZyY1q=zB5~4R|N7Us_S$Q)X3d%| zhfuBM%jf>z|Ni$ynrbP+Sg1#s4y%b!_FGIw671e*-RSQbOz~E3b}L|Elo{mZEitB z!wz{jl&F-Rd=JrZ1T__vD36z+rn*{wlF=0jhY=!6h}9FLk*uz6<`_~9ru|JVg0Wt{2THGEAmw62pnU36 zpAx$~zezX6LjObl{+{#C#qePx5cUcOOA&B(aRbl_Tm6@_;byXEZrFvE#$8yqdJUE> zeGSW(zJ~3aH=}7+6Pg+uWfsND;?nO%7NMMj3AH1of%5pV^_Vz*0uDQLF2>i7!|>t5 zQB^-y^>$?=9qxZb$J>4WJ$DCtNLJP-9 zbGeJD-@FFLpK3h!*Xq2M$OE%+b>rv)P+2}j@=3408tp8fvO6HSnBxzw%2PNr1 zLCX1~sjeJ9jxQN#BuQ`q^uH614FSqy_~H8@IFCK{SaGz`UosG<7mWy6ihROUgY-(4 zPYHrlCV#$SdU5ZrKcu2xbYC1%4gl3ms-oP2Akp4aP9%C=Nf;nli%C*_eLn++_pL#~ zb5p|TK_}oi!8y?>O?1`{??bDXL6G)zf3s)L7IJ}>X8QSgPQCiBTenWiG2U{^E!ets zYd&7<2ZffNd|pZq7AL0)MiB8lnkUR>;yr6MR%;yk-t{@Ts8QV`sf7CnH5DGu3B`qv z;U|(hy53I#q^c>EcyMGcWKE#W%_41C*y$$F)Y6R2tJY!diZ}4$)6Zhvs?~VyrI%p2 z2JBQC$mXPt1)D$-=u}_XK9V4%aZ8z49W6t|HQ;2j$RdRrs}iGzkHF}?F-T&baf56}V z_BXup$}93Nf*_@aq@^k6!U-pwAS4;G+Bo-m;#PNC+2s$tgS4%+6~;y1`L=t>Pn5cw zmrzW{>OtKt22$-}_n*VRnsDMUobc11{*oF0f~uafVPQ4?FCzJUI81B)#HF zk6{1ZZ-2|B6Q*l`E6}hh5XA23ruC==S27L)XxrYmUyQ~V)FgNz5-hj~GG48(7aU&=(yOn& zT0&JtLCW4v>>x)Y)BsW;s<$@QHSNHf9b2$r$2M$PzX6Zlb{AH?vJCdFCgtb}g<*Q_ zA(gb#tus7|UOslBq@l!AJ&DalfyYw9()Jt?j$>v;9j1&JgGm!7Vf2itnE$a05Sug_ zHhUr)E-c#cI^F{y2-2XrqRl4FIHK0VvDWrG=LT(l3J1;wdW-!V_v1U`eA4VSF4T-J zFwK+a^=|{VNdxL`Hl4-|*I$n-u4MU?78n1VeJrYQ96kX2Rl;jcy;YcY--qsSC+nt zXBIBP`j?l(ZfI12QA$UGj1rFj)FAbmRf)*+K$`FB=1Ewp)#_NaI1s4iurMt)43jE` zVN7K$YU)N{_9@3=&gsXaeEN7~!X~VcG?>h9+9q8j++F3=@^3+qzWd$p&YKb3kMn>8 z7skt}jRXP8f9r)^LQT0GKKjv*$|8Hj5l3|M1MD4;UUpfR8|&)-_ILAAyX}r7-5Ve! z0H|jE&;R_7IBoo%TP-d5H#&Ss=_4qa4a2`tqB3-&9Y@6^y$-=>Nvf+)(C(!TO8b)w z1SJ^(98__&^N7bW#!E>?4l(1cykDJE9(V~w%arscNe2Z|X{qQpZ&ueJ+f4B8FgS7?y0Aq5-mwP>GU}WOg<}ZP1>MLI{4%#KPf4aI%8<>OVYPFNC`Ho zC{!KkjnglM(vAa8b%ucAATu|T5|1mOmN0$ANwuWcAk{8+UW@1Y-S2*v_at)>(kr(H zly*$eCj7)FJ|P5uIg&a=f5G_|2#Dy=5rB#$6&VcMFp#ue>`HWE zebWwX*|h`Pwr|Bl_uhx+9{&$gTerio!iX3q9Cj+tvL~y=aq?aahFd&%s=4cdRI`+H z&qfijt^%lGyRZxcmII8atdd5{Q;bR+J81@{Rn=kYoS7JT>S3rmVit@M)j-&UEnU)G zyx=*Go_uPtG*#w(`8O_-1aAt13%GN6zNPxV!p2}UxuyQw_(esO|U{?#Ho2ClcJ`w2{P?XdVwntMs3Ex zG@}w{jh~5eqsE|o)?^&<(F=e>CaaF;v@0D4FTA(}-?`|!pd_^!>S2RsUrRw9d#1Wi zKvI$tptR+gq@gtsJ*IkpdU474;lH^sGsaF<8^d}2t=MAPZ4&nQ2Y+iyrNgFEY20wb z^|2D9z3Q$ASHk}Nw2x;YMg(;1xku~)IK3Az?4tQ z02%?TY2AetZ>+$^)obwJZMS3jQ_lbm%_w7_-zao!<)q4HG6LM%npzxw_+dEx^wTlp z;2HAVls-}h#x&5<+KO%4w+m~Fq!T7ZkX=(6SHRCdm*b$sHBse;QRf)AVB{Q3sv3b2 z(l0tN%hHE*D!sTq&ob3Y!v_1{RXT#IndMJbEUg#lYRfMp{v;_)(^=GkgT z9&tq8o36uNlBn-xDAAL8?|t{;KaW3wd+xmlq!s4u930QK4donBp(BQc;cgg*g+^k| z$O)J-VG`=+9gLYDdk-*W3=m<3KpW4#^di2)$_$jGwu;9FB`LKU+K^1aql9FK`p3r2*rbtog$b5mi`SF+l^=e;rC+0+gQQ_rL%B z0#NNh3No_#0_&az>AB~fE9$P6qy!wu(S-rZ{->I@V#ymT5Y9Nb{SSY}E4SYbw09zI zga9W8Ct||!QeSv)B_*YJ?|U!6r$7A}NkWK(LkL-_^eQ*b4{di#rj2Pzb_dn-Yp%H( z_uYS=l8QMSmhB*%vt%0e&Ip{DX>4SBxxY0L2)?9Go`(rqdrB)bbp%muE1$l3SG@VT0 z#v9pY;wrSYwZi!3SHI$3cKHIYh?fN;p8?~`Ast|=k05CIvcC7d@8#p9J&^_aYm*k6 z)TD9IaTLse3GPdfQq9pI<-O4^`N~(ml229B$M8FCU-EDMJV>t0e&>RJRpm?M%jY?1 zhidg#OBJ;s_R*TmcjJDL4#vAH&mod@9GF?bV7?!u4r>>~l(5S#xcK*LFJi;a287zv z`1Qq?A-QY?kaJK+oE>326U zY1!K{+|?%Ko~cAa<|xBuk_GdPuYB3PY{3Gt8JGp}b_OXOBD%C=v6sYw)smDFQO7#_ z0x6HvAHHb5L>)@fo?QOape41DETYeR<}e(?Pt;KLvO5Xws9g3Vkm z+bc*35G_#&)Qd0qF@F2o-@wkfs3?iSOsYcb$q*2+fsw9-S=MlzHDNYJ)(peMQ;xzx z?>ie9TMH-R;!K17&K9I6u_?u_~$}z@ax}q-9eh{ z>=bG#K`QyAU;WaBF3Z`QUaHc*08&=uBiTR~9P7`-rX(c;gey-^>Nf|MDi7_+{({s$ z(7X@50`nUBzVxc9|4ol3y}oo5>0)O(*4Dol*LAPGElCMds=A%o47R6|SiE@yHt%S_ zvv)s)2mkgDpsf|Kvk;bpX&~gdC@(2Rdq=wzf&1kzekp2hh;dWNEzJeZto#G{r5eYJ zC0Xu&;C_7UqaQ^}YYUv5i*g~7j-x+v0WiHDsEpy6 zS6{;aBS;sj5R4s&qYiY;=_n$fn(bF;rf3G!;Idr$x_ZwbW%QsMNNGnDsxo*w?f_L? zQFj9QaRXI%2Mf~k&O1+R#UL$A-w!7RLCUx$Gh_Oaq(SM$=is^YYOKK%1Sx?@N5fBk z@)NOZ)MQkjp0ZSWdzEhnNGT&bQYmcgXvd>#R-m;#fhYcY8(w;BArcMS>BG%~G-{X# z8>TqM=v4XMMc+f+s5&(+F4;Muet}d%Zy`&(!}I3N1?%T#QfW|;W{xGj&S3|LF~*5X zoH1$!#?_2O_0;h=^^+ffHD@YN6UTEezaWkyvY~|TrxViq!bcC^6PWZ&vp4|f37t#+ zcf99RT|rAAogUDVG!N3RU3j5OBClkeu+IpMeP+%Kvd3q!=jKECuI3+UsUj=@%p@f)-$HsOI6A5 z+V2af!SfXZssEn(3c&i}+rMV3YZ~O;deDE>k677JK z5s(^|i3mFgwdV4SW-bJ|i?|%oK zCMtVW0X{^!plf5YQH9g%XJCBgaEzHc38#JH11erRyc{n)|1AFBMHk_zMT^8~r=$#mt9d^Od9*0+W6VYMFeOyw~7++cRJ-Zj(~o?E+Hft6d7p{qT%5QX^KY7Yq@52vjq6(j zQWL3+jm@b9?jlHATCwPcf8eDD9z!PC4%iux4n)ZZTag(E(rlYKNXdg` zxPvcOC)gHq1o>A+N>Z|UbcZzm{(g|sUL=uvZ-P{(K2g=BT}n0(B{)}ShHZ3xr8f(t zvM2=Nq<-&i4kR{&@*ur;<*R6JX~h#a{sT)MdJImo6K*y|ktWlGQZ&LGOvjP9}r;Zm% zYRpyY?vm%96PuKA(i|mep5|CEy@J|Mf6WV0LCI3$e9`YO*fntXz}gQ<`lZkRuY2va zzvv=Gm8LuhW3-1SAE+c9EJ#WB(#g2RK*|+TJ9X$@@2@1)Dz4u~EvD{jiNS@1&Ie9N zzF1CVei)X~s&9WM3HRGwbvFo7I@p93=-F?Wpa5AAN%;naQT7-0#brA7EwjXdjo0ETw#&|t3{9~AF?cj7-=9# zZ6HdCiX5h*8fTB0iTaumsG2qor+(%`Fy~ALs!D`4q(Lg`Zr4HwGSvM6sn(GAlXHXb zk`D<*h-FXiHar0+Ld-QAZ!s$YP%r8pLpl&qpa ziTK7FZ{#!g^*+IuMsPCohSV}HB2;~Q^H}d`b+;Qx&pTfc>@`rOW{`n&&c&`=77x7s zDt5NE;A->%_zTv_Q5qO@d11SXsNvtNRaE*?X*msJr+wAV4h{?f|!xFjV= zeUem3R0BE3K#S|(p=GaPb7Lb`zPuE7{P8d7T)P2bHiH?lORaIrniu*_m{u?Wtq&B!n!<4u@}3iC21G$?p0UeymQYh3Q`Hf0C;Bo z1}xjKUNTi~|I=Tv^|_Z2PN!hHIT)r3*Kox-#KvCyFyPP0JOAjT1ptw7q#H={`J^7( zD(B>|X~RZooyltXuPt4gFIN%{TVjtAr0m2x3T2pCG92fPKLlgzMq|pkC!qYaBZ0b7 zWGkY0F#u90Qvj(}bvcLlA=pkj=_GMfQIaw-0m-IdkdsGHper z8h~_W(PpF6p%aNVAys7^I}HN$tpsTTz>208EM312TN@kj@4x&N%kO>=Rw{+ClY>d3 zfayY5JyOWe0?U2;_Xj?RFMRO}m^E`I%Hm~3L8_fq*<2Q#oe3;nya+d3cRlXE=UxFf zom&jYghQ6ZM*wxYjIHNaGWvu5R4cz8V7&u9E6TI2yS&0si=u1FD=3U`>t{v zNt&9IF9wmfM|DLE#?nbqWkn2K5|xF=2vn-Qy5Vq8no?8ZcU+uly72vJjc8A+yMFGj zkQqMp(T}*aDfXngTP%**Tbxw0cjz@^Di>40G~=ikjjN|P>D~q@JDwq`w$Y)4t71UZwmb|zel14ATdBoY=6C^LSJIP7pqu&3ss z9W7dt@_OqxZNwdS-hq4Xxfic2c?s<;tt#=Gp!b6NA=^O=E=D4RIjFUcYo?&+xwmNaFXOiC@%L$zN)ND<7a z@s8J0mG!8!Baq|DXAI8AfvLUSC8gc)_*7)wgIh}27&e5Z1ith#KOR9?PVZhPpbQgYi3l3Y?Lg~dLJwP{kF zs+Jss>>=%CeWBSviYwC5(V-fWK2s}PFpydyjG4~(vNTUn-)ryX22A(U*+JUa*d&94 zvlOIgq+HknSyaoDVwQw?lq^r0Ed`UUz}}Y9%-w97lj*qpqe_p4_@sHg4FcHMkZ$GEK_arpO)|?xTsM{Og1N$eA;v za-eOG{Bg%l={@*g89Q}K3X2O>?<${ez=9Bu=j)h>f`URV^TRbj2*F}uIenRWecIIl*aQe_dYRn9qHf>5;DVhB z>j0rJ9WpY;Wf(}a`8G3c?%o}cLsJH7xl+tsj5{d2=s_7cdrl7abxZ%ifE@bdfV92+ zPkH;b*X7j5`z2O9PYP4yw}91Cuo84BD=U@0o?cB`uoswvCbX2Mh3lU^qpfeeN{dUB zuQ!jhi#E)8f(V!|F{zhQx$7IZO6{V{rT*Hh3C$qy!>fPyOL{_q;2= zqL`r-`V_8foK60!o4E@}nWS*xL^cVNvryz}4!?zNnYUSj#HTe1Zq`88WMI>-TKn95z)}-dwW&&wyhC`RSHcsj?SQAGMk^uGY#vWBK7Nn2hn4u41qDpOZt7Pe6u`WB9b^Qb+JlW zb6LHts#z|}RxXztZogHQfA>boUtZ0ZMB*fO{qYs;ZS83w)ikZMK~|0lr!(4*Cj3m6 z3;W1GZ1#^cNT7)5DlhKc+!qr%Of;ZAn_!Z~75p0JY>jf6Ae9}YO{Pg7yl<2D!j2tZ zdXPeC0>=?y^h{0VEb@f}sR0L|GL#q-nrLCBCIQ~#KJk$_Fqpko&0@_4+05TewWv`b z4X0oXr1=E}K2yB|(gX|%fmTJ?4UCLPXJ3yT>^iIincCibOFn7+w~TamYosTSj+fv? zA%do5bTKCId!&$Kb7lZ3-829-kvOCJuR@BXHeN1YySzqLRxXj+`a1d6h95}HO*crv z%4(7Fc|JqF(>v1M?$0MhldAR$jiLZRtQ#Q3(t#YnUaXA;g?Nv%vuoEb4J2Vk8$GLi z&cF&#u@>;VadTjNKsgXFvy|P`wA@6HQqlFhXP;FfvO&g7TuLBi@d*Ot3R0IGI}^R8 z`6qPfn#dV{)YHb2;?ke(Ct@8}i{hZF009psLywzi~XE=p?=x z2C4IJoi`KspbU44GmHt^l>E3X&M%gmms}y&FR7PRwaewo)z{04jkk-`E)=i4NPA4R z=sr+Z{Fo|8X~qYn2y@ep?oShd)K}B}^3qE$>Ci2=-q>=cW(xCfa^Fy_kYckG4%ap9 zI=N<@2vTaJTbf(^rf&jAvl*n;jgZOwbfpxFfhNrrq}rYri)mEPCC3g+z+6CT8kPAh z_?*myF*C`2AD?jvv`HOtcnCtchsKrm1%*2$Awx5(N%*Q#0Sg491M zK1lIT)f^4{(|!U;XGi4N@#Au=t49vK*CD&#dQ$2kT`Z7tv)Jx{!Dh3#K)@HXQY)%JFgM7Pns$l;DT@L~ZT2V;Q}=~g z!h84&T$cqUr^j_!WGaRr48wN6AZD)E%)e#>Rn*L&Oo^v z&CCQBcy@rweeiqu{l>vdlQ?`jXwyt(g)T@Fzor?QOfIwe@Z3{J2xj z4h>0h*?iTA!i-SL^Yl+bwQ7D|zIM(O=EWrsQth(|DTxO zH+}mSS#|YQvf`R+L>4XZ!@j|YQl;|_OjJvUk{^BK(MM$W?lvDJ=gy`1q?|w2oc%>Z zx<09Uw#@7`%ZHH@FfH0!!CfA1L zfR-)N7Vazj{9%wH)To5&?Ci`qYLWXv*sNZ?THDIjtzG8_cw%`9LVZrnPx=gkDM6!% zB{%~kg%93@mz3e;sPy#rN_SV696o$VKIqsh9q+#{`}gga{@z}V(gGBsl*WO}HPM!U zw7`q$kfySt5?M6ALawU2LI(-o)NrFLs$L>>U%yt0%1b4$tjxa^BNj6f%Yekq?v)W3 zk3RO8f{A?z3u*S4Gsu~usD^?Ivsm0cb_Jo82vVX-v=?SW&WF+G*q(50)|WHP=m|7B z!rZEn!WK~4z8Xlwj7(#m{N|~rmC0#z3$r zfGJZkLnevDA!m*U<#|L?!+s?jXPO#mN`w!GpKGysB(N#+w&~ei&qfGXp#k@Y)}si) zdR=Y7!yWr>%`wxuxi4ya*<_oKYMaP+d7n+^x&)E}$0Em+!aexF z11ijXs+^dnPr{Z;3Zy|ti&`{Lkm+a&PtGLI`Vn1kOom5BXvhSmPa^&#m zvTyHRWmp&*8kW(~)2dbZeMNyLt*@?8j-=Y9)l$23nOt+_N~x)?*1%4zs8D1P$9 zmB4vaa0W!b`gdQr1O-nztP7e}N;Cmzc(#u1J(XezLJJ&a({$_+LXG{V8i^nvu?VAN zb!XhN)|@F=D#?H2Hj!4dK;^VR`hVWvtxr6m?QvSnkfup#79`I!!ypATB>UkvWnsdH z$cpG$Omc=uB8u0|lr*qrbHMpNnhMQj01IncGfCM%s$kHz)L*igEHGNgMjF}>CCl>x zUNkYLDCSsLN`{{YLBs}gZ8SU2j%4OKR_LvT)9}g$eWyG-!i0N6Q|AIw?hRIbp3%w@ z-R~P28f!zYa9&A?mI>NHH;`sZx&ca}w$^{@4_xvYJd$2gg^s3`;sr7^I4DQ^`ej~m zv5X9l=#*-h7D&e!NDK1fQXG#yyi!?EStX@aO!QWjuD~1{ONd7SJCS3T^VxtI z(xm1?+5qNo1sD4aczK^Fx^Wg|v(VTJn;&F_5DepD@3@vS@&`V#X;${TySrN>_9&Y3 z0%dvl8q(x2UPkGJE69WoEof`x6$zYo;z8{3ZCBY0#42r4$bT6VWsvQp$e*B9074rwtV%n$Ub<%TN-d9IJcSEV z14+2hBK3Yir;-AxF;VJIPZChF1nD2Ht5rxg>_kZ(CRXscl}irnBlk`}8^MH`38ZP3 zMKH!9{L5w>q%F-dOmz1rcW?A|?%XM*6nS&=v&h_?(u#ipANneTl;utV#2p6gxG@SU z7gs@BN*YLmU=Zdq1^$4PukbcBES9I$-{*AOOwdN@x_L^cVfKO4T~$9w=9|0E$S|q8 zA8*{?5qT}Gs7PznJ)hd$DXr8c{GqVq45ta0^Im-MMJcPCGk0@d%&+Jdq7LyK zNYC$JBohhQ($uJ$bae2f#5Ue_r}u}KU!DW$`K{|$>f3W5%@EC+!4m*Tn;JLEbK9Hc zG(PEuJAdfC{K_kHAf3TQzSJ)j2~s~jF#eh|cc*kDY{}>#LX!g0GlM7Pf2nysEeiU~ QjQ{`u07*qoM6N<$g88?WF8}}l literal 0 HcmV?d00001 diff --git a/test/Charly/06-manager/public/index.php b/test/Charly/06-manager/public/index.php new file mode 100644 index 0000000..019426a --- /dev/null +++ b/test/Charly/06-manager/public/index.php @@ -0,0 +1,26 @@ + + + + + + + Erreur 404 + + +

Erreur 404

+ +

La page demandée n'existe pas

+ + diff --git a/test/Charly/06-manager/view/README.md b/test/Charly/06-manager/view/README.md new file mode 100644 index 0000000..2af35fa --- /dev/null +++ b/test/Charly/06-manager/view/README.md @@ -0,0 +1,2 @@ +# View + diff --git a/test/Charly/06-manager/view/comment/insertComment.view.php b/test/Charly/06-manager/view/comment/insertComment.view.php new file mode 100644 index 0000000..fa6b761 --- /dev/null +++ b/test/Charly/06-manager/view/comment/insertComment.view.php @@ -0,0 +1,25 @@ + + + + + + Exemple du CommentManager::insert() + + +

Exemple du CommentManager::insert()

+
+ $error"; + ?> +

Insertion d'un commentaire

+
+ + + +
+ +
+ + + \ No newline at end of file diff --git a/test/Charly/06-manager/view/comment/selectAllComment.view.php b/test/Charly/06-manager/view/comment/selectAllComment.view.php new file mode 100644 index 0000000..ddf10d5 --- /dev/null +++ b/test/Charly/06-manager/view/comment/selectAllComment.view.php @@ -0,0 +1,33 @@ + + + + + + Exemple du CommentManager::selectAll() + + + +

Exemple du CommentManager::selectAll()

+
+ +

Pas encore de commentaire !

+ +

ID : getCommentId()?> Voir ce commentaire via son id | Mettre à jour | Supprimer

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + \ No newline at end of file diff --git a/test/Charly/06-manager/view/comment/selectOneComment.view.php b/test/Charly/06-manager/view/comment/selectOneComment.view.php new file mode 100644 index 0000000..e7b9ed5 --- /dev/null +++ b/test/Charly/06-manager/view/comment/selectOneComment.view.php @@ -0,0 +1,34 @@ + + + + + + Exemple du CommentManager::selectOneComment() + + +

Exemple du CommentManager::selectOneComment()

+
+ +

Commentaire inexistant

+ + +

ID : getCommentId()?> Voir ce commentaire via son id

+

getCommentText()?>

+

getCommentDateCreate()?>


+ +
+ + + + \ No newline at end of file diff --git a/test/Charly/06-manager/view/comment/updateComment.view.php b/test/Charly/06-manager/view/comment/updateComment.view.php new file mode 100644 index 0000000..17116fa --- /dev/null +++ b/test/Charly/06-manager/view/comment/updateComment.view.php @@ -0,0 +1,35 @@ + + + + + + Exemple du CommentManager::update() + + +

Exemple du CommentManager::update()

+
+ +

Commentaire inexistant

+ + $error"; + ?> +

Modification d'un commentaire

+
+ + + +
+ + +
+ + + \ No newline at end of file diff --git a/test/Charly/06-manager/view/homepage.view.php b/test/Charly/06-manager/view/homepage.view.php new file mode 100644 index 0000000..0b6e57f --- /dev/null +++ b/test/Charly/06-manager/view/homepage.view.php @@ -0,0 +1,30 @@ + + + + + + + Accueil + + +

Accueil

+ +

Bienvenue sur la page d'accueil

+

CRUD des tables de la DB

+

Comment - + Insert Comment

+

Article - + Insert Article

+

Category - + Insert Category

+

File - +Insert File

+

Permission - +Insert Permission

+

Tag - +Insert Tag

+

User - +Insert User

+ + diff --git a/test/Charly/06-manager/view/menu.homepage.view.php b/test/Charly/06-manager/view/menu.homepage.view.php new file mode 100644 index 0000000..c452a7f --- /dev/null +++ b/test/Charly/06-manager/view/menu.homepage.view.php @@ -0,0 +1,17 @@ +