From 42160b1ca17b7fd58afc05e763e2bfe4379eea74 Mon Sep 17 00:00:00 2001 From: briskt <3172830+briskt@users.noreply.github.com> Date: Tue, 21 May 2024 14:29:55 +0800 Subject: [PATCH 1/9] copy content from the simplesamlphp-module-material repo https://github.com/silinternational/simplesamlphp-module-material --- README.md | 69 ++ docs/material_tests.md | 187 +++++ .../dictionaries/about2expire.definition.json | 45 ++ .../dictionaries/error.definition.json | 21 + .../dictionaries/expired.definition.json | 27 + .../dictionaries/footer.definition.json | 9 + .../dictionaries/login.definition.json | 62 ++ .../dictionaries/logout.definition.json | 21 + .../material/dictionaries/mfa.definition.json | 399 ++++++++++ .../material/dictionaries/nag.definition.json | 75 ++ .../dictionaries/review.definition.json | 75 ++ .../dictionaries/selectidp.definition.json | 38 + .../themes/material/common-announcement.php | 15 + .../themes/material/common-footer.php | 3 + .../themes/material/common-head-elements.php | 39 + .../themes/material/core/loginuserpass.php | 159 ++++ .../themes/material/default/error.php | 41 + .../themes/material/default/logout.php | 27 + .../material/default/selectidp-links.php | 124 +++ .../material/expirychecker/about2expire.php | 58 ++ .../themes/material/expirychecker/expired.php | 41 + .../material/mfa/low-on-backup-codes.php | 52 ++ .../themes/material/mfa/must-set-up-mfa.php | 48 ++ .../themes/material/mfa/new-backup-codes.php | 158 ++++ .../themes/material/mfa/other_mfas.php | 58 ++ .../material/mfa/out-of-backup-codes.php | 58 ++ .../mfa/prompt-for-mfa-backupcode.php | 92 +++ .../material/mfa/prompt-for-mfa-manager.php | 89 +++ .../material/mfa/prompt-for-mfa-totp.php | 92 +++ .../material/mfa/prompt-for-mfa-u2f.php | 175 ++++ .../material/mfa/prompt-for-mfa-webauthn.php | 157 ++++ .../themes/material/mfa/send-manager-mfa.php | 51 ++ .../material/profilereview/nag-for-method.php | 52 ++ .../material/profilereview/nag-for-mfa.php | 63 ++ .../themes/material/profilereview/review.php | 128 +++ modules/material/www/bowser.1.9.4.min.js | 6 + modules/material/www/default-favicon.ico | Bin 0 -> 5430 bytes modules/material/www/default-favicon.png | Bin 0 -> 1527 bytes modules/material/www/default-logo.png | Bin 0 -> 16314 bytes modules/material/www/email.svg | 1 + modules/material/www/material-icons.woff | Bin 0 -> 61928 bytes modules/material/www/material-icons.woff2 | Bin 0 -> 46740 bytes modules/material/www/material.1.2.1.min.js | 9 + .../www/material.blue_grey-teal.1.2.1.min.css | 8 + .../www/material.brown-orange.1.2.1.min.css | 8 + .../www/material.indigo-purple.1.2.1.min.css | 8 + .../material.orange-light_blue.1.2.1.min.css | 8 + .../www/material.red-teal.1.2.1.min.css | 8 + .../www/material.teal-blue.1.2.1.min.css | 8 + modules/material/www/mfa-backupcode.svg | 1 + modules/material/www/mfa-manager.svg | 3 + modules/material/www/mfa-totp.svg | 7 + modules/material/www/mfa-u2f-api.js | 748 ++++++++++++++++++ modules/material/www/mfa-u2f.svg | 27 + modules/material/www/mfa-webauthn.svg | 27 + modules/material/www/shield.svg | 3 + .../material/www/simplewebauthn/LICENSE.md | 21 + .../material/www/simplewebauthn/browser.js | 2 + modules/material/www/styles.2.3.6.css | 282 +++++++ 59 files changed, 3993 insertions(+) create mode 100644 docs/material_tests.md create mode 100644 modules/material/dictionaries/about2expire.definition.json create mode 100644 modules/material/dictionaries/error.definition.json create mode 100644 modules/material/dictionaries/expired.definition.json create mode 100644 modules/material/dictionaries/footer.definition.json create mode 100644 modules/material/dictionaries/login.definition.json create mode 100644 modules/material/dictionaries/logout.definition.json create mode 100644 modules/material/dictionaries/mfa.definition.json create mode 100644 modules/material/dictionaries/nag.definition.json create mode 100644 modules/material/dictionaries/review.definition.json create mode 100644 modules/material/dictionaries/selectidp.definition.json create mode 100644 modules/material/themes/material/common-announcement.php create mode 100644 modules/material/themes/material/common-footer.php create mode 100644 modules/material/themes/material/common-head-elements.php create mode 100644 modules/material/themes/material/core/loginuserpass.php create mode 100644 modules/material/themes/material/default/error.php create mode 100644 modules/material/themes/material/default/logout.php create mode 100644 modules/material/themes/material/default/selectidp-links.php create mode 100644 modules/material/themes/material/expirychecker/about2expire.php create mode 100644 modules/material/themes/material/expirychecker/expired.php create mode 100644 modules/material/themes/material/mfa/low-on-backup-codes.php create mode 100644 modules/material/themes/material/mfa/must-set-up-mfa.php create mode 100644 modules/material/themes/material/mfa/new-backup-codes.php create mode 100644 modules/material/themes/material/mfa/other_mfas.php create mode 100644 modules/material/themes/material/mfa/out-of-backup-codes.php create mode 100644 modules/material/themes/material/mfa/prompt-for-mfa-backupcode.php create mode 100644 modules/material/themes/material/mfa/prompt-for-mfa-manager.php create mode 100644 modules/material/themes/material/mfa/prompt-for-mfa-totp.php create mode 100644 modules/material/themes/material/mfa/prompt-for-mfa-u2f.php create mode 100644 modules/material/themes/material/mfa/prompt-for-mfa-webauthn.php create mode 100644 modules/material/themes/material/mfa/send-manager-mfa.php create mode 100644 modules/material/themes/material/profilereview/nag-for-method.php create mode 100644 modules/material/themes/material/profilereview/nag-for-mfa.php create mode 100644 modules/material/themes/material/profilereview/review.php create mode 100644 modules/material/www/bowser.1.9.4.min.js create mode 100644 modules/material/www/default-favicon.ico create mode 100644 modules/material/www/default-favicon.png create mode 100644 modules/material/www/default-logo.png create mode 100644 modules/material/www/email.svg create mode 100644 modules/material/www/material-icons.woff create mode 100644 modules/material/www/material-icons.woff2 create mode 100644 modules/material/www/material.1.2.1.min.js create mode 100644 modules/material/www/material.blue_grey-teal.1.2.1.min.css create mode 100644 modules/material/www/material.brown-orange.1.2.1.min.css create mode 100644 modules/material/www/material.indigo-purple.1.2.1.min.css create mode 100644 modules/material/www/material.orange-light_blue.1.2.1.min.css create mode 100644 modules/material/www/material.red-teal.1.2.1.min.css create mode 100644 modules/material/www/material.teal-blue.1.2.1.min.css create mode 100644 modules/material/www/mfa-backupcode.svg create mode 100644 modules/material/www/mfa-manager.svg create mode 100644 modules/material/www/mfa-totp.svg create mode 100644 modules/material/www/mfa-u2f-api.js create mode 100644 modules/material/www/mfa-u2f.svg create mode 100644 modules/material/www/mfa-webauthn.svg create mode 100644 modules/material/www/shield.svg create mode 100644 modules/material/www/simplewebauthn/LICENSE.md create mode 100644 modules/material/www/simplewebauthn/browser.js create mode 100644 modules/material/www/styles.2.3.6.css diff --git a/README.md b/README.md index f920c616..c94666ca 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,75 @@ This is adapted from the `ssp-iidp-expirycheck` and `expirycheck` modules. Thanks to Alex Mihičinac, Steve Moitozo, and Steve Bagwell for the initial work they did on those two modules. +### Material Module + +Material Design theme for use with SimpleSAMLphp + +#### Installation + +``` +composer.phar require silinternational/simplesamlphp-module-material:dev-master +``` + +#### Configuration + +Update `/simplesamlphp/config/config.php`: + +``` +'theme.use' => 'material:material' +``` + +This project provides a convenience by loading this config with whatever is in the environment variable `THEME_USE`._ + +##### Google reCAPTCHA + +If a site key has been provided in `$this->data['recaptcha.siteKey']`, the +username/password page may require the user prove his/her humanity. + +##### Branding + +Update `/simplesamlphp/config/config.php`: + +``` +'theme.color-scheme' => ['indigo-purple'|'blue_grey-teal'|'red-teal'|'orange-light_blue'|'brown-orange'|'teal-blue'] +``` + +The login page looks for `/simplesamlphp/www/logo.png` which is **NOT** provided by default. + +##### Analytics + +Update `/simplesamlphp/config/config.php`: + +``` +'analytics.trackingId' => 'UA-some-unique-id-for-your-site' +``` + +This project provides a convenience by loading this config with whatever is in the environment variable `ANALYTICS_ID`._ + +##### Announcements + +Update `/simplesamlphp/announcement/announcement.php`: + +``` + return 'Some important announcement'; +``` + +By default, the announcement is whatever is returned by `/simplesamlphp/announcement/announcement.php`._ + +If provided, an alert will be shown to the user filled with the content of that announcement. HTML is supported. + +#### Testing the Material theme + +[Manual tests](./docs/material_tests.md) + +#### i18n support + +Translations are categorized by page in definition files located in the `dictionaries` directory. + +Localization is affected by the configuration setting `language.available`. Only language codes found in this property will be utilized. +For example, if a translation is provided in Afrikaans for this module, the configuration must be adjusted to make 'af' an available +language. If that's not done, the translation function will not utilize the translations even if provided. + ### Multi-Factor Authentication (MFA) simpleSAMLphp Module A simpleSAMLphp module for prompting the user for MFA credentials (such as a TOTP code, etc.). diff --git a/docs/material_tests.md b/docs/material_tests.md new file mode 100644 index 00000000..fef075af --- /dev/null +++ b/docs/material_tests.md @@ -0,0 +1,187 @@ + +# Testing the Material Module theme + +[Make](https://www.gnu.org/software/make/), [Docker](https://www.docker.com/products/overview) and +[Docker Compose](https://docs.docker.com/compose/install/) are required. + +## Setup + +1. Setup `localhost` (or `192.168.62.54`, if using Vagrant) aliases for `ssp-hub1.local`, `ssp-hub2.local`, `ssp-idp1.local`, `ssp-idp2.local`, `ssp-idp3.local`, `ssp-idp4.local`, `ssp-sp1.local` and `ssp-sp2.local`. This is typically done in `/etc/hosts`. _Example line: `0.0.0.0 ssp-hub1.local ssp-idp1.local ssp-idp2.local ssp-idp4.local ssp-hub2.local ssp-idp3.local ssp-sp1.local ssp-sp2.local`_ +1. Start test environment, i.e., `make` from the command line. + +## Hub page + +1. Goto [Hub 1](http://ssp-hub1.local/module.php/core/authenticate.php?as=hub-discovery) + +## Error page + +1. Goto [Hub 1](http://ssp-hub1.local) +1. Click **Federation** tab +1. Click either **Show metadata** link +1. Login as hub administrator: `username=`**admin** `password=`**abc123** + +## Logout page + +1. Goto [Hub 1](http://ssp-hub1.local) +1. Click **Authentication** tab +1. Click **Test configured authentication sources** +1. Click **admin** +1. Login as hub administrator: `username=`**admin** `password=`**abc123** +1. Click **Logout** + +## Login page + +### Without theme in place + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp1** (first one) +1. login page should **NOT** have material design + +### With theme in place + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp2** (second one) +1. login page **SHOULD** have material design + +## Forgot password functionality + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp2** (second one) +1. Forgot password link should be visible + +## Helpful links functionality + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Help link should be visible under login form +1. Profile link should be visible under login form + +## Expiry functionality + +### About to expire page + +_Note: This nag only works once since choosing later will simply set the nag date into the future a little._ + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp2** (second one) +1. Login as an "about to expire" user: `username=`**near_future** `password=`**a** +1. Click **Later** +1. Click **Logout** + +### Expired page + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp2** (second one) +1. Login as an "expired" user: `username=`**already_past** `password=`**a** + +## Multi-factor authentication (MFA) functionality + +### Nag about missing MFA setup + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Login as an "unprotected" user: `username=`**nag_for_mfa** `password=`**a** +1. The "learn more" link should be visible +1. Click **Enable** +1. Click your browser's back button +1. Click **Remind me later** +1. Click **Logout** + +### Nag about missing password recovery methods + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Login as a user without any methods: `username=`**nag_for_method** `password=`**a** +1. Enter one of the following codes to verify (`94923279, 82743523, 77802769, 01970541, 37771076`) +1. Click **Add** +1. Click your browser's back button +1. Click **Remind me later** +1. Click **Logout** + +### Force MFA setup + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Login as an "unsafe" user: `username=`**must_set_up_mfa** `password=`**a** + +### Backup code + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Login as a "backup code" user: `username=`**has_backupcode** `password=`**a** +1. Enter one of the following codes to verify (`94923279, 82743523, 77802769, 01970541, 37771076`) +1. Click **Logout** +1. In order to see the "running low on codes" page, simply log back in and use another code. +1. In order to see the "out of codes" page, simply log back in and out repeatedly until there are no more codes. + +### TOTP code + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Login as a "totp" user: `username=`**has_totp** `password=`**a** +1. Set up an app using this secret, `JVRXKYTMPBEVKXLS` +1. Enter code from app to verify +1. Click **Logout** + +### Key (U2F) + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Login as a "u2f" user: `username=`**has_u2f** `password=`**a** +1. Insert key and press +1. Click **Logout** + +### Key (WebAuthn) + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Login as a "webauthn" user: `username=`**has_webauthn** `password=`**a** +1. Insert key and press +1. Click **Logout** + +### Multiple options + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Login as a "multiple option" user: `username=`**has_all** `password=`**a** +1. Click **MORE OPTIONS** + +### Multiple options (legacy, with U2F) + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Login as a "multiple option" user: `username=`**has_all_legacy** `password=`**a** +1. Click **MORE OPTIONS** + +### Manager rescue + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Login as a "multiple option" user: `username=`**has_all** `password=`**a** +1. Click **MORE OPTIONS** +1. Click the help option +1. Choose **Send** + +_NOTE: At this time, the correct code is not known and can't be tested locally (it's only available in an email to the manager)_ + +## Announcements functionality + +1. Goto [SP 2](http://ssp-sp2.local:8083/module.php/core/authenticate.php?as=hub-discovery) +1. The announcement should be displayed on the hub +1. Click **idp3** (first one) +1. The announcement should be displayed at the login screen + +## SP name functionality + +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. The sp name should appear in the banner + +## Profile review functionality +1. Goto [SP 1](http://ssp-sp1.local:8082/module.php/core/authenticate.php?as=hub-discovery) +1. Click **idp4** (third one) +1. Login as a "Review needed" user: `username=`**needs_review** `password=`**a** +1. Enter one of the following printable codes to verify (`94923279, 82743523, 77802769, 01970541, 37771076`) +1. Click the button to update the profile +1. Click the button to continue +1. Click **Logout** + diff --git a/modules/material/dictionaries/about2expire.definition.json b/modules/material/dictionaries/about2expire.definition.json new file mode 100644 index 00000000..b39acd50 --- /dev/null +++ b/modules/material/dictionaries/about2expire.definition.json @@ -0,0 +1,45 @@ + +{ + "title": { + "en": "Expiring password", + "es": "Contraseña vencida", + "fr": "Mot de passe expiré", + "ko": "만료 된 암호" + }, + "header": { + "en": "Password expiring soon", + "es": "Contraseña caducada pronto", + "fr": "Mot de passe expire bientôt", + "ko": "곧 만료되는 암호" + }, + "expiring_in_a_day": { + "en": "Your password will expire in one day.", + "es": "Su contraseña caducará en un día.", + "fr": "Votre mot de passe expirera en un jour.", + "ko": "암호는 하루 만료됩니다." + }, + "expiring_soon": { + "en": "Your password will expire in {daysLeft} days.", + "es": "Su contraseña caducará en {daysLeft} días.", + "fr": "Votre mot de passe expirera en {daysLeft} jours.", + "ko": "비밀번호는 {daysLeft} 일 후에 만료됩니다." + }, + "change_now": { + "en": "Would you like to change it now?", + "es": "¿Quieres cambiarlo ahora?", + "fr": "Voulez-vous le changer maintenant?", + "ko": "지금 변경 하시겠습니까?" + }, + "button_change": { + "en": "Yes", + "es": "Sí", + "fr": "Oui", + "ko": "예" + }, + "button_continue": { + "en": "Later", + "es": "Después", + "fr": "Plus tard", + "ko": "후에" + } +} diff --git a/modules/material/dictionaries/error.definition.json b/modules/material/dictionaries/error.definition.json new file mode 100644 index 00000000..1cff9bba --- /dev/null +++ b/modules/material/dictionaries/error.definition.json @@ -0,0 +1,21 @@ + +{ + "title": { + "en": "Error", + "es": "Error", + "fr": "Erreur", + "ko": "오류" + }, + "header": { + "en": "Error", + "es": "Error", + "fr": "Erreur", + "ko": "오류" + }, + "message": { + "en": "An error occurred, please contact your help desk for further assistance.", + "es": "Se ha producido un error, póngase en contacto con su asistencia técnica para obtener más ayuda.", + "fr": "Une erreur s'est produite, s'il vous plaît contacter votre service d'assistance pour plus d'assistance.", + "ko": "오류가 발생했습니다. 도움을 받으려면 헬프 데스크에 문의하십시오." + } +} diff --git a/modules/material/dictionaries/expired.definition.json b/modules/material/dictionaries/expired.definition.json new file mode 100644 index 00000000..0915a459 --- /dev/null +++ b/modules/material/dictionaries/expired.definition.json @@ -0,0 +1,27 @@ + +{ + "title": { + "en": "Expired password", + "es": "Contraseña caducada", + "fr": "Mot de passe expiré", + "ko": "만료 된 암호" + }, + "header": { + "en": "Password expired", + "es": "La contraseña expiró", + "fr": "Mot de passe expiré", + "ko": "암호가 만료되었습니다." + }, + "expired": { + "en": "Your password has expired and must be changed before continuing.", + "es": "Su contraseña ha caducado y debe cambiarse antes de continuar.", + "fr": "Votre mot de passe a expiré et doit être modifié avant de continuer.", + "ko": "비밀번호가 만료되었으므로 계속하기 전에 비밀번호를 변경해야합니다." + }, + "button_change": { + "en": "Change", + "es": "Cambiar", + "fr": "Changer", + "ko": "바꾸다" + } +} diff --git a/modules/material/dictionaries/footer.definition.json b/modules/material/dictionaries/footer.definition.json new file mode 100644 index 00000000..0ee65023 --- /dev/null +++ b/modules/material/dictionaries/footer.definition.json @@ -0,0 +1,9 @@ + +{ + "copyright": { + "en": "Unauthorized use of this site is prohibited and may be subjected to civil and criminal prosecution.", + "es": "El uso no autorizado de este sitio está prohibido y puede ser sometido a procesamiento civil y penal.", + "fr": "L'utilisation non autorisée de ce site est interdite et peut faire l'objet de poursuites civiles et pénales.", + "ko": "이 사이트의 무단 사용은 금지되어 있으며 민사 및 형사 고발의 대상이 될 수 있습니다." + } +} diff --git a/modules/material/dictionaries/login.definition.json b/modules/material/dictionaries/login.definition.json new file mode 100644 index 00000000..e5d1d69b --- /dev/null +++ b/modules/material/dictionaries/login.definition.json @@ -0,0 +1,62 @@ +{ + "title": { + "en": "Login with your {idpName} identity", + "es": "Inicie sesión con su identidad de {idpName}", + "fr": "Connectez-vous avec votre identité {idpName}", + "ko": "{idpName} 신원 계정으로 로그인하십시오." + }, + "header": { + "en": "Login with your {idpName} identity", + "es": "Inicie sesión con su identidad de {idpName}", + "fr": "Connectez-vous avec votre identité {idpName}", + "ko": "{idpName} 신원 계정으로 로그인하십시오." + }, + "label_username": { + "en": "Username", + "es": "Nombre de usuario", + "fr": "Nom d'utilisateur", + "ko": "사용자 이름" + }, + "label_password": { + "en": "Password", + "es": "Contraseña", + "fr": "Mot de passe", + "ko": "암호" + }, + "error_wronguserpass": { + "en": "Something is wrong with that username or password, please verify and try again.", + "es": "Algo está mal con ese nombre de usuario o contraseña, compruebe e inténtelo de nuevo.", + "fr": "Quelque chose ne va pas avec ce nom d'utilisateur ou ce mot de passe, veuillez vérifier et essayer à nouveau.", + "ko": "해당 사용자 이름 또는 비밀번호가 잘못되었습니다. 다시 확인하고 다시 시도하십시오." + }, + "button_login": { + "en": "Login", + "es": "Iniciar sesión", + "fr": "Connexion", + "ko": "로그인" + }, + "forgot": { + "en": "Forgot password?", + "es": "¿Se te olvidó tu contraseña?", + "fr": "Mot de passe oublié?", + "ko": "비밀번호를 잊으 셨나요?" + }, + "logo": { + "en": "{idpName} logo", + "es": "Logotipo de {idpName}", + "fr": "Logo {idpName}", + "ko": "{idpName} 로고" + }, + "help": { + "en": "I need help", + "es": "necesito ayuda", + "fr": "j'ai besoin d'aide", + "ko": "도움이 필요해." + }, + "profile": { + "en": "Manage my profile", + "es": "Administrar mi perfil", + "fr": "Gérer mon profil", + "ko": "내 프로필 관리" + } +} diff --git a/modules/material/dictionaries/logout.definition.json b/modules/material/dictionaries/logout.definition.json new file mode 100644 index 00000000..61324e70 --- /dev/null +++ b/modules/material/dictionaries/logout.definition.json @@ -0,0 +1,21 @@ + +{ + "title": { + "en": "Logged out", + "es": "Desconectado", + "fr": "Déconnecté", + "ko": "로그 아웃 됨" + }, + "header": { + "en": "Logged out", + "es": "Desconectado", + "fr": "Déconnecté", + "ko": "로그 아웃 됨" + }, + "message": { + "en": "You have now been logged out.", + "es": "Se ha desconectado.", + "fr": "Vous êtes maintenant déconnecté.", + "ko": "이제 로그 아웃되었습니다." + } +} diff --git a/modules/material/dictionaries/mfa.definition.json b/modules/material/dictionaries/mfa.definition.json new file mode 100644 index 00000000..1d992b32 --- /dev/null +++ b/modules/material/dictionaries/mfa.definition.json @@ -0,0 +1,399 @@ + +{ + "title": { + "en": "2-Step Verification", + "es": "Verificación en 2 pasos", + "fr": "Vérification en deux étapes", + "ko": "2 단계 인증" + }, + "header": { + "en": "2-Step Verification", + "es": "Verificación en 2 pasos", + "fr": "Vérification en deux étapes", + "ko": "2 단계 인증" + }, + "backupcode_header": { + "en": "Printable code", + "es": "código imprimible", + "fr": "code imprimable", + "ko": "인쇄 가능한 코드" + }, + "backupcode_icon": { + "en": "Printable code icon", + "es": "icono de código imprimible", + "fr": "icône de code imprimable", + "ko": "인쇄 가능한 코드 아이콘" + }, + "backupcode_reminder": { + "en": "Each code can only be used once, so the code you enter this time will be used up and will not be available again.", + "es": "Cada código solo se puede usar una vez, por lo que el código que ingrese esta vez se agotará y no estará disponible nuevamente.", + "fr": "Chaque code ne peut être utilisé qu'une seule fois, de sorte que le code que vous entrez cette fois sera épuisé et ne sera plus disponible.", + "ko": "각 코드는 한번만 사용할 수 있으므로 이번에 입력한 코드는 소멸되어 다시 사용할 수 없습니다." + }, + "backupcode_input": { + "en": "Enter code", + "es": "Introduzca el código", + "fr": "Entrer le code", + "ko": "코드 입력" + }, + "totp_header": { + "en": "Smartphone app", + "es": "Aplicación de teléfono inteligente", + "fr": "Application pour smartphone", + "ko": "스마트폰 앱" + }, + "totp_icon": { + "en": "Smartphone app icon", + "es": "Icono de aplicación de teléfono inteligente", + "fr": "Icône de l'application Smartphone", + "ko": "스마트폰 응용 프로그램 아이콘" + }, + "totp_instructions": { + "en": "You will need to check your smartphone app for the current code.", + "es": "Deberá verificar la aplicación de su teléfono inteligente para ver el código actual.", + "fr": "Vous devriez vérifier l'application sur votre smartphone pour voir le code actuel.", + "ko": "스마트폰 앱에서 현재 코드를 확인해야합니다." + }, + "totp_input": { + "en": "Enter 6-digit code", + "es": "Ingrese el código de 6 dígitos", + "fr": "Entrer le code à 6 chiffres", + "ko": "6 자리 코드 입력" + }, + "u2f_header": { + "en": "Security key", + "es": "Clave de seguridad", + "fr": "Clé de sécurité", + "ko": "보안키" + }, + "webauthn_header": { + "en": "Security key", + "es": "Clave de seguridad", + "fr": "Clé de sécurité", + "ko": "보안키" + }, + "u2f_icon": { + "en": "USB key icon", + "es": "Icono de la llave USB", + "fr": "Icône de clé USB", + "ko": "USB 키 아이콘" + }, + "webauthn_icon": { + "en": "USB key icon", + "es": "Icono de la llave USB", + "fr": "Icône de clé USB", + "ko": "USB 키 아이콘" + }, + "u2f_instructions": { + "en": "You may now insert your security key and press its button.", + "es": "Ahora puede insertar su clave de seguridad y presionar su botón.", + "fr": "Vous pouvez maintenant insérer votre clé de sécurité et appuyer sur le bouton.", + "ko": "이제 보안 키를 삽입하고 단추를 누를 수 있습니다." + }, + "webauthn_instructions": { + "en": "You may now insert your security key and press its button.", + "es": "Ahora puede insertar su clave de seguridad y presionar su botón.", + "fr": "Vous pouvez maintenant insérer votre clé de sécurité et appuyer sur le bouton.", + "ko": "이제 보안 키를 삽입하고 단추를 누를 수 있습니다." + }, + "u2f_unsupported": { + "en": "Unsupported in your current browser. Please consider a more secure browser like Google Chrome.", + "es": "No compatible en su navegador actual. Considere un navegador más seguro como Google Chrome.", + "fr": "Non compatible avec votre navigateur actuel. Veuillez considérer un navigateur plus sûr comme Google Chrome.", + "ko": "현재 브라우저에서 지원되지 않습니다. Chrome과 같은 보다 안전한 브라우저를 고려하십시오." + }, + "webauthn_unsupported": { + "en": "Unsupported in your current browser. Please consider a more secure browser like Google Chrome.", + "es": "No compatible en su navegador actual. Considere un navegador más seguro como Google Chrome.", + "fr": "Non compatible avec votre navigateur actuel. Veuillez considérer un navigateur plus sûr comme Google Chrome.", + "ko": "현재 브라우저에서 지원되지 않습니다. Chrome과 같은 보다 안전한 브라우저를 고려하십시오." + }, + "u2f_error_unknown": { + "en": "Something went wrong with that request, unable to verify at this time.", + "es": "Algo salió mal con esa solicitud, no se pudo verificar en este momento.", + "fr": "Quelque chose s'est mal passé avec cette demande, impossible de vérifier pour le moment.", + "ko": "요청에 문제가 발생하여 지금은 확인할 수 없습니다." + }, + "webauthn_error_unknown": { + "en": "Something went wrong with that request, unable to verify at this time.", + "es": "Algo salió mal con esa solicitud, no se pudo verificar en este momento.", + "fr": "Quelque chose s'est mal passé avec cette demande, impossible de vérifier pour le moment.", + "ko": "요청에 문제가 발생하여 지금은 확인할 수 없습니다." + }, + "u2f_error_wrong_key": { + "en": "This may not be the correct key for this site.", + "es": "Esta puede no ser la clave correcta para este sitio.", + "fr": "Ce n'est peut-être pas la bonne clé pour ce site.", + "ko": "이 사이트의 올바른 키가 아닐 수도 있습니다." + }, + "u2f_error_timeout": { + "en": "That took a little too long, check to make sure your key is inserted right-side up.", + "es": "Eso llevó demasiado tiempo, verifique que su clave esté insertada boca arriba.", + "fr": "Cela a pris un peu trop de temps, vérifiez que votre clé est insérée dans le bons sens.", + "ko": "오랜 시간이 경과 되었으니 키가 오른쪽 위로 삽입되었는지 확인 하십시오." + }, + "webauthn_error_abort": { + "en": "It looks like you clicked cancel. Would you like us to try again?", + "es": "It looks like you clicked cancel. Would you like us to try again?", + "fr": "Il semble que vous ayez cliqué sur annuler. Souhaitez-vous que nous essayions à nouveau ?", + "ko": "It looks like you clicked cancel. Would you like us to try again?" + }, + "webauthn_error_not_allowed": { + "en": "Something about that didn't work. Please ensure that your security key is plugged in and that you touch it within 60 seconds when it blinks.", + "es": "Something about that didn't work. Please ensure that your security key is plugged in and that you touch it within 60 seconds when it blinks.", + "fr": "Quelque chose n'a pas fonctionné avec ça. Veuillez vous assurer que votre clé de sécurité est insérée et que vous la touchez dans les 60 secondes lorsqu'elle clignote.", + "ko": "Something about that didn't work. Please ensure that your security key is plugged in and that you touch it within 60 seconds when it blinks." + }, + "manager_icon": { + "en": "Recovery contact icon", + "es": "Icono de contacto de recuperación", + "fr": "Icône du contact de récupération", + "ko": "복구 연락처 아이콘" + }, + "manager_header": { + "en": "Recovery contact help", + "es": "Ayuda de contacto de recuperación", + "fr": "Aide de contact de récupération", + "ko": "복구 연락처" + }, + "manager_info": { + "en": "We can send a code to your recovery contact which can be used as a temporary 2-Step Verification option. The email address on file (masked for privacy) is {managerEmail}.", + "es": "Podemos enviar un código a su contacto de recuperación que puede usarse como una opción de Verificación temporal de 2 pasos. La dirección de correo electrónico en el archivo (enmascarada por privacidad) es {managerEmail}.", + "fr": "Nous pouvons envoyer un code à votre contact de récupération, qui peut être utilisé comme option de vérification temporaire en deux étapes. L'adresse électronique au dossier (masquée pour la confidentialité) est {managerEmail}.", + "ko": "\n임시 2 단계 인증 옵션으로 사용할 수있는 코드를 복구 담당자에게 보낼 수 있습니다. 파일의 이메일 주소 (개인 정보 보호를 위해 마스크 됨)는 {managerEmail}입니다." + }, + "manager_sent": { + "en": "A temporary code was sent your recovery contact at {managerEmail}.", + "es": "Se envió un código temporal a su contacto de recuperación en {managerEmail}.", + "fr": "Un code temporaire a été envoyé à votre contact de récupération à l'adresse {managerEmail}.", + "ko": "{managerEmail} (으)로 복구 담당자에게 임시 코드를 보냈습니다." + }, + "manager_input": { + "en": "Enter code", + "es": "Introduzca el código", + "fr": "Entrer le code", + "ko": "코드 입력" + }, + "shield_icon": { + "en": "Shield icon", + "es": "Icono de escudo", + "fr": "Icône de bouclier", + "ko": "방패 아이콘" + }, + "required_header": { + "en": "Protect this account", + "es": "Protege esta cuenta", + "fr": "Protéger ce compte", + "ko": "이 계정 보호" + }, + "required_info": { + "en": "Your identity account requires additional security, you must set up 2-Step Verification at this time.", + "es": "Su cuenta de identidad requiere seguridad adicional, debe configurar la verificación en dos pasos en este momento.", + "fr": "Votre compte d'identité nécessite une sécurité supplémentaire, vous devez configurer la vérification en deux étapes en ce moment.", + "ko": "신원 계정에 추가 보안이 필요하므로 현재 2 단계 인증을 설정해야합니다." + }, + "running_out_header": { + "en": "Almost out of printable codes", + "es": "Casi sin códigos imprimibles", + "fr": "Codes imprimables presque épuisés", + "ko": "인쇄 가능한 코드가 거의 남지 않았습니다" + }, + "running_out_info": { + "en": "You only have {numBackupCodesRemaining} more left.", + "es": "Solo tiene {numBackupCodesRemaining} más disponible.", + "fr": "Vous avez seulement {numBackupCodesRemaining} qui restent.", + "ko": "{numBackupCodesRemaining} 만 남았습니다." + }, + "no_more_codes_header": { + "en": "Last printable code used", + "es": "Último código imprimible utilizado", + "fr": "Dernier code imprimable utilisé", + "ko": "마지막 인쇄 가능 코드가 사용되었습니다." + }, + "new_codes_header": { + "en": "New printable codes", + "es": "Nuevos códigos imprimibles", + "fr": "Nouveaux codes imprimables", + "ko": "새로운 인쇄 가능 코드" + }, + "old_codes_gone": { + "en": "You may now discard any of your previous codes, they have been deleted.", + "es": "Ahora puede descartar cualquiera de sus códigos anteriores, se han eliminado.", + "fr": "Vous pouvez maintenant jeter tous vos codes précédents, ils ont été supprimés.", + "ko": "이제 이전 코드를 삭제해도 삭제 될 수 있습니다." + }, + "new_codes_info": { + "en": "Printable codes should be treated with the same level of attention as any password.", + "es": "Los códigos imprimibles deben tratarse con el mismo nivel de atención que cualquier contraseña.", + "fr": "Les codes imprimables doivent être traités avec le même niveau d'attention que les mots de passe.", + "ko": "인쇄 가능한 코드는 모든 비밀번호와 동일한주의 수준으로 처리되어야합니다." + }, + "new_codes_only_once": { + "en": "Each code may only be used once.", + "es": "Cada código solo puede usarse una vez.", + "fr": "Chaque code ne peut être utilisé qu'une seule fois.", + "ko": "각 코드는 한 번만 사용할 수 있습니다." + }, + "new_codes_failed": { + "en": "Something went wrong while creating new printable codes for you. We are sorry for the inconvenience, please check your configuration at the following address after continuing: ", + "es": "Algo salió mal al crear nuevos códigos imprimibles para usted. Disculpe las molestias, compruebe su configuración en la siguiente dirección después de continuar: ", + "fr": "Une erreur s'est produite lors de la création de nouveaux codes imprimables. Nous sommes désolés pour le dérangement. Veuillez vérifier votre configuration à l'adresse suivante après avoir continué: ", + "ko": "새로운 인쇄 가능한 코드를 만드는 동안 문제가 발생했습니다. 불편을 끼쳐 드려 죄송합니다. 계속 진행 한 후 다음 주소로 구성을 확인하십시오. " + }, + "new_codes_saved": { + "en": "I saved a personal copy of these for later use", + "es": "Guardé una copia personal de estos para uso posterior", + "fr": "J'ai sauvegardé une copie personnelle de ceux-ci pour une utilisation ultérieure", + "ko": "나는 나중에 사용하기 위해 이들의 개인 사본을 저장했다." + }, + "account": { + "en": "{idpName} identity account", + "es": "Cuenta de identidad de {idpName}", + "fr": "Compte d'identité {idpName}", + "ko": "{idpName} 신원 계정" + }, + "has_options_besides_codes": { + "en": "Thankfully you do have other 2-Step Verification options set up but you should create more Printable codes if you plan to need them in the future.", + "es": "Afortunadamente, tiene otras opciones de verificación en dos pasos configuradas, pero debe crear más códigos imprimibles si planea necesitarlos en el futuro.", + "fr": "Heureusement, vous avez d'autres options de vérification en deux étapes, mais vous devriez créer plus de codes imprimables si vous prévoyez en avoir besoin à l'avenir.", + "ko": "다른 2 단계 인증 옵션은 설정 되었으나 인쇄 가능 코드가 나중에 필요할 것으로 예상되면 코드를 더 만들어야 합니다." + }, + "has_no_more_options": { + "en": "Since you do not have any other 2-Step Verification options set up at this time, you will need to get more Printable codes before another one is required.", + "es": "Como no tiene configuradas otras opciones de verificación en dos pasos en este momento, necesitará obtener más códigos imprimibles antes de que se requiera otro.", + "fr": "Comme aucune autre option de vérification en deux étapes n'est configurée pour l'instant, vous devez obtenir davantage de codes imprimables avant d'en avoir besoin d'un autre.", + "ko": "코드가 요구되기 전에 인쇄 가능 코드를 더 가져와야 합니다." + }, + "use_others": { + "en": "More options", + "es": "Mas opciones", + "fr": "Davantage d'options", + "ko": "추가 옵션" + }, + "use_u2f": { + "en": "Use my security key instead", + "es": "Use mi clave de seguridad en su lugar", + "fr": "Utiliser plutôt ma clé de sécurité", + "ko": "내 보안키 사용" + }, + "use_webauthn": { + "en": "Use my security key instead", + "es": "Use mi clave de seguridad en su lugar", + "fr": "Utiliser plutôt ma clé de sécurité", + "ko": "내 보안키 사용" + }, + "use_totp": { + "en": "Use my smartphone app instead", + "es": "Use la aplicación de mi teléfono inteligente en su lugar", + "fr": "Utiliser plutôt mon application smartphone", + "ko": "내 스마트폰 앱 사용" + }, + "use_backupcode": { + "en": "Use a printable code instead", + "es": "Use un código imprimible en su lugar", + "fr": "Utiliser plutôt un code imprimable", + "ko": "인쇄 가능한 코드 사용" + }, + "use_help": { + "en": "I need help", + "es": "necesito ayuda", + "fr": "j'ai besoin d'aide", + "ko": "도움이 필요해." + }, + "use_manager": { + "en": "Use code from my recovery contact", + "es": "Usar código de mi contacto de recuperación", + "fr": "Utiliser le code de mon contact de récupération", + "ko": "복구 담당자의 코드 사용" + }, + "button_verify": { + "en": "Verify", + "es": "Verificar", + "fr": "Vérifier", + "ko": "검증" + }, + "button_later": { + "en": "Remind me later", + "es": "Recuérdame más tarde", + "fr": "Rappelez-moi plus tard", + "ko": "추후 알림" + }, + "button_enable": { + "en": "Enable now", + "es": "Habilite ahora", + "fr": "Activer maintenant", + "ko": "지금 사용" + }, + "button_set_up": { + "en": "Set up now", + "es": "Configurar ahora", + "fr": "Configurer maintenant", + "ko": "지금 설정" + }, + "button_try_again": { + "en": "Try again", + "es": "Inténtalo de nuevo", + "fr": "Essayer de nouveau", + "ko": "다시 시도" + }, + "button_get_more": { + "en": "Get more", + "es": "Obtenga más", + "fr": "Avoir plus", + "ko": "더 가져오기" + }, + "button_continue": { + "en": "Continue", + "es": "Continuar", + "fr": "Continuer", + "ko": "계속하다" + }, + "button_print": { + "en": "Print", + "es": "Imprimir", + "fr": "Imprimer", + "ko": "인쇄" + }, + "button_download": { + "en": "Download", + "es": "Descargar", + "fr": "Télécharger", + "ko": "다운로드" + }, + "button_copy": { + "en": "Copy", + "es": "Copiar", + "fr": "Copier", + "ko": "사본" + }, + "button_send": { + "en": "Send", + "es": "Enviar", + "fr": "Envoyer", + "ko": "보내다" + }, + "button_cancel": { + "en": "Cancel", + "es": "Cancelar", + "fr": "Annuler", + "ko": "취소" + }, + "button_copied": { + "en": "Copied ✓", + "es": "Copiado ✓", + "fr": "Copié ✓", + "ko": "복사 됨 ✓" + }, + "remember_this": { + "en": "Remember this browser for 30 days", + "es": "Recuerde esta navegador por 30 días", + "fr": "Se rappeler de ce navigatuer pour 30 jours", + "ko": "이 브라우저를 30일간 기억" + }, + "unsupported": { + "en": "Not supported in this browser", + "es": "No compatible con este navegador", + "fr": "Non pris en charge dans ce navigateur", + "ko": "이 브라우저에서는 지원되지 않습니다." + } +} diff --git a/modules/material/dictionaries/nag.definition.json b/modules/material/dictionaries/nag.definition.json new file mode 100644 index 00000000..9c450e90 --- /dev/null +++ b/modules/material/dictionaries/nag.definition.json @@ -0,0 +1,75 @@ + +{ + "mfa_title": { + "en": "2-Step Verification", + "es": "Verificación en 2 pasos", + "fr": "Vérification en deux étapes", + "ko": "2 단계 인증" + }, + "mfa_header": { + "en": "2-Step Verification", + "es": "Verificación en 2 pasos", + "fr": "Vérification en deux étapes", + "ko": "2 단계 인증" + }, + "method_title": { + "en": "Password recovery methods", + "es": "Métodos de recuperación de contraseña", + "fr": "Méthodes de récupération de mot de passe", + "ko": "비밀번호 복구 방법" + }, + "method_header": { + "en": "Password recovery methods", + "es": "Métodos de recuperación de contraseña", + "fr": "Méthodes de récupération de mot de passe", + "ko": "비밀번호 복구 방법" + }, + "shield_icon": { + "en": "Shield icon", + "es": "Icono de escudo", + "fr": "Icône de bouclier", + "ko": "방패 아이콘" + }, + "header": { + "en": "Protect yourself", + "es": "Protéjase", + "fr": "Protégez-vous", + "ko": "자기 보호" + }, + "mfa_info": { + "en": "Did you know you could easily increase the security of your identity account by enabling 2-Step Verification?", + "es": "¿Sabía que podría aumentar fácilmente la seguridad de su cuenta de identidad al habilitar la verificación en dos pasos?", + "fr": "Savez-vous que vous pouvez facilement augmenter la sécurité de votre compte d'identité en activant la vérification en deux étapes?", + "ko": "2 단계 인증을 사용하여 신원 계정의 보안을 쉽게 높일 수 있다는 사실을 알고 계셨습니까?" + }, + "method_info": { + "en": "Do you forget your password sometimes? Did you know it is very easy to add an alternate email address for password recovery just in case?", + "es": "¿Olvidas tu contraseña a veces? ¿Sabía que es muy fácil agregar una dirección de correo electrónico alternativa para recuperar la contraseña por si acaso?", + "fr": "Avez-vous oublié votre mot de passe parfois? Saviez-vous qu'il est très facile d'ajouter une adresse électronique de remplacement pour la récupération du mot de passe au cas où?", + "ko": "가끔 암호를 잊어 버리십니까? 혹시라도 비밀번호 복구를 위해 보조 이메일 주소를 추가하는 것이 매우 쉽다는 것을 알고 계셨습니까?" + }, + "button_later": { + "en": "Remind me later", + "es": "Recuérdame más tarde", + "fr": "Rappelez-moi plus tard", + "ko": "추후 알림" + }, + "button_learn_more": { + "en": "Learn more", + "es": "Aprende más", + "fr": "Apprendre encore plus", + "ko": "더 알아보기" + }, + "button_enable": { + "en": "Enable now", + "es": "Habilite ahora", + "fr": "Activer maintenant", + "ko": "지금 사용" + }, + "button_add": { + "en": "Add one now", + "es": "Agrega uno ahora", + "fr": "Ajouter un maintenant", + "ko": "지금 하나 추가" + } +} diff --git a/modules/material/dictionaries/review.definition.json b/modules/material/dictionaries/review.definition.json new file mode 100644 index 00000000..96764c14 --- /dev/null +++ b/modules/material/dictionaries/review.definition.json @@ -0,0 +1,75 @@ + +{ + "title": { + "en": "Profile review", + "es": "Revisión del perfil", + "fr": "Examen du profil", + "ko": "프로필 검토" + }, + "header": { + "en": "Profile review", + "es": "Revisión del perfil", + "fr": "Examen du profil", + "ko": "프로필 검토" + }, + "info": { + "en": "Are these still correct?", + "es": "¿Siguen siendo correctos?", + "fr": "Sont-ils toujours corrects?", + "ko": "여전히 맞습니까?" + }, + "mfa_header": { + "en": "2-Step Verification", + "es": "Verificación en 2 pasos", + "fr": "Vérification en 2 étapes", + "ko": "2 단계 인증" + }, + "methods_header": { + "en": "Password Recovery Methods", + "es": "Métodos de recuperación de contraseña", + "fr": "Méthodes de récupération de mot de passe", + "ko": "비밀번호 복구 방법" + }, + "remaining": { + "en": "({count} remaining)", + "es": "({count} restante)", + "fr": "({count} restant)", + "ko": "({count} 남음)" + }, + "used": { + "en": "last used: {when}", + "es": "último uso: {when}", + "fr": "dernière utilisation: {when}", + "ko": "마지막 사용 시간 : {when}" + }, + "used_never": { + "en": "last used: Never", + "es": "último uso: nunca", + "fr": "Dernière utilisation: Jamais", + "ko": "마지막 사용 : Never" + }, + "verified": { + "en": "Verified", + "es": "Verificado", + "fr": "Vérifié", + "ko": "검증 된" + }, + "unverified": { + "en": "Unverified", + "es": "Inconfirmado", + "fr": "Non vérifié", + "ko": "확인되지 않음" + }, + "button_update": { + "en": "Some of these need updating", + "es": "Algunos de estos necesitan actualización", + "fr": "Certains ont besoin d'être mis à jour", + "ko": "이들 중 일부는 업데이트해야합니다." + }, + "button_continue": { + "en": "These are still correct", + "es": "Estos siguen siendo correctos", + "fr": "Ceux-ci sont toujours corrects", + "ko": "이들은 여전히 정확하다." + } +} diff --git a/modules/material/dictionaries/selectidp.definition.json b/modules/material/dictionaries/selectidp.definition.json new file mode 100644 index 00000000..55a261ac --- /dev/null +++ b/modules/material/dictionaries/selectidp.definition.json @@ -0,0 +1,38 @@ +{ + "title": { + "en": "Choose an identity account", + "es": "Elige una cuenta de identidad", + "fr": "Choisissez un compte d'identité", + "ko": "ID 계정 선택" + }, + "header": { + "en": "Choose an identity account", + "es": "Elige una cuenta de identidad", + "fr": "Choisissez un compte d'identité", + "ko": "ID 계정 선택" + }, + "header-for-sp": { + "en": "Choose an identity account to continue to {spName}", + "es": "Elija una cuenta de identidad para continuar en {spName}", + "fr": "Choisissez un compte d'identité pour continuer vers {spName}", + "ko": "{spName}을 계속 진행하려면 신원 계정을 선택하십시오." + }, + "enabled": { + "en": "Login with your {idpName} identity account", + "es": "Inicie sesión con su cuenta de identidad {idpName}", + "fr": "Connectez-vous avec votre compte d'identité {idpName}", + "ko": "{idpName} 신원 계정으로 로그인하십시오." + }, + "disabled": { + "en": "{idpName} coming soon", + "es": "{IdpName} próximamente", + "fr": "{IdpName} à venir", + "ko": "{idpName} 곧 제공됨" + }, + "help": { + "en": "Help", + "es": "Ayuda", + "fr": "Aidez-moi", + "ko": "도움" + } +} diff --git a/modules/material/themes/material/common-announcement.php b/modules/material/themes/material/common-announcement.php new file mode 100644 index 00000000..74d5649b --- /dev/null +++ b/modules/material/themes/material/common-announcement.php @@ -0,0 +1,15 @@ + +
-*;rZuc4Qr8{?DjQ@rEUvkYdH{{PwOivoe z>OcO0iu43Pcs`4CcA4!5mOF+%G+I=`a=ia_O*T!}Cv~vj(zwa(uJ^4?XD5InWZ${qPdRi%3*zoH56|p?x!eb54vjd8}`jGB-#vtF$P9IIn~+{&$)r|JO3iMiGJl zvR|!-_3^J{2LR8xvRdL}osi~`0bH!(ATsZ5VI^Pm#83TgyU`sC`YFIIwkkzTzzhZ^ zGXB&&6!a|Xq@l}ZAsFti{b{4lg~UEbRW|KAuX);bOB8$)L`I7_!%yg+uW3@tb8cP( zMq$AubpP!Gz~BjzpD4jSACpO Ay9GW?-pjE*TY9vogZ6^~AvDl6z0;-XD2K#Qi?GM!M|e2L>}C zYTg+N3%|jD>cQp_Gj>B?L1-iMtf4@9OI>2QH>te~23B$MYR(QX $^BLs_$9@gmsVhA`~Ie(C6h+_Uyv0iPr!~j-?>&P8Gz5XT*`}c?3nWpQ{h)|g_ zT)bnanH9gf7tUrhHmbfs+RpL$J{54?&Ubq2HLJN_LCsIYBC!1~?y|{cupdf*Mk}Gm zX2T*w;6LqDaRz)vImv_=5Rpn-t$l9DWgc7YwAg6X`l|@}0V{2gjQoot>OrJl!`Aqv zkeDM8!j1Gn86tJT8h5vvZeo|Ws2C;e?&i@7$+A;lU2l8tyCaljeSmnJATiI7nGyNN z4~!FMuh#ZvrcJsXluBmZA9A_uq|yMML3ehW+=RIy{JCxmQSeOBUx3fFpu_p~kxNSA z2z$a%zHoTcd=_hTI*Vo&Up+(OcoDW&$WfABb^VS*-AD^B7* zr$$EjTn3ghHeb6Q3_B==wSV#yE(kKOFD%n&ad=G@F!Vqrc18J3iHQhc95H~HrcuOd z9W!4yD{VD NF`w0j zy~X^B<`vyu6w`m15%?yUL;Yjkni9PHf@Hj*gWx5~=KCXz96s$EltmQV@%H@G_<_m! zq~0aZnZ!Rel@$)%;&HtnJ)=9av>DD6GhjHP2R;x58Docu6sU2yK0GDqt#vzjb?D=h z_-gLiZ75tzf#V{@G`>^5$iDO1o>sPxpX6L&(p{znm&yuI&Ng@+!r|$;jaF|V{v^7k z{Ix5O7DmH=9%=hr@BKO~xK}be;51h74;qc=o=b3FoWCTmDcSAyhktGyk>hQ)F`nkw ze7#9=vBNAG$ry3^k`cG?f ~~GwvV ~btBN?^P>_JUPs!}%q2g<|7< z+2a{^T`#c+oW`Hf_UZF`n*W$s*$TTC^TVY(5j2moF(oC1hJgopv4~kOrtAv2ChD10 z{X0I9{2<{TIq*Z+F~JtRI^NZR62 O`*I@l z-0LlKn;^OWiBI2WaA#@Lsr9IdBUC>-_f(86XWV6jfj2 z;Owy*8(oeU-H<49m4ddWD#xsn{-nmqz6ptTRBunoG)_mNdJP|cUqn=+k%y3%3{B+m zG_|%nK=mCvqJ!KXXk}hi@23jnAB -3h*Ex3dnW@7xmrVW3FJEPH(%E z9~cQ$`YhS!8VJ+^pWDJ~Thoe<+t#gGcA=!FE_GeU+N!XczO?4MnGhHI+pi9kQig~( z26+DX0zQEQ+Kg7vm}pGUGV5}GW#)uai@D|u+&eYfO|Gmp!ttw+mG&ThNY!aw-Mw zYikiaAC!$NLv7^7dG$r(Xr|NZ2y&KqTj?Auk$S;o)@?bkH@Ee`&-j>FmN$iVoynVp zr5-(38|hssZchjcpZbB^N;z(4z^LLHliH|Cfv|Ozb$MKxGQ&C>#Bnm|83#A|ye}Xq zJX}cN*PazOJ>S&fph#jK#KeV;4ngIXuVxo2Q7U9;aN0j}>*^Gx1_^L%mfEK6G4P7f zfJbBz5CisHPKc{qzE4py&ldb g42J>DvPFKMQ3!|90gg?Xhhom5Qk_) zNvCj+6F-$7JQRl5>H^1s!zXD;JzSBlen9$3;uuS|8+s{s_`a?s<|9$qg5SMMYx0YB zc5*h}fkw?doNKl*7*T36M$0?_dBZTEg~^Q4WRJI|0)U$sRELVc(io^rXah#waH~zR zs`9wN^t=S27!x%Z8TJ#<=eu-o@&pJwEI?gOpUsLepV=9}vqkhTkjna`z|k0n)MSNx zlL@8$&mQqWpk%H}7hnx{PkwlDZ%XRSz=ym6K|MLj%y%91M`PX0W^-|fqadUeN=}G= z+dRaZmNkxhIBPA$3kI^%@4J#9EYkNwcBn^in96gmmk*Hk1{DH@fDww+gqiLD`R?IS zt3xvt+M>Gnj)f$8p9U^$u-Iy3J4#_k_!!y0ABO~2`AlA$mXJXQuU#P&*x`nJ5$%>k z#@tyl6YVMuq0jRiE(J|%B!-9KwosjzjS%u7-ipwyI>vm!J+BUbbOW2=`02a+7 ZlK@F?We6u4X33?_f2EP*9@tvMqkC_Vq3iE~ZM%7=X z2Hh+w6sG_{9|&~h2V{N)x(|X3bZRtPAX8 OlgzJ_uHTlkcO2v&bb)htqI=)Fq9X&VG6gI9{0x1feGS} zjCUagm<*oUEo& ;m_kPv>Nk?wxV=);HO z1Q}}oo*eQntOEKx4HnA6DH?*++~>ZYxVB=BJ}B)zw|p7Mb_R5o1{ICHxd-98>FCyw zwM6x_H{0m#n3QBPZ!EHw?p;(0@^C0uA>~h%>kA*Q3zC{-i@}d^aiO{#Y@np#q+Rxq zqfKJfDrTS{GcsgmLJi#)77lOQgLJDhh%F?Kw~Sm8w{HG=DKz&9pVLR+d1LBYxHZY{ zi6**-i;9gG8LHf*jALoF-P`*S-xHt+3BN#%*G{ZS!Lw2MFRls_eNtrB1RZm_B)3#X z!foIBnVKsA>jDPz?yasEn5 \ No newline at end of file diff --git a/modules/material/www/material-icons.woff b/modules/material/www/material-icons.woff new file mode 100644 index 0000000000000000000000000000000000000000..e2cd4f1ba16de1acfeebc00b1dc56635899f93f4 GIT binary patch literal 61928 zcmYgW18gr}u&!>~TidpKYu@(Owr$(CZQHhO+qR8g&DZ}+Uh*dS_GG?%Gkf-AvpXke zTx5iWfq;R2?Cul@{$~I|TmA9>m-&zV|0W_RBn$)utop+d|9}Kc7)U`xRz~56^ZfB? zf55tnag!;cpv3>fRRRG~p#uTgot8uE+RG@=GXeoo5B_L)f1nHHKxANGrDqESL<0r{ z1d0m;1di4lf<9v4>_`9vL{IXg`Qd+n2rOu#=kTMWr}*(9|HJn;5U7czoAD3#2MDMc z00bOfT*x&`VQQpj2n2NeU+mAlfLNiT(11*T$RF;%Iivo71PmAi%+$)!^@sb(31an= zj>d_{cGuFz;7515`{Vzt0wl$9I$M*Kp6ie1_Vy=^;6H#_0qt4qSsDGT6~d3-|MQIQ zI7lq}wl)rqKiuLEhy0)JI~a)3b=^SMP*-;sSRa$X7=++$lE|JOUwh3Iqjo925u| z6(}3%|1|os27mN)C&g&S40d&O^?>}pzxx;?htibFWb1yx{7j(>58Ur3vFm!InvtVM z8xo!v`qpxtO>Wo~Gn+K)#N 8tXkf~;po+`!|fSXw&%eemXDju@Yl5~U+=i~?|D`t=LHoa zHl*qxn0n!ig5ivk?uA5M@gpUm1@$~Ck%Rga7c;q6iC0H_ZZb+sbm#VunQub$1<$kS z=XGze2}~1dT9akR)`0leNeh7ToijlC(fYaA!{%kZ=I!F`{iWo+ ^Gt}n$TRRX^`oHY0YWiY5(byspW(G zgZhIK&QOwTn(L=)$V=`^;>*X&+sl`$=Li2s%}duyMdqP>8;Qz%jX2xW9I@65orM2q zQM|3o03_vp2YgPxBJdSaHx+I#xqGr=di7O*X;gE$Xqd9ZXaT{?5>wGfhf4C@MgU^r z1;^Bi9Dkpl`N~x6{7rJoD8KKssP@e8hl}_`rMnPkMzwho9oIPMitw6{SDJ4&)&r=* zVQB{Ozrsj4Ka^j !!?&^uOc&`p0|VK_{+IP zZv3j#k}+Y8aGWTNY5B2ML712K&07odxy9+$5-4OvPAzy&e)sD;lhY=vP=A864!X$k zQV6-QHnFdR02F&7??9wCAH?kV(3l3woZ>Dv&Oo;gSBF3O$zD3)J*$>+6E~ Q=CktH|atR3kVnIhb=L-IBL zj^U5L7WI+qpxPW^RO6Z7?>LVauQ#+mJNtQK!+k3u+^OEVRJL``M8lLhr)eoSsL zx8>%jrt&+%Wn8=~1lQ*%hx&61a$S$hzMA!f|A*LDj4!OTKHJKokmomsIs9)_-QOqe zpnhZ57GQ>?{xN6Z#WY6iaVFQ&XHvT0OByx(P+BB32E +!ajruwAXVx9;>61Tj5Q ztqK3E2(_-xUkqRgl!?7~cLM|i)-~(_hn(jUKvuW-Ovtmtmdt3g!Ja1a|FAn(9#knf z*v+1eisDSDnLD6osT!1nlp;7s_mQ~X{o>=kql1h-4`jovlx;1f#Pma2)P^06^j?19 zGZ8QVM1#^|Ud6Wv?F5=#`H5N_l$q3^VtHJ!W~UQ@$Hr+UFn$MBT#7}f#41~~JQ~pd zW^yy=<)$Ze+kn!iN=>o4%saUQ1Aq|cM!MCsYk}y7FqwNumApuQ#pAR9Da@lsjBI9| zGYyH-*B0DCcRdJvSj8zFVzjAc$H^#Ws7qbtNvpV&mn>?mFMPUtb>;9V>{OFq_?+2D z_R$zGvw5T@OdcKc0V3U|K770FC~XXE@NZ c%X_s;;Cd-?~P zC;Z2fcZZLb5Bd)sf6ZA!d{M50XpWpF5aqmUtLouK@ucOKM5T)HamBol#)R(vP(#m# ze(!D36Lb73YmS_MX>RJt2zoL4PLy%&3Oosgao8$_xw_oCPfaLHkHwezD0qD8t2&R2 zCd3+XycfJHG?TawP# )`el;9&?q(&4R#6%-FK@WUEN|hn!mnEXkLF;)(aY7B zMP#H-Y-O_zhWGMI!u{{QOXf%RVddkqG&1Vdk{W-ZCUx5n71cX}OTc04ic9bWINWsc z%=&4S;o15G&-2JqW&f^%A(uj=>v}r*AV-$$K!9(>Jept!HBK971_1Km`#8B x~(moylyKcfgH%+Mt<4nK%5czY=^r4}6N<`LpuqMP%nyS=t2@5Uqwi z0TyOeB~a2Yr;nCY$|}9seCM!le? z%(#(eFj;i0_wz^Sjpzin@lp)zab58!=u+Dz_nyY@wdlA0`u$b(_4%dXD)T}|0Tuyf z0m1c4 N=pqD0qsLb1z%sdgc<8Twv(a(--&tf)eiIn z#4wB%WE-Qr`qotltC3=%bJYUBjvySVdrOtrrW!;=Q~}e3t`Qf(ld+_=8@3-^^&&ez z_)2vSHRlpy?w+~)8dqu26_P!(j`-ZNAEQWR$ZTL@AWUz4(5uFBWE`3cAb5FtnbN|z zCGA(`78eUva$8xEb|~g)DRQI1b^(tsOlg7d)WUv%Bj>r=?xok{o1UD!dNa22dX7g$ zEn~+!5n*j !mL_=rT=v38$uhL6-LDtC~Kb-GfWQ zQbv1mMfMqt$=#!wZ0s?b{EFyFdt}v(u7I42dt-t>8jDn*LHWcjA*LHE70ayJTnfBc z`5UASKDEdXlli1Hz}L=XX47~^%NnRy+2OrC|7ogv%s!#Qa8y@KAPShf1A84WQ+Q>- zN{a` z#Mt0@P~>K!JEMKqKl?OQTF5+eklf~X H@nikqXk$A~x{n=xc zR!3%}=VD w4lFN9eA?*ZnKM`lShvQHb%}GfcD1t(Ha6X;YF7v6gZ@aO2{2T z+^GgQMy%b4RGiv8l!#8mQoWGn64+hZRzEIp7l#0AxOD~b;qLxS9>H(ozZsjXv5c#` zQ%S8 uMLb>b64;M9QjIu_e=V-qPvVr<^si=@amsUNWJ#mWT)*H%V)&SI3U4-i zg|14EYD;r(*i;jQj21Dfe-$)h$!3%jFBYBKv50sTZ9G7^b9rTU%kxG{Um-Is(ipR{ zLZmWHRT+1t8Svb5*X&pAS_NBQk=*FtNZWKihd&2DN8!I_eGz?8eFc9xfAM_DeNld; zeFeR-h^eBEM~ZvkH`5Q(>U+uZwgXWO2X3cww3Osw>w`IL0+&an%lZW)uFaTt5gIYe z7fq@c&ea4Mf3>G5kzcKic>l?xyDVAryJZQ*LOm{E;}*4<4a`sK+&!t4^>eEIg5_=U zp08$$OBTkv-bs}1y54o=-@~2F!|djd;f&sb0+1MtZB 2#&eKZHA<{1VC$ z;64~z|5K*s1MQtfdZ7dQ;NA;Yj@!{@<7c%v#VVc+zK2Z*ccg5^Hy={0mKzBJHN3BVHN`E}grrnQWt z2TOwP?9-fVIk28|0^79p6u4_~ygXYXU(d3K(Q7fClIpKXz#$3})iEH@t_?8@-cg1P z Ne-ydm#dJu{*s*?WYF(XLyJko~dG8 zJ+4*zn*VoD`vQH$IqBqBLK;!h4ZDj;p?2awBz0&O0UsJ*3lIa nMB*LC|uP3nUq-ur~|QkF&Qa}=j4tTN-$n8p(7(aDTG zIIs9_)t$1D^OT402NU7gJT9poHE^%DTT2t|_Z%ZKk@fG=2cN>G;BM0kBR{95*O+wR zQU1$#1@tD;>sE7}2yHE(ppu+k%7->Qn62a{+wG^2hFgshKd;E7+!@g9zd0UR0q}pG zJlyD*PCB*&f?wUaKXap2F#&yVZ-$u0Mr>c-4W;il tI0bzgo&9jI%3#>A>ieU*|U(k+9h;UM0SQCrKTLmI6OLh93FKbhdPgk|58a< zI2h)O80WE0z@@T~26t-rD_8^=ku+z~J6pT7Rthdg+>ms-bn%N0V;RH#rj-f;{N5i3 zNTZ)L-{(4u2)(iNjC;98yRUbB(sUM>^vpvO=*+AcE@yj??TX))$f>|z`u?L2K52Z6 z;ZT)kstw?_L3E@OaZPcLac8<6XI|8q+*#!X${N4=GW^#0V&g-iLAAufLCD10#E2Y* zUVz9$kA_tF-SQj$w+ws@JU+Y* 6K~7Y3=F5>H4W&C(S4A8_ Z&c=J!dMKA}p zwC0GOu{6#KA=^htT0(GI8II$Y?dG5MJo)oK oX?IR zyvaEnwe`r;gaVC4qyA$#%p{YrptZkN6%JQe0(WUaPBpwLOvsU|LWH{Ep4G(mET!5a zO72SFifTPw%oI+H5S&lWq>e=1Kr_o=*I8 E5l3b-?}rLo8kdv;pH5R zx!Yc*;k3gYp7}60#HmW~aBgapDpXT*V}oMEkgSDB!Zf5z<2p?J;ZbRFx@!KXYA4Z_ zK2f>Ba{*bNI61~^bo15-EtN7fu>&dn(!EwM!1s@8A@vTw{%w`Ns>KW8V`;Vz`Hk28 z^}p;yWZ!+wf|CbZ5+si;4BV7_nNFK%36?`O1vK)*Qj)1)7dv#$e>|m~@M3uMLX~kS zhFW24h}eHq006biF()&NOGNsMQ#FY!RkXSy3-DAXr8;{3h;-@VZn9&nM%hSzujgX* zh@uvq3rSoT bQX_HefnaiCjE3S z!g>T-JQQb3N~hex9Ry5=D?!+Up^#9<7_OP32?>OzYg4zskN?`bGcWdUAOU#n;4Mu2 z5&l3SM3av!#Ai=5$qa9YCV`@7EFTMhBb`}jLhtrjz=l1E?#h*r!c{8c|8-g>y_}z9 za#Wg$dC!?2g!QPCR;L;yvG3zU!tgwl=MesREapZ9uCakI>NMYnt;nf&-J+u0V|WQ> zzJaArVZB4@?CjFS*QT@E2aO69v*Xk}H$wR9iUOCkGQ_**`_zyQ3DGz(8}?fjoog2| zGuq-7D0?s?m7JhFpE4OGVK7)9yDozLpCmf@u7>)AF _EwgVm{A6-`1Lgfqfmt z_}pOd5#evpp4noRswr(I4+hsvZ?*;nVI1%r78 v_P6|NL1|@ceIpWds1UEc*@wsW>qV7p^u0g zpBGs@+~b;PC)y~FuUyd&4=t|AD*1zJ()E`Q;<$72+X5wf q(1EN<`wC#2 z@eKv$pf5v}nF{$`NqObe`?fE`sS|fMcb3RL!#y3Z&)hG}{K9~d+lL$Nrr( VJ6+DSA z?CsjBH^rnA$VVHFj_$!9!O(O!=mzXqpj7wGC9VxU9OtizX=44xYnLHd?tU4>UEo+? zp{j&4$qCROluLRj-oVz8nGcu3zU9k3>@G2t=82eaB3sd;601~bd@eeo(2gWnN1vxY zJnS1Qx{_Gy9cvF_m0}dk!Vz(n6}@o8cWw{ol}{nI;C{mlzK&W_1L&J5$4`rp`?o1A z3M?Z_i1qD>#@&NpCUa5)?@upimifz62MQebez%_f5(`_8{F1?>zT?=mgkb@J5G;5> zf|4qBvbqcb+-Y>u;xN!GqjiKD3=Zw1F=U-$O&g?;2o>l##_*4*(l+@pTTMEzx1%w| zHaAwRrV`&tEDoPX{n-)OuyXwBNy`iQ`I
5y1(m*Aj`>L=++VW0A>d)(5-{)wPPUq8sh2s%l9ChjbDVGMFJhPT1DGDUeNM z6W?$YGOi$C?$i{Jo=2zrTz0Y~B7F$MRl%i@Wj5V5Z8c3}QVq!3uuXAXadNSZv7K?W zvHd>nzMKYt*kra;wsf}yxTLzIyA-*^uuXVuWt?z%r||aW9NHY;?BgHj?B?9)oa~(N zUiX~#T=*anP(Wz)$=15o>ess0=56}hN(N@nX%?ko 9nFP31%v^LEZOLH!T8}557Ud~y5 zRONTj<#r8dyA}yqe1!iY`{bOFqa}#Ka3g&dUc#E_uNg($%IAtvN1tP`XDbMLO22<+ zvVZRUHSu>U)iCFwa}zd6?tK?;(WG?tQlZ>t^&}97FTaO=TZsr;@H%bfyfmtNiMWM! zdEQm3oS0WLGgQ!_js?4w7%9MdzAjS^D>(z*;!LMrjD4XERR2Juzn4LZ`WAC7i8$I( z+dKR&YdA4(QCiUQBYJKibc{;5;ez?An(~CuIxc|9!N$O#v(S}T%qmQ^CL-#6WBjE$ zVCG*u?IUzzS#`xx#g^Q%4uikHTRr0I>p&z6wIJ3lnHN(bX~;0)dI_3`0aq(u@?bKK z%qRk}ly%a+Wuld~t+$U!VmP(1oNrL )YAn zrEpu9oOEOCN=t%VHKN)%X`-vOA+Uv%9b8k3$uf0|fZ}NgQ;|KBVDf`A0czkpUr*ZK zBo9n02nyt-*bWqlN2?fgM6+{dd3EdX+Sz1;V0+}i *p3R mb$JOAWie#)Zv(1060J?2{X)7}Q(z-9ZDdjYABm #|q5aB}2j5=&O+G3RcN z)o+t_nTwbwH0LxIl8(zxtPW&cTzhn!4QJq4UMY Jh_}@1BuLfK9QA?Ez{*Pzlz%);Kqu z)?Y^2nD2tQrgeCAu?|QV@=~y6R{?swiHy-GDoWQ8NWmIRyZI1uJQiIpI>qw!fuT2! z`=b*a)9Gk8%wbLl4Bc_YBC7$4?xD=MoYYZkq3T8o@?eP@jKB2%2D%4Fq9>^kEFLtZ zP>OoYtHWI&?{f#zGPWW4XQJ(2lY8C}0b h6qu9L@Cvg4=j_{}%_R5vOmU9K41fp!xvN<$|+2)yrT7m-T3ofPY3FVq&aDU(f7lMFv*a@27TeN@(trHK5; zZ#j#xz*Lo7zryMD*SVEC+f>Hg{RD&hyxWjw=@_zT45~xNnW>Azk%{QWbE(Rm!{U02 z{>2fr;)vw}wSeq!%w>?E$;Uj*9Vxybzk5(Y9cGhdku-lllliHnR{E4=x0pd>_*7gD zk+n#gCuki@akSYOq#bluSEiNH;)(1R9H?E+A16j#3w{I3(2>u^XCL7&W+C#^j{_Rs zbpBjRIYzL2)!u5oNy`>n+3`{WT*VS+sW$xlO#8nZD+vCjCO>BpDe2+9P2d)C9JCQq zjKyytu92l?xgu}3P!1X35D!hUvZw!0fsH1GYvHAPk6PgymYzy|FNw3%Dhyj#LN(~? zyb|rNx4Fr8_$`HDA1$Dr9`O^!knOUjU13YrDAZUEqsnk)>rL}6W7iS$= J+*_ za+VW6Q6z`GUSu7^oQ4qh!SC`D?fp0TrBhZ$$&bj(C8QKPN);Ay&7 UvM8?-^1?ZZt(7NU#46flS+t75PZl?h)oE7(2fwFVods6py`n5lqpF% z&J|G#e@Zj4qj4Oq nASoGe&7 zIW}I!)u9z`m3z`x(ofi3;O3y|q{W48RZn%De#Xwj9d`2G`S?04NO^T!XcwlpH@nQ$ zqRD4ps4~68ehfNZMgqajdfk;3S#|hpE58$DeM3zYu-j~tP^p2cGHVa2rU2u<SBC zSfDOiX0Nw&E?JizF^;=xM$|A`Uxf^t Y^n&N5B6GFQRGA`nS* zokUMOrjmTD+1S@3ls~hvjOzj#FGq2}o%zvsy7s1g6(y*!Wr%0)Cg*X~ Cqj0kZ-0i}EUWchMu_G!Qb9Se?42Ai=lUMo9 zd?{pCF1IkcBIul3X~ukHgPSO_!fSu@fxRG+=rcM}XL-AG!g4Idk(O`Rl_+Er9x5S6 zb$TS6OswERw68R|(<^%T9BOa2lz1&w)V!^M9Cw^I%{NxFra Jq-xeLJ>| z4PKR_iq8Wsx7T!$Nc!UGzkvPA+~n OVZ|T#@Sz}A6No&Q@%9- 7gwz|5M30cYC$Kr~gp`isd9_A4~S zj$sSLEY`8bFfpv<^(tOsmO)tqw}2BN>2lh%JHP>7#OQHq)8lB8*^VFAH}#xjTF}7Q zwCPcH-V40}?4o~aoHE`83$M3>2$6dJoqZ)tZC?O$RIjagQ*1gGeZu2#;a=d^Qc<#^ zMFr(Kfs=o`>Q*tHvcuy0IrNAF)^u${WkWmDzNFKWT`>na#|ftjCtDe#UEsdD $y}Pq_(=0QiN@kOIgP-bo7Rb{UV_dRmi$d#_A}RUh7H5{)hUaaQVswk zlXvlDA{*vgumC489dFGtVF$%KYwp;~Sz1+Oez=0M{OVL6`iwwP-NCx?9K}qIfy&@v zwqjdXQ o`(|WSAQxZUSwAP%(oT@69Y3)p3DMhS0jB99tImz`F@vkR9rg zXPhj=i7pqy$l!`)xL2$+nBDTouS1TpTd&cN8= 6L$ zBCZcu9ocfQ=!2io;@Sj}@!Uyu=XyP9{C?|(PY=Cf(l6eIaM0h=|JiSwtIrxT(i!;r zU#^`NrP##{Wp=LJ*17D9&~|yiE`W2^i`$L#^IF%VRG~}kE`;!SH24+@;0~v)cP-OD zp`wuqNAI&Cj4SEHQn;vZ;QFgQ$FHKTo@Y~1c}dUKRp=Wer2Be6?nOK@G+|I+U&lTZ zCvIe{<4{vc33-X bd$Z`+?`K z<3s5a_ap5K_ABA5GZ(KCLlUkSA_bxcejCOcawG_OfO4<#w*R) tO#2iK1G{$irV9-`+ok&X+mKlBvFP^N3FZ&!_dw8 zHG(~SWJqGfVkF_ zyoD5=1fE=mjGoMf{9BYqq8r(WMmS#j$r;aYo}NGI$sS_}KFU>#p7{EM2BHMy!90W6 zC(n-0tK9Z0@N %V?+-s(-26;QNB! z6^=@9MYX{!E2J~oS$?QBK~V0>S(VHU7A^G~y)9WzM9(i-P4S*BqV#6p`vU})$^^F9 zK_#GaNs`u`lo&JE$+=U+#7KQxw(lrtSqTQIX|iZ}`5c3J_|PYRr}9*Y$lMeIDgFIU zecc|OZ_sp7B-;Z}T9O_D9voUOcR)!dlNb?9`|FBSZA$PYwZZbZyDHtdWyy5^Iyv xNo3hcFlR{%3I43>s8_S%d~ `K&uzF4*Rg7p6HX >20T}h)~cGtguN-B`WaB_INh E`%r>AJnqSrW9Y6)&6~2diMwRF+J5MFbFPz|At9Y)PK}J9(qCl&lYtkkNyZ zu^7*9RFCAye?;Bmyo7ly1~nt@LCzA*7GcKIU@Q&a707X_UJKiXIuBqS%l~MyHq|rU zIq!cDTD`hs>PrYa*4#6^RiiJ-AtaU%Ta#<-Zzi|5cRSVp)wdc`X-twH l3MNO0H_>i5yQ^ zU1#l|0#7s}VDf%R5!EPu2+c48C#IgEg`3Njdc5EQu?}~M 98!NrZ4XuYQ}g~>IHo!iOloE(B(AN?DV$+ZA4$hrfY9C+dxCEU61}ZVJcR|4sgc z&~i?S7*dV%zVZbelIfvi`Avg>#4NXzDQZp;HP9WFGmIGbUN^8&o0-@=BfJ42^^HF( z-1mq@U>`Ty_e5ua;7p9a7`vV$ s?7`$(i1-ExOuQ#YIrMeNaC`rpl;~d}Gt#hY z&h;tTIyq3B3WcsD+jbdJu@jO78Ujek7}#rguCc|?%IF1tB)|_E=(u-dCy*{v*!|P} zriXwxT*fzdUhNBtvDQ ?)Jwj9{%EEHTP&5a@KJzuc%+l%YB?j;g|}aEg;=|Cq4_=^(s1fJmMRUiJiMG zKih!vkuU2?Wvl=PDDzin?M2p}x@njFC6-E909&h7$0;Mp=^-0ly65syqGy=lVwxP6 z9S@RMKkTX+p%dbYykk@9CwbMqi7=0uCEikeVVMqbbJ;SA)`EJ;_xkW-=v9wed{)Cb z)f?R$!|lhfsp8Ba#tX)DKD>7{je^1x8D++yhKzgWL{S-48`*LTx%x6 !Clf$3}y!5Lk!0*d|@mGc3mDMYgXBJZ)FmnllG z8U?sM`iFxt;FrNR8i+TG&knICcp+26}OHZO-1 z>u5JGGvj&vGUf -ei@~`RAg_A_(dT zhzrT}nJ#_14wonx!izdylH)qZsZQ7;ZmIb974~j$OI!9(X_ixVeXV0dIZ@Idju(R2 zK~{8GzethlT32N+35~<4f8Lu2{cIRRg=z|sL%e$ox4cd%9x9zAKw`<;;=H*Pi`rF5 zw8BXR_M*VK*kkc3Mpkh&_Q9`|s9|%9F4msk^L6X@YfY%-;QsALO>%7%O`;5i2M)Mo z{Q{cN;nxMy%J#`}Hu21x5*3!8xTsfqo5AcCIix+sb-y&ua6BZgHMS~y44?&wl{=PT zGYiOd#v_}@hGd(M7iQAJtz?%A;+ksAI-yCwf~AFUfxC)iwU^w2v?WExax>~)&*8SR z59K#h*wDt27g_ktH4+_bhFrwSG>$$vOWPsjs7sclLhrZTMBoo7sG8~kK751Pn$;!{ zhxwuEhPtX-WfGL2! o*; z_pUQ=BwSjIQ3KA%PBl1&QWq))4{sp5?S@yhI(G V4O#_mwVLS>-o?bD)6HRdZtQ)N~LJ*C2gjul3?3 zLob8#X2?IyTwX>ZL1 2fVb zRTsp?*7{5LDOuB2u?$OddYVr5_Z~W8nIK$&9JxLmS^#MhZM?x9&*#Y})B(Bn4iVsW zN-~YmWSq8~|FIm{ycVm9tQ6Bcp V)%j`utV z(%e5=*ErXozW>SAlASjlYYXjcH9}>u=w;yLK=rvKERLBpYi!a`z}~8!mLo}AJ&Cmh znpZ2!h=?(}VMe)s&C5I%t9rOx%shEL|7TmP$d~kp*)@c &RBcmee(tOIpWh)`_$Wc}Lgu^E6=E zVVY@LXgX;6mvm5q1B}S!q;-o1U<4p@j6VZE&USbKaPs1yZt$+{ZrH95SMK99#BGFA zeXsIb-p-E4xc}CIMF2GT=uGvwPX2>4`KmxPIY46$qu~41ve$?n%g_i9x@vGn0AnnZ zH^7koH!6Av?8%bzH`6NMjK)%*zCgp4_MPU9@u~Kv@Vz$23!XN2v^ysG?)N(|Vi%Z7 zL(AOz9VAz73~>CsiJYzve+-cD-@johtFRBaoio;XP&^$0UxfSEm)4vpDfRECcqnTo z3yjhA^m*h!2T*ajSS**+X1MOFDhkj{Yc6vmd8;xC_&T-3Z%v}B(_g{P`jw$#19z!2 zc;rY?eTq+>oS-drD)S)B@7izwzFMI3cN5AxsfToq0bI{wVykNO<$J=z3Gl=YSlW zB$`OVJe@S+WyUd?Qgf~)IWij8Uz}oD>bA^FwI*)~)r_z{F}H)3tg kXO z?gS=<^+b#A#Ph{|df*7h`OHgc6l~!5)&e+8zU)E1i>4nj4&i=k7Xcq}RO$w#-uraR zKj*{XOv`gO2Ci#kWG}XJLZk%L@oftPK8O3kIu{UZ8d^?BwQqs%y$fvXPKyWwVtD8P z{ks0RQr%N%fj<`phkN=5HVR4p531O305vJ{hkPAOe6bn1_x>2U&;D5T#j+#rCHWcZ z9ej4-%utx5Xptf%ddiF7q{lKNiBSK+fX(K%_ra49cwyDv$XYQ|tX}MXbv3bb*y`-# z=_*^HK }xt5@iR+tzhAr=n6|BKI|2UF(S&^$JX?GCP}sA`(mSH>IVu^Qp&VM zuz+~5=&H5mr$zM{tp*#hOPNi5pG$Fb%EwCUjhBvAvIz?r4D^6GQ6j`JaC$6UhAgtt zih$1M-IU)kjY6YH`x;c~kn{JW%*DB2ND@o)-Xz_5&*|-TXdCz%Ob>|^#hlRxrs;HI zZ;$g=eWvVq@FD>%DYm@Bh2e}_Nu)Pp&HGy4E;K0NLHp>etaO%>f5!Y#@*P%KPd7_a zO(~C9>*S=Zz-5R-^X0DxN@dyEm7{n>8!Xf6bMNJe)XGzj@~J3)+mvC42MyGH>z=HL zp=-bN-?;CswHWE7_Z) NnY*ByWP#F>0(;Ko-VW% z_3S41OClKszn>Y}-yEy 3$;D8?v(I_OcExOP%zUGv#&YVqEP Ay-xD_HI&8j`tl8PZX2Ai!d2QPE&~=1Ob@%0$TY-*dWPw@zx-2ERxz-m zui4#k`#h)=L2>y?{`I?kG${xyiF0&CCnNEZll(#J3Bgd4t-pPt!QiUiICCUtSZ1jz zy1+0mIl$So4JHvod^Sfn20}!en^Xl$(_OyX<&q{zp3H;C*hABV?=1X_QFu-GI{PSh z8E6FQcG{oAD9tnglSeS>p9@uPK37AkQBPBw2rR0`?y=jv0hft79w5gXR))__pRK9M zjmYJ5JIlezNtvA!+4ajfQ-Z(Ku&$PUG)%jpv&+r&YCW&XM{PU0ZudRPB80Ui#iOVB zgWeIyn)kzgkkrXGkI&4wy@-O@d)K=eXVSp=-^G>WOkd(0&gAg!pPAdn^cP?&gsl)6 za5cE$PTU@H_yjw+$I~TZGgSc*(WW`(OOXsIkiwt`)>v&g7bP_H86M~;aBbLITV}Qf znx<1fVO(_spdJg03%;0gJC0#80RLK|h(docS2DbJZC6mH8|xVnGkr&6EOfFQ6-_M` zm9Zu;_k(eSI^>r%0VtcO#DENJLBl{|s%H`{5^=1ETWV-&Lz#DH(%V|HTs&wZd|`(# z#A3~c&_mo=nrO|!JqD19O-b3#13Jr;ktB@kDP!6(CA=s(|Gh{3BdTE^#=$Qw1?14} zcc0^c69S~yu +o~&>}`ccYQn%@LVPK}M=15KhR`SM-* z44UN+RUO=j401IGr8@}R-ls1T;n2`SLD0-R+XT#^{#AJ`mXo9lXNQ|Jw6hy7wH~b? zx05t}xPbtBm~*YcZk`hc9&xg3kL+OC2N||lPuSbVQoTsW%d9W_JJ{@_xO+Fx^z(3| z(S&~_ktgz2kY!gSMa%5WnPjX{J2WQz-an^X6s_0|GCD$2OBE{>N)6G$4o-lFrHYa% zD(S`Z$2ppKa=qawOR?~xe5{IGe*%I?0di%0^}mF?jqC3*G=bUE-30IGmd7?-X~^sX zspNKjMo+yr?ns!n$Xqv|Dd$mKngPVwNB)j$^gTD=b55Nzi53_P-Z7IzLX`FYnkb_| zkW9y|uBw=zM2U+UuCo7LWLNRnK^%XSbVn!y&5my7ydJ$XJs0qy+$=A3th>y2bfJ5V zL})+Yn%t*2v`Mr{h@QvV4`k=tu+RBO6_nuZ`9eH-f#j`UV7{X)l)=m#3wrHp=80 zHljvx%}HPE fghN)9^d9O?3CK%cO@M2ghJFZ1CF{-hi6NMRk<4$XD%Z{ zFPh1?=jd&$ws@9)1F!o v@f zSM=Ead4IPOq4SK!#r4xO_6bo%oCUd!_LvEp@#oPaGvH4N!m~(fvv?>+nxt$as$hzs zH<&Q}=}5IEN3-|sZo8Q?W(a p4Nz`Hqq@B+WIZVUX8NPK|+z5G+zLH-K(@?p08D3TMz~B(M}?m zwP@7Nz4~A_?kfN9pVva>bDu_(1o@h2s>8e-`h MsP?jLUiv|boD7_*<6>6v+61||CExr=pGDd#U z@x>=sZ%O0eL`e+cA&*(d;g^rsyx3bAKp@Ga9R(w2_FB?hM1Cgk=xYKWurUEjdS3}h zgDZd7%P(s*bdc((I-yM7P27~x4@Eno+_f~*SbTA&%MzJ)lYE?;7$|laFi)mX2-ko2 zz5%^B(u^c>{ji0aL>Ux%cuRg{75rl~1%YL{!62BT1}ewp>WYh$8TURQ=x`Xnq5*`s zJc5y{a&U4V0z5*6e|qJNy KzO=%k`{8p%+x9!e9DxutgM1$NlaeNdf$D2^Eh zcvE368kWC7bX%6&NFozfA9Y8ze|P`Q$EyosY 25uR_;i(OY=)(?Ujd*|}{6q7X6!QQ!iianX$8tG>d;2{|dFGdjq=0xO z+ePJb<+IKo?g4w9E*+~gPFVgr6v7W6l~fYZ
p3BbsgHyo4K(kB^Q!4^z(X8O~J| zC!7Ul>N9apE55}F>ATG`8>I>jr^$cU a=9e+?>r<=D1n_P7~O}(6?Z)H1c;bI431k#lHB{>g(h7A`<18 zO54P^2HuXgSjtX%+IE^pqy_f`@AaptwhXP5@W^bQ@&)hi3Pg-WpZ?n}iJrAN8{gW< z;l3=Jxvwc#*0bkj0k4B)4Yu%$iy`fVzfe2)ZO?fg#1(r7D$yaleY-GCNlR&N!LYDX z51jClI?tB^6{%=MPL{kMObg2CdvySK-GjZPH>NZHL34W(nl3<$60KPBMwz^xj8~sJ zlN%F!G_;{CzTW(~?9~lR-ZJN7u#M3#DQLcL7%K-?&S37=N@3kc#$9W5`@V}*uv=f9 zX_o5=+zY34mKqJD$-fOr4GHPX^dRra83&N#M81FE2!bHNdIq);p=A`sYP+#mbfO7J zxSqi~Y=&C9D6lkcHfkrXmC^{g%2XS|)DC+CL++p36MS_+bLJ$N`O^1^9?q`)$SVv{ zjlQ@@LO(_g^LFA0L8TZHc&I5QRDDPJ<(gdi%2ZvIsgr2{AdcBSaov<{FEVTWZ*n0! zIa+%&*C$TiM^zU=m3E4}?hhE6Z`~ut4{7h4@3)&C63N?Nvv2qLb`O-E!>ao5Uf*w= zXfvCm*vagVAg^OoK~Ag&Wn1aM8 qvlwp&yH+dF(*CtRCYNVa+dyI_xcDD##LfsS5zy%+|`{#2rf zr&gyWD-ZfayREp8&-dRmVzIe$x{XRY3y;etMNq~3SRn#fQBN2M*0sDiX$9++e`+vp zvu6T6b**(*!M1N@k*YAAT~e?g@cp$#Ojd2OmZN5^%$2TPW%4T+n3%~qk#%Y(&9F7r zi2;00oiUS4_<8!SENS;;UiMRGu==jAB^B@Ry~5QO+88+ztTej7etif)Vf+X{9H7bw zU@dkg9((2$zFJk`DqBQ`7Dg6JMll)XS*?0m>@&@kgV9ohM-oI_TcHQcHtDzll+yQ! z`|N7Pf4_4!ySYz&rrVf$Nkyx(o-aE+Ns4DSJx-=+OTMD3OB!7@JAjA=TM@s(Y))FM zF>g( EEYsvU-F*M;@Exso$+POSTzz8oJdx zNovXftb+IVp`>j~d=uFT&3)KJ&~Opr^uy@n&CGgcyidpmQ<7RM68{4?K*+yU9se}` zr(1v3dZSdY!N99&D>$#}8k49^7U^8uK?B9&5^L7|kR eM%O@QYD`V}l5gAEw8FbSb zP)yIq)gVFC~S(%hss9`X!$@*dAUY~&t~Cl3dqxObKreS7=deS`eW9e4112K(H- zd;9r}P8yO9C_54wGBli8UHf+Q+wWkN`a58YU-}{GI`#~E5$^J$Bvwr-a9`dJlNl&V zmdxk_=8@ kDEcL?1g9z^fk9V#LBR9TUCDu z>#!`9iL&T`135>x7FhM$?|`DPcYIrel5k4AXx-HZ<&aglFCzmDu4JG*^_ly%J7-qS znZ@WLtIpj2^Do>vW73i2YSSx*xW+*xnQWrfDP(Se@rr~rmQGTsI_ODRkz}!DU9WHf zWsw2JM7^#;Z^%=X{6M0~kZuZ=3e(|Pro#-Vv9b=$t)ywvRwZ#;OUjp_p2>R+7lm6( z5#*sZ;eiD*=(h?YAucWr(JUmfx aE<$u0DOxRmDfernTBAoCuA%3MyuWE4(f;{kSPR$bperlxM0 z>g*XE3o3@L81&Yq;EQd&W$LDxsZN*orC^W-U$|EZ>d5zWHLVu77BmKRG6nShZjc?F zXvxll)^@(_IBlP|uDR^vwym8GN!G33`-T0xX#Fd+ZhS$wAl}N>=;$utin#v;Vf}t# z-QXKZnC09g%Z1LYs2c|SD*g#yxCr&6FW1EHDriW1NHU2OpKLWsMa2{|#8F_g>FKN& zVK7%Zdw>Hfu625uf;zAg)5&hh+u5kWb-gAvZ9HnEKLRN#P8hk2O0yFyqLxalz+wO& zb-7Z!e3^P!oYmMLQI8*nk{|&c48n`$Nr$b%xWbukAc-X=%|uT;k{$^D#9iTI|13wg zPwhN3J1LLvh%lYKXBw}Sr{4d^ci%Ol&mD_&M7F1Ar`|HVBhsh~7I>)R%tB7{yyN8P z8>2J@b_=pVS0VpuSL&Vss7EyT4n5(J77A%(4plUaB9UmRz)&)mOTxL4o=7CoJra4h zt}_@|(AvT b6}(XK8} zU@jAP?T`FyhuVK2Yb>4}z0Mb7-S_T~92%VL?v~X9drrr?gK)#$1N$e>E>0gf-ZvPG z@h_s2eT xsDNhadFBF+ZlqIF zhLeG4Vlt!5Y|CcrdMY-%>)aEuxN_%AlFcSNUCCe=?76N4LEZFWAevnx1A&=P%C{q# zj>RVDCr_xUq1(3~-8SJ4#9~jJ+cg`@j32!7t4UWU=s}X5OL^qOCCMNjmygj?@U76` z7D_F9(9jNuOKTn**h*vnL`O$5u4Vf?p1!OWzjW^8x%ZQ)z*VB0OSrBpSw+(mbFi69 z=vq-3PNjwwCXwO5UF*nOce6y?79}Z-bKXPw9_4U@ZcZ(*`pRYnU=;)YQ2l9coi}hn zL0zXh+2@d`?IPW!!Iw?LC_qFn4TB;D*iIilbJP(%_FC;vk429aIq5ev?45k|Ix3M( z9c8g&PcJXuxD-A1zxe5JFA#=(>qth(|3*n?A7N|6qeO6QN?Ep8qHHNW3(X6fkUGzI zm|;HA)!W PKj~|Z+;*E0pD2@j=#3$piG=lk zos!V#SEji=fz))83zV(4NE4}LxELhUVrCW%n2}&YGK$STRxMSMv$M$xrV4Xx1t%qb zu<6JxNJLZX2hFmM%n=K=hFwLczuJ2GSduExf=x;0GUriie(_k_(b*ucMJjth&cWcs z?p@UN#q8C^Y<5v+Q@8EkKhwB6vw#0>2O<|DwJcqv^?Tve0lbVV-5K6$Otwb3g<4ix zwvCm?ljIgl!M7r{6#B`()QdOw?A1U-p4ax)iG g)}z^(QB}f>uGi~2YHN#1v82GdRAg&5^KR&@q#M5Q`|V4xCd(QtH(44+ zOJu+OW!w4~|H_3eN^`{@_TSjm@9VzQ)!*NhnjHPqx)L!Z?(OgQ#{0XM;3io0#ldhf z_?h;y@p)Wfb*sgOrIF2Btvg8O2nE{AWtc8BVx|WI%D}+hv9aLra1r?kb~!Ax=wDIh z{K3%R-gG$?jGY+5I?y1 zt9J #4+542NG5M4_^xZkqE=c%8Bt3gf;M2qJuKV!3M;`ml3St-lX^)WQhpvJ zm1!Kuan@I$TR3M`ADO!230y`z^qEoaKF?|iZO`1?o=oPLCcB)D@m+i7^rQ3BsDzUB zrK8}d@XfCH%W)QuH-6V8GiX*S^SIbHkSW322+}t$5iBH#Ibj>*cvX_7S4E2urj$X` zvAoz)j>jC#|o ?AjTz20@yu zOQOt# tt+AC&(kJ;G$qBpR+q5bWbR(u_!fy>%X1m`|>Kc~G ztXx8~X0v6BwFbxVtG7$;o7T?$^(or287rmNkoC2d$W^kvZnNEvY~s_WwA5%*O} zWxZoxiINs%?M^QF_9rq4e}T%C65p{ 4R`f1sjrJw zf{m9h>H0gpeT{F@J9qVYN4?N~98LbCn` e?4S+t4)}xt#T0oZvTdu{VgLi@xz r27UghoT5(XZ3m*Z8(lv9HUs_A^cYGfQ5Z z!uO}P=-Z07%*{h_R94YewGWbOqS^AgyFrd?aTy3L!+<%|^wM=vS?wPj^h-hyMejM1 zrvbYLyrjFJ%1QQ1nUfjd`DQ&0^Pf)s(@D0B$8b3C5*#)qjP%6@XwH@0Elp1WC^9B} z`qQ6gZ{ryUe*M=2Yp=cgZWn!?ddPeK{p2yp^+vYTynu3V;H*%+Z!)P-!?CDRT0=+E zx~}uKWsuyz(;C;Hnm~_}d-!t4!y4RP*D9 I)u}i)28#Op*`cq0v2yAERQ{W6ckRNf%H>AQkh#(W0|3pGmVZAOoZEu3D=6sx#ixjp&h=S!S3X2_dtIi^L5J)q|zPf z9=Y>7qu!24G!`ApjQR!#f}=YNBl!c1nMmSrR|gm|xsND)0cZF0Xy52aB*=zb&h=k0 z#I=SwnwR|>b=UP0I*(C9sUz)EtJl$6j7i)q#-a nkG3! zPbMxcX^yDnRlhY;X`9Yc{!KiL+Puz}S6A0fP5U&7aXSV}lNSuCWMx)=_5B0aeXvqt zM&Fxme9hTP#ip9^K6+dGPFYrA%@peaP+kj9p$q|@6=yzsHdcaGS^cUaCo_3SLhB0p zd_mv6=v8qM2!oq^!T$ari^C!O+EO7ogP6*C-{SgXL|RshO}A$#OPxFVOo91LlTH{A zQpHh)ysStYH40Q;R+<5g)OKkR 6Mza_2{ZVaSiUP z(lE{D;OgY_Ht}X%d`8I0XyB;AbO?_zY3$_9f$W{}JF|f=5_N5s(^G3}Q|C1*O_lw3 ztKZC$bQy+7737oitoz6V>a6dEg~jRPwPU+s1m532w`UA`PeE+&wmrQw>C6>!?V}eE zJM8+2*NnYpV({VnTAlcf+3Y12Y+N;1T%6!ue(*uj62b#>ew=1FBK5Z(B8$jBFK-wp znO=gqv}})-a9SKKH=zMlnOw08*QNpYbn&Jvkbn;Y1^6XzzfA%5dy`&oi$<%F{aBJ) zSg5iO@&F#s77Yn*EVx=L7K4TXl_4 FiqF`jPMAqA#dd$d_@}cLz$;WI3qz?OpSq-d{T}p*{l+mCw-x1uoEJ= zCdo()pCtM*aj!zs?IGh14G+5 U)2b#`BAj ;_r>~XIpa1XX 1dnjS@(thi!;Jh&&n6KMfRJGtKxhw)DF(W+%`&L z0x!Fj-y>7V3T=E-$46-B_*>h|@sTJR%Y!a#wO$2UiVQF@uwbLHfDDWXI~jQlgo4`2 z8_U)GKMj%~_RdJ-(~(C{#8E05zm(TbM#`G<)5j4gMo3x0dhx4by4HB3{@K^7l;R4c zR%J#df2o;P`4T2`iEP{}kW!h|+kNWWc}koR$fy2xug~ZGZ@5a9>fqO=qbk_j_(c?x zvqN5=Mt$B+)h&f^6i%X7+$Jfm;jAyFSbYA$=U-||j@hY^K54UZ9T!qy)waj~51$w6 zh^)l3P)F@{4jarI#KdR%V3Ldj@=s?VFf!0LcAJpd|L9Y2s)Vl*hO27-z^&usOlvEE zlPnG%C5vk}(U2L%2afPCvyt%`4H#_K*x0U{ZhBO?4J8G)DL*xSiglbCzv-q&Uf^e5 zkleO!G <-f`&A9en+TP^em~X|LlaX#I=Fk4s|8 zuon|8s`v<$YRlm-$=^7>jGie>7qehRaxwnNCA{{ykP-GlvHZ>P*}X1hMZIFB${(Y( zNvRF+Lt2Ze5$Bj94p(hUi%F;%thOcf+hRgCm-iL&B7t-Ysx2!}XiE17n-&%sCLPW$ z826rg;=WV!N6(%)b>F~3*U|a%LgMTb=gvIRVRT%-uy~f;)A7ie=}clM3=mV2t7*H| z1Fa+^Ww_64OC?so`Bhe_wWKVCBzFa1WsM}`ni0M2w&=dkM)&QD-qyHkoh)la=N7e7 zcy&Mg_D654;7JyOv+z}I-3m$O;+yOHQwphCNYA3Mda+C%wuq0=xVj2#3~IzHmoL}6 zopm?~E3dw07(jLEwug|&tr1F&Wz*}X?baR#6@)|4uA&{Z=y$*wdNR%}(z?b?i^9H^ z1A=X#uCO)IHlRIVvpuCq+{0mdkT9E{N4_u^^jK}0&;0EAY*xOoPuq7vws*ctjk @U2jl^RqIQ{IG#%H0uZbzasoAU5-6ejM_GQ;smbn$F= zyx;v_w@g3$FCorPb_*xjr3}a-gy99-3@kV=6@lv~)`jV%BDPsTWLse?4Spb4zBy3N z#28qqvlX2o!cB)X&%RA^K$`ug3mFjSvY%%!zR31J(s+ca?4_63^~It{fr57!SvZoH zIr+FLLB+<*Lx=NCw9L$eQfVtj5IDSG$alH1BI; huD>u-uY zy5teimV9JckddY(iS#fyuDGoMj@Wb}W^F@TRDC2+BtxuR@iH3OnJ}Q?j&`}^4+Gut z79d|iUV>-WF4Hx-%1qqVp1@oD=80`Zrqg+gWBCjA7ft^xVhA(1BDoN|{gFp*t{#85 z3V-Y`9)az{$E!Ct{<2z?Tmr7lFd=b}R0$iByv|xfvBpglL9jNa{qN`cf_*+5I6+l_ zn`QJ-6V!5gFxb`C_pBFD0Kwb_ r@sG_$!jMZIPT*I6N*YA+f$ zOEN_xj@ss>qq vo;277pW#t?FADYyX%M&4N`dk zPzyJWmxoUE-tnG}xaR=7*wyuPXSnMXsjKU$&Pdl>bmEb3JUkU;SGv3V6y^Pd@X#Fu z9IkHKg(un5x9_<1?Qri?U0qCqXP@qZ$FdK9 $N-`Tu8Pi5G7!T&Uqp8ind6JudFhE6bqag&MgK`)COjvPAk?Zkx6e*b~LoXEbB{k6C8_eUd#?q>N&AbaDx{-R6r z*it@GCU48$6AJl9qTbIs2KE`+0tm~oMQC_{Ji1XTUB-2db|og=C8cSc%Qlh7lH&YD z)dYLoq7afM%PH6}qo{-ijBsQu5;nlUZ74ky;sOr^EeHledwPfbL-6a}6B@|&MgoyY zV5ld%0#h-ki0OOPX+$IRnQMKX3|^Aid>p MgCi}&Za1B@&e16>j7`0M?9)$d zn+ay7?)Z^A$d;QGlf#Mzv?&^R18??u1f%{D$qf52e%-lLzm( Kz?hQ0)L?TF6y9g)Df<;LZc$EAU_u?pmMShTR}MmmV3Wtf8a*` ztw8e1)E0%l{D#Q;Pes`Lx>Eo38zMh`D)N;L29!=IZjBaQmIqBT!wrml89B$novcYY z!^&US-W5f*Z1s=+=sbIWB;^?Fhr=aS***j*e_g-(58u_eE0XFD!kC&`;xZtGnQV>Z z^++%AF`KtUDz{*zrTA!{U5JChZ0_JJw7)nY7sCb)nECR|fdezF3r&Gv!j^aC3bw &j$8K=M`w!VK44#$1tBSu1ZOu2T% zBE}tB+(;zZlw&R&W2(oiKs(QPCMRVrF`@R2_N#k_$K}bXj_mM6a9~(+Z=%m@dJ<=> ztrI-n;q#L1k*SjjlVX}H_Ky`CrX=~=Q`*Fzv>@#O8fBj(A=jzk*aTa`mx2+-4f}3e z;b+afpZK#J@g*DN@!(iHB0o)D|E6*ht@6h@^pp9UhJ$6-0Q))9^o)rmMgLh(gKIn zkk~J2CpEHOIk0+iwFnak9Fz459{&eh0)G9Z^|l4OB|yfqb?mghe1Td7Uu?B-9`=2( zg*P{O9ihUPnRVE$V!hA@FT$GqoNP_7N!3J0tXT>4tVz48TstiFi0`q*J5c%Qiwjx- zET10_g_ewO>9or1rz0vi6sTI&s#PGns3^dn!kWrl;UzTTGW@V?jINnhVe58D;qO0I z=XOg~c|B5{`>b !g=5)nnVQ`QVXtA@hnoFow@7MYb!v @jjB@Y7c0ljpI^^*Dtk?8Z?5H#ws77ctM!LQ|6!~4QLt~HUIx$E45o( zvsJ=^xTW?vaZ74Sq1KXCt*$j);5GWdyc5&b9-Ej!Z@<#47hX$*) MtJf%Y zjaog1;dS9{a WRMp}~apHQ#Wv za+yqm#3-%J3Pu__lRd_&+-BL 5m`s0sWTG#(bGwJlMIK2QbMIvp z<79Spr_0^A5_#nKWABwDmoO9ea%3i&i)|u&z5t3P?wFY5o`{7EpPDN=_*^Mnjj#Rw z-EZ&ey42O$SO9vB YJ!1a g+`;cLj5%HcI1Qk~|8LbFNc^x0Yi5=u$qvbQJP7 zQ30c^9z6;_c$d5c+yQ%@r)K+ziam3*4JRRJZ3!jATAn8HtoUOU$OwOVI%a-QJP!=L zme!VZq1KcxD3EJr{d>qw9BAMeT60Vu7cuAhvXRLcX&;Ik3}7IeFIWl&vhXvEV5t@? z1-pV>WMyng_G5ws0-7Wyya5ZyG^zl804^em1s+ZS;jCJ%A)B>URPYqB{@l8#!YZt6 z;Ug5N%t^jsx@MT#nr;9ARx-^JF2s40S164YL=6zl0lnJ?{{}+%FlE^&Gsyr8&Z>bQ zQgYH$RCCnwY#Tu$6Cn*6r>aa_Mwnux<{*_ HE= zvVtlFf {oI$C7P5*AwgK?h4pC=#2vU>P#QP`RWzem6w)9h2}^=WY0Qg! zFKkI#{l(>_e0DJlELjnBxz(7i$Ewvl? uMW@$#Plx&$Dy4+YI3`N(DIqY7C+LI5@m`lxY`^*2Pl3biurk=Lfj{ z-^X4Ou`$FIIzAupmi@=!|w0BWe6fFjxgR>Z%QGTbKitF^|dw?vHt- z5IC6a?<~&r_!t1G{ysC$IGMap3HA4l1~Q+_jdnZx`+IM5b;L(z^3m8o%#Zf>b~qfm z&fLs5u*>gp%6-GL4^IR=9Vj D`bbRd*ri^kM$ zJfM?wk$9uOTNp|$^(Bu)506~1BnPXoa0`8Nm9PHo^lP+Q?J7xUbhr*bo!?Qk?jRJ8 zB}r#5Hph61V4%t=SPB;ZgH_0uC!!OL--u2`U$1F6Tbt~GiRk2HbRuRNFmM^m%UpYQ zh1FSJir8OtB$M>OVq+Vqxp`dJ^C-z3?OE(O49lo^!1ADoi^HF_kv7z_1vd+f7}oO| zR5OpuR%TahI>Yv%%~*5>y8;x#Dhrm4GDAAUC=;O}YS%^(za(YJim9Y&l;V1*$140y zf}ja%1__GpJHHSaoN#E49ovReH*8af@-EG}Z`*@3iM*j_ewW%C=?jc)>(ew(GO`ft zN%SaqWJfDvP0t3I`U{n`%(P3!C1w#q*34eFyah;(Q^?cE&$yX8PP}B1K)$r_UI^~t z3pL6(XfA`Myj(8V*23&AGHeew%r$V`y?RxAb3U(&p0Ml3WA43L6Gmk_B+q4GaNd;K zrT3zLA1v-`P`f&gzRjg*q|-?55{z>&$P}%#1+_~f$r1JftJ$8SqZa0w!`gbREgK=P zoDb0Yaa!NU!=(+==54fI7s1g_*w8S;0|%-U)Qqj!fm$lSzM3Nt%fbeiHnRwSW@&!D zG@p;_qdNR9wP>xiJX{AA>vvDa`{6fj8uX{P$92d !v zT$9^PH%Y!w{!!cLHJv4*ujye^vA!Hdk8q-l4z}$4jvWv0-1!jL#hLhNzVs#P Y>lDrhlW@A^b%zVLC`{)WN><~Le zVom$L0rCMOwuLkB==2t39~j@hJKI>xFYTRHj!kSo$28|IExUUuKXb&LnLZ-6?*S>? zlu^ua$2lrkvnO95yNlUmbV7Eb;?2oJf58Bh%%z4Hv 9SEW%I$By2F&%!`V?(laFyDy4!zL& z6pVa2c#`gx?PoG6fNOmug E{`A6VI+NADSC7h Hb zH@&++N`8KKv50r;B@^xzVj&{UrIM~*gig^#*U+j?n%ySquVB5Pw2*nl=W{Bnt~Z1; zbwr1jgoJbv|AeBQZHmd+o^EBw+zt*JX^5#;f__!?2df}V3yqu?vk}VMEe*G0FKkSo zFu_YLjA<0FlLJVVqoEM6v@Re^VA%sS=hz4%;&xr|8m=){Zhcn2|HR@seRnpTHdvLr z_B4L6UhBd>Nof5n0Bbze5Zf0Se~m z`_Rgc^+R-EXg$tzlGKRF4QS65ZAIgdQe^B$oVuYXhRxv%DMr@Ya3vLM=HEI^60q1X zhq|WeR;nJ`Pfd_zPqolQ3YJvSO*3N?c)5+SRdUG4nB}rbYmStx;a}KikvTdzA2P)R z`pGa#8u5mNx7^}=(O1N@>>QkSG{}u^Da67QR|s&EufV|_UQEcS0SQY#(8$5IxAmG7 z;?_6{Z<)Mb+qSH8pML&gI&2idNVsT((`@bj6PLs3s*WL~b% L@!yIlLo9J`d~&T#4TH zaa!XYpOxOmitKIV7hS+RK1&b(B&{ir&q5wWx}Kpt=+V#8T8J>$L4K$z&!pD)@-e*O z7*n+CaOb*aRKjOSr%60%hHf??56mlS>iX}~j?`nJsMVVBJct{&I8+TrwMDds&lUbp zK8I9XF}~LqQA$^BDIr(nR%k~TP8z~k#U$NEcBejKRYw9