From 2b9d7af69f6886a21a7cd40fd82b20b3df2c20dc Mon Sep 17 00:00:00 2001 From: Emmanuel ROY Date: Tue, 9 Feb 2021 14:16:16 +0100 Subject: [PATCH] update: correction quelques erreurs et mise en place du fil d'ariane --- application/class/Modele.php | 2 +- application/config/ldap-parameters.php.skel | 6 + application/include/modeles/index.model | 3 +- .../include/vues/layout/body.blade.php | 23 +- .../include/vues/layout/body.html.twig | 119 ++ .../include/vues/system/base.html.twig | 72 + .../include/vues/system/system.blade.php | 26 + application/modules/gitlist/.htaccess | 14 + application/modules/gitlist/INSTALL.md | 96 + application/modules/gitlist/LICENSE.txt | 9 + application/modules/gitlist/README.md | 86 + application/modules/gitlist/boot.php | 16 + application/modules/gitlist/config.ini | 58 + application/modules/gitlist/index.php | 30 + .../modules/gitlist/logo/editablefile.ai | 1670 +++++++++++++++++ .../modules/gitlist/logo/horizontal.png | Bin 0 -> 26594 bytes .../modules/gitlist/logo/horizontal.svg | 78 + application/modules/gitlist/logo/logomark.png | Bin 0 -> 33093 bytes application/modules/gitlist/logo/logomark.svg | 25 + application/modules/gitlist/logo/vertical.png | Bin 0 -> 33950 bytes application/modules/gitlist/logo/vertical.svg | 66 + .../modules/gitlist/src/Application.php | 187 ++ application/modules/gitlist/src/Config.php | 77 + .../gitlist/src/Controller/BlobController.php | 95 + .../src/Controller/CommitController.php | 132 ++ .../gitlist/src/Controller/MainController.php | 77 + .../src/Controller/NetworkController.php | 129 ++ .../gitlist/src/Controller/TreeController.php | 128 ++ .../src/Controller/TreeGraphController.php | 72 + .../gitlist/src/Escaper/ArgumentEscaper.php | 15 + .../src/Exception/BlankDataException.php | 7 + .../Exception/EmptyRepositoryException.php | 7 + .../modules/gitlist/src/Git/Client.php | 232 +++ .../modules/gitlist/src/Git/Repository.php | 457 +++++ .../src/Provider/GitServiceProvider.php | 27 + .../RepositoryUtilServiceProvider.php | 21 + .../Provider/RoutingUtilServiceProvider.php | 21 + .../src/Provider/ViewUtilServiceProvider.php | 21 + .../modules/gitlist/src/Util/Repository.php | 235 +++ .../modules/gitlist/src/Util/Routing.php | 164 ++ application/modules/gitlist/src/Util/View.php | 49 + .../gitlist/themes/default/twig/blame.twig | 25 + .../themes/default/twig/branch_menu.twig | 21 + .../themes/default/twig/breadcrumb.twig | 9 + .../gitlist/themes/default/twig/commit.twig | 82 + .../gitlist/themes/default/twig/commits.twig | 13 + .../themes/default/twig/commits_list.twig | 45 + .../gitlist/themes/default/twig/error.twig | 17 + .../gitlist/themes/default/twig/file.twig | 33 + .../gitlist/themes/default/twig/footer.twig | 3 + .../gitlist/themes/default/twig/index.twig | 34 + .../gitlist/themes/default/twig/layout.twig | 30 + .../themes/default/twig/layout_page.twig | 31 + .../gitlist/themes/default/twig/logpatch.twig | 83 + .../gitlist/themes/default/twig/menu.twig | 7 + .../themes/default/twig/navigation.twig | 20 + .../gitlist/themes/default/twig/network.twig | 23 + .../gitlist/themes/default/twig/rss.twig | 18 + .../gitlist/themes/default/twig/search.twig | 42 + .../themes/default/twig/searchcommits.twig | 13 + .../gitlist/themes/default/twig/stats.twig | 48 + .../gitlist/themes/default/twig/tree.twig | 95 + .../themes/default/twig/treegraph.twig | 48 + .../default_without_html/twig/blame.twig | 25 + .../twig/branch_menu.twig | 21 + .../default_without_html/twig/breadcrumb.twig | 9 + .../default_without_html/twig/commit.twig | 82 + .../default_without_html/twig/commits.twig | 13 + .../twig/commits_list.twig | 45 + .../default_without_html/twig/error.twig | 17 + .../default_without_html/twig/file.twig | 33 + .../default_without_html/twig/footer.twig | 3 + .../default_without_html/twig/index.twig | 34 + .../default_without_html/twig/layout.twig | 21 + .../twig/layout_page.twig | 31 + .../default_without_html/twig/logpatch.twig | 83 + .../default_without_html/twig/menu.twig | 7 + .../default_without_html/twig/navigation.twig | 20 + .../default_without_html/twig/network.twig | 23 + .../themes/default_without_html/twig/rss.twig | 18 + .../default_without_html/twig/search.twig | 42 + .../twig/searchcommits.twig | 13 + .../default_without_html/twig/stats.twig | 48 + .../default_without_html/twig/tree.twig | 95 + .../default_without_html/twig/treegraph.twig | 48 + application/objets/Ldap.php | 66 + console/command/Action.php | 25 + console/command/Conduit.php | 25 + console/command/Module.php | 36 +- console/command/Page.php | 67 +- console/skel/action.php.skel | 12 + console/skel/conduit.php.skel | 25 + console/skel/module.blade.php | 2 +- console/skel/module.model | 5 +- console/skel/module.php | 2 +- console/skel/module_symfony.php | 2 +- console/skel/page.blade.php | 2 +- console/skel/page.html.twig | 20 + console/skel/page.model | 7 +- public/.htaccess | 7 +- public/assets/css/custom-320.css | 32 + public/assets/css/custom.css | 30 +- public/humans.txt | 2 +- 103 files changed, 6320 insertions(+), 70 deletions(-) create mode 100644 application/config/ldap-parameters.php.skel create mode 100644 application/include/vues/layout/body.html.twig create mode 100644 application/include/vues/system/base.html.twig create mode 100644 application/modules/gitlist/.htaccess create mode 100644 application/modules/gitlist/INSTALL.md create mode 100644 application/modules/gitlist/LICENSE.txt create mode 100644 application/modules/gitlist/README.md create mode 100644 application/modules/gitlist/boot.php create mode 100644 application/modules/gitlist/config.ini create mode 100644 application/modules/gitlist/index.php create mode 100644 application/modules/gitlist/logo/editablefile.ai create mode 100644 application/modules/gitlist/logo/horizontal.png create mode 100644 application/modules/gitlist/logo/horizontal.svg create mode 100644 application/modules/gitlist/logo/logomark.png create mode 100644 application/modules/gitlist/logo/logomark.svg create mode 100644 application/modules/gitlist/logo/vertical.png create mode 100644 application/modules/gitlist/logo/vertical.svg create mode 100644 application/modules/gitlist/src/Application.php create mode 100644 application/modules/gitlist/src/Config.php create mode 100644 application/modules/gitlist/src/Controller/BlobController.php create mode 100644 application/modules/gitlist/src/Controller/CommitController.php create mode 100644 application/modules/gitlist/src/Controller/MainController.php create mode 100644 application/modules/gitlist/src/Controller/NetworkController.php create mode 100644 application/modules/gitlist/src/Controller/TreeController.php create mode 100644 application/modules/gitlist/src/Controller/TreeGraphController.php create mode 100644 application/modules/gitlist/src/Escaper/ArgumentEscaper.php create mode 100644 application/modules/gitlist/src/Exception/BlankDataException.php create mode 100644 application/modules/gitlist/src/Exception/EmptyRepositoryException.php create mode 100644 application/modules/gitlist/src/Git/Client.php create mode 100644 application/modules/gitlist/src/Git/Repository.php create mode 100644 application/modules/gitlist/src/Provider/GitServiceProvider.php create mode 100644 application/modules/gitlist/src/Provider/RepositoryUtilServiceProvider.php create mode 100644 application/modules/gitlist/src/Provider/RoutingUtilServiceProvider.php create mode 100644 application/modules/gitlist/src/Provider/ViewUtilServiceProvider.php create mode 100644 application/modules/gitlist/src/Util/Repository.php create mode 100644 application/modules/gitlist/src/Util/Routing.php create mode 100644 application/modules/gitlist/src/Util/View.php create mode 100644 application/modules/gitlist/themes/default/twig/blame.twig create mode 100644 application/modules/gitlist/themes/default/twig/branch_menu.twig create mode 100644 application/modules/gitlist/themes/default/twig/breadcrumb.twig create mode 100644 application/modules/gitlist/themes/default/twig/commit.twig create mode 100644 application/modules/gitlist/themes/default/twig/commits.twig create mode 100644 application/modules/gitlist/themes/default/twig/commits_list.twig create mode 100644 application/modules/gitlist/themes/default/twig/error.twig create mode 100644 application/modules/gitlist/themes/default/twig/file.twig create mode 100644 application/modules/gitlist/themes/default/twig/footer.twig create mode 100644 application/modules/gitlist/themes/default/twig/index.twig create mode 100644 application/modules/gitlist/themes/default/twig/layout.twig create mode 100644 application/modules/gitlist/themes/default/twig/layout_page.twig create mode 100644 application/modules/gitlist/themes/default/twig/logpatch.twig create mode 100644 application/modules/gitlist/themes/default/twig/menu.twig create mode 100644 application/modules/gitlist/themes/default/twig/navigation.twig create mode 100644 application/modules/gitlist/themes/default/twig/network.twig create mode 100644 application/modules/gitlist/themes/default/twig/rss.twig create mode 100644 application/modules/gitlist/themes/default/twig/search.twig create mode 100644 application/modules/gitlist/themes/default/twig/searchcommits.twig create mode 100644 application/modules/gitlist/themes/default/twig/stats.twig create mode 100644 application/modules/gitlist/themes/default/twig/tree.twig create mode 100644 application/modules/gitlist/themes/default/twig/treegraph.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/blame.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/branch_menu.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/breadcrumb.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/commit.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/commits.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/commits_list.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/error.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/file.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/footer.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/index.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/layout.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/layout_page.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/logpatch.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/menu.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/navigation.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/network.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/rss.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/search.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/searchcommits.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/stats.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/tree.twig create mode 100644 application/modules/gitlist/themes/default_without_html/twig/treegraph.twig create mode 100644 application/objets/Ldap.php create mode 100644 console/command/Action.php create mode 100644 console/command/Conduit.php create mode 100644 console/skel/action.php.skel create mode 100644 console/skel/conduit.php.skel create mode 100644 console/skel/page.html.twig create mode 100644 public/assets/css/custom-320.css diff --git a/application/class/Modele.php b/application/class/Modele.php index d690124..9597b51 100644 --- a/application/class/Modele.php +++ b/application/class/Modele.php @@ -16,7 +16,7 @@ class Modele //on recherche le pattern des tableau dans la valeur du paramètre // dans le cas ou la déclaration se fait sur une seule ligne if (preg_match("#{.*}#", $matches[2])) { - if (preg_match_all("#(?[0-9a-zA-ZÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ_+\-]*)#", $matches[2], $arrayMatches)) { + if (preg_match_all("#(?[0-9a-zA-ZÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ_+\- ']*)#", $matches[2], $arrayMatches)) { $array = array(); foreach ($arrayMatches['capture'] as $val) { if ($val != '') { diff --git a/application/config/ldap-parameters.php.skel b/application/config/ldap-parameters.php.skel new file mode 100644 index 0000000..53cdac2 --- /dev/null +++ b/application/config/ldap-parameters.php.skel @@ -0,0 +1,6 @@ + -
+
Vous êtes connecté en tant que {{$_SESSION['user_login']}} Se Deconnecter
+ + + @if (isset($ariane)) + + @endif + +
diff --git a/application/include/vues/layout/body.html.twig b/application/include/vues/layout/body.html.twig new file mode 100644 index 0000000..5ccabf1 --- /dev/null +++ b/application/include/vues/layout/body.html.twig @@ -0,0 +1,119 @@ + +{% block body %} + +
+ + + + + + + +
+
+ Vous êtes connecté en tant que {{$_SESSION['user_login']}} + Se Deconnecter +
+
+ +
+
+ + + {% if $_SESSION['alerts'] is defined %} + {% foreach $_SESSION['alerts'] as alert %} + + {% endforeach %} + {% endif %} + + {% block content %}{% endblock %} + +
+
+ + +
+ +
+ + +
+ +{% endblock %}} diff --git a/application/include/vues/system/base.html.twig b/application/include/vues/system/base.html.twig new file mode 100644 index 0000000..3e5642c --- /dev/null +++ b/application/include/vues/system/base.html.twig @@ -0,0 +1,72 @@ + + + + {% block head %} + {{page_title}} + + + + + + + + + + + + + + + + + + + + + + + + + {% block top-css %} + + + {% endblock %} + {% endblock %} + + + +{% block top-javascript %}{% endblock %} + +{% block body %}{% endblock %} + +{% block bottom-javascript %} + + + +/* +SCRIPT JS permettant de ne valider qu'une seule fois un formulaire +ATTENTION tous les formulaires sont affecté +Lors d'une validation bootstrap personnalisé veuillez utilisé +la class do-resubmit sur le formulaire afin de permettre +l'activation supplémentaire du bouton. +*/ + +{% endblock %} + + \ No newline at end of file diff --git a/application/include/vues/system/system.blade.php b/application/include/vues/system/system.blade.php index df91786..04bd7ad 100644 --- a/application/include/vues/system/system.blade.php +++ b/application/include/vues/system/system.blade.php @@ -1,3 +1,4 @@ + @@ -43,6 +44,31 @@ @section('bottom-javascript') + + /* + SCRIPT JS permettant de ne valider qu'une seule fois un formulaire + ATTENTION tous les formulaires sont affecté + Lors d'une validation bootstrap personnalisé veuillez utilisé + la class do-resubmit sur le formulaire afin de permettre + l'activation supplémentaire du bouton. + */ + @show diff --git a/application/modules/gitlist/.htaccess b/application/modules/gitlist/.htaccess new file mode 100644 index 0000000..c3447e4 --- /dev/null +++ b/application/modules/gitlist/.htaccess @@ -0,0 +1,14 @@ + + Options -MultiViews +SymLinksIfOwnerMatch + + RewriteEngine On + #RewriteBase /path/to/gitlist/ + + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^(.*)$ index.php/$1 [L,NC] + + + order allow,deny + deny from all + diff --git a/application/modules/gitlist/INSTALL.md b/application/modules/gitlist/INSTALL.md new file mode 100644 index 0000000..d7f29c4 --- /dev/null +++ b/application/modules/gitlist/INSTALL.md @@ -0,0 +1,96 @@ +# GitList Installation +* Download GitList from [gitlist.org](http://gitlist.org/) and decompress to your `/var/www/gitlist` folder, or anywhere else you want to place GitList. +* Rename the `config.ini-example` file to `config.ini`. +* Open up the `config.ini` and configure your installation. You'll have to provide where your repositories are located and the base GitList URL (in our case, http://localhost/gitlist). +* Create the cache folder and give read/write permissions to your web server user: + +``` +cd /var/www/gitlist +mkdir cache +chmod 777 cache +``` + +That's it, installation complete! + +## Webserver configuration +Apache is the "default" webserver for GitList. You will find the configuration inside the `.htaccess` file. However, nginx and lighttpd are also supported. + +### nginx server.conf + +``` +server { + server_name MYSERVER; + access_log /var/log/nginx/MYSERVER.access.log combined; + error_log /var/log/nginx/MYSERVER.error.log error; + + root /var/www/DIR; + index index.php; + +# auth_basic "Restricted"; +# auth_basic_user_file .htpasswd; + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + location ~* ^/index.php.*$ { + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + + # if you're using php5-fpm via tcp + fastcgi_pass 127.0.0.1:9000; + + # if you're using php5-fpm via socket + #fastcgi_pass unix:/var/run/php5-fpm.sock; + + include /etc/nginx/fastcgi_params; + } + + location / { + try_files $uri @gitlist; + } + + location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { + add_header Vary "Accept-Encoding"; + expires max; + try_files $uri @gitlist; + tcp_nodelay off; + tcp_nopush on; + } + +# location ~* \.(git|svn|patch|htaccess|log|route|plist|inc|json|pl|po|sh|ini|sample|kdev4)$ { +# deny all; +# } + + location @gitlist { + rewrite ^/.*$ /index.php; + } +} +``` + +### lighttpd + +``` +# GitList is located in /var/www/gitlist +server.document-root = "/var/www" + +url.rewrite-once = ( + "^/gitlist/web/.+" => "$0", + "^/gitlist/favicon\.ico$" => "$0", + "^/gitlist(/[^\?]*)(\?.*)?" => "/gitlist/index.php$1$2" +) +``` + +### hiawatha + +``` +UrlToolkit { + ToolkitID = gitlist + RequestURI isfile Return + # If you have example.com/gitlist/ ; Otherwise remove "/gitlist" below + Match ^/gitlist/.* Rewrite /gitlist/index.php + Match ^/gitlist/.*\.ini DenyAccess +} +``` diff --git a/application/modules/gitlist/LICENSE.txt b/application/modules/gitlist/LICENSE.txt new file mode 100644 index 0000000..f8757b3 --- /dev/null +++ b/application/modules/gitlist/LICENSE.txt @@ -0,0 +1,9 @@ +Copyright (c) 2012, Klaus Silveira and contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of GitList nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/application/modules/gitlist/README.md b/application/modules/gitlist/README.md new file mode 100644 index 0000000..359f9e3 --- /dev/null +++ b/application/modules/gitlist/README.md @@ -0,0 +1,86 @@ +

gitlist"

+ +# GitList: an elegant git repository viewer +[![Build Status](https://secure.travis-ci.org/klaussilveira/gitlist.png)](http://travis-ci.org/klaussilveira/gitlist) + +GitList is an elegant and modern web interface for interacting with multiple git repositories. It allows you to browse repositories using your favorite browser, viewing files under different revisions, commit history, diffs. It also generates RSS feeds for each repository, allowing you to stay up-to-date with the latest changes anytime, anywhere. GitList was written in PHP, on top of the [Silex](http://silex.sensiolabs.org/) microframework and powered by the Twig template engine. This means that GitList is easy to install and easy to customize. Also, the GitList gorgeous interface was made possible due to [Bootstrap](http://twitter.github.com/bootstrap/). + +## Features +* Multiple repository support +* Multiple branch support +* Multiple tag support +* Commit history, blame, diff +* RSS feeds +* Syntax highlighting +* Repository statistics + +## Screenshots +![Screenshot 1](https://raw.githubusercontent.com/klaussilveira/gitlist/gh-pages/img/roller/1.png) +![Screenshot 2](https://raw.githubusercontent.com/klaussilveira/gitlist/gh-pages/img/roller/2.png) +![Screenshot 3](https://raw.githubusercontent.com/klaussilveira/gitlist/gh-pages/img/roller/3.png) +![Screenshot 4](https://raw.githubusercontent.com/klaussilveira/gitlist/gh-pages/img/roller/4.png) +![Screenshot 5](https://raw.githubusercontent.com/klaussilveira/gitlist/gh-pages/img/roller/5.png) +![Screenshot 6](https://raw.githubusercontent.com/klaussilveira/gitlist/gh-pages/img/roller/6.png) +![Screenshot 7](https://raw.githubusercontent.com/klaussilveira/gitlist/gh-pages/img/roller/7.png) +![Screenshot 8](https://raw.githubusercontent.com/klaussilveira/gitlist/gh-pages/img/roller/8.png) +![Screenshot 9](https://raw.githubusercontent.com/klaussilveira/gitlist/gh-pages/img/roller/9.png) +![Screenshot 10](https://raw.githubusercontent.com/klaussilveira/gitlist/gh-pages/img/roller/10.png) + +## Requirements +In order to run GitList on your server, you'll need: + +* PHP 5.3+ +* git +* Webserver (Apache, nginx, lighttpd) + +## Installation +* Download GitList from [gitlist.org](http://gitlist.org/) and decompress to your `/var/www/gitlist` folder, or anywhere else you want to place GitList. +* Do not download a branch or tag from GitHub, unless you want to use the development version. The version available for download at the website already has all dependencies bundled, so you don't have to use composer or any other tool +* Rename the `config.ini-example` file to `config.ini`. +* Open up the `config.ini` and configure your installation. You'll have to provide where your repositories are located. +* In case GitList isn't accessed through the root of the website, open .htaccess and edit RewriteBase (for example, /gitlist/ if GitList is accessed through http://localhost/gitlist/). +* Create the cache folder and give read/write permissions to your web server user: + +``` +cd /var/www/gitlist +mkdir cache +chmod 777 cache +``` + +That's it, installation complete! If you're having problems, check the [Troubleshooting](https://github.com/klaussilveira/gitlist/wiki/Troubleshooting) page. + + +## Authors and contributors +* [Klaus Silveira](http://www.klaussilveira.com) (Creator, developer) + +## License +[New BSD license](http://www.opensource.org/licenses/bsd-license.php) + +## Development +GitList uses [Composer](http://getcomposer.org/) to manage dependencies and [Ant](http://ant.apache.org/) to build the project. + +Once you have all the dependencies set, you can clone the repository and run Ant: + +``` +git clone https://github.com/klaussilveira/gitlist.git +ant +``` + +If you just want to get the project dependencies, instead of building everything: + +``` +git clone https://github.com/klaussilveira/gitlist.git +curl -s http://getcomposer.org/installer | php +php composer.phar install +``` + +If you have Composer in your path, things get easier. But you know the drill. + +## Contributing +If you are a developer, we need your help. GitList is a young project and we have lots of stuff to do. Some developers are contributing with new features, others with bug fixes. But you can also dedicate yourself to refactoring the current codebase and improving what we already have. This is very important, we want GitList to be a state-of-the-art application, and we need your help for that. + +* Stay tuned to possible bugs, suboptimal code, duplicated code, overcomplicated expressions and unused code +* Improve the test coverage by creating unit and functional tests + +## Further information +If you want to know more about customizing GitList, check the [Customization](https://github.com/klaussilveira/gitlist/wiki/Customizing) page on the wiki. Also, if you're having problems with GitList, check the [Troubleshooting](https://github.com/klaussilveira/gitlist/wiki/Troubleshooting) page. Don't forget to report issues and suggest new features! :) diff --git a/application/modules/gitlist/boot.php b/application/modules/gitlist/boot.php new file mode 100644 index 0000000..ed65bfa --- /dev/null +++ b/application/modules/gitlist/boot.php @@ -0,0 +1,16 @@ +mount('', new GitList\Controller\MainController()); +$app->mount('', new GitList\Controller\BlobController()); +$app->mount('', new GitList\Controller\CommitController()); +$app->mount('', new GitList\Controller\TreeController()); +$app->mount('', new GitList\Controller\NetworkController()); +$app->mount('', new GitList\Controller\TreeGraphController()); + +return $app; diff --git a/application/modules/gitlist/config.ini b/application/modules/gitlist/config.ini new file mode 100644 index 0000000..5575ba1 --- /dev/null +++ b/application/modules/gitlist/config.ini @@ -0,0 +1,58 @@ +[git] +client = '/usr/bin/git' ; Your git executable path +default_branch = 'master' ; Default branch when HEAD is detached +repositories[] = '/home/git/repositories/' ; Path to your repositories + ; If you wish to add more repositories, just add a new line + +; WINDOWS USERS +;client = '"C:\Program Files (x86)\Git\bin\git.exe"' ; Your git executable path +;repositories[] = 'C:\Path\to\Repos\' ; Path to your repositories + +; You can hide repositories from GitList, just copy this for each repository you want to hide or add a regex (including delimiters), eg. hidden[] = '/(.+)\.git/' +; hidden[] = '/home/git/repositories/BetaTest' + +[app] +debug = false +cache = true +theme = "default" +title = "" + +[clone_button] +; ssh remote +show_ssh_remote = false ; display remote URL for SSH +ssh_host = '' ; host to use for cloning via HTTP (default: none => uses gitlist web host) +ssh_url_subdir = '' ; if cloning via SSH is triggered using special dir (e.g. ssh://example.com/git/repo.git) + ; has to end with trailing slash +ssh_port = '' ; port to use for cloning via SSH (default: 22 => standard ssh port) +ssh_user = 'git' ; user to use for cloning via SSH +ssh_user_dynamic = false ; when enabled, ssh_user is set to $_SERVER['PHP_AUTH_USER'] + +; http remote +show_http_remote = false ; display remote URL for HTTP +http_host = '' ; host to use for cloning via HTTP (default: none => uses gitlist web host) +use_https = true ; generate URL with https:// +http_url_subdir = 'git/' ; if cloning via HTTP is triggered using virtual dir (e.g. https://example.com/git/repo.git) + ; has to end with trailing slash +http_user = '' ; user to use for cloning via HTTP (default: none) +http_user_dynamic = false ; when enabled, http_user is set to $_SERVER['PHP_AUTH_USER'] + +; If you need to specify custom filetypes for certain extensions, do this here +[filetypes] +; extension = type +; dist = xml + +; If you need to set file types as binary or not, do this here +[binary_filetypes] +; extension = true +; svh = false +; map = true + +; set the timezone +[date] +; timezone = UTC +; format = 'd/m/Y H:i:s' + +; custom avatar service +[avatar] +; url = '//gravatar.com/avatar/' +; query[] = 'd=identicon' diff --git a/application/modules/gitlist/index.php b/application/modules/gitlist/index.php new file mode 100644 index 0000000..703fd0c --- /dev/null +++ b/application/modules/gitlist/index.php @@ -0,0 +1,30 @@ +get('date', 'timezone')) { + date_default_timezone_set($config->get('date', 'timezone')); +} + +$app = require 'boot.php'; +$app->run(); + diff --git a/application/modules/gitlist/logo/editablefile.ai b/application/modules/gitlist/logo/editablefile.ai new file mode 100644 index 0000000..717534d --- /dev/null +++ b/application/modules/gitlist/logo/editablefile.ai @@ -0,0 +1,1670 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[6 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + gitlist + + + + + 2018-06-12T22:12:12+03:00 + 2018-06-12T22:12:12+03:00 + 2018-06-12T22:12:12+04:00 + Adobe Illustrator CS6 (Windows) + + + + 192 + 256 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q0zKqlmIVVFWY7AAd zikC2CfmlL5hn8uxXWhzB9LI9W8e3J9Ux7FHVlO8fdqfqrmu15mYXD6ev47noOwo4Y5zHMP3nKN8 r7vf3frYZ+X/AOZNzpFwLHV5Xn0uZtpXJd4GP7QrUlPEfSPfB0etMDUvp+53fa/Ysc0ePGKyD7f2 vbYpYpoklicSRSAMjqQVZSKggjqDm+BvcPCSiYmjsQuwodirsVQ8mo6fE5jluokkHVGdQfuJyJnE dWyOGZFgH5IgEEAg1B3BGSa3Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FWmZVUsxCqoqzHYADuc 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 + + + + + + uuid:8324c252-80fa-494e-aabd-dcba4f8313de + xmp.did:A3FAB7ED726EE81199C0AB5D7B9ED9E4 + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + xmp.iid:A2FAB7ED726EE81199C0AB5D7B9ED9E4 + xmp.did:A2FAB7ED726EE81199C0AB5D7B9ED9E4 + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + + + + saved + xmp.iid:9EFAB7ED726EE81199C0AB5D7B9ED9E4 + 2018-06-12T22:01:06+03:00 + Adobe Illustrator CS6 (Windows) + / + + + saved + xmp.iid:A3FAB7ED726EE81199C0AB5D7B9ED9E4 + 2018-06-12T22:12:10+03:00 + Adobe Illustrator CS6 (Windows) + / + + + + + + Print + Document + + + False + False + 1 + + 1344.000000 + 1225.566406 + Points + + + + + PRIMETIME-Regular + PRIMETIME + Regular + TrueType + Version 1.00 2014 + False + PRIMETIME © PERSONAL USE ONLY.ttf + + + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + White + RGB + PROCESS + 255 + 255 + 255 + + + Black + RGB + PROCESS + 35 + 31 + 32 + + + CMYK Red + RGB + PROCESS + 237 + 28 + 36 + + + CMYK Yellow + RGB + PROCESS + 255 + 242 + 0 + + + CMYK Green + RGB + PROCESS + 0 + 166 + 81 + + + CMYK Cyan + RGB + PROCESS + 0 + 174 + 239 + + + CMYK Blue + RGB + PROCESS + 46 + 49 + 146 + + + CMYK Magenta + RGB + PROCESS + 236 + 0 + 140 + + + C=15 M=100 Y=90 K=10 + RGB + PROCESS + 190 + 30 + 45 + + + C=0 M=90 Y=85 K=0 + RGB + PROCESS + 239 + 65 + 54 + + + C=0 M=80 Y=95 K=0 + RGB + PROCESS + 241 + 90 + 41 + + + C=0 M=50 Y=100 K=0 + RGB + PROCESS + 247 + 148 + 30 + + + C=0 M=35 Y=85 K=0 + RGB + PROCESS + 251 + 176 + 64 + + + C=5 M=0 Y=90 K=0 + RGB + PROCESS + 249 + 237 + 50 + + + C=20 M=0 Y=100 K=0 + RGB + PROCESS + 215 + 223 + 35 + + + C=50 M=0 Y=100 K=0 + RGB + PROCESS + 141 + 198 + 63 + + + C=75 M=0 Y=100 K=0 + RGB + PROCESS + 57 + 181 + 74 + + + C=85 M=10 Y=100 K=10 + RGB + PROCESS + 0 + 148 + 68 + + + C=90 M=30 Y=95 K=30 + RGB + PROCESS + 0 + 104 + 56 + + + C=75 M=0 Y=75 K=0 + RGB + PROCESS + 43 + 182 + 115 + + + C=80 M=10 Y=45 K=0 + RGB + PROCESS + 0 + 167 + 157 + + + C=70 M=15 Y=0 K=0 + RGB + PROCESS + 39 + 170 + 225 + + + C=85 M=50 Y=0 K=0 + RGB + PROCESS + 28 + 117 + 188 + + + C=100 M=95 Y=5 K=0 + RGB + PROCESS + 43 + 57 + 144 + + + C=100 M=100 Y=25 K=25 + RGB + PROCESS + 38 + 34 + 98 + + + C=75 M=100 Y=0 K=0 + RGB + PROCESS + 102 + 45 + 145 + + + C=50 M=100 Y=0 K=0 + RGB + PROCESS + 146 + 39 + 143 + + + C=35 M=100 Y=35 K=10 + RGB + PROCESS + 158 + 31 + 99 + + + C=10 M=100 Y=50 K=0 + RGB + PROCESS + 218 + 28 + 92 + + + C=0 M=95 Y=20 K=0 + RGB + PROCESS + 238 + 42 + 123 + + + C=25 M=25 Y=40 K=0 + RGB + PROCESS + 194 + 181 + 155 + + + C=40 M=45 Y=50 K=5 + RGB + PROCESS + 155 + 133 + 121 + + + C=50 M=50 Y=60 K=25 + RGB + PROCESS + 114 + 102 + 88 + + + C=55 M=60 Y=65 K=40 + RGB + PROCESS + 89 + 74 + 66 + + + C=25 M=40 Y=65 K=0 + RGB + PROCESS + 196 + 154 + 108 + + + C=30 M=50 Y=75 K=10 + RGB + PROCESS + 169 + 124 + 80 + + + C=35 M=60 Y=80 K=25 + RGB + PROCESS + 139 + 94 + 60 + + + C=40 M=65 Y=90 K=35 + RGB + PROCESS + 117 + 76 + 41 + + + C=40 M=70 Y=100 K=50 + RGB + PROCESS + 96 + 57 + 19 + + + C=50 M=70 Y=80 K=70 + RGB + PROCESS + 60 + 36 + 21 + + + + + + Grays + 1 + + + + C=0 M=0 Y=0 K=100 + RGB + PROCESS + 35 + 31 + 32 + + + C=0 M=0 Y=0 K=90 + RGB + PROCESS + 65 + 64 + 66 + + + C=0 M=0 Y=0 K=80 + RGB + PROCESS + 88 + 89 + 91 + + + C=0 M=0 Y=0 K=70 + RGB + PROCESS + 109 + 110 + 113 + + + C=0 M=0 Y=0 K=60 + RGB + PROCESS + 128 + 130 + 133 + + + C=0 M=0 Y=0 K=50 + RGB + PROCESS + 147 + 149 + 152 + + + C=0 M=0 Y=0 K=40 + RGB + PROCESS + 167 + 169 + 172 + + + C=0 M=0 Y=0 K=30 + RGB + PROCESS + 188 + 190 + 192 + + + C=0 M=0 Y=0 K=20 + RGB + PROCESS + 209 + 211 + 212 + + + C=0 M=0 Y=0 K=10 + RGB + PROCESS + 230 + 231 + 232 + + + C=0 M=0 Y=0 K=5 + RGB + PROCESS + 241 + 242 + 242 + + + + + + Brights + 1 + + + + C=0 M=100 Y=100 K=0 + RGB + PROCESS + 237 + 28 + 36 + + + C=0 M=75 Y=100 K=0 + RGB + PROCESS + 242 + 101 + 34 + + + C=0 M=10 Y=95 K=0 + RGB + PROCESS + 255 + 222 + 23 + + + C=85 M=10 Y=100 K=0 + RGB + PROCESS + 0 + 161 + 75 + + + C=100 M=90 Y=0 K=0 + RGB + PROCESS + 33 + 64 + 154 + + + C=60 M=90 Y=0 K=0 + RGB + PROCESS + 127 + 63 + 152 + + + + + + + + + Adobe PDF library 10.01 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 8 0 obj <>/Resources<>/ExtGState<>/Font<>/ProcSet[/PDF/Text]/Properties<>>>/Thumb 13 0 R/TrimBox[0.0 0.0 1344.0 1225.57]/Type/Page>> endobj 9 0 obj <>stream +H͎%9)[BPb`Q4K|'켷g@%ݬHG{| ?K +B.>Fȵp=O_אo͋7?>~ ,C%zئCK<k~-h*-҂VVR Qǒ/H饶ߟMbR>ƞ(G`& B}k8Y -^:nnfRDH-*X$h_ +Ͽ<ҙw /CW!R [Xhx/\[Cc]`|n^]SjkTff7f2 +}y^3&ߑtX\g9y2Lcc]d'$[ ??A%1dƦִQU!9.jt~*Ƅ#6̮g*cJ1zXK?w.'%Z{~lLH V-Uo R H#XןƸ4o :6#}cy%΂'C"]x[?ؿ}>"LAw+)*zU/U4_U>0BG%[0H*q4Ѫ")Q*Hy]@/a@Ҕ6?t[ +n?nϖ{쯦o`' [ vM5r @fD +m|tX1Jȵ~~4ݔпi{5NX @l˘ :3v|O!Yz7*VȢ@R 2M3VxH(nIL^m,^'/Q90~k S 6zJdɧH'0IO +51T}&}4Pbq'L ۨx:F,io.Ȟ%z]]/6Dzs X,Xnl)7UULDTЏ89oxͧ1rBSs@ݲqAL"dzK eV@fCk(*& .1[i`,&cwX0IҜ0ɩk NoGD:/pR_+$\hMQ9.w157HP-t/{MF5Lܲ"Z08>GN%-uZmTY^$բ9hT1).zyJTQ>/|B Ve˭ӧV]mHV Q%.t*W{U05x&Ib]'Sp4vlЈ)!/0A";߀v4ol8" ;8/D%Ư xtE(L|ydVGG^%Z= `.P$Hr-jJv2<=(ٷ%lj ;H ϵgaD@ +@1| U-S v2ذjN&,(:0;M>LNc4, .#L<]KJL.~[[sr%b*Ј:pŪ 4 65ڮM⼵auj!v }6 +&Ů&ɍAHG>U]9%#xo1Mb}q5}\=vTgbƯ4Q)I$!՛<__9VsS!|D/c xzg̀B&ڽhlRܻ:X-v5!\˗DZOJ +.SWSP]4ݦЅ_Di+LlWFUWtOȾ+09=.ݿh9~TVY$I(ׯ(sƨxGeY!Ԟ5Hbw s#{A2T߬Ȉ8`Nv~erǷlxdjBR, E/e"CjnCÝ~7tNqjƳ_h؜f |GAqk:!F,|B}:uL\ +Bu?({_2@ŧ+j]XN;1JV3Ve{Gz@noGqk~Ϸ>? WbMKyTS5;GoqP)~N`-|Dq$M|C2RJV/kl_ ܷ^#OܗwѰYE + V[Oe*Hʡ[$-̗f?o;gm}ظߔr麝)D:CGwXy3¹|X[9يI/ũ1EFp6DhbC'.BI%,D=_b yKC >Y~:򑲷Sr*cڊpOS{J0,]& ukZ}r =(x [=_ rht4\BdvRCQex\b*;II,'I&HCTIծCU95J4Q޲vûv?o:}*X;5m31&-I9䲷2dkۜV5E$$hh`Կ\I\nf}}Ƕo!e1ܰXt: EfUM Uͱ<i8tҞ 2cKmAŌ-frzG'ŏ?/hFFV{$7k#.eH09u so!)I@RB_572+xx[#erXeN<$X!õeg[."ht}˔X:iM&d~ގ]Sj&zK];"Ut|W$SEl1=X({ sd)5}|r,Ԯ3j=*y8GzgZ_0ףKna#l%=g5&I&&?4:?Op%WF D+$`Iی9p jA+.؜rVnIz  a[YS gali{CR& +,a.;-YFc1\K6wwF(-jǛ0H X.'K9aB|ޔ VcU^"U,&hA$S$IcqoTa|$Ȟ߅D_.x_9}뷯]~GvIwy%O ͓3%nRjO^_~/ǧoG??xG" +endstream endobj 13 0 obj <>stream +8;Z]"@?Q6c%#)Cp"`bH/E=/kT![35ih(=`4lqF!ct48d>AVh +8=@jgh+.4Z:63(/:+QhGFF/pEX63uUZ0sYKh4Q-O%i]pm`4k5ap7"C#P-%R@e>aa\ +@OlnhKJ^@(ef,U2AM(9Y>t?g\M6_*hBgh)nN%\eA;+_e6_#9ta*+'V>q2TYsm8FcC +b%q6m^RLhikaEL-Nhc:fREQ(I7P^Cr$H[,XG5Y4=b\0Wh0H5pXnU/`!X3I=q8=.it +U[(KN$C[L!i[Ergf55e]9hRA!T>YNUelMn&.\]tH8.$ghWa&IMWIUqu$UiE@b6f)J +Jf0Dj;H94JoVZW>eOXhK)eA3TL81\,fU$B!5OI1ScN(KEP2l~> +endstream endobj 14 0 obj [/Indexed/DeviceRGB 255 15 0 R] endobj 15 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 6 0 obj <> endobj 16 0 obj [/View/Design] endobj 17 0 obj <>>> endobj 5 0 obj <> endobj 18 0 obj <> endobj 12 0 obj <> endobj 11 0 obj [/ICCBased 19 0 R] endobj 19 0 obj <>stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  + 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km +endstream endobj 10 0 obj <> endobj 20 0 obj <> endobj 21 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 16.0 +%%AI8_CreatorVersion: 16.0.0 +%%For: (avpc) () +%%Title: (vertical.svg) +%%CreationDate: 6/12/2018 10:12 PM +%%Canvassize: 16383 +%%BoundingBox: 100 -1143 834 -156 +%%HiResBoundingBox: 100.75 -1142.3457 833.9385 -156.7061 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 12.0 +%AI12_BuildNumber: 682 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Registration]) +%AI3_Cropmarks: -242 -1167 1102 58.5664 +%AI3_TemplateBox: 421.5 -298.5 421.5 -298.5 +%AI3_TileBox: 21.1602 -834.7764 838.8398 -273.6567 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 2 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI9_OpenToView: -394 -11 0.5 1141 603 26 0 0 82 116 0 0 0 1 1 0 1 1 0 1 +%AI5_OpenViewLayers: 7 +%%PageOrigin:115 -694 +%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 22 0 obj <>stream +%%BoundingBox: 100 -1143 834 -156 +%%HiResBoundingBox: 100.75 -1142.3457 833.9385 -156.7061 +%AI7_Thumbnail: 96 128 8 +%%BeginData: 9197 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45FD0BFFBCC2CAFD5CFF99B592BBCAFD5BFFC2B5BB93BBCAFD58FFC9 +%FFFFC292BB92BBCAFD0FFFCACAA7CACAFD15FFCAFD2CFFBBBBCAFFFFC2B4 +%BBB5BBCAFD0DFFC2BCB5BBB5BBC2FD14FFC3BBBCBCFD28FF99BB93BBC9FF +%FFC99ABB93BBCAFD0AFFCA93B593BB93BB93B593CAFD12FF99B592BBCAFD +%0FFFCACFCACFCFFD12FFBBBB93BBB5BBCAFFFFFFBCBBB5BBCAFD09FFBBBB +%93BBB5BB92BBB5B5BBFFFFC9BBBCC2FFC2BCBCBCBBC2BCBCBBC2CAC293BB +%BBFD07FFCABCBBBCCAFFFFFFBCBB93BBB5BCC2FFC3BCBBC2BCBCBBC2BCBC +%CAFD04FF99B593BB93BB92BCFFFFFFC392BB92BBA8FD07FF99B593B593C3 +%C3C393BBA0FFFFFF9AB592BCFFBC92BB92B592BB92B592CF99B592BBCAFD +%06FFCF93B592CAFFFF93B593B592BB92B4A1C392B592BB92B592B592CAFF +%FFFFFD04BBB5BBBCC9BBCAFFCFC3C2B5BBB5BBCAFD05FFCABBB5BBBBFD05 +%FFCAFD04FFC3B5BBBCFFBCBBB5BBB5BBBBBBB5BCCAC2B5BBBBFD07FFCABB +%B5BBCAFFC2BBB5BCBCC2BBB5BCFFC3BBB5BBBBBBB5BBB5BBCAFFFF99B593 +%BB93B59AFFFFFF93BBBCFFFFBC92BB92BBCAFD04FFC392BB92C9FD08FFCA +%FFC2B592BCFFFFC9CFC2B592BCCACACAFF99B593BBFD08FF93BB93CAFFBC +%92BBBCFFFFFFC3CAFFFFCACAA0BB93BBC9CACAFFFFFD04BB93BBB4C3FFFF +%FFC292BBC9FFFFC2B5BB93BBCAFFFFFFC2BB93BBCAFFFFFFBBBB99BCBBBC +%FFC3B5BBBBFD04FFCAB4BBBBFD04FFC2B5BB99FD07FFCABBB5BBCAFFBCBB +%93BBBBC3C3FD06FFCA92BBBBFD04FF9AB593BB93B599C299FFFFCAA0BB92 +%BBC3FFCABC92BB92BCFFFFFFC392BB93CFFFFFA8BB92BB92BB93FFA0B592 +%BCCAFFFFFFA1B592BCCAFFFFFF99BB93BBCAFD06FFCA93BB93CAFFCA92B5 +%92BB92B592C3FD04FFC3B592BBCAFFFFFFC2B5BBBBBBBCFFFFCABBC2C3FF +%CABBB5BBC3FFFFC2B4BBBBFFFFFFC3BBB5BBC3FFFFFFB5BBB5BBB5BCFFC3 +%B5BBBBFD04FFC9B5BBBBFD04FFC2B5BBBBFD07FFCABCB5BBCAFFFFCABBBB +%B5BBB5BBB4C3FFFFFFCAB5BBBBFD04FFCABB92BB92C9FFFFFFBB92BBCAFF +%CABB92B5A1FFFFBC92CAFFFFFFCA93BB92BBCAFFFFCAC2BB93BB93FFA0BB +%93BCFD04FFA1B593BCFD04FF99BB93BBCFFD06FFCF93BB93CAFD04FFCACA +%BCBB93BB99FFFFFFC3B592BBFD05FFCABB93BBC2FFFFCFBCBB92BBCAFFCA +%BBB5BBC3FFCACAFD05FFC2B5BB93BBC3CAC3BCB5BB93BCFFC392BBBCFD04 +%FFC992BBBCFD04FFBC93BBBBC2BCC2BCC2BCC3CABB93BBCAFFFFC3C3FFFF +%FFC2BB93BCFFFFFFCAB5BB99FD06FFCABB92BB9AC3A1FFC3B592BBCAFFA8 +%BB92B5A1FD07FFA8BB92BB92B592B592BB93BB93FFA0B592BCFD04FFC3B5 +%92BCFD04FF99B593BB92B592BB92B593CA93B592CAFFCA92B593BB99BB93 +%B599FFFFFFA1BB93BBCAFD06FFCABBB5BBB4C2FFFFC3BBB5BBCAFFCABBB4 +%CAFD08FFCABCB4BBB5BBB5BBB5BBB4BBFFC3B4BBBBFD04FFC992BBBBFD04 +%FFBCB4BBB5BBB5BBB5BBB4BCCABBB4BBCAFFBCBBB5BBB5BBB5BBBBFD04FF +%CAB4BBB5FD08FFCABB93BB92BCFFFFA1BB92BBCAFFCACAFD0BFFC399BB93 +%BB99C3BCC29AFFC3BC9AC3FD04FFC3BC9AC3FD04FFC2BC9AC2BCC29AC2BC +%C29AFFBCC29ACFFFFFA1C299BB93BCBCFD05FFC9C2BCC2CAFD08FFCABBB5 +%BB92C2FFFFC3BBB5BBCAFD0FFFCAFD44FFA8BB92BB92BCFFFFA1B592CAFD +%55FFCABBB5BBB5C2FFFFC3CAFD57FFCABB92BB92BCCAFD5AFFCABB92BBB5 +%CAFD5BFFCABC93CAFDFCFFFDFCFFFDFCFFFD2DFFCFFD5EFFC3B5C2FD5CFF +%C392BB92BCCAFD59FFC992BBB5BB92BCFD59FFCAC292BB93BB92BCCAFD59 +%FFC3B5BBB5BBB5BCFD54FFC292CAFFFFFFC292BB93BB92BCCAFD51FFC3B5 +%BB93CAFFFFFFC2B4BB93BBB5BCCFFD4FFFC292BB93B592CAFFFFCACAA1BB +%92BB92BCCAFD4DFFC3B4BBBBBBB5BBB5CAFD04FFC9BBB5BBB4C2FD4CFFC3 +%92BB93BB93BB93BB93FD05FF93BB93BB92BCCAFD49FFC392BBB5BB93BBB5 +%BB92BBCAFD04FFBB93BBB5BB92BCFD48FFC292BB93BB93BB92BB9AC393C2 +%FFFFFFC3C3BC92BB93BB92BCCAFD45FFC3B5BBB5BBBBBBB5BBC3FFFFFFBC +%BCC2C2CAFFCABCB5BBB5BBB5BCFD44FFC292BB93BB93BB93BB99FD04FFCA +%92B592C9FFFFCABC92BB93BB92BCCAFD41FFC3B5BB93BBB5BB93BBB5BCFD +%04FFCABBB5BB92C9FFFFCABCB5BB93BBB5BCCAFD3FFFC392BB93BB93BB93 +%B593BC92CAFFFFFFC39ABB93BB92C3FFFFA8BB92BB93BB92BCFD3FFFFD04 +%BBB5BBBBBBC3FFFFCAB5C9C3C3CAFFC3BBB5BBB5C3FFFFCABCB5BBBBBBB5 +%FD3FFFC992BB93BB93BBBCFD04FFC392B593FFFFFFC3B593BB92C3FFFFCA +%BB92BB92C3FD40FFC992BBBBBB92C9FD04FFC3B593BBBBFFFFFFC3BB93BB +%B5C3FFFFCABC92C3FD42FFC992BB93B599FD04FFC293B593B593CFFFFFA0 +%B592BB92C3FFFFCAC3FD44FFCAB5BBB5BBC2FFCAC3CAFFFD05BBFFFFFFC3 +%BBB5BBB4C9FD48FFC992BB93BB93B59AFFFFFF93BB93B593FFFFFFA0BB93 +%BB92CAFD48FFCAB5BB93BBB5BBC3FFFFFF99BBBBBB99FFFFFFC3BBB4C3FD +%4AFFC992BB93BB93B5A1FFFFCF93B593B593FFFFFFA0C2FD4CFFCAB5BBBB +%BBB5BBC9FFFFFFBBBBB5BBBBFD51FFC992BB93BB92BBC3FFFFFF99B593BB +%93FD51FFC992BBBBBB93BBC9FFFFFFBBBB92C3FD52FFC992BB93BB92B5C3 +%FFFFFF93C2FD54FFCAB5BBB5BBB5BBC3FD59FFC992BB93BB93B5A1FD59FF +%CAB5BB93BBB4C3FD5AFFC992B592C3FD5CFFCABBC3FDFCFFFD6AFFCAC9C2 +%C3C9FD11FFC9CAC9FD46FF9ABB92B592B599CAFD0FFFBB92BBCAFD44FFBC +%B593BBB5BB93BBB5FFFFC9C2C3FFC9C2C3C2C3C2C3C2FFBBBB93FD06FFCA +%BCC3CAFFFFCABCBCBBC2C3FFC3C3C2C3C2C3C2C3CAFD28FFA1B593B59ACA +%C3BB99CAFFFF93B593FF93B492B592B592B5A1BC92BBA8FD05FFA0B492C9 +%FFC392B592B592B5C3C28CB592B592B592C3FD28FFC2B5BBC3FD08FFC2B5 +%BCFFC3BBBCB5BBBBBCBCCFBBBBB5FD06FFC9B4BBC9FFBBBBBBCAC3BCBCFF +%C3BCBBBBB5BCBCBCCAFD28FF93BB93FFFFFFC3C3A1C3C3FF99BB93FFFFFF +%CABB92C3FFFFCABB93BBCAFD05FFC3B592CACABB92BCC3CFCAFD05FF93B5 +%9AFD2AFFCABB93BCFFFFFFBBB4B592BBFFC292BCFFFFFFCAB5BBC2FFFFFF +%99BBBBFD06FFC9B4BBC3FFBCB593BBB5BCC3FFFFFFCABBB5C2FD2BFF93B5 +%92CAFFFF93BB93BB93FF99B593FFFFFFA7BB92C3FFFFCABB92BBCAFD05FF +%A1B592C9FFFF9ABB92B592B5A0FFFFCA93B59AFD2BFFC2B4BBBCFFFFCFBC +%BBB5BCFFC2B5BCFFFFFFCFB5BBC2FFFFFFBBBBBBFD06FFC9B5BBC3FD05FF +%C3BBB5BCFFFFCABCB5C2FD2BFFCAB592BB93BC99BB93BB93FF99B593FFFF +%FFC9BB92C3FFFFFFBB93BB93BB93BB93C2A1B592C9FFCA93C3C9CA93B599 +%FFFFCF93BBBCFD2CFFC3BB92BBB5BB93BBB5BBCFBCB4BBFFFFFFCA92B5C2 +%FFFFFFB5BB93BBB5BB92B5BCC392BBC9FF93B5B4BB92BBB4C9FFFFCABB92 +%C2FD2DFFCAC293BB93BC9AC29AFFA0C29AFFFFFFCAC299C9FFFFCAC29AC2 +%9AC29AC299C3C3BC99CAFFC399BB93BB99C9FD04FF9ABCA0FD30FFCAFDFC +%FFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFD74FF7D7D +%527D7DA8FD1BFFA87DA87DA8A8FD37FF7DFD07F8277DFD19FF7DFD04F87D +%FD35FF7D27FD0AF827FD07FFA8FFFFFFA8FFA8FFA8FFA8FFA8FFA8FFFF7D +%FD04F852FD0DFFA8FD07FFA8FFA8FD07FFA8FFA8FFA8FFA8FFA8FFA8FD0A +%FFA8FD0DF852FFFFFF5227272752FF27F8F827F827F827F827F8F827FF7D +%FD04F87DFD0AFFFD0427A8FD04FFA85227F827F85252FFFFFF52F8F827F8 +%27F827F827F82727FD08FFA8FD06F8525252FD04F87DFD04FF52F8F8F852 +%FF27FD0BF827FF7DFD04F87DFD09FFA8FD04F8A8FFFFFF52FD09F852FF52 +%FD0BF827FD08FF52FD04F827FD05FF5252A8FD05FF52F8F8F852FF27FD0B +%F827FF7DFD04F87DFD09FFA8FD04F8A8FFFF7DFD0AF852FF27FD0CF8FD08 +%FFFD05F8FD0EFF52F8F8F852FF52FD0BF827FF7DFD04F852FD09FFA8FD04 +%F8A8FFFFFD0BF8FFFF52FD0BF827FD07FF7DFD04F87DFD0EFF52F8F8F852 +%FD05FF52F8F8F827FD05FF7DFD04F87DFD09FFA8FD04F8A8FFA8FD04F8A8 +%FFFFA87DF87DFD06FF52F8F8F827FD0BFF7DFD04F8A8FD04FF7D527D527D +%525252FFFF52F8F8F852FD05FF52F8F8F852FD05FF7DFD04F852FD09FFA8 +%FD04F8A8FFFFFD04F852A8A8FD0AFF52F8F8F852FD0BFF52FD04F8FD05FF +%27FD07F8FFFF52F8F8F852FD05FF52F8F8F827FD05FF7DFD04F87DFD0AFF +%FD04F8A8FFFF27FD05F827277DA8FD07FF52F8F8F852FD0BFF7DFD04F87D +%FD04FF27FD07F8FFFF52F8F8F852FD05FF52F8F8F852FD05FF7DFD04F852 +%FD09FFA8FD04F8A8FFFFA827FD08F827FD06FF52F8F8F852FD0BFFA8FD04 +%F852FD04FF27FD06F827FFFF52F8F8F852FD05FF52F8F8F827FD05FF7DFD +%04F87DFD0AFFF8F8F827A8FD04FF7D27FD07F827FD05FF52F8F8F852FD0C +%FF27FD04F87DFFFFFF7D527DFD05F8FFFF52F8F8F852FD05FF52F8F8F852 +%FD05FF7DFD04F87DFD09FFA8FD04F8A8FD06FFA8A85227FD04F87DFD04FF +%52F8F8F852FD0CFFA8FD05F852A8FFFFA827FD04F827FFFF52F8F8F852FD +%05FF52F8F8F852FD05FF7DFD04F87DFD09FFA8FD04F8A8FFFFFF527DFD05 +%FF27F8F8F87DFD04FF52F8F8F827FD0DFF52FD0FF8FFFF52F8F8F852FD05 +%FF52F8F8F852FD05FF7DFD0DF852A8FD04F8A8FFFFA8F8F827277D5252FD +%04F87DFD04FF52F8F8F852FD0EFF52FD0DF827FFFF52F8F8F852FD05FF52 +%F8F8F852FD05FF7DFD0DF852FFFD04F8A8FFFF52FD0BF8FD05FF52F8F8F8 +%27FD0FFF7DFD0DF8FFFF52F8F8F852FD05FF52F8F8F852FD05FF7DFD0DF8 +%52A8FD04F8A8FFA8FD0BF87DFD05FF52F8F8F852FD11FF5252F8F8F82727 +%52F827F827FFFF52F8F8F852FD05FF52F8F8F852FD05FF7DF8F827F827F8 +%27F827F827F8F852FFF8F8F827A8FFFFA85227FD07F87DFD06FF52F8F8F8 +%52FD14FFA8FFA8FFFFFFA8FFA8FFFFFFA8FFA8FD07FFA8FFA8FD07FFA8FF +%A8FFA8FFA8FFA8FFA8FFA8FFFFFFA8FFA8FD05FFA8A8527D527D7DFD09FF +%A8FFA8FDFCFFFD8CFFFF +%%EndData + +endstream endobj 23 0 obj <>stream +%AI12_CompressedDatax{o%Ǒ'}s^Lz8Y-ƖaMI&{l{t?_DFdf:$Izɔ؇y2#߼ZU8V_~ՊW_}-~_\Ww?\~'p/./W%z{{I}z}ß=n]sur~_5CйxPo׭^9j >]~_w6$ԟ>MaL|wn^|wy}ۛח>lo~j?7?]}{9\ѵWK^{\;\|wqrvm>^}﾿EG;?hw_o.h a?MfFݦԑoo޿w+:JY/ѻ3ZU?%z1_H_zE[w6 }=0t-˯V̫F $FǷbrM\ys(C^*qswۋ/n~c)%r%|ۛ?T_ IJU߅<8F8?v۫-o?ż|{Ww9'?OZ߁m +z_Gloa/>a$&z{cſ}EǛ4ԟx{K|fBW]ŇhG+z篯n P~x{ to^_\H~{{$cϴ?#RC#ޝ_^;97824؇C77 \״}<GͿ_^\?}<.]]_]?;?]^ߜxiѲ&'$Ow~p~iѮnn~.^<qp}o^h/\}{A#с;hB.>g4}{񧋷?3r燕၆Zne}kzS8{FW䪯_U|e~: ?ZnZnkv߻o޿o]/斠5ڇ yEu<常<q)_f䪫Wv%-ǵgo~d'귴w|~ۏ?||7_~ p("^oV_?⚘l?v_>0 !˕|K1. ?_y_ l=}VHo/hQxO75GsAգuq}?l!7o>.ZyOoonޖ Weo䞿K/v^wBOW_tGAk^'_Î[zmB~'|󗋻?zhg7.~ݼ{9rOэ+ՕePW' [mKӘog_m0GM"4 OaJi HpCO| d6+A^}wfzxWcɛPF|y8I10ͮnʼn̪lѬLMDVzb}}R5W}6am6l6mfa.ݰwnv߇}ܧ=NWt-OqQ_AѻgujۅYh6Iޏ}cz;ڮCӲl&ӔF>O۸81).Ҭ!u]lGшEngm +ϱ_؏8q7nrS┦~iLi7M)zXzb6+M6fl68lh7c2!֕?4PNx[Z5Hݏ=~tc7=fXZyC?pou?váimynj^@iǥ^C 74= E:{5-Q֞D'xC'@tZ5ٮ?|:ZўvUjƎ>i{և0m΁P!28a Xp OG؎>2&>a:S?y)-qO<(xwfcZ9^XXԀqC.Vc"!DD4!K ȍkP @HXPa%f% DZ BK ?7O!b j%ݷpE"DZ$GaBHL,wBHB6ʳ&j6_~AI;?mYSΉ/ ̑'.$ c ^ p-^EIx0$ED +ϝXkKf,o\9*f;n>KkGp- ֘Mw͔PkذjcOb T#+86g%cLljtC`JOz`oT~۳gߔtY6ļg5@SuVmp܋=i|'GF2j:F>`Y>2ۿf`JuVbcQ›;jrd5$Ȇp'adnrhȪTѹv,R*ΏکUe>Z7OdbH ).#oO&f PK<;,^a>N<0O(,\d7]cO}W#e;B>[32WWGI&h9De[\FBb4ыF:X!^/hОs\+2`i(b1xS-}5nQ ++ F'Ǭ.XMmhb"ǐbB/i!C#6:ZO0ʢˍ~m4y?mlP59WtU;̞׃F5F֜z^*Uq5T#[KDO4Uڪ+t#srY_;U;Wj0}B-aY̻ RSr\wn0PCD4+=Z;["+;'Cb90| 1\ OOҎI-wXb۲Nvj+;?&|rOXƙaJInUfV6ք47"0y1?4,eAmώ:u"E]@1kgM6z{vǬgOĺu)S6lf( b dNrF;('\0Ag{ q,LOr 7 'bܮq 7aq!Jhi&eQ=ݷbn35{:г8e{MU+ TiePEtI]oƶ)NchZY5\wl?:.{mg~u'jP:'tʪ8Hveٮ:MCJ< ;[rG$:eƠಔnp8iD{#p4Ua5UaqYaϮUaYrp|c6 ٣l݂ͦ'_yё*|}(+|Q*R4>eebN3IY'aji1bY(Q`Иe\XK5fL@zVL@@6*1ڳHP!̂&a b Yl`62Qi0F8]%aU.LW7yWb+N+4 ( D%8)[vO֘'LVR uYE +0I 1VSӊwV,3e Jn{#JYϞ$.U.7C^_!7kFF29I_$/3Y76`$gQ(Iw퐙O5+쨊y3VJise48f=ɔۭ[SOf.MB7Ո+7U[}#S1koLH5Vtl\mT}kqǎ|uJMF2 ^V5HD<{k:HFdg(Gvx ZPLQ 3/AѨ@]E9Mֳ6͛4`m0<)S96JrN—^ܸ34fW^μvvk)k{j1k?0k_{csWfiq}+s~g= s/lM0*l;^<Ⱥq280>ӌ ӓSz PELoqⶵޝ~\6}*̤d߻ݿASfO-(̬#?&qMΖ(:e͢Ƙ#XVlce-ձlCCXp3me~O, Ggk^O8)~ $]aƹm2w~!= x0n~bGDLo9VR+-rK'%@xӜ[x'397{Bug$=a{fakll-6X y\Uuܵ r*Rzԁa3~p' `uTNxuʓoox=4^'`?o8p--YXYf%߳:*D5\ͱzN4bv"M ,B)# &aEIjr% ).R0db&`+Xa e`vgedd5 {b%HQwj4.P3i3 ٪EiŇif*8?8LcjV{M,XozE;y+^rky\j||V9`Y)u_yK,ʮ9''5bCvBb.q +Ll>]=v$ DZKksTgLC(Z +0ª`\L2D}"*U7I.7oZ4cj:kf;i.1cLG8wQnI>F#.>}(Gl}<M:H, ĀJ^۲*1Ɨlyr 7f%KcUkcyӊŕy%kkwU˫3Q5mǭ "u3UmZk{˭Ux)dœy~PJ$q#wSߍ+ Yʻ<#u Xlgm]w6 `y;qg| z z z ^B^B^B^B^B^B^B^B^B^B^B;KHKHKHQHڼD@p$v^˵,=sovi+{_ڶ`h +*@uԺnc^E+6Ac;;pTp)xC1{`ľ̟E^+xce+Hś90יY=I֏?>^%m_~1S]%rhq`WWA]3ץu*yʵ;qORܐ9IahkQM Oӄ*Wy%ScVO 1e_Npai!M٢h63ZLAi:jgo5 #ZNL*jpÈD=O]N˶ ZviU!^^si|uC͉eOE˼+E 8濴[b7{stqoTE%EMTQ,8d+]Rz+R=d-i2Em)Erm6&,,J BJ@R+lRf[{FR1D\wLg+3DZ +XD 'ǡgOITLY#jcFb˜ jǙpa)s/.sjW%S5fuU0Nb_[m hNfo,_7wڿ3")uTUUR/%goҳYwi Ő1r)aGvwk[&Ny8#LOH' C%eWмVg^z8O~@wm f ,;TX|Y_ȑH9HumϱG,~R?xF7FGU)+kKpYٯumw[YLXnGƖ9'5CRu {3娛cn\0;0u2A7 +IԙXё8O[\E$19Y犩!fgTQL%e˦%hsEUT8=WWxu#11cBFQW()k/I$u3kP 9&9NkTyƻOmrZ-{+C֭^S/ooc*j9SEhd3oaM%~QsqׂꟌhS:Ė9'南::UNZ/bE:p{0Pu-)'R7QYu)8wރv97ѐy9ޜHՑT,ҺJ_\t̷p kJF҆&sY;H &ƺUg7E7'2?*tpṩ.~nwh %-)\|ó|,\sJ.Y*vX>_ҥ \"(ş?S$4U᫤/ȘEL8mt)LRfYbǜ, a*Ղ?b2SlRի1`;?$"U+zi Lɶ~eSm%'*SE"yҰEN8-..gs9 N؁OKŹY8#'DfZvJY4-+,m1f*\c˸R?婛n6߬Ε߳zDj8`& +t@F5נkkt皵DV6);ʩ%y :'M0R E`6 DURTemڠuѼ2hUQZYΆL(f̼VG3 +r(OwН6d'˩yYN3ipڰѸ&Ħ œpjyS‰KM @/y8$:ўM#) =e!s[u 8J9qΡ#Z$602` (ya.D{-;V&( +<>c9egbWuq;GftMp[4{OV[NIi˓Y40hb8eQ LY9rG17m6Mgjl-پ&g3|dLCB#.Eu!5fuehj?xYMcc\.X1(+2X&'U4 1חwJTgx,3  +u"s5gqm{bOr=hY^2Odzۇ6X,^36 =.'cӴ=.bh{Fno!Ff%XGCfB"HȐ{s?] 4iCDT(v«靹v2ϰHl)1CZSZRF%ۦULk`^iLߥɻ8W~őӮD 6JlQ-n mQӾv.{t }n7˻KZK' ,?gqL4o4@$ˡZ6g%ȼO]'!,;.}ў,.S  +3ӳ\|H N3v3bit,#X3635nEDbH3ggOH5\-~.TyJ&ؒ?7)>J4R>&NG8j̑5OFVEQ>h⨦ѹGQQ0HMhqG"kGnI.KOħ =Yu$uKTA ܛ hDR?IDeJSl/G*{bġb.cl1 +~o99형dNv[*\iY/kua6L_. [TK֖b1>R}P ;cE{w-Ξv31Nh)g>ݜH)= ҪHm6qƜ1>l%GVq}{o=BIY! bn}KnDb=D]j$ h)?(~w+6,(;>I=-n?vľ/di罟Ğn'/NZ͏Eedgf'ffeZU)Z7=J~:%*?ߘO+0>l=UT%r:;=sAdt`j#՟| 3{`Ǽw3#>&Iu4n1'ZQ&.:Xl>sUo,lmF7Ә3iR2hqhzKZZjwSDmN⸫шˉd֟8CNX ?=\ץ9p +`q>MثmK~D]. #LbY8}ӻ3xB<]˗FhK0Ͽ99#,3<|c'U+ 8i4.uBn:VOtuwۋT8m9wn,-`Y*j\Ug.ڲP%#h>GvȽ͑S*Si9եvR+N#WG>U0=YM",nMk +%88y^ +.huyyɈ\\Յ-fKNЦl?R]#G?[cma]\8vsX;I{tGb/uz +Gݪ=`+rX<#hlT\g;DlXS%띮 1G>Ǟ]/7ۍbUBa.s=;B%mOsh *FZط%Iv+젝rڞMNV.pL,v-mltlܰuDNyv|#>Vm6"ӫPYk1mߓz-'9>2 ?CNébXETu'qOOI|sf{I#Oʳ*9pBeWʁ8&) 㤠7}.åOy>א,\>= |^]]]U-"|owA5IW?^Bpԏ+D\ʹ`dp!0dk_?>O ׫͗|XґW}տ4:iXmƯϫ_|ssvWyuۿnC4w^w~GW_ .\,J O3YpE0ٳrpF#F@j.zџf"n#vHx=ħ+dzއVnFlJ'CP8g)lܻ1EH$ }€e=~< ty=gHKn8HYΈ1yzw#0YB":4^cD 3\HBHj\„h4zj{*E.t67Q# m'^W&w40%8UxF/|k*xO2XYӺbiTwvaMO6mY?`=E(z$KE&w Gmv(c. 6" <]pt43Z=F=ѡ<.<UFԫ +жʼn6zh&Phc C7`t̓>a>lV>&IDtOGGv$DDyL=rTB@'bA`" tt=1+Li5xZjmFt]DMiFx~īhh1U)ac2DD>hB*$A @!D"B_E,ɷ4i˼HDc~MϖjL G0X#F.tCo=0.! " !4L}t^دiة,y(E( =#pFO'fbDC1w] @4Vޠ^=-J`tzlX㵃s>Əvi,m:15 +  dtcfP-]AS"8Zz @R/#4KdI$ *jtD6_Ot #Ⅻc$hxd,I$y5,C)͈F@_483'B:u_28 +uy\ +M'@Kԭ/Dm1fCP ++JmϘD6:Z4S1*NXn26oh}g胘` ZpQ'+H?BXûDGaZ&єiiRVD\π-I nB)T4r=B 4 /UƍXyG"7;,*."ux 3b)2N"`#`Ce}9`鉆xp٧y KSd%q83(iQ!3*ziCLb-}'nNlU&jï:940pI&2Dp~wyLv1Nȏ]@|@lb:ּ' g uQ)eN@O—@Y�j^vy 0 +Sf Rw!M~I`ASw@i +=Ĵwhgz<„N0Xev" )HbH.VҳCnj+'*)CEt +J`_dVP+ +uē +&vTa*ax`>8"l#b24NaeD*JNm؂~d*i fBVML+FN0@FvYКtJ~̛w*`z^+e\yhws-k@"ң| #["w,OKFЖ8! ƅn@mdG`q`-#qX%UсHNYMN$K +!1CY%Sg0 h*;B RelgM鮌5>ڠbaQPY}~Qڨ06ƙЀn0W hPQ#SԷ-ŒB}LܡI}~Mp3ʤ'W0(krfw&;ȉU#r"CFFc ]R,X6ydvHJac _VGd][&& LRfk Z&QuZtoϒx&E670S)k2%}OJX2/h:7 j+B$: 5tv|[bOK +)S@,A2fU'vaѷ`yj.|ʚ!]٢z]\Ad 4}WwUllDYŦf:8Gյk:=pS) +Ni6=\gTGѤ*1k^VQn  +6DbERnQi 7r:coSaHTF TTFWf])NYFTo44-q4ÀQQ5CKaFKOn@bLQZ-ƦAffy ȸ'lٔʅjv2اNX˘Dܤ̌4f~9X3kv3spfn=3_Thn +:DͦnҪ[l&;J߈=dn$ˁe91HDMME0@>eQg,&"gDO)+-TF?ffA $3`*eg1h\e)C*F+ꥲ* ( +FvA^[nvUUheUv̎6H?$yw^Uh"G8FĉH@{dv +&ē HcC'CU*6'!)'jO)]hGko($ݬ;Vc70BzWYO~kcx!{P3uK[2 +!rWP_룥a$q֓d9yk~́oc޺V[ZpSR*m`.7P_rtF5: 8qE +岼e ݔ-$ov6#1!^cޯKj!1Y=5x8B Nc ɹ`rrpOu9NIƼt6Z0D',(6SF(Dk `~L*GI8;O:-;s:s=PNUA͚_pnPAB-fJ`42~ +T8;Fsl+{ -y#sNz9y']ǫֈ /Sn|{vaAQ=Ҹ"8P'K7VdԾ"4;t1TjYXr9zkEŞ7>`B75R rFQ~ 3< xpc~(Ɋt|ĭ0z@}"<*xK |+̎f ž`iP#'Ix.&&X40yؚDB_ǮG4o =bt[辨bb8A_HP^PNGun +َ8W)Uy$g4B"!!;6|}acFhc)8ܦg6e3!h{"BZ%Xy$JE Vi$SN]%HNjda| 70EH%z +$R4W\&z. a`:'~ABŒfNr—e: |N /g[%}ne5~b؝abe\,$.ኵ []5D #]D吹1#O?=!ڂa@[2i`Y[emy`QX5A*QLc7&);_.T()͞VY^A!}Wq[;pv^.K:zy''N_ 1_}w//.gqTǔy6XPj&C**6 E>5$`X?ۓ`X`XDG`u0,!AїX0I|4#y +$V>j(OILq aSiBa=l(.`o9HXbZ#aq# Ľ&бY#aqk6HXQn +Su h4n|,ñ}%x%Q)GO'^Iwha0 >c5!" !.)xAaG } "s, ѰOKio]uJ 8;p0%ki +g;D ,Oi/GIJ$񔰴;@67q2r`"UfY&00>JOudR@{$F RʢlJzÌ>9Tmv528^]p%^5 + B2g$ٴOr0:a*x4B4hDcA?J/rŒiQ\dWdq[. g21sXŨe ]UT ^XK0s4L(-%eڔ?2# 6W4 + |)ckxkeyd6kZ(ǤaS'.jb{%#+GwT`ؚ% oBٺd50ҨJe*QwzMHTg*gi25 @Dm\١fao:uyc(i%Y%dLK*{,;le@l C?cú&D߫RI@6S(P+tо :%4#l:hanG+#5[gi#fA'y,6ŶTW7q."adHdxXPU9GF +ʧ̂ZR>mҔO=e0KP)f) "2XʂiX6K)´0Xx3EѳE)o#[$+D3bwF~,@TgBiT&r觅0D#mL-ꩣ$N\DՑ64Ә45*,OUt-WMر?r!I=;ȱp@97` ˹436GWe,Pڤ( 4_ћK"+9R Cwz< [64CZ5eyeK/ Lj@;tcNRh7 ;7ۙE|phvIKނ6ŮҘRfG歀<(?XkЌ$~XLֿN`9YCB Y*8]l˕?W8)+ du9^gWiИ~ެq`uT bf>ggY \4}n3qU33#!ʑՅe8.[XQ\[ \NnəWdm18"j"{qЂ&;5[i!"j*4<.s@2 6.D%d>umX 4]6Jˆ6e˅ +e0S3  nWU%#`fg]_;Tf͏g%HE%0J )PQƢ}-P>TdAIoZdz8*Lr0K O35 ,L3 1? 2)Ֆ,L[5 (-'O 2=L*\2ȀHZpz* fUsZ + +R@sHm–CqrȰuB>3 GN"{i )d2,^r9& WPի8Ą(8ǜxYj.ɽq>,!DIY":.<Rb(<hQe1\ݕl8nr ~D8=W3YCM+/jI(I3Cadic#5<>5!}>dHpr#/d΂Cɖ`IHȡ$oy۹&CuBS띹6ZKU \R $ hVlIu0Y!೗U\Y\-P]7>\z`ʄ4jݐ2r ~W=D> |B'ɨ/+tcÊJanb1L:iUsMF7k>h| ]i O.(íU Ӕ\[O2 HU4 zxZ%tk4R; Xhseq )8kɝdg(Rkm8Ajlb#ero3#,Lw4#aPyϘ@p*4 +4eesXJycři1#V^?#D5l t!|.HB+`ȥDQ@1ϮՐ?R4 PҐ)^$VPZQޑ8hhH>aAbAtOR!# +F#ⵐJc)*^>* |"DtDJtBB󒌤+Vf2R[aFԣDӨ2+5dτ8S܈ȜČ .1TbU:| +C`=43P.KG/І`9r3Gٞ)UP/pUDd9CegBDL/ƩM9RdES>Ϊ爽ȕ3814 +iW"X<ĺ!9J~j؅ӱJOmSMRyU9oz)[S\銩~]جZ2!S[iZ窙30 8l4ߦ3Q1)S{3h}8Mjg4vM%"0!SX4ƆLl(-3=!IUe5wnM3nXٴ熹Mޢx-P S]66#@f,0JV7%zfh2(YEZlfa1^zFt+Ǡfc*rf'26lI = Sug,X=e&V.Tl0wb3t&A'gg*sjVĆ5kqf4L-l6Ncjlx16V7fm34a_80%f@ZM1Ct+$&jTeV2;ifIWQ,gy zo[A\Rs0< Z\L.n +*'F2&y[%jέbu+[ekLva0΢p]/UaC̅5asHDDl2@:~ +pG ISRyqJrZr? ʙs ?ȃU׹]l==htOp%=q Tlz#B=Aq93_B1MF ?"X\"-afg)@ [kS:c`YH>]sf 7 a[@jv*UPAcra\ Jv)KKPe.`_F'c{{MrwK;8U}̝ƱЈ W4EA>Cڽqd+1fǪU{g\E 0XXb],yה&DKrnimpn#9C],pZ:=nH`.W|<`JFy]O_Cmu(T`ԗu$e$U};e & tt 'gu5jJLmڳ7}'一xy[$?m㋙AL?g:-}5Db!~ (6e&B"Dn&t#`T%ewy><22#ܥ,E!ػMĮ?*$ wٔ,T _եa?I=5Ov2t7Y_{ti IN&򦼠JkC_/|&Fjl'tsvB~RE5]xRJcqVr,q^oh߽3~}_ ?{C=?vtƓ,4Y2&n3)n1 hq\ckb1A#KAI s%`bt4۠S.'NA zjpYiPbVsJm(1(ݎb6()h'Q'bLRQeLږA1C>ǘ|4}Ԏ} L>.Ato~,;]v# q{K~q7ꆥ!Qa!B@V"U< #YTanMLgS|"1VxzKMBT1jZS& 3J8ءEEiJݨغu;*'I=WY "K|x8WCmgh?հ&pͭkR ( vqC:H!BR9FV n gTýNVMMyab蒁Th㯫JI_?8*mUwjDmA⫧uvZey,Y}NMFJڈ7 ߮xO6|8~joB4jcCw[u8#E}'kI +x"N*R( "f}i+CUztP4;H4>fzFm׆Va)]֩jTg!Sr@ 뛉 1{XC2yCdH)D)_wHxx;,*% + *`jߗp^MI01*ѫ%n h,Rͱ41$)MPOjvvUSsrZ"#f8 WC=p3eOĀk.m I(ҵG6>esld6[֕1=N-Tg!E~`MhW[i~)OZUuf1MLT\ȯ[5R*7{q?̍rF i]G3tL\ V37J*Ӯ37'b݈6u"%-MVN,VTn_4u=(MË}o4]4}\7(oh*lj FwNđC7M5g`YWH fwƎ&ԈhR2"(PFDW *q@wHUXROb#ho\DEj:~ۈv:x 'u,3-%@ޚRxJx ?KF<ȯZ3MLbOaiIx6㍀ gG|p@=$ǐ 9&H˷QA!yK#oQ;ڜ^}Nkx3 E'TH,z9<06%reu YS00UX2:+e[];C:S*>,*_ΤKTeKgK0XVu^sóȵ»HgS{lH7 gjp]G=$h_noMV`>+iA13ob Z %6 U5;_T>՜C@j;J6V9e4 0t![Z+OA $J|'o yC۪KmnrُBÃJ&.ؼq a y| /N{[jУS1!O{#r ..US)0eqw[%n8tR,n,eIlwuQDɐ{hUK2D6@U!vU.lgUɹx>]3>*,~ c?y ,)4LC[SHu[xxvx0~D8TZO9OvM'OWy;6-o[> 6_$@xto_-:-b@׍X6@oz9[5^q96g`q}/Re(*L#Ttkjd~!DvlHޞp(TݻtKdKvW2]J8-̺OSYHudm=(tK+f~Zu (~겕 _PsXu{Cݳ3W,.+>#D(XZX!V })uyBڍ\(GH1:| +W5_+kk'e>)s ,BQ/$|T5 +Q۹$p~^n c]_JڕR9ߺURBxh{՟7+~45mr"ְe?I%*3 gd^k= +֪|뼽O8ؼZu߻%dyvDa}"]+_o[2&Dfm=W*d=; W_s2_Ab:up׸`K˛BE̎{jqWvQ^l=]f YJ-5o#[]UEVvO_2gWq":6\2?1%G"ɞ`d9q%6i~' +9fGІ߬PP"m:9;b0dHDw0V+`crsjXe '}JEm 5`A? 1ٜօ3#DY* nLn+Gt${:9xY3͹4)7sD~΄ӆug-Ia!7?<|:5K#JI^=HrG{s`MMtUKRt'ln.>cW~\E̶B_SN?RC]u*Wuxw/lCw_+p\+ JvvR'iI*+bѠ/& ۏ"9|)2aS>,3ZrE3hf;\Y:)g$g̰ ?r32~ETF2i)ndv(2XBEՊp2g~[&תYGΝő+NpP3Xّn&-^trCbqy3lA4o: %σW3<6z22W泞#ɯe$,jH8:R-35Uű9 JoPknY )#"Q|ڒ|n}ӞPK#]+*GV7X'ڽK~\tI'/IFnJ7WnydL DDS@^ngfLGwfH T]%!fqndNgOǿU=vO-;^=Ar5z{G)F+x;4[z_70BLJdm<+WsޒPn!rGR}9r-_<&psH}z{_Pdl2T{ڵmٵmٵ1&KFMfFMfFM֮l̮l,]5]ϫ4Y6i26i26inddnDdvnddܰlȮȮڷ]ӆ5Y7k27k27k6ndh܈Ѹ}q#&q#&q#&kFMfFMF~)tj1Chun,"Dj5,>Rt_`*9'JJPO!XF`K]%X78(zҵ^rXQ]hi拧`zy^ +qp}f Q4$8qME"i;UO":}'Eٌ/>VGŢ5)Y54N "锢E hS}ϲE)}|-*Z:ԬŬS]f;l|,,B٩0&͢IK^Ydo},z9r<^? i58GFKWC%ƫhUjx-9\FKR%hjH*5ZbJRVђPijjh5DZb"-e"-1Z JKLKVC%FRFPj2#h:&wk[eZg)$&BT}-"- Vۧ_B1T~O~_}c=*E*f-PZE٣ZKR"XEe)R&EzC"EeIQ^Rs,(B/M"EeO!x/=RRZ](R/;(R0;( [u2~Rpo:Y-k*r` xUƫ}]5NPC:r(> +|18SitPQjoIed׎SYFHB#EkWdb!S>ظ]a% ڰTpM=mH Q{rqB.3B}\婼Cnwơ9S^M '>@ +G:q6 Q i޴3D)O\Riӆw1ߨtagGTyhC-/U +=/5n qU55m(u_I+ֵGEh?F)\sk>#Q| ȗ^iyKK6>ƗOa||_(N=V>9X0fQrS՜Uc-%D.,sM/,;ՎSԙ7+&̲9Dy]Uϫ&k.M-p6#t3Dž &ckna6[@]|ceυ[rj|Mg٦'v=g.$7[̩X,Gk&䝢:]sGaViKvdC'5"W3|>?äYYhNWYHR,$FLCy4y-h@gJJ\ERdqlbtmUʒ^QsOacU$B#o50lhk_eu"F\*gu tl/dt6iq[Nˀi'@s#Yp֢^J H6k`]ݸv6G[Gݪ/X "օ9v <O]9Z>~rWk1R%c(Z25+ 5Jr4b-](n (xqvYS%]Ot̷tY*6"XZIdž_޻}G,S('X8b6YӦXune΃0%l]x9 ou#/eSj++JvW^Zu,fTy +S~VjHћz_=SOzS'\Xu1⿈{iM|m-:m1ݷVK*5} \yI?>+R((׫{:.S6cVOKӜ^r#\46=IKqsҜ;Mf@5V +aߍN=<5ڧw̕thSKZAGuI&")P{]I}[p_7jV#ky+T=on|߇O*]eMV~~AV׬Ea^̦XAK`zFEms@bu!-40oˬڕm[QMKw^ԝޛk3cux"2&#mFeɊ ?E L6V 6@e=e0),טbY:)Q/}huq oVBܸ}:W/v 0eֳ+9.(nW,#q-@4D|%!}VqnpK +!^_ŶJ kӾRC뀸-uRqjd\$Ϛv+AQ3pŽ=cz< {C9$^ΌڧXe(jߋW~oqD3_oCn}5rvvx|$lӷ{Zg_tѷzZ͙wu+c(`Cg<#Ҧ ^$-kŒ:J\1u&#vT8Axz%F.?e^ u^7;ceΉrv.TSo:i,ts2҄<"'{ʚse.ʮx)&oiiC% ,,O0>dpdZ=pbxͧ GgOɂ^Gjzg¹Y=ªo{k|45p~Cw Rk0CU\ָ~&ǚP8s)33dcuƶ똞A3PCFsRBc}KcLq3afr,ØT#6FbLӞyt "2ȹyH$p>Xk3EhI_zs"56d2UݸH w/Rd%\ڛIdfb.U3}f2px4Nr&әd#SYhYt3=ZG%CZcQ)ٺܭP2KץNsI\4e.2EkLb*-u-I\e'>I0!ʴa^Q;{k%{֓"nCRj< JS˯}7ܢٛ͸ebQ#a?{nT826THaO/?Nf5e|Rv?kۭ5"I=s + kXd~NWT[]^089U ///uy?a㞡A"1zs=ߧg hrDnáDU68HZWW|= ;j~Wqvv)=Z !|R1'cV<ȳoQ=AW?'kR@uTϨGD!'@WTZmfJ"hך~5+YϙuSF1{9ԥjkѐžAMly3uVM6ULuzGNKmͩ2}2blm.ff#fj أky-s:jwQkIjsw^_kvq콛`J +dzg}xѴ)@]"j +*ey 5ݠ,*Q w<|YI2\"h/%nNg +kNB{Csy~)ZfYP3ͨ )?BB ’n +^$gڮ8/+SRw59#ˠ`ZZ2_SBjUM_MT KRHhvCzn$ t,:kwqΐ=&`6=]C?O$q4ISjSYiMx (!N2an־f'+q<ט#hwi~*HwK(Êѽ;v{#ƠvnV=gwsungZ* +(̛ +uۧK{r>o.f gu5kgdz7us72?_z ɏ oZ*Q=|"fO'O_/G%{ʂ5 i؜/g?׿ן~X-=Nd_ XQ۟Fg{6~_/[O_~~?~?Տ[}cĹ~uï~ 6.xD:|ܜ?/lw>'_7~.;Rgg??_/~7Ogp?~?7J$7ڡW` [U,6 Ͽ[71?~Yu|7Oןzn>rȴ7?*<|PwO~Erc.[𿘛 'BRˎ򚠈R ZlYq1OO//q 9^jy&j0e]FWh 꾡7J\rɤ&qW;V@BH'u>* ( X46 +󒌉WQzYy`e׌@%,B坭#wNֵZ]JOϚZ/4+qhv9)GSua No>i%#~DJ!˜6 pKܕ%yDavQaQM3̘+Dt/l.ᔩCm7HH]>,؎|$1Z+c'oGψp/E^ k"1~UU),s7w,bx:b1 0ݜ]u`j/pԉ2ee6k%&L4)f+!rP1PLXY%=&uƼu)Rov1oISCDy+u:;,dzY' 6}PK)aicVΡ e$2JߙvYHEt-U(qXlWqx LҰ~%Ȩ:U-iWqSI0ʀjx K'U몿?ᆝ~GZ_`*C!^%KGAf/HC0,nn s^TN:8E8^?#ʠސ8oW r?%h(X's%^܂uȊ3sZ8f ٹhȃȽ9WKKиܬCB^Vp0޼u7qW9^+6E$L-Ѵ~[.SK=UJʥCxX˘AnKD@+0PtMxN I1eE{VLs YZ^Igd$H?R.N6_ Rnn\.J{yD\[No>5U +63l~y^MJi%e͡AxŲyOe̴SU-k]dn'H2:6ɀro2!jչT:c3֯aSwRGCTBA27;|[$}<Xu7aW@Ţ@j4K*h/DZkJFO.Xa`]ºXSվnpڀK4 =|Y;l- /?'hsCg? "-༌K[TNjYV0I|۲XJz'ܥ'X5ñI(/mcXU>t/Sm I[d%WO+Tn6Q ;f=KEчagEmMI>ﷅ\e)4vK7)Y]-jSzk鸚rs| ղF̟gVj_c5fC$(̨`CZs8 29{Iu"s"`DPvro~'HɡٽڊpYXOj*nʷVzDEܵ+!2htQ:Ȓ~GdrPN_I46:hb#f`턢L\hYF207d QԋUeLn[2p 0Xma4,WkϾtrwyo+_Au6䟻ŗ+J_o$ \*pd Zӓ&[..k"h}UrQԤ~ֶZyۧ%B>ꭀl· maA׋n]aJ{M_iA!' +m;~Io5]"WmebXD_E^>:.zG6f爫$պu1\,K|G JwkxoJռ@xt֊J%BΘU4 k,bEd c5xߘ…L-u9NŰ&8I7i(J6+^烮^UKJ޹W?ka1㺄 z JPZxܴQnѹ0rq?13Z"oEǸ@5[&"*Y2>*ꈇ28X De{~gDC.B{0 snטD\- v2ܚf;@/i򜖯fܐV1-jEHPb9oF*vy&BQHcͨA=OK4OyhzmKa3}fglGE%0]} c(\/Ѯrp~[$KZ@`Y9' ǑWxP/ t +l1Ī,hl\N˒Ia<6>~I,{ ,S27dɧ-Ddq+Snf5ɢ쪁#wtw!L~Uچ8F ֶ@Q,>ﻆ>[:希aHPZoN/ ˤcYfBdCYY@R)6\K﨩*ΟJܳ[OHKfe4-L(aV͎1YnaVN}G(\6Ʋ0ԦfaK,3jx% e&2V2q\GZ#a@ \tE{y,EmX_{h-K05+F D.rR4Pzd[N#>'kw$뮊Db3W&yYvZ@ ؞ae"Iޑ.6 @YL)̸{VY[S(K=p+MZV66=T1=J֜˼OJTjs%Բox.z>e/_nN)Lp)d7a>Ck% gI2'*c`-JO ZHF+詈7=P&3$ 7w}'7~o Aď%ʘ[܈J=?JMuh-b^l3AH7eĉr_ﮊ[Ij_\3^0z\y@MM>PwG Ѳ{a+ӷ3SGJ+-,uCg9uYh|R[y0,~Ѱˆ 'X_Hf%?gc.^%}5\XT(sK![\Wb* Y*w߻ǵR+-#b}ԲڮhD9,XY(F +4hf ?dDnp貇n4z>jmX +f4<ɂܤO1[; 6 1qt#KPrdѫr*cyG$G{ C8I8[[9 Kp[M/1gJ-D~-# "!(~KYZh!\kTvHw*wR;D0 lk28#G&V2ts1ܔe!vnOLJ;X6 ]^ݬqxMo:\TѮG>66@nXoc> {vSYT";j΍֌Q!AP @niN[絘U=eg[HaPc3ևri=Mig_FPs^ՋDfzV +POkcΫ4 zsCpԋ/UfYbu۷)!XJT͆׫CiVjreP=)NHgZa]W`oDR#gN7*vjẃ.Ms',BS!Ilk3^Z!5P\ uNmKÁ-}Ge`#Z*P,Ly/R>D&Nk; ++%]0mvt sWjc&3,%7Y[v`%[0kGͱF-XԒER,$ceHZxQvJxr/1T-`H)6%>p_w"V6,/V[ ӵ7E'V[KK$LSZ8-6ER9]"d37 f$tz!z-݋KC. G3FUTLt..km`yWdv^P*c﹙t*VEHN)ELf)ŷ@Eʦ N|P-6+z\ҝ+lvbXh\ƬEV*,rgqeUv"@,g}杍52ЯRG{K( +&d"RL붫 dJ"M]`V喻]tg| +w܍ny\ȼFt Dj- @< G7lcɹ!YD$zyj7D,V20>[ +uowI, X,J()LuQ8[]R5y[Un-FBXVLSܿ)UXEiܒFQyja,觺ͨG +Їbo&y^ڢɇR.3$QHnw/baekyl%@bT g*IYB"K1~Lw[ܢD?7xXi9(+D{s1_'XL;GMrJZRGh"^<'e#E0Ix ?)p vKò9JfmΏw=H]F*|g}UPk\$,&q~vUTVĊ3%1W/s|!i"[D+R,PɾIM*2Ft'}WPubbr] K%dE9]jWrܒ_!9@lNqXI>u(_Wҳ%ԃ''CiDDd`DyiZ<đݪ7uTY5G.k^k& ,3n=Nu*-/e?)1yn&bkɵˊiVfD}GƟʠcTc#_[\BYVKpDH*Eֹ[Άz\3/j@~df앷5fULK{v*> +$ӆ0wțbKJs2. t=3=fs)Ner4\5G!i(Y$I +>ߢ**UB&_:E8#lUWSPeYDѯi⥼x~qi40V[qѱ蜺oaQ}|暊V46[?"?|Ŝ>G+G +ʫkB>Bp?}UaVł>GO&O9{e=iZ'k^"0CvVS| @ډ&@mqjXx.KɿA\m?1ܱAO+Ԉu{n@$߲J]Uz6 2YiB*Ko=:=+x4cJ(k\]?Uⴚ~few D4e'Ą%ԋ|xi!E=ll?tTiMA64lº&/7:HK9'9]묯x1W7ׄ OAq,;]2Gb)nU;2P$t<:Jr^r:2^:t"@U\FlZ';ũ)6HCyi%7K<j.&Asa|K{%+A2a` !.7v;|Zx8OZfPmwL*^o1#cr஽UHVjLw./m V +y[b$XP](o;b"SGjEXɯ q[LHɭ[2HE1o9 +֍k -A}Bz×(^yIYKd20bxolM?;5ڔrOY3S{HR^%|bKKbgLUjIHz*ݶvtfDلmb b6ۈFYF,Cj5,c)P ;oBzۏ*{knιt :{X,~} ׸`udQy( 3o#QXkn'*&K"צJyrMEJ>{V1'>ll69wf6&!͐xm@ѫjp<[IY،Y.bC{jӓ%ZV25̪5Oœ}4I'c-Q4jt1'5JUޕ%n,l5fn3CB-2#gi|4u[8S= []d)r˴,i_ X)LexZؐf)I?QS&4VO[DuR!ji- /&lB;R0GL9,k:XC丕yjác>VV=u;fq}}jf9rea YbIppl֣LsGᤤdN# +/E"i=-Ľ/ɱ # eg)h+,* [oiG#\D|zGSݟZO1ӖI띰Ġ"az0[S+-dݩ/ +jq Ķ o!GûբCEILI- f>kTs"U <(o8@a&P%2bUw OncgeDy^2acԡds/?NQu6ʡNlB ́`UVn;*4a?U!#1x8Cp\pd`nRL'*4 +Mn `wFYL9錐[P^"<8﫤.ATn^nm:7Zm CjS9a$;%d~J$//fH=] 4WBlp 2B}ɕggY`@0!9㙪č2(¢;24݊":#fQbXeRV (s2!@7gTb*uSXB7cYRhAb=-Xygb=TÄ3 ^}37%-1 dR 7ө2u*Iܼ[h'B F =}D%us/7UXwT׼bklì*)`ː2Y,Z$xpj'pW*nEWĻ%\! yy8:n)4ORκFbH1LU= +XK|fL5!TÐaOJg$/W mtRj-#xX5=-KA٣K}T48^u8h6yp> Pnq;`"g O~ #~Wo7*?l`:/ OzBPuM2oTuMi^LVvRuNǛu*z]SuM֙^'v^XS@QuM .b^xzJr}0}Qu2z,6tUz]K5`[GKznB#WueMf! oD#׭w:N^kcIBTxkux:^H묔`!Vue s +#^g"3nU[(w놥>4c? ):\ƯyPu/ _'L:,_gU|8_ _GQuO|3*_,u]=_/zuɷzԋ'N몧~:7_|zu _y_|7zou|,3|抯RuX>:_%4랏K>N]_ٌa,: _&0߄k*\&qw|],e1q|]Ǩ\uX:f|]C_Q+a(:&b9u振kh`A& _VOص@NNC_Su{!u0:]˄kd=u_'C?N=uM30T3Vpzz&z#4Su }Ǚ^פ6,?u8 + 4PuiMzwڹ~5F@׽Nsasa(:m5&8Lk>u C׽O: N:I* +64z]X^4}MvmOz]{1L::[^רox^gwo KMf׵(uzITz:̕^'Ka.:ζڵ}蜛1H4Tz0~`ױX@#[u^z'DSrץuxL#^Tz]KAB\uzv}uJBaz];O:M^G&ˠ c0*gzz޽B㣫&A\uzv}d.&^ӫF&L׽^7zo:х^X?uM3W+>ul7ZJR˾ZܐB,3n^2:~IS밈>:Y: N+:]^G0NzduuMYUGtQ.Uuo֯O:u-s^'?&L5^p^nj^u,B*nX +n^p^uD[:p^G,눃|_:v@#SuhWzzA Δfz]Z +.NS;D^FЙ^Gf=#d;z^Vz]_7z6,_u,+^'3c0Tx:=Ru +=uK^Ix'h`:H'` #SuJ>0xu>du +x:e0 +&x]_:2 +0Uש7̀lr.캮]Gwe +]Tvt:E +N®ɮ\ujB/:vaʮr`~`ZurvwH[e!^u u]3`vʮê.qseRu):%F +(:vמuu6: ],Ocu=(@a+: ]']'댮aFaxg +f9t8u]jF1?uft]W󄮓ၮ:ntMAWt}_:ǹO:96PQu2˭ t,Lk{Cɣ.:*] +PtoEױn*:jtT+/N<]m+N悮o,љͪ~[uTv-Yh]GHe@/&e׵'5vʮSX}@Tv]K|v뚐8:E +Ke`a:Y&v +{Vu +aujRsF_u| t'OA57O:$:뗛u߂kJZ-مrt]K!@|@ש`B5T3I:]RuJtPDy@ױ{EWt];Oj'~fwKܴ$: N'sE5ft:׊SQBA1@\uX +].:,u]Y>뚘=SAQDש묠#N]Gr릴B:Y\oL_|r\ǟuVrD\}y0Wr]i&a@\u\'˃\וud* FSd!Tr%v]o:v亮Nwr]jDz"ص:,Vu\z%Q$a:亲 \uX*r]A$e}#~ ש"t\EX~Ԓ9^Pug>u +\0TuT=uZ=AVufrk!שEIy&a(.wr:I +NBA/:%1:O:u::rvuR,亡::\G댑 Py&)k0:r +N$Yo&RuICԝ0zpx +\VB#}\] +8W uh.n&) ufr*\Gr + Ө:z,>83=i$YLRuX>0:ar,r23rk3N}*r^u|\GVIKVw8R%quf~:^JS\GZ.T뤽u]_c_ue[`$Qu +غa(غalj'gl]B`سb+غ[GTb l: NkSj䁭ua:,u +:flm.:b[?l[ [G;l抭krfl]kN[= NG`L`55غ&*[bbغ͂SMRuV\ul~ާ`x.[7,[g['"wljNbh3'N[J[G[Y;߰ufy k`TLSu+}Y 挭غa)غغvrk蚆*NeSOl['ˌ[yuM![N[']w偭k%uܒ,3j2;N[Gl: N[7,[7́7*7bXfTlݰlgl[Q^u-:![''NJN[V'sa:mֵUl +c:lduYRb:ʌPu`-:jY*nXֵؐ{:$x`Li!fYud?`L2jebpb Kc-[g[g[gbduS|a::jn*QrYu|a:,[;N[W,ՎOlw`?u*K K֙yqk N-l*fl][!a-:)n:z̟:3 N`Ɛۡ8Qui)غ~ u]): +N [GDs)[ui):N:غuX Ìl[glv{`x3/b0c:gl]Q{`luu[h›u qOl^[8PuD:3N::c0l':uOغ3넭S錭S`;c%߰uܝu8[GPYu +}Ms:BZ$C֥Pթu*uNZPdxPdu:L˲B#\u*xu0Sթu=rX#֩l/ԺڇwjjGurgj0ԺMe1b:5B֙Z֠IqֱxRyTjDZB֩AɫPjEHOjQB)fߕZ֠IPh6@S L{-XߨuH#?3D JZw*0TQR +OK/:|{]Rq1uT7^nNZضXNNPuLRd;(uj;nG$C)v7Bkwimp+(x:B8]c߶NG op:Mǁ2ds6)kjjKғJ6JB>Kk" m5GeL5,FnƘHGqo@:kNtݽ 7N^m:K3 !Fk:k%<0t c H *CE.<%QsK|Yфb4wi'91QZ|HL9tdFqWɰBB1!︾p10/X`:])]Ny6Yцٕc3))^r_K$Ivj {4r|.aԸQ^6N2rB+T-?T9{o*G.ooBddN,*u7׳9UK۶cPTYeʑ5rT{>/wUMP9۲ fZn:TC#[r+rtISg~+7r!Qw$KJ`ʌsڻ=U7(zn3#JܓrGxrQS>TCd&˙rBRH9%qoW(G@qwʱd'p)89qMI`ro,n%qNSHrS9 j6S$r]S<'Dn1Bs~@ȩ6JD;( DC^/q'-Ϥl9';N 4Z/%tϐPgNV)};7.iv܅T8ߍ~OQZ2.Nĸ^ʢSz⨻DqqiˣS3,NQRDa ] XV,VKc6_dZj: p/ZSwZ\{:lǂ7DjpQ[a`YLqg^{aJ6&-n +TQAsZ[dzr~=&/Fʜ8ðr +|ʼ8'Bts^ċØD^]gwx2/N%ٟj `_}㖰Sao־L1KXL8FySm)$^TB .Wϼ8]v$Q 7J.No¹ E1;.G澩~O\y[Pf"v?'GK3iqCY*qIv(n8%=I |8Σ]Ȁ-a-aqTJqW-5N'a2Z~CZ&\r\/PiqqeX.N(-aM5pq`:*Yʸ8Ie. [|Ah+Kԭqq3gN0:4}:LƆPG]"[z 8*0 \\ذ{yТIpxL8&AVM'MOq[?@[F)~AEU%;'ωw"nɗW'b1?e2Tߦ"-o"đWi}% p/=p'5Gl8͊g='/ϬpA7߉ +PL ؙp ;DiE2@LCgFIv$Ndx Wh?j.yL$& rNR3D8NG-̨WUX6pR,H8]GH8d⛁㥗_G5N?iG=4i1H)$$\+Q5io8ip(<kՌY3 [rᴹZY7')~n4V7tpKIdMv2\jd8~Ovpw- 'łAҏ"Ñ 8p29ECR9$2V(XyJ&́x&&%Z 7L[r$2O*h$M_PP?^q42nɆइFq.ͣ G-W.pس]q Ǯq}_Aps&i z{/4@"T Ge [rd4M'&^@ ᖰpS zZQ`tIF*iq&. +#:EeeQPsS楌 +g,*WPᰙz7pvR©|r]A۔ +}激=P8E[G=DS3Y] ,vN?H]-r' #q/ n ; +nASJ{ʵpNK%u*Lyڂ)3rM'QDΫ7 $UDY@7unr{7UI79.O7j=D4NRQ-aǽM5hoj{IF +s}Nh+Z={Tm) 䀽{gg&f7ZiƘ°7a5XoCxn`)ʹj@JY$TFѬ/hoO2kZZe, ++bXbqĠq`ioXho܎kN{{ڛ.$2aEĽI Ee ܛ8`Eڿpo!7QQM{S0sـC jw 7a>{STMX{L-pow;:S-O7F48&s潑` ޛU]eުEڵgp @{zqĽ 7H_ +ﭒ=MMVS7~{f]hoR`Y3"u/Q u^7 &!{SPڍ`˃&gG3?Yop,hKYB)Jb*[%0z#WQoCq&Ml]FIdⳁz3ҾPoP79 !\7} + ֛^i͇+XoT0o덁z/CNz{kxˤ70g&溈< [=<ު&9 JA B|3!'͎:'MIK7XAz1HoVtq`Qޘ['C`n {p[٪D<FD!3}/u.hiOCԩn|2ngP7)1roItù/Lyt֠$mgaL7lF +t#uz)LTEP2A݈h1mXTUl9@xӦzQjz͆ +]ט6,/m'St,Hm$ŴP+q6;hQ9ԆugHgi^niR%(Ҧ:9L&mm Ѧ0 j; h[>Z)7c5zlJp6lm3lpf3TxdO @²^T6pC& ϗKL6A@MumJn]<6E*#bkkj%k ƦbSb,6aCAcTilicmQf1Ylw;G 6Alÿ_IԖ'8l,ub-V-Sn}B"lrc̍5hV=Lk2ɨLx꤯b_kVt٣+$$kM~<5k"6arjB._`w5D-\k):Hl5*5o5jjM'iM +hM`P/_פQ@Sr@֘jό5Hf}2dX#{O k-T,5VL<;a|q=FL +endstream endobj 24 0 obj <>stream +$2#`kHX'{ҭAXCl sc&eY)ʀ5dbXC!5q$`#*=TmN i }6XXd!S +5)`Md X7FEp&5Cc3|5)2cјi-W#m|5>;;曉jX |Gƾ'xDTW+sZ]|5XaM2qXkO.!0b ҁX'&ً!%2BXošTƩ$52`MN kJXI"RbVAXi kZ6EXWK*+/9en܄XSR5,F>͡W5$h9>aM 3ꉰV,1L kh?6Xg£bg)Gl˨(<\0kJy5.l FDG憪erk5V^o5`JBgM>ɥ/ԽYH!+P-8kWݹ;'} D! 4aǬ׸br+#>g8|hߏG;(NM[x5CDjrWIfը!pg"(|5 +_͎jnu_MazGj|rUi*4^M2W#j(fՎQjZ*`px5pxx-FMiP.g(K|5TJܜRx#3 &oK!ju\N^|5vZeCՖ㽖|57|5 ̓􂯆ɴ;_ Q%nWC$|5 _bo͝XQVUVj-|5 ^bwNZmp{M5jtRp5˿jX/\m +p5_p\ 3&7\ u!lp5!p5`;\M &tH6 Zbi&1;ovK] y89͠ʁ +{Tf1]nDWc'HSմ%t5U_iŐIWC wt5^GPkI^ֶj Dij46S]PZicϾ-jDxPrfS'FAWCvaW`{@#QBi{O,jnre@?dGJ +Gq 9jR +{VCb(jDL[jR,jڑYh9jZJ7^poz}aܵy5/CQl5d&nդPbj +;Zʂ2닭ƶ"`QVV+8jl5uGiVB"- ^mwvɔa:oXAU~an^6fjTU YPդOT56;2\H";U RS٩jxXlAU۔cAUӇm&.MۺW C +@n9U[rp(T 6j@C{Ya07N:n8mY^)P/;%4 '`V#LUs9 Y 86oF4udV#dK"j(9mj}o]3:{Sy*W 6 .j2Xmޥ\5[W3j#ZkU HN!ŌpdLL52Ŧu+=D5xUWatEEsԠBUT1$\H#O^J(Hj +>]y GmVx41jSH5ԫ/Z\ 8B8HZɸ P{/L5-efĢ2 !:b8m8$'8-L^P;J_9uZ4ʹ3m)L{htΔ4XQi-"&ƷvG<`iw,nfPib[PIi`< {8iF¤g?ATo5HЁr ҖS4EwgLx4hm;L,0+Ndvτ Fv P$(Z]du& :M}Wa`N[@4H2; ?{$ńtSphg44qC6,3~'BSC0W*ІLu4ov R 4̃C-L0T $N4LctU~/LlN?&l ;l>#:re&f-U{.g^b3wlgblS3P-wD $BVW8l)_r` 3tss̈݋{FR]3L҇A.9)T3[<<kQ9QLn!mQLBg;yMU瞡X=#߱gh0 #=ia3:(ya@ϰJ3zV(qRNzƦmaL9YRW#v'L;X3p *zF:; zF.gRlг$=gSh$$3j=g`1N3yt7m4ط;#$Z3x3 GP<3plQv{oG,g<+Lf%`f>ߞk^a- J"M5gZqw ~'v:w0sy6=[S +~9g%r +; &'jA>cyy>x3R&L35k,}^ heml85Rw೩$T|f'Ew+|F ~Zy|` 7PR$Vc7eڥ"VO3p||ʑ%&N>C3- ~'5 mwYh=`kvjǞ1kTybhI{ǞM5z3/xfzewaQ!g G8g}ְ3^0y瞡V`si`'fN3z!lsL,kcϬ^Gݚz%:t {o|{f@:LQGVq {/{FlRkQ$߮=SؚzVh4gSHܳ:{gdԵYus U*g+apgE`(BR& gKرgKuYRpN/nCU +ߚw66 {wk41A9_u:N9 ZpRغAS^M(3ag Nj ϧޛ3qlު0W ` ڎF%jRoQtPun; +Yc&W/SƂ$YMoWf| |֕g%:U\(CU,BS-(B'Hϊug湌 +4mq@+hЊz BZhMltqV QZ"Z-wsiϣN]EKeCrmrw* + w}n04QTS [U5m8~"t~asQE8F)LR +=L- R&M_ﺙǢ+8 m)cGMY]?ԏ' + i9Շ線: C_㱭҅ Px6KN:JLEK(4dURS#aZAY4d=* Vv:M盟ٜT<֐s6l`NO;O3ښ&7y.@Mc-BP:N;оǔ<.֋b!v6…Q̣h;xYx%*2زkLl(T].G),Uv$ӱ)^ E0)MU^:Qj)T]]OͭJڞ ֱC6[%6"ٟ|(5O)/{|ſN'ScdInB N'`(v|wk]=yYU{{ܚ}IWT +mFS܏@q@KxjRZI2:\+]%JYyQ쐺8L}TrL,kb5:}c}b )Q L8]^̵pÓ]*q}Xosj RQhҜɳLǚ"dIP{ɇs ?]$}Pt Y3XjLxkKDY.L[&ʽVŸ@moƘ\MuPH[[b9}e*OW+.;=^WeK CN}`{t+҉W#P!b>ɖRdǺ~xWjyT~_-*vv`U7yo)l<10F[Wfi+J8;KFD2[ɉjj.<|"]&uDޞ&o`5Vw)]~Ώ8d3ìn*)W +w#*3(7s4nw3^Z>Qpd0F eMHYk=)u[fۆNCX\:Ae]\0a QKOƒP{ܐme am3NΆywEp\zZo%vmjBusZE=N"JLx5Ǹm7Ω Is + !uiN2{T!lvlum_CًJ0USZ?TqU4eYxɽPյ,4Ox*+Ѳ2@եht(rw +.$y>MQT~g-Y"FSv [yNӲGZi +* i̼-ùUOw%k ۪4j/3y~O`@ÄP?CJLHz' `Զ1tW̡W) +J@o6-z6CpKjmq/ߔ~dfF~Z`="t{;c?P[emAm¿ǡܪoʼXOY%zzߖsq~Z!i=Ko;jp(1|4V|3ca1h>-zI=Y`\,yt?L &He/!eZ KR^I:a}nSGvcuLŐ}M.;GggԫP]@8.d=ai^pUךfPUq|W1;k}kibN3+(JI,E -~Jf\S.Qօ9U"5JhWUk7r=2PcVc(LȻs[U}ڄ g;󩤱aɊcyHS=XqP,Z#?xk$w`eA'NV?ZqF'˦blGtPfQ.^gJdUōIHRzv¹"C) Ez4A v) +]ʻ3{~fHv!WJ.aV޶y8ST`'GN-”闽bUM`iwSTSgŪ[e9L9m[MCWPOh1)ƏXJ|TXi}g6g)g/ G{> /<΍.'ZPshbPN)C{qLM5蔆̻d*QzSW|AM,dܛ86 RuXYcL3Xwl'vTzsֽ&]N!>?|~V#[o_LAM3>U*0JGTұߺau +nOv3kIC.[j|H_#qg9Yہ *w*}c-Ylv:Ye<Ү]NjC#U om) +eK2smؼ!pU .j]Ut'V⸆i=cfuC;/y 61CKpfyʷO) +崋/'uf(tm62@e SASۗdچ(:.ׄe/ؔkl%+0^6ĆugJTV |ϖ|T;w.rg +1mN5j9eL/*eP[PtiЩcq{sF^r/V ';:Zi<ƀ:gcw,]3 Ų+~VI:YF2\܀4f2qAi> MU BHƠ`>nKO )^ʩ͆}㈗Օ$NKl/E}Yu+!ӬػE5*̆A!>TS3[*(J-eYRxJy? bkEb'o +u或Q<Mgy7"6c)^Z̞p=|<]Vd[+joKsV(Zfs^dΜ~>L㖔J54;E>#s aQ-ŷ)Dz_j +F +rgſwlVO-ye&[Sh)ΈBըؚ7ml% +bw" ]NJ (l0ia o\:EK&S7,j\2L.'N!fϬVE"|-%IZ~l\0AD``#m(0 s;BefvH06ww!$ $&suP=^tǧN2R l[@XS.KCۊHoMqgٸtcx[__~P4n_hGEB kk0QvԂ(x^VUxזY?}C/&gʯV=7 fm{c&Ҡ$aKYA!]J-^N_϶(b$vXvDN@;w=}+Ņe, "qȾa e!juz@u4 䰷7"N;n%$nuM^H{s$tQJҭ!@=62iL̽jWTpv9/ zwۃ&lt}C̄QVo6 u  '?N_Rhu_\%E .*5L5jXd>1-DNPҗU4VX"x7neO\$ίH 52WW5FBV`ѦDv3"*M%jf+Otsj2lw +@ +ΙA,4"(,Z8T[SBtޝ[ +e2b+~'&u/VLTb1b[Mihz/ } Hv`mkK}5VGRL{ȕRpq?dUMj-:aD-w7ZeQ/M;4\egR 0jL8"zopD묆kr`xmL2+ 3SJލRhmQZN^h{B:RT#>zDI~gĬq3kh>[Dɥ:}O +_zzMX%4v@cp6m>lT.e/ޟ9+RX,h[/!C@>jlL>^N|(Si2pnL&'ai4EfmkN=KoK׏u㼞J#h0}ԓo>Բ9oYX>6 H9(~*Xjdj鶅"friO۵4aY%1|H3+AXq[žUh9}z9kjP(]T72J߈}YX` +`3e6^If)kqf`AK!+eu3L H̓”˳N'O64i2&3wV _71f]d-#A֚pшh=$ TV]Q6W%2*h=fW#;N J7W.j2!犆c)ָ!eR:]R1bi;c#'u]`IfCUQmu[ۧzͺc$4y-^ bRo&UVâi=zXD3)݌as[LYZI;Pw"!+p5;GH,DSG=\!"{l BB+ؖKBQ)5mY@*@InJXV*٤,@cU|eT40~yZsҲY [߳B%|a +DS,~bJC6Ytbz/4d7n +)R6 Y2&Fc}L>&o#h")K6eD䠲KLˏR>fS݄"EFuCAuN̻-O)xUAO R k\Wώ/ [W#dSF_ٵЁ_D_S]Ϩr ;_!u +7yroe-.^Hm Њ}n1%n+!N.j+BtPho[/BVim^0 !20HY?;paT@AR3z+) ]S2un7]eˣk5U:]_15NZ+-n3P, }gT 4j UR?e\?*eS ,=a~ق]0Z" m1Ɏ*WMPa 3 RH hkR=\ފw9ifG^JDѢǺi[W-j$i-~L߁GEUHPmyTZ*D OޥU GZ0s na͋҉9Ŏkx0ۡIg)dCQ&opд_Ӭ6wMu"\^75KZZC Tc39?0[@lvus"b[MRA[):^o]w9e +y.k`>Ϫ: IR6ݒd }yWyA] q욇auR))+|بqR'UYan`ҾTmiz}s&ʝ"K82q +ڬڹa?L\-Ba),6c9fY U0h1逃n{:_jȗobphRN"Z/(>D@Y *ï˲ P|Tτ+ [-X^ ;ar!N1R jU=6wsHTnkCvJ&#qal䘱S6+OHZ鷣ud.+= "ֹDb$zؔ@@T,b}ł*LusiqӸ$mR"IDf-&aPRbeku*dJH̚- KC٧ᆬ;="\S&_Hw;ּ +DJeR(/W.[  rIn<=Vwxtx[kCCX9DL3 ೽Զܻ!y eH4Klcw:9zUw'^Ƚ:jT|4>'z=:TM !j*tc∫=$%Z%e#}eIGex>eWGotBYQ!ު(βl uDV{s𧍨TCK^lwx#j!ךl;(x#u9vSW>c~Żw5u ^<4 +t+Im^{_tYeU-d@VrDl'1D +=Bbk; m[FF쏻N10hST%;E]ʷ4v9jPi256mV֋"hBvŠZKHo>_;p=!6vkhug UM EZ _ <&lM,cec)=uMEM jJt-Lpצ P9Vp)Ea؋QWyR;O]}xMuVZX +t|_@ wgT5LsF̓j3RPXKGD׃P +n_ݔL(|=n{@$VGZ6ǻ2WFθCi~h7?g?y94T2j6:ywIk'M@$?R3|#d_iI,4'.D8SX\:0#IXcY|} Mn!t)W(,r9(:,OI1w# +I3]ĥqt$,Ժ@NIY2 w,+t.}wﻓ"#8yP>A^S$43ka7bX(_Iˆ, [A}Md6R\<18FK1eJr Yhmվ:D~]a8Zҍ+\=[SF;l˧m %{eƙدgW4#:f7K˸^BfnuV6 J=n¾M.# }ή a(J()ג%7f>ܾݚ}xn7:èPȔ{:P13ɕ[{-h ȚTX(E}j}I"*0Z05rᜅ_OUO|@L/}ـk "*Uy>,RxGeJYOw~d +Lg Pô]Zih<n疮Sm(KoOjP—nB/x)ejM(TW|Tڳ*c/nJ  Hr\)}6jј]R|>y źGͨl'?ezJ{B&T-ՕnYٳ>*mG6`@zW߇rH]I(5J4E4FNS6 iMт ;MMSDiȇhiKiK "j 2MQƌ4EiMD;uJ2Mq)))h-3MQ:LS\J).9hl4EI)db勦Eϛh(FESiR2MQ".҉9>yU)hiӖyV牦񃦨;,A'4%MJ)u?d"ES\&⒃w4Eʖ4ELM|JꛦT)J4E)?hZMQJ)14Em3MQ6\(;4EMQs@).%7i6 Sԇ)]LQJ)^)ya)o SܜaKI0Mvbc׿|.;LcSlT`x% SuL-`)jaKCÔHqi)2~O0v/bdS$IJqy1/a33Lr `0ES^0EJ"L%Q0E +[LQJ)Jxm]!&" Sa0E=LHC)y)1Sa!ՏaL)j?aSܔ)Vw"7LQM)jeaSaX%bS`X0ExI0EL7LQr)J0E)"'"/a_`J0)$TXv"ր/"R;LQSL1Ā)ja?`2LNSܔ)("? SDN0E)(L:o"SB/Sn SY&0%LQ Ss SԨat>'RLqSԍa0ELQ Sb)2$^O)=+}iM0EsaKI0%;LHn)=6AP`-^3LSS{ SL0Eb)fXR~(%Y2KQRd{{,E^d?X +x,EŐ2KQ,Eɉq;KQ"R$XR~I$4n,Ŧԛ%,E_,E8JQM HwPj(E~UB)d@)J(E)R$P( F)J(EJQJQARP" @) 7A$thm(E](EM&`RԷ(EyI(ERD8$F")6Z^$Ef"E>P&)fI=B!/-%")J$Ŷ;w#pIR2IMRDN$EDR&)jd$E]LRIQ&)2s%bÝER4hI(o"e;I!y囤eO&)do + )}#)%\HD9vy3IQQDR&)jٖIW%n "IRj)|I9#yn3JQ0hE=RAL(E3JQ1RTJRQV0QS@)B7H(E H@R$PuH$d" HeB)l(E{JsP8(EJR~A$.JF)|(Edbej(EonR=AQ2H+)}w"BB)Z_EF)ZRS@)fYJ=p7J5qJ&JRRDN(EJvE oQ79(ARTRF)RDѷi{7J*Rd`"lRĖ<Q@edJ#g"RDQUlF)jj5ewo"R4ÎRMF)*̝QTԿP dvbiwC)R$ǘPd w2o"#hv/"ʄR4"MJ;JQAߌRR+3JQQ(ER oQ(ob ˦Rn(E~`F)#QRd%bB)j\l +RnJW-JkB)V'׆RRrP)f"yJ2f]?P'buIIZDR4NRVERDM$E-&IQz'"ꉤH|2ܚ2IQZ")j*,"oƳLRoIQ"eHLm}J(3IR3IC$)JekMyyXO"mp,I¬/''IQ{U$IB𝤨Iњw"'hS֋w/H5̄'IQ$E!6"KDRd-&)N$Ehob )1{)H$E XI1 A{~Ih")I,IQYLR򃤨:)H$E$EDRH$EH= )jEIR2IQK$Eډw"E;I'IwLIDRd&)K$-C$E )6X;Ixx (5%l E,@)J EY)J ll)b)J Ed)@D*vhI/" H()x+IM\)B{qM EPW Ex)Rh)ӛ@(5MA @X& 6A)R6 h/"HE) RԸA؞'"q7HMR)h Ŷv"Q) Eg E(!%A$"RDy E2HhHX)*j)N)*g)*AF~c$>HR +o#wv"/} E1HMS)*lA4%K?@4A3A. HRT2'"7HnR E%RAA㷃d E;H6RDyI E EZs^ ER$ݿ4~'[~Nh Hx) E6 Eҏ&kdǽspYOE.o(6zsm(HE ?8NE)6.G2Qdðs/"Q1supGQ&siXsFEG‹7G‹Qb("98w3GR7G&G($(򎉣(%s=/b(R8p5dFQTEVQH1}  HN(JQDNEQ^EQ+2F=Fa1Ѿ,0EpFt3>"|40FF+F5aQFQb(vU&ŎoQG-Q&cń 1!% +`(.%_)EuQ;V9E59EQ s$"2vAQDaQE >mET(E[IQrvn,SEQ3S)Z$"kDQIMQDNE)LQ$(]IEkE)onEDQoDQ$|(DcEEEs3ER$(*)DE7E9QQE7EH_Y(xzShHE]LQ|_CMQTF(r`(JAQDNE;EQ6u|(*H?x(R(("'LQ򃢈A(NH!Q)aME~Pپ(ť$&{NȨ(jC)TgE^Mv"?,QL(((E=h(E}3SbM [E}h(ꌿ(8$"DQdgP8SA)S &?(zd"8(ħEd(yQQw"(ENQD)vċk(Ҽ(PE)_ExE+DQMQ4K+EwQa(R(:݋h6l;EQ +X' 6Q s$"J(Z(EQDNEDQS_EwvK(N%SM)7b(WmE+I) +G)r$"2Ęw$QM(NuRJEE+B)DEq)(E(IEE2EJ7E9QQvE}D(JE)?(v%Yv0/.2EQ$S7e'mS)6NE(;(8t&REqʓE?($OEQLQJ(SmSqlySU֟)5A&Er7EՍj(=EQ( &"Ǽ)LQu#Q,AQNQ<.Q7e(.(zLQw(|H_()&EDQ(LEB.DQ\rP+7E˒(fS!(z`E DQ(ME\dR( KE3mxQ k(R( E)3)dvj`2EQc?(&ESv)/VڙQMQ$[SiIE4EDQ6Q{S7;EQJ(?(⶙(I).'DQľHcN(JM)&E NE7E"DQlQEəz(AQ(++W81vHwva9C&Weӿ?뒷ی.܏YB <Pgkx/vc\e KNm| fP7(aQBuJXsQ]xj_#k q N =]vpYPPBP d-41]Yx@2Pe_HBKZB/>ccV>ˤgA O.(!O?w*!]s5(J^=-d7k$D>P,1-5y8pB 흝 %\%\j@ 9YkP(3=JL@Q?"8&Ϸ)_LbmbBr`mbca3 !bc{$\Jb.94k5X|1 tKIL%P,j=TSglK'<ܽtcwè6:p|!ybuXux!P TB)6$*^6i)$T ԱKa!WVh ?APr%;3yܔ?+4.?O*"x 9P +9m?XjDsQX'd[tPft `n)_5ZU\$.%A,6셵i*vj&{4Y(@:/ ".%l"w񰯊 aB7!Jܳ~ lUI!(SIs;(;C}u.-¥$@Gi`RJڤKxs6ҜR:#Flr) T]{P._Aɟ_V{e8n^Jz0M`r='A};R=\r,ßzHP=q Jy("q3nY_^qAM uB.[O1AݮtvT7tMm<3lPRTq\ 5xʤA54Bdun ڥ_mQE,Jn cp$gbiK^X.UI`(se J]XA-8}.vT)(;h6)}h.`ف=&)\r 5@w@ +*kggG +*g +T+9 ,KQP9I+/v|x-߹PrXf PqDřKIL%;SЊuoZPwWb +Ҏz6*cH +;"SXgb +@'SP + ,(-u `wu:)̲ ŜemuAO'TPJY}PP_PAU,v1&S`x/ aZ$ K_RYPA\B|A-;rn_p: *ͤ +V;Sɏ0 Uj2!z/QGʂ +~sAWl5ADP( R (HV $դR +j% +>22 +B9QN1%S-3$@A + Xo$ ,(hU2DQu& +U9װ +.z%oy(X(" +RPϾx |kx'1ĩzPS/"^@@R~:Aq' P)d$3 PcY Tm`*^ƟDT"ŗcNTn^ja8bg:M<WH"3/O}yN,`&xuf6X Pt4ԣNLb?JZG> PĔa&B (1ʶ6k +֖a`EIͩGqcS\Fb7Tl̓>6@ +mMkI氥Q쿻x|*qOZN׹l5p{Rhw4%F.wS4fASn )\]"n`V6?UXsG]6gw g4>S_4Fډ -@lo`k@nO ٺo(/#]a5":( Q(<+̓'Z~ҥU[O*-=RIISjy,,y&O73( !X5)v~1_O 3S/̰sH?j2O6/nc4>n͏Nd :>4P~ Ej I,K[M5!+5(h#if   !hyGxc yНm_?.,c:ǯc_;oLcUpH1:rӺRWN{³R|,731~%LdLx60~(uWh8O N%0~+cmGi, +ƯXK94̣yKf3YOI*? 52ƯX˻gaa'Wh.r]'ţW֪&SO(Tؑ(~Ժ;${'>LSiwqI8O5Q +1V50~aIxOyR@~q3ȏ ǂ=6$w ?-;hH+q2ƏKI+0~(cw_!cۻn+R*5wqI?~.&<1 W׾0~:8*c>?R1G.㧂ơO^?H( =s_?wbs +ΈZϔ0~ąCf?)maXCUƯXO/}XaB1~|ׁ+pc(L036!‡gi`i,r cd*aT\+QB41~?F۶SbQkrC&?)X?)#aJyTȆ?ǯvR*A^?UƃG>8~w8rժuSϼGkJ6YrMF՛F.K45mg\}qB}3NkWAQ߼UD@p +e)?jwgDǏS"&eaǏa[I?6E%9ǯ?Nǯrcsq]lI*G[Op)\U1ȏ +[$8Ϙ_3QA6M9~RgǏ*6+9~Vgta봣Qs >I '"҆񣲋j`Png.ub򳄛nBg2}7BAK"H~ֲ (?s>*Aӗ`h$?d"TM{:ɏ*GCr@=;ϊq0jǢqi4?p?c_u0i~Z&h~mMWJ~$aa(u'70|S|A1a)aTAualĶ_?z%_e_S6e-9(~ +v|O0ͦa%N9⇊}/(~(WG kZ) ⹷zTq|KO5Z!~z#~ k}o:YNG)`C M[2@zaC{!X'79!Pv/jBI?"~z2O7DYC~ 2uu04CJ ?#gO+$8~O?~$qT2O2A`2.9 o ?✷7{۶_1QfG]qx$W0P,ux;!&"?!@8"遧E&1 +|)}Ku-<N>Z^J:~amH?*(qEb_?u~-]X~<H`mnp>CRCO_V/_?"D>ҝHŽ9/v0o V0CߟP3¯~#ox#p 78eN;}D4g"aO()3>phFwl_,>}yD+}Gh>%7> HB*OQ^l`'a8dT.DS@ڝ#Kx1`}!dV*y3oV9Fm7P}yh4Eύᘾ{2rbyԌ"B=v ڄɴ<3|}s_̧Ŗud2RoA{(Fu}# -h+ʧU|'nX8n5d;ӌ GZىG( 㻣%{<(>%Y( vvRw?(8zUtnatnfsqnH=ҝ~t+!k@DM%LR/{{-܉z;DQY"+w5&&w^WcA1PTKS/UJSo_sf؉{g➒o`7nS7TcvT7DDw0#ړr;qPgac}Pu|Xor0zN7D؛j3qy!U8cd8zq^C,3eN eBVONp=6tYw8\o)酟z/ "kK@^qYW'b@WȜzIV̋vFii/d=) b{'~fN֓-L\' A֓ұOYOE2Y7@Bܼ|z4V_X`[ 'PHY&:0zI26D6^Q8\$];:$ޒˣ֓}ȮܟSDқ\NV MpKjI~?k[G'ô: y؆칋 kvp4J7 {DFݐ%hLT +]R箛2}38%_N;!T7%S?}Z"hS +׷zy S7&K"šn^N-'=U0}eR%J]Ү$!Btܜꃈ9zζ1yUyEDq+v,iVҐOkB'@~sCSor;r] +e<h,dp ZI1%ku7XlWdkYA`uL=js9T68$*D:0τ/6(*'$Hޯa⠐Rm#-cDxf=۔>0)£iҬoh6? <~ *]۾N'[{"$U)Qr+q9u +_us 7-g.. гnL?(ORT')t 2 '~x.\g ?]隹!q_SM}jѯA^ـ~ܖXbQ*WcMS {I,]ԙx5i5dFLh!h0- y>QP?=Q&OMfP܅tX[cs?6cCΆ]V(v*ݾxNO/`(\MN{Ovb*^aC뾖bUxkiہJϤlBuٔiMi~eT*\P+#ׁ !i֥(<-YHvs4j/3y}OubM4d̐F/yW% yXj)0,d"\_&})Dz3.Cyu/OCilr~S,-E\` 5z?RTbcx*-ޖ)o<,YW-Cσ-Cfc"ƌ>l2QOߒe_o%p* ڳ@iᣱ*Qe8{:=U%)V c~9%bN2^2=V's2; AhRq~)Ę!FV0oo>~ɮc)[ptFϚ3O^X7r"]}$VknDQ3'^Z{ yVPOXܻz["1%Vrn)Sf6C}!t`8Ycʵc(ʧs[Oh/dmˆ43MIcÔV;-i5vUaA %pDӡ6wcNE ;}G߅e_8/2#i*ʖ|vjm%0fJ%BԆf(pk)EnG)YHy6 SbS&P"|zhRRKSgޔ1>L#l" 6~9d]G;Tzio4&P2bw=LxKPl>p.1uW\լ_%.X ; UU|AM,.dMmv)`8<ĨϚX@FԩWUpֽ&P!;s} )pf§N~ +Rc"}|vX0vb4b,5̮>PC~[jxt-5|(&v 2QRu6X(&R^ k 0ցtlۂh)CT`JA#:k{ї@2@6/2.hNhjH.d:Wh25lJYL@.F`nr=gc5hkQۡt8 +k\ Y雿|.-UDj*~?|@Y]'X@MGO:M9tK!-MZ) ؁9qdd?͌x!#4w^" 쿱ɏ@jtz>.+-8vķvTR5{RXfi;>7\9|f}㖼`W%Z@!R=R|r-]RsE@*6uU<UqVZh)ΈBeTpEŏ[D0=+ך{-T:VF"uAMe,>,'j]g|O]\@LTY!0j&@gKIda:a "%z~w7l8,zh2RG$%3<)|ߖ R&ƅƇA1=4hJk1 ;w|EC@6JtMc#xRT] +XSW<; /F_L6\Fec"jWc\>Z +Qʊ?eAFԊ~wl@=Ss`P(8BG0ǒhOcdl}> +J{4e@Z!Qme-^@&%+qff}Bb"v +I#G+5^ c'1>Q b46Q +#*3فC%ucW J[W;p {rA ER/d#@6zXwͣwOخmwhZC) (. tY՚ pa-|4S10j__)]ǏG;#a~S珶R:*B&jcg230 5 8=pРm?pd O({s}JfDO+&E{)lPΫÃ[}a:2oQ5;ӗ`Xg#>Dp7U8#K$(MFZD5eEJ!zd5iM.֧-XXKyp˰~QH^JӖJ-{%)cSYv7^e|E!D{m֟CQ#~޶ XBJx1Y/{FY}wJ"ؗվ UX t(lY`AS%nvʣf>Nw3׳=JfѰӬ tB#ɸH%N%l0-P4Pvg2o},tran~°D9F(1UQ oO?b[{/N46I覘M& RX/?M<Z B v:ڌ)a};o6z>w!h0`6C*(d:2FEǾ S-F˺*^O5LBg?^:)7m J4ȷ˟.)f<ŋ:q* ZBso'62 Y6 +JKӖLPl m3 +'7o@ӫ Hh[TR'k +\A+:<{ j+Sl "w:KeV^2z] +yrV/]iRݱb8w&:%">f4ꄥ=샃YE"ԙf•qQ-x+B\X NZ˲Úh~B(x4ó6(J >ڈprSEt@8<໨\1mLXV)olɡqђqWb;e,8!1WQ6QX1̬qo=KeUZFܦ3m/N +ŠN4 TxBW_avxi.7X gjj|Œx 3ú^*6"zȑ)os'ԃX^b{Rau.*UH5̿k-96Z!/M4L. +& XxzFC 5+tPsy2,M գ),QFd9ԇA.Dv.O'szGL%x:p 1gF1-,|B%/[Y֬g,+c5eQ g.oyEzdXQyV>'vŕ\qz-`Ffmf;V\2$OeH5-12V.,?n(C}T/G @h2q b,e[׸2̲SP4-ΔYy%X (TI!+e3hMQT cVEi|w 5aSK&c93~S"BD_if촥'"Q"nAi2ʩqR,tyM2yMk! 2~)̦*&24fE.sֵEylr J!TZ٢+XZ,$jǭ2?Jd"NBhx&!@ mTc͙K`m?ͱNǚ2׸-ːf)Vɶ %clnqNwByʄJ6aft) ,V|:aQٻR2lC`Ť@O=a4CrGT пIy8fjE3Df5BIh8b5NbRMVw2GW]M|#& #lFgaE3$OxXj-BS夅mƭI3@jk:LvcuD+4CIԦ*y1ЦR-Su@1wPoMNvfF,N"몊B*V-{ER݄ 5 p+;_Wȿб>{5R bREPTZ5s -WGU; JSR$wp2 fr͠=)c'}eq(#*Ivؚ^aqZ\"t4X(zÝdq;F +:JLIƻ 3DRɢJ D{&NT_1kN&#3Tb"eֻ7@ye-w 8a/Hpf-;uYN*BuwN[+`.щͣR( Wƭ2`ˬO6f9]>rߞuSN z2=,^f;Z3<=n/ {m]e'בȬVW}P-[Gˡ}|+N4sB+Vox'̐d?6NY6w +t%_d%RJmlY(^7ݏ{AP$s݇ l`}y M>3$ 2So;=mrN鶮~uXQe5&پLuzpOe]&Ȕr2Xiqw[W)wT 4j Yr1PYe|g#'P[1f;̯UmbRVA[LңlnqRAZ +zVKǗ5ZfV lum,.6[Cu Ic.#tu$Ma/1 +@C-bel6$J~j;۝f~CBݗdtc.;f|V!HFʏgE>Z[,̌z!:Uj6Nh)r{h;K .4!ħpkbTufWh@9lƒȧ?*"EQT.'|F2<[ q +1xpgqք$@:J<|JuPB. +.؉QYQ(}y-uP4uҍaw+UbIl%6,uJ -zvP5LLw佴]BfSV Ybajt݉^rt?ؔ,9 j8dkᶸ5ZPCO xMu݄"GqnR +/TW5` h:hN@PC=Y_+nz.j3@飬rv ;NעX=p1LNpȶ9i(Br~fճoLCv, +pi"g·$EO3cS9NfPh#'e9,dȇ.Ybbxg"$L%v[Ib;Vfb*w1 4c\}yq1 ky0(B7użBZ]jHBUԗ*MBY-PcFJބM??;P9PwbT("Qbm@@Y+Hj@]ȭ0<|AI% ؄9A_r{Q &G)*WdY8AE5XC0Y +euH<`a:zS"ZխneV/ r=l7m\%_%xlsjOmu`$:.ܭ)?r-IFUЛUvXn,|v+9نlC0ٚP|ZGF5ݽ i;X[jBD?쨻-|qS^6HtkYàв* TP_a)C~;CǮa6۠N kqhWHL6̈.ƿYI[jؐ9ؚ}gyX6Œ6(S,LTѧ[,Ž/ @x[zZRpf5T/aqQ+B[#Ǧ*&{m T(pnCTc4fA!ŧzsS8+ܶ^nQF os&<6kٷx/ohʹ&XVRsǦ8㫶u={\P}K=HȂVtH.&"Ц\I :M=cut8w5m"όOUuICdYMq(B7'֯8I}D'nr?eZ"-jXK@YgH~hUSC 5t *|xY"R9YSdBszwQrrةϿx;R&\eߊ!-2& {tnDؽcyE(-:Ԕ35Y5guRnkHp*Qrmw1q-#GRچN\Ҍ*¡$)^,x0B^Nvz($˔:_ɧ} a>;󌀼uHabEMzKUN؉KJ5+R=+~j};0υ*> W;9 +*;Q Ȕª|oqOEN\rwvvf,P%1.W;-qI4۞mEETm(]Rȟ'J<@:@V2V=r!Qi'0bHbaXzN;@ -Pd =%lފ? +CFBAX_*R AR u1DGOa9`>\/ޡ~44MQr)V;M(h)V4EaJKM%/"%d_4E3MQLSMjWNurhM4JES+ +;M(91ױhd"r) ":{MQbch(7M܁(iC4Ţ-&&Q7MpNS44Б`,`i`NE;LQJ)J~)e"S\J)n3LzE40Ecc̔X^7QOaͅSD8E)XNMqSNrQ5D)"'\vlF)SljpSl)SO"J)6/b%(d8E3N ȿpMASlZ%bkN5Qvb(9d8ŦrSlq[ϼM oSSlD_qR3NQJ)6q;N(|)2qG3Ns?Mqi2q( XSʖrd"XUcDEr Xz:6("pNq) ɞZcDF7NQP)V:_NqS6NdoSDiS7NQr)VB;NS~8MqKF)jXI8ŪUb).%7qUѢSSF8Ū| X1pUySLK8N> X/&q)J8FhSq( )V6;N>N=)oޣS* q3N~\ HS)rb)oS$p/"h H0 qNт ;NSDq }w~@)N%8EE:2NQ8E8&^i)jSl|~'M/"0S%8ť$'NB آes)6٭N pKI8%NQ28E}Sl|i)"'"J)Q%g"tSqNNQ8S4:Sܔɞ7v>5~GtS\J)Ny<;NQ8E=ȆS8%NQq2)*Aqv hqJ8E)Ȅ)kM8E)h|ST=5 +)2r&"MNqSvȸ%F6M_/"%mhtzMih|H3dRMqASl7"+MI?&?h K4E +MQ5?hlMQ{LS\JB4& S)2~q})@gb)+obFSL%o"j)My%g"J)iUDSh4X|,k;kV LSd)J4ESv"cJ4ŪL)VÉ8CX4MiKb ڤ)֫)4ϣES|_4Eə(%+(/DSh)V:*4z/bUMS7LS +~MSw")VvKM4)$TXvbUESO4E 3;M1h!MiU+7MJhv w4%M]:h7M9d4/"J)i3MQ7e8uDS\ro4Em4E²;Ml).%l4&ZNSTMQr)J4:{%LSDI4EN}ShDS) I4z]hLԉT).e)Nq2ϔ4E ?h~ahS4%M_)ESԞiڳdT2MqASpiiJ1f"`8b{Si4Emq3MQ_4EJpMѺu4ť$⒝h䍦H;7MDSkh +hm&b+㋦ȁ(MB) +-u~{]0E hL`RLxG*0Fgo"AS$`;zqun0EŐ2L(oV6"0Eo"S$`Đ0E+ h LP+;LV HY 㩋zg)6/"RW%"=,Ef%"R\狥H0QK,/"ĀR4R5R$X4ML,EE~,E/HӬ7K,pb)YA,E.oR$]XX-,E\hr^_(E2 P(Eqk2J^Q hCRdM(R .$JѺ}%fRDyJ%IJPJQRԘ?JQS"3DB)6w"PJ3(E-{2JQ ߷h}(ƆRd!R$YJJM0jJwB)͓P@)jyQAdG)ʍd]JQrW-%"(ERoQ'm KQRݢ ~R`)YRJYJ!db _d)jSX,EHDRN,:yRTR$pXR2KRY(K>RWK,E]R$f)VJ;KRX:1uS2KQ,E52Kgcg)*XM,EŚ2KKQ[f)2K*f)d"R_RDYX=gb=[f)%Y󋥨Yr${s{U!XXEzL,E󃥈XY5XRHWgbK%+/Qdb[XbX,ZYKQRfKQѢ,EəXウQ,%[g`)J!9Y(bKQ%w^9KQZf)*{f)j,Eق3KQKQɛRT;+;oƨRTn,EF7KҺlg)2YJzYvb0`o"RTt-YRJig)*YZ=`)RȖYć,EəoY(obMhn,E}FXY,ϋȈXR^,EKw6^ۉH5+kc)`)j,E%3KQ7KRԉu~Df)VVm5\QX(ER@)&"3(OF)J(E}یRr[{Gw XRfR,̒PsP? XeI(*RD6,Ƥs&JSF)V(E)lM)/"% bUPR,ӇPJ(EUx}rUʽR8wV?PVu3JQ@)y&JF7RzJ;ĆRz0J~R|Qd!J(ΉRZJ~G)jl(z#+Ppb*G)e"rB)B)Q3JQiތRX K$ ?P (%%Q;J{B)JRtwQR2JQK(ŪeG)*PQ% (UR$R_JQ(o3_$E(a#)?H"IT") +(9$$EəȕL$EIHJ4fbERʙH~d;IƛXB$EIIERTg&)IoI:5/bSf23IQ>7IIє\$EDRIR~}$v/$E|1uǽha H RԫAZf ES;HQ RZHQ~ R_HQN Es)jA)\A +e"ohH#R$)H ERDxHq گ E@v '& R@L E ?@ RAd EvH. x<~$"^Q䷽9ȉ8|؋Q8go"=k8KIMC @MMwFQwEz88ĶE\@(JQ+98sE6E%3UEى:⦤2(."@.Qdz&0Y$"umEQW|aQE.lHcj-dFQ)1֔QǎQd0T1 h]"v{df4FX!nEE1o")„QDIEN}c%'"ۄQzQ$ԙ0Q'FQY2FjĄQzQDNEQķ(*0Y&"7F^g(dןob%Oc90a("'"(FQQlPMv:(`LE"r(JE)?07HE آ~(uHXi(QdOE"3FqSvH+QlgE:'"h ɎQ%EQDIE)?0AFW(Ql;F dld(f"[o"NFߎQ\B(n?p0:3c &?0 ^ŽQT|:aQ$>0 F c%db Hx("E;QTceU:q (aQF/131Z&<0;Fєh v(lE(12FQEy2FQQ(9cd"o"6F1)fՉok0*OE_Em2FQJ(nʎQ4y(f" nELR Z(Qz(FQr(JEyc0)fQņKb(1(6Q7F)ya5dRFqɁQ62ci(ʬ1\8(*nc[FFu(rd6oԄQDHE7FQ c[i_E5vQ\J(.90'FQE2FQT|FQAQ$,0KIEw"ڄQl*hyc%gQDxc%'"B(r;0(AHŦehQǺc0OFQC"`(jEŦE 0("'Q/aiZ߼/ԮLzP{;BC'KA벐-՘:>W_[/d~U?^ȿW.z!qDw]gh?3_o ?:/\j bY(xɾ' u!m?x} v| ugMr/z!|m%~酰ib^D/Ƨ1;XE/,v4?^D/\r 6VXB?ˮ' e@m# è6:p! bñ +Ǻ _(\R +2P_W/~7jS3VB@pMSoN)d؋~:; +" |g;W¥$~'PH#%E@`=a^ ?3pɁ/*aQÖEaz>^Btfz!hT|:`aN)9g x*C +8v/US %B4u@kOH3g,>uxR Fпoju6pN&Th_K]sKD8oP 9kA WRI(KHB}S 1;o .O[8 \r5@w*kWg*g*J[AH>TdΆ`̇ab*^Ӫ&ЂRM?;5V]Lrjq -8}p)>dRuߖ:x{e u'3Ž fF;ՠ+"_#bEB/RN.Uu'ܧY~Pej?X(7/ 4RɂAڿz}PI<*$lT3# ?;`U繾 +X7{e* +Ds,!&sq{ht+˷ ? I!ƝG4 O2U?D V \A[MA&PT:WѲ,O}PjPO _ABxO J}DѥAWdPM"[}cPO6~Za' ,~+p_!'5=/ AO-H.c T |"XAIPOcOc9UkBZtAXew$)H@{ Py@Sv|J1J@ܲNf_.Z +xuReRCATizЏZ"PFfwSNo=z;Xٸbu%#A3TGcw5n6 EO {W]dy,6`xB+eNE/ÿhJ<\@ g hE4 +8;'P-㴹;krW> yx4adxZʪג{ +Kg`dʌO;(^_$@s. +LZї˸P}+5D_@Eyv;Z_?%eԅEi38^ ᆳkQ[(fY`4s(OxZ-&K1+7Ʒ}=H?XN+ +S_Q@ASD`<%GdYWܜFDǹRvds.:v"[;B ,㦛? +Z'w~|ku,I8OZ[$a8O(64$_?(?= eO9l[Z Ʃyd,cն&"z)? 4H?m ?&֫FՂqdv% ?Zl)u);O <|9iZF[jpcjpO4(a4buׄgU$)k^.Ppx B?&~jq;OϬYHM7RɍPPT0yv7MjnIPp`μ?J񪬉m^,bki;aqZVЏfLܟFy`f Yp`b̼?d<{Cig_?> 'uQ8Äc*E/ﯲ/yKIdMv`IVa;dÚ-N4gWŝdpvp|K7ڄ)KI[b;X=3ƽr;Pg$0_W/݇d4ޭM!(> Q,@T⌑lGfB:,HA|B[XJXON>6S,ˋe÷/90|mhL>kDYsSLS +&)gotmg֙hƏp +ꨞ/ +-~- +)W(x˴ICz>$G&O&21|Zu 'W§M=;!|{CVX[)|/)s戚ISzw8O§`9\6v9v'v~۔gu/1Gk?C-{1̓f߼ՙ'GWl=Ghoz3\|cvGRS~f'[MWe1tS+VX۾|޹gGӣE |W4w P0$:0|I\>l\7_Q8~̪wL>x ioG`f&@F>dq8 );oASD"9CWN+K҃ħݴV* ' 񡔲@|$Oou]\ӷt"{wn Ro?O;n ' +CLB߶cL B,_"-%Lvk >|hx'r8Ouv9ÉP$ԡ~ħ[ze$>]1fr\S9|S Czp My'M8 ÷NRYzOʀ@9jJOac)3OSgќLÇ\cC˞/^)J>};?U>P:o gr߻L;!1|ry±ae26,ݏ3~t) &tP>E5Yf 4c~>6zdk 5`X ;9|s>C_}1|xJY>X Çl9laIhu +H>ś3i`Z + ߦ%ԖΊn֧?FS#1|7OhKs0|S +_iRzlX޵7Hn@_ /L$ӶX,CI\HOܪ9작iN2Xȸ<ӄ$z SDKFK&$i+QXHK as +$E&o +>7T8)|?K^՟/?ߺN>Eg?+;g +(?Q<p^J]H_訐+継oho o]02_jT!Ȑ2Qb&GSIPsH_M964yZ|PVQCx>34].,Q[3^Alqa/X|.mO'NpS0N7_CvVo柞>ɶx-}1UIۗXwB_2R6MH_o'J :2]6([P;RGq,Dbu0H(R&S̡x%JХ&/D +(.DE@ Ng:%`t〗|s VzR3AD􌊹<~K[a ,]DtrρoL$=PC,"3TWe^iCxis"44q.0"}{_dP<҉l0ҩNP24H+Dub1HO$1 60`Oȓp=wbr ,hHD2+ԡy 22 +DR4_#>)1UDVu[b:e窮%1gn\5'Ñ+'*Wr W^D\Wdp'f዁+R tYȲsPYYPQ6߉. =H@#38˘87<"0#!{Xt]E}H2݄&'h&J5q)UeQ$ls;GXvL2C:4 ˤE#K'Iqe 黖܇ւ^v$nK #9a6J{S%/ `?T۴Y 7ƻoǹ>vWݛ6T0RLo2l&O hEHGzI6r_oGz9pa폟vO}:O/#}DCO/۷O gEy#} ?Q7?l%O}lH}zhD?=?h^vD9xqR(TĶPV4P{B\͈ش7WQ_!wTVki LIw􈳍]7EՁǍϋ2;u2nh`LK)E![=ЎplBLBџ>;9ƃcz?Dw}.]}i²ڙ; u2D'J8_,\[I }>RCt; y) vRADʱg +=0r N&+Dm+3!#dk)-1L.b%GLw:yd )RS*#g `&+ ].4 +t꒓[tt2uVz.Z=Gف'=><.ZM4yJ ھA6eHKN +͕'mdXjַi}q@V8ѫ_ uED7ɦK5MwL'RJ88aLjcN'5TSK} 2\)э58$j"j6~pKV*&yt G&5ɔWWFZvУ0. c/J7`LnEƾM=u;R&Za?܄Džn3n@[5|d LH53%Z hܶm,f"0ϚPPiP^}Dc&ȳ |BB:s- H\~Qlph tULqɟ?&= o{mcX,Zd}8,લlL0S(;('/Dxt-P Niyh#/-ABSb +G66d:'|GàLME>2ㅘy "`A EMC.%T?4%p Yړdmև{kџ +W(grnzp7\ .PKOA U3˕ᒚ>T_&.O殺A)= +ؠ$]@WDO)TfGhH_\MEQ +w?qv&S,Jf( bzd|"ZŞ!bLl%gD: Nƴ0*>0.d(Ɓuա&_8 + ij9ƛBGkǦa[΢A&3Dn$s`&x]oӣ?8m6ux'HoEFR0H{31J:f(U5&)qa(ف?-2TWcGC 1@`&Ѓ;\.:HrjSve_+]]SJBDH!JBc6lSG16V.N)VRjBC nh>p\J<<eF4D)L- l t9YCthpfAk5uj"W^Ha4pe"% "XT4Y ?>E,7!6 +:6hϪ7=6:txuB~1ZGrVJDOeS~ٲ}rNhy|J&J!{Ә2KԘőlxH6EbV.k#hrP*ab?)8FNs[s3NJ.L7ƺ4QG!ᦻYɰ;ͻE1f( ;?LT_Z!]y 9Dw̜^o!XdsP(DE Ҭhe{k9 + j& [ÁX$KEm\Z9ZgE{\:G9F^+ Tiw!7p3%-f:Ђ9}08ّvYuY!* +Monnt< Stȵ)8YE]EA yc К"l]{7fje4F/.LJTt Zւ8²gهbs`JKIFE4Hp̛3m`#w~cL J?m8i~cVM.le[TRQ9MVm.0^2 UFQZYZ %}&J1%hGvKg#2Nlƹ>HBޅ{q (HC3 : P5%:t躡,#zB^en؅Qy\c̆CR:3!-d#.N郵 Hr 4/f*]o.M쐤^")L½a4J4G[e-\t3H!UZj6S(ќk$,0YI%Eӓ@ECfġI;X zͿRzDᐌHLC]S/,6+T#u鶾%AUt4Rօucbs.M52pa`V++ 4%@&c+݇W^UcoT Nk176)>yT҈ Y)dW2K2ݧn-c@5*CWA06@! +%KlMvn&JllP5L5 Dl\Ь ]s; +stN2n\ɻ>hHL MTk쾱pf Us*UѭAuPp;.k|0wLFf85W(Ƶ܆_ɓi:aFɝlWD)u< k)+&r5qZE+.1R9!6"b1Z-G,\HJGJJӮ$7[ +P\'SInbtAm "98#~e"bD" `׸9PjOƅ5>iT +h0Y A8-Ml+{ ~광ZjDTb28vM!jY9TNAS0>nDj"YRQ1Y +2M@TQ"ӈf|gzpSgP,!'=ZδODtYL#TO +AdqyZ닮Ө>sl\EP9'lL"K+]#3#YB B`䐦 +)':wAZbrX]Ap\]z23N}D: }#_\)01\\Ǡ1!PhrU31fta㮌^ԍYq$Z!O+vmpu"7 ՘8${Ҡ.tg3@콊9$i3LGAUX\rls  $ZT1g$5-GZΪH$Fb|!nqg1ʖŮjNOӔM +68Tul9YReU`!j $Qh8]dv +ڃs4P +*SqmYIo^#`75 +8j*gg &Į\LR15Ynag{qP+Ps7Fa@wZtL +f1bUN3IM6iA"HnxB6ɬ!JxU+Ǭ>stream +AZ"x%y^SZApfNT(Np[kQ.՗=fotZc V&h\'NԱA kăM%6P4/dbת: U09DBb4c7M:jH|弭N)ky:|Iq%xTаʱ~]7=fLEd|moPYAݬ>8# +TlPqа7vʨhE"aIk:y=c +ϣd^9i}7$u)8,8pdsyco dAl-`ZdP)H[Ysm [Ж~#э8VB:n`FUM `Z+Y G΍܊a_יkǩ1sZ.[?^ xCʹ-D$HR映0oD8s9FTr+YWi +Ь ҘIu5{I]F@n*HX)}t)(;Ӊؐ@$Z.ciFiN7NTuNPl+|Q$5pkjh&r89 feRHkef~.U\2aqKe>95˪lSIol!؉.LVrV#L.7ea$E3NH!ص݂#'U2qL'd%$KLj`5ߒa4QqUC%-YUI +MyAih~߹jg" ̾3oPު0xqhOm5 Q赪yyӡldLǭT ﭬ@5kn̝WϠrq6)n&nsp%idY0<ό[&s)f $y6A}k,0 HE)wWCRYB{r7 9G(\kcI[Rzcd8, + ~VB'W1¤$1ydܚc/Zȧ=$cDؗ?rĵ֪ Qn#2dpAFP5%Dc֑}T6V,:J+[0A0,1Jz2kSQSIUd- T0ш)7LZVD!++-qћkn1z δ9X-rR42b'6)T?;[HZbYՉ+ :ぉ#ӻOg86{X" (nʦg1K3no<F< 5L-}AubJi,Hu1ւ`G;?5"&!t=GE>4Nͪ@ΑKrJƊ6U_44cԥ0Vax:Jk1![+. ti)։I#p V7"Z1&n+ +9slh?d/4:4M0 6N +ֵ0F@ժ=ڡNPh#9DqYa4Nߢ Mw ?-2j0+\A45rĔO-D&(f\6*,{ѮbZb'F٣5)F7S2DBSǥLgK&pTM1mhVJO@h{e-"IQ60v4KE^ҜŬr+Z4ߴEFcȤrq6NqQc) ւ|wWo>$MuP\*h +D\DROYVg`$ҫLB'@\Ǝob9.lRiY1F+NKMqB 澬|wJO. UXGt*Ѥ-LNK^)}+zG,lSr|XZ(I#A3x8MnXRf8"fuQ0QS֕ҳ(": +E.SPp³gו 4P ,?IJ೚JYP⠋N4)K̛4vY (ϩ8(JDЭABчP* +`xtI漩A夠TMCOjhA]&Jy!Kt"q4U0)!^&Ix>xޓu4RΙva~U]a0C 30)2曳<~ !),! +Sqp#0,N=z`~+օ(1frHT"Q~F8tr^kIw(R>+ycPheJݤ&E^-gB9[: uXRVJOIϷ,i45DgU,4ea }SMxJiqr\t薂W_M>%\z ZtYYd٭e&k +?JfUok^ff +ZHGrLe.cjALd.PfHr3Rg宛qjֲXýL.̗ZaBT:M_YJv8v}LkR#^(y݇[ⓡ0qz[L3t"rh^#>A3$N'qwEˏ"wqi?ڤl=JI&E^GTv/A;kd8#K9"9YS U3"fY`iF#wGS><<&$ d[npɠy3U=լ1r4A N2Z)7:ki9"dy4KLTg2P&x^yVQkMP˗nO~,P.M:ĒhYwAG:L5 JB4`[N|Z5`?a0z&* f 覎Y.OJu VS Yf R̾) R g/{0nvzbo.,tR->/*2(NX/8,l +;?LjS-fFrfQOZ*Ti[~zNEY۶^fxKj~otIy9eSnf'RbFiHUS: PSVn\IptJ3 Mkjt(gHÖڈc@Kѹ/6l J9:I}g(@In$ Zʴ]z)w)dS̍ 7^Uk׈bS5zci2]ttpjPpm K$Иlg:J^1Me,զgх6IbbZ +9Nͣ$Mz+'o/)d|m|FM״.'0qL| +&vd_Rқk$?^2 -[mMhPkE'D91l~kq">Tvl(x%,蒰8{eetV/6H] h5.F}_ԪN<ڇٜ MVq͌_hZ[N+UHMEԭ"'c4`^n˵_\ˏX͋^擳~|:W9xqDN?r`8W oN G:^W>**J3#։'Ռ'>,Z+6nУe*%[C9Yұx !{DyeG?-c7`)'ȏKAޗh0cL]n]~@epoԳP2 :зSC7. +\$ J?=->~\\9 d*y}5]0#RKRz]AdnB Qכ}ҭcӑOb!8H-Ny>=%6i{6鷧z'i͚=ҭc_g+/>EkSf[em F: r w/]ѠFڝ2B5SK`32n,@k1TJXke4;W_^o&o/~gra p/O_LDZrs3*ogM). Q\@"p3G9^?L #\2!0ȖҖ3Ė5*A/L>zblXJNV>6hfcQը2)<6ٍNx@,зw4cF277?7/~k?[?|~ã_wW/}GwwggοzqwqCO~#s÷_a寏~N}ߝ]|q럆ZFه}sq7ۏM0m?ŀ~~@?<݀>]}n]>6$iH{c~|gߜ' +YN^yw][2ӷj_^z,qҧT>˗g7?:w[ߞ#_pTx³bpRx£b/^^?}_TFB + +-Ww7]k'W;Sb!/_}uv~N[{ Q~A/h{w٧\dy7/d{j4u3O>՟vӞx2N /)On/oW;9~3+Q^Yhۗ#|=0< L52v?ps0ÈӍh{FbD,ڈSX/G7;,>W]>f7YwHȡ\?]}}ygk->,Oڙw#p#,m?=\{;R_ʒ;پTًW;̏>:o='SowІz2 P>ߜ)Ln~vc{'vS(g_bQbg=ޱ}V؞Qܳy$y5';f8|FQ7'>~w۫닛?}gYon>nÑh[qӏ;>}9wGacN-Dͻ-,wY=N;9y4.M>'Wg?|cv컌?\:]\>V,eO4]޼ѻא{^n+Wj/EAy(GiPP:Ph\wіzΡ ViG.G???89|zN z?jq"N;xӀݾoxl~x'^{yqSʑS> }a w#z 6&#z$Z6#zd9FLס/G7;~4,%bټ7[C[v! ;=Dg+yn~˥6hhlhO3C4H|h>TCb;DG C U17}ۍk/=pquu9o?{OKoI_~ի7ĹA,^|2eSW݊ڑA'г=v{rx*Ϣ BW.J뻋6{a?+/۫.^|x{wvts|rg{y pTUm7'v_ ;!ci%R7He[o/λw3ɼ)}]7l۟^}7':x':xeO%n)rHӐvQPE7tXbySf7yK>޵:8oΛ㼁yy p`\>?򫻳?^1o;M'Oz!mڷW7_ޟ?'^s ^^R`n^]vp}9/^^9 [P6PPg/V6l1Z~+_^ XPXPWn_e)~*__}/^;Rwі&?ARew>r<. .,À*8j_}}g8 m cLԝ7F޾li}P^?\yG_Eϥ̡#:ԑygݢJ<Ӹ>}|~{u{o_^#&~{v~yÿ|y1yXl7n۳}>oWk?Ooko"%=}΂=9]ԐfZWp8GCT~Eۛg]=f_|nzw#jk. ٳ~K^xE5ZTCɋ}T.<[^O!+,Y|t^zɛWo7u:~ooo.v1oywhAA;(hOG?L6sPۗ3Ϭ" +oU*s'`;Sk# +{1G*k#GFz0{s]s}Bx,_]rv|8߉3y'g#:LYqfH>HG7ܽR~c'>s˳fP- +{pMN^g˙ߦv>GGȾ~89WwbR9kjG);)7ssodK$˓?3+W7O9 +g 9gEX.{힋|r_]qk+O]}8f;zn^zbaW7z|xR$'M$~.@>CUޝݼjrF:վ(oup3N^wI?}^d]Ywm~ސ޷;Б7U _ݮGBUˎח7ӿ|?Dg?\y{Oݗ]~1}x/?Oiţ?G//?i#NucHtpFՍ7ҧ NNJ)1Cv>ޞ4b?\s8Iq!ħRI;q !t[R upROR*(C-ttNZNIb%IL΃ZH_2 +!W.;}5hwJ.c8zC G_KKs'3} ++}С)É˱ w{7r0%c>qX>a!Cak~K]h.e}Bk_N0K8JH6e,%:9@Z'@4u.L`b.NL<(5@H'H<ܧ\%&}kqz ?ZcbPvFHD }UP]' ]FA-f|lCHu +A$Xyj}#xB-I>iuV ,7L Hoy qsSb"Jv5z] ؗG`0%>ep*SډkY"O-}2ؿ?Vj؛HKjt@2|Aig$=n.҅:WnϹ85u c6V;F![+}^<&͢ݜYD`Coug +3<@/<]! Kռ#od)'EL'e'$ZS*,~4$7dZT(q"g]e6\. Ȳ”@vFJ9$i#& Y'̒Hb+p29tB2it$S۸kp)_w6}ZT,3azGmpnp<,´4?O>Y$ n ؿ:}cU*:Evʐ`l|L 'c)W@>~x8缮z*; S\I4xf{-Oy6BLgp4">z{&1&zWUfvQCPb K f(6&t~AD$::2^' vcn!.S!9rT%8úIّzÆgl\&Y}`gtJO7{'dnTZȍuÑbEc-hb8.p( rg >t-  +YBpV$} p^<|U[S +)CT] ~d6Է?] x!LDuP2nj6ߜ(Q좀wfnu:.F_Swݍ|ʹO\c_369dwA ~Tvdw b da!Dڑ Z h黄*٦ ?"0 ,|b{NiYFւE$Bk-Z >Ϯ@A|i@s=Diviԭo ̈p9;M"&1bkQЬ]Gg|/7J B}og+_D2|1?`S5\=kS=4 ,- &dul;J.* +-t&Ql` Q摖E8Ţ'N_r$BdaU{/_!p<O6cAz;R*dbVheKtDLЁ]bSs4nlb+R+9t#Ÿ ,<|'1`UȬcy^t$l+RAsvR58&Կ:&)J1bzh2@؉@ޞ4etʼAœNnlTI?S }<& 8) }H#5K<ѤI`O]%;H~t%LMD&Eow;΋ߦQo$ + .B$g:/6T /9;~ipG%aelt­tZ48ua9E6}94M8 ew@]@N<%JƌhB,yn-zlAy zC8wcwT=l49 s +EBjF$7Lrqi]ƄgsYrvaK>$ !':`2rcJ=b#Hg@* + aAI\9-p I1(AD2Is" aaJl1#"OMv/2D;6A'hw`QpI꼵MkYqё޹0!iDgHERKbF̧ LeV#nɞ/9肔^l%k"&j:Rg%b!`nj)@M-Gu/$+ٿD0"BB^ +e-&~(tRD@NNl`&^L FCH `bšgbc8->, #s\9Gdno,I\Jda qKDO9Iv=&$Kw6%¿X?6Di^_k)7,e90exeq9 p0̑2934QE=D_z(uXZ- +f ( @.VE{ :.zvMlڛo ֓, ׄ !0qcH P8PF^""Gӫ7:Aa}l=E\u[.償#(DΡdPXD y"oh10N9`~ؿd|;o>Sb +*ރOnk%s":uqYdUЪ}'@i {$o=%S^$Et`V$VMG޻NaAGtHAy)p)(@L6m 8IA%btBΖ@2-rLRwb5XÕ|Z4-0O3`AKOZ25}빅YDѩy"鮇RfOK`0X t"+p,c"u6<īYIqUpUʟDLX $dTZ@fxs;%{ ~PPZ6E0S>C@TyF&- g_EW()`5wMbt7͛sXW H SN4а,H# eOP^fM5)Sh/T E̒2f#ө؛wt*gB:w5ccg17Dh 2((#G<"X@P VG<a/3UKaOeWdx}g(zt_#:LWd*KXXSC=8[*0!=l;<1JA)B &D@ū/IKFPb 7cY#!` ƙDÃ|8T0QBG].rܗ|s@1sY(˵/?dI3rC-h%`s>߽Vݱc?\1S5>_͗`Z s`98\D u9*mB_Fc $ qBe,zd`:sAFyɎr@Kƿ)FhfltOrFLط*52Jdto7\ST` Pe1 +:9j#!dY94U!^/YNBHK838fqt9Wo Lȡz$4k0` +nM8sųc+ ̑]tBˀ俰; PC,3f8:|f`9e"336}E0"c{"5#E+=])l -z"ʼfFQE6_mGau='^e7jg@Hzm\)sB63Jmg\ZǨ-Pl ŝ3gkK/e[';&^uӵ ?礦qAK`D~22wH%Ze힙*I)K& P爈%jbd 9t{`Dזe8~y ,@)Nbg"16R)fj9 8,?6Z ETjZPh ՠh{/]z_)aCdom{yf. Nu'ł3FAs3s}3̳m[$/ Rko|s̿A^ezJ"ӎ%֚HKQ,RA2kwBX]4%H׭ytJہs;qnِ:nl}κ8؟t(񴹞|uUzjkHeH36&YyZk\@ZF NBPY[WY]sG}wuk/Ջa>Ct!۵BrRMuiR js +~?-E)ɅvWb+د Lq?&ElT)WHj% sџ"qn=F0;U%i!sxV&,L+{"s:V:"P(h b2L5-լ+ϑlS,ZܛxLهLQIPZ+ +L<ʰÚ4ǫ9N7Tuh?)b(KK!. K<\ +A$7MI< t`r937_.N gPdWoή,;( +ġG둂 +k1Bƒ*5BV=ٓf _cI8V>.X.M Fu.z;3MH.4ӕž +a]pMx8̦I)Ad*T D W1dtLdc'IyR'iٸdX@0%c5sIcߒ<؅5eGsզ/V +䜅;ҍMD{%5!%9'/SqLQ]GJsM"˳)ID'!6FtJIwm{{ sgѲR ixՅ[EQ ߕ Ů^c C(x5y.g"Q:VW1jg7Qj%@xN|sjF @-uq|ԯ6|Yct?ŒTp\51*u5y€2&OX_;M_I9ٸUSj| +l**ZwaɋTυK&[ɬ:[MA_q^'R޵#M_6E~/@ /&ե zu}ysv/wg7__̋O df5Ӂ@@Gȕ5cJoĿ,=FUB:{ {?蟆G6+6m}%fWA1G_ߝ?4A sųkڦQIpt:Kl>^{ljBٮ~2|>}lُ9Z3b!ץhJBU{Lq|m` ׏?~ ώiu9g`ݏu=+VfGXxl'lC⯯3.#oHʄ}p~9 +G߂ӕ {5<-ȿⓛq"eo"̥疳cmȯ8.hG#Q-)kDGF)_L\=a{|^~_o/NjNFB ƭq=ٗN[n9lM-ntܕB~,d(k[]'ymg.ȩS 0h}$B%U %_>hNjџ>x%ͳ*,&_l7/p&~ #ך7zX7b'gw7׷w՛~pۏoo՞ +'w/_}zq~MFy¦8-s ~ +gF8&${ fN%1iŤF;{˄ oPcEPҋ^nx 2y~"Ry{Wck@ޕϚpkiH+@m~}ڀ"3eoŹdAnF ovh{alx=|*< Mۯ'JȒ}Ɖ)CrKZ4a[$57X8ܼ˰3cj^~G_0x{KU@oo_Z ޓ ;kHӆAq:_ +O#BTDz?} I7apZԐP8QԔOsW@t;e(++(% +PY+K b|b7$*/Gl@*9ICRreq+ &IOH)6v@|WCD|d(p@EBsVTҨu8TMbeTЂ&W$$*4;0SK>K2WUC{3C8i%\44sY@~*݇t+<05&28%%br;0qI]JLr )gH"+cH(2ːMA`$eڄ$9[H͂&N27R1aS*1a% +c +1P) +Jًಶ"HdBҰ)"V.)(*poC @%8.%) +/x +g7rv,&cbV_cĄJR Eu,=)Ԝ)$?xr4Sa]xwcwvח$j`L!"5gBN-8&A[&QbҎF 7`JB8;7`Q\R-kl?~EFvL&L9NMS\8A꣣ĊT'PhBWAYLҹ+5f'0xRSYXRҜ*dGAZ+KZQ,T &Z\ ,;|'X,<sgM.JBq(rq-pCLOK0tSnI>VJeSbv 5QPA[!8Ů?;j|ۯM`w +4x}ն94StFjzn\wN`?k˲F9yz +ZQOP2$sĺV5kպ]p4}s1@>C +&%L]3+ xQ +C0b{GaHؖձ3h +7*Dsp6rtr9LaTh=nMqx&96%X^Q嘗roCS9sp6")瘀X +]`|vcspUs<QPcxWv.; "TA㊪s4 i0۲$0,@%8DbCE1H&RkJލq 7ˆH&)R +l +U4hɃ@ua$Q?FZ]7 +S>iЊaEXj4ðeJkTh AA5pc +5wka B5K` ¨xz>1([*(z*GF !]A*(A8!!"5`r[k@u@(FB2w2)E(( /g+E@2QFN"AhYo5;*E猱<\h0@j SU7d#+7 eĚD(EVKWӷ3:JZ"`b,cB|ݱ)k L2-O%.fEwyHTqCI1p\1P&v]w1 [ro#;a;U1: RwA)+tңK6 t9e@M  d}\1ȤyNJх)hLF eO,T!9d̗M[3B=*YvuP !10u6d1?dr@ǁS+QUht$Q%ٔa6ݓzpmEU*5ʘWA!`~ +G#pb Q=dyPV*@=cۭC?`;4kJ ,GRQ:b5$su L>m#1*pqTmwȠe@Ҫ㲨$LSe$U̍cu`93cP͍*OhA%X&[lx1rՃ<rH(0xx`"2qwFREJtNQ7+@9G +7-@[4֙e!ѯ= Kd\_ 3/T4š<EO`1 V冷O{y[ ]:BA=%`uTeyB0uvFDFGDSZ|irNd>ǏA.ӳ''ap2.)s;dǸ |9I*Fݒ󥩺`Y1^]$j׈bWn<ÝCr! [;3fS|jzdݿ/^Dt}\ߚIdX&4$B&=8M4&gA*r=s(w3Ed^ikL|!I^$A D!9gT@%}nK,|  xS]onLE0ox~T̔Atq OyӺ^ăPdtJAE֬Ek@">O]oK09B:"MFj*9A]0/tQP% +ǡm Jr *M=V7iRlmnuYp?/ʷauZWC +$dvy+TVA9AiP%@ +wSoN|6BVo70X:]y\ +nTDpD9^(M8hTEx +P -Bx) 9'[2B]ex9P؞55ٔ +9$+iӜk@Ϲ)G9$,hs5T5vBG&T7yeDNRg`g⎼sUcȑ";Ae읋;!(W#$r:;H>7C y:b`h.7R#=8Kߜt}sUIG-2r;59LsaPwp +֐4^Jpθ 99x5aE1HpEPMqlTq3fNR塸 B3/Msy/էh5ϯu=n$IC]d^07g84ۂo.E9oΰ'RW7gXã\)a />_$9*5X@c$0]TYdA=އ;Cu.^9w;\)6*sF{%@WޡyEL~eVE^ `œKDs`|M'JǓ !3kɻ$" ,/|, eݙ %$ %>%AQS~Jv%QW䯔̓ ٗBE͹1$lzun%є>*w<Ȼ@gCP[,xWKݱlӋaە^0Uipʊ? V@BE"p"}P}DF)TIKX + cdve& j HIL@ZPҳ`kꛙl* <84X9OzqP(`@1O7.J*5 ONƃڅɴJ֓rqP@݊(t38w +(>5~QE#,"fY)PWGvjaP,_k`bHrE_FCA)@:tۇr_Sf2SRdޅ!v_.Ɵ, BC8؝ +JksQ$Zxs&;)d1yK%[g0GLAfR +\4hHbR}뒳MDBP(95R"RC m?P|@QR(p.`$jb'/zaڽ KDy5;gIvX A7ȖQ  Tw$P OF')$#&[!,kR 2 \%NAŦ]4$WHȋ<)%IȆơ)Ns\8,"sK!G3{Gfbg7hh?鹍C}H'$ `_&.cL "@ ̾`4Y&Ax%(*z.=|˸i&H3#X\Lɻiq9ҌH3).'mq9Lˑf,.Gi&HSˑ\P\ o]4cq9Lˑf,.Gz\q>H3#X\4r9!#X\4cq9Lˑf,.Gi&H3#X\4r#X\4rˑf,.GIq92q9ROˑz,.G걸Jrv..G걸<rˑzR\7I!鱸'H=#X\q9IC`zB\cq9Rr#X\cq9raAx#rˑzR\cq9RH5).'iH~ZrrˑzR\4ir#X\4cq9Lˑf,.Gi&hH3#ͧv't:xS;@.HO!nz5;gjpࠩ dφ4hN&jv푳$;IvJح;Yv1hnؚ@1;3vph}fc4n@/QK]C;.(3fS;NqkI& gvv)yXٸޔ1hQYz1cvb,54n@dvܒԚl_EP'/:`QnFv9Nn]P#Av ݏhzu;@2\u Icq;vL6O%P'D*U"J"/qNDVր/ȷ "m3;*P6&i&@)` 0?r7G"?4h=A$fx(mEtHN_9n[@JyB-SDaQ@@Ue[,0l3J(o R.)kLgQm-p +J:S(o +0TA`80!oP`AUNE{Zg4ܽV)l↔7;"f,k9 %dl IH,90^9^\ ɠY3I(XJ˛ ʣj@EFM,sΨ{ZM_( =e[IP@W2)薨-Pe%Bs\™ S@uq̖gh\NzKiR+آ!NSt7pmoyRA@379JX][rwXc+@FtP +)Yf;b+EVU +"[r')S;+@vEy>bmQC!) 林S*pl&D_y+@h2 B* *JD1op`%iJtz7I*z]Ƶk9HL>Qq7J+j9{_I=zaӾq ([j&%i32m$_!E;Gc kIH 8Cɲ'a9`531~:2!\YUH:hS-2H S#Կ`1|8idfa.K +(^R8D%F)nyP/.^4?!xI +2x,?o8?!SN$A3 i]8Q7Y1)o C+~ڨxs鬊@nΨ;Y*j߼&H>sii n(2rK+~kXӿ1sȣ;z#)(&0 t^ݵvn?'daNw `px|$*&3o\R, P'qwrǧS-=L>z>Đ\J/!Ē +elOqPƢ%eDk7 y" +qݑK%x1MMg{I<4xI|oK⇍CrttN%gMOsyTXpbK"r/ NjUH$[Ob1Fh'xy^'BQn+Ņ<&~e%Ss +;QEl-]cS2d!IYM*X(dh^R +D(֘Y.=s$2ZKq#Z=nuK)T')Ge7 Yl۲Ұ٥c-{'ٯB䏙G$F2a`j+YS䛢.2' Y%)]w^) I=@iRX0jM5mߧp&[X=iŠ ,Qpw- ~oYU$OH˛$&|.c'I^T+/RAK$K srEKCRn%Q}eR 6ѓqѻig!e$1&ʦ$. 9FFBoH $⴪bqgi% rH " +;f>7qʛb]Pa}Mb Z<8<CL} z8:"l. +4})Cjpm\J 1 _X4<.P8 +AD&=A14ScK +&c4Q]ԘQEx̎5^ "!Sv{G(4^@^O)Adl!l Å|β# c2!QTOvH dY^c7ŐW#Ǐ +>p47xcPCvX2gLu͏H)]AM؋A v=;hIɮaͻhq慀” ?Ȉ@yr\-tw 0 $CiWeI!dw6R(~J^R=tRE3`&rD5rϒ2 aAm **%G<0 ޟh=5~v9%2ML3{4۞rDfΜaF2'8\.]R|S*~>PkAVQFZ0ɭ_НP6~"Sѽe%;H(x61~uqfu( N%35ύrɩ͵3Bt&Pt{!cZ6=3̻e3*˰Z65 O PLt4`~rFZˮCP[vL +5ۿG7?aTZY@y(@mxǮ=adWd FA;p.Ҙ'n?md $ܞ~Ga)}r c# ؿ~_g,R:j8~Ȗ!ATԞ~u_B{k?9t҃nWΊ$]=K>=?}06^;?m^GY9X|َQ0SNQBa,Ddžl3}Js;-DQR}"u@jJ^RyFvv^@D+,+,BQS2P2 +(y +|^(,k| 9~wk<42A {\.`G&q;O@lr##L3K AX]c.xVbkA5CW9`gC%"e^I ۯ$Є}EFJVrr:KPjr}@kDLeZkH"+JL\bEDb 0XbZ&K?,K[z8X,ٮC-`~sctz!G([DPo,5]D De"Sx6Ccg X phGIOqVdk"z XWbS.cVnuI{PKvpC.W%#gZrC .pFhQ +P7nāV'_slj ײ0ۗ!N/wex(jekvR%\r?Dts((ETƧtMe)4JY ) 7.'Ë2.A\.? 8EsI0砠J!@bXX%]P''TT(+55Nxfr*j GqIA!X܂Z4 Imm_ w/}D&u藂XcNFC]-zHUu14q8pa%0YIx*pPDr/z ą.U g\昅 BU3AGkP^f\*fθ q, +}WW zQqvh E![!g$HB#9T̡ %DYnA\53X_h-#${*@,H@ډ +, ?L@a5e07P&a~ D[)0OiEY 1S1I싙|!XR%`l2  !V#4!z)Za,O"ZйS֖Rݤ +Y6TG0 7tN SFzڥ47OvGl41*H)W|=LkCo%e G54pQSf!rr](D)za *Ǐp=ٜYdEG w7*f@'@vVR 3A~ UF9QxW-.> +9GN *<aij[P%r@=?';lSKj]`fF*+1@&^a&䁱FX:T( b)&TK+[<1"T;Vx<ʢ6cvIEРU(\yw]ېV GU ,$?̌W%QPd̿TNE*@۩fQirH'攋-n G(maʸEǴձ& (xHqW3dXct7|C}3C)x<.Gs蜴*!eQx@e15܊- +iYpmRr؂V2-3 d1lHC9L[g/EaVq +}R=eC< V,t:qޢKNT16QqM`aLq 6[*A05gi* JbqRӃRa- ;,Qq@-1ejz+Sۊ5 iڴKEmJ_"~%*ǯm# C*ރ9C>Q c8 +M%2p+.*J* ҂#aY)<覭0nM8yEkR!nʠT"<@FKBr4[JbNMˣj`*U[//S/nZIx] d$E LvL-}Q3g% +;]P|sNOӯE +]n +)wDF6RhFiub""2&SUQKPQ.G`{Ab(%iR@ u:,!RIVt0hǒ|U[x+,8%dp{>1w.ϡFnU*0W@I{ΰ)|&4ɒn*"{gJ^l$,0@ |J`YT.lJLp .R\U؊7XAl܆iQϧbXRTxȣ"0\".Lb5!#KK2#B!FQ S|o"8 e$T*H) g >|<~BP;OY=A&+IN:)pD%cLj L) pYOSSAq3dd&&g4^RF]7 7P-YnEtMPhK;Og.3DdVdblj{Czh8w0AE"n Nd,T\ɽ*x}L,Q`*X @G$PKz7EO(x$n1(G{P-kZzm@=X +qAli,@LJw𪢁&H <X5;2yh#FHFnBShDnj&WfFٍ X*WD;^mr.͜ /tY6#%] 1^h[&6J +vEIRG`)@)eFZ,mA*YVme Z(~sJKlz8!2ᩢKA*ɾ2@%a\TgłQ-Ӵ5P`dSXƫ߁h +V +d 8!tTA├QWHDFrȌܕ R. ,͒0fRKv +!~Z;7tȐ?Yh`E.16:$@ʴ7"~RT,"*i甆+4ր!FAX) `WdE + 9' ?nC<4dxyT9[+b EBdkAg츊 +!sL¤8nߣ548 E +7`()$L{(5Xsd9T "0hE&v`܂ Dޠ)d$ʌIHB[}. $,gaۍN; +pCexv!INfp8 ++f>z1~k6Fv P/?C[I[n}k?Ss;vc~p4o B ZmniW90QT03rx*BIX5P ,w[#%՞ݹl[tcm'noD}Pݣk43i +Gƽ61h\n4y- gl@vSLB R~J#o7?'oW:[ [ذ-;FʻV]1D+AꚌ^+O4 7΃|É79F8t +.[|ligZצIl0ƈ*3'^렽g@Lq'9?ٟMy_}^ȶo0C`%z!5Wj ]8n`<1DZidԃ[?\Nbwڲ ~}zov_7FOy@~-n(33sV>rkWXԄi3O;Î lZ?ְO93khbWAcsf#O +ƒh[kJ  8O &=3pZE*U1& Lx{I)!IKJh|mhXƞO0s w_dv_&-:Q{f|y,>2eC\Cdd&P Y* SOk(>>_\q_hx~*N!NFԺ5 Jأ|_'IgŋzCI9e3(6F-|accǵ/C5\ Vp2OOYB[=l#@9=Gʼwcs b|` M'П4r6jvPӫi-~S{4jQ!5"Jk&a&;oB% „Q%bVV!A +Eǽ0ceҳd϶P::pWY|c3G6T2gl ٲc{a2m*fn>'@C<PJpxBޓ)"W4kXv f wI1StĎSmcm<<$[O+vx}i6_Xv[dǍO[.t`A=کntŢO`Ը;;ZNF9hF~}urn{.iع'8aAvo nF @n=mYWZ97hX~ _E,WA0 ؘZ?)uz#»)[`\F^gӡCFT2n{D1 {M{`9\ӯI_N6qEZh<;N>_RMR],ps{Wiq`9\b"ӡjvbEYRK.әվ/-J`+p7w#T  `> +{}8hZ;V +d9L46090qT>tGvnǑʜkdB +dߘ;=pn p+h|Y4j G' ֨؂ aUa਋15z&-gwﻙ˨>E+OY=a`]y;q+li;wm3ܷ~ {;?;)#(1s>}>L|9+ +6N:9>ÝwOɤ?<p&xNL'7^ͼvxj:;)ʦOn=Q)S{r4thYNcScq`/{;>vǷJxBg\wvc,{ +_i;{+Ob[9OljY[A-ݘw̓`L9~1OZ4=aNNl>iμ5Yoke_Mrd鉄5O&Fn" Nm)+nv?vox"YF#+ƮcVi:<:I 8;lx"fCTZ٣r)A&74!Hi5F5y[`:xZ:VX8 ʎr`%j 'miXet֣u4_Zqf[ <ݜrG^χ/L֊٩ZA,iM=in4[>|z=luʂ8I@9Ke<(:餜vS$y~"L?˙Ϲ/c={_m2  ]W+HݘW0U:ل>{0 }I~.\pa4lgy`\4лJul6howz|׳1pS&u[۝} B¥FDQW-.s4PPc;^hRXM}yIK@HDofXZ*{-QGO! Sc`Ejh8 Mas:<<%N#&{ :'i]ef6-=5Zv^ 65$5l5߁p[FL׎'C;SaOU5D84uɆ;@v0iϮ1CFMF ^X8>L~oCg):n3l>B.mz{9<*MjM' )ak{&Ә/ӛo.{d/'k̮sxs K);#-NdH\w6-AT {*P٬?Ĩ7Գ X6zNaDIڎ1g' 91`'s!DDiԳR42/[ƞ?p䷟~=%b٥O_$k~znsQvfypuڅ婻;v{{w<+滳wG K`m;QGvÅ{o-߹n~MykS}mO-w7n]PzمKOGWn?}p~v#ԹOClU :y`g{ΥGs+\`_aO/\LqV(fjn}_\x]. Z3\,̴&Gʅم7?[VxU~v{ӝW7-g4ӝL9hqu/0Lx`;L}\|l!_z/}Kϳo/]wnqGnݼ׷~ƶyㆱ) SS֡U[#̜_|?lm.~;V/֓څOVw7:f^|G}\z'>V?<{={EX~_;0`ùՕ+/<$8\6_-v^fol~|0:_\ &f<s]mK/w.7,f˯g7-\vu_Wxsf!`51ܝ{@ ܼzx\vsۛ4#z^xxya?_tu՞}d6K;@t\;yaoiX~>Wv4K׶IR}l?\m>ڹjjq~IŦQ/]{xd&G3Z[ֽh^ʫヌnaiv]ۻKϧW"i{Oᨋ3w{Os}<;8\U._.^ͭ_8_]gyyqҽηO,q{T˳{==L][|-?to"w  d7?NvoS~-ԭߞW Qg'kPzpf^u_m޼дM?`xynnhSbcir0;ؾ~,>3/nY]{Sb9u/K@ ,t;{pW[kS whHQ$ng󈑶ş%f8W'XN2 m>}[޴zjgoϽ^\_>w ,t/VY8wKHw[$cN,\}hkƃS]ܛ|dµ_K/DzO/MU G/>m>^zoquv` H_|UT.m_ۜϯH[{+Kȅԃ*jŒ_A]:xgG`b @YY޼+4rʼnPaqX'ۏA)=އ'>S ]3~Α]pGWAzֹOn[ ѤKb+痗zGp<$̫^y0xm/~0׍?<Yhk-[9lvWۃxFCa˃_.XdT[ښyI%߯P+|e٣Í>M^zJ,7^^ھSc +$;O..?輚7O7_Yۛ[߼ + w `肹5x@ֱ77&Mܼ_,Zw_-><"O(^]h)/FZ].]O+v壕u hٜNv\vݛ܇rѮΥǏwmnyŽ+3W07_>+ů7VkMn^v,]M1a=]>xf3FKnyO݅͝_ީ>^YuӳEb#w5-AyL؇=on.vWLy#ߞ?c[nO"$ahwF̭^_z8{c0yn7fpٹίJKVxbzavZwGrV&QIqnisQ|x4q sofrKܟf>Mn2w囋h:/yly8x X +俴w.ރ淗7^Rk. ȇOw7o;ӳ16{ 9Tq}l~{1rohp˿\xb)o8<^g_uCLY/Xnsfqws`l :o߽|nМ@G.so@b(|K/?t2i>/޽}m*'ӗC;@} b[P$ѻԕ˥xfVż7oO;3"ᵗ'ziL޳;} }?'!B/$$tHIH!!Hs}q?l ݓaihXd yL[B*Tk}VO&CgU|{7u1TO8:7 /"/nn]T6?/TTJM; ?Z*Gj}|ۆ CWwm3B, 3 bdBK!8gõ};_zq6J-*{F=|[I[ +pyCDw! +,_ 8lsz#UH `w5K6LP4VOX +pLzе, 4B?\{% +{#g[5nIƈQ"U`vs/ZOծs*0L}S;{Z|;sRՇ|V}.|p荻'+O6 AAJw3d%g11A/Ǐ`2~Tm>O'cXh% қ7OOBջuQdC*."PՓՉm`͵[i6Bøi^zT;Hbr`ɽA,TinK@7ZIx+OZK]d̤OmvgW ٔŞL60mhj}S UH2䪬fFq^%K~v~ {[#ۿ3fpĈLd3Γ <2xi0s! Ǹ'v`q_MJ;-,DLߜE~mH%*֎+ɗZ,}ՐS;ԓomUA* >ucN!ӯW4qsוZzvϞ{27j{d6ڥWNM(DE:H>]`W3$J tO 4{`AZ$1~z[\t6rDA^cHLe|Rx2\7K:yˆ]QqUIsT&m9S ~!;3j5]k7+ee{Gn5YVP3uG 8ol F/.~~5򕵤שNʀӗJY:T + Ex:EK@~[<~Ya/'Z#$ +yKn咟ú5Ms>-Q0>*ա)/g!똵7} U˱H_>;+*ЭϷe7Y9xߗEQS9ۥkS(H^_/=[.Oy.*77{Km?}\[%n*8.BMGiU`8q%H{VOH6tFg|@||~ǯwkQ?C<GXǯ(bb$a}mWO]^~tïd +hJ|Z_5S)CJI|퓯t5MU>FZ3>v_1+6R)/ q";~U/0gkHܳXْvJ"ߜ/Oqs.VL)QHY{dq ۏ&iH!SפC6,5Bۋp([w l&)mnV:h dFO7U)W_gzR)ӛ?F!6G~@(=;L[m䁡T\TUU޶\L,}n-5C` YZV"N\1%kB5ƍ=?R8 ݾKwet+<(mTE[S\JNG?.2\8wW9xeř K$B\bK$!vyzW ЗfS>SrU +\DLr+ \|KTds5˥B%.}=2W.{Ipu?I'UNmsj:4;gos]n[j\m?qB+|~lrKnk;53E[v7R n?nqhkGY;{ qg_*w~/wyָ%wsۓ#;=ZW{ #uM K;h) şڡTye+7!~R^!}7?/CXo-χGZ)C^h~G|ڿ'ǡ]C#:tWK_-kQ?i8s6‚JTJ v<|=Wv#n/z& 'b+;ᇧDu4yX~ŧHho1K"n9¯6_# +?B󛋔+B,ҐNTl̝GzEqyEnĕnk%mzS+kJKF~Nd @I%T )ryEi]W~IMM&K.4Z)w]wD䥬jFnZ_ q6wxV#U\V*q媵z[k|Jo_wmrv7)bP>.?O*;lebf稚^%=/b%ѩN_ܳQ}xkn~u.X+[J"N'7xYnToj|J7 [Du}qWz5ğ]xO +Š~=i> `/֯EmŊNBNv +/qEy-r)yV/vOee/S[ݫtyq"^xko{]=赯_0)5qҫvx6?vGh;=%eX?X;~oɻpt̷Ϗ6շ.<vNDsNOs}%t,T^*zsIDN}۹sxnm_DBx$/S{[Lq啗wEKju7{>8j]}k]{cEKvz+.hwgϩwSnweocw?]=߿=?ٿ'osw4.[{5zp?N.6<쯟˫RqqSzDii(z6➥["_&V_*eik͈߿TV=;Gvk۟Ƅϻֲ_ -{ `~s 9)^Z}Xy4ۏhi݁ lw=(%4_D߉˸w _rwoҘUq]`H \^>A֏K#&Y*(7Zj6R;󯄟Dy / 8~"?JǿʣQk{, S3O.~d8TT39p~Gspā<;0ʛwSJ%qN2u_k+߸~*~ޖnvW-U=-ryP7ʵ l36|f^?=nTT3FP7^P)zɆ] ,fG{UyNnoʝ_3]Pᇸǂ׮jPNph&Cu{ko8aBd. oh3U/j垯--# ×zˈUvuqcAE ׺tP+N`CowPVcJ{jp$P/2u"Ćl<^'.$><nnjKZi6Hk'!O'Я=tYqAE0Nz=bB{QkP/uj%~Ąz_9Jq.yj|c ǗͫL܇Z6J IzIX!p.$EvAq_,wC|EM)1].j#l9b?h8gO[k1a_L˻TH|{w_|"d P9H+ySl.$n}]95WW9>Nx]oW`ĕǯ Tybz@Յkk7sWm+A7DZ{nhc="1cS/(_o>==_H;]qO/+u_oVZW_?jׯUeEpkn]&' -Z->xv7BׯEN$WדUk9,Ӈ"he>vQ77+Ԧ{Z\5صA.zVҕ29wTPa,FBXۓl"?>R6)ùPw8د* `U"@2POu*#mڹ^k6z0 h995ӭ4ǣʳI}&(/)ltoC3P|&ziqQOMǦ3rek!)`/*zU-xlFz2!,ֿ#.O0R2s2 +>x`vfgy`}Ek/i!&sp?7iC4ڱo+++R]gob@;i1\o.)AxWj?ucΝg^dBg#6Gs&=Wzm{H_,B/Pфd6m4?4lWg BsF\%΍rr a֨wHroǡ5%RgCc2"6!=}< ӎ'q1q̲8ixg(L%g]٨Ic4_0'_$j?e3- ͽ3$lnQYg:o5|1TUxO䞿R xhXCyj@yOBgw3,B\166't'X!CKOm`8-`5u +ہ2ɛ~۹1l¶Ʒ>Yx01~JdUAǹ(@dqp).I[;Es('LwcCzә4'KkkhL{ws3_)8 k8hFΌH͈n#ۑKǬYbm͹1xJgϜ훜x-x~"~i.AB5Ʀ!9T %!A*l1= i@LqjfB6L}jE/Zcُ49rY>m!W';SL}"q8SF,uğ=ToVpYv8l ++`0&o\nah +s+BjP0gs5x/Ir—a01rþ>L3npu:l3ms|l;{)֦p {qDL'9B6?vk bYIc6cb\bm*ny]L2ǵNDA6pI8?f;@ ~KfLK.R͆-N>b )-.1yq9&g%wJM, $)YF{E +@sLq3]8%'ASs1#I!uA"ƍB ~% Kչ#w(3;;"`䥅yY84!:7oAd) uY(@9(@̜d!s4G[瀣MǝhdNO_L2]1G3F +=$7D6xKq[fFͥ^7?iռ漇.LBL͓ -(MnT:d t)> 'ȹi,;Fi$[w1Ȭ\GƼ/~4Q2lod:| ˣ +P&qN汸G{ʙ +pqFi3 4=5 ++ ay8+3Xd; v3@.?X#͢{52?)io&x3dZ>ɂ}b%EnIUzOz&3N,MR眘w`I2h>?Sb?8YmLi^^Pޖtg,˓,|FμΙbG|2 s̷%'|5eR3M# (\b6&|k&-JM0)\˷*] \7B&Q.r|19gr>WK}6dM6 +w%1Zbϴs(wpJV͝:Cu㩨2/*Dp-D!@OKٰKܒe䱭}T-7Y,ל6Gi3ed6Nɼ%-z2Tj{w0FfCلѦL(MIa96pu&M{[ĉ SF;NƙG՘\WEy3O?i 32+Cn7f>5\ +chz1Q1ƴW{֒={j\qi(4X7Fzt\4;Jz4b!{PESJ\eYQ\j)gӶf:[j_K wCc[n1tI rI;' 9n&b?yA^;iZNMv{={à4<ޛxoH|^ޛ$'/Zv=O 9`d;{iUD{]NHmQНa #兼ꘌYKrf@~<}~PNމHnEh361h4MuBQ#VC\&ŀfjI_zw=zis-I֌fv\دn~cx֩:ǕjP˥]\5څoK8ynM(lBw}~߷ӫ/zc[۠*ɕ5˫lz9W¥]췲z3د1lPS!Twٝ|C aE;! 5U짆?ߥw_bRǤbcO&zx*{Txp {QA]0)^{A=#(8&|$<؏Rlxn\اR\{w Io۴ 9N/_﫷9X&cZ~xsČ`c%V$~sljr&{ӳoiʽQ +\s\C.cp,Eq}z/UշMUgB>HUgk *cU:/c XYHaU2gaK6qQGH[Xak<)cUM==13?WakIco🩰9i6Hi#2b[3sj5Oa?)[?Y΢r]Soߔ$"Tm ۍ;qzSz QjלfkbzƌsBOfi2m$Eowb]`lHs<üώY/؞?~u|.etM.g/C9?|^v<7ŠKNsl-nZt9wobznR7G]ҨtwbGvZ]zwgJRc$\"|,ij܄cΔ.0>/`ToMdT+WT+OvS +NGR5܅d dNyghvwH.h<ږzCͳeY뇱}KO=MVPyH[X8 %X)qyNKq֚\1۾ RB̙J(Gqjƀ4U7 z@82"oÃiUPFdAqRzϙ=Ŕ4IWR˟hqޮj_!4l ;,hF. B0S߾wg-մEpb&xz<̊iWx6{!՘YT3g+J}3PLϏi~Ꭳ9|N}(oa{RsZ*&vݟ\He7K~&J;;baj(&]TdJN̔4ZUc# [s*{'- 뫾j0}\ϐBHHiy&nyҨ/lE\x諬t 'vH,i.Oo<?%KfsEWѝCs)YNߩe>Mq>?*?'i1!W^CLJͷ=l?槺˝n"R<^lm%C/)5-NlɉO?'5)J_{j߿1~5w[3Pn/uǩ\4+U.>#f'zֵQ;ƣb^IxJf`7q^a?|r~\|s(?ax5~cyU]L$\v|Gm˩,nl+3Tz.BFA])Ukg~UL-߇6skۛjWO7.`P?9,6T2k\zE`\HiX[n>YW5(6OOSՓ~g8M}q'crВ)9E3E${z|vчխUmJzolm G ` +Zb8+!YV/?l?"urfX:ooX?l 6mD-&| V7lK&Xf?d?|yl˙jcӇP["ݛ]~]~O~ dc8&sd#wjYį핏j]2Vl^#r&Vt*#tFm.v)(R& +`F|45~OsXN^YwBKh?*E_g#/-|Z^n|JYR@%8Asza]3Hh1GH77+ö@ 3|Vwp+M܌`gԬ 5ˢ|iFEG}>Zz}քF&CS^ohG6E[O*E4fѾxz (!=nQ[קo&{_"9zŇ#3{샤z'TjrU;&!NғigWJ~c m\w_ZnI%x0 > pnGx\_H)Xxs#J?^{V*=J01FLO9HJ1~~n' `lpl,I#zN='j4"9IIc!8#e@i +I 9.of㶻2H}JF i<ؓk=,2Y6-Mjdw[M׃vt+(B蚣w'Nl*z| :鹅NK^S{.*FUKW|X7%8pE[Oհ&@`t,9M]CHtr~,X&qz?ebQkMV{dĶF  i^Ɍ!j7'r%'jΉDߥHܴ-fqBu^ݷ%DCڨG:?Dj*b:1Qg CTTa?KїcHCo9':nƩWtfk"E<^/cɓ9Vs_BѐR16ͩsK݁)ʲInG^3D|~Mҭf4_3JfG)j^pNጔ" &07! 9|Տ'g/Xv-ݩmxkmywmӾ9ץhxKm6hZ&ϞAs_e?<|IתpwlHQ.٠oP`mEN8K2F+s9N#4m;X8BDzp"D$<`q?Wj/Bi >=9d5δ~a  +1cEl0\"yDZ"CE8Vd;7 CNq54tbA%p[qr+΍u\UNK.Q/.u]\Zq _;kLUAf ђCWMN]gX#q}TOKZQ1O[9c;kz8^#װL F?Hէa ب^N;:EO'!\6utFiޯD stjJt`rӨ5GkۿJlAx-L4y3:iT sDZ%[>cZU~eI>ChqaS,dg& Ҳɐmqe~3OULx1uR(zp=;e1vΤ34 43*nban{$sr/1};$CfH3|=o}hVm +t%]NPmag\ۇJXT%}x,?һm̑rɒFh};d~P6'XGٝ)~_('ddB;ÊKoSl].;ord) W5$g\[yz%v&#mc8/.yp@1%317mCbaOO2!1ց3eNTclLMlޝ&7e{9R-% 3&SOnI`ECh5yڕy\\`s5}I6844{]8c>C2>S0Le?Ɉ]7Q`=rRE.~3:eF1O3:?@-_etG$IFK(u.R6cɪDAtz +eF#2:hQԔgtLM5qf; $6QJ (et97W}ziwv|XA$Ìhͅ< XBƂ`W0a}h 8qӜϛKzF*rfltcCq%#S h(FmW|g4mMښ!Y-cȃ(GWS/R=(0"c꯻i::]i딝ʆ6$ӌ=(#K:YB#TW$qSiITW?TzkQ?$أbe?T"UVc̑uL9դhbz:qJiWD;Orj%% +pWJCǹz OЕټ]/ob@W"q?&~a(t[p];y~#u ne/_XD}YT`kvqXn} ׹br>stream +! ?I?YYmçWh?|q//Ku9+e `2Had5Eӗ3bdU[na5UFg- U7ZVd\TIFM̊&x"/d V'˒L[լU< . + PAUhbxJ,/t[f GOz'od%ױU*$.<$:l %+KH04G.2<}u@G?|Je3*F1UŬ!aM0AVX;E(kYAQ"D2  b ,1+inZ[' 2&`]ˈf)+ @f5QJVl [tEB,ɒM"VвO%@3HU:@:D'+8F(tTYPU$MT,nKdix%/geE J{*]tѹMZq5`[m3X}ēZA<x2c>BN$E)YYd,A!趾H2`@Wp]GL6djV5*` +V} vyjʨi8g{_MȪp@FMd*j{GHyS82gL +Jae$Y%Q@&$:Q}ut1`nh*æќ}o02j"Sэez)"r<|vrbZ@Yfsб9(KLS`ulءw`֎3wQp ڙ,~:81l? GX=.)Q{q!,Ka}51scڙql"ۃ k[3~~}.Kasptz!!2I&F[x i +\ip+ +.DEp7@"(lbL Rᑓ!#ǟ3byw<4 ,-g+ 2bsnr !1i`xl6flH +US5R{rvL7C³58Y0:0y FTt,DqlMm39\1)eiJL|cdl)ò\b!vC22SDC0,ed~d^F>Sc+}li]\]/P$k"E[+!E @#% +2A 6,3ЉNejdG +/Cp2bRl,/,E5U +Z)  Ӂ}uxW!$*e5Mp#,WҁՉ6á N/1PpdJǀy`/&?͐# /N%A ^6(ФTՁ)ꁒ) KUl"ڗ}e:Jt%p828IƣD0pޢ4 X9REN$I d C[2/D5|lMPa(5IAE l-Tkymb&*`k (I_P'Eښ=nӣM,'yh*2eD<(asMPIh% ,*Ҥ%@mzh+6))xR5P B@}3FU8(U+yPpZJ;zLFC +L44@@{.ۚ/Ra2I{AGWq $"alBw 6 M3W!'jPLдՀmJ%Z Ex(ICǐMe`Jf_ZUX3xLMh +l73;x]lUjp:1 TKi CsFkU`/`/#B??ۑ5Tl|3DL?-=@̓0rut{ DIh!iR]"32)KxիC#52Qr&>8,(ؚn"ٰCX Q4@,kĠ!+CBv B԰DQ"" p8B_Ĕ} 1J#;@ؼS,r=x/聨9A 5"H'`@Dw4DWr2P0bT&E "=("lU hd $~029(9ÙLG$kTGMɄGiA=p zPO&>Wɠ}G.QUuW sk~䄓$2|H8K46e*н892}P1iĸh-uGfY3H"u +-iy`e-^KiF#HLbuz:MPTk)NP:q"%l YĘa +5r50E&K$]APfG#P1Bm +0q섬[PI + +=8M\(i 1 . 2t`ӳ (24E-:{I_8*QhU4Ƒ$"'"xd&T k %k <\!5a!2\? ]Pʊ$tTq RMVQ2]:@. բFChHx:O05Ƭ;Ñ yr k[ͤ-˳_CUIS]溆P9l6SWӫ`#gov;m.|hćs|ؕ};o`w>vGv^wCn}}Pk;r~܈.~={w#w#~ُ(Gb G* G,_f;6W+SR<&Kv`vf ;;(̰1034`ov`;+@hw,$p4j= hg 53phv&;x6;hwHp;&&0& *@a>G`zZw `}肃w0h@* jށ 9hY ?`8D<!"`E`dF HP0$%( 44AR#<(wH  CHf! W9pȂ T-@ 6hi;p z0! khwT2mRI1?þ8"w@eJEU$J$H +imlySWjLa-ҀW ؊0q#`8qqOcAyE_Kdcjw&w@ +Xp +4*jVqe* VL Op5jm9Zm @l =[5TH#5ZSF"roH4| J&rK72L~WI@H7EoLɼAy7"bDɇdg$>@-{${']:ꃋlAAˮZo9[Eziuץ(߄?!&h5ŨEYD$Ǝ«X7y„-QAo!>՗)1Z!8ڲig]2 'A!k +7J4tɓ"{;ք^{D0-ϴnpbQg$ 69ʡ(f}8 +V!N.y[shVqE*1CFSiSaRB"R!%u`]$E0H wiE;: Ӡ@'{݉vY,˜9zKBA$OZgs g$DUH:YχeX-rW=ww-4-XFJ!Sq0*%C7F_!c(3\z]Z9N~VE݀H PQG?YИL-8RF0 yW6Ki/r({OoK wVDiug̮$Dǚ\gqˮ՗_*&,aVv2DĶ.){ wVCI ];}t)I誩T! +`X|Tq'ӂQt7)DCR"oez;\Q5 z( /aAQh/osȈ8De:E)Le]U$&/.tP9^:7{$ƛ:H#iRuj +ɩ@o: h^UJ -%'c7?)Ɠnn<M_$>N/D~O38|,k)TI},VbߝOb}&gh? (gt0-Mkjh jܼk`g:h iR56PiS iR +HSBƉF %0btv`p錒; ^`QbCNAOp8A8EY0MZ]5+%,( 1g{pMY`Uǩ (y/'00<8Hb08Nc0q"CPhlRl;|Ҷ&6 +m)6M6<}N.~鏛7.~(=}zq}|'}zs㻛??~?<~4mzK/g7o^?n2pGo?=]on>N?]=}=]| :|Ǐv  +endstream endobj 7 0 obj [6 0 R] endobj 27 0 obj <> endobj xref +0 28 +0000000000 65535 f +0000000016 00000 n +0000000144 00000 n +0000052136 00000 n +0000000000 00000 f +0000059705 00000 n +0000059519 00000 n +0000280311 00000 n +0000052187 00000 n +0000052594 00000 n +0000063929 00000 n +0000061245 00000 n +0000061132 00000 n +0000058251 00000 n +0000058957 00000 n +0000059005 00000 n +0000059589 00000 n +0000059620 00000 n +0000060891 00000 n +0000061280 00000 n +0000064003 00000 n +0000064243 00000 n +0000065311 00000 n +0000074719 00000 n +0000140308 00000 n +0000205897 00000 n +0000271486 00000 n +0000280334 00000 n +trailer +<<7BAC5166B5FBAA4BAFB4DE9E83A2E968>]>> +startxref +280518 +%%EOF diff --git a/application/modules/gitlist/logo/horizontal.png b/application/modules/gitlist/logo/horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..d0811a70814829e6e29c4c002443b574331c48f7 GIT binary patch literal 26594 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/application/modules/gitlist/logo/logomark.png b/application/modules/gitlist/logo/logomark.png new file mode 100644 index 0000000000000000000000000000000000000000..46b46d101e923ee2a55c79413493dd562f98c5a7 GIT binary patch literal 33093 zcmY&=c|6qL_y5bj)MSks$(|H#45?&DQuauaY}qm-C6Z-`iX=*seJfkm$`V-;Nr-G? zCrWmbeVgBTneqO7e}9z6>%PuC=XuUO=iYPAy{`$-(K>@+#j+v@f;p?EavnkG+t7c^ zjLAd%5KpmC@3X+vi{M{8$S^P5(PlBJ`CmEc(ia~rGk zR_2y&PBm615X8IbtcsHUozC$dwva0}Zv7)&qXw5VUv%fI=I4BBkF=EGwu-XMczJFg zgH{_uN7^g<=QUdQBLhn6><{Ny3bN3g{}kX_XJ5YL>m&89S7UEiOGrdbWqVZJb+fIx z5`vdKX@22NG#x$JW>zrwj_z~|JW&(nUMF5WZ`=)QR z<>Y1y78ff>YggGO%KBWlAZCMpIK&%ccr3CS%L3gM z3|Z}54|w$OERw^R-jW4q`4Id9+U>SlRxU~VP$qL^^ z2BiE$_f-tie*$G)I$e8JN;fl4#<%)~H7$aF!Uammqi^~i{rgF8b;oQxVXc6V4k_OW zEb)ZjUUmxyJ$fv#guAb94<#i`7BeEE+FCK>2}{E^DQ{P@dPK8mkhELDI7IMT zqLKECsbZG^T?CQfYD2s&1MK*O;dKrAAR1uznw^ArzXIFgZ>r>-4}iaK!CrzAiAG|T z@b@f;4cV%jd42%??gEX~?xnWzq7U5g;2)dXb`gEpiatc98f zT%u???jHJ}i9U#=;~t?8>ga=TI_??za29g7%Ju-DkexgUF7J7xgH+V)+DtUmiL>M*eos(N1H9W;*+LG1GMpmmN+Y0*+H+8og`+k82&gHl zW=Q9)0utrHYMde&G0+>_;K3h#*a;73;6V+2;D85pcwj~!Sl~e$?E^Mrr_sgS6Uw5&tAI6`qf;3_aR6ve z08Ou+r0L>f?plLW;1+f5{UIRdv``fYe12kIjL_A&v=l=qr(SVr+ z*%PrUsF-q845Ev9hKj+17~4|y{IzW2Y*8mYac$* zSRd_jt&2N)eP76f6yDP7Sa)0UepMQz{#PXyks-+okh`5bwja-5`}F6@*2mZ7cB=V? z5|G9l09>XyeLpj&(4Y-fj#G4TSn)xe~` z3a5q+E)E7ap18~jO~0s3o)9E>;w%n2Hc~q-e{kfZLG-g;q~_099L!R(gCQCwWjW9z zI%!5pfUJ~?Ou#*#1ELno0sLmE{4Pwjt0G94tv-PJNd>3>!4w!i&w2_vRGCtBXuXay zOjkXV7si06wpE#+ZIObYKBpi>@Lu;6Sz2W8X&qe$D-L#wvd=$g13!Di5NO-E*_Nk{ zwy8Bjo6u%k?ipyCm3)+%|CZaIVinn$SzHnH7QH4V$Cka5Lsy|i@QNQ6YP2KK6h_|1=-J0X+3f(Ysn8^5JT=FjS)w?Q%zn4(UoIzoruTm3>BuI9n}@HK;`G zD{p{EP*-Z`_a;$sF-pYIdfrfnO7zklC1Tf=dJVb2Ms)iXyhDlDThANoQ;7^$VC93^ zPU^SSCegb$K!g!b2YcUz_^fEx1A8-awH_^gPZ@3Rp{Z1`5|@?ZE9RtJPB zqZ3&Y2fa1l%`%SWa*^jf9bdXHHF9wMjQ&k!FXJi)Mvt_VPlxV9+PfSz(V5eqV4PD< z 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 D$39?d literal 0 HcmV?d00001 diff --git a/application/modules/gitlist/logo/logomark.svg b/application/modules/gitlist/logo/logomark.svg new file mode 100644 index 0000000..d53eb45 --- /dev/null +++ b/application/modules/gitlist/logo/logomark.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + diff --git a/application/modules/gitlist/logo/vertical.png b/application/modules/gitlist/logo/vertical.png new file mode 100644 index 0000000000000000000000000000000000000000..6dc50d4c3c648afaa6c08df9b9777a11b42d3c78 GIT binary patch literal 33950 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 literal 0 HcmV?d00001 diff --git a/application/modules/gitlist/logo/vertical.svg b/application/modules/gitlist/logo/vertical.svg new file mode 100644 index 0000000..0e2eaf2 --- /dev/null +++ b/application/modules/gitlist/logo/vertical.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/application/modules/gitlist/src/Application.php b/application/modules/gitlist/src/Application.php new file mode 100644 index 0000000..fd0f119 --- /dev/null +++ b/application/modules/gitlist/src/Application.php @@ -0,0 +1,187 @@ +path = realpath($root); + + $this['debug'] = $config->get('app', 'debug'); + $this['theme'] = $config->get('app', 'theme') ? $config->get('app', 'theme') : 'default'; + $this['date.format'] = $config->get('date', 'format') ? $config->get('date', 'format') : 'd/m/Y H:i:s'; + $this['filetypes'] = $config->getSection('filetypes'); + $this['binary_filetypes'] = $config->getSection('binary_filetypes'); + $this['cache.archives'] = $this->getCachePath() . 'archives'; + $this['avatar.url'] = $config->get('avatar', 'url'); + $this['avatar.query'] = $config->get('avatar', 'query'); + + // Register services + $this->register(new TwigServiceProvider(), array( + 'twig.path' => array($this->getThemePath($this['theme']), $this->getThemePath('default')), + 'twig.options' => $config->get('app', 'cache') ? + array('cache' => $this->getCachePath() . 'views') : array(), + )); + + $repositories = $config->get('git', 'repositories'); + $this['git.projects'] = $config->get('git', 'project_list') ? + $this->parseProjectList($config->get('git', 'project_list')) : + false; + + $this->register(new GitServiceProvider(), array( + 'git.client' => $config->get('git', 'client'), + 'git.repos' => $repositories, + 'ini.file' => 'config.ini', + 'git.hidden' => $config->get('git', 'hidden') ? + $config->get('git', 'hidden') : array(), + 'git.default_branch' => $config->get('git', 'default_branch') ? + $config->get('git', 'default_branch') : 'master', + )); + + $this->register(new ViewUtilServiceProvider()); + $this->register(new RepositoryUtilServiceProvider()); + $this->register(new RoutingUtilServiceProvider()); + $this->register(new UrlGeneratorServiceProvider()); + + $this['twig'] = $this->share($this->extend('twig', function ($twig, $app) use ($config) { + $twig->addFilter(new \Twig_SimpleFilter('htmlentities', 'htmlentities')); + $twig->addFilter(new \Twig_SimpleFilter('md5', 'md5')); + $twig->addFilter(new \Twig_SimpleFilter('format_date', array($app, 'formatDate'))); + $twig->addFilter(new \Twig_SimpleFilter('format_size', array($app, 'formatSize'))); + $twig->addFunction(new \Twig_SimpleFunction('avatar', array($app, 'getAvatar'))); + $twig->addGlobal('theme', $app['theme']); + $twig->addGlobal('title', $config->get('app', 'title') ? $config->get('app', 'title') : 'GitList'); + $twig->addGlobal('show_http_remote', $config->get('clone_button', 'show_http_remote')); + $twig->addGlobal('use_https', $config->get('clone_button', 'use_https')); + $twig->addGlobal('http_url_subdir', $config->get('clone_button', 'http_url_subdir')); + $twig->addGlobal('http_user', $config->get('clone_button', 'http_user_dynamic') ? $_SERVER['PHP_AUTH_USER'] : $config->get('clone_button', 'http_user')); + $twig->addGlobal('http_host', $config->get('clone_button', 'http_host')); + $twig->addGlobal('show_ssh_remote', $config->get('clone_button', 'show_ssh_remote')); + $twig->addGlobal('ssh_user', $config->get('clone_button', 'ssh_user_dynamic') ? $_SERVER['PHP_AUTH_USER'] : $config->get('clone_button', 'ssh_user')); + $twig->addGlobal('ssh_url_subdir', $config->get('clone_button', 'ssh_url_subdir')); + $twig->addGlobal('ssh_host', $config->get('clone_button', 'ssh_host')); + $twig->addGlobal('ssh_port', $config->get('clone_button', 'ssh_port')); + + return $twig; + })); + + $this['escaper.argument'] = $this->share(function() { + return new Escaper\ArgumentEscaper(); + }); + + // Handle errors + $this->error(function (\Exception $e, $code) use ($app) { + if ($app['debug']) { + return; + } + + return $app['twig']->render('error.twig', array( + 'message' => $e->getMessage(), + )); + }); + + $this->finish(function () use ($app, $config) { + if (!$config->get('app', 'cache')) { + $fs = new Filesystem(); + $fs->remove($app['cache.archives']); + } + }); + } + + public function formatDate($date) + { + return $date->format($this['date.format']); + } + + public function formatSize($size) + { + $mod = 1000; + $units = array('B', 'kB', 'MB', 'GB'); + for ($i = 0; $size > $mod; $i++) { + $size /= $mod; + } + + return round($size, 2) . $units[$i]; + } + + public function getAvatar($email, $size) + { + $url = $this['avatar.url'] ? $this['avatar.url'] : '//gravatar.com/avatar/'; + $query = array("s=$size"); + if (is_string($this['avatar.query'])) { + $query[] = $this['avatar.query']; + } elseif (is_array($this['avatar.query'])) { + $query = array_merge($query, $this['avatar.query']); + } + $id = md5(strtolower($email)); + + return $url . $id . '?' . implode('&', $query); + } + + public function getPath() + { + return $this->path . DIRECTORY_SEPARATOR; + } + + public function setPath($path) + { + $this->path = $path; + + return $this; + } + + public function getCachePath() + { + return $this->path + . DIRECTORY_SEPARATOR + . 'cache' + . DIRECTORY_SEPARATOR; + } + + public function getThemePath($theme) + { + return $this->path + . DIRECTORY_SEPARATOR + . 'themes' + . DIRECTORY_SEPARATOR + . $theme + . DIRECTORY_SEPARATOR + . 'twig' + . DIRECTORY_SEPARATOR; + } + + public function parseProjectList($project_list) + { + $projects = array(); + $file = fopen($project_list, 'r'); + while ($file && !feof($file)) { + $projects[] = trim(fgets($file)); + } + fclose($file); + + return $projects; + } +} diff --git a/application/modules/gitlist/src/Config.php b/application/modules/gitlist/src/Config.php new file mode 100644 index 0000000..2a00b7a --- /dev/null +++ b/application/modules/gitlist/src/Config.php @@ -0,0 +1,77 @@ +data = $data; + } + + public static function fromFile($file) + { + if (!file_exists($file)) { + die(sprintf('Please, create the %1$s file.', $file)); + } + + $data = parse_ini_file($file, true); + $config = new static($data); + $config->validateOptions(); + + return $config; + } + + public function get($section, $option) + { + if (!array_key_exists($section, $this->data)) { + return false; + } + + if (!array_key_exists($option, $this->data[$section])) { + return false; + } + + return $this->data[$section][$option]; + } + + public function getSection($section) + { + if (!array_key_exists($section, $this->data)) { + return false; + } + + return $this->data[$section]; + } + + public function set($section, $option, $value) + { + $this->data[$section][$option] = $value; + } + + protected function validateOptions() + { + $repositories = $this->get('git', 'repositories'); + + $atLeastOneOk = false; + $atLeastOneWrong = false; + + foreach ($repositories as $directory) { + if (!$directory || !is_dir($directory)) { + $atLeastOneWrong = true; + } else { + $atLeastOneOk = true; + } + } + + if (!$atLeastOneOk) { + die('Please, edit the config file and provide your repositories directory'); + } + + if ($atLeastOneWrong) { + die('One or more of the supplied repository paths appears to be wrong. Please, check the config file'); + } + } +} diff --git a/application/modules/gitlist/src/Controller/BlobController.php b/application/modules/gitlist/src/Controller/BlobController.php new file mode 100644 index 0000000..1945c08 --- /dev/null +++ b/application/modules/gitlist/src/Controller/BlobController.php @@ -0,0 +1,95 @@ +get(MODULE_NAME.'/{repo}/blob/{commitishPath}', function ($repo, $commitishPath) use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + list($branch, $file) = $app['util.routing'] + ->parseCommitishPathParam($commitishPath, $repo); + + list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file); + + $blob = $repository->getBlob("$branch:\"$file\""); + $breadcrumbs = $app['util.view']->getBreadcrumbs($file); + $fileType = $app['util.repository']->getFileType($file); + + if ($fileType !== 'image' && $app['util.repository']->isBinary($file)) { + return $app->redirect($app['url_generator']->generate('blob_raw', array( + 'repo' => $repo, + 'commitishPath' => $commitishPath, + ))); + } + + return $app['twig']->render('file.twig', array( + 'file' => $file, + 'fileType' => $fileType, + 'blob' => $blob->output(), + 'repo' => $repo, + 'branch' => $branch, + 'breadcrumbs' => $breadcrumbs, + 'branches' => $repository->getBranches(), + 'tags' => $repository->getTags(), + )); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('commitishPath', '.+') + ->convert('commitishPath', 'escaper.argument:escape') + ->bind('blob'); + + $route->get(MODULE_NAME.'/{repo}/raw/{commitishPath}', function ($repo, $commitishPath) use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + list($branch, $file) = $app['util.routing'] + ->parseCommitishPathParam($commitishPath, $repo); + + list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file); + + $blob = $repository->getBlob("$branch:\"$file\"")->output(); + + $headers = array(); + if ($app['util.repository']->isBinary($file)) { + $headers['Content-Disposition'] = 'attachment; filename="' . $file . '"'; + $headers['Content-Type'] = 'application/octet-stream'; + } else { + $headers['Content-Type'] = 'text/plain'; + } + + return new Response($blob, 200, $headers); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) + ->convert('commitishPath', 'escaper.argument:escape') + ->bind('blob_raw'); + + $route->get(MODULE_NAME.'/{repo}/logpatch/{commitishPath}', function ($repo, $commitishPath) use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + list($branch, $file) = $app['util.routing'] + ->parseCommitishPathParam($commitishPath, $repo); + + $filePatchesLog = $repository->getCommitsLogPatch($file); + $breadcrumbs = $app['util.view']->getBreadcrumbs($file); + + return $app['twig']->render('logpatch.twig', array( + 'branch' => $branch, + 'repo' => $repo, + 'breadcrumbs' => $breadcrumbs, + 'commits' => $filePatchesLog, + )); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('commitishPath', '.+') + ->convert('commitishPath', 'escaper.argument:escape') + ->bind('logpatch'); + + return $route; + } +} diff --git a/application/modules/gitlist/src/Controller/CommitController.php b/application/modules/gitlist/src/Controller/CommitController.php new file mode 100644 index 0000000..bb8439b --- /dev/null +++ b/application/modules/gitlist/src/Controller/CommitController.php @@ -0,0 +1,132 @@ +get(MODULE_NAME.'/{repo}/commits/search', function (Request $request, $repo) use ($app) { + $subRequest = Request::create( + '/' . $repo . '/commits/master/search', + 'POST', + array('query' => $request->get('query')) + ); + + return $app->handle($subRequest, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST); + })->assert('repo', $app['util.routing']->getRepositoryRegex()); + + $route->get(MODULE_NAME.'/{repo}/commits/{commitishPath}', function (Request $request, $repo, $commitishPath) use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + if ($commitishPath === null) { + $commitishPath = $repository->getHead(); + } + + list($branch, $file) = $app['util.routing'] + ->parseCommitishPathParam($commitishPath, $repo); + + list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file); + + $type = $file ? "$branch -- \"$file\"" : $branch; + $pager = $app['util.view']->getPager($request->get('page'), $repository->getTotalCommits($type)); + $commits = $repository->getPaginatedCommits($type, $pager['current']); + $categorized = array(); + + foreach ($commits as $commit) { + $date = $commit->getCommiterDate(); + $date = $date->format('Y-m-d'); + $categorized[$date][] = $commit; + } + + $template = $request->isXmlHttpRequest() ? 'commits_list.twig' : 'commits.twig'; + + return $app['twig']->render($template, array( + 'page' => 'commits', + 'pager' => $pager, + 'repo' => $repo, + 'branch' => $branch, + 'branches' => $repository->getBranches(), + 'tags' => $repository->getTags(), + 'commits' => $categorized, + 'file' => $file, + )); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) + ->value('commitishPath', null) + ->convert('commitishPath', 'escaper.argument:escape') + ->bind('commits'); + + $route->post(MODULE_NAME.'/{repo}/commits/{branch}/search', function (Request $request, $repo, $branch = '') use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + $query = $request->get('query'); + + $commits = $repository->searchCommitLog($query, $branch); + $categorized = array(); + + foreach ($commits as $commit) { + $date = $commit->getCommiterDate(); + $date = $date->format('Y-m-d'); + $categorized[$date][] = $commit; + } + + return $app['twig']->render('searchcommits.twig', array( + 'repo' => $repo, + 'branch' => $branch, + 'file' => '', + 'commits' => $categorized, + 'branches' => $repository->getBranches(), + 'tags' => $repository->getTags(), + 'query' => $query, + )); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('branch', $app['util.routing']->getBranchRegex()) + ->convert('branch', 'escaper.argument:escape') + ->bind('searchcommits'); + + $route->get(MODULE_NAME.'/{repo}/commit/{commit}', function ($repo, $commit) use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + $commit = $repository->getCommit($commit); + $branch = $repository->getHead(); + + return $app['twig']->render('commit.twig', array( + 'branch' => $branch, + 'repo' => $repo, + 'commit' => $commit, + )); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('commit', '[a-f0-9^]+') + ->bind('commit'); + + $route->get(MODULE_NAME.'/{repo}/blame/{commitishPath}', function ($repo, $commitishPath) use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + list($branch, $file) = $app['util.routing'] + ->parseCommitishPathParam($commitishPath, $repo); + + list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file); + + $blames = $repository->getBlame("$branch -- \"$file\""); + + return $app['twig']->render('blame.twig', array( + 'file' => $file, + 'repo' => $repo, + 'branch' => $branch, + 'branches' => $repository->getBranches(), + 'tags' => $repository->getTags(), + 'blames' => $blames, + )); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) + ->convert('commitishPath', 'escaper.argument:escape') + ->bind('blame'); + + return $route; + } +} diff --git a/application/modules/gitlist/src/Controller/MainController.php b/application/modules/gitlist/src/Controller/MainController.php new file mode 100644 index 0000000..b2523b7 --- /dev/null +++ b/application/modules/gitlist/src/Controller/MainController.php @@ -0,0 +1,77 @@ +get(MODULE_NAME.'/', function () use ($app) { + $repositories = $app['git']->getRepositories($app['git.repos']); + + return $app['twig']->render('index.twig', array( + 'repositories' => $repositories, + )); + })->bind('homepage'); + + $route->get(MODULE_NAME.'/refresh', function (Request $request) use ($app) { + // Go back to calling page + return $app->redirect($request->headers->get('Referer')); + })->bind('refresh'); + + $route->get(MODULE_NAME.'/{repo}/stats/{branch}', function ($repo, $branch) use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + if ($branch === null) { + $branch = $repository->getHead(); + } + + $stats = $repository->getBranchStatistics($branch); + $authors = $repository->getAuthorStatistics($branch); + + return $app['twig']->render('stats.twig', array( + 'repo' => $repo, + 'branch' => $branch, + 'branches' => $repository->getBranches(), + 'tags' => $repository->getTags(), + 'stats' => $stats, + 'authors' => $authors, + )); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('branch', $app['util.routing']->getBranchRegex()) + ->value('branch', null) + ->convert('branch', 'escaper.argument:escape') + ->bind('stats'); + + $route->get(MODULE_NAME.'/{repo}/{branch}/rss/', function ($repo, $branch) use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + if ($branch === null) { + $branch = $repository->getHead(); + } + + $commits = $repository->getPaginatedCommits($branch); + + $html = $app['twig']->render('rss.twig', array( + 'repo' => $repo, + 'branch' => $branch, + 'commits' => $commits, + )); + + return new Response($html, 200, array('Content-Type' => 'application/rss+xml')); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('branch', $app['util.routing']->getBranchRegex()) + ->value('branch', null) + ->convert('branch', 'escaper.argument:escape') + ->bind('rss'); + + return $route; + } +} diff --git a/application/modules/gitlist/src/Controller/NetworkController.php b/application/modules/gitlist/src/Controller/NetworkController.php new file mode 100644 index 0000000..77d30c1 --- /dev/null +++ b/application/modules/gitlist/src/Controller/NetworkController.php @@ -0,0 +1,129 @@ +get( + MODULE_NAME.'/{repo}/network/{commitishPath}/{page}.json', + function ($repo, $commitishPath, $page) use ($app) { + /** @var Repository $repository */ + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + if ($commitishPath === null) { + $commitishPath = $repository->getHead(); + } + + $pager = $app['util.view']->getPager($page, $repository->getTotalCommits($commitishPath)); + $commits = $repository->getPaginatedCommits($commitishPath, $pager['current']); + + $jsonFormattedCommits = array(); + + foreach ($commits as $commit) { + $detailsUrl = $app['url_generator']->generate( + 'commit', + array( + 'repo' => $repo, + 'commit' => $commit->getHash(), + ) + ); + + $jsonFormattedCommits[$commit->getHash()] = array( + 'hash' => $commit->getHash(), + 'parentsHash' => $commit->getParentsHash(), + 'date' => $commit->getDate()->format('U'), + 'message' => htmlentities($commit->getMessage()), + 'details' => $detailsUrl, + 'author' => array( + 'name' => $commit->getAuthor()->getName(), + 'email' => $commit->getAuthor()->getEmail(), + 'image' => $app->getAvatar($commit->getAuthor()->getEmail(), 40), + ), + ); + } + + $nextPageUrl = null; + + if ($pager['last'] !== $pager['current']) { + $nextPageUrl = $app['url_generator']->generate( + 'networkData', + array( + 'repo' => $repo, + 'commitishPath' => $commitishPath, + 'page' => $pager['next'], + ) + ); + } + + // when no commits are given, return an empty response - issue #369 + if (count($commits) === 0) { + return $app->json( + array( + 'repo' => $repo, + 'commitishPath' => $commitishPath, + 'nextPage' => null, + 'start' => null, + 'commits' => $jsonFormattedCommits, + ), + 200 + ); + } + + return $app->json( + array( + 'repo' => $repo, + 'commitishPath' => $commitishPath, + 'nextPage' => $nextPageUrl, + 'start' => $commits[0]->getHash(), + 'commits' => $jsonFormattedCommits, + ), + 200 + ); + } + )->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) + ->value('commitishPath', null) + ->convert('commitishPath', 'escaper.argument:escape') + ->assert('page', '\d+') + ->value('page', '0') + ->bind('networkData'); + + $route->get( + MODULE_NAME.'/{repo}/network/{commitishPath}', + function ($repo, $commitishPath) use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + if ($commitishPath === null) { + $commitishPath = $repository->getHead(); + } + + list($branch, $file) = $app['util.routing']->parseCommitishPathParam($commitishPath, $repo); + list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file); + + return $app['twig']->render( + 'network.twig', + array( + 'repo' => $repo, + 'branch' => $branch, + 'commitishPath' => $commitishPath, + ) + ); + } + )->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) + ->value('commitishPath', null) + ->convert('commitishPath', 'escaper.argument:escape') + ->bind('network'); + + return $route; + } +} diff --git a/application/modules/gitlist/src/Controller/TreeController.php b/application/modules/gitlist/src/Controller/TreeController.php new file mode 100644 index 0000000..36b9a22 --- /dev/null +++ b/application/modules/gitlist/src/Controller/TreeController.php @@ -0,0 +1,128 @@ +get(MODULE_NAME.'/{repo}/tree/{commitishPath}/', $treeController = function ($repo, $commitishPath = '') use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + if (!$commitishPath) { + $commitishPath = $repository->getHead(); + } + + list($branch, $tree) = $app['util.routing']->parseCommitishPathParam($commitishPath, $repo); + + list($branch, $tree) = $app['util.repository']->extractRef($repository, $branch, $tree); + $files = $repository->getTree($tree ? "$branch:\"$tree\"/" : $branch); + $breadcrumbs = $app['util.view']->getBreadcrumbs($tree); + + $parent = null; + if (($slash = strrpos($tree, '/')) !== false) { + $parent = substr($tree, 0, $slash); + } elseif (!empty($tree)) { + $parent = ''; + } + + return $app['twig']->render('tree.twig', array( + 'files' => $files->output(), + 'repo' => $repo, + 'branch' => $branch, + 'path' => $tree ? $tree . '/' : $tree, + 'parent' => $parent, + 'breadcrumbs' => $breadcrumbs, + 'branches' => $repository->getBranches(), + 'tags' => $repository->getTags(), + 'readme' => $app['util.repository']->getReadme($repository, $branch, $tree ? "$tree" : ''), + )); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) + ->convert('commitishPath', 'escaper.argument:escape') + ->bind('tree'); + + $route->post(MODULE_NAME.'/{repo}/tree/{branch}/search', function (Request $request, $repo, $branch = '', $tree = '') use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + if (!$branch) { + $branch = $repository->getHead(); + } + + $query = $request->get('query'); + $breadcrumbs = array(array('dir' => 'Search results for: ' . $query, 'path' => '')); + $results = $repository->searchTree($query, $branch); + + return $app['twig']->render('search.twig', array( + 'results' => $results, + 'repo' => $repo, + 'branch' => $branch, + 'path' => $tree, + 'breadcrumbs' => $breadcrumbs, + 'branches' => $repository->getBranches(), + 'tags' => $repository->getTags(), + 'query' => $query, + )); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('branch', $app['util.routing']->getBranchRegex()) + ->convert('branch', 'escaper.argument:escape') + ->bind('search'); + + $route->get(MODULE_NAME.'/{repo}/{format}ball/{branch}', function ($repo, $format, $branch) use ($app) { + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + $tree = $repository->getBranchTree($branch); + + if (false === $tree) { + return $app->abort(404, 'Invalid commit or tree reference: ' . $branch); + } + + $file = $app['cache.archives'] . DIRECTORY_SEPARATOR + . $repo . DIRECTORY_SEPARATOR + . substr($tree, 0, 2) . DIRECTORY_SEPARATOR + . substr($tree, 2) + . '.' + . $format; + + if (!file_exists($file)) { + $repository->createArchive($tree, $file, $format); + } + + /** + * Generating name for downloading, lowercasing and removing all non + * ascii and special characters. + */ + $filename = strtolower($repo . '_' . $branch); + $filename = preg_replace('#[^a-z0-9]+#', '_', $filename); + $filename = $filename . '.' . $format; + + $response = new BinaryFileResponse($file); + $response->setContentDisposition('attachment', $filename); + + return $response; + })->assert('format', '(zip|tar)') + ->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('branch', $app['util.routing']->getBranchRegex()) + ->convert('branch', 'escaper.argument:escape') + ->bind('archive'); + + $route->get(MODULE_NAME.'/{repo}/{branch}/', function ($repo, $branch) use ($app, $treeController) { + return $treeController($repo, $branch); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('branch', $app['util.routing']->getBranchRegex()) + ->convert('branch', 'escaper.argument:escape') + ->bind('branch'); + + $route->get(MODULE_NAME.'/{repo}/', function ($repo) use ($app, $treeController) { + return $treeController($repo); + })->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->bind('repository'); + + return $route; + } +} diff --git a/application/modules/gitlist/src/Controller/TreeGraphController.php b/application/modules/gitlist/src/Controller/TreeGraphController.php new file mode 100644 index 0000000..371c2ca --- /dev/null +++ b/application/modules/gitlist/src/Controller/TreeGraphController.php @@ -0,0 +1,72 @@ +get( + MODULE_NAME.'/{repo}/treegraph/{commitishPath}', + function ($repo, $commitishPath) use ($app) { + /** @var \GitList\Git\Repository $repository */ + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + $command = 'log --graph --date-order --all -C -M -n 100 --date=iso ' . + '--pretty=format:"B[%d] C[%H] D[%ad] A[%an] E[%ae] H[%h] S[%s]"'; + $rawRows = $repository->getClient()->run($repository, $command); + $rawRows = explode("\n", $rawRows); + $graphItems = array(); + + foreach ($rawRows as $row) { + if (preg_match("/^(.+?)(\s(B\[(.*?)\])? C\[(.+?)\] D\[(.+?)\] A\[(.+?)\] E\[(.+?)\] H\[(.+?)\] S\[(.+?)\])?$/", $row, $output)) { + if (!isset($output[4])) { + $graphItems[] = array( + 'relation' => $output[1], + ); + continue; + } + $graphItems[] = array( + 'relation' => $output[1], + 'branch' => $output[4], + 'rev' => $output[5], + 'date' => $output[6], + 'author' => $output[7], + 'author_email' => $output[8], + 'short_rev' => $output[9], + 'subject' => preg_replace('/(^|\s)(#[[:xdigit:]]+)(\s|$)/', '$1$2$3', $output[10]), + ); + } + } + + if ($commitishPath === null) { + $commitishPath = $repository->getHead(); + } + + list($branch, $file) = $app['util.routing']->parseCommitishPathParam($commitishPath, $repo); + list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file); + + return $app['twig']->render( + 'treegraph.twig', + array( + 'repo' => $repo, + 'branch' => $branch, + 'commitishPath' => $commitishPath, + 'graphItems' => $graphItems, + ) + ); + } + )->assert('repo', $app['util.routing']->getRepositoryRegex()) + ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) + ->value('commitishPath', null) + ->convert('commitishPath', 'escaper.argument:escape') + ->bind('treegraph'); + + return $route; + } +} diff --git a/application/modules/gitlist/src/Escaper/ArgumentEscaper.php b/application/modules/gitlist/src/Escaper/ArgumentEscaper.php new file mode 100644 index 0000000..6717dd8 --- /dev/null +++ b/application/modules/gitlist/src/Escaper/ArgumentEscaper.php @@ -0,0 +1,15 @@ +setDefaultBranch($options['default_branch']); + $this->setHidden($options['hidden']); + $this->setProjects($options['projects']); + } + + public function getRepositoryFromName($paths, $repo) + { + $repositories = $this->getRepositories($paths); + $path = $repositories[$repo]['path']; + + return $this->getRepository($path); + } + + /** + * Searches for valid repositories on the specified path. + * + * @param array $paths Array of paths where repositories will be searched + * + * @return array Found repositories, containing their name, path and description sorted + * by repository name + */ + public function getRepositories($paths) + { + $allRepositories = array(); + + foreach ($paths as $path) { + $repositories = $this->recurseDirectory($path); + + if (empty($repositories)) { + throw new \RuntimeException('There are no GIT repositories in ' . $path); + } + + /** + * Use "+" to preserve keys, only a problem with numeric repos. + */ + $allRepositories = $allRepositories + $repositories; + } + + $allRepositories = array_unique($allRepositories, SORT_REGULAR); + uksort($allRepositories, function ($k1, $k2) { + return strtolower($k2) < strtolower($k1); + }); + + return $allRepositories; + } + + /** + * Return name of default branch as a string. + */ + public function getDefaultBranch() + { + return $this->defaultBranch; + } + + /** + * Overloads the parent::createRepository method for the correct Repository class instance. + * + * {@inheritdoc} + */ + public function createRepository($path, $bare = null) + { + if (file_exists($path . '/.git/HEAD') && !file_exists($path . '/HEAD')) { + throw new \RuntimeException('A GIT repository already exists at ' . $path); + } + + $repository = new Repository($path, $this); + + return $repository->create($bare); + } + + /** + * Overloads the parent::getRepository method for the correct Repository class instance. + * + * {@inheritdoc} + */ + public function getRepository($path) + { + if (!file_exists($path) || !file_exists($path . '/.git/HEAD') && !file_exists($path . '/HEAD')) { + throw new \RuntimeException('There is no GIT repository at ' . $path); + } + + return new Repository($path, $this); + } + + /** + * Set default branch as a string. + * + * @param string $branch name of branch to use when repo's HEAD is detached + * + * @return object + */ + protected function setDefaultBranch($branch) + { + $this->defaultBranch = $branch; + + return $this; + } + + /** + * Get hidden repository list. + * + * @return array List of repositories to hide + */ + protected function getHidden() + { + return $this->hidden; + } + + /** + * Set the hidden repository list. + * + * @param array $hidden List of repositories to hide + * + * @return object + */ + protected function setHidden($hidden) + { + $this->hidden = $hidden; + + return $this; + } + + /** + * Get project list. + * + * @return array List of repositories to show + */ + protected function getProjects() + { + return $this->projects; + } + + /** + * Set the shown repository list. + * + * @param array $projects List of repositories to show + */ + protected function setProjects($projects) + { + $this->projects = $projects; + + return $this; + } + + private function recurseDirectory($path, $appendPath = '') + { + $dir = new \DirectoryIterator($path); + + $repositories = array(); + + foreach ($dir as $file) { + if ($file->isDot()) { + continue; + } + + if (strrpos($file->getFilename(), '.') === 0) { + continue; + } + + if (!$file->isReadable()) { + continue; + } + + if ($file->isDir()) { + $isBare = file_exists($file->getPathname() . '/HEAD'); + $isRepository = file_exists($file->getPathname() . '/.git/HEAD'); + + if ($isRepository || $isBare) { + $hidden = function ($path, $hide) { + $return = false; + + array_walk($hide, function ($value, $key) use ($path, &$return) { + if (($path === $value) || (1 === preg_match($value, $path))) { + $return = true; + } + }); + + return $return; + }; + + if ($hidden($file->getPathname(), $this->getHidden())) { + continue; + } + + if ($isBare) { + $description = $file->getPathname() . '/description'; + } else { + $description = $file->getPathname() . '/.git/description'; + } + + if (file_exists($description)) { + $description = file_get_contents($description); + } else { + $description = null; + } + + $repoName = $appendPath . $file->getFilename(); + + if (is_array($this->getProjects()) && !in_array($repoName, $this->getProjects())) { + continue; + } + + $repositories[$repoName] = array( + 'name' => $repoName, + 'path' => $file->getPathname(), + 'description' => $description, + ); + + continue; + } + $repositories = array_merge($repositories, $this->recurseDirectory($file->getPathname(), $appendPath . $file->getFilename() . '/')); + } + } + + return $repositories; + } +} diff --git a/application/modules/gitlist/src/Git/Repository.php b/application/modules/gitlist/src/Git/Repository.php new file mode 100644 index 0000000..81a175f --- /dev/null +++ b/application/modules/gitlist/src/Git/Repository.php @@ -0,0 +1,457 @@ +getClient()->run($this, "show $commitHash"); + $logs = explode("\n", $logs); + + return strpos($logs[0], 'commit') === 0; + } + + /** + * Get the current branch, returning a default value when HEAD is detached. + */ + public function getHead($default = null) + { + $client = $this->getClient(); + + return parent::getHead($client->getDefaultBranch()); + } + + /** + * Show Patches that where apllied to the selected file. + * + * @param string $file File path for which we will retrieve a list of patch logs + * + * @return array Collection of Commits data + */ + public function getCommitsLogPatch($file) + { + $record_delimiter = chr(hexdec('0x1e')); + $file_patches = $this->getClient()->run( + $this, + 'log -p --pretty=format:"' . $record_delimiter . '%H' + . '%h%T%P' + . '%aN%aE' + . '%at%cN%cE' + . '%ct' + . '' + . '' + . "\" -- $file" + ); + + $patch_collection = array(); + foreach (preg_split('/(' . $record_delimiter . '\)/', $file_patches, null, PREG_SPLIT_NO_EMPTY) as $patches) { + $patches = '' . $patches; + $xmlEnd = strpos($patches, '') + 7; + $commitInfo = substr($patches, 0, $xmlEnd); + $commitData = substr($patches, $xmlEnd); + $logs = explode("\n", $commitData); + + // Read commit metadata + $format = new PrettyFormat(); + $data = $format->parse($commitInfo); + $commit = new Commit(); + $commit->importData($data[0]); + $commit->setDiffs($this->readDiffLogs($logs)); + $patch_collection[] = $commit; + } + + return $patch_collection; + } + + /** + * Show the data from a specific commit. + * + * @param string $commitHash Hash of the specific commit to read data + * + * @return array Commit data + */ + public function getCommit($commitHash) + { + $logs = $this->getClient()->run( + $this, + 'show --pretty=format:"%H' + . '%h%T%P' + . '%aN%aE' + . '%at%cN%cE' + . '%ct' + . '' + . '' + . "\" $commitHash" + ); + + $xmlEnd = strpos($logs, '') + 7; + $commitInfo = substr($logs, 0, $xmlEnd); + $commitData = substr($logs, $xmlEnd); + $logs = explode("\n", $commitData); + + // Read commit metadata + $format = new PrettyFormat(); + $data = $format->parse($commitInfo); + $commit = new Commit(); + $commit->importData($data[0]); + + if ($commit->getParentsHash()) { + $command = 'diff ' . $commitHash . '~1..' . $commitHash; + $logs = explode("\n", $this->getClient()->run($this, $command)); + } + + $commit->setDiffs($this->readDiffLogs($logs)); + + return $commit; + } + + /** + * Blames the provided file and parses the output. + * + * @param string $file File that will be blamed + * + * @return array Commits hashes containing the lines + */ + public function getBlame($file) + { + $blame = array(); + $logs = $this->getClient()->run($this, "blame --root -sl $file"); + $logs = explode("\n", $logs); + + $i = 0; + $previousCommit = ''; + foreach ($logs as $log) { + if ($log == '') { + continue; + } + + preg_match_all("/([a-zA-Z0-9]{40})\s+.*?([0-9]+)\)(.+)/", $log, $match); + + $currentCommit = $match[1][0]; + if ($currentCommit != $previousCommit) { + ++$i; + $blame[$i] = array( + 'line' => '', + 'commit' => $currentCommit, + 'commitShort' => substr($currentCommit, 0, 8), + ); + } + + $blame[$i]['line'] .= $match[3][0] . PHP_EOL; + $previousCommit = $currentCommit; + } + + return $blame; + } + + /** + * Read diff logs and generate a collection of diffs. + * + * @param array $logs Array of log rows + * + * @return array Array of diffs + */ + public function readDiffLogs(array $logs) + { + $diffs = array(); + $lineNumOld = 0; + $lineNumNew = 0; + foreach ($logs as $log) { + // Skip empty lines + if ($log == '') { + continue; + } + + if ('diff' === substr($log, 0, 4)) { + if (isset($diff)) { + $diffs[] = $diff; + } + + $diff = new Diff(); + if (preg_match('/^diff --[\S]+ a\/?(.+) b\/?/', $log, $name)) { + $diff->setFile($name[1]); + } + continue; + } + + if ('index' === substr($log, 0, 5)) { + $diff->setIndex($log); + continue; + } + + if ('---' === substr($log, 0, 3)) { + $diff->setOld($log); + continue; + } + + if ('+++' === substr($log, 0, 3)) { + $diff->setNew($log); + continue; + } + + // Handle binary files properly. + if ('Binary' === substr($log, 0, 6)) { + $m = array(); + if (preg_match('/Binary files (.+) and (.+) differ/', $log, $m)) { + $diff->setOld($m[1]); + $diff->setNew(" {$m[2]}"); + } + } + + if (!empty($log)) { + switch ($log[0]) { + case '@': + // Set the line numbers + preg_match('/@@ -([0-9]+)(?:,[0-9]+)? \+([0-9]+)/', $log, $matches); + $lineNumOld = $matches[1] - 1; + $lineNumNew = $matches[2] - 1; + break; + case '-': + $lineNumOld++; + break; + case '+': + $lineNumNew++; + break; + default: + $lineNumOld++; + $lineNumNew++; + } + } else { + $lineNumOld++; + $lineNumNew++; + } + + if (isset($diff)) { + $diff->addLine($log, $lineNumOld, $lineNumNew); + } + } + + if (isset($diff)) { + $diffs[] = $diff; + } + + return $diffs; + } + + /** + * Show the repository commit log with pagination. + * + * @param string $file + * @param int $page + * + * @return array Commit log + */ + public function getPaginatedCommits($file = null, $page = 0) + { + $page = 15 * $page; + $pager = "--skip=$page --max-count=15"; + $command = + "log $pager --pretty=format:\"%H" + . '%h%T%P' + . '%aN%aE' + . '%at%cN' + . '%cE' + . '%ct' + . '"'; + + if ($file) { + $command .= " $file"; + } + + try { + $logs = $this->getPrettyFormat($command); + } catch (\RuntimeException $e) { + return array(); + } + + foreach ($logs as $log) { + $commit = new Commit(); + $commit->importData($log); + $commits[] = $commit; + } + + return $commits; + } + + public function searchCommitLog($query, $branch) + { + $query = escapeshellarg($query); + $query = strtr($query, array('[' => '\\[', ']' => '\\]')); + $command = + "log --grep={$query} -i --pretty=format:\"%H" + . '%h%T%P' + . '%aN%aE' + . '%at%cN' + . '%cE' + . '%ct' + . '"' + . " $branch"; + + try { + $logs = $this->getPrettyFormat($command); + } catch (\RuntimeException $e) { + return array(); + } + + foreach ($logs as $log) { + $commit = new Commit(); + $commit->importData($log); + $commits[] = $commit; + } + + return $commits; + } + + public function searchTree($query, $branch) + { + if (empty($query)) { + return null; + } + + $query = preg_replace('/(--?[A-Za-z0-9\-]+)/', '', $query); + $query = escapeshellarg($query); + + try { + $results = $this->getClient()->run($this, "grep -i --line-number -- {$query} $branch"); + } catch (\RuntimeException $e) { + return false; + } + + $results = explode("\n", $results); + $searchResults = array(); + + foreach ($results as $result) { + if ($result == '') { + continue; + } + + preg_match_all('/([\w\-._]+):([^:]+):([0-9]+):(.+)/', $result, $matches, PREG_SET_ORDER); + + $data['branch'] = $matches[0][1]; + $data['file'] = $matches[0][2]; + $data['line'] = $matches[0][3]; + $data['match'] = $matches[0][4]; + + $searchResults[] = $data; + } + + return $searchResults; + } + + public function getAuthorStatistics($branch) + { + $logs = $this->getClient()->run($this, 'log --pretty=format:"%aN||%aE" ' . $branch); + + if (empty($logs)) { + throw new \RuntimeException('No statistics available'); + } + + $logs = explode("\n", $logs); + $logs = array_count_values($logs); + arsort($logs); + + foreach ($logs as $user => $count) { + $user = explode('||', $user); + $data[] = array('name' => $user[0], 'email' => $user[1], 'commits' => $count); + } + + return $data; + } + + public function getBranchStatistics($branch) + { + // Calculate amount of files, extensions and file size + $logs = $this->getClient()->run($this, 'ls-tree -r -l ' . $branch); + $lines = explode("\n", $logs); + $files = array(); + $data['extensions'] = array(); + $data['size'] = 0; + $data['files'] = 0; + + foreach ($lines as $key => $line) { + if (empty($line)) { + unset($lines[$key]); + continue; + } + + $files[] = preg_split("/[\s]+/", $line); + } + + foreach ($files as $file) { + if ($file[1] == 'blob') { + $data['files']++; + } + + if (is_numeric($file[3])) { + $data['size'] += $file[3]; + } + } + + $logs = $this->getClient()->run($this, 'ls-tree -l -r --name-only ' . $branch); + $files = explode("\n", $logs); + foreach ($files as $file) { + if (($pos = strrpos($file, '.')) !== false) { + $extension = substr($file, $pos); + + if (($pos = strrpos($extension, '/')) === false) { + $data['extensions'][] = $extension; + } + } + } + + $data['extensions'] = array_count_values($data['extensions']); + arsort($data['extensions']); + + return $data; + } + + /** + * Create a TAR or ZIP archive of a git tree. + * + * @param string $tree Tree-ish reference + * @param string $output Output File name + * @param string $format Archive format + */ + public function createArchive($tree, $output, $format = 'zip') + { + $fs = new Filesystem(); + $fs->mkdir(dirname($output)); + $this->getClient()->run($this, "archive --format=$format --output='$output' $tree"); + } + + /** + * Return true if $path exists in $branch; return false otherwise. + * + * @param string $commitish commitish reference; branch, tag, SHA1, etc + * @param string $path path whose existence we want to verify + * + * @return bool + * + * GRIPE Arguably belongs in Gitter, as it's generally useful functionality. + * Also, this really may not be the best way to do this. + */ + public function pathExists($commitish, $path) + { + $output = $this->getClient()->run($this, "ls-tree $commitish '$path'"); + + if (strlen($output) > 0) { + return true; + } + + return false; + } +} diff --git a/application/modules/gitlist/src/Provider/GitServiceProvider.php b/application/modules/gitlist/src/Provider/GitServiceProvider.php new file mode 100644 index 0000000..0ec0344 --- /dev/null +++ b/application/modules/gitlist/src/Provider/GitServiceProvider.php @@ -0,0 +1,27 @@ + 'php', + 'c' => 'clike', + 'h' => 'clike', + 'cpp' => 'clike', + 'm' => 'clike', + 'mm' => 'clike', + 'ino' => 'clike', + 'cs' => 'text/x-csharp', + 'java' => 'text/x-java', + 'clj' => 'clojure', + 'coffee' => 'coffeescript', + 'css' => 'css', + 'diff' => 'diff', + 'ecl' => 'ecl', + 'el' => 'erlang', + 'go' => 'go', + 'groovy' => 'groovy', + 'hs' => 'haskell', + 'lhs' => 'haskell', + 'jsp' => 'application/x-jsp', + 'asp' => 'htmlembedded', + 'aspx' => 'htmlembedded', + 'html' => 'htmlmixed', + 'tpl' => 'htmlmixed', + 'js' => 'javascript', + 'json' => 'javascript', + 'less' => 'less', + 'lua' => 'lua', + 'md' => 'markdown', + 'markdown' => 'markdown', + 'sql' => 'mysql', + 'ml' => 'ocaml', + 'mli' => 'ocaml', + 'pl' => 'perl', + 'pm' => 'perl', + 'pas' => 'pascal', + 'ini' => 'properties', + 'cfg' => 'properties', + 'nt' => 'ntriples', + 'py' => 'python', + 'rb' => 'ruby', + 'rst' => 'rst', + 'r' => 'r', + 'sh' => 'shell', + 'ss' => 'scheme', + 'scala' => 'text/x-scala', + 'scm' => 'scheme', + 'sls' => 'scheme', + 'sps' => 'scheme', + 'rs' => 'rust', + 'st' => 'smalltalk', + 'tex' => 'stex', + 'vbs' => 'vbscript', + 'vb' => 'vbscript', + 'v' => 'verilog', + 'xml' => 'xml', + 'xsd' => 'xml', + 'xsl' => 'xml', + 'xul' => 'xml', + 'xlf' => 'xml', + 'xliff' => 'xml', + 'xaml' => 'xml', + 'wxs' => 'xml', + 'wxl' => 'xml', + 'wxi' => 'xml', + 'wsdl' => 'xml', + 'svg' => 'xml', + 'rss' => 'xml', + 'rdf' => 'xml', + 'plist' => 'xml', + 'mxml' => 'xml', + 'kml' => 'xml', + 'glade' => 'xml', + 'xq' => 'xquery', + 'xqm' => 'xquery', + 'xquery' => 'xquery', + 'xqy' => 'xquery', + 'yml' => 'yaml', + 'yaml' => 'yaml', + 'png' => 'image', + 'jpg' => 'image', + 'gif' => 'image', + 'jpeg' => 'image', + 'bmp' => 'image', + 'csproj' => 'xml', + ); + + protected static $binaryTypes = array( + 'exe', 'com', 'so', 'la', 'o', 'dll', 'pyc', + 'jpg', 'jpeg', 'bmp', 'gif', 'png', 'xmp', 'pcx', 'svgz', 'ttf', 'tiff', 'oet', + 'gz', 'tar', 'rar', 'zip', '7z', 'jar', 'class', + 'odt', 'ods', 'pdf', 'doc', 'docx', 'dot', 'xls', 'xlsx', + ); + + public function __construct(Application $app) + { + $this->app = $app; + } + + /** + * Returns the file type based on filename by treating the extension. + * + * The file type is used by CodeMirror, a Javascript-based IDE implemented in + * GitList, to properly highlight the blob syntax (if it's a source-code) + * + * @param string $file File name + * + * @return mixed File type + */ + public function getFileType($file) + { + if (($pos = strrpos($file, '.')) !== false) { + $fileType = substr($file, $pos + 1); + } else { + return 'text'; + } + + if (!empty($this->app['filetypes'])) { + if (isset($this->app['filetypes'][$fileType])) { + return $this->app['filetypes'][$fileType]; + } + } + + if (isset($this->defaultFileTypes[$fileType])) { + return $this->defaultFileTypes[$fileType]; + } + + return 'text'; + } + + /** + * Returns whether the file is binary. + * + * @param string $file + * + * @return bool + */ + public function isBinary($file) + { + if (($pos = strrpos($file, '.')) !== false) { + $fileType = substr($file, $pos + 1); + } else { + return false; + } + + if (!empty($this->app['binary_filetypes']) && array_key_exists($fileType, $this->app['binary_filetypes'])) { + return $this->app['binary_filetypes'][$fileType]; + } + + if (in_array($fileType, self::$binaryTypes)) { + return true; + } + + return false; + } + + public function getReadme($repository, $branch = null, $path = '') + { + if ($branch === null) { + $branch = $repository->getHead(); + } + + if ($path != '') { + $path = "$path/"; + } + + $files = $repository->getTree($path != '' ? "$branch:\"$path\"" : $branch)->output(); + + foreach ($files as $file) { + if (preg_match('/^readme*/i', $file['name'])) { + return array( + 'filename' => $file['name'], + 'content' => $repository->getBlob("$branch:\"$path{$file['name']}\"")->output(), + ); + } + } + // No contextual readme, try to catch the main one if we are in deeper context + if ($path != '') { + return $this->getReadme($repository, $branch, ''); + } + + return array(); + } + + /** + * Returns an Array where the first value is the tree-ish and the second is the path. + * + * @param \GitList\Git\Repository $repository + * @param string $branch + * @param string $tree + * + * @return array + */ + public function extractRef($repository, $branch = '', $tree = '') + { + $branch = trim($branch, '/'); + $tree = trim($tree, '/'); + $input = $branch . '/' . $tree; + + // If the ref appears to be a SHA, just split the string + if (preg_match('/^([[:alnum:]]{40})(.+)/', $input, $matches)) { + $branch = $matches[1]; + } else { + // Otherwise, attempt to detect the ref using a list of the project's branches and tags + $validRefs = array_merge((array) $repository->getBranches(), (array) $repository->getTags()); + foreach ($validRefs as $key => $ref) { + if (!preg_match(sprintf('#^%s/#', preg_quote($ref, '#')), $input)) { + unset($validRefs[$key]); + } + } + + // No exact ref match, so just try our best + if (count($validRefs) > 1) { + preg_match('/([^\/]+)(.*)/', $input, $matches); + $branch = preg_replace('/^\/|\/$/', '', $matches[1]); + } else { + // Extract branch name + $branch = array_shift($validRefs); + } + } + + return array($branch, $tree); + } +} diff --git a/application/modules/gitlist/src/Util/Routing.php b/application/modules/gitlist/src/Util/Routing.php new file mode 100644 index 0000000..b307736 --- /dev/null +++ b/application/modules/gitlist/src/Util/Routing.php @@ -0,0 +1,164 @@ +app = $app; + } + + /* @brief Return $commitish, $path parsed from $commitishPath, based on + * what's in $repo. Raise a 404 if $branchpath does not represent a + * valid branch and path. + * + * A helper for parsing routes that use commit-ish names and paths + * separated by /, since route regexes are not enough to get that right. + * + * @param string $commitishPath + * @param string $repo + * @return array + */ + public function parseCommitishPathParam($commitishPath, $repo) + { + $app = $this->app; + $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); + + $commitish = null; + $path = null; + + $slashPosition = strpos($commitishPath, '/'); + if (strlen($commitishPath) >= 40 && + ($slashPosition === false || + $slashPosition === 40)) { + // We may have a commit hash as our commitish. + $hash = substr($commitishPath, 0, 40); + if (preg_match('/[^a-zA-Z0-9]/i', $hash) === 0) { + if ($repository->hasCommit($hash)) { + $commitish = $hash; + } + } + } + + if ($commitish === null) { + $branches = $repository->getBranches(); + + $tags = $repository->getTags(); + if ($tags !== null && count($tags) > 0) { + $branches = array_merge($branches, $tags); + } + + $matchedBranch = null; + $matchedBranchLength = 0; + foreach ($branches as $branch) { + if (strpos($commitishPath, $branch) === 0 && + strlen($branch) > $matchedBranchLength) { + $matchedBranch = $branch; + $matchedBranchLength = strlen($matchedBranch); + } + } + + if ($matchedBranch !== null) { + $commitish = $matchedBranch; + } else { + // We may have partial commit hash as our commitish. + $hash = $slashPosition === false ? $commitishPath : substr($commitishPath, 0, $slashPosition); + if ($repository->hasCommit($hash)) { + $commit = $repository->getCommit($hash); + $commitish = $commit->getHash(); + } else { + throw new EmptyRepositoryException('This repository is currently empty. There are no commits.'); + } + } + } + + $commitishLength = strlen($commitish); + $path = substr($commitishPath, $commitishLength); + if (strpos($path, '/') === 0) { + $path = substr($path, 1); + } + + return array($commitish, $path); + } + + public function getBranchRegex() + { + static $branchRegex = null; + + if ($branchRegex === null) { + $branchRegex = '(?!/|.*([/.]\.|//|@\{|\\\\))[^\040\177 ~^:?*\[]+(?app['git']->getRepositories($this->app['git.repos']) + ); + usort( + $quotedPaths, + function ($a, $b) { + return strlen($b) - strlen($a); + } + ); + $regex = implode('|', $quotedPaths); + } + + return $regex; + } + + public function isWindows() + { + switch (PHP_OS) { + case 'WIN32': + case 'WINNT': + case 'Windows': + return true; + default: + return false; + } + } + + /** + * Strips the base path from a full repository path. + * + * @param string $repoPath Full path to the repository + * + * @return string Relative path to the repository from git.repositories + */ + public function getRelativePath($repoPath) + { + if (strpos($repoPath, $this->app['git.repos']) === 0) { + $relativePath = substr($repoPath, strlen($this->app['git.repos'])); + + return ltrim(strtr($relativePath, '\\', '/'), '/'); + } + throw new \InvalidArgumentException( + sprintf("Path '%s' does not match configured repository directory", $repoPath) + ); + } +} diff --git a/application/modules/gitlist/src/Util/View.php b/application/modules/gitlist/src/Util/View.php new file mode 100644 index 0000000..9d8dc20 --- /dev/null +++ b/application/modules/gitlist/src/Util/View.php @@ -0,0 +1,49 @@ + $path) { + $breadcrumbs[] = array( + 'dir' => $path, + 'path' => implode('/', array_slice($paths, 0, $i + 1)), + ); + } + + return $breadcrumbs; + } + + public function getPager($pageNumber, $totalCommits) + { + $pageNumber = (empty($pageNumber)) ? 0 : $pageNumber; + $lastPage = (int) ($totalCommits / 15); + + // If total commits are integral multiple of 15, the lastPage will be commits/15 - 1. + $lastPage = ($lastPage * 15 == $totalCommits) ? $lastPage - 1 : $lastPage; + $nextPage = $pageNumber + 1; + $previousPage = $pageNumber - 1; + + return array('current' => $pageNumber, + 'next' => $nextPage, + 'previous' => $previousPage, + 'last' => $lastPage, + 'total' => $totalCommits, + ); + } +} diff --git a/application/modules/gitlist/themes/default/twig/blame.twig b/application/modules/gitlist/themes/default/twig/blame.twig new file mode 100644 index 0000000..d58d918 --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/blame.twig @@ -0,0 +1,25 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'commits' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Blame', path:''}]} %} + +
+
+
{{ file }}
+
+ + {% for blame in blames %} + + + + + {% endfor %} +
{{ blame.commitShort }}
{{ blame.line }}
+
+ +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/branch_menu.twig b/application/modules/gitlist/themes/default/twig/branch_menu.twig new file mode 100644 index 0000000..c627d1d --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/branch_menu.twig @@ -0,0 +1,21 @@ +
+ + + +
\ No newline at end of file diff --git a/application/modules/gitlist/themes/default/twig/breadcrumb.twig b/application/modules/gitlist/themes/default/twig/breadcrumb.twig new file mode 100644 index 0000000..735e8d7 --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/breadcrumb.twig @@ -0,0 +1,9 @@ + diff --git a/application/modules/gitlist/themes/default/twig/commit.twig b/application/modules/gitlist/themes/default/twig/commit.twig new file mode 100644 index 0000000..c80a05f --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/commit.twig @@ -0,0 +1,82 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'commits' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: "Commit #{commit.hash}", path:''}]} %} + +
+
+ Browse code +

{{ commit.message }}

+
+
+ {% if commit.body is not empty %} +

{{ commit.body | nl2br }}

+ {% endif %} + + + {{ commit.author.name }} authored on {{ commit.date | format_date }} + {% if commit.author.email != commit.commiter.email %} + • {{ commit.commiter.name }} committed on {{ commit.commiterDate | format_date }} + {% endif %} +
Showing {{ commit.changedFiles }} changed files +
+
+
+ +
    + {% for diff in commit.diffs %} +
  • {{ diff.file }} {{ diff.index }}
  • + {% endfor %} +
+ + {% for diff in commit.diffs %} +
+ + +
+ + {% for line in diff.getLines %} + + + + + + {% endfor %} +
+ {% if line.getType != 'chunk' %} + + + {% endif %} + {{ line.getNumOld }} + {% if line.getType != 'chunk' %} + + {% endif %} + + {% if line.getType != 'chunk' %} + + + {% endif %} + {{ line.getNumNew }} + {% if line.getType != 'chunk' %} + + {% endif %} + + {{ line.getLine }} +
+
+
+ {% endfor %} + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/commits.twig b/application/modules/gitlist/themes/default/twig/commits.twig new file mode 100644 index 0000000..b059ff7 --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/commits.twig @@ -0,0 +1,13 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'commits' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Commit history', path:''}]} %} + + {% include 'commits_list.twig' %} + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/commits_list.twig b/application/modules/gitlist/themes/default/twig/commits_list.twig new file mode 100644 index 0000000..6521276 --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/commits_list.twig @@ -0,0 +1,45 @@ +{% if commits %} +{% for date, commit in commits %} + + + + + + + + {% for item in commit %} + + + + + {% endfor %} + +
{{ date | date("F j, Y") }}
+ View {{ item.shortHash }} +

{{ item.message }}

+ + {{ item.author.name }} authored on {{ item.date | format_date }} + {% if item.author.email != item.commiter.email %} + • {{ item.commiter.name }} committed on {{ item.commiterDate | format_date }} + {% endif %} + +
+{% endfor %} +{% else %} +

No results found.

+{% endif %} + +{% if page != 'searchcommits' %} +
    + {% if pager.current != 0 %} + + {% endif %} + {% if pager.current != pager.last %} + + {% endif %} +
+{% endif %} diff --git a/application/modules/gitlist/themes/default/twig/error.twig b/application/modules/gitlist/themes/default/twig/error.twig new file mode 100644 index 0000000..a22e67d --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/error.twig @@ -0,0 +1,17 @@ +{% extends 'layout.twig' %} +{% block title %}GitList{% endblock %} + +{% block body %} +{% include 'navigation.twig' %} + +
+ +
+ Oops! {{ message }} +
+ +
+ + {% include 'footer.twig' %} +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/file.twig b/application/modules/gitlist/themes/default/twig/file.twig new file mode 100644 index 0000000..34ea180 --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/file.twig @@ -0,0 +1,33 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'files' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: breadcrumbs} %} + +
+
+
+ + +
+ {% if fileType == 'image' %} +
{{ file }}
+ + {% elseif fileType == 'markdown' %} +
{{ blob }}
+ + {% else %} +
{{ blob|htmlentities|raw }}
+ {% endif %} +
+ +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/footer.twig b/application/modules/gitlist/themes/default/twig/footer.twig new file mode 100644 index 0000000..f76aa82 --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/footer.twig @@ -0,0 +1,3 @@ + diff --git a/application/modules/gitlist/themes/default/twig/index.twig b/application/modules/gitlist/themes/default/twig/index.twig new file mode 100644 index 0000000..1f52c6e --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/index.twig @@ -0,0 +1,34 @@ +{% extends 'layout.twig' %} +{% block title %}GitList{% endblock %} + +{% block body %} +{% include 'navigation.twig' %} + +
+ + +
+ {% for repository in repositories %} +
+ +
+ {% if repository.description %} +

{{ repository.description }}

+ {% else %} +

There is no repository description file. Please, create one to remove this message.

+ {% endif %} +
+
+ {% endfor %} +
+ +
+ + {% include 'footer.twig' %} +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/layout.twig b/application/modules/gitlist/themes/default/twig/layout.twig new file mode 100644 index 0000000..c26d259 --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/layout.twig @@ -0,0 +1,30 @@ + + + + + {{ title }}{% if title %} - {% endif %}{% block title %}Welcome!{% endblock %} + + + + + + + + {% block body %}{% endblock %} + {% block javascripts %} + + + + + + + + + + + + {% endblock %} + + diff --git a/application/modules/gitlist/themes/default/twig/layout_page.twig b/application/modules/gitlist/themes/default/twig/layout_page.twig new file mode 100644 index 0000000..307fffb --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/layout_page.twig @@ -0,0 +1,31 @@ +{% extends 'layout.twig' %} + +{% block body %} + {% include 'navigation.twig' %} + +
+
+
+ {% if page in ['commits', 'searchcommits'] %} + + {% else %} + + {% endif %} + + {% if branches is defined %} + {% include 'branch_menu.twig' %} + {% endif %} + + {% include 'menu.twig' %} +
+
+ + {% block content %}{% endblock %} + + {% include 'footer.twig' %} +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/logpatch.twig b/application/modules/gitlist/themes/default/twig/logpatch.twig new file mode 100644 index 0000000..361a8a6 --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/logpatch.twig @@ -0,0 +1,83 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'commits' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + + {% include 'breadcrumb.twig' with {breadcrumbs: breadcrumbs} %} + + {% for commit in commits %} + +
+
+ Browse code +

{{ commit.message }}

+
+
+ {% if commit.body is not empty %} +

{{ commit.body | nl2br }}

+ {% endif %} + + + {{ commit.author.name }} authored on {{ commit.date | format_date }} + {% if commit.author.email != commit.commiter.email %} + • {{ commit.commiter.name }} committed on {{ commit.commiterDate | format_date }} + {% endif %} +
Showing {{ commit.changedFiles }} changed files +
+
+
+ + {% for diff in commit.diffs %} +
+ + +
+ + {% for line in diff.getLines %} + + + + + + {% endfor %} +
+ {% if line.getType != 'chunk' %} + + + {% endif %} + {{ line.getNumOld }} + {% if line.getType != 'chunk' %} + + {% endif %} + + {% if line.getType != 'chunk' %} + + + {% endif %} + {{ line.getNumNew }} + {% if line.getType != 'chunk' %} + + {% endif %} + + {{ line.getLine }} +
+
+
+ {% endfor %} + + {% endfor %} + + + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/menu.twig b/application/modules/gitlist/themes/default/twig/menu.twig new file mode 100644 index 0000000..f98e5e1 --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/menu.twig @@ -0,0 +1,7 @@ + diff --git a/application/modules/gitlist/themes/default/twig/navigation.twig b/application/modules/gitlist/themes/default/twig/navigation.twig new file mode 100644 index 0000000..cf8df6b --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/navigation.twig @@ -0,0 +1,20 @@ + diff --git a/application/modules/gitlist/themes/default/twig/network.twig b/application/modules/gitlist/themes/default/twig/network.twig new file mode 100644 index 0000000..8d5b31d --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/network.twig @@ -0,0 +1,23 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'network' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Network', path:''}]} %} +
+
+
Network Graph of {{ repo }} / {{ commitishPath }}
+
+ +
+ {#
#} + +
+
+ + + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/rss.twig b/application/modules/gitlist/themes/default/twig/rss.twig new file mode 100644 index 0000000..9416ca8 --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/rss.twig @@ -0,0 +1,18 @@ + + + + Latest commits in {{ repo }}:{{ branch }} + RSS provided by GitList + {{ url('homepage') }} + + {% for commit in commits %} + + {{ commit.message }} + {{ commit.author.name }} authored {{ commit.shortHash }} in {{ commit.date | format_date }} + {{ url('commit', {repo: repo, commit: commit.hash}) }} + {{ commit.date | date('r') }} + {{ commit.author.email }} ({{ commit.author.name }}) + + {% endfor %} + + diff --git a/application/modules/gitlist/themes/default/twig/search.twig b/application/modules/gitlist/themes/default/twig/search.twig new file mode 100644 index 0000000..c01abb8 --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/search.twig @@ -0,0 +1,42 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'files' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% embed 'breadcrumb.twig' with {breadcrumbs: breadcrumbs} %} + {% block extra %} +
+
+ ZIP + TAR +
+ +
+ {% endblock %} + {% endembed %} + + {% if results %} + + + + + + + + + {% for result in results %} + + + + + {% endfor %} + +
namematch
{{ result.file }}{{ result.match }}
+ {% else %} +

No results found.

+ {% endif %} + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/searchcommits.twig b/application/modules/gitlist/themes/default/twig/searchcommits.twig new file mode 100644 index 0000000..20495bc --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/searchcommits.twig @@ -0,0 +1,13 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'searchcommits' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Commits search results for: ' ~ query, path:''}]} %} + + {% include 'commits_list.twig' %} + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/stats.twig b/application/modules/gitlist/themes/default/twig/stats.twig new file mode 100644 index 0000000..495663e --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/stats.twig @@ -0,0 +1,48 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'stats' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Statistics', path:''}]} %} + + + + + + + + + + + + + + + + +
File extensions ({{ stats.extensions|length }})Authors ({{ authors|length }})Other
+
    + {% for ext, amount in stats.extensions %} +
  • {{ ext }}: {{ amount }} files
  • + {% endfor %} +
+
+
    + {% for author in authors %} +
  • {{ author.name }}: {{ author.commits }} commits
  • + {% endfor %} +
+
+

+ Total files: {{ stats.files }} +

+ +

+ Total bytes: {{ stats.size }} bytes ({{ stats.size | format_size }}) +

+
+ +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/tree.twig b/application/modules/gitlist/themes/default/twig/tree.twig new file mode 100644 index 0000000..984513a --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/tree.twig @@ -0,0 +1,95 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'files' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% embed 'breadcrumb.twig' with {breadcrumbs: breadcrumbs} %} + {% block extra %} +
+
+ {% if show_http_remote or show_ssh_remote %} + Clone + {% endif %} + ZIP + TAR +
+ +
+ {% if show_http_remote or show_ssh_remote %} +
+
+ × +
+ {% if show_ssh_remote %} + + {% endif %} + {% if show_http_remote %} + + {% endif %} +

+ {% if show_ssh_remote %} + + {% endif %} + {% if show_http_remote %} + + {% endif %} +
+
+ {% endif %} + {% endblock %} + {% endembed %} + + {% if files is not empty %} + + + + + + + + + + {% if parent is not null %} + + + + + + {% endif %} + {% for file in files %} + + + + + + {% endfor %} + +
namemodesize
+ {% if not parent %} + .. + {% else %} + .. + {% endif %} +
{{ file.name }}{{ file.mode }}{% if file.size %}{{ file.size | format_size }}{% endif %}
+ {% else %} +

This repository is empty.

+ {% endif %} + {% if readme is defined and readme is not empty %} +
+
+
{{ readme.filename }}
+
+
{{ readme.content }}
+
+ {% endif %} + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default/twig/treegraph.twig b/application/modules/gitlist/themes/default/twig/treegraph.twig new file mode 100644 index 0000000..a8bd45b --- /dev/null +++ b/application/modules/gitlist/themes/default/twig/treegraph.twig @@ -0,0 +1,48 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'treegraph' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Graph', path:''}]} %} +
+
+
Graph of {{ repo }}
+
+ +
+
+ +
    + {% for item in graphItems %} +
  • {{ item.relation }}
  • + {% endfor %} +
+
+
+
+
    + {% for item in graphItems %} +
  • + {% if item.rev is defined %} + {{ item.short_rev }} + {{ item.branch }} + {{ item.subject }} by + {{ item.author }} <{{ item.author_email }}> + {{ item.date }}; + {% else %} + + {% endif %} +
  • + {% endfor %} +
+
+
+
+
+ + + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/blame.twig b/application/modules/gitlist/themes/default_without_html/twig/blame.twig new file mode 100644 index 0000000..d58d918 --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/blame.twig @@ -0,0 +1,25 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'commits' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Blame', path:''}]} %} + +
+
+
{{ file }}
+
+ + {% for blame in blames %} + + + + + {% endfor %} +
{{ blame.commitShort }}
{{ blame.line }}
+
+ +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/branch_menu.twig b/application/modules/gitlist/themes/default_without_html/twig/branch_menu.twig new file mode 100644 index 0000000..c627d1d --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/branch_menu.twig @@ -0,0 +1,21 @@ +
+ + + +
\ No newline at end of file diff --git a/application/modules/gitlist/themes/default_without_html/twig/breadcrumb.twig b/application/modules/gitlist/themes/default_without_html/twig/breadcrumb.twig new file mode 100644 index 0000000..735e8d7 --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/breadcrumb.twig @@ -0,0 +1,9 @@ + diff --git a/application/modules/gitlist/themes/default_without_html/twig/commit.twig b/application/modules/gitlist/themes/default_without_html/twig/commit.twig new file mode 100644 index 0000000..c80a05f --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/commit.twig @@ -0,0 +1,82 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'commits' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: "Commit #{commit.hash}", path:''}]} %} + +
+
+ Browse code +

{{ commit.message }}

+
+
+ {% if commit.body is not empty %} +

{{ commit.body | nl2br }}

+ {% endif %} + + + {{ commit.author.name }} authored on {{ commit.date | format_date }} + {% if commit.author.email != commit.commiter.email %} + • {{ commit.commiter.name }} committed on {{ commit.commiterDate | format_date }} + {% endif %} +
Showing {{ commit.changedFiles }} changed files +
+
+
+ +
    + {% for diff in commit.diffs %} +
  • {{ diff.file }} {{ diff.index }}
  • + {% endfor %} +
+ + {% for diff in commit.diffs %} +
+ + +
+ + {% for line in diff.getLines %} + + + + + + {% endfor %} +
+ {% if line.getType != 'chunk' %} + + + {% endif %} + {{ line.getNumOld }} + {% if line.getType != 'chunk' %} + + {% endif %} + + {% if line.getType != 'chunk' %} + + + {% endif %} + {{ line.getNumNew }} + {% if line.getType != 'chunk' %} + + {% endif %} + + {{ line.getLine }} +
+
+
+ {% endfor %} + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/commits.twig b/application/modules/gitlist/themes/default_without_html/twig/commits.twig new file mode 100644 index 0000000..b059ff7 --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/commits.twig @@ -0,0 +1,13 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'commits' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Commit history', path:''}]} %} + + {% include 'commits_list.twig' %} + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/commits_list.twig b/application/modules/gitlist/themes/default_without_html/twig/commits_list.twig new file mode 100644 index 0000000..6521276 --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/commits_list.twig @@ -0,0 +1,45 @@ +{% if commits %} +{% for date, commit in commits %} + + + + + + + + {% for item in commit %} + + + + + {% endfor %} + +
{{ date | date("F j, Y") }}
+ View {{ item.shortHash }} +

{{ item.message }}

+ + {{ item.author.name }} authored on {{ item.date | format_date }} + {% if item.author.email != item.commiter.email %} + • {{ item.commiter.name }} committed on {{ item.commiterDate | format_date }} + {% endif %} + +
+{% endfor %} +{% else %} +

No results found.

+{% endif %} + +{% if page != 'searchcommits' %} +
    + {% if pager.current != 0 %} + + {% endif %} + {% if pager.current != pager.last %} + + {% endif %} +
+{% endif %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/error.twig b/application/modules/gitlist/themes/default_without_html/twig/error.twig new file mode 100644 index 0000000..a22e67d --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/error.twig @@ -0,0 +1,17 @@ +{% extends 'layout.twig' %} +{% block title %}GitList{% endblock %} + +{% block body %} +{% include 'navigation.twig' %} + +
+ +
+ Oops! {{ message }} +
+ +
+ + {% include 'footer.twig' %} +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/file.twig b/application/modules/gitlist/themes/default_without_html/twig/file.twig new file mode 100644 index 0000000..34ea180 --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/file.twig @@ -0,0 +1,33 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'files' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: breadcrumbs} %} + +
+
+
+ + +
+ {% if fileType == 'image' %} +
{{ file }}
+ + {% elseif fileType == 'markdown' %} +
{{ blob }}
+ + {% else %} +
{{ blob|htmlentities|raw }}
+ {% endif %} +
+ +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/footer.twig b/application/modules/gitlist/themes/default_without_html/twig/footer.twig new file mode 100644 index 0000000..f76aa82 --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/footer.twig @@ -0,0 +1,3 @@ + diff --git a/application/modules/gitlist/themes/default_without_html/twig/index.twig b/application/modules/gitlist/themes/default_without_html/twig/index.twig new file mode 100644 index 0000000..1f52c6e --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/index.twig @@ -0,0 +1,34 @@ +{% extends 'layout.twig' %} +{% block title %}GitList{% endblock %} + +{% block body %} +{% include 'navigation.twig' %} + +
+ + +
+ {% for repository in repositories %} +
+ +
+ {% if repository.description %} +

{{ repository.description }}

+ {% else %} +

There is no repository description file. Please, create one to remove this message.

+ {% endif %} +
+
+ {% endfor %} +
+ +
+ + {% include 'footer.twig' %} +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/layout.twig b/application/modules/gitlist/themes/default_without_html/twig/layout.twig new file mode 100644 index 0000000..a884f33 --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/layout.twig @@ -0,0 +1,21 @@ + + + + + + + {% block body %}{% endblock %} + {% block javascripts %} + + + + + + + + + + + + {% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/layout_page.twig b/application/modules/gitlist/themes/default_without_html/twig/layout_page.twig new file mode 100644 index 0000000..307fffb --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/layout_page.twig @@ -0,0 +1,31 @@ +{% extends 'layout.twig' %} + +{% block body %} + {% include 'navigation.twig' %} + +
+
+
+ {% if page in ['commits', 'searchcommits'] %} + + {% else %} + + {% endif %} + + {% if branches is defined %} + {% include 'branch_menu.twig' %} + {% endif %} + + {% include 'menu.twig' %} +
+
+ + {% block content %}{% endblock %} + + {% include 'footer.twig' %} +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/logpatch.twig b/application/modules/gitlist/themes/default_without_html/twig/logpatch.twig new file mode 100644 index 0000000..361a8a6 --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/logpatch.twig @@ -0,0 +1,83 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'commits' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + + {% include 'breadcrumb.twig' with {breadcrumbs: breadcrumbs} %} + + {% for commit in commits %} + +
+
+ Browse code +

{{ commit.message }}

+
+
+ {% if commit.body is not empty %} +

{{ commit.body | nl2br }}

+ {% endif %} + + + {{ commit.author.name }} authored on {{ commit.date | format_date }} + {% if commit.author.email != commit.commiter.email %} + • {{ commit.commiter.name }} committed on {{ commit.commiterDate | format_date }} + {% endif %} +
Showing {{ commit.changedFiles }} changed files +
+
+
+ + {% for diff in commit.diffs %} +
+ + +
+ + {% for line in diff.getLines %} + + + + + + {% endfor %} +
+ {% if line.getType != 'chunk' %} + + + {% endif %} + {{ line.getNumOld }} + {% if line.getType != 'chunk' %} + + {% endif %} + + {% if line.getType != 'chunk' %} + + + {% endif %} + {{ line.getNumNew }} + {% if line.getType != 'chunk' %} + + {% endif %} + + {{ line.getLine }} +
+
+
+ {% endfor %} + + {% endfor %} + + + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/menu.twig b/application/modules/gitlist/themes/default_without_html/twig/menu.twig new file mode 100644 index 0000000..f98e5e1 --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/menu.twig @@ -0,0 +1,7 @@ + diff --git a/application/modules/gitlist/themes/default_without_html/twig/navigation.twig b/application/modules/gitlist/themes/default_without_html/twig/navigation.twig new file mode 100644 index 0000000..cf8df6b --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/navigation.twig @@ -0,0 +1,20 @@ + diff --git a/application/modules/gitlist/themes/default_without_html/twig/network.twig b/application/modules/gitlist/themes/default_without_html/twig/network.twig new file mode 100644 index 0000000..8d5b31d --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/network.twig @@ -0,0 +1,23 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'network' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Network', path:''}]} %} +
+
+
Network Graph of {{ repo }} / {{ commitishPath }}
+
+ +
+ {#
#} + +
+
+ + + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/rss.twig b/application/modules/gitlist/themes/default_without_html/twig/rss.twig new file mode 100644 index 0000000..9416ca8 --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/rss.twig @@ -0,0 +1,18 @@ + + + + Latest commits in {{ repo }}:{{ branch }} + RSS provided by GitList + {{ url('homepage') }} + + {% for commit in commits %} + + {{ commit.message }} + {{ commit.author.name }} authored {{ commit.shortHash }} in {{ commit.date | format_date }} + {{ url('commit', {repo: repo, commit: commit.hash}) }} + {{ commit.date | date('r') }} + {{ commit.author.email }} ({{ commit.author.name }}) + + {% endfor %} + + diff --git a/application/modules/gitlist/themes/default_without_html/twig/search.twig b/application/modules/gitlist/themes/default_without_html/twig/search.twig new file mode 100644 index 0000000..c01abb8 --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/search.twig @@ -0,0 +1,42 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'files' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% embed 'breadcrumb.twig' with {breadcrumbs: breadcrumbs} %} + {% block extra %} +
+
+ ZIP + TAR +
+ +
+ {% endblock %} + {% endembed %} + + {% if results %} + + + + + + + + + {% for result in results %} + + + + + {% endfor %} + +
namematch
{{ result.file }}{{ result.match }}
+ {% else %} +

No results found.

+ {% endif %} + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/searchcommits.twig b/application/modules/gitlist/themes/default_without_html/twig/searchcommits.twig new file mode 100644 index 0000000..20495bc --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/searchcommits.twig @@ -0,0 +1,13 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'searchcommits' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Commits search results for: ' ~ query, path:''}]} %} + + {% include 'commits_list.twig' %} + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/stats.twig b/application/modules/gitlist/themes/default_without_html/twig/stats.twig new file mode 100644 index 0000000..495663e --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/stats.twig @@ -0,0 +1,48 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'stats' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Statistics', path:''}]} %} + + + + + + + + + + + + + + + + +
File extensions ({{ stats.extensions|length }})Authors ({{ authors|length }})Other
+
    + {% for ext, amount in stats.extensions %} +
  • {{ ext }}: {{ amount }} files
  • + {% endfor %} +
+
+
    + {% for author in authors %} +
  • {{ author.name }}: {{ author.commits }} commits
  • + {% endfor %} +
+
+

+ Total files: {{ stats.files }} +

+ +

+ Total bytes: {{ stats.size }} bytes ({{ stats.size | format_size }}) +

+
+ +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/tree.twig b/application/modules/gitlist/themes/default_without_html/twig/tree.twig new file mode 100644 index 0000000..984513a --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/tree.twig @@ -0,0 +1,95 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'files' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% embed 'breadcrumb.twig' with {breadcrumbs: breadcrumbs} %} + {% block extra %} +
+
+ {% if show_http_remote or show_ssh_remote %} + Clone + {% endif %} + ZIP + TAR +
+ +
+ {% if show_http_remote or show_ssh_remote %} +
+
+ × +
+ {% if show_ssh_remote %} + + {% endif %} + {% if show_http_remote %} + + {% endif %} +

+ {% if show_ssh_remote %} + + {% endif %} + {% if show_http_remote %} + + {% endif %} +
+
+ {% endif %} + {% endblock %} + {% endembed %} + + {% if files is not empty %} + + + + + + + + + + {% if parent is not null %} + + + + + + {% endif %} + {% for file in files %} + + + + + + {% endfor %} + +
namemodesize
+ {% if not parent %} + .. + {% else %} + .. + {% endif %} +
{{ file.name }}{{ file.mode }}{% if file.size %}{{ file.size | format_size }}{% endif %}
+ {% else %} +

This repository is empty.

+ {% endif %} + {% if readme is defined and readme is not empty %} +
+
+
{{ readme.filename }}
+
+
{{ readme.content }}
+
+ {% endif %} + +
+{% endblock %} diff --git a/application/modules/gitlist/themes/default_without_html/twig/treegraph.twig b/application/modules/gitlist/themes/default_without_html/twig/treegraph.twig new file mode 100644 index 0000000..a8bd45b --- /dev/null +++ b/application/modules/gitlist/themes/default_without_html/twig/treegraph.twig @@ -0,0 +1,48 @@ +{% extends 'layout_page.twig' %} + +{% set page = 'treegraph' %} + +{% block title %}GitList{% endblock %} + +{% block content %} + {% include 'breadcrumb.twig' with {breadcrumbs: [{dir: 'Graph', path:''}]} %} +
+
+
Graph of {{ repo }}
+
+ +
+
+ +
    + {% for item in graphItems %} +
  • {{ item.relation }}
  • + {% endfor %} +
+
+
+
+
    + {% for item in graphItems %} +
  • + {% if item.rev is defined %} + {{ item.short_rev }} + {{ item.branch }} + {{ item.subject }} by + {{ item.author }} <{{ item.author_email }}> + {{ item.date }}; + {% else %} + + {% endif %} +
  • + {% endfor %} +
+
+
+
+
+ + + +
+{% endblock %} diff --git a/application/objets/Ldap.php b/application/objets/Ldap.php new file mode 100644 index 0000000..5cfabc4 --- /dev/null +++ b/application/objets/Ldap.php @@ -0,0 +1,66 @@ +requête de test de LDAP'; + + echo 'Connexion ...'; + $ds = ldap_connect(LDAP_URL,LDAP_PORT); // doit être un serveur LDAP valide ! + echo 'Le résultat de connexion est ' . $ds . '
'; + + if ($ds) { + echo 'Liaison ...'; + $r = ldap_bind_ext($ds, LDAP_USER, LDAP_PASSWORD); + //$r = ldap_bind($ds); // connexion anonyme, typique + // pour un accès en lecture seule. + echo 'Le résultat de connexion depuis ' . $_SERVER['SERVER_ADDR'] . ' est ' . $r . '
'; + + echo 'Recherchons (uid=m*) ...'; + // Recherche par nom de famille + $sr=ldap_search($ds, "ou=people, dc=univ-fcomte, dc=fr", "uid=m*"); + echo 'Le résultat de la recherche est ' . $sr . '
'; + + echo 'Le nombre d\'entrées retournées est ' . ldap_count_entries($ds,$sr) + . '
'; + + echo 'Lecture des entrées ...
'; + $info = ldap_get_entries($ds, $sr); + echo 'Données pour ' . $info["count"] . ' entrées:
'; + echo "
    "; + for ($i=0; $i<$info["count"]; $i++) { + echo "
  • " . $info[$i]['mail'][0] ; + echo "
      "; + foreach($info[$i] as $key => $value){ + if(is_int($key)) continue; + echo "
    • " . $key . ' est : '; + echo "
        "; + if(isset($value["count"])) { + for ($j = 0; $j < $value["count"]; $j++) { + echo "
      • " . $value[$j] . "
      • "; + } + }else{ + echo "
      • " . $value . "
      • "; + } + echo "
      "; + echo "
    • "; + } + echo "
    "; + echo "
  • "; + } + echo "
"; + echo ""; + + echo 'Fermeture de la connexion'; + ldap_close($ds); + + } else { + echo '

Impossible de se connecter au serveur LDAP.

'; + } + + } +} \ No newline at end of file diff --git a/console/command/Action.php b/console/command/Action.php new file mode 100644 index 0000000..f419d3a --- /dev/null +++ b/console/command/Action.php @@ -0,0 +1,25 @@ +render('', array()); + } + + +} diff --git a/console/skel/conduit.php.skel b/console/skel/conduit.php.skel new file mode 100644 index 0000000..fec42e1 --- /dev/null +++ b/console/skel/conduit.php.skel @@ -0,0 +1,25 @@ +id != 'undefined') { + $bdd = new \MVC\Classe\Bdd(); + $sql = "SELECT * FROM table WHERE id = '{$this->id}';"; + $req = $bdd->faireSQLRequete($sql); + $data = $bdd->exploiterResultat($req); + } else { + $data = false; + } + + return $this->render('', array()); + } + +} diff --git a/console/skel/module.blade.php b/console/skel/module.blade.php index 0d749a0..0967505 100644 --- a/console/skel/module.blade.php +++ b/console/skel/module.blade.php @@ -1 +1 @@ -{{$app->load('MODULE')}} \ No newline at end of file +{{$app->load('%%MODULE%%')}} \ No newline at end of file diff --git a/console/skel/module.model b/console/skel/module.model index 2142f46..00b3cd3 100644 --- a/console/skel/module.model +++ b/console/skel/module.model @@ -1,5 +1,6 @@ -name : MODULE +name : %%MODULE%% page_title : module_title description : module_description -params : module_params +ariane : {%%MODULE%%} +arianelink : {%%MODULE%%} diff --git a/console/skel/module.php b/console/skel/module.php index 91900d9..3405910 100644 --- a/console/skel/module.php +++ b/console/skel/module.php @@ -1,3 +1,3 @@ $app); diff --git a/console/skel/module_symfony.php b/console/skel/module_symfony.php index df1353d..9e1a3c3 100644 --- a/console/skel/module_symfony.php +++ b/console/skel/module_symfony.php @@ -3,5 +3,5 @@ use MVC\Classe\Session; Session::start(); -$app = new MVC\Classe\Modular($name, 'MODULE', $url_params); +$app = new MVC\Classe\Modular($name, '%%MODULE%%', $url_params); $templateData = array('app' => $app); diff --git a/console/skel/page.blade.php b/console/skel/page.blade.php index eb4a52f..0909c50 100644 --- a/console/skel/page.blade.php +++ b/console/skel/page.blade.php @@ -6,7 +6,7 @@ @endsection @section('content') -

%PAGE% Controlleur

+

%%PAGE%% Controlleur




@if (isset($id)) {{$id}} diff --git a/console/skel/page.html.twig b/console/skel/page.html.twig new file mode 100644 index 0000000..9e48139 --- /dev/null +++ b/console/skel/page.html.twig @@ -0,0 +1,20 @@ +{% extends "base.html" %} + +{% block top-css %} + {{ parent() }} +{% endblock %} + +{% block top-javascript %} + {{ parent() }} +{% endblock %} + +{% block bottom-javascript %} + {{ parent() }} +{% endblock %} + +{% block content %} +

%%PAGE%%

+

+ Welcome to my awesome homepage. +

+{% endblock %} \ No newline at end of file diff --git a/console/skel/page.model b/console/skel/page.model index 9f05b6a..c2a4338 100644 --- a/console/skel/page.model +++ b/console/skel/page.model @@ -1,6 +1,7 @@ -name : PAGE +name : %%PAGE%% page_title : module_title description : module_description -engine : blade -params : module_params +engine : %%ENGINE%% +ariane : {acceuil, %%PAGE%%} +arianelink : {index, %%PAGE%%} diff --git a/public/.htaccess b/public/.htaccess index 3b4f6bb..37f414a 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -19,7 +19,7 @@ # Options +SymLinksIfOwnerMatch # (4) - #RewriteBase /directory/public/ + #RewriteBase /fiches3pro/public/ #RewriteBase / # (5) @@ -27,9 +27,8 @@ # (6) RewriteCond %{REQUEST_FILENAME} !-f - RewriteCond %{REQUEST_FILENAME} !-d - RewriteRule ^(.*)$ /index.php [L] - RewriteRule ^$ /index.php [L] + #RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . index.php [L] diff --git a/public/assets/css/custom-320.css b/public/assets/css/custom-320.css new file mode 100644 index 0000000..decede3 --- /dev/null +++ b/public/assets/css/custom-320.css @@ -0,0 +1,32 @@ +/* + +1. Add your custom Css styles below +2. Place the this code in your template: + + + +*/ + +@media (max-width: 540px) { + table.contour_table tr td { + display: block; + text-align: center; + } + table.contour_table tr th { + display: block; + text-align: center; + } + .nav-link{ + color:slategray !important; + } + .nav-link:hover{ + color:darkslategray !important; + } + .nav-item { + background-color: white !important; + } + .navbar { + background-color: darkslateblue; + z-index: 100; + } +} \ No newline at end of file diff --git a/public/assets/css/custom.css b/public/assets/css/custom.css index 7d52d79..0a539a4 100644 --- a/public/assets/css/custom.css +++ b/public/assets/css/custom.css @@ -55,6 +55,7 @@ dl, ol, ul { width: 250px; border: 2px solid transparent; margin: 0 auto; + margin-left: auto; padding: 23px 30px; color: #fff; font-weight: 400; @@ -76,15 +77,24 @@ dl, ol, ul { padding-bottom: 2rem; } -/** Sub Menu sub bar, visible on mobile **/ -#sub-bar{ - height: 25px; +/** SubBar **/ +#subbar{ + height: 1.2rem; background-color: antiquewhite; font-size: 0.7rem; - margin-bottom: 2rem; - padding-top: 5px; } -/** Sub Menu top bar , invisible on mobile **/ +/** Breadcrumbs **/ +#breadcrumbs{ + clear:both; + height: 1.2rem; + background-color: whitesmoke; + font-size: 0.7rem; +} +/** Page content spacing **/ +#page-content{ + padding-top: 2rem; +} +/** Top menu bar ,invisible on mobile**/ .top-menu{ display: flex; justify-content: end; @@ -97,6 +107,14 @@ dl, ol, ul { .top-menu > li:hover{ background-color: slategrey; } +.top-menu > li > a{ + color:darkslategray; + text-decoration: none; +} +.top-menu > li > a:hover{ + color: black; +} + /** Menu de navigation **/ nav > ul { display:flex; diff --git a/public/humans.txt b/public/humans.txt index 7c6578c..72be02a 100644 --- a/public/humans.txt +++ b/public/humans.txt @@ -13,7 +13,7 @@ /* SITE */ Standards: HTML5, CSS3 - Components: Blade, Vue.js + Components: Modernizr, jQuery Software: