diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index cc7f030ec..2cb383ec0 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -12,7 +12,7 @@ permissions: jobs: coding-standards: - name: "CS Fixer & PHPStan" + name: "CS Fixer, PHPStan & TwigCS" runs-on: "ubuntu-20.04" steps: @@ -24,7 +24,7 @@ jobs: with: coverage: "none" php-version: "7.4" - tools: cs2pr, pecl, composer:2.2 + tools: cs2pr, pecl extensions: pdo, pdo_mysql, pdo_sqlite, pdo_pgsql, curl, imagick, pgsql, gd, tidy ini-values: "date.timezone=Europe/Paris" env: @@ -46,3 +46,6 @@ jobs: - name: "Run PHPStan" run: "php bin/phpstan analyse --no-progress --error-format=checkstyle | cs2pr" + + - name: "Run TwigCS" + run: "php bin/twigcs --severity=error --display=blocking --reporter checkstyle app/ src/ | cs2pr" diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index d2de81748..44e10c59d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -48,7 +48,7 @@ jobs: with: php-version: "${{ matrix.php }}" coverage: none - tools: pecl, composer:2.2 + tools: pecl extensions: json, pdo, pdo_mysql, pdo_sqlite, pdo_pgsql, curl, imagick, pgsql, gd, tidy ini-values: "date.timezone=Europe/Paris" diff --git a/.github/workflows/translations.yml b/.github/workflows/translations.yml index b5de2b372..2194f49e6 100644 --- a/.github/workflows/translations.yml +++ b/.github/workflows/translations.yml @@ -29,7 +29,7 @@ jobs: with: coverage: "none" php-version: "${{ matrix.php }}" - tools: pecl, composer:2.2 + tools: pecl extensions: pdo, pdo_mysql, pdo_sqlite, pdo_pgsql, curl, imagick, pgsql, gd, tidy ini-values: "date.timezone=Europe/Paris" env: diff --git a/.gitignore b/.gitignore index d31a615dd..2504e972d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,11 +9,10 @@ !/var/sessions /var/sessions/* !var/sessions/.gitkeep -!var/SymfonyRequirements.php /bin/* !/bin/console -!/bin/symfony_requirements -.php_cs.cache +.php-cs-fixer.php +.php-cs-fixer.cache .phpunit.result.cache phpunit.xml diff --git a/.php_cs b/.php-cs-fixer.dist.php similarity index 66% rename from .php_cs rename to .php-cs-fixer.dist.php index 9ee02779b..a64299b8b 100644 --- a/.php_cs +++ b/.php-cs-fixer.dist.php @@ -1,6 +1,7 @@ setRiskyAllowed(true) ->setRules([ '@Symfony' => true, @@ -10,16 +11,18 @@ return PhpCsFixer\Config::create() ], 'combine_consecutive_unsets' => true, 'heredoc_to_nowdoc' => true, - 'no_extra_consecutive_blank_lines' => [ - 'break', - 'continue', - 'extra', - 'return', - 'throw', - 'use', - 'parenthesis_brace_block', - 'square_brace_block', - 'curly_brace_block' + 'no_extra_blank_lines' => [ + 'tokens' => [ + 'break', + 'continue', + 'extra', + 'return', + 'throw', + 'use', + 'parenthesis_brace_block', + 'square_brace_block', + 'curly_brace_block' + ], ], 'no_unreachable_default_argument_value' => true, 'no_useless_else' => true, @@ -28,7 +31,7 @@ return PhpCsFixer\Config::create() 'ordered_imports' => true, 'php_unit_strict' => true, 'phpdoc_order' => true, - // 'psr4' => true, + // 'psr_autoloading' => true, 'strict_comparison' => true, 'strict_param' => true, 'concat_space' => [ @@ -45,4 +48,5 @@ return PhpCsFixer\Config::create() ]) ->in(__DIR__) ) + ->setCacheFile('.php-cs-fixer.cache') ; diff --git a/GNUmakefile b/GNUmakefile index 399fa44f0..7a7f60ed2 100755 --- a/GNUmakefile +++ b/GNUmakefile @@ -46,7 +46,7 @@ fixtures: ## Load fixtures into database php bin/console doctrine:fixtures:load --no-interaction --env=test test: prepare fixtures ## Launch wallabag testsuite - XDEBUG_MODE=off bin/simple-phpunit -v + XDEBUG_MODE=off php -dmemory_limit=-1 bin/simple-phpunit -v release: ## Create a package. Need a VERSION parameter (eg: `make release VERSION=master`). ifndef VERSION diff --git a/app/AppKernel.php b/app/AppKernel.php index 347197e4a..aabe7579a 100644 --- a/app/AppKernel.php +++ b/app/AppKernel.php @@ -48,7 +48,6 @@ class AppKernel extends Kernel if (in_array($this->getEnvironment(), ['dev', 'test'], true)) { $bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle(); $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); - $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); $bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(); if ('test' === $this->getEnvironment()) { diff --git a/app/DoctrineMigrations/Version20200414120227.php b/app/DoctrineMigrations/Version20200414120227.php new file mode 100644 index 000000000..a24ce45ee --- /dev/null +++ b/app/DoctrineMigrations/Version20200414120227.php @@ -0,0 +1,23 @@ +addSql('UPDATE ' . $this->getTable('config', true) . " SET theme = 'material';"); + } + + public function down(Schema $schema): void + { + throw new SkipMigrationException('Not possible ... '); + } +} diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.cs.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.cs.yml index 3db86d926..2ca932278 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.cs.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.cs.yml @@ -1,10 +1,8 @@ matomo_enabled: Povolit Matomo unmark_url: Adresa URL Unmark, pokud je služba povolena -scuttle_url: Adresa URL Scuttle, pokud je služba povolena shaarli_url: Adresa URL Shaarli, pokud je služba povolena share_unmark: Povolit sdílení na Unmark.it share_twitter: Povolit sdílení na Twitteru -share_scuttle: Povolit sdílení na Scuttle share_shaarli: Povolit sdílení na Shaarli share_mail: Povolit sdílení e-mailem share_diaspora: Povolit sdílení na diaspora* @@ -16,7 +14,6 @@ export_csv: Povolit export do CSV export_pdf: Povolit export do PDF export_mobi: Povolit export do .mobi diaspora_url: Adresa URL diaspora*, pokud je služba povolena -carrot: Povolit sdílení na Carrot download_pictures: Stáhnout obrázky na váš server settings_changed: Konfigurace byla aktualizována shaarli_share_origin_url: Povolit sdílení původní adresy URL na Shaarli, pokud je služba povolena diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml index 184410239..3a1e65dc7 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml @@ -1,5 +1,4 @@ download_pictures: Download billeder på din server -carrot: Aktiver deling til Carrot diaspora_url: diaspora* URL, hvis tjenesten er aktiv export_epub: Aktiver eksport til ePub export_mobi: Aktiver eksport til .mobi @@ -9,12 +8,10 @@ export_json: Aktiver eksport til JSON export_txt: Aktiver eksport til TXT export_xml: Aktiver eksport til XML shaarli_url: Shaarli-URL, hvis tjenesten er aktiv -scuttle_url: Scuttle-URL, hvis tjenesten er aktiv unmark_url: Unmark-URL, hvis tjenesten er aktiv share_diaspora: Aktiver deling til diaspora* share_mail: Aktiver deling med email share_shaarli: Aktiver deling gennem Shaarli -share_scuttle: Aktiver deling gennem Scuttle share_twitter: Aktiver deling gennem Twitter share_unmark: Aktiver deling gennem Unmark.it show_printlink: Vis et link til print-indhold diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml index f86e009b5..7c744d9f3 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml @@ -1,6 +1,5 @@ settings_changed: Konfiguration aktualisiert download_pictures: Bilder auf den Server herunterladen -carrot: Teilen zu Carrot aktivieren diaspora_url: diaspora*-URL, sofern der Service aktiviert ist export_epub: ePUB-Export aktivieren export_mobi: mobi-Export aktivieren @@ -12,7 +11,6 @@ export_xml: XML-Export aktivieren import_with_rabbitmq: Aktiviere RabbitMQ, um Artikel asynchron zu importieren import_with_redis: Aktiviere Redis, um Artikel asynchron zu importieren shaarli_url: Shaarli-URL, sofern der Service aktiviert ist -scuttle_url: Scuttle-URL, sofern der Service aktiviert ist unmark_url: Unmark-URL, sofern der Service aktiviert ist share_diaspora: Freigabe für diaspora* aktivieren share_mail: Freigabe per E-Mail aktivieren @@ -40,4 +38,3 @@ api_user_registration: Registrierung eines Benutzers über die API ermöglichen store_article_headers: Speichern von HTTP-Headern für jeden Artikel aktivieren shaarli_share_origin_url: Original-URL mit Shaarli teilen, wenn der Service aktiviert ist -share_scuttle: Freigabe für Scuttle aktivieren diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.el.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.el.yml index 4b4f77f33..685ba7de7 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.el.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.el.yml @@ -18,12 +18,10 @@ wallabag_support_url: Υποστήριξη URL για wallabag show_printlink: Προβολή συνδέσμου για εκτύπωση περιεχομένου share_unmark: Ενεργοποίηση κοινοποίησης στο Unmark.it share_twitter: Ενεργοποίηση κοινοποίησης στο Twitter -share_scuttle: Ενεργοποίηση κοινοποίησης στο Scuttle share_shaarli: Ενεργοποίηση κοινοποίησης στο Shaarli share_mail: Ενεργοποίηση κοινοποίησης με ηλεκτρονικό ταχυδρομείο share_diaspora: Ενεργοποίηση κοινοποίησης στο diaspora* unmark_url: URL του Unmark, αν είναι ενεργοποιημένη η υπηρεσία -scuttle_url: URL του Scuttle, αν είναι ενεργοποιημένη η υπηρεσία shaarli_url: URL του Shaarli, αν είναι ενεργοποιημένη η υπηρεσία import_with_redis: Ενεργοποίηση Redis για την ασύγχρονη εισαγωγή δεδομένων import_with_rabbitmq: Ενεργοποίηση RabbitMQ για την ασύγχρονη εισαγωγή δεδομένων @@ -35,6 +33,5 @@ export_pdf: Ενεργοποίηση εξαγωγής PDF export_mobi: Ενεργοποίηση εξαγωγής .mobi export_epub: Ενεργοποίηση εξαγωγής ePub diaspora_url: URL του diaspora*, αν είναι ενεργοποιημένη η υπηρεσία -carrot: Ενεργοποίηση κοινοποίησης στο Carrot download_pictures: Λήψη των εικόνων στον διακομιστή σας settings_changed: Η ρύθμιση παραμέτρων ενημερώθηκε diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml index 8c92aebdd..4ceabd761 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml @@ -1,6 +1,5 @@ settings_changed: Configuration updated download_pictures: Download pictures onto your server -carrot: Enable share to Carrot diaspora_url: diaspora* URL, if the service is enabled export_epub: Enable ePub export export_mobi: Enable .mobi export (deprecated, will be removed soon) @@ -12,12 +11,10 @@ export_xml: Enable XML export import_with_rabbitmq: Enable RabbitMQ to import data asynchronously import_with_redis: Enable Redis to import data asynchronously shaarli_url: Shaarli URL, if the service is enabled -scuttle_url: Scuttle URL, if the service is enabled unmark_url: Unmark URL, if the service is enabled share_diaspora: Enable share to diaspora* share_mail: Enable share by e-mail share_shaarli: Enable sharing to Shaarli -share_scuttle: Enable sharing to Scuttle share_twitter: Enable sharing to Twitter share_unmark: Enable sharing to Unmark.it show_printlink: Display a link to print content diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml index c09820e74..728cab6fa 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml @@ -1,6 +1,5 @@ settings_changed: Configuración actualizada download_pictures: Descargar imágenes en el servidor -carrot: Activar compartir en Carrot diaspora_url: URL de diaspora*, si el servicio está activado export_epub: Activar exportación a ePub export_mobi: Activar exportación a .mobi @@ -12,12 +11,10 @@ export_xml: Activar exportación a XML import_with_rabbitmq: Activar RabbitMQ para importar datos de forma asíncrona import_with_redis: Activar Redis para importar datos de forma asíncrona shaarli_url: URL de Shaarli, si el servicio está activado -scuttle_url: URL de Scuttle, si el servicio está activado unmark_url: URL de Unmark, si el servicio está activado share_diaspora: Activar compartir en diaspora* share_mail: Activar compartir por correo electrónico share_shaarli: Activar compartir en Shaarli -share_scuttle: Activar compartir en Scuttle share_twitter: Activar compartir en Twitter share_unmark: Activar compartir en Unmark.it show_printlink: Mostrar un enlace para imprimir el contenido diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml index 20b8769ae..cce8b005b 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml @@ -1,5 +1,4 @@ download_pictures: تصاویر را در کارگزار خودتان باربگیرید -carrot: فعال‌سازی هم‌رسانی به Carrot diaspora_url: نشانی Diaspora، اگر فعال بود export_epub: فعال‌سازی برون‌سپاری به ePub export_mobi: فعال‌سازی برون‌سپاری به mobi @@ -9,12 +8,10 @@ export_json: فعال‌سازی برون‌سپاری به JSON export_txt: فعال‌سازی برون‌سپاری به TXT export_xml: فعال‌سازی برون‌سپاری به XML shaarli_url: نشانی Shaarli، اگر فعال بود -scuttle_url: نشانی Scuttle، اگر فعال بود unmark_url: نشانی Unmark، اگر فعال بود share_diaspora: فعال‌سازی هم‌رسانی به Diaspora share_mail: فعال‌سازی هم‌رسانی با ایمیل share_shaarli: فعال‌سازی هم‌رسانی به Shaarli -share_scuttle: فعال‌سازی هم‌رسانی به Scuttle share_twitter: فعال‌سازی هم‌رسانی به Twitter share_unmark: فعال‌سازی هم‌رسانی به Unmark.it show_printlink: نمایش پیوندی برای چاپ مطلب diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml index 8f82781d5..971b9137c 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml @@ -1,6 +1,5 @@ settings_changed: Configuration mise à jour download_pictures: Télécharger les images sur le serveur -carrot: Activer le partage vers Carrot diaspora_url: URL de diaspora*, si le service est activé export_epub: Activer l'export ePub export_mobi: Activer l'export .mobi (déprécié, sera supprimé prochainement) @@ -12,12 +11,10 @@ export_xml: Activer l'export XML import_with_rabbitmq: Activer RabbitMQ pour gérer les imports de façon asynchrone import_with_redis: Activer Redis pour gérer les imports de façon asynchrone shaarli_url: URL de Shaarli, si le service Shaarli est activé -scuttle_url: URL de Scuttle, si le service Scuttle est activé unmark_url: URL de Unmark, si le service Unmark est activé share_diaspora: Activer le partage vers diaspora* share_mail: Activer le partage par courriel share_shaarli: Activer le partage vers Shaarli -share_scuttle: Activer le partage vers Scuttle share_twitter: Activer le partage vers Twitter share_unmark: Activer le partage vers Unmark.it show_printlink: Afficher un lien pour imprimer diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.gl.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.gl.yml index 5615ec474..aede3bf89 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.gl.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.gl.yml @@ -18,12 +18,10 @@ wallabag_support_url: URL de axuda de wallabag show_printlink: Mostrar unha ligazón para imprimir o contido share_unmark: Activar a compartición en Unmark.it share_twitter: Activar a compartición en Twitter -share_scuttle: Activar a compartición en Scuttle share_shaarli: Activar a compartición en Shaarli share_mail: Activar a compartición por email share_diaspora: Activar a compartición en diaspora* unmark_url: URL Unmark, se o servizo está activo -scuttle_url: URL Scuttle, se o servizo está activo shaarli_url: URL Shaarli, se o servizo está activo import_with_redis: Activar a importación asíncrona con Redis import_with_rabbitmq: Activar a importación asíncrona con RabbitMQ @@ -35,6 +33,5 @@ export_pdf: Activar exportación PDF export_mobi: Activar exportación .mobi (xa non se usa, vai ser eliminada) export_epub: Activar exportación ePub diaspora_url: URL de diaspora*, se o servizo está activo -carrot: Activar compartir en Carrot download_pictures: Descargar imaxes no teu servidor settings_changed: Configuración actualizada diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.hr.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.hr.yml index 10310013f..4e18c0b6a 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.hr.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.hr.yml @@ -20,7 +20,6 @@ import_with_redis: Aktiviraj Redis za asinkroni uvoz podataka restricted_access: Aktiviraj autentifikaciju za naplatne web-stranice export_mobi: Aktiviraj .mobi izvoz (zastarjelo, uskoro će se ukloniti) demo_mode_enabled: Aktivirati demo modus? (Koristi se samo za javnu wallabag demonstraciju) -carrot: Aktiviraj dijeljenje na Carrot diaspora_url: diaspora* URL, ako je usluga aktivirana import_with_rabbitmq: Aktiviraj RabbitMQ za asinkroni uvoz podataka api_user_registration: Aktiviraj korisničku registraciju putem sučelja diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.hu.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.hu.yml index 168713001..9176c0a0a 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.hu.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.hu.yml @@ -1,6 +1,5 @@ settings_changed: Beállítások frissítve download_pictures: Képek letöltése a kiszolgálóra -carrot: Megosztás engedélyezése a Carrot-ra diaspora_url: diaspora* URL, ha a szolgáltatás engedélyezett export_epub: ePub-ba exportálás engedélyezése export_mobi: .mobi-ba exportálás engedélyezése @@ -12,12 +11,10 @@ export_xml: XML-be exportálás engedélyezése import_with_rabbitmq: A RabbitMQ aszinkron adatimportálásának engedélyezése import_with_redis: A Redis aszinkron adatimportálásának engedélyezése shaarli_url: Shaarli URL, ha a szolgáltatás engedélyezett -scuttle_url: Scuttle URL, ha a szolgáltatás engedélyezett unmark_url: Unmark URL, ha a szolgáltatás engedélyezett share_diaspora: Megosztás engedélyezése a diaspora*-ra share_mail: Megosztás engedélyezése e-mail-ben share_shaarli: Megosztás engedélyezése a Shaarli-ra -share_scuttle: Megosztás engedélyezése a Scuttle-ra share_twitter: Megosztás engedélyezése a Twitter-re share_unmark: Megosztás engedélyezése az Unmark.it-ra show_printlink: Hivatkozás mutatása a tartalom nyomtatására diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.id.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.id.yml index caf491d32..21f6af160 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.id.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.id.yml @@ -5,12 +5,10 @@ export_pdf: Aktifkan pengeksporan PDF export_mobi: Aktifkan pengeksporan .mobi export_epub: Aktifkan pengeksporan ePub diaspora_url: URL diaspora*, jika layanan diaktifkan -carrot: Aktifkan bagikan ke Carrot settings_changed: Konfigurasi diperbarui share_unmark: Aktifkan berbagi ke Unmark.it shaarli_share_origin_url: Aktifkan berbagi URL asal ke Shaarli, jika layanan diaktifkan share_public: Izinkan URL publik untuk entri -share_scuttle: Aktifkan berbagi ke Scuttle restricted_access: Aktifkan otentikasi untuk situs web berbayar share_twitter: Aktifkan berbagi ke Twitter demo_mode_enabled: Aktifkan mode demo? (Hanya digunakan untuk demo wallabag publik) @@ -18,7 +16,6 @@ download_images_enabled: Unduh gambar secara lokal store_article_headers: Aktifkan jika wallabag menyimpan header HTTP untuk setiap artikel api_user_registration: Aktifkan pendaftaran pengguna melalui API demo_mode_username: Pengguna demo -scuttle_url: Scuttle URL, jika layanan diaktifkan download_pictures: Unduh gambar ke server Anda export_xml: Aktifkan ekspor XML import_with_rabbitmq: Aktifkan RabbitMQ untuk mengimpor data secara asinkron diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml index 8629f3d31..d70344b94 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml @@ -1,5 +1,4 @@ download_pictures: Scarica le immagini sul tuo server -carrot: Abilita condivisione con Carrot diaspora_url: URL di diaspora*, se il servizio è abilitato export_epub: Abilita esportazione ePub export_mobi: Abilita esportazione .mobi (deprecato, verrà rimosso presto) @@ -9,12 +8,10 @@ export_json: Abilita esportazione JSON export_txt: Abilita esportazione TXT export_xml: Abilita esportazione XML shaarli_url: URL Shaarli, se il servizio è abilitato -scuttle_url: URL Scuttle, se il servizio è abilitato unmark_url: URL Unmark, se il servizio è abilitato share_diaspora: Abilita la condivisione con diaspora* share_mail: Abilita la condivisione via e-mail share_shaarli: Abilita la condivisione con Shaarli -share_scuttle: Abilita la condivisione con Scuttle share_twitter: Abilita la condivisione con Twitter share_unmark: Abilita la condivisione con Unmark.it show_printlink: Mostra un collegamento per stampare il contenuto diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ja.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ja.yml index 22bf1f0cb..74dd9737c 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ja.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ja.yml @@ -1,6 +1,5 @@ settings_changed: 設定を更新しました download_pictures: サーバー上の画像をダウンロード -carrot: Carrot への共有を有効にする diaspora_url: diaspora* URL、サービスが有効になっている場合 export_epub: ePub のエクスポートを有効にする export_mobi: .mobi のエクスポートを有効にする(非推奨、近日中に削除されます) @@ -12,12 +11,10 @@ export_xml: XML のエクスポートを有効にする import_with_rabbitmq: RabbitMQ を有効にして、データを非同期的にインポートする import_with_redis: Redis を有効にして、データを非同期的にインポートする shaarli_url: サービスが有効になっている場合、Shaarli URL -scuttle_url: Scuttle URL、サービスが有効になっている場合 unmark_url: Unmark URL、サービスが有効な場合 share_diaspora: diaspora* に共有を有効にする share_mail: メールで共有を有効にする share_shaarli: Shaarli に共有を有効にする -share_scuttle: Scuttle に共有を有効にする share_twitter: Twitter に共有を有効にする share_unmark: Unmark.it に共有を有効にする show_printlink: 印刷するコンテンツへのリンクを表示 diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ko.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ko.yml index 2f8ffb172..2af7174aa 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ko.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ko.yml @@ -19,13 +19,11 @@ wallabag_support_url: Wallabag 지원 URL show_printlink: 콘텐츠 인쇄 링크 표시 share_unmark: Unmark.it 공유 활성화 diaspora_url: Diaspora* URL (서비스가 활성화 된 경우) -share_scuttle: Scuttle 공유 활성화 share_shaarli: Shaarli 공유 활성화 share_mail: 이메일 공유 활성화 share_diaspora: Diaspora* 공유 활성화 share_twitter: Twitter 공유 활성화 unmark_url: Unmark URL (서비스가 활성화 된 경우) -scuttle_url: Scuttle URL (서비스가 활성화 된 경우) shaarli_url: Shaarli URL (서비스가 활성화 된 경우) import_with_redis: Redis가 데이터를 비동기적으로 가져오도록 설정 import_with_rabbitmq: RabbitMQ가 데이터를 비동기적으로 가져오도록 설정 @@ -36,5 +34,4 @@ export_csv: CSV 내보내기 활성화 export_pdf: PDF 내보내기 활성화 export_mobi: .mobi 내보내기 활성화 export_epub: ePub 내보내기 활성화 -carrot: Carrot에 공유 활성화 settings_changed: 설정을 업데이트했습니다 diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.nb.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.nb.yml index a8b26ed59..9c6a644d3 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.nb.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.nb.yml @@ -1,6 +1,5 @@ settings_changed: Oppsett oppdatert download_pictures: Last ned bilder til tjeneren din -carrot: Skru på deling til Carrot diaspora_url: diaspora*-nettadresse, hvis tjenesten er avskrudd export_epub: Skru på ePub-eksport export_mobi: Skru på .mobi-eksport @@ -32,9 +31,7 @@ demo_mode_username: Demo-bruker share_public: Tillat offentlige nettadresser for oppføringer download_images_enabled: Last ned bilder lokalt restricted_access: Skru på identitetsbekreftelse for nettsider med betalingsmur -scuttle_url: Scuttle-nettadresse, hvis tjenesten er påskrudd unmark_url: Unmark-nettadresse, hvis tjenesten er påskrudd -share_scuttle: Skru på deling til Scuttle api_user_registration: Skru på brukerregistrering via API-et store_article_headers: Skru på hvis wallabag lagrer HTTP-hoder for hver artikkel shaarli_share_origin_url: Skru på deling av opprinnelsesnettadresse til Shaarli, hvis tjenesten er påskrudd diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.nl.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.nl.yml index 4b3e5054c..ada10e7df 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.nl.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.nl.yml @@ -17,7 +17,6 @@ wallabag_support_url: Hulp URL voor wallabag show_printlink: Toon een link naar de print inhoud share_unmark: Schakel delen met Unmark.it in share_twitter: Schakel delen met Twitter in -share_scuttle: Schakel delen met Scuttle in share_shaarli: Schakel delen met Shaarli in share_mail: Schakel delen naar e-mail in share_diaspora: Schakel deel naar diaspora* in @@ -33,7 +32,6 @@ export_csv: Schakel CSV-export in export_pdf: Schakel PDF-export in export_mobi: Schakel .mobi-export in export_epub: Schakel ePub-export in -carrot: Schakel delen naar Carrot in download_pictures: Download foto's naar jouw server settings_changed: Instellingen bijgewerkt diaspora_url: diaspora* URL, als de dienst is aangezet diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml index 9f039ecfb..e8208f539 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml @@ -1,6 +1,5 @@ settings_changed: Configuracion mesa a jorn download_pictures: Telecargar los imatges sul servidor -carrot: Activar lo partatge cap a Carrot diaspora_url: URL de diaspora*, se lo servici diaspora* es activat export_epub: Activar l'expòrt ePub export_mobi: Activar l'expòrt .mobi @@ -12,7 +11,6 @@ export_xml: Activar l'expòrt XML import_with_rabbitmq: Activar RabbitMQ per importar de donadas de manièra asincròna import_with_redis: Activar Redis per importar de donadas de manièra asincròna shaarli_url: URL de Shaarli, se lo servici Shaarli es activat -scuttle_url: URL de Scuttle, se lo servici Scuttle es activat unmark_url: URL de Unmark, se lo servici Scuttle es activat share_diaspora: Activar lo partatge cap a Diaspora* share_mail: Activar lo partatge per corrièl diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml index 83dde93ad..7b649e2ec 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml @@ -1,6 +1,5 @@ settings_changed: Konfiguracja zaktualizowana download_pictures: Pobierz obrazy na swój serwer -carrot: Włącz udostępnianie dla Carrot diaspora_url: Adres URL Diaspora, jeżeli usługa jest włączona export_epub: Włącz eksport do ePub export_mobi: Włącz eksport do plików .mobi (przestarzałe, zostanie wkrótce usunięte) @@ -12,11 +11,9 @@ export_xml: Włącz eksport do XML import_with_rabbitmq: Włącz RabbitMQ dla asynchronicznego importu danych import_with_redis: Włącz Redis dla asynchronicznego importu danych shaarli_url: Adress URL Shaarli, jeżeli usługa jest włączona -scuttle_url: Adress URL Scuttle, jeżeli usługa jest włączona share_diaspora: Włącz udostępnianie dla Diaspora share_mail: Włącz udostępnianie przez e-mail share_shaarli: Włącz udostępnianie dla Shaarli -share_scuttle: Włącz udostępnianie dla Scuttle share_twitter: Włącz udostępnianie dla Twitter share_unmark: Włącz udostępnianie dla Unmark.it show_printlink: Pokaż link do wydrukowania zawartości diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml index f942b105c..a7d834ccb 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml @@ -1,5 +1,4 @@ download_pictures: Descarregar imagens ao seu servidor -carrot: Habilitar compartilhamento para o Carrot diaspora_url: URL de diaspora* caso o serviço esteja ativado export_epub: Habilita exportação para ePub export_mobi: Habilita exportação para .mobi @@ -9,13 +8,11 @@ export_json: Habilita exportação para JSON export_txt: Habilita exportação para TXT export_xml: Habilita exportação para XML shaarli_url: URL de Shaarli caso o serviço esteja ativado -scuttle_url: URL de Scuttle caso o serviço esteja ativado unmark_url: URL de Unmark caso o serviço esteja ativado pocket_consumer_key: Chave de consumidor do Pocket para importar conteúdo (https://getpocket.com/developer/docs/authentication) share_diaspora: Habilitar compartilhamento para o diaspora* share_mail: Habilitar compartilhamento por e-mail share_shaarli: Habilitar compartilhamento para o Shaarli -share_scuttle: Habilitar compartilhamento para o Scuttle share_twitter: Habilitar compartilhamento para o Twitter share_unmark: Habilitar compartilhamento para o Unmark.it show_printlink: Mostrar um link para imprimir o conteúdo diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml index 777adc79a..28f68da3f 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml @@ -1,5 +1,4 @@ download_pictures: Descarcă poze pe server -carrot: Permite share către Carrot diaspora_url: diaspora* URL, dacă serviciul este permis export_epub: Permite exportare ePub export_mobi: Permite exportare .mobi @@ -9,12 +8,10 @@ export_json: Permite exportare JSON export_txt: Permite exportare TXT export_xml: Permite exportare XML shaarli_url: Shaarli URL, dacă serviciul este permis -scuttle_url: Scuttle URL, dacă serviciul este permis unmark_url: Unmark URL, dacă serviciul este permis share_diaspora: Permite share către diaspora* share_mail: Permite share prin email share_shaarli: Permite share către Shaarli -share_scuttle: Permite share către Scuttle share_twitter: Permite share către Twitter share_unmark: Permite share către Unmark.it show_printlink: Afișează un link pentru a printa content-ul diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ru.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ru.yml index d66de1b7b..294a36f5b 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ru.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ru.yml @@ -1,6 +1,5 @@ settings_changed: "Настройки обновлены" download_pictures: "Скачивать картинки на Ваш сервер" -carrot: "Включить возможность отслеживания событий через Carrot" diaspora_url: "Diaspora URL, если сервис включен" export_epub: "Включить ePub экспорт" export_mobi: "Включить .mobi экспорт" @@ -12,7 +11,6 @@ export_xml: "Включить XML экспорт" import_with_rabbitmq: "Включить RabbitMQ для импорта данных(асинхронно)" import_with_redis: "Включить Redis для импорта данных(асинхронно)" shaarli_url: "Shaarli URL, если сервис включен" -scuttle_url: "Scuttle URL, если сервис включен" unmark_url: "Unmark URL, если сервис включен" share_diaspora: "Включить возможность поделиться в соц.сети Diaspora" share_mail: "Включить возможность поделиться по email" @@ -38,4 +36,3 @@ restricted_access: "Включить авторизацию на сайте с shaarli_share_origin_url: Включите отправку URL-адреса источника для Shaarli, если услуга включена store_article_headers: Включите, если wallabag хранит заголовки HTTP для каждой статьи api_user_registration: Разрешить пользователю регистрироваться с помощью API -share_scuttle: Включить возможность поделиться в Shaarli diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.th.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.th.yml index 6a4cddb45..c957f3f41 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.th.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.th.yml @@ -1,6 +1,5 @@ settings_changed: ปรับปรุงองค์ประกอบ download_pictures: ดาวน์โหลดรูปภาพผ่านเซิฟเวอร์ของคุณ -carrot: เปิดการแชร์ Carrot diaspora_url: Diaspora-URL, ถ้าเซิฟเวอร์ถูกเปิดใช้งาน export_epub: เปิดใช้งานการนำเข้าข้อมูลแบบ ePub export_mobi: เปิดใช้งานการนำเข้าข้อมูลแบบ .mobi @@ -15,7 +14,6 @@ shaarli_url: Shaarli-URL, ถ้าเซิฟเวอร์ถูกเปิ share_diaspora: เปิดการแชร์ Diaspora share_mail: เปิดการแชร์ผ่าน email share_shaarli: เปิดการแชร์ Shaarli -share_scuttle: เปิดการแชร์ Scuttle share_twitter: เปิดการแชร์ Twitter share_unmark: เปิดการแชร์ Unmark.it show_printlink: แสดงลิงค์เพื่อปรินท์เนื้อหา diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml index bfc1459e3..c4093a1ec 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml @@ -1,6 +1,5 @@ settings_changed: Ayarlar güncellendi download_pictures: Resimleri sunucuya indir -carrot: Carrot'a paylaşımı etkinleştir diaspora_url: hizmet etkinse diaspora* URL'si export_epub: ePub dışa aktarımını etkinleştir export_mobi: .mobi dışa aktarımını etkinleştir (kullanım dışı, yakında kaldırılacak) @@ -12,12 +11,10 @@ export_xml: XML dışa aktarımını etkinleştir import_with_rabbitmq: Verileri eşzamansız olarak içe aktarmak için RabbitMQ'yu etkinleştir import_with_redis: Verileri eşzamansız olarak içe aktarmak için Redis'i etkinleştir shaarli_url: Hizmet etkinse Shaarli URL'si -scuttle_url: Hizmet etkinse Scuttle URL'si unmark_url: Hizmet etkinse Unmark URL'si share_diaspora: diaspora*'ya paylaşımı etkinleştir share_mail: E-posta ile paylaşımı etkinleştir share_shaarli: Shaarli'ye paylaşımı etkinleştir -share_scuttle: Scuttle'a paylaşımı etkinleştir share_twitter: Twitter'a paylaşımı etkinleştir share_unmark: Unmark.it'e paylaşımı etkinleştir show_printlink: İçeriği yazdırabilmek için bir bağlantı görüntüle diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.uk.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.uk.yml index 8f606cdc9..68d8bcd19 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.uk.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.uk.yml @@ -1,6 +1,5 @@ settings_changed: Конфігурацію оновлено download_pictures: Завантажити картинки на ваш сервер -carrot: Дозволити ділитися в Carrot diaspora_url: diaspora* адреса, якщо сервіс увімкнено export_epub: Увімкнути експорт в ePub export_mobi: Увімкнути експорт в .mobi @@ -12,12 +11,10 @@ export_xml: Увімкнути експорт в XML import_with_rabbitmq: Увімкнути можливість асинхронного імпорту через RabbitMQ import_with_redis: Увімкнути можливість асинхронного імпорту через Redis shaarli_url: Shaarli URL, якщо сервіс увімкнено -scuttle_url: Scuttle URL, якщо сервіс увімкнено unmark_url: Unmark URL, якщо сервіс увімкнено share_diaspora: Дозволити ділитися в diaspora* share_mail: Дозволити ділитись електронною поштою share_shaarli: Дозволити ділитися в Shaarli -share_scuttle: Дозволити ділитися в Scuttle share_twitter: Дозволити ділитися в Twitter share_unmark: Дозволити ділитися в Unmark.it show_printlink: Показувати лінк для друку diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.zh.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.zh.yml index 8dd8509f0..b5e16519b 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.zh.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.zh.yml @@ -1,6 +1,5 @@ settings_changed: 配置已更新 download_pictures: 在你的服务器上缓存图片 -carrot: 启用分享到 Carrot diaspora_url: diaspora* 链接,如果该服务已被启用 export_epub: 启用 ePub 导出 export_mobi: 启用 .mobi 导出(已废弃,不久后将移除) @@ -12,12 +11,10 @@ export_xml: 启用 XML 导出 import_with_rabbitmq: 启用 RabbitMQ 来异步导入数据 import_with_redis: 启用 Redis 来异步导入数据 shaarli_url: Shaarli 链接,如果该服务已被启用 -scuttle_url: Scuttle 链接,如果该服务已被启用 unmark_url: Unmark 链接,如果该服务已被启用 share_diaspora: 启用分享到 diaspora* share_mail: 启用邮件分享 share_shaarli: 启用分享到 Shaarli -share_scuttle: 启用分享到 Scuttle share_twitter: 启用分享到 Twitter share_unmark: 启用分享到 Unmark.it show_printlink: 展示一个用于打印内容的链接 diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.zh_Hant.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.zh_Hant.yml index a3f6f83d3..f9cb434e2 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.zh_Hant.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.zh_Hant.yml @@ -2,4 +2,3 @@ download_pictures: 下載圖片至你的服務器上 diaspora_url: diaspora* URL(如果該服務已啟用) settings_changed: 已更新設定 export_epub: 啟用 ePub 輸出 -carrot: 啟用分享至 Carrot diff --git a/app/Resources/CraueConfigBundle/views/Settings/modify.html.twig b/app/Resources/CraueConfigBundle/views/Settings/modify.html.twig index db153270b..4e61ec4cd 100644 --- a/app/Resources/CraueConfigBundle/views/Settings/modify.html.twig +++ b/app/Resources/CraueConfigBundle/views/Settings/modify.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'menu.left.internal_settings'|trans }}{% endblock %} @@ -12,17 +12,17 @@
- {% for section in sections | craue_sortSections %} + {% for section in sections|craue_sortSections %}
{% for setting in form.settings if setting.vars.value.section == section %} {{ form_row(setting.value, { - 'label': setting.vars.value.name | trans({}, 'CraueConfigBundle'), + 'label': setting.vars.value.name|trans({}, 'CraueConfigBundle'), }) }} {% endfor %}
@@ -30,7 +30,7 @@
{{ form_widget(form._token) }} diff --git a/app/Resources/FOSUserBundle/views/ChangePassword/changePassword_content.html.twig b/app/Resources/FOSUserBundle/views/ChangePassword/changePassword_content.html.twig index abb684213..f8527b382 100644 --- a/app/Resources/FOSUserBundle/views/ChangePassword/changePassword_content.html.twig +++ b/app/Resources/FOSUserBundle/views/ChangePassword/changePassword_content.html.twig @@ -1,6 +1,6 @@ {% trans_default_domain 'FOSUserBundle' %} -{{ form_start(form, { 'action': path('fos_user_change_password'), 'attr': { 'class': 'fos_user_change_password' } }) }} +{{ form_start(form, {'action': path('fos_user_change_password'), 'attr': {'class': 'fos_user_change_password'}}) }}
{{ form_widget(form) }} diff --git a/app/Resources/FOSUserBundle/views/Registration/check_email.html.twig b/app/Resources/FOSUserBundle/views/Registration/check_email.html.twig index 509372766..df81509cf 100644 --- a/app/Resources/FOSUserBundle/views/Registration/check_email.html.twig +++ b/app/Resources/FOSUserBundle/views/Registration/check_email.html.twig @@ -1,4 +1,4 @@ -{% extends "FOSUserBundle::layout.html.twig" %} +{% extends "@FOSUser/layout.html.twig" %} {% trans_default_domain 'FOSUserBundle' %} diff --git a/app/Resources/FOSUserBundle/views/Registration/confirmed.html.twig b/app/Resources/FOSUserBundle/views/Registration/confirmed.html.twig index cb8d40a44..f89294733 100644 --- a/app/Resources/FOSUserBundle/views/Registration/confirmed.html.twig +++ b/app/Resources/FOSUserBundle/views/Registration/confirmed.html.twig @@ -1,4 +1,4 @@ -{% extends "FOSUserBundle::layout.html.twig" %} +{% extends "@FOSUser/layout.html.twig" %} {% trans_default_domain 'FOSUserBundle' %} @@ -11,7 +11,7 @@ {% endif %}
- {{ 'security.register.go_to_account'|trans({},'messages') }} + {{ 'security.register.go_to_account'|trans({}, 'messages') }}
{% endblock fos_user_content %} diff --git a/app/Resources/FOSUserBundle/views/Registration/register_content.html.twig b/app/Resources/FOSUserBundle/views/Registration/register_content.html.twig index 85cd4f0d3..5637511d4 100644 --- a/app/Resources/FOSUserBundle/views/Registration/register_content.html.twig +++ b/app/Resources/FOSUserBundle/views/Registration/register_content.html.twig @@ -5,8 +5,8 @@
{{ form_widget(form._token) }} - {% for flashMessage in app.session.flashbag.get('notice') %} -

{{ flashMessage }}

+ {% for flash_message in app.session.flashbag.get('notice') %} +

{{ flash_message }}

{% endfor %}
diff --git a/app/Resources/FOSUserBundle/views/Resetting/check_email.html.twig b/app/Resources/FOSUserBundle/views/Resetting/check_email.html.twig index e9d46dcc8..c4d9c91bb 100644 --- a/app/Resources/FOSUserBundle/views/Resetting/check_email.html.twig +++ b/app/Resources/FOSUserBundle/views/Resetting/check_email.html.twig @@ -1,4 +1,4 @@ -{% extends "FOSUserBundle::layout.html.twig" %} +{% extends "@FOSUser/layout.html.twig" %} {% trans_default_domain 'FOSUserBundle' %} diff --git a/app/Resources/FOSUserBundle/views/Resetting/request_content.html.twig b/app/Resources/FOSUserBundle/views/Resetting/request_content.html.twig index 010ee0d03..f33c25cdc 100644 --- a/app/Resources/FOSUserBundle/views/Resetting/request_content.html.twig +++ b/app/Resources/FOSUserBundle/views/Resetting/request_content.html.twig @@ -5,8 +5,8 @@

{{ 'security.resetting.description'|trans({}, "messages") }}

- {% for flashMessage in app.session.flashbag.get('notice') %} -

{{ flashMessage }}

+ {% for flash_message in app.session.flashbag.get('notice') %} +

{{ flash_message }}

{% endfor %} {% if invalid_username is defined %} diff --git a/app/Resources/FOSUserBundle/views/Resetting/reset_content.html.twig b/app/Resources/FOSUserBundle/views/Resetting/reset_content.html.twig index a19dc7d20..7926110f1 100644 --- a/app/Resources/FOSUserBundle/views/Resetting/reset_content.html.twig +++ b/app/Resources/FOSUserBundle/views/Resetting/reset_content.html.twig @@ -1,6 +1,6 @@ {% trans_default_domain 'FOSUserBundle' %} -{{ form_start(form, { 'action': path('fos_user_resetting_reset', {'token': token}), 'attr': { 'class': 'fos_user_resetting_reset' } }) }} +{{ form_start(form, {'action': path('fos_user_resetting_reset', {'token': token}), 'attr': {'class': 'fos_user_resetting_reset'}}) }}
{{ form_widget(form) }} diff --git a/app/Resources/FOSUserBundle/views/Security/login.html.twig b/app/Resources/FOSUserBundle/views/Security/login.html.twig index 3dd98fb64..291a0a428 100644 --- a/app/Resources/FOSUserBundle/views/Security/login.html.twig +++ b/app/Resources/FOSUserBundle/views/Security/login.html.twig @@ -1,4 +1,4 @@ -{% extends "FOSUserBundle::layout.html.twig" %} +{% extends "@FOSUser/layout.html.twig" %} {% block fos_user_content %}
@@ -8,8 +8,8 @@ {% endif %} - {% for flashMessage in app.session.flashbag.get('notice') %} - + {% for flash_message in app.session.flashbag.get('notice') %} + {% endfor %}
diff --git a/app/Resources/FOSUserBundle/views/layout.html.twig b/app/Resources/FOSUserBundle/views/layout.html.twig index 71df1efec..937fd5cb0 100644 --- a/app/Resources/FOSUserBundle/views/layout.html.twig +++ b/app/Resources/FOSUserBundle/views/layout.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'security.login.page_title'|trans }}{% endblock %} diff --git a/app/Resources/static/themes/_global/img/icons/carrot-icon--black.png b/app/Resources/static/themes/_global/img/icons/carrot-icon--black.png deleted file mode 100644 index 3a5ef1d3a..000000000 Binary files a/app/Resources/static/themes/_global/img/icons/carrot-icon--black.png and /dev/null differ diff --git a/app/Resources/static/themes/_global/img/icons/carrot-icon--white.png b/app/Resources/static/themes/_global/img/icons/carrot-icon--white.png deleted file mode 100644 index 48bcd68a9..000000000 Binary files a/app/Resources/static/themes/_global/img/icons/carrot-icon--white.png and /dev/null differ diff --git a/app/Resources/static/themes/baggy/css/article.scss b/app/Resources/static/themes/baggy/css/article.scss deleted file mode 100644 index 9d0a0568b..000000000 --- a/app/Resources/static/themes/baggy/css/article.scss +++ /dev/null @@ -1,164 +0,0 @@ -#article { - width: 70%; - margin-bottom: 3em; - text-align: justify; - - .tags { - margin-bottom: 1em; - } - - i { - font-style: normal; - } - - h1 { - text-align: left; - } - - h2::after { - content: none; - } - - h2, - h3, - h4 { - text-transform: none; - } -} - -blockquote { - border: 1px solid #999; - background-color: #fff; - padding: 1em; - margin: 0; -} - -.topPosF { - position: fixed; - right: 20%; - bottom: 2em; - font-size: 1.5em; -} - -#article_toolbar { - margin-bottom: 1em; - - li { - display: inline-block; - margin: 3px auto; - } - - a { - background-color: #000; - padding: 0.3em 0.5em 0.2em; - color: #fff; - text-decoration: none; - - &:hover, - &:focus { - background-color: #999; - } - } -} - -#nav-btn-add-tag { - cursor: pointer; -} - -.shaarli::before { - content: "*"; -} - -.return { - text-decoration: none; - margin-top: 1em; - display: block; -} - -.return::before { - margin-right: 0.5em; -} - -.notags { - font-style: italic; - color: #999; -} - -.icon-feed { - background-color: #000; - color: #fff; - padding: 0.2em 0.5em; - - &::before { - position: relative; - top: 2px; - } -} - -.list-tags { - li { - margin-bottom: 0.5em; - } - - .icon-feed:hover, - .icon-feed:focus { - background-color: #fff; - color: #000; - text-decoration: none; - } - - a { - text-decoration: none; - - &:hover, - &:focus { - text-decoration: underline; - } - } -} - -pre code { - font-family: "Courier New", Courier, monospace; -} - -#filters { - position: fixed; - width: 20%; - height: 100%; - top: 0; - right: 0; - background-color: #fff; - padding: 30px 30px 15px 15px; - border-left: 1px #333 solid; - z-index: 12; - min-width: 300px; - - form .filter-group { - margin: 5px; - } -} - -#download-form { - position: fixed; - width: 10%; - height: 100%; - top: 0; - right: 0; - background-color: #fff; - padding: 30px 30px 15px 15px; - border-left: 1px #333 solid; - z-index: 12; - min-width: 200px; - - li { - display: block; - padding: 0.5em 2em 0.5em 1em; - color: #fff; - position: relative; - text-transform: uppercase; - text-decoration: none; - font-weight: 400; - font-family: "PT Sans", sans-serif; - transition: all 0.5s ease; - } -} diff --git a/app/Resources/static/themes/baggy/css/guide.scss b/app/Resources/static/themes/baggy/css/guide.scss deleted file mode 100644 index 6f050e231..000000000 --- a/app/Resources/static/themes/baggy/css/guide.scss +++ /dev/null @@ -1,258 +0,0 @@ -::selection { - color: #fff; - background-color: #000; -} - -.desktopHide { - display: none; -} - -.logo { - position: fixed; - z-index: 20; - top: 0.4em; - left: 0.6em; -} - -h2, -h3, -h4 { - font-family: "PT Sans", sans-serif; - text-transform: uppercase; -} - -p, -li, -label { - color: #666; -} - -a { - color: #000; - font-weight: bold; - - &.nostyle { - text-decoration: none; - } - - &:hover, - &:focus { - text-decoration: none; - } -} - -form fieldset { - border: 0; - padding: 0; - margin: 0; -} - -form input[type="text"], -form input[type="number"], -select, -form input[type="password"], -form input[type="url"], -form input[type="email"] { - border: 1px solid #999; - padding: 0.5em 1em; - min-width: 12em; - color: #666; -} - -@media screen { - select { - appearance: none; - border-radius: 0; - background: #fff url("../../_global/img/bg-select.png") no-repeat right center; - } -} - -.inline { - .row { - display: inline-block; - margin-right: 0.5em; - } - - label { - min-width: 6em; - } -} - -fieldset label { - display: inline-block; - min-width: 12.5em; - color: #666; -} - -label { - margin-right: 0.5em; -} - -form .row { - margin-bottom: 0.5em; -} - -form button, -input[type="submit"] { - cursor: pointer; - background-color: #000; - color: #fff; - padding: 0.5em 1em; - display: inline-block; - border: 1px solid #000; -} - -form button:hover, -form button:focus, -input[type="submit"]:hover, -input[type="submit"]:focus { - background-color: #fff; - color: #000; - transition: all 0.5s ease; -} - -#bookmarklet { - cursor: move; -} - -h2::after { - content: ""; - height: 4px; - width: 20%; - background-color: #000; - display: block; -} - -.links { - padding: 0; - margin: 0; - - li { - list-style: none; - margin: 0; - padding: 0; - } -} - -#links { - position: fixed; - top: 0; - width: 10em; - left: 0; - text-align: right; - background-color: #333; - padding-top: 9.5em; - height: 100%; - box-shadow: inset -4px 0 20px rgb(0 0 0 / 60%); - z-index: 15; - - > li > a { - display: block; - padding: 0.5em 2em 0.5em 1em; - color: #fff; - position: relative; - text-transform: uppercase; - text-decoration: none; - font-weight: normal; - font-family: "PT Sans", sans-serif; - transition: all 0.5s ease; - - &:hover, - &:focus { - background-color: #999; - color: #000; - } - } - - .current::after { - content: ""; - width: 0; - height: 0; - position: absolute; - border: 10px solid transparent; - border-right-color: #eee; - right: 0; - top: 50%; - margin-top: -10px; - } - - li:last-child { - position: fixed; - bottom: 1em; - width: 10em; - - a::before { - font-size: 1.2em; - position: relative; - top: 2px; - } - } -} - -#main { - margin-left: 12em; - position: relative; - z-index: 10; - padding-right: 5%; - padding-bottom: 1em; -} - -#sort { - padding: 0; - list-style-type: none; - opacity: 0.5; - display: inline-block; - - li { - display: inline; - font-size: 0.9em; - - & + li { - margin-left: 10px; - } - } - - a { - padding: 2px 2px 0; - vertical-align: middle; - } - - img { - vertical-align: baseline; - - :hover { - cursor: pointer; - } - } -} - -#display-mode { - float: right; - margin-top: 10px; - margin-bottom: 10px; - opacity: 0.5; -} - -#listmode { - width: 16px; - display: inline-block; - text-decoration: none; - - &.tablemode { - background: url("../../_global/img/table.png") no-repeat bottom; - } - - .listmode { - background: url("../../_global/img/list.png") no-repeat bottom; - } -} - -#warning_message { - position: fixed; - background-color: #ff6347; - z-index: 1000; - bottom: 0; - left: 0; - width: 100%; - color: #000; -} diff --git a/app/Resources/static/themes/baggy/css/index.scss b/app/Resources/static/themes/baggy/css/index.scss deleted file mode 100644 index 2dc6638e6..000000000 --- a/app/Resources/static/themes/baggy/css/index.scss +++ /dev/null @@ -1,13 +0,0 @@ -/* Style */ -@import "guide"; -@import "layout"; -@import "article"; -@import "pictos"; -@import "login"; -@import "save"; -@import "messages"; - -/* Tools */ -@import "media_queries"; -@import "print"; -@import "ratatouille"; diff --git a/app/Resources/static/themes/baggy/css/layout.scss b/app/Resources/static/themes/baggy/css/layout.scss deleted file mode 100644 index 493924ca8..000000000 --- a/app/Resources/static/themes/baggy/css/layout.scss +++ /dev/null @@ -1,309 +0,0 @@ -#content { - margin-top: 2em; - min-height: 30em; -} - -footer { - text-align: right; - position: relative; - bottom: 0; - right: 5em; - color: #999; - font-size: 0.8em; - font-style: italic; - z-index: 20; - - a { - color: #999; - font-weight: normal; - } -} - -.list-entries { - letter-spacing: -5px; -} - -.listmode.entry { - width: 100%; - height: inherit; -} - -.card-entry-tags { - max-height: 2em; - overflow-y: hidden; - padding: 0; - margin: 0; -} - -.card-entry-tags li, -.card-entry-tags span { - display: inline-block; - margin: 0 5px; - padding: 5px 12px; - background-color: rgb(0 0 0 / 60%); - border-radius: 3px; - max-height: 2em; - overflow: hidden; - text-overflow: ellipsis; -} - -.card-entry-tags a, -.card-entry-labels a { - text-decoration: none; - font-weight: normal; - color: #fff; -} - -.nav-panel-add-tag { - margin-top: 10px; -} - -.list-entries + .results { - margin-bottom: 2em; -} - -.reading-time, -.created-at { - color: #999; - font-style: italic; - font-weight: normal; - font-size: 0.9em; -} - -.estimatedTime small { - position: relative; - top: -1px; -} - -.entry { - background-color: #fff; - letter-spacing: normal; - box-shadow: 0 3px 7px rgb(0 0 0 / 30%); - display: inline-block; - width: 32%; - margin-bottom: 1.5em; - vertical-align: top; - margin-right: 1%; - position: relative; - overflow: hidden; - padding: 1.5em 0 3em; - height: 440px; - - img.preview { - width: 100%; - object-fit: cover; - height: 100%; - } - - &::before { - content: ""; - width: 0; - height: 0; - border: 10px solid transparent; - border-bottom-color: #000; - position: absolute; - bottom: 0.7em; - z-index: 10; - right: 1.5em; - transition: all 0.5s ease; - } - - &::after { - content: ""; - position: absolute; - height: 7px; - width: 100%; - bottom: 0; - left: 0; - background-color: #000; - transition: all 0.5s ease; - } - - &:hover { - box-shadow: 0 3px 10px rgb(0 0 0 / 100%); - - &::after { - height: 40px; - } - - &::before { - bottom: 2.3em; - } - - h2 a { - color: #666; - } - - .tools { - bottom: 0; - } - } - - h2 { - text-transform: none; - margin-bottom: 0; - line-height: 1.2; - margin-left: 5px; - } - - &::after { - content: none; - } - - a { - display: block; - text-decoration: none; - color: #000; - word-wrap: break-word; - transition: all 0.5s ease; - } - - p { - color: #666; - font-size: 0.9em; - line-height: 1.7; - margin: 5px 5px auto; - } - - h2 a::first-letter { - text-transform: uppercase; - } - - .tools { - position: absolute; - bottom: -40px; - left: 0; - background: #000; - width: 100%; - z-index: 10; - padding-right: 0.5em; - text-align: right; - transition: all 0.5s ease; - - a { - color: #666; - text-decoration: none; - display: block; - padding: 0.4em; - - &:hover { - color: #fff; - } - } - - li { - display: inline-block; - margin-top: 10px; - } - - li:first-child { - float: left; - font-size: 0.9em; - max-width: calc(100% - 40px * 4); - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - max-height: 2em; - margin-left: 10px; - } - } - - .card-entry-labels { - position: absolute; - top: 100px; - left: -1em; - z-index: 90; - max-width: 50%; - padding-left: 0; - - li { - margin: 10px 10px 10px auto; - padding: 5px 12px 5px 25px; - background-color: rgb(0 0 0 / 60%); - border-radius: 0 3px 3px 0; - color: #fff; - cursor: default; - max-height: 2em; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - - a { - color: #fff; - } - } - } -} - -.entry:nth-child(3n+1) { - margin-left: 0; -} - -.results { - letter-spacing: -5px; - padding: 0 0 0.5em; - - > * { - display: inline-block; - vertical-align: top; - letter-spacing: normal; - width: 50%; - text-align: right; - } -} - -div.pagination ul { - text-align: right; -} - -.nb-results { - text-align: left; - font-style: italic; - color: #999; - display: inline-flex; -} - -div.pagination ul { - a { - color: #999; - text-decoration: none; - - &:hover, - &:focus { - text-decoration: underline; - } - } - - > * { - display: inline-block; - margin-left: 0.5em; - } - - .prev.disabled, - .next.disabled { - display: none; - } - - .current { - height: 25px; - padding: 4px 8px; - border: 1px solid #d5d5d5; - text-decoration: none; - font-weight: bold; - color: #000; - background-color: #ccc; - } -} - -.card-tag-form { - display: inline-block; -} - -.card-tag-form input[type="text"] { - min-width: 20em; -} - -.hide, -.hidden { - display: none; -} diff --git a/app/Resources/static/themes/baggy/css/login.scss b/app/Resources/static/themes/baggy/css/login.scss deleted file mode 100644 index 3e0ea73dc..000000000 --- a/app/Resources/static/themes/baggy/css/login.scss +++ /dev/null @@ -1,26 +0,0 @@ -.login { - background-color: #333; - - #main { - padding: 0; - margin: 0; - } - - form { - background-color: #fff; - padding: 1.5em; - box-shadow: 0 1px 8px rgb(0 0 0 / 90%); - width: 20em; - position: absolute; - top: 8em; - left: 50%; - margin-left: -10em; - } - - .logo { - position: absolute; - top: 2em; - left: 50%; - margin-left: -55px; - } -} diff --git a/app/Resources/static/themes/baggy/css/main.css b/app/Resources/static/themes/baggy/css/main.css deleted file mode 100755 index 0d69e45cf..000000000 --- a/app/Resources/static/themes/baggy/css/main.css +++ /dev/null @@ -1,1320 +0,0 @@ -/* ========================================================================== - Sommaire - - 1 = Style Guide - 2 = Layout - 3 = Pictos - 4 = Messages - 5 = Article - 6 = Media queries - - ========================================================================== */ - -html { - min-height: 100%; -} - -body { - background-color: #eee; -} - -.login { - background-color: #333; -} - -.login #main { - padding: 0; - margin: 0; -} - -.login form { - background-color: #fff; - padding: 1.5em; - box-shadow: 0 1px 8px rgb(0 0 0 / 90%); - width: 20em; - position: absolute; - top: 8em; - left: 50%; - margin-left: -10em; -} - -.login .logo { - position: absolute; - top: 2em; - left: 50%; - margin-left: -55px; -} - -/* ========================================================================== - 1 = Style Guide - ========================================================================== */ - -::selection { - color: #fff; - background-color: #000; -} - -.desktopHide { - display: none; -} - -.logo { - position: fixed; - z-index: 20; - top: 0.4em; - left: 0.6em; -} - -h2, -h3, -h4 { - font-family: "PT Sans", sans-serif; - text-transform: uppercase; -} - -p, -li, -label { - color: #666; -} - -a { - color: #000; - font-weight: bold; -} - -a.nostyle { - text-decoration: none; -} - -a:hover, -a:focus { - text-decoration: none; -} - -form fieldset { - border: 0; - padding: 0; - margin: 0; -} - -form input[type="text"], -form input[type="number"], -select, -form input[type="password"], -form input[type="url"], -form input[type="email"] { - border: 1px solid #999; - padding: 0.5em 1em; - min-width: 12em; - color: #666; -} - -@media screen and (min-device-pixel-ratio: 0) { - select { - appearance: none; - border-radius: 0; - background: #fff url("../../_global/img/bg-select.png") no-repeat right center; - } -} - -.inline .row { - display: inline-block; - margin-right: 0.5em; -} - -.inline label { - min-width: 6em; -} - -fieldset label { - display: inline-block; - min-width: 12.5em; - color: #666; -} - -label { - margin-right: 0.5em; -} - -form .row { - margin-bottom: 0.5em; -} - -form button, -input[type="submit"] { - cursor: pointer; - background-color: #000; - color: #fff; - padding: 0.5em 1em; - display: inline-block; - border: 1px solid #000; -} - -form button:hover, -form button:focus, -input[type="submit"]:hover, -input[type="submit"]:focus { - background-color: #fff; - color: #000; - transition: all 0.5s ease; -} - -#bookmarklet { - cursor: move; -} - -h2::after { - content: ""; - height: 4px; - width: 70px; - background-color: #000; - display: block; -} - -.links { - padding: 0; - margin: 0; -} - -.links li { - list-style: none; - margin: 0; - padding: 0; -} - -#links { - position: fixed; - top: 0; - width: 10em; - left: 0; - text-align: right; - background-color: #333; - padding-top: 9.5em; - height: 100%; - box-shadow: inset -4px 0 20px rgb(0 0 0 / 60%); - z-index: 15; -} - -#main { - margin-left: 12em; - position: relative; - z-index: 10; - padding-right: 5%; - padding-bottom: 1em; -} - -#links > li > a { - display: block; - padding: 0.5em 2em 0.5em 1em; - color: #fff; - position: relative; - text-transform: uppercase; - text-decoration: none; - font-weight: normal; - font-family: "PT Sans", sans-serif; - transition: all 0.5s ease; -} - -#links > li > a:hover, -#links > li > a:focus { - background-color: #999; - color: #000; -} - -#links .current::after { - content: ""; - width: 0; - height: 0; - position: absolute; - border-style: solid; - border-width: 10px; - border-color: transparent #eee transparent transparent; - right: 0; - top: 50%; - margin-top: -10px; -} - -#links li:last-child { - position: fixed; - bottom: 1em; - width: 10em; -} - -#links li:last-child a::before { - font-size: 1.2em; - position: relative; - top: 2px; -} - -#sort { - padding: 0; - list-style-type: none; - opacity: 0.5; - display: inline-block; -} - -#sort li { - display: inline; - font-size: 0.9em; -} - -#sort li + li { - margin-left: 10px; -} - -#sort a { - padding: 2px 2px 0; - vertical-align: middle; -} - -#sort img { - vertical-align: baseline; -} - -#sort img:hover { - cursor: pointer; -} - -#display-mode { - float: right; - margin-top: 10px; - margin-bottom: 10px; - opacity: 0.5; -} - -#listmode { - width: 16px; - display: inline-block; - text-decoration: none; -} - -#listmode.tablemode { - background-image: url("../../_global/img/table.png"); - background-repeat: no-repeat; - background-position: bottom; -} - -#listmode.listmode { - background-image: url("../../_global/img/list.png"); - background-repeat: no-repeat; - background-position: bottom; -} - -#warning_message { - position: fixed; - background-color: #ff6347; - z-index: 1000; - bottom: 0; - left: 0; - width: 100%; - color: #000; -} - -/* ========================================================================== - 2 = Layout - ========================================================================== */ - -#content { - margin-top: 2em; - min-height: 30em; -} - -footer { - text-align: right; - position: relative; - bottom: 0; - right: 5em; - color: #999; - font-size: 0.8em; - font-style: italic; - z-index: 20; -} - -footer a { - color: #999; - font-weight: normal; -} - -.list-entries { - letter-spacing: -5px; -} - -.listmode.entry { - width: 100%; - height: inherit; -} - -.card-entry-labels { - position: absolute; - top: 100px; - left: -1em; - z-index: 90; - max-width: 50%; - padding-left: 0; -} - -.card-entry-labels li { - margin: 10px 10px 10px auto; - padding: 5px 12px 5px 25px; - background-color: rgb(0 0 0 / 60%); - border-radius: 0 3px 3px 0; - color: #fff; - cursor: default; - max-height: 2em; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.card-entry-tags { - max-height: 2em; - overflow-y: hidden; - padding: 0; - margin: 0; -} - -.card-entry-tags li, -.card-entry-tags span { - display: inline-block; - margin: 0 5px; - padding: 5px 12px; - background-color: rgb(0 0 0 / 60%); - border-radius: 3px; - max-height: 2em; - overflow: hidden; - text-overflow: ellipsis; -} - -.card-entry-tags a, -.card-entry-labels a { - text-decoration: none; - font-weight: normal; - color: #fff; -} - -.nav-panel-add-tag { - margin-top: 10px; -} - -.list-entries + .results { - margin-bottom: 2em; -} - -.reading-time, -.created-at { - color: #999; - font-style: italic; - font-weight: normal; - font-size: 0.9em; -} - -.estimatedTime small { - position: relative; - top: -1px; -} - -.entry { - background-color: #fff; - letter-spacing: normal; - box-shadow: 0 3px 7px rgb(0 0 0 / 30%); - display: inline-block; - width: 32%; - margin-bottom: 1.5em; - vertical-align: top; - margin-right: 1%; - position: relative; - overflow: hidden; - padding: 1.5em 1.5em 3em; - height: 440px; -} - -.entry::before { - content: ""; - width: 0; - height: 0; - border-style: solid; - border-color: transparent transparent #000; - border-width: 10px; - position: absolute; - bottom: 0.3em; - z-index: 10; - right: 1.5em; - transition: all 0.5s ease; -} - -.entry::after { - content: ""; - position: absolute; - height: 7px; - width: 100%; - bottom: 0; - left: 0; - background-color: #000; - transition: all 0.5s ease; -} - -.entry:hover { - box-shadow: 0 3px 10px rgb(0 0 0 / 100%); -} - -.entry:hover::after { - height: 40px; -} - -.entry:hover::before { - bottom: 2.4em; -} - -.entry:hover h2 a { - color: #666; -} - -.entry h2 { - text-transform: none; - margin-bottom: 0; - line-height: 1.2; -} - -.entry h2::after { - content: none; -} - -.entry h2 a { - display: block; - text-decoration: none; - color: #000; - word-wrap: break-word; - transition: all 0.5s ease; -} - -img.preview { - max-width: calc(100% + 3em); - left: -1.5em; - position: relative; -} - -.entry p { - color: #666; - font-size: 0.9em; - line-height: 1.7; - margin-top: 5px; -} - -.entry h2 a::first-letter { - text-transform: uppercase; -} - -.entry:hover .tools { - bottom: 0; -} - -.entry .tools { - position: absolute; - bottom: -50px; - left: 0; - width: 100%; - z-index: 10; - padding-right: 0.5em; - text-align: right; - transition: all 0.5s ease; -} - -.entry .tools a { - color: #666; - text-decoration: none; - display: block; - padding: 0.4em; -} - -.entry .tools a:hover { - color: #fff; -} - -.entry .tools li { - display: inline-block; -} - -.entry:nth-child(3n+1) { - margin-left: 0; -} - -.results { - letter-spacing: -5px; - padding: 0 0 0.5em; -} - -.results > * { - display: inline-block; - vertical-align: top; - letter-spacing: normal; - width: 50%; - text-align: right; -} - -div.pagination ul { - text-align: right; -} - -.nb-results { - text-align: left; - font-style: italic; - color: #999; - display: inline-flex; -} - -div.pagination ul > * { - display: inline-block; - margin-left: 0.5em; -} - -div.pagination ul a { - color: #999; - text-decoration: none; -} - -div.pagination ul a:hover, -div.pagination ul a:focus { - text-decoration: underline; -} - -div.pagination ul .prev.disabled, -div.pagination ul .next.disabled { - display: none; -} - -div.pagination ul .current { - height: 25px; - padding: 4px 8px; - border: 1px solid #d5d5d5; - text-decoration: none; - font-weight: bold; - color: #000; - background-color: #ccc; -} - -.hide { - display: none; -} - -/* ========================================================================== - 2.1 = "save a link" related styles - ========================================================================== */ - -.popup-form { - background: rgb(0 0 0 / 50%); - position: absolute; - top: 0; - left: 10em; - z-index: 20; - height: 100%; - width: 100%; - margin: 0; - margin-top: -30% !important; - padding: 2em; - display: none; - border-left: 1px #eee solid; -} - -.popup-form form { - background-color: #fff; - position: absolute; - top: 0; - left: 0; - z-index: 20; - border: 10px solid #000; - width: 400px; - height: 200px; - padding: 2em; -} - -#bagit-form-form .addurl { - margin-left: 0; -} - -.closeMessage, -.close-button { - background-color: #000; - color: #fff; - font-size: 1.2em; - line-height: 1.6; - width: 1.6em; - height: 1.6em; - text-align: center; - text-decoration: none; -} - -.closeMessage:hover, -.closeMessage:focus, -.close-button:hover, -.close-button:focus { - background-color: #999; - color: #000; -} - -.close-button--popup { - display: inline-block; - position: absolute; - top: 0; - right: 0; - font-size: 1.4em; -} - -.active-current { - background-color: #999; -} - -.active-current::after { - content: ""; - width: 0; - height: 0; - position: absolute; - border-style: solid; - border-width: 10px; - border-color: transparent #eee transparent transparent; - right: 0; - top: 50%; - margin-top: -10px; -} - -.opacity03 { - opacity: 0.3; -} - -.add-to-wallabag-link-after { - background-color: #000; - color: #fff; - padding: 0 3px 2px; -} - -a.add-to-wallabag-link-after { - visibility: hidden; - position: absolute; - opacity: 0; - transition-duration: 2s; - transition-timing-function: ease-out; -} - -#article article a:hover + a.add-to-wallabag-link-after, -a.add-to-wallabag-link-after:hover { - opacity: 1; - visibility: visible; - transition-duration: 0.3s; - transition-timing-function: ease-in; -} - -a.add-to-wallabag-link-after::after { - content: "w"; -} - -#add-link-result { - font-weight: bold; - font-size: 0.9em; -} - -.btn-clickable { - cursor: pointer; -} - -/* ========================================================================== - 3 = Pictos - ========================================================================== */ - -@font-face { - font-family: icomoon; - src: url("../fonts/IcoMoon-Free.ttf"); - font-weight: normal; - font-style: normal; -} - -@font-face { - font-family: "Material Icons"; - font-style: normal; - font-weight: 400; - src: url(../fonts/MaterialIcons-Regular.eot); - - /* For IE6-8 */ - src: local("Material Icons"), local("MaterialIcons-Regular"), url(../fonts/MaterialIcons-Regular.woff2) format("woff2"), url(../fonts/MaterialIcons-Regular.woff) format("woff"), url(../fonts/MaterialIcons-Regular.ttf) format("truetype"); -} - -.material-icons { - font-family: "Material Icons"; - font-weight: normal; - font-style: normal; - font-size: 1em; /* Preferred icon size */ - width: 1em; - height: 1em; - display: inline-block; - line-height: 1; - text-transform: none; - letter-spacing: normal; - word-wrap: normal; - white-space: nowrap; - direction: ltr; - - /* Support for all WebKit browsers. */ - -webkit-font-smoothing: antialiased; - - /* Support for Safari and Chrome. */ - text-rendering: optimizeLegibility; - - /* Support for Firefox. */ - -moz-osx-font-smoothing: grayscale; - - /* Support for IE. */ - font-feature-settings: "liga"; -} - -.material-icons.md-18 { font-size: 18px; } -.material-icons.md-24 { font-size: 24px; } -.material-icons.md-36 { font-size: 36px; } -.material-icons.md-48 { font-size: 48px; } - -.icon span, -.icon-image span { - position: absolute; - top: -9999px; -} - -[class^="icon-"]::before, -[class*=" icon-"]::before { - font-family: icomoon; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - - /* Enable Ligatures ================ */ - letter-spacing: 0; - font-feature-settings: "liga"; - - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.icon-flattr::before { - content: "\ead4"; -} - -.icon-mail::before { - content: "\ea86"; -} - -.icon-up-open::before { - content: "\e80b"; -} - -.icon-star::before { - content: "\e9d9"; -} - -.icon-check::before { - content: "\ea10"; -} - -.icon-link::before { - content: "\e9cb"; -} - -.icon-reply::before { - content: "\e806"; -} - -.icon-menu::before { - content: "\e9bd"; -} - -.icon-clock::before { - content: "\e803"; -} - -.icon-twitter::before { - content: "\ea96"; -} - -.icon-down-open::before { - content: "\e809"; -} - -.icon-trash::before { - content: "\e9ac"; -} - -.icon-delete::before { - content: "\ea0d"; -} - -.icon-power::before { - content: "\ea14"; -} - -.icon-arrow-up-thick::before { - content: "\ea3a"; -} - -.icon-rss::before { - content: "\e808"; -} - -.icon-print::before { - content: "\e954"; -} - -.icon-reload::before { - content: "\ea2e"; -} - -.icon-price-tags::before { - content: "\e936"; -} - -.icon-eye::before { - content: "\e9ce"; -} - -.icon-no-eye::before { - content: "\e9d1"; -} - -.icon-calendar::before { - content: "\e953"; -} - -.icon-pencil2::before { - content: "\e906"; -} - -.icon-users::before { - content: "\e972"; -} - -.icon-time::before { - content: "\e952"; -} - -/* .icon-image class, for image-based icons - ========================================================================== */ - -.icon-image { - background-size: 16px 16px; - background-repeat: no-repeat; - background-position: center; - padding-right: 1em !important; - padding-left: 1em !important; -} - -/* Carrot (http://carrot.org) */ -.icon-image--carrot { - background-image: url("../../_global/img/icons/carrot-icon--white.png"); -} - -/* Diaspora */ -.icon-image--diaspora { - background-image: url("../../_global/img/icons/diaspora-icon--black.png"); -} - -/* Unmark.it */ -.icon-image--unmark { - background-image: url("../../_global/img/icons/unmark-icon--black.png"); -} - -/* shaarli */ -.icon-image--shaarli { - background-image: url("../../_global/img/icons/shaarli.png"); -} - -/* scuttle */ -.icon-image--scuttle { - background-image: url("../../_global/img/icons/scuttle.png"); -} - -/* ========================================================================== - Icon selected - ========================================================================== */ - -.icon-star.fav::before { - color: #fff; -} - -.icon-check.archive::before { - color: #fff; -} - -/* ========================================================================== - 4 = Messages - ========================================================================== */ - -.messages { - text-align: left; - margin-top: 1em; -} - -.messages > * { - display: inline-block; -} - -.warning { - font-weight: bold; - display: block; - width: 100%; -} - -.more-info { - font-size: 0.85em; - line-height: 1.5; - color: #aaa; -} - -.more-info a { - color: #aaa; -} - -/* ========================================================================== - 5 = Article - ========================================================================== */ - -#article { - width: 70%; - margin-bottom: 3em; - text-align: justify; -} - -#article .tags { - margin-bottom: 1em; -} - -#article i { - font-style: normal; -} - -blockquote { - border: 1px solid #999; - background-color: #fff; - padding: 1em; - margin: 0; -} - -#article h2, -#article h3, -#article h4 { - text-transform: none; -} - -#article h2::after { - content: none; -} - -.topPosF { - position: fixed; - right: 20%; - bottom: 2em; - font-size: 1.5em; -} - -#article_toolbar { - margin-bottom: 1em; -} - -#article_toolbar li { - display: inline-block; - margin: 3px auto; -} - -#article_toolbar a { - background-color: #000; - padding: 0.3em 0.5em 0.2em; - color: #fff; - text-decoration: none; -} - -#article_toolbar a:hover, -#article_toolbar a:focus { - background-color: #999; -} - -#nav-btn-add-tag { - cursor: pointer; -} - -.shaarli::before { - content: "*"; -} - -.scuttle::before { - content: "*"; -} - -.return { - text-decoration: none; - margin-top: 1em; - display: block; -} - -.return::before { - margin-right: 0.5em; -} - -.notags { - font-style: italic; - color: #999; -} - -.icon-rss { - background-color: #000; - color: #fff; - padding: 0.2em 0.5em; -} - -.icon-rss::before { - position: relative; - top: 2px; -} - -.list-tags li { - margin-bottom: 0.5em; -} - -.list-tags .icon-rss:hover, -.list-tags .icon-rss:focus { - background-color: #fff; - color: #000; - text-decoration: none; -} - -.list-tags a { - text-decoration: none; -} - -.list-tags a:hover, -.list-tags a:focus { - text-decoration: underline; -} - -pre code { - font-family: "Courier New", Courier, monospace; -} - -#filters { - position: fixed; - width: 20%; - height: 100%; - top: 0; - right: 0; - background-color: #fff; - padding: 15px; - padding-right: 30px; - padding-top: 30px; - border-left: 1px #333 solid; - z-index: 12; - min-width: 300px; -} - -#filters form .filter-group { - margin: 5px; -} - -#download-form { - position: fixed; - width: 10%; - height: 100%; - top: 0; - right: 0; - background-color: #fff; - padding: 15px; - padding-right: 30px; - padding-top: 30px; - border-left: 1px #333 solid; - z-index: 12; - min-width: 200px; -} - -#download-form li { - display: block; - padding: 0.5em 2em 0.5em 1em; - color: #fff; - position: relative; - text-transform: uppercase; - text-decoration: none; - font-weight: 400; - font-family: PT Sans, sans-serif; - transition: all 0.5s ease; -} - -/* ========================================================================== - 6 = Media Queries - ========================================================================== */ - -@media screen and (max-width: 1050px) { - .entry { - width: 49%; - } - - .entry:nth-child(3n+1) { - margin-left: 1.5%; - } - - .entry:nth-child(2n+1) { - margin-left: 0; - } -} - -@media screen and (max-width: 900px) { - #article { - width: 80%; - } - - .topPosF { - right: 2.5em; - } -} - -@media screen and (max-width: 700px) { - .entry { - width: 100%; - margin-left: 0; - } - - #display-mode { - display: none; - } -} - -@media screen and (max-height: 770px) { - .menu.users, - .menu.internal, - .menu.developer { - display: none; - } -} - -@media screen and (max-width: 500px) { - .entry { - width: 100%; - margin-left: 0; - } - - body > header { - background-color: #333; - position: fixed; - top: 0; - width: 100%; - height: 3em; - z-index: 11; - } - - #links li:last-child { - position: static; - width: auto; - } - - #links li:last-child a::before { - content: none; - } - - .logo { - width: 1.25em; - height: 1.25em; - left: 0; - top: 0; - } - - .login > header { - position: static; - } - - .login form { - width: 100%; - position: static; - margin-left: 0; - } - - .login .logo { - height: auto; - top: 0.5em; - width: 75px; - margin-left: -37.5px; - } - - .desktopHide { - display: block; - position: fixed; - z-index: 20; - top: 0; - right: 0; - border: 0; - width: 2.5em; - height: 2.5em; - cursor: pointer; - background-color: #999; - font-size: 1.2em; - } - - .desktopHide:hover, - .desktopHide:focus { - background-color: #fff; - } - - #links { - display: none; - width: 100%; - height: auto; - padding-top: 3em; - } - - #links.menu--open { - display: block; - } - - footer { - position: static; - margin-right: 3em; - } - - #main { - margin-left: 1.5em; - padding-right: 1.5em; - position: static; - margin-top: 3em; - } - - .card-entry-labels { - display: none; - } - - #article_toolbar .topPosF { - display: none; - } - - #article { - width: 100%; - } - - #article h1 { - font-size: 1.5em; - } - - #article_toolbar a { - padding: 0.3em 0.4em 0.2em; - } - - #display-mode { - display: none; - } - - .popup-form, - #bagit-form, - #search-form { - left: 0; - width: 100%; - border-left: none; - } - - .popup-form form, - #bagit-form form, - #search-form form { - width: 100%; - } -} diff --git a/app/Resources/static/themes/baggy/css/media_queries.scss b/app/Resources/static/themes/baggy/css/media_queries.scss deleted file mode 100755 index d8014ca65..000000000 --- a/app/Resources/static/themes/baggy/css/media_queries.scss +++ /dev/null @@ -1,177 +0,0 @@ -@media screen and (max-width: 1050px) { - .entry { - width: 49%; - } - - .entry:nth-child(3n+1) { - margin-left: 1.5%; - } - - .entry:nth-child(2n+1) { - margin-left: 0; - } -} - -@media screen and (max-width: 900px) { - #article { - width: 80%; - } - - .topPosF { - right: 2.5em; - } -} - -@media screen and (max-width: 700px) { - .entry { - width: 100%; - margin-left: 0; - } - - #display-mode { - display: none; - } -} - -@media screen and (max-height: 770px) { - .menu.users, - .menu.internal, - .menu.developer { - display: none; - } -} - -@media screen and (max-width: 500px) { - .entry { - width: 100%; - margin-left: 0; - } - - body > header { - background-color: #333; - position: fixed; - top: 0; - width: 100%; - height: 3em; - z-index: 11; - } - - #links li:last-child { - position: static; - width: auto; - } - - #links li:last-child a::before { - content: none; - } - - .logo { - width: 1.25em; - height: 1.25em; - left: 0; - top: 0; - } - - .login > header { - position: static; - } - - .login form { - width: 100%; - position: static; - margin-left: 0; - } - - .login .logo { - height: auto; - top: 0.5em; - width: 75px; - margin-left: -37.5px; - } - - .desktopHide { - display: block; - position: fixed; - z-index: 20; - top: 0; - right: 0; - border: 0; - width: 2.5em; - height: 2.5em; - cursor: pointer; - background-color: #999; - font-size: 1.2em; - } - - .desktopHide:hover, - .desktopHide:focus { - background-color: #fff; - } - - #links { - display: none; - width: 100%; - height: auto; - padding-top: 3em; - } - - #links.menu--open { - display: block; - } - - footer { - position: static; - margin-right: 3em; - } - - #main { - margin-left: 1.5em; - padding-right: 1.5em; - position: static; - margin-top: 3em; - } - - .card-entry-labels { - display: none; - } - - #article_toolbar .topPosF { - display: none; - } - - #article { - width: 100%; - } - - #article h1 { - font-size: 1.5em; - } - - #article_toolbar a { - padding: 0.3em 0.4em 0.2em; - } - - #display-mode { - display: none; - } - - .popup-form, - #bagit-form, - #search-form { - left: 0; - width: 100%; - border-left: none; - } - - .popup-form form, - #bagit-form form, - #search-form form { - width: 100%; - } -} - -@media only print { - header h1.logo { - display: none; - } -} diff --git a/app/Resources/static/themes/baggy/css/messages.scss b/app/Resources/static/themes/baggy/css/messages.scss deleted file mode 100755 index a388419eb..000000000 --- a/app/Resources/static/themes/baggy/css/messages.scss +++ /dev/null @@ -1,50 +0,0 @@ -/* ========================================================================== - Messages - ========================================================================== */ - -.messages { - text-align: left; - width: 60%; - margin: auto 17%; - - > * { - display: inline-block; - } - - .install { - text-align: left; - - &.error { - border: 1px solid #c42608; - color: #c00 !important; - background: #fff0ef; - } - - &.notice { - border: 1px solid #ebcd41; - color: #000; - background: #fffcd3; - } - - &.success { - border: 1px solid #6dc70c; - background: #e0fbcc !important; - } - } -} - -.warning { - font-weight: bold; - display: block; - width: 100%; -} - -.more-info { - font-size: 0.85em; - line-height: 1.5; - color: #aaa; - - a { - color: #aaa; - } -} diff --git a/app/Resources/static/themes/baggy/css/pictos.scss b/app/Resources/static/themes/baggy/css/pictos.scss deleted file mode 100644 index bdd39dc1e..000000000 --- a/app/Resources/static/themes/baggy/css/pictos.scss +++ /dev/null @@ -1,205 +0,0 @@ -/* ========================================================================== - Pictos - ========================================================================== */ - -@font-face { - font-family: icomoon; - src: url("~icomoon-free-npm/Font/IcoMoon-Free.ttf"); - font-weight: normal; - font-style: normal; -} - -.material-icons { - font-family: "Material Icons"; - font-weight: normal; - font-style: normal; - font-size: 1em; /* Preferred icon size */ - width: 1em; - height: 1em; - display: inline-block; - line-height: 1; - text-transform: none; - letter-spacing: normal; - word-wrap: normal; - white-space: nowrap; - direction: ltr; - - /* Support for all WebKit browsers. */ - -webkit-font-smoothing: antialiased; - - /* Support for Safari and Chrome. */ - text-rendering: optimizeLegibility; - - /* Support for Firefox. */ - -moz-osx-font-smoothing: grayscale; - - /* Support for IE. */ - font-feature-settings: "liga"; - - .md-18 { font-size: 18px; } - .md-24 { font-size: 24px; } - .md-36 { font-size: 36px; } - .md-48 { font-size: 48px; } - - .vertical-align-middle { - vertical-align: middle !important; - } -} - -.icon span, -.icon-image span { - position: absolute; - top: -9999px; -} - -[class^="icon-"]::before, -[class*=" icon-"]::before { - font-family: icomoon; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - - /* Enable Ligatures ================ */ - letter-spacing: 0; - font-feature-settings: "liga"; - - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.icon-flattr::before { - content: "\ead4"; -} - -.icon-mail::before { - content: "\ea86"; -} - -.icon-up-open::before { - content: "\e80b"; -} - -.icon-star::before { - content: "\e9d9"; -} - -.icon-check::before { - content: "\ea10"; -} - -.icon-link::before { - content: "\e9cb"; -} - -.icon-reply::before { - content: "\e806"; -} - -.icon-menu::before { - content: "\e9bd"; -} - -.icon-clock::before { - content: "\e803"; -} - -.icon-twitter::before { - content: "\ea96"; -} - -.icon-down-open::before { - content: "\e809"; -} - -.icon-trash::before { - content: "\e9ac"; -} - -.icon-delete::before { - content: "\ea0d"; -} - -.icon-power::before { - content: "\ea14"; -} - -.icon-arrow-up-thick::before { - content: "\ea3a"; -} - -.icon-feed::before { - content: "\e808"; -} - -.icon-print::before { - content: "\e954"; -} - -.icon-reload::before { - content: "\ea2e"; -} - -.icon-price-tags::before { - content: "\e936"; -} - -.icon-eye::before { - content: "\e9ce"; -} - -.icon-no-eye::before { - content: "\e9d1"; -} - -.icon-calendar::before { - content: "\e953"; -} - -.icon-time::before { - content: "\e952"; -} - -/* .icon-image class, for image-based icons - ========================================================================== */ - -.icon-image { - background: no-repeat center/80%; - padding-right: 1em !important; - padding-left: 1em !important; -} - -/* Carrot (http://carrot.org) */ -.icon-image--carrot { - background-image: url("../../_global/img/icons/carrot-icon--white.png"); -} - -/* Diaspora */ -.icon-image--diaspora { - background-image: url("../../_global/img/icons/Diaspora-asterisk.svg"); -} - -/* Unmark.it */ -.icon-image--unmark { - background-image: url("../../_global/img/icons/unmark-icon--black.png"); -} - -/* shaarli */ -.icon-image--shaarli { - background-image: url("../../_global/img/icons/shaarli.png"); -} - -/* ========================================================================== - Icon selected - ========================================================================== */ - -.icon-star.fav::before { - color: #fff; -} - -.icon-check.archive::before { - color: #fff; -} diff --git a/app/Resources/static/themes/baggy/css/print.scss b/app/Resources/static/themes/baggy/css/print.scss deleted file mode 100755 index 6f1c442e6..000000000 --- a/app/Resources/static/themes/baggy/css/print.scss +++ /dev/null @@ -1,63 +0,0 @@ -@media print { - /* ### Layout ### */ - - body { - font-family: serif; - background-color: #fff; - } - - @page { - margin: 1cm; - } - - img { - max-width: 100% !important; - } - - /* ### Content ### */ - - /* Hide useless blocks */ - body > .logo, - #article_toolbar, - #links, - #sort, - body > footer, - .top_link, - div.tools, - header div, - .messages, - .entrie + .results, - #article .mbm a, - #article-informations { - display: none !important; - } - - article { - border: none !important; - } - - /* Add URL after links */ - .vieworiginal a::after { - content: " (" attr(href) ")"; - } - - /* Add explanation after abbr */ - abbr[title]::after { - content: " (" attr(title) ")"; - } - - /* Change border on current pager item */ - .pagination span.current { - border-style: dashed; - } - - #main { - width: 100%; - margin: 0; - padding: 0; - } - - #article { - width: 100%; - } -} diff --git a/app/Resources/static/themes/baggy/css/ratatouille.scss b/app/Resources/static/themes/baggy/css/ratatouille.scss deleted file mode 100644 index c54667706..000000000 --- a/app/Resources/static/themes/baggy/css/ratatouille.scss +++ /dev/null @@ -1,223 +0,0 @@ -/* - Ratatouille mini Framework css by Thomas LEBEAU - Base on KNACSS => www.KNACSS.com (2013-10) @author: Raphael Goetter, Alsacreations - and normalize.css -*/ - -* { - box-sizing: border-box; -} - -html { - font-family: sans-serif; /* 1 */ - text-size-adjust: 100%; /* 2 */ -} - -body { - font-size: 1em; - line-height: 1.5; - margin: 0; -} - -/* ========================================================================== - Mise en forme - ========================================================================== */ - -h1:first-child, -h2:first-child, -h3:first-child, -h4:first-child, -h5:first-child, -h6:first-child, -p:first-child, -ul:first-child, -ol:first-child, -dl:first-child { - margin-top: 0; -} - -code, -kbd, -pre, -samp { - font-family: monospace, serif; -} - -pre { - white-space: pre-wrap; -} - -.upper { - text-transform: uppercase; -} - -.bold { - font-weight: bold; -} - -.inner { - margin: 0 auto; - max-width: 61.25em; /* 980px */ -} - -table, -img, -figure { - max-width: 100%; - height: auto; -} - -iframe { - max-width: 100%; -} - -.fl { - float: left; -} - -.fr { - float: right; -} - -table { - border-collapse: collapse; -} - -figure { - margin: 0; -} - -button, -input, -select, -textarea { - font-family: inherit; - font-size: 100%; - margin: 0; -} - -input[type="search"] { - appearance: textfield; -} - -/* ========================================================================== - Mise en page - ========================================================================== */ - -.dib { - display: inline-block; - vertical-align: middle; -} - -.dnone { - display: none; -} - -.dtable { - display: table; -} - -.dtable > * { - display: table-row; -} - -.dtable > * > * { - display: table-cell; -} - -.element-invisible { - border: 0; - clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; -} - -.small { - font-size: 0.8em; -} - -.big { - font-size: 1.2em; -} - -/* Width */ - -.w100 { - width: 100%; -} - -.w90 { - width: 90%; -} - -.w80 { - width: 80%; -} - -.w70 { - width: 70%; -} - -.w60 { - width: 60%; -} - -.w50 { - width: 50%; -} - -.w40 { - width: 40%; -} - -.w30 { - width: 30%; -} - -.w20 { - width: 20%; -} - -.w10 { - width: 10%; -} - -/* ========================================================================== - Internet Explorer - ========================================================================== */ - -/* IE8 and IE9 */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -nav, -section, -summary { - display: block; -} - -/* IE8 and IE9 */ - -audio, -canvas, -video { - display: inline-block; -} - -@media screen { - select { - appearance: none; - border-radius: 0; - } -} diff --git a/app/Resources/static/themes/baggy/css/save.scss b/app/Resources/static/themes/baggy/css/save.scss deleted file mode 100644 index 4a7b0b4b6..000000000 --- a/app/Resources/static/themes/baggy/css/save.scss +++ /dev/null @@ -1,115 +0,0 @@ -/* ========================================================================== - "save a link" related styles - ========================================================================== */ - -.popup-form { - background: rgb(0 0 0 / 50%); - position: absolute; - top: 0; - left: 10em; - z-index: 20; - height: 100%; - width: 100%; - margin: 0; - margin-top: -30% !important; - padding: 2em; - display: none; - border-left: 1px #eee solid; - - form { - background-color: #fff; - position: absolute; - top: 0; - left: 0; - z-index: 20; - border: 10px solid #000; - width: 400px; - height: 200px; - padding: 2em; - } -} - -#bagit-form-form .addurl { - margin-left: 0; -} - -.closeMessage, -.close-button { - background-color: #000; - color: #fff; - font-size: 1.2em; - line-height: 1.6; - width: 1.6em; - height: 1.6em; - text-align: center; - text-decoration: none; - - &:hover, - &:focus { - background-color: #999; - color: #000; - } -} - -.close-button--popup { - display: inline-block; - position: absolute; - top: 0; - right: 0; - font-size: 1.4em; -} - -.active-current { - background-color: #999; - - &::after { - content: ""; - width: 0; - height: 0; - position: absolute; - border: 10px solid transparent; - border-right-color: #eee; - right: 0; - top: 50%; - margin-top: -10px; - } -} - -.opacity03 { - opacity: 0.3; -} - -.add-to-wallabag-link-after { - background-color: #000; - color: #fff; - padding: 0 3px 2px; -} - -a.add-to-wallabag-link-after { - visibility: hidden; - position: absolute; - opacity: 0; - transition-duration: 2s; - transition-timing-function: ease-out; -} - -#article article a:hover + a.add-to-wallabag-link-after, -a.add-to-wallabag-link-after:hover { - opacity: 1; - visibility: visible; - transition-duration: 0.3s; - transition-timing-function: ease-in; -} - -a.add-to-wallabag-link-after::after { - content: "w"; -} - -#add-link-result { - font-weight: bold; - font-size: 0.9em; -} - -.btn-clickable { - cursor: pointer; -} diff --git a/app/Resources/static/themes/baggy/img/blank.png b/app/Resources/static/themes/baggy/img/blank.png deleted file mode 100755 index 113f5d56e..000000000 Binary files a/app/Resources/static/themes/baggy/img/blank.png and /dev/null differ diff --git a/app/Resources/static/themes/baggy/img/down.png b/app/Resources/static/themes/baggy/img/down.png deleted file mode 100644 index d048e4cbc..000000000 Binary files a/app/Resources/static/themes/baggy/img/down.png and /dev/null differ diff --git a/app/Resources/static/themes/baggy/img/list.png b/app/Resources/static/themes/baggy/img/list.png deleted file mode 100755 index 3ee98c212..000000000 Binary files a/app/Resources/static/themes/baggy/img/list.png and /dev/null differ diff --git a/app/Resources/static/themes/baggy/img/table.png b/app/Resources/static/themes/baggy/img/table.png deleted file mode 100755 index 24e7b6fa2..000000000 Binary files a/app/Resources/static/themes/baggy/img/table.png and /dev/null differ diff --git a/app/Resources/static/themes/baggy/img/top.png b/app/Resources/static/themes/baggy/img/top.png deleted file mode 100644 index 782acc095..000000000 Binary files a/app/Resources/static/themes/baggy/img/top.png and /dev/null differ diff --git a/app/Resources/static/themes/baggy/index.js b/app/Resources/static/themes/baggy/index.js deleted file mode 100755 index 39ad49aa6..000000000 --- a/app/Resources/static/themes/baggy/index.js +++ /dev/null @@ -1,266 +0,0 @@ -import $ from 'jquery'; - -/* Global imports */ -import '../_global/index'; - -/* Shortcuts */ -import './js/shortcuts/main'; -import './js/shortcuts/entry'; - -/* Tools */ -import toggleSaveLinkForm from './js/uiTools'; - -/* Theme style */ -import './css/index.scss'; - -$(document).ready(() => { - /* ========================================================================== - Menu - ========================================================================== */ - - $('#menu').click(() => { - $('#links').toggleClass('menu--open'); - const content = $('#content'); - if (content.hasClass('opacity03')) { - content.removeClass('opacity03'); - } - }); - - /* ========================================================================== - Add tag panel - ========================================================================== */ - - $('#nav-btn-add-tag').on('click', () => { - $('.baggy-add-tag').toggle(100); - $('.nav-panel-menu').addClass('hidden'); - $('#tag_label').focus(); - return false; - }); - - /** - * Filters & Export - */ - // no display if filters not available - if ($('div').is('#filters')) { - $('#button_filters').show(); - $('#clear_form_filters').on('click', () => { - $('#filters input').val(''); - $('#filters :checked').removeAttr('checked'); - return false; - }); - } - - /** - * Close window after adding entry if popup - */ - const currentUrl = window.location.href; - if (currentUrl.match('&closewin=true')) { - window.close(); - } - - /** - if ($('article').size() > 0) { - const waypoint = new Waypoint({ - element: $('.wallabag-title').get(0), - handler: (direction) => { - console.log(direction); - if (direction === 'down') { - $('aside.tags').fadeIn('slow'); - } else { - $('aside.tags').fadeOut('slow'); - } - }, - offset: 250, - }); - } - */ - - /** - * Tags autocomplete - */ - /** - * Not working on v2 - * - - $('#value').bind('keydown', (event) => { - if (event.keyCode === $.ui.keyCode.TAB && $(this).data('ui-autocomplete').menu.active) { - event.preventDefault(); - } - }).autocomplete({ - source: function source(request, response) { - $.getJSON('./?view=tags', { - term: extractLast(request.term), - //id: $(':hidden#entry_id').val() - }, response); - }, - search: function search() { - // custom minLength - const term = extractLast(this.value); - return term.length >= 1; - }, - focus: function focus() { - // prevent value inserted on focus - return false; - }, - select: function select(event, ui) { - const terms = split(this.value); - // remove the current input - terms.pop(); - // add the selected item - terms.push(ui.item.value); - // add placeholder to get the comma-and-space at the end - terms.push(''); - this.value = terms.join(', '); - return false; - }, - }); - */ - - //--------------------------------------------------------------------------- - // Close the message box when the user clicks the close icon - //--------------------------------------------------------------------------- - $('a.closeMessage').on('click', () => { - $(this).parents('div.messages').slideUp(300, () => { $(this).remove(); }); - return false; - }); - - $('#search-form').hide(); - $('#bagit-form').hide(); - $('#filters').hide(); - $('#download-form').hide(); - - //--------------------------------------------------------------------------- - // Toggle the 'Search' popup in the sidebar - //--------------------------------------------------------------------------- - function toggleSearch() { - $('#search-form').toggle(); - $('#search').toggleClass('current'); - $('#search').toggleClass('active-current'); - $('#search-arrow').toggleClass('arrow-down'); - if ($('#search').hasClass('current')) { - $('#content').addClass('opacity03'); - } else { - $('#content').removeClass('opacity03'); - } - } - - //--------------------------------------------------------------------------- - // Toggle the 'Filter' popup on entries list - //--------------------------------------------------------------------------- - function toggleFilter() { - $('#filters').toggle(); - } - - //--------------------------------------------------------------------------- - // Toggle the 'Download' popup on entries list - //--------------------------------------------------------------------------- - function toggleDownload() { - $('#download-form').toggle(); - } - - //--------------------------------------------------------------------------- - // Toggle the 'Save a Link' popup in the sidebar - //--------------------------------------------------------------------------- - function toggleBagit() { - $('#bagit-form').toggle(); - $('#bagit').toggleClass('current'); - $('#bagit').toggleClass('active-current'); - $('#bagit-arrow').toggleClass('arrow-down'); - if ($('#bagit').hasClass('current')) { - $('#content').addClass('opacity03'); - } else { - $('#content').removeClass('opacity03'); - } - } - - //--------------------------------------------------------------------------- - // Close all #links popups in the sidebar - //--------------------------------------------------------------------------- - function closePopups() { - $('#links .messages').hide(); - $('#links > li > a').removeClass('active-current'); - $('#links > li > a').removeClass('current'); - $('[id$=-arrow]').removeClass('arrow-down'); - $('#content').removeClass('opacity03'); - } - - $('#search').click(() => { - closePopups(); - toggleSearch(); - $('#searchfield').focus(); - }); - - $('.filter-btn').click(() => { - closePopups(); - toggleFilter(); - }); - - $('.download-btn').click(() => { - closePopups(); - toggleDownload(); - }); - - $('#bagit').click(() => { - closePopups(); - toggleBagit(); - $('#plainurl').focus(); - }); - - $('#search-form-close').click(() => { - toggleSearch(); - }); - - $('#filter-form-close').click(() => { - toggleFilter(); - }); - - $('#download-form-close').click(() => { - toggleDownload(); - }); - - $('#bagit-form-close').click(() => { - toggleBagit(); - }); - - const bagitFormForm = $('#bagit-form-form'); - - /* ========================================================================== - bag it link and close button - ========================================================================== */ - - // send 'bag it link' form request via ajax - bagitFormForm.submit((event) => { - $('body').css('cursor', 'wait'); - $('#add-link-result').empty(); - - $.ajax({ - type: bagitFormForm.attr('method'), - url: bagitFormForm.attr('action'), - data: bagitFormForm.serialize(), - success: function success() { - $('#add-link-result').html('Done!'); - $('#plainurl').val('').blur(''); - $('body').css('cursor', 'auto'); - }, - error: function error() { - $('#add-link-result').html('Failed!'); - $('body').css('cursor', 'auto'); - }, - }); - - event.preventDefault(); - }); - - /* ========================================================================== - Process all links inside an article - ========================================================================== */ - - $('article a[href^="http"]').after( - () => ``, - ); - - $('.add-to-wallabag-link-after').click((event) => { - toggleSaveLinkForm($(this).attr('href'), event); - event.preventDefault(); - }); -}); diff --git a/app/Resources/static/themes/baggy/js/autoCompleteTags.js b/app/Resources/static/themes/baggy/js/autoCompleteTags.js deleted file mode 100755 index 64fdaa927..000000000 --- a/app/Resources/static/themes/baggy/js/autoCompleteTags.js +++ /dev/null @@ -1,8 +0,0 @@ -function split(val) { - return val.split(/,\s*/); -} -function extractLast(term) { - return split(term).pop(); -} - -export default { split, extractLast }; diff --git a/app/Resources/static/themes/baggy/js/shortcuts/entry.js b/app/Resources/static/themes/baggy/js/shortcuts/entry.js deleted file mode 100644 index c87408b92..000000000 --- a/app/Resources/static/themes/baggy/js/shortcuts/entry.js +++ /dev/null @@ -1,26 +0,0 @@ -import Mousetrap from 'mousetrap'; -import $ from 'jquery'; - -$(document).ready(() => { - if ($('#article').length > 0) { - /* Article view */ - Mousetrap.bind('o', () => { - $('div#article_toolbar ul.links a.original')[0].click(); - }); - - /* mark as favorite */ - Mousetrap.bind('f', () => { - $('div#article_toolbar ul.links a.favorite')[0].click(); - }); - - /* mark as read */ - Mousetrap.bind('a', () => { - $('div#article_toolbar ul.links a.markasread')[0].click(); - }); - - /* delete */ - Mousetrap.bind('del', () => { - $('div#article_toolbar ul.links a.delete')[0].click(); - }); - } -}); diff --git a/app/Resources/static/themes/baggy/js/shortcuts/main.js b/app/Resources/static/themes/baggy/js/shortcuts/main.js deleted file mode 100644 index 43ebf3be8..000000000 --- a/app/Resources/static/themes/baggy/js/shortcuts/main.js +++ /dev/null @@ -1,10 +0,0 @@ -import $ from 'jquery'; -import Mousetrap from 'mousetrap'; - -$(document).ready(() => { - Mousetrap.bind('s', () => { - $('#search').trigger('click'); - $('#search_entry_term').focus(); - return false; - }); -}); diff --git a/app/Resources/static/themes/baggy/js/uiTools.js b/app/Resources/static/themes/baggy/js/uiTools.js deleted file mode 100644 index 713c53f76..000000000 --- a/app/Resources/static/themes/baggy/js/uiTools.js +++ /dev/null @@ -1,35 +0,0 @@ -import $ from 'jquery'; - -function toggleSaveLinkForm(url, event) { - $('#add-link-result').empty(); - - const $bagit = $('#bagit'); - const $bagitForm = $('#bagit-form'); - - $bagit.toggleClass('active-current'); - - // only if bag-it link is not presented on page - if ($bagit.length === 0) { - if (event !== 'undefined' && event) { - $bagitForm.css({ position: 'absolute', top: event.pageY, left: event.pageX - 200 }); - } else { - $bagitForm.css({ position: 'relative', top: 'auto', left: 'auto' }); - } - } - - const searchForm = $('#search-form'); - const plainUrl = $('#plainurl'); - if (searchForm.length !== 0) { - $('#search').removeClass('current'); - $('#search-arrow').removeClass('arrow-down'); - searchForm.hide(); - } - $bagitForm.toggle(); - $('#content').toggleClass('opacity03'); - if (url !== 'undefined' && url) { - plainUrl.val(url); - } - plainUrl.focus(); -} - -export default toggleSaveLinkForm; diff --git a/app/Resources/static/themes/material/css/cards.scss b/app/Resources/static/themes/material/css/cards.scss index a648c3887..f46971781 100644 --- a/app/Resources/static/themes/material/css/cards.scss +++ b/app/Resources/static/themes/material/css/cards.scss @@ -211,6 +211,10 @@ a.original:not(.waves-effect) { display: flex; } +.card-tag-delete { + margin-left: 10px; +} + .card-tag-labels { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); diff --git a/app/Resources/static/themes/material/css/icons.scss b/app/Resources/static/themes/material/css/icons.scss index 4a698e3be..5f60d20fd 100644 --- a/app/Resources/static/themes/material/css/icons.scss +++ b/app/Resources/static/themes/material/css/icons.scss @@ -123,10 +123,6 @@ a.icon-image { margin: 7px 1.5px 0 0; } - &.carrot::before { - background: url("../../_global/img/icons/carrot-icon--black.png") no-repeat center/90%; - } - &.diaspora::before { background: url("../../_global/img/icons/diaspora-icon--black.png") no-repeat center/80%; } diff --git a/app/Resources/static/themes/material/index.js b/app/Resources/static/themes/material/index.js index 2eff59c38..c13a564ab 100755 --- a/app/Resources/static/themes/material/index.js +++ b/app/Resources/static/themes/material/index.js @@ -222,4 +222,10 @@ $(document).ready(() => { }); }); } + $('form[name="form_mass_action"] input[name="tags"]').on('keydown', (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + $('form[name="form_mass_action"] button[name="tag"]').trigger('click'); + } + }); }); diff --git a/app/config/config.yml b/app/config/config.yml index 254344e7c..cced41f53 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -39,8 +39,10 @@ twig: debug: "%kernel.debug%" strict_variables: "%kernel.debug%" form_themes: - - "LexikFormFilterBundle:Form:form_div_layout.html.twig" - exception_controller: wallabag_core.exception_controller:showAction + - "@LexikFormFilter/Form/form_div_layout.html.twig" + exception_controller: Wallabag\CoreBundle\Controller\ExceptionController:showAction + globals: + registration_enabled: '%fosuser_registration%' # Doctrine Configuration doctrine: @@ -167,9 +169,8 @@ nelmio_cors: liip_theme: load_controllers: false themes: - - baggy - material - autodetect_theme: wallabag_core.helper.detect_active_theme + autodetect_theme: Wallabag\CoreBundle\Helper\DetectActiveTheme path_patterns: bundle_resource: @@ -210,14 +211,14 @@ scheb_two_factor: google: enabled: "%twofactor_auth%" issuer: "%server_name%" - template: WallabagUserBundle:Authentication:form.html.twig + template: "@WallabagUser/Authentication/form.html.twig" email: enabled: "%twofactor_auth%" sender_email: "%twofactor_sender%" digits: 6 - template: WallabagUserBundle:Authentication:form.html.twig - mailer: wallabag_user.auth_code_mailer + template: "@WallabagUser/Authentication/form.html.twig" + mailer: Wallabag\UserBundle\Mailer\AuthCodeMailer kphoen_rulerz: targets: @@ -404,7 +405,7 @@ sensio_framework_extra: httplug: clients: wallabag_core: - factory: 'wallabag_core.http_client_factory' + factory: Wallabag\CoreBundle\Helper\HttpClientFactory config: defaults: timeout: 10 diff --git a/src/Wallabag/CoreBundle/Resources/config/parameters.yml b/app/config/parameters_addons.yml similarity index 100% rename from src/Wallabag/CoreBundle/Resources/config/parameters.yml rename to app/config/parameters_addons.yml diff --git a/app/config/routing.yml b/app/config/routing.yml index 4fff4cb62..86c6602e6 100644 --- a/app/config/routing.yml +++ b/app/config/routing.yml @@ -33,7 +33,7 @@ rest : homepage: path: "/{page}" defaults: - _controller: WallabagCoreBundle:Entry:showUnread + _controller: 'Wallabag\CoreBundle\Controller\EntryController::showUnreadAction' page : 1 requirements: page: \d+ @@ -41,25 +41,13 @@ homepage: fos_user: resource: "@FOSUserBundle/Resources/config/routing/all.xml" -fos_user_security_login: - path: /login - defaults: - _controller: Wallabag\UserBundle\Controller\SecurityController::loginAction - methods: [GET, POST] - -fos_user_registration_register: - path: /register - defaults: - _controller: Wallabag\UserBundle\Controller\RegistrationController::registerAction - methods: [GET, POST] - fos_oauth_server_token: resource: "@FOSOAuthServerBundle/Resources/config/routing/token.xml" craue_config_settings_modify: path: /settings defaults: - _controller: CraueConfigBundle:Settings:modify + _controller: 'Craue\ConfigBundle\Controller\SettingsController::modifyAction' fos_js_routing: resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml" @@ -76,34 +64,34 @@ fos_js_routing: rss_to_atom_unread: path: /{username}/{token}/unread.xml defaults: - _controller: FrameworkBundle:Redirect:redirect + _controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction' route: unread_feed permanent: true rss_to_atom_archive: path: /{username}/{token}/archive.xml defaults: - _controller: FrameworkBundle:Redirect:redirect + _controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction' route: archive_feed permanent: true rss_to_atom_starred: path: /{username}/{token}/starred.xml defaults: - _controller: FrameworkBundle:Redirect:redirect + _controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction' route: starred_feed permanent: true rss_to_atom_all: path: /{username}/{token}/all.xml defaults: - _controller: FrameworkBundle:Redirect:redirect + _controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction' route: all_feed permanent: true rss_to_atom_tags: path: /{username}/{token}/tags/{slug}.xml defaults: - _controller: FrameworkBundle:Redirect:redirect + _controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction' route: tag_feed permanent: true diff --git a/app/config/security.yml b/app/config/security.yml index 5e74e82fb..2a09648f3 100644 --- a/app/config/security.yml +++ b/app/config/security.yml @@ -9,7 +9,7 @@ security: providers: administrators: entity: - class: WallabagUserBundle:User + class: 'Wallabag\UserBundle\Entity\User' property: username fos_userbundle: id: fos_user.user_provider.username_email diff --git a/app/config/services.yml b/app/config/services.yml index aab2a0568..eafa90809 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -1,40 +1,113 @@ +imports: + - { resource: services_rabbit.yml } + - { resource: services_redis.yml } + - { resource: parameters_addons.yml } + parameters: lexik_form_filter.get_filter.doctrine_orm.class: Wallabag\CoreBundle\Event\Subscriber\CustomDoctrineORMSubscriber services: - twig.extension.text: + _defaults: + autowire: true + autoconfigure: true + public: true + bind: + $rootDir: '%kernel.root_dir%' + $debug: '%kernel.debug%' + $defaultLocale: '%kernel.default_locale%' + $wallabagUrl: '%domain_name%' + $tablePrefix: "%database_table_prefix%" + $defaultTheme: '%wallabag_core.theme%' + $encryptionKeyPath: "%wallabag_core.site_credentials.encryption_key_path%" + $fetchingErrorMessageTitle: "%wallabag_core.fetching_error_message_title%" + $fetchingErrorMessage: '%wallabag_core.fetching_error_message%' + $languages: '%wallabag_core.languages%' + $lifeTime: '%wallabag_core.cache_lifetime%' + $cookieFile: "%kernel.cache_dir%/cookiejar.json" + $logoPath: 'web/img/appicon/apple-touch-icon-152.png' + $registrationEnabled: '%fosuser_registration%' + $restrictedAccess: '@=service(''craue_config'').get(''restricted_access'')' + $senderEmail: "%scheb_two_factor.email.sender_email%" + $senderName: "%scheb_two_factor.email.sender_name%" + $storeArticleHeaders: '@=service(''craue_config'').get(''store_article_headers'')' + $supportUrl: '@=service(''craue_config'').get(''wallabag_support_url'')' + $themes: '%liip_theme.themes%' + + Wallabag\AnnotationBundle\: + resource: '../../src/Wallabag/AnnotationBundle/*' + exclude: '../../src/Wallabag/AnnotationBundle/{Controller,Entity}' + + Wallabag\ApiBundle\: + resource: '../../src/Wallabag/ApiBundle/*' + exclude: '../../src/Wallabag/ApiBundle/{Controller,Entity}' + + Wallabag\CoreBundle\: + resource: '../../src/Wallabag/CoreBundle/*' + exclude: '../../src/Wallabag/CoreBundle/{Controller,Entity}' + + Wallabag\ImportBundle\: + resource: '../../src/Wallabag/ImportBundle/*' + exclude: '../../src/Wallabag/ImportBundle/{Consumer,Controller,Redis}' + + Wallabag\UserBundle\: + resource: '../../src/Wallabag/UserBundle/*' + exclude: '../../src/Wallabag/UserBundle/{Controller,Entity}' + + Doctrine\DBAL\Connection: + alias: doctrine.dbal.default_connection + + Doctrine\ORM\EntityManagerInterface: + alias: doctrine.orm.entity_manager + + Doctrine\Persistence\ManagerRegistry: + alias: doctrine + + Craue\ConfigBundle\Util\Config: + alias: craue_config + + JMS\Serializer\SerializerInterface: + alias: jms_serializer + + Lexik\Bundle\FormFilterBundle\Filter\FilterBuilderUpdaterInterface: + alias: lexik_form_filter.query_builder_updater + + Liip\ThemeBundle\ActiveTheme: + alias: liip_theme.active_theme + + Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface: + alias: scheb_two_factor.security.google_authenticator + + Symfony\Component\HttpFoundation\Session\SessionInterface: + alias: session + + Symfony\Component\EventDispatcher\EventDispatcherInterface: + alias: event_dispatcher + + Symfony\Component\Form\FormFactoryInterface: + alias: form.factory + + Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface: + alias: security.token_storage + + Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface: + alias: security.authorization_checker + + Symfony\Component\Translation\TranslatorInterface: + alias: translator + + Symfony\Component\Validator\Validator\ValidatorInterface: + alias: validator + + FOS\UserBundle\Model\UserManagerInterface: + alias: fos_user.user_manager + + Twig_Extensions_Extension_Text: class: Twig_Extensions_Extension_Text - tags: - - { name: twig.extension } - wallabag.twig_extension: - class: Wallabag\CoreBundle\Twig\WallabagExtension + MatomoTwigExtension\MatomoTwigExtension: public: false - arguments: - - "@wallabag_core.entry_repository" - - "@wallabag_core.tag_repository" - - "@security.token_storage" - - "%wallabag_core.cache_lifetime%" - - "@translator" - - "%kernel.root_dir%" - tags: - - { name: twig.extension } - wallabag.twig_matomo_extension: - class: MatomoTwigExtension\MatomoTwigExtension - public: false - tags: - - { name: twig.extension } - - wallabag.locale_listener: - class: Wallabag\CoreBundle\Event\Listener\LocaleListener - arguments: ["%kernel.default_locale%"] - tags: - - { name: kernel.event_subscriber } - - wallabag.user_locale_listener: - class: Wallabag\CoreBundle\Event\Listener\UserLocaleListener - arguments: ["@session"] + Wallabag\CoreBundle\Event\Listener\UserLocaleListener: tags: - { name: kernel.event_listener, event: security.interactive_login, method: onInteractiveLogin } @@ -42,6 +115,148 @@ services: class: Symfony\Component\Cache\Adapter\FilesystemAdapter public: false arguments: - - 'craue_config' - - 0 - - '%kernel.cache_dir%' + $namespace: 'craue_config' + $defaultLifetime: 0 + $directory: '%kernel.cache_dir%' + + Wallabag\CoreBundle\ParamConverter\UsernameFeedTokenConverter: + tags: + - { name: request.param_converter, converter: username_feed_token_converter } + + Wallabag\CoreBundle\Event\Subscriber\TablePrefixSubscriber: + tags: + - { name: doctrine.event_subscriber } + + Graby\Graby: + arguments: + $config: + error_message: '%wallabag_core.fetching_error_message%' + error_message_title: '%wallabag_core.fetching_error_message_title%' + calls: + - [ setLogger, [ "@logger" ] ] + tags: + - { name: monolog.logger, channel: graby } + + Graby\SiteConfig\ConfigBuilder: + arguments: + $config: {} + + wallabag_core.http_client: + alias: 'httplug.client.wallabag_core' + + Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder: + tags: + - { name: monolog.logger, channel: graby } + + # service alias override + bd_guzzle_site_authenticator.site_config_builder: + alias: Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder + + Wallabag\CoreBundle\Helper\HttpClientFactory: + calls: + - ["addSubscriber", ["@bd_guzzle_site_authenticator.authenticator_subscriber"]] + + Wallabag\CoreBundle\Operator\PHP\Matches: + tags: + - { name: rulerz.operator, target: native, operator: matches } + + Wallabag\CoreBundle\Operator\Doctrine\Matches: + tags: + - { name: rulerz.operator, target: doctrine, operator: matches, inline: true } + + Wallabag\CoreBundle\Operator\PHP\NotMatches: + tags: + - { name: rulerz.operator, target: native, operator: notmatches } + + Wallabag\CoreBundle\Operator\Doctrine\NotMatches: + tags: + - { name: rulerz.operator, target: doctrine, operator: notmatches, inline: true } + + Wallabag\CoreBundle\Operator\PHP\PatternMatches: + tags: + - { name: rulerz.operator, target: native, operator: "~" } + + Predis\Client: + arguments: + $parameters: + scheme: '%redis_scheme%' + host: '%redis_host%' + port: '%redis_port%' + path: '%redis_path%' + password: '%redis_password%' + + Wallabag\CoreBundle\Controller\ExceptionController: ~ + + Wallabag\CoreBundle\Event\Subscriber\SQLiteCascadeDeleteSubscriber: + tags: + - { name: doctrine.event_subscriber } + + Wallabag\CoreBundle\Event\Subscriber\DownloadImagesSubscriber: + arguments: + $enabled: '@=service(''craue_config'').get(''download_images_enabled'')' + + Wallabag\CoreBundle\Helper\DownloadImages: + arguments: + $baseFolder: "%kernel.project_dir%/web/assets/images" + + wallabag_core.entry.download_images.client: + alias: 'httplug.client.wallabag_core.entry.download_images' + + Wallabag\UserBundle\EventListener\CreateConfigListener: + arguments: + $theme: "%wallabag_core.theme%" + $itemsOnPage: "%wallabag_core.items_on_page%" + $feedLimit: "%wallabag_core.feed_limit%" + $language: "%wallabag_core.language%" + $readingSpeed: "%wallabag_core.reading_speed%" + $actionMarkAsRead: "%wallabag_core.action_mark_as_read%" + $listMode: "%wallabag_core.list_mode%" + + Wallabag\UserBundle\EventListener\AuthenticationFailureListener: + tags: + - { name: kernel.event_listener, event: security.authentication.failure, method: onAuthenticationFailure } + + wallabag_import.pocket.client: + alias: 'httplug.client.wallabag_import.pocket.client' + + Wallabag\ImportBundle\Import\PocketImport: + calls: + - [ setClient, [ "@wallabag_import.pocket.client" ] ] + tags: + - { name: wallabag_import.import, alias: pocket } + + Wallabag\ImportBundle\Import\WallabagV1Import: + tags: + - { name: wallabag_import.import, alias: wallabag_v1 } + + Wallabag\ImportBundle\Import\WallabagV2Import: + tags: + - { name: wallabag_import.import, alias: wallabag_v2 } + + Wallabag\ImportBundle\Import\ElcuratorImport: + tags: + - { name: wallabag_import.import, alias: elcurator } + + Wallabag\ImportBundle\Import\ReadabilityImport: + tags: + - { name: wallabag_import.import, alias: readability } + + Wallabag\ImportBundle\Import\InstapaperImport: + tags: + - { name: wallabag_import.import, alias: instapaper } + + Wallabag\ImportBundle\Import\PinboardImport: + tags: + - { name: wallabag_import.import, alias: pinboard } + + Wallabag\ImportBundle\Import\DeliciousImport: + tags: + - { name: wallabag_import.import, alias: delicious } + + Wallabag\ImportBundle\Import\FirefoxImport: + tags: + - { name: wallabag_import.import, alias: firefox } + + Wallabag\ImportBundle\Import\ChromeImport: + tags: + - { name: wallabag_import.import, alias: chrome } diff --git a/app/config/services_rabbit.yml b/app/config/services_rabbit.yml new file mode 100644 index 000000000..e407745d2 --- /dev/null +++ b/app/config/services_rabbit.yml @@ -0,0 +1,56 @@ +# RabbitMQ stuff +services: + _defaults: + autowire: true + autoconfigure: true + public: true + + wallabag_import.consumer.amqp.pocket: + class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer + arguments: + $import: '@Wallabag\ImportBundle\Import\PocketImport' + + wallabag_import.consumer.amqp.readability: + class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer + arguments: + $import: '@Wallabag\ImportBundle\Import\ReadabilityImport' + + wallabag_import.consumer.amqp.instapaper: + class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer + arguments: + $import: '@Wallabag\ImportBundle\Import\InstapaperImport' + + wallabag_import.consumer.amqp.pinboard: + class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer + arguments: + $import: '@Wallabag\ImportBundle\Import\PinboardImport' + + wallabag_import.consumer.amqp.delicious: + class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer + arguments: + $import: '@Wallabag\ImportBundle\Import\DeliciousImport' + + wallabag_import.consumer.amqp.wallabag_v1: + class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer + arguments: + $import: '@Wallabag\ImportBundle\Import\WallabagV1Import' + + wallabag_import.consumer.amqp.wallabag_v2: + class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer + arguments: + $import: '@Wallabag\ImportBundle\Import\WallabagV2Import' + + wallabag_import.consumer.amqp.elcurator: + class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer + arguments: + $import: '@Wallabag\ImportBundle\Import\ElcuratorImport' + + wallabag_import.consumer.amqp.firefox: + class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer + arguments: + $import: '@Wallabag\ImportBundle\Import\FirefoxImport' + + wallabag_import.consumer.amqp.chrome: + class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer + arguments: + $import: '@Wallabag\ImportBundle\Import\ChromeImport' diff --git a/src/Wallabag/ImportBundle/Resources/config/redis.yml b/app/config/services_redis.yml similarity index 59% rename from src/Wallabag/ImportBundle/Resources/config/redis.yml rename to app/config/services_redis.yml index 893778c03..02c7eba95 100644 --- a/src/Wallabag/ImportBundle/Resources/config/redis.yml +++ b/app/config/services_redis.yml @@ -1,11 +1,15 @@ # Redis stuff services: + _defaults: + autowire: true + autoconfigure: true + public: true + # readability wallabag_import.queue.redis.readability: class: Simpleue\Queue\RedisQueue arguments: - - "@wallabag_core.redis.client" - - "wallabag.import.readability" + $queueName: "wallabag.import.readability" wallabag_import.producer.redis.readability: class: Wallabag\ImportBundle\Redis\Producer @@ -15,18 +19,13 @@ services: wallabag_import.consumer.redis.readability: class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.readability.import" - - "@event_dispatcher" - - "@logger" + $import: '@Wallabag\ImportBundle\Import\ReadabilityImport' # instapaper wallabag_import.queue.redis.instapaper: class: Simpleue\Queue\RedisQueue arguments: - - "@wallabag_core.redis.client" - - "wallabag.import.instapaper" + $queueName: "wallabag.import.instapaper" wallabag_import.producer.redis.instapaper: class: Wallabag\ImportBundle\Redis\Producer @@ -36,18 +35,13 @@ services: wallabag_import.consumer.redis.instapaper: class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.instapaper.import" - - "@event_dispatcher" - - "@logger" + $import: '@Wallabag\ImportBundle\Import\InstapaperImport' # pinboard wallabag_import.queue.redis.pinboard: class: Simpleue\Queue\RedisQueue arguments: - - "@wallabag_core.redis.client" - - "wallabag.import.pinboard" + $queueName: "wallabag.import.pinboard" wallabag_import.producer.redis.pinboard: class: Wallabag\ImportBundle\Redis\Producer @@ -57,18 +51,13 @@ services: wallabag_import.consumer.redis.pinboard: class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.pinboard.import" - - "@event_dispatcher" - - "@logger" + $import: '@Wallabag\ImportBundle\Import\PinboardImport' # delicious wallabag_import.queue.redis.delicious: class: Simpleue\Queue\RedisQueue arguments: - - "@wallabag_core.redis.client" - - "wallabag.import.delicious" + $queueName: "wallabag.import.delicious" wallabag_import.producer.redis.delicious: class: Wallabag\ImportBundle\Redis\Producer @@ -78,18 +67,13 @@ services: wallabag_import.consumer.redis.delicious: class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.delicious.import" - - "@event_dispatcher" - - "@logger" + $import: '@Wallabag\ImportBundle\Import\DeliciousImport' # pocket wallabag_import.queue.redis.pocket: class: Simpleue\Queue\RedisQueue arguments: - - "@wallabag_core.redis.client" - - "wallabag.import.pocket" + $queueName: "wallabag.import.pocket" wallabag_import.producer.redis.pocket: class: Wallabag\ImportBundle\Redis\Producer @@ -99,18 +83,13 @@ services: wallabag_import.consumer.redis.pocket: class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.pocket.import" - - "@event_dispatcher" - - "@logger" + $import: '@Wallabag\ImportBundle\Import\PocketImport' # wallabag v1 wallabag_import.queue.redis.wallabag_v1: class: Simpleue\Queue\RedisQueue arguments: - - "@wallabag_core.redis.client" - - "wallabag.import.wallabag_v1" + $queueName: "wallabag.import.wallabag_v1" wallabag_import.producer.redis.wallabag_v1: class: Wallabag\ImportBundle\Redis\Producer @@ -120,18 +99,13 @@ services: wallabag_import.consumer.redis.wallabag_v1: class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.wallabag_v1.import" - - "@event_dispatcher" - - "@logger" + $import: '@Wallabag\ImportBundle\Import\WallabagV1Import' # wallabag v2 wallabag_import.queue.redis.wallabag_v2: class: Simpleue\Queue\RedisQueue arguments: - - "@wallabag_core.redis.client" - - "wallabag.import.wallabag_v2" + $queueName: "wallabag.import.wallabag_v2" wallabag_import.producer.redis.wallabag_v2: class: Wallabag\ImportBundle\Redis\Producer @@ -141,18 +115,13 @@ services: wallabag_import.consumer.redis.wallabag_v2: class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.wallabag_v2.import" - - "@event_dispatcher" - - "@logger" + $import: '@Wallabag\ImportBundle\Import\WallabagV2Import' # elcurator wallabag_import.queue.redis.elcurator: class: Simpleue\Queue\RedisQueue arguments: - - "@wallabag_core.redis.client" - - "wallabag.import.elcurator" + $queueName: "wallabag.import.elcurator" wallabag_import.producer.redis.elcurator: class: Wallabag\ImportBundle\Redis\Producer @@ -162,18 +131,13 @@ services: wallabag_import.consumer.redis.elcurator: class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.elcurator.import" - - "@event_dispatcher" - - "@logger" + $import: '@Wallabag\ImportBundle\Import\ElcuratorImport' # firefox wallabag_import.queue.redis.firefox: class: Simpleue\Queue\RedisQueue arguments: - - "@wallabag_core.redis.client" - - "wallabag.import.firefox" + $queueName: "wallabag.import.firefox" wallabag_import.producer.redis.firefox: class: Wallabag\ImportBundle\Redis\Producer @@ -183,18 +147,13 @@ services: wallabag_import.consumer.redis.firefox: class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.firefox.import" - - "@event_dispatcher" - - "@logger" + $import: '@Wallabag\ImportBundle\Import\FirefoxImport' # chrome wallabag_import.queue.redis.chrome: class: Simpleue\Queue\RedisQueue arguments: - - "@wallabag_core.redis.client" - - "wallabag.import.chrome" + $queueName: "wallabag.import.chrome" wallabag_import.producer.redis.chrome: class: Wallabag\ImportBundle\Redis\Producer @@ -204,8 +163,4 @@ services: wallabag_import.consumer.redis.chrome: class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.chrome.import" - - "@event_dispatcher" - - "@logger" + $import: '@Wallabag\ImportBundle\Import\ChromeImport' diff --git a/app/config/services_test.yml b/app/config/services_test.yml index 1b3aff63e..5073b64b9 100644 --- a/app/config/services_test.yml +++ b/app/config/services_test.yml @@ -9,11 +9,11 @@ services: public: true wallabag_core.entry_repository.test: - alias: wallabag_core.entry_repository + alias: Wallabag\CoreBundle\Repository\EntryRepository public: true wallabag_user.user_repository.test: - alias: wallabag_user.user_repository + alias: Wallabag\UserBundle\Repository\UserRepository public: true filesystem_cache: diff --git a/app/config/wallabag.yml b/app/config/wallabag.yml index 210c63e76..46977235e 100644 --- a/app/config/wallabag.yml +++ b/app/config/wallabag.yml @@ -41,10 +41,6 @@ wallabag_core: name: share_public value: 1 section: entry - - - name: carrot - value: 1 - section: entry - name: share_diaspora value: 1 @@ -65,18 +61,10 @@ wallabag_core: name: share_shaarli value: 1 section: entry - - - name: share_scuttle - value: 1 - section: entry - name: shaarli_url value: https://myshaarli.com section: entry - - - name: scuttle_url - value: https://scuttle.org - section: entry - name: share_mail value: 1 @@ -178,9 +166,6 @@ wallabag_core: - rule: _all ~ "https?://www\.lemonde\.fr/tiny.*" -wallabag_user: - registration_enabled: "%fosuser_registration%" - wallabag_import: allow_mimetypes: ['application/octet-stream', 'application/json', 'text/plain', 'text/csv'] resource_dir: "%kernel.project_dir%/web/uploads/import" diff --git a/app/config/webpack/common.js b/app/config/webpack/common.js index ebca21009..cc16bafc3 100644 --- a/app/config/webpack/common.js +++ b/app/config/webpack/common.js @@ -7,7 +7,6 @@ const rootDir = path.resolve(__dirname, '../../../'); module.exports = { entry: { material: path.join(rootDir, './app/Resources/static/themes/material/index.js'), - baggy: path.join(rootDir, './app/Resources/static/themes/baggy/index.js'), public: path.join(rootDir, './app/Resources/static/themes/_global/share.js'), }, output: { diff --git a/bin/symfony_requirements b/bin/symfony_requirements deleted file mode 100755 index a7bf65a1b..000000000 --- a/bin/symfony_requirements +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env php -getPhpIniConfigPath(); - -echo_title('Symfony Requirements Checker'); - -echo '> PHP is using the following php.ini file:'.PHP_EOL; -if ($iniPath) { - echo_style('green', ' '.$iniPath); -} else { - echo_style('yellow', ' WARNING: No configuration file (php.ini) used by PHP!'); -} - -echo PHP_EOL.PHP_EOL; - -echo '> Checking Symfony requirements:'.PHP_EOL.' '; - -$messages = array(); -foreach ($symfonyRequirements->getRequirements() as $req) { - if ($helpText = get_error_message($req, $lineSize)) { - echo_style('red', 'E'); - $messages['error'][] = $helpText; - } else { - echo_style('green', '.'); - } -} - -$checkPassed = empty($messages['error']); - -foreach ($symfonyRequirements->getRecommendations() as $req) { - if ($helpText = get_error_message($req, $lineSize)) { - echo_style('yellow', 'W'); - $messages['warning'][] = $helpText; - } else { - echo_style('green', '.'); - } -} - -if ($checkPassed) { - echo_block('success', 'OK', 'Your system is ready to run Symfony projects'); -} else { - echo_block('error', 'ERROR', 'Your system is not ready to run Symfony projects'); - - echo_title('Fix the following mandatory requirements', 'red'); - - foreach ($messages['error'] as $helpText) { - echo ' * '.$helpText.PHP_EOL; - } -} - -if (!empty($messages['warning'])) { - echo_title('Optional recommendations to improve your setup', 'yellow'); - - foreach ($messages['warning'] as $helpText) { - echo ' * '.$helpText.PHP_EOL; - } -} - -echo PHP_EOL; -echo_style('title', 'Note'); -echo ' The command console could use a different php.ini file'.PHP_EOL; -echo_style('title', '~~~~'); -echo ' than the one used with your web server. To be on the'.PHP_EOL; -echo ' safe side, please check the requirements from your web'.PHP_EOL; -echo ' server using the '; -echo_style('yellow', 'web/config.php'); -echo ' script.'.PHP_EOL; -echo PHP_EOL; - -exit($checkPassed ? 0 : 1); - -function get_error_message(Requirement $requirement, $lineSize) -{ - if ($requirement->isFulfilled()) { - return; - } - - $errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL; - $errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL; - - return $errorMessage; -} - -function echo_title($title, $style = null) -{ - $style = $style ?: 'title'; - - echo PHP_EOL; - echo_style($style, $title.PHP_EOL); - echo_style($style, str_repeat('~', strlen($title)).PHP_EOL); - echo PHP_EOL; -} - -function echo_style($style, $message) -{ - // ANSI color codes - $styles = array( - 'reset' => "\033[0m", - 'red' => "\033[31m", - 'green' => "\033[32m", - 'yellow' => "\033[33m", - 'error' => "\033[37;41m", - 'success' => "\033[37;42m", - 'title' => "\033[34m", - ); - $supports = has_color_support(); - - echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : ''); -} - -function echo_block($style, $title, $message) -{ - $message = ' '.trim($message).' '; - $width = strlen($message); - - echo PHP_EOL.PHP_EOL; - - echo_style($style, str_repeat(' ', $width)); - echo PHP_EOL; - echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT)); - echo PHP_EOL; - echo_style($style, $message); - echo PHP_EOL; - echo_style($style, str_repeat(' ', $width)); - echo PHP_EOL; -} - -function has_color_support() -{ - static $support; - - if (null === $support) { - if (DIRECTORY_SEPARATOR == '\\') { - $support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'); - } else { - $support = function_exists('posix_isatty') && @posix_isatty(STDOUT); - } - } - - return $support; -} diff --git a/composer.json b/composer.json index 72f2fd76e..36d1b6739 100644 --- a/composer.json +++ b/composer.json @@ -37,6 +37,7 @@ "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", + "ext-filter": "*", "ext-gd": "*", "ext-hash": "*", "ext-iconv": "*", @@ -50,26 +51,34 @@ "ext-tidy": "*", "ext-tokenizer": "*", "ext-xml": "*", - "composer": "< 2.3", "babdev/pagerfanta-bundle": "^2.5", "bdunogier/guzzle-site-authenticator": "^1.0.0", "craue/config-bundle": "^2.3.0", "defuse/php-encryption": "^2.1", + "doctrine/collections": "^1.6", + "doctrine/common": "^2.13", + "doctrine/dbal": "^2.13", "doctrine/doctrine-bundle": "^1.9", "doctrine/doctrine-cache-bundle": "^1.3", "doctrine/doctrine-migrations-bundle": "^1.3", + "doctrine/event-manager": "^1.1", + "doctrine/migrations": "^1.8", "doctrine/orm": "^2.6", + "doctrine/persistence": "^1.3", "enshrined/svg-sanitize": "^0.15.4", "friendsofsymfony/jsrouting-bundle": "^2.2", "friendsofsymfony/oauth-server-bundle": "^1.5", "friendsofsymfony/rest-bundle": "~2.1", - "friendsofsymfony/user-bundle": "2.0.*", + "friendsofsymfony/user-bundle": "2.1.*", "guzzlehttp/guzzle": "^5.3.1", + "guzzlehttp/psr7": "^1.8", "html2text/html2text": "^4.1", "incenteev/composer-parameter-handler": "^2.1", "j0k3r/graby": "^2.0", "javibravo/simpleue": "^2.0", + "jms/serializer": "^3.17", "jms/serializer-bundle": "~3.6", + "kphoen/rulerz": "^0.21", "kphoen/rulerz-bundle": "~0.13", "laminas/laminas-code": "^3.4", "laminas/laminas-diactoros": "^2.3", @@ -81,31 +90,41 @@ "nelmio/cors-bundle": "~1.5", "ocramius/proxy-manager": "^2.1.1", "pagerfanta/pagerfanta": "^2.4", + "php-amqplib/php-amqplib": "^2.12", "php-amqplib/rabbitmq-bundle": "^1.14", + "php-http/client-common": "^2.4", + "php-http/discovery": "^1.14", "php-http/guzzle5-adapter": "^2.0", + "php-http/httplug": "^2.3", "php-http/httplug-bundle": "^1.14", + "php-http/message": "^1.13", + "php-http/message-factory": "^1.0", "pragmarx/recovery": "^0.2.0", "predis/predis": "^1.1.3", + "psr/http-message": "^1.0", + "psr/log": "^1.1", "scheb/two-factor-bundle": "^4.11.0", - "sensio/distribution-bundle": "^5.0", "sensio/framework-extra-bundle": "^5.2", "sentry/sentry-symfony": "3.5.3", "stof/doctrine-extensions-bundle": "^1.2", + "swiftmailer/swiftmailer": "^6.3", "symfony/dom-crawler": "^3.4", "symfony/monolog-bundle": "^3.1", "symfony/swiftmailer-bundle": "^3.2", "symfony/symfony": "3.4.*", "tecnickcom/tcpdf": "^6.3.0", "twig/extensions": "^1.5", + "twig/twig": "^2.15", "wallabag/php-mobi": "~1.0", "wallabag/phpepub": "^4.0.10", + "willdurand/hateoas": "^3.8", "willdurand/hateoas-bundle": "~2.1" }, "require-dev": { "dama/doctrine-test-bundle": "^6.0", "doctrine/doctrine-fixtures-bundle": "~3.0", "friendsofphp/php-cs-fixer": "~2.13", - "guzzlehttp/psr7": "^1.0", + "friendsoftwig/twigcs": "^4.1", "m6web/redis-mock": "^5.0", "php-http/mock-client": "^1.0", "phpstan/extension-installer": "^1.0", @@ -122,10 +141,8 @@ "scripts": { "post-cmd": [ "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", - "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", - "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", - "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", - "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" + "bin/console cache:clear --no-warmup", + "bin/console assets:install web --symlink --relative" ], "post-install-cmd": [ "@post-cmd" @@ -135,12 +152,6 @@ ] }, "extra": { - "symfony-app-dir": "app", - "symfony-bin-dir": "bin", - "symfony-var-dir": "var", - "symfony-web-dir": "web", - "symfony-tests-dir": "tests", - "symfony-assets-install": "relative", "incenteev-parameters": { "file": "app/config/parameters.yml" } diff --git a/composer.lock b/composer.lock index 0a4605dc2..efc69dc87 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5aec7c6af1a3c05510db2e1243da8db5", + "content-hash": "e01063964db1acb5dd93d6d0a8d309d8", "packages": [ { "name": "babdev/pagerfanta-bundle", @@ -2549,26 +2549,27 @@ }, { "name": "friendsofsymfony/user-bundle", - "version": "v2.0.2", + "version": "v2.1.2", "source": { "type": "git", "url": "https://github.com/FriendsOfSymfony/FOSUserBundle.git", - "reference": "2fc8a023d7ab482321cf7ec810ed49eab40eb50f" + "reference": "1049935edd24ec305cc6cfde1875372fa9600446" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfSymfony/FOSUserBundle/zipball/2fc8a023d7ab482321cf7ec810ed49eab40eb50f", - "reference": "2fc8a023d7ab482321cf7ec810ed49eab40eb50f", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSUserBundle/zipball/1049935edd24ec305cc6cfde1875372fa9600446", + "reference": "1049935edd24ec305cc6cfde1875372fa9600446", "shasum": "" }, "require": { "paragonie/random_compat": "^1 || ^2", "php": "^5.5.9 || ^7.0", - "symfony/form": "^2.7 || ^3.0", - "symfony/framework-bundle": "^2.7 || ^3.0", - "symfony/security-bundle": "^2.7 || ^3.0", - "symfony/templating": "^2.7 || ^3.0", - "symfony/twig-bundle": "^2.7 || ^3.0", + "symfony/form": "^2.8 || ^3.0 || ^4.0", + "symfony/framework-bundle": "^2.8 || ^3.0 || ^4.0", + "symfony/security-bundle": "^2.8 || ^3.0 || ^4.0", + "symfony/templating": "^2.8 || ^3.0 || ^4.0", + "symfony/twig-bundle": "^2.8 || ^3.0 || ^4.0", + "symfony/validator": "^2.8 || ^3.0 || ^4.0", "twig/twig": "^1.28 || ^2.0" }, "conflict": { @@ -2577,18 +2578,17 @@ }, "require-dev": { "doctrine/doctrine-bundle": "^1.3", - "friendsofphp/php-cs-fixer": "^1.11", - "phpunit/phpunit": "~4.8|~5.0", + "friendsofphp/php-cs-fixer": "^2.2", + "phpunit/phpunit": "^4.8.35|^5.7.11|^6.5", "swiftmailer/swiftmailer": "^4.3 || ^5.0 || ^6.0", - "symfony/console": "^2.7 || ^3.0", - "symfony/phpunit-bridge": "^2.7 || ^3.0", - "symfony/validator": "^2.7 || ^3.0", - "symfony/yaml": "^2.7 || ^3.0" + "symfony/console": "^2.8 || ^3.0 || ^4.0", + "symfony/phpunit-bridge": "^2.8 || ^3.0 || ^4.0", + "symfony/yaml": "^2.8 || ^3.0 || ^4.0" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "2.1.x-dev" } }, "autoload": { @@ -2613,8 +2613,7 @@ "homepage": "https://github.com/friendsofsymfony/FOSUserBundle/contributors" }, { - "name": "Thibault Duplessis", - "email": "thibault.duplessis@gmail.com" + "name": "Thibault Duplessis" } ], "description": "Symfony FOSUserBundle", @@ -2625,9 +2624,9 @@ "support": { "docs": "https://symfony.com/doc/master/bundles/FOSUserBundle/index.html", "issues": "https://github.com/FriendsOfSymfony/FOSUserBundle/issues", - "source": "https://github.com/FriendsOfSymfony/FOSUserBundle/tree/2.0.x" + "source": "https://github.com/FriendsOfSymfony/FOSUserBundle/tree/v2.1.2" }, - "time": "2017-11-29T17:01:21+00:00" + "time": "2018-03-08T08:59:27+00:00" }, { "name": "gedmo/doctrine-extensions", @@ -4492,16 +4491,16 @@ }, { "name": "j0k3r/graby-site-config", - "version": "1.0.158", + "version": "1.0.159", "source": { "type": "git", "url": "https://github.com/j0k3r/graby-site-config.git", - "reference": "980c2aadf60f067f5eae34d10d3b194a91434394" + "reference": "e5bfb9d608f0ce6390d6791ede196c769216ee84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/j0k3r/graby-site-config/zipball/980c2aadf60f067f5eae34d10d3b194a91434394", - "reference": "980c2aadf60f067f5eae34d10d3b194a91434394", + "url": "https://api.github.com/repos/j0k3r/graby-site-config/zipball/e5bfb9d608f0ce6390d6791ede196c769216ee84", + "reference": "e5bfb9d608f0ce6390d6791ede196c769216ee84", "shasum": "" }, "require": { @@ -4530,9 +4529,9 @@ "description": "Graby site config files", "support": { "issues": "https://github.com/j0k3r/graby-site-config/issues", - "source": "https://github.com/j0k3r/graby-site-config/tree/1.0.158" + "source": "https://github.com/j0k3r/graby-site-config/tree/1.0.159" }, - "time": "2022-10-20T13:53:08+00:00" + "time": "2022-11-01T02:53:54+00:00" }, { "name": "j0k3r/httplug-ssrf-plugin", @@ -7398,16 +7397,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.16", + "version": "3.0.17", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "7181378909ed8890be4db53d289faac5b77f8b05" + "reference": "dbc2307d5c69aeb22db136c52e91130d7f2ca761" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7181378909ed8890be4db53d289faac5b77f8b05", - "reference": "7181378909ed8890be4db53d289faac5b77f8b05", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/dbc2307d5c69aeb22db136c52e91130d7f2ca761", + "reference": "dbc2307d5c69aeb22db136c52e91130d7f2ca761", "shasum": "" }, "require": { @@ -7488,7 +7487,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.16" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.17" }, "funding": [ { @@ -7504,20 +7503,20 @@ "type": "tidelift" } ], - "time": "2022-09-05T18:03:08+00:00" + "time": "2022-10-24T10:51:50+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "1.12.0", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "5f13698464773fa6f5392a9e311f81e23e9c3ba7" + "reference": "33aefcdab42900e36366d0feab6206e2dd68f947" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/5f13698464773fa6f5392a9e311f81e23e9c3ba7", - "reference": "5f13698464773fa6f5392a9e311f81e23e9c3ba7", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/33aefcdab42900e36366d0feab6206e2dd68f947", + "reference": "33aefcdab42900e36366d0feab6206e2dd68f947", "shasum": "" }, "require": { @@ -7547,9 +7546,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.12.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.13.0" }, - "time": "2022-10-20T07:49:58+00:00" + "time": "2022-10-21T09:57:39+00:00" }, { "name": "phpzip/phpzip", @@ -8421,63 +8420,6 @@ "abandoned": "scheb/2fa-bundle", "time": "2020-10-30T19:24:18+00:00" }, - { - "name": "sensio/distribution-bundle", - "version": "v5.0.25", - "source": { - "type": "git", - "url": "https://github.com/sensiolabs/SensioDistributionBundle.git", - "reference": "80a38234bde8321fb92aa0b8c27978a272bb4baf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/SensioDistributionBundle/zipball/80a38234bde8321fb92aa0b8c27978a272bb4baf", - "reference": "80a38234bde8321fb92aa0b8c27978a272bb4baf", - "shasum": "" - }, - "require": { - "php": ">=5.3.9", - "sensiolabs/security-checker": "~5.0|~6.0", - "symfony/class-loader": "~2.3|~3.0", - "symfony/config": "~2.3|~3.0", - "symfony/dependency-injection": "~2.3|~3.0", - "symfony/filesystem": "~2.3|~3.0", - "symfony/http-kernel": "~2.3|~3.0", - "symfony/process": "~2.3|~3.0" - }, - "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Sensio\\Bundle\\DistributionBundle\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Base bundle for Symfony Distributions", - "keywords": [ - "configuration", - "distribution" - ], - "support": { - "issues": "https://github.com/sensiolabs/SensioDistributionBundle/issues", - "source": "https://github.com/sensiolabs/SensioDistributionBundle/tree/master" - }, - "abandoned": true, - "time": "2019-06-18T15:43:58+00:00" - }, { "name": "sensio/framework-extra-bundle", "version": "v5.4.1", @@ -8555,59 +8497,6 @@ }, "time": "2019-07-08T08:31:25+00:00" }, - { - "name": "sensiolabs/security-checker", - "version": "v6.0.3", - "source": { - "type": "git", - "url": "https://github.com/sensiolabs/security-checker.git", - "reference": "a576c01520d9761901f269c4934ba55448be4a54" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/security-checker/zipball/a576c01520d9761901f269c4934ba55448be4a54", - "reference": "a576c01520d9761901f269c4934ba55448be4a54", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "symfony/console": "^2.8|^3.4|^4.2|^5.0", - "symfony/http-client": "^4.3|^5.0", - "symfony/mime": "^4.3|^5.0", - "symfony/polyfill-ctype": "^1.11" - }, - "bin": [ - "security-checker" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.0-dev" - } - }, - "autoload": { - "psr-4": { - "SensioLabs\\Security\\": "SensioLabs/Security" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien.potencier@gmail.com" - } - ], - "description": "A security checker for your composer.lock", - "support": { - "issues": "https://github.com/sensiolabs/security-checker/issues", - "source": "https://github.com/sensiolabs/security-checker/tree/master" - }, - "abandoned": "https://github.com/fabpot/local-php-security-checker", - "time": "2019-11-01T13:20:14+00:00" - }, { "name": "sentry/sdk", "version": "2.2.0", @@ -9277,16 +9166,16 @@ }, { "name": "symfony/http-client", - "version": "v5.4.14", + "version": "v5.4.15", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "8a3929c814cba77db93de61c22759e0dbeaa4c87" + "reference": "8f29b0f06c9ff48c8431e78eb90c8bd6f82cb12b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/8a3929c814cba77db93de61c22759e0dbeaa4c87", - "reference": "8a3929c814cba77db93de61c22759e0dbeaa4c87", + "url": "https://api.github.com/repos/symfony/http-client/zipball/8f29b0f06c9ff48c8431e78eb90c8bd6f82cb12b", + "reference": "8f29b0f06c9ff48c8431e78eb90c8bd6f82cb12b", "shasum": "" }, "require": { @@ -9344,7 +9233,7 @@ "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-client/tree/v5.4.14" + "source": "https://github.com/symfony/http-client/tree/v5.4.15" }, "funding": [ { @@ -9360,7 +9249,7 @@ "type": "tidelift" } ], - "time": "2022-10-11T15:16:01+00:00" + "time": "2022-10-25T16:22:13+00:00" }, { "name": "symfony/http-client-contracts", @@ -9440,89 +9329,6 @@ ], "time": "2022-04-12T15:48:08+00:00" }, - { - "name": "symfony/mime", - "version": "v5.4.13", - "source": { - "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "bb2ccf759e2b967dcd11bdee5bdf30dddd2290bd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/bb2ccf759e2b967dcd11bdee5bdf30dddd2290bd", - "reference": "bb2ccf759e2b967dcd11bdee5bdf30dddd2290bd", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "egulias/email-validator": "~3.0.0", - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<4.4" - }, - "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/property-access": "^4.4|^5.1|^6.0", - "symfony/property-info": "^4.4|^5.1|^6.0", - "symfony/serializer": "^5.2|^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Mime\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Allows manipulating MIME messages", - "homepage": "https://symfony.com", - "keywords": [ - "mime", - "mime-type" - ], - "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.13" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-09-01T18:18:29+00:00" - }, { "name": "symfony/monolog-bundle", "version": "v3.6.0", @@ -12337,6 +12143,55 @@ ], "time": "2021-11-15T17:17:55+00:00" }, + { + "name": "friendsoftwig/twigcs", + "version": "v4.1.0", + "source": { + "type": "git", + "url": "https://github.com/friendsoftwig/twigcs.git", + "reference": "ad7e235fe3cc7842b5919f109afaacc56bb3ff49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/friendsoftwig/twigcs/zipball/ad7e235fe3cc7842b5919f109afaacc56bb3ff49", + "reference": "ad7e235fe3cc7842b5919f109afaacc56bb3ff49", + "shasum": "" + }, + "require": { + "php": "^7.0", + "symfony/console": "^3.4 || ^4.3 || ^5.0", + "symfony/filesystem": "^3.4 || ^4.3 || ^5.0", + "symfony/finder": "^3.4 || ^4.3 || ^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.2" + }, + "bin": [ + "bin/twigcs" + ], + "type": "library", + "autoload": { + "psr-4": { + "FriendsOfTwig\\Twigcs\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tristan Maindron", + "email": "tmaindron@gmail.com" + } + ], + "description": "Checkstyle automation for Twig", + "support": { + "issues": "https://github.com/friendsoftwig/twigcs/issues", + "source": "https://github.com/friendsoftwig/twigcs/tree/v4.1.0" + }, + "time": "2021-02-04T13:07:32+00:00" + }, { "name": "m6web/redis-mock", "version": "v5.3.0", @@ -12613,16 +12468,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.99", + "version": "0.12.100", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "b4d40f1d759942f523be267a1bab6884f46ca3f7" + "reference": "48236ddf823547081b2b153d1cd2994b784328c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/b4d40f1d759942f523be267a1bab6884f46ca3f7", - "reference": "b4d40f1d759942f523be267a1bab6884f46ca3f7", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/48236ddf823547081b2b153d1cd2994b784328c3", + "reference": "48236ddf823547081b2b153d1cd2994b784328c3", "shasum": "" }, "require": { @@ -12653,7 +12508,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/0.12.99" + "source": "https://github.com/phpstan/phpstan/tree/0.12.100" }, "funding": [ { @@ -12664,16 +12519,12 @@ "url": "https://github.com/phpstan", "type": "github" }, - { - "url": "https://www.patreon.com/phpstan", - "type": "patreon" - }, { "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", "type": "tidelift" } ], - "time": "2021-09-12T20:09:55+00:00" + "time": "2022-11-01T09:52:08+00:00" }, { "name": "phpstan/phpstan-doctrine", @@ -13048,6 +12899,7 @@ "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", + "ext-filter": "*", "ext-gd": "*", "ext-hash": "*", "ext-iconv": "*", @@ -13060,12 +12912,11 @@ "ext-simplexml": "*", "ext-tidy": "*", "ext-tokenizer": "*", - "ext-xml": "*", - "composer": "< 2.3" + "ext-xml": "*" }, "platform-dev": [], "platform-overrides": { "php": "7.4.29" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.3.0" } diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile index 67488d1fd..c22237266 100644 --- a/docker/php/Dockerfile +++ b/docker/php/Dockerfile @@ -65,7 +65,7 @@ RUN npm install -g yarn RUN curl -L -o /usr/local/bin/envsubst https://github.com/a8m/envsubst/releases/download/v1.1.0/envsubst-`uname -s`-`uname -m`; \ chmod +x /usr/local/bin/envsubst -COPY --from=composer:2.2.12 /usr/bin/composer /usr/local/bin/composer +COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer COPY entrypoint.sh /entrypoint.sh COPY config/ /opt/wallabag/config/ diff --git a/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php b/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php index 883ce4a89..4bf51b5f2 100644 --- a/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php +++ b/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php @@ -2,8 +2,10 @@ namespace Wallabag\AnnotationBundle\Controller; -use FOS\RestBundle\Controller\FOSRestController; +use FOS\RestBundle\Controller\AbstractFOSRestController; +use JMS\Serializer\SerializerInterface; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; +use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Wallabag\AnnotationBundle\Entity\Annotation; @@ -11,7 +13,7 @@ use Wallabag\AnnotationBundle\Form\EditAnnotationType; use Wallabag\AnnotationBundle\Form\NewAnnotationType; use Wallabag\CoreBundle\Entity\Entry; -class WallabagAnnotationController extends FOSRestController +class WallabagAnnotationController extends AbstractFOSRestController { /** * Retrieve annotations for an entry. @@ -24,12 +26,12 @@ class WallabagAnnotationController extends FOSRestController { $annotationRows = $this ->getDoctrine() - ->getRepository('WallabagAnnotationBundle:Annotation') + ->getRepository(Annotation::class) ->findAnnotationsByPageId($entry->getId(), $this->getUser()->getId()); $total = \count($annotationRows); $annotations = ['total' => $total, 'rows' => $annotationRows]; - $json = $this->get('jms_serializer')->serialize($annotations, 'json'); + $json = $this->get(SerializerInterface::class)->serialize($annotations, 'json'); return (new JsonResponse())->setJson($json); } @@ -49,7 +51,7 @@ class WallabagAnnotationController extends FOSRestController $annotation = new Annotation($this->getUser()); $annotation->setEntry($entry); - $form = $this->get('form.factory')->createNamed('', NewAnnotationType::class, $annotation, [ + $form = $this->get(FormFactoryInterface::class)->createNamed('', NewAnnotationType::class, $annotation, [ 'csrf_protection' => false, 'allow_extra_fields' => true, ]); @@ -59,7 +61,7 @@ class WallabagAnnotationController extends FOSRestController $em->persist($annotation); $em->flush(); - $json = $this->get('jms_serializer')->serialize($annotation, 'json'); + $json = $this->get(SerializerInterface::class)->serialize($annotation, 'json'); return JsonResponse::fromJsonString($json); } @@ -72,7 +74,7 @@ class WallabagAnnotationController extends FOSRestController * * @see Wallabag\ApiBundle\Controller\WallabagRestController * - * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") + * @ParamConverter("annotation", class="Wallabag\AnnotationBundle\Entity\Annotation") * * @return JsonResponse */ @@ -80,7 +82,7 @@ class WallabagAnnotationController extends FOSRestController { $data = json_decode($request->getContent(), true); - $form = $this->get('form.factory')->createNamed('', EditAnnotationType::class, $annotation, [ + $form = $this->get(FormFactoryInterface::class)->createNamed('', EditAnnotationType::class, $annotation, [ 'csrf_protection' => false, 'allow_extra_fields' => true, ]); @@ -91,7 +93,7 @@ class WallabagAnnotationController extends FOSRestController $em->persist($annotation); $em->flush(); - $json = $this->get('jms_serializer')->serialize($annotation, 'json'); + $json = $this->get(SerializerInterface::class)->serialize($annotation, 'json'); return JsonResponse::fromJsonString($json); } @@ -104,7 +106,7 @@ class WallabagAnnotationController extends FOSRestController * * @see Wallabag\ApiBundle\Controller\WallabagRestController * - * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") + * @ParamConverter("annotation", class="Wallabag\AnnotationBundle\Entity\Annotation") * * @return JsonResponse */ @@ -114,7 +116,7 @@ class WallabagAnnotationController extends FOSRestController $em->remove($annotation); $em->flush(); - $json = $this->get('jms_serializer')->serialize($annotation, 'json'); + $json = $this->get(SerializerInterface::class)->serialize($annotation, 'json'); return (new JsonResponse())->setJson($json); } diff --git a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php index 0de5c934e..59c17e447 100644 --- a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php +++ b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php @@ -2,15 +2,21 @@ namespace Wallabag\AnnotationBundle\Repository; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\QueryBuilder; +use Doctrine\Persistence\ManagerRegistry; use Wallabag\AnnotationBundle\Entity\Annotation; /** * AnnotationRepository. */ -class AnnotationRepository extends EntityRepository +class AnnotationRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Annotation::class); + } + /** * Retrieves all annotations for a user. * diff --git a/src/Wallabag/AnnotationBundle/Resources/config/routing_annotations.yml b/src/Wallabag/AnnotationBundle/Resources/config/routing_annotations.yml index 4f3a5c93b..ba076b9f4 100644 --- a/src/Wallabag/AnnotationBundle/Resources/config/routing_annotations.yml +++ b/src/Wallabag/AnnotationBundle/Resources/config/routing_annotations.yml @@ -1,4 +1,4 @@ annotations: type: rest - resource: "WallabagAnnotationBundle:WallabagAnnotation" - name_prefix: annotations_ + resource: 'Wallabag\AnnotationBundle\Controller\WallabagAnnotationController' + name_prefix: annotations_ diff --git a/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php b/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php index 66693189a..58c942d40 100644 --- a/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php +++ b/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php @@ -26,7 +26,7 @@ class AnnotationRestController extends WallabagRestController { $this->validateAuthentication(); - return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:getAnnotations', [ + return $this->forward('Wallabag\AnnotationBundle\Controller\WallabagAnnotationController::getAnnotationsAction', [ 'entry' => $entry, ]); } @@ -48,7 +48,7 @@ class AnnotationRestController extends WallabagRestController { $this->validateAuthentication(); - return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:postAnnotation', [ + return $this->forward('Wallabag\AnnotationBundle\Controller\WallabagAnnotationController::postAnnotationAction', [ 'request' => $request, 'entry' => $entry, ]); @@ -63,7 +63,7 @@ class AnnotationRestController extends WallabagRestController * } * ) * - * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") + * @ParamConverter("annotation", class="Wallabag\AnnotationBundle\Entity\Annotation") * * @return JsonResponse */ @@ -71,7 +71,7 @@ class AnnotationRestController extends WallabagRestController { $this->validateAuthentication(); - return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:putAnnotation', [ + return $this->forward('Wallabag\AnnotationBundle\Controller\WallabagAnnotationController::putAnnotationAction', [ 'annotation' => $annotation, 'request' => $request, ]); @@ -86,7 +86,7 @@ class AnnotationRestController extends WallabagRestController * } * ) * - * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") + * @ParamConverter("annotation", class="Wallabag\AnnotationBundle\Entity\Annotation") * * @return JsonResponse */ @@ -94,7 +94,7 @@ class AnnotationRestController extends WallabagRestController { $this->validateAuthentication(); - return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:deleteAnnotation', [ + return $this->forward('Wallabag\AnnotationBundle\Controller\WallabagAnnotationController::deleteAnnotationAction', [ 'annotation' => $annotation, ]); } diff --git a/src/Wallabag/ApiBundle/Controller/ConfigRestController.php b/src/Wallabag/ApiBundle/Controller/ConfigRestController.php index 134efd19d..24c26103e 100644 --- a/src/Wallabag/ApiBundle/Controller/ConfigRestController.php +++ b/src/Wallabag/ApiBundle/Controller/ConfigRestController.php @@ -3,6 +3,7 @@ namespace Wallabag\ApiBundle\Controller; use JMS\Serializer\SerializationContext; +use JMS\Serializer\SerializerInterface; use Nelmio\ApiDocBundle\Annotation\ApiDoc; use Symfony\Component\HttpFoundation\JsonResponse; @@ -19,7 +20,7 @@ class ConfigRestController extends WallabagRestController { $this->validateAuthentication(); - $json = $this->get('jms_serializer')->serialize( + $json = $this->get(SerializerInterface::class)->serialize( $this->getUser()->getConfig(), 'json', SerializationContext::create()->setGroups(['config_api']) diff --git a/src/Wallabag/ApiBundle/Controller/DeveloperController.php b/src/Wallabag/ApiBundle/Controller/DeveloperController.php index 3224d7893..a8a67ad3a 100644 --- a/src/Wallabag/ApiBundle/Controller/DeveloperController.php +++ b/src/Wallabag/ApiBundle/Controller/DeveloperController.php @@ -3,8 +3,12 @@ namespace Wallabag\ApiBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\ApiBundle\Entity\Client; use Wallabag\ApiBundle\Form\Type\ClientType; @@ -15,11 +19,11 @@ class DeveloperController extends Controller * * @Route("/developer", name="developer") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function indexAction() { - $clients = $this->getDoctrine()->getRepository('WallabagApiBundle:Client')->findByUser($this->getUser()->getId()); + $clients = $this->getDoctrine()->getRepository(Client::class)->findByUser($this->getUser()->getId()); return $this->render('@WallabagCore/themes/common/Developer/index.html.twig', [ 'clients' => $clients, @@ -31,7 +35,7 @@ class DeveloperController extends Controller * * @Route("/developer/client/create", name="developer_create_client") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function createClientAction(Request $request) { @@ -45,9 +49,9 @@ class DeveloperController extends Controller $em->persist($client); $em->flush(); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.developer.notice.client_created', ['%name%' => $client->getName()]) + $this->get(TranslatorInterface::class)->trans('flashes.developer.notice.client_created', ['%name%' => $client->getName()]) ); return $this->render('@WallabagCore/themes/common/Developer/client_parameters.html.twig', [ @@ -67,7 +71,7 @@ class DeveloperController extends Controller * * @Route("/developer/client/delete/{id}", requirements={"id" = "\d+"}, name="developer_delete_client") * - * @return \Symfony\Component\HttpFoundation\RedirectResponse + * @return RedirectResponse */ public function deleteClientAction(Client $client) { @@ -79,9 +83,9 @@ class DeveloperController extends Controller $em->remove($client); $em->flush(); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.developer.notice.client_deleted', ['%name%' => $client->getName()]) + $this->get(TranslatorInterface::class)->trans('flashes.developer.notice.client_deleted', ['%name%' => $client->getName()]) ); return $this->redirect($this->generateUrl('developer')); @@ -92,7 +96,7 @@ class DeveloperController extends Controller * * @Route("/developer/howto/first-app", name="developer_howto_firstapp") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function howtoFirstAppAction() { diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php index 9b6aa1b9d..3b898368c 100644 --- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php +++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php @@ -5,6 +5,8 @@ namespace Wallabag\ApiBundle\Controller; use Hateoas\Configuration\Route; use Hateoas\Representation\Factory\PagerfantaFactory; use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Pagerfanta\Pagerfanta; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -14,7 +16,11 @@ use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Tag; use Wallabag\CoreBundle\Event\EntryDeletedEvent; use Wallabag\CoreBundle\Event\EntrySavedEvent; +use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Helper\EntriesExport; +use Wallabag\CoreBundle\Helper\TagsAssigner; use Wallabag\CoreBundle\Helper\UrlHasher; +use Wallabag\CoreBundle\Repository\EntryRepository; class EntryRestController extends WallabagRestController { @@ -40,7 +46,7 @@ class EntryRestController extends WallabagRestController public function getEntriesExistsAction(Request $request) { $this->validateAuthentication(); - $repo = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry'); + $repo = $this->getDoctrine()->getRepository(Entry::class); $returnId = (null === $request->query->get('return_id')) ? false : (bool) $request->query->get('return_id'); @@ -136,8 +142,8 @@ class EntryRestController extends WallabagRestController $domainName = (null === $request->query->get('domain_name')) ? '' : (string) $request->query->get('domain_name'); try { - /** @var \Pagerfanta\Pagerfanta $pager */ - $pager = $this->get('wallabag_core.entry_repository')->findEntries( + /** @var Pagerfanta $pager */ + $pager = $this->get(EntryRepository::class)->findEntries( $this->getUser()->getId(), $isArchived, $isStarred, @@ -215,7 +221,7 @@ class EntryRestController extends WallabagRestController $this->validateAuthentication(); $this->validateUserAccess($entry->getUser()->getId()); - return $this->get('wallabag_core.helper.entries_export') + return $this->get(EntriesExport::class) ->setEntries($entry) ->updateTitle('entry') ->updateAuthor('entry') @@ -247,7 +253,7 @@ class EntryRestController extends WallabagRestController // handle multiple urls foreach ($urls as $key => $url) { - $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( + $entry = $this->get(EntryRepository::class)->findByUrlAndUserId( $url, $this->getUser()->getId() ); @@ -256,7 +262,7 @@ class EntryRestController extends WallabagRestController if (false !== $entry) { // entry deleted, dispatch event about it! - $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); + $this->get(EventDispatcherInterface::class)->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); $em = $this->getDoctrine()->getManager(); $em->remove($entry); @@ -301,7 +307,7 @@ class EntryRestController extends WallabagRestController // handle multiple urls foreach ($urls as $key => $url) { - $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( + $entry = $this->get(EntryRepository::class)->findByUrlAndUserId( $url, $this->getUser()->getId() ); @@ -311,7 +317,7 @@ class EntryRestController extends WallabagRestController if (false === $entry) { $entry = new Entry($this->getUser()); - $this->get('wallabag_core.content_proxy')->updateEntry($entry, $url); + $this->get(ContentProxy::class)->updateEntry($entry, $url); } $em = $this->getDoctrine()->getManager(); @@ -321,7 +327,7 @@ class EntryRestController extends WallabagRestController $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; // entry saved, dispatch event about it! - $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); + $this->get(EventDispatcherInterface::class)->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); } return $this->sendResponse($results); @@ -358,7 +364,7 @@ class EntryRestController extends WallabagRestController $url = $request->request->get('url'); - $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( + $entry = $this->get(EntryRepository::class)->findByUrlAndUserId( $url, $this->getUser()->getId() ); @@ -371,7 +377,7 @@ class EntryRestController extends WallabagRestController $data = $this->retrieveValueFromRequest($request); try { - $this->get('wallabag_core.content_proxy')->updateEntry( + $this->get(ContentProxy::class)->updateEntry( $entry, $entry->getUrl(), [ @@ -401,7 +407,7 @@ class EntryRestController extends WallabagRestController } if (!empty($data['tags'])) { - $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $data['tags']); + $this->get(TagsAssigner::class)->assignTagsToEntry($entry, $data['tags']); } if (!empty($data['origin_url'])) { @@ -417,11 +423,11 @@ class EntryRestController extends WallabagRestController } if (empty($entry->getDomainName())) { - $this->get('wallabag_core.content_proxy')->setEntryDomainName($entry); + $this->get(ContentProxy::class)->setEntryDomainName($entry); } if (empty($entry->getTitle())) { - $this->get('wallabag_core.content_proxy')->setDefaultEntryTitle($entry); + $this->get(ContentProxy::class)->setDefaultEntryTitle($entry); } $em = $this->getDoctrine()->getManager(); @@ -429,7 +435,7 @@ class EntryRestController extends WallabagRestController $em->flush(); // entry saved, dispatch event about it! - $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); + $this->get(EventDispatcherInterface::class)->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); return $this->sendResponse($entry); } @@ -463,7 +469,7 @@ class EntryRestController extends WallabagRestController $this->validateAuthentication(); $this->validateUserAccess($entry->getUser()->getId()); - $contentProxy = $this->get('wallabag_core.content_proxy'); + $contentProxy = $this->get(ContentProxy::class); $data = $this->retrieveValueFromRequest($request); @@ -518,7 +524,7 @@ class EntryRestController extends WallabagRestController if (!empty($data['tags'])) { $entry->removeAllTags(); - $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $data['tags']); + $this->get(TagsAssigner::class)->assignTagsToEntry($entry, $data['tags']); } if (null !== $data['isPublic']) { @@ -534,11 +540,11 @@ class EntryRestController extends WallabagRestController } if (empty($entry->getDomainName())) { - $this->get('wallabag_core.content_proxy')->setEntryDomainName($entry); + $this->get(ContentProxy::class)->setEntryDomainName($entry); } if (empty($entry->getTitle())) { - $this->get('wallabag_core.content_proxy')->setDefaultEntryTitle($entry); + $this->get(ContentProxy::class)->setDefaultEntryTitle($entry); } $em = $this->getDoctrine()->getManager(); @@ -546,7 +552,7 @@ class EntryRestController extends WallabagRestController $em->flush(); // entry saved, dispatch event about it! - $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); + $this->get(EventDispatcherInterface::class)->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); return $this->sendResponse($entry); } @@ -569,7 +575,7 @@ class EntryRestController extends WallabagRestController $this->validateUserAccess($entry->getUser()->getId()); try { - $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl()); + $this->get(ContentProxy::class)->updateEntry($entry, $entry->getUrl()); } catch (\Exception $e) { $this->get('logger')->error('Error while saving an entry', [ 'exception' => $e, @@ -589,7 +595,7 @@ class EntryRestController extends WallabagRestController $em->flush(); // entry saved, dispatch event about it! - $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); + $this->get(EventDispatcherInterface::class)->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); return $this->sendResponse($entry); } @@ -627,7 +633,7 @@ class EntryRestController extends WallabagRestController } // entry deleted, dispatch event about it! - $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); + $this->get(EventDispatcherInterface::class)->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); $em = $this->getDoctrine()->getManager(); $em->remove($entry); @@ -676,7 +682,7 @@ class EntryRestController extends WallabagRestController $tags = $request->request->get('tags', ''); if (!empty($tags)) { - $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags); + $this->get(TagsAssigner::class)->assignTagsToEntry($entry, $tags); } $em = $this->getDoctrine()->getManager(); @@ -736,7 +742,7 @@ class EntryRestController extends WallabagRestController $results = []; foreach ($list as $key => $element) { - $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( + $entry = $this->get(EntryRepository::class)->findByUrlAndUserId( $element->url, $this->getUser()->getId() ); @@ -752,7 +758,7 @@ class EntryRestController extends WallabagRestController $label = trim($label); $tag = $this->getDoctrine() - ->getRepository('WallabagCoreBundle:Tag') + ->getRepository(Tag::class) ->findOneByLabel($label); if (false !== $tag) { @@ -794,7 +800,7 @@ class EntryRestController extends WallabagRestController // handle multiple urls foreach ($list as $key => $element) { - $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( + $entry = $this->get(EntryRepository::class)->findByUrlAndUserId( $element->url, $this->getUser()->getId() ); @@ -805,7 +811,7 @@ class EntryRestController extends WallabagRestController $tags = $element->tags; if (false !== $entry && !(empty($tags))) { - $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags); + $this->get(TagsAssigner::class)->assignTagsToEntry($entry, $tags); $em = $this->getDoctrine()->getManager(); $em->persist($entry); diff --git a/src/Wallabag/ApiBundle/Controller/SearchRestController.php b/src/Wallabag/ApiBundle/Controller/SearchRestController.php index 7b415ea24..54709f317 100644 --- a/src/Wallabag/ApiBundle/Controller/SearchRestController.php +++ b/src/Wallabag/ApiBundle/Controller/SearchRestController.php @@ -9,6 +9,7 @@ use Pagerfanta\Doctrine\ORM\QueryAdapter as DoctrineORMAdapter; use Pagerfanta\Pagerfanta; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; +use Wallabag\CoreBundle\Repository\EntryRepository; class SearchRestController extends WallabagRestController { @@ -33,7 +34,7 @@ class SearchRestController extends WallabagRestController $page = (int) $request->query->get('page', 1); $perPage = (int) $request->query->get('perPage', 30); - $qb = $this->get('wallabag_core.entry_repository') + $qb = $this->get(EntryRepository::class) ->getBuilderForSearchByUser( $this->getUser()->getId(), $term, diff --git a/src/Wallabag/ApiBundle/Controller/TagRestController.php b/src/Wallabag/ApiBundle/Controller/TagRestController.php index 1b9f3aea2..7e14e8d1c 100644 --- a/src/Wallabag/ApiBundle/Controller/TagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/TagRestController.php @@ -2,6 +2,7 @@ namespace Wallabag\ApiBundle\Controller; +use JMS\Serializer\SerializerInterface; use Nelmio\ApiDocBundle\Annotation\ApiDoc; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -22,10 +23,10 @@ class TagRestController extends WallabagRestController $this->validateAuthentication(); $tags = $this->getDoctrine() - ->getRepository('WallabagCoreBundle:Tag') + ->getRepository(Tag::class) ->findAllFlatTagsWithNbEntries($this->getUser()->getId()); - $json = $this->get('jms_serializer')->serialize($tags, 'json'); + $json = $this->get(SerializerInterface::class)->serialize($tags, 'json'); return (new JsonResponse())->setJson($json); } @@ -46,7 +47,7 @@ class TagRestController extends WallabagRestController $this->validateAuthentication(); $label = $request->get('tag', ''); - $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findByLabelsAndUser([$label], $this->getUser()->getId()); + $tags = $this->getDoctrine()->getRepository(Tag::class)->findByLabelsAndUser([$label], $this->getUser()->getId()); if (empty($tags)) { throw $this->createNotFoundException('Tag not found'); @@ -55,12 +56,12 @@ class TagRestController extends WallabagRestController $tag = $tags[0]; $this->getDoctrine() - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->removeTag($this->getUser()->getId(), $tag); $this->cleanOrphanTag($tag); - $json = $this->get('jms_serializer')->serialize($tag, 'json'); + $json = $this->get(SerializerInterface::class)->serialize($tag, 'json'); return (new JsonResponse())->setJson($json); } @@ -82,19 +83,19 @@ class TagRestController extends WallabagRestController $tagsLabels = $request->get('tags', ''); - $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findByLabelsAndUser(explode(',', $tagsLabels), $this->getUser()->getId()); + $tags = $this->getDoctrine()->getRepository(Tag::class)->findByLabelsAndUser(explode(',', $tagsLabels), $this->getUser()->getId()); if (empty($tags)) { throw $this->createNotFoundException('Tags not found'); } $this->getDoctrine() - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->removeTags($this->getUser()->getId(), $tags); $this->cleanOrphanTag($tags); - $json = $this->get('jms_serializer')->serialize($tags, 'json'); + $json = $this->get(SerializerInterface::class)->serialize($tags, 'json'); return (new JsonResponse())->setJson($json); } @@ -114,19 +115,19 @@ class TagRestController extends WallabagRestController { $this->validateAuthentication(); - $tagFromDb = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findByLabelsAndUser([$tag->getLabel()], $this->getUser()->getId()); + $tagFromDb = $this->getDoctrine()->getRepository(Tag::class)->findByLabelsAndUser([$tag->getLabel()], $this->getUser()->getId()); if (empty($tagFromDb)) { throw $this->createNotFoundException('Tag not found'); } $this->getDoctrine() - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->removeTag($this->getUser()->getId(), $tag); $this->cleanOrphanTag($tag); - $json = $this->get('jms_serializer')->serialize($tag, 'json'); + $json = $this->get(SerializerInterface::class)->serialize($tag, 'json'); return (new JsonResponse())->setJson($json); } diff --git a/src/Wallabag/ApiBundle/Controller/UserRestController.php b/src/Wallabag/ApiBundle/Controller/UserRestController.php index 922ab7bbb..5d91cd582 100644 --- a/src/Wallabag/ApiBundle/Controller/UserRestController.php +++ b/src/Wallabag/ApiBundle/Controller/UserRestController.php @@ -2,14 +2,20 @@ namespace Wallabag\ApiBundle\Controller; +use Craue\ConfigBundle\Util\Config; use FOS\UserBundle\Event\UserEvent; use FOS\UserBundle\FOSUserEvents; +use FOS\UserBundle\Model\UserManagerInterface; use JMS\Serializer\SerializationContext; +use JMS\Serializer\SerializerInterface; use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\ApiBundle\Entity\Client; use Wallabag\UserBundle\Entity\User; +use Wallabag\UserBundle\Form\NewUserType; class UserRestController extends WallabagRestController { @@ -45,20 +51,20 @@ class UserRestController extends WallabagRestController */ public function putUserAction(Request $request) { - if (!$this->container->getParameter('fosuser_registration') || !$this->get('craue_config')->get('api_user_registration')) { - $json = $this->get('jms_serializer')->serialize(['error' => "Server doesn't allow registrations"], 'json'); + if (!$this->container->getParameter('fosuser_registration') || !$this->get(Config::class)->get('api_user_registration')) { + $json = $this->get(SerializerInterface::class)->serialize(['error' => "Server doesn't allow registrations"], 'json'); return (new JsonResponse()) ->setJson($json) ->setStatusCode(JsonResponse::HTTP_FORBIDDEN); } - $userManager = $this->get('fos_user.user_manager'); + $userManager = $this->get(UserManagerInterface::class); $user = $userManager->createUser(); // user will be disabled BY DEFAULT to avoid spamming account to be enabled $user->setEnabled(false); - $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user, [ + $form = $this->createForm(NewUserType::class, $user, [ 'csrf_protection' => false, ]); @@ -92,7 +98,7 @@ class UserRestController extends WallabagRestController $errors['password'] = $this->translateErrors($data['plainPassword']['children']['first']['errors']); } - $json = $this->get('jms_serializer')->serialize(['error' => $errors], 'json'); + $json = $this->get(SerializerInterface::class)->serialize(['error' => $errors], 'json'); return (new JsonResponse()) ->setJson($json) @@ -111,7 +117,7 @@ class UserRestController extends WallabagRestController // dispatch a created event so the associated config will be created $event = new UserEvent($user, $request); - $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event); + $this->get(EventDispatcherInterface::class)->dispatch(FOSUserEvents::USER_CREATED, $event); return $this->sendUser($user, 'user_api_with_client', JsonResponse::HTTP_CREATED); } @@ -126,7 +132,7 @@ class UserRestController extends WallabagRestController */ private function sendUser(User $user, $group = 'user_api', $status = JsonResponse::HTTP_OK) { - $json = $this->get('jms_serializer')->serialize( + $json = $this->get(SerializerInterface::class)->serialize( $user, 'json', SerializationContext::create()->setGroups([$group]) @@ -148,7 +154,7 @@ class UserRestController extends WallabagRestController { $translatedErrors = []; foreach ($errors as $error) { - $translatedErrors[] = $this->get('translator')->trans($error); + $translatedErrors[] = $this->get(TranslatorInterface::class)->trans($error); } return $translatedErrors; diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php index 44fd96835..5ac85d39a 100644 --- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php @@ -4,8 +4,11 @@ namespace Wallabag\ApiBundle\Controller; use FOS\RestBundle\Controller\AbstractFOSRestController; use JMS\Serializer\SerializationContext; +use JMS\Serializer\SerializerInterface; use Nelmio\ApiDocBundle\Annotation\ApiDoc; use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Symfony\Component\Security\Core\Exception\AccessDeniedException; class WallabagRestController extends AbstractFOSRestController @@ -22,7 +25,7 @@ class WallabagRestController extends AbstractFOSRestController public function getVersionAction() { $version = $this->container->getParameter('wallabag_core.version'); - $json = $this->get('jms_serializer')->serialize($version, 'json'); + $json = $this->get(SerializerInterface::class)->serialize($version, 'json'); return (new JsonResponse())->setJson($json); } @@ -39,15 +42,15 @@ class WallabagRestController extends AbstractFOSRestController $info = [ 'appname' => 'wallabag', 'version' => $this->container->getParameter('wallabag_core.version'), - 'allowed_registration' => $this->container->getParameter('wallabag_user.registration_enabled'), + 'allowed_registration' => $this->container->getParameter('fosuser_registration'), ]; - return (new JsonResponse())->setJson($this->get('jms_serializer')->serialize($info, 'json')); + return (new JsonResponse())->setJson($this->get(SerializerInterface::class)->serialize($info, 'json')); } protected function validateAuthentication() { - if (false === $this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) { + if (false === $this->get(AuthorizationCheckerInterface::class)->isGranted('IS_AUTHENTICATED_FULLY')) { throw new AccessDeniedException(); } } @@ -60,7 +63,7 @@ class WallabagRestController extends AbstractFOSRestController */ protected function validateUserAccess($requestUserId) { - $user = $this->get('security.token_storage')->getToken()->getUser(); + $user = $this->get(TokenStorageInterface::class)->getToken()->getUser(); if ($requestUserId !== $user->getId()) { throw $this->createAccessDeniedException('Access forbidden. Entry user id: ' . $requestUserId . ', logged user id: ' . $user->getId()); } @@ -79,7 +82,7 @@ class WallabagRestController extends AbstractFOSRestController $context = new SerializationContext(); $context->setSerializeNull(true); - $json = $this->get('jms_serializer')->serialize($data, 'json', $context); + $json = $this->get(SerializerInterface::class)->serialize($data, 'json', $context); return (new JsonResponse())->setJson($json); } diff --git a/src/Wallabag/ApiBundle/Form/Type/ClientType.php b/src/Wallabag/ApiBundle/Form/Type/ClientType.php index 14dc5c44f..3d00b2ac8 100644 --- a/src/Wallabag/ApiBundle/Form/Type/ClientType.php +++ b/src/Wallabag/ApiBundle/Form/Type/ClientType.php @@ -9,6 +9,7 @@ use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\UrlType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\ApiBundle\Entity\Client; class ClientType extends AbstractType { @@ -40,7 +41,7 @@ class ClientType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\ApiBundle\Entity\Client', + 'data_class' => Client::class, ]); } diff --git a/src/Wallabag/ApiBundle/Repository/ClientRepository.php b/src/Wallabag/ApiBundle/Repository/ClientRepository.php index fc14262e2..1c00e1645 100644 --- a/src/Wallabag/ApiBundle/Repository/ClientRepository.php +++ b/src/Wallabag/ApiBundle/Repository/ClientRepository.php @@ -2,10 +2,17 @@ namespace Wallabag\ApiBundle\Repository; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; +use Wallabag\ApiBundle\Entity\Client; -class ClientRepository extends EntityRepository +class ClientRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Client::class); + } + public function findOneBy(array $criteria, array $orderBy = null) { if (!empty($criteria['id'])) { diff --git a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml index 7785d25f2..de592c217 100644 --- a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml +++ b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml @@ -1,39 +1,39 @@ entry: type: rest - resource: "WallabagApiBundle:EntryRest" + resource: 'Wallabag\ApiBundle\Controller\EntryRestController' name_prefix: api_ search: type: rest - resource: "WallabagApiBundle:SearchRest" + resource: 'Wallabag\ApiBundle\Controller\SearchRestController' name_prefix: api_ tag: type: rest - resource: "WallabagApiBundle:TagRest" + resource: 'Wallabag\ApiBundle\Controller\TagRestController' name_prefix: api_ tagging_rule: type: rest - resource: "WallabagApiBundle:TaggingRuleRest" + resource: 'Wallabag\ApiBundle\Controller\TaggingRuleRestController' name_prefix: api_ annotation: type: rest - resource: "WallabagApiBundle:AnnotationRest" + resource: 'Wallabag\ApiBundle\Controller\AnnotationRestController' name_prefix: api_ misc: type: rest - resource: "WallabagApiBundle:WallabagRest" + resource: 'Wallabag\ApiBundle\Controller\WallabagRestController' name_prefix: api_ user: type: rest - resource: "WallabagApiBundle:UserRest" + resource: 'Wallabag\ApiBundle\Controller\UserRestController' name_prefix: api_ config: type: rest - resource: "WallabagApiBundle:ConfigRest" + resource: 'Wallabag\ApiBundle\Controller\ConfigRestController' name_prefix: api_ diff --git a/src/Wallabag/CoreBundle/Command/CleanDownloadedImagesCommand.php b/src/Wallabag/CoreBundle/Command/CleanDownloadedImagesCommand.php index d81becdc3..90af26cb0 100644 --- a/src/Wallabag/CoreBundle/Command/CleanDownloadedImagesCommand.php +++ b/src/Wallabag/CoreBundle/Command/CleanDownloadedImagesCommand.php @@ -8,6 +8,8 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Finder\Finder; +use Wallabag\CoreBundle\Helper\DownloadImages; +use Wallabag\CoreBundle\Repository\EntryRepository; class CleanDownloadedImagesCommand extends ContainerAwareCommand { @@ -34,7 +36,7 @@ class CleanDownloadedImagesCommand extends ContainerAwareCommand $io->text('Dry run mode enabled (no images will be removed)'); } - $downloadImages = $this->getContainer()->get('wallabag_core.entry.download_images'); + $downloadImages = $this->getContainer()->get(DownloadImages::class); $baseFolder = $downloadImages->getBaseFolder(); $io->text('Retrieve existing images'); @@ -56,7 +58,7 @@ class CleanDownloadedImagesCommand extends ContainerAwareCommand $io->text('Retrieve valid folders attached to a user'); - $entries = $this->getContainer()->get('wallabag_core.entry_repository')->findAllEntriesIdByUserId(); + $entries = $this->getContainer()->get(EntryRepository::class)->findAllEntriesIdByUserId(); // retrieve _valid_ folders from existing entries $validPaths = []; diff --git a/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php b/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php index 64b91520a..5af642dd8 100644 --- a/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php +++ b/src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php @@ -2,6 +2,7 @@ namespace Wallabag\CoreBundle\Command; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\NoResultException; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputArgument; @@ -9,7 +10,9 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Repository\EntryRepository; use Wallabag\UserBundle\Entity\User; +use Wallabag\UserBundle\Repository\UserRepository; class CleanDuplicatesCommand extends ContainerAwareCommand { @@ -49,7 +52,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand $this->io->success('Finished cleaning.'); } else { - $users = $this->getContainer()->get('wallabag_user.user_repository')->findAll(); + $users = $this->getContainer()->get(UserRepository::class)->findAll(); $this->io->text(sprintf('Cleaning through %d user accounts', \count($users))); @@ -65,8 +68,8 @@ class CleanDuplicatesCommand extends ContainerAwareCommand private function cleanDuplicates(User $user) { - $em = $this->getContainer()->get('doctrine.orm.entity_manager'); - $repo = $this->getContainer()->get('wallabag_core.entry_repository'); + $em = $this->getContainer()->get(EntityManagerInterface::class); + $repo = $this->getContainer()->get(EntryRepository::class); $entries = $repo->findAllEntriesIdAndUrlByUserId($user->getId()); @@ -105,10 +108,10 @@ class CleanDuplicatesCommand extends ContainerAwareCommand * * @param string $username * - * @return \Wallabag\UserBundle\Entity\User + * @return User */ private function getUser($username) { - return $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($username); + return $this->getContainer()->get(UserRepository::class)->findOneByUserName($username); } } diff --git a/src/Wallabag/CoreBundle/Command/ExportCommand.php b/src/Wallabag/CoreBundle/Command/ExportCommand.php index 128f9d65b..a24a7ce2e 100644 --- a/src/Wallabag/CoreBundle/Command/ExportCommand.php +++ b/src/Wallabag/CoreBundle/Command/ExportCommand.php @@ -8,6 +8,9 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use Wallabag\CoreBundle\Helper\EntriesExport; +use Wallabag\CoreBundle\Repository\EntryRepository; +use Wallabag\UserBundle\Repository\UserRepository; class ExportCommand extends ContainerAwareCommand { @@ -35,14 +38,14 @@ class ExportCommand extends ContainerAwareCommand $io = new SymfonyStyle($input, $output); try { - $user = $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($input->getArgument('username')); + $user = $this->getContainer()->get(UserRepository::class)->findOneByUserName($input->getArgument('username')); } catch (NoResultException $e) { $io->error(sprintf('User "%s" not found.', $input->getArgument('username'))); return 1; } - $entries = $this->getContainer()->get('wallabag_core.entry_repository') + $entries = $this->getContainer()->get(EntryRepository::class) ->getBuilderForAllByUser($user->getId()) ->getQuery() ->getResult(); @@ -56,7 +59,7 @@ class ExportCommand extends ContainerAwareCommand } try { - $data = $this->getContainer()->get('wallabag_core.helper.entries_export') + $data = $this->getContainer()->get(EntriesExport::class) ->setEntries($entries) ->updateTitle('All') ->updateAuthor('All') diff --git a/src/Wallabag/CoreBundle/Command/GenerateUrlHashesCommand.php b/src/Wallabag/CoreBundle/Command/GenerateUrlHashesCommand.php index f870059bb..1d0fa3031 100644 --- a/src/Wallabag/CoreBundle/Command/GenerateUrlHashesCommand.php +++ b/src/Wallabag/CoreBundle/Command/GenerateUrlHashesCommand.php @@ -2,11 +2,14 @@ namespace Wallabag\CoreBundle\Command; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\NoResultException; +use Doctrine\Persistence\ManagerRegistry; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Helper\UrlHasher; use Wallabag\UserBundle\Entity\User; @@ -40,7 +43,7 @@ class GenerateUrlHashesCommand extends ContainerAwareCommand return 1; } } else { - $users = $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findAll(); + $users = $this->getDoctrine()->getRepository(User::class)->findAll(); $output->writeln(sprintf('Generating hashed urls for "%d" users', \count($users))); @@ -56,8 +59,8 @@ class GenerateUrlHashesCommand extends ContainerAwareCommand private function generateHashedUrls(User $user) { - $em = $this->getContainer()->get('doctrine.orm.entity_manager'); - $repo = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry'); + $em = $this->getContainer()->get(EntityManagerInterface::class); + $repo = $this->getDoctrine()->getRepository(Entry::class); $entries = $repo->findByEmptyHashedUrlAndUserId($user->getId()); @@ -86,11 +89,11 @@ class GenerateUrlHashesCommand extends ContainerAwareCommand */ private function getUser($username) { - return $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findOneByUserName($username); + return $this->getDoctrine()->getRepository(User::class)->findOneByUserName($username); } private function getDoctrine() { - return $this->getContainer()->get('doctrine'); + return $this->getContainer()->get(ManagerRegistry::class); } } diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php index 8d08187a9..1dafde40d 100644 --- a/src/Wallabag/CoreBundle/Command/InstallCommand.php +++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php @@ -2,8 +2,13 @@ namespace Wallabag\CoreBundle\Command; +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Exception\DriverException; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\Persistence\ManagerRegistry; use FOS\UserBundle\Event\UserEvent; use FOS\UserBundle\FOSUserEvents; +use FOS\UserBundle\Model\UserManagerInterface; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\InputInterface; @@ -12,6 +17,7 @@ use Symfony\Component\Console\Output\BufferedOutput; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule; use Wallabag\CoreBundle\Entity\InternalSetting; @@ -20,21 +26,28 @@ class InstallCommand extends ContainerAwareCommand /** * @var InputInterface */ - protected $defaultInput; + private $defaultInput; /** * @var SymfonyStyle */ - protected $io; + private $io; /** * @var array */ - protected $functionExists = [ + private $functionExists = [ 'curl_exec', 'curl_multi_init', ]; + private bool $runOtherCommands = true; + + public function disableRunOtherCommands(): void + { + $this->runOtherCommands = false; + } + protected function configure() { $this @@ -68,11 +81,11 @@ class InstallCommand extends ContainerAwareCommand $this->io->success('You can now configure your web server, see https://doc.wallabag.org'); } - protected function checkRequirements() + private function checkRequirements() { $this->io->section('Step 1 of 4: Checking system requirements.'); - $doctrineManager = $this->getContainer()->get('doctrine')->getManager(); + $doctrineManager = $this->getContainer()->get(ManagerRegistry::class)->getManager(); $rows = []; @@ -95,7 +108,7 @@ class InstallCommand extends ContainerAwareCommand $status = 'OK!'; $help = ''; - $conn = $this->getContainer()->get('doctrine')->getManager()->getConnection(); + $conn = $this->getContainer()->get(ManagerRegistry::class)->getManager()->getConnection(); try { $conn->connect(); @@ -168,7 +181,7 @@ class InstallCommand extends ContainerAwareCommand return $this; } - protected function setupDatabase() + private function setupDatabase() { $this->io->section('Step 2 of 4: Setting up database.'); @@ -236,7 +249,7 @@ class InstallCommand extends ContainerAwareCommand return $this; } - protected function setupAdmin() + private function setupAdmin() { $this->io->section('Step 3 of 4: Administration setup.'); @@ -244,9 +257,9 @@ class InstallCommand extends ContainerAwareCommand return $this; } - $em = $this->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->getContainer()->get(EntityManagerInterface::class); - $userManager = $this->getContainer()->get('fos_user.user_manager'); + $userManager = $this->getContainer()->get(UserManagerInterface::class); $user = $userManager->createUser(); $user->setUsername($this->io->ask('Username', 'wallabag')); @@ -264,21 +277,21 @@ class InstallCommand extends ContainerAwareCommand // dispatch a created event so the associated config will be created $event = new UserEvent($user); - $this->getContainer()->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event); + $this->getContainer()->get(EventDispatcherInterface::class)->dispatch(FOSUserEvents::USER_CREATED, $event); $this->io->text('Administration successfully setup.'); return $this; } - protected function setupConfig() + private function setupConfig() { $this->io->section('Step 4 of 4: Config setup.'); - $em = $this->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->getContainer()->get(EntityManagerInterface::class); // cleanup before insert new stuff - $em->createQuery('DELETE FROM WallabagCoreBundle:InternalSetting')->execute(); - $em->createQuery('DELETE FROM WallabagCoreBundle:IgnoreOriginInstanceRule')->execute(); + $em->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\InternalSetting')->execute(); + $em->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule')->execute(); foreach ($this->getContainer()->getParameter('wallabag_core.default_internal_settings') as $setting) { $newSetting = new InternalSetting(); @@ -307,8 +320,12 @@ class InstallCommand extends ContainerAwareCommand * @param string $command * @param array $parameters Parameters to this command (usually 'force' => true) */ - protected function runCommand($command, $parameters = []) + private function runCommand($command, $parameters = []) { + if (!$this->runOtherCommands) { + return $this; + } + $parameters = array_merge( ['command' => $command], $parameters, @@ -329,7 +346,7 @@ class InstallCommand extends ContainerAwareCommand // PDO does not always close the connection after Doctrine commands. // See https://github.com/symfony/symfony/issues/11750. - $this->getContainer()->get('doctrine')->getManager()->getConnection()->close(); + $this->getContainer()->get(ManagerRegistry::class)->getManager()->getConnection()->close(); if (0 !== $exitCode) { $this->getApplication()->setAutoExit(true); @@ -347,7 +364,7 @@ class InstallCommand extends ContainerAwareCommand */ private function isDatabasePresent() { - $connection = $this->getContainer()->get('doctrine')->getManager()->getConnection(); + $connection = $this->getContainer()->get(ManagerRegistry::class)->getManager()->getConnection(); $databaseName = $connection->getDatabase(); try { @@ -368,7 +385,7 @@ class InstallCommand extends ContainerAwareCommand // custom verification for sqlite, since `getListDatabasesSQL` doesn't work for sqlite if ('sqlite' === $schemaManager->getDatabasePlatform()->getName()) { - $params = $this->getContainer()->get('doctrine.dbal.default_connection')->getParams(); + $params = $this->getContainer()->get(Connection::class)->getParams(); if (isset($params['path']) && file_exists($params['path'])) { return true; @@ -379,7 +396,7 @@ class InstallCommand extends ContainerAwareCommand try { return \in_array($databaseName, $schemaManager->listDatabases(), true); - } catch (\Doctrine\DBAL\Exception\DriverException $e) { + } catch (DriverException $e) { // it means we weren't able to get database list, assume the database doesn't exist return false; @@ -394,7 +411,7 @@ class InstallCommand extends ContainerAwareCommand */ private function isSchemaPresent() { - $schemaManager = $this->getContainer()->get('doctrine')->getManager()->getConnection()->getSchemaManager(); + $schemaManager = $this->getContainer()->get(ManagerRegistry::class)->getManager()->getConnection()->getSchemaManager(); return \count($schemaManager->listTableNames()) > 0 ? true : false; } diff --git a/src/Wallabag/CoreBundle/Command/ListUserCommand.php b/src/Wallabag/CoreBundle/Command/ListUserCommand.php index a7101a020..d26fba30c 100644 --- a/src/Wallabag/CoreBundle/Command/ListUserCommand.php +++ b/src/Wallabag/CoreBundle/Command/ListUserCommand.php @@ -8,6 +8,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use Wallabag\UserBundle\Repository\UserRepository; class ListUserCommand extends ContainerAwareCommand { @@ -26,13 +27,13 @@ class ListUserCommand extends ContainerAwareCommand { $io = new SymfonyStyle($input, $output); - $users = $this->getContainer()->get('wallabag_user.user_repository') + $users = $this->getContainer()->get(UserRepository::class) ->getQueryBuilderForSearch($input->getArgument('search')) ->setMaxResults($input->getOption('limit')) ->getQuery() ->getResult(); - $nbUsers = $this->getContainer()->get('wallabag_user.user_repository') + $nbUsers = $this->getContainer()->get(UserRepository::class) ->getSumUsers(); $rows = []; diff --git a/src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php b/src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php index 10918872f..e02aa7218 100644 --- a/src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php +++ b/src/Wallabag/CoreBundle/Command/ReloadEntryCommand.php @@ -3,12 +3,17 @@ namespace Wallabag\CoreBundle\Command; use Doctrine\ORM\NoResultException; +use Doctrine\Persistence\ManagerRegistry; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Wallabag\CoreBundle\Event\EntrySavedEvent; +use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Repository\EntryRepository; +use Wallabag\UserBundle\Repository\UserRepository; class ReloadEntryCommand extends ContainerAwareCommand { @@ -30,7 +35,7 @@ class ReloadEntryCommand extends ContainerAwareCommand if ($username = $input->getArgument('username')) { try { $userId = $this->getContainer() - ->get('wallabag_user.user_repository') + ->get(UserRepository::class) ->findOneByUserName($username) ->getId(); } catch (NoResultException $e) { @@ -40,7 +45,7 @@ class ReloadEntryCommand extends ContainerAwareCommand } } - $entryRepository = $this->getContainer()->get('wallabag_core.entry_repository'); + $entryRepository = $this->getContainer()->get(EntryRepository::class); $entryIds = $entryRepository->findAllEntriesIdByUserId($userId); $nbEntries = \count($entryIds); @@ -63,9 +68,9 @@ class ReloadEntryCommand extends ContainerAwareCommand $progressBar = $io->createProgressBar($nbEntries); - $contentProxy = $this->getContainer()->get('wallabag_core.content_proxy'); - $em = $this->getContainer()->get('doctrine')->getManager(); - $dispatcher = $this->getContainer()->get('event_dispatcher'); + $contentProxy = $this->getContainer()->get(ContentProxy::class); + $em = $this->getContainer()->get(ManagerRegistry::class)->getManager(); + $dispatcher = $this->getContainer()->get(EventDispatcherInterface::class); $progressBar->start(); foreach ($entryIds as $entryId) { diff --git a/src/Wallabag/CoreBundle/Command/ShowUserCommand.php b/src/Wallabag/CoreBundle/Command/ShowUserCommand.php index 87bccf718..f982db734 100644 --- a/src/Wallabag/CoreBundle/Command/ShowUserCommand.php +++ b/src/Wallabag/CoreBundle/Command/ShowUserCommand.php @@ -9,6 +9,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Wallabag\UserBundle\Entity\User; +use Wallabag\UserBundle\Repository\UserRepository; class ShowUserCommand extends ContainerAwareCommand { @@ -64,10 +65,10 @@ class ShowUserCommand extends ContainerAwareCommand * * @param string $username * - * @return \Wallabag\UserBundle\Entity\User + * @return User */ private function getUser($username) { - return $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($username); + return $this->getContainer()->get(UserRepository::class)->findOneByUserName($username); } } diff --git a/src/Wallabag/CoreBundle/Command/TagAllCommand.php b/src/Wallabag/CoreBundle/Command/TagAllCommand.php index 666654c02..66eb2a36a 100644 --- a/src/Wallabag/CoreBundle/Command/TagAllCommand.php +++ b/src/Wallabag/CoreBundle/Command/TagAllCommand.php @@ -3,11 +3,15 @@ namespace Wallabag\CoreBundle\Command; use Doctrine\ORM\NoResultException; +use Doctrine\Persistence\ManagerRegistry; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use Wallabag\CoreBundle\Helper\RuleBasedTagger; +use Wallabag\UserBundle\Entity\User; +use Wallabag\UserBundle\Repository\UserRepository; class TagAllCommand extends ContainerAwareCommand { @@ -35,7 +39,7 @@ class TagAllCommand extends ContainerAwareCommand return 1; } - $tagger = $this->getContainer()->get('wallabag_core.rule_based_tagger'); + $tagger = $this->getContainer()->get(RuleBasedTagger::class); $io->text(sprintf('Tagging entries for user %s...', $user->getUserName())); @@ -59,15 +63,15 @@ class TagAllCommand extends ContainerAwareCommand * * @param string $username * - * @return \Wallabag\UserBundle\Entity\User + * @return User */ private function getUser($username) { - return $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($username); + return $this->getContainer()->get(UserRepository::class)->findOneByUserName($username); } private function getDoctrine() { - return $this->getContainer()->get('doctrine'); + return $this->getContainer()->get(ManagerRegistry::class); } } diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index 5841f4da7..2db7dd93f 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php @@ -2,9 +2,15 @@ namespace Wallabag\CoreBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\DBAL\Platforms\SqlitePlatform; +use Doctrine\Persistence\ManagerRegistry; +use FOS\UserBundle\Model\UserManagerInterface; use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializerBuilder; +use Liip\ThemeBundle\ActiveTheme; use PragmaRX\Recovery\Recovery as BackupCodes; +use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -12,8 +18,11 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Validator\Constraints\Locale as LocaleConstraint; -use Wallabag\CoreBundle\Entity\Config; +use Symfony\Component\Validator\Validator\ValidatorInterface; +use Wallabag\AnnotationBundle\Entity\Annotation; +use Wallabag\CoreBundle\Entity\Config as ConfigEntity; use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule; use Wallabag\CoreBundle\Entity\RuleInterface; use Wallabag\CoreBundle\Entity\TaggingRule; @@ -24,7 +33,10 @@ use Wallabag\CoreBundle\Form\Type\IgnoreOriginUserRuleType; use Wallabag\CoreBundle\Form\Type\TaggingRuleImportType; use Wallabag\CoreBundle\Form\Type\TaggingRuleType; use Wallabag\CoreBundle\Form\Type\UserInformationType; +use Wallabag\CoreBundle\Repository\EntryRepository; +use Wallabag\CoreBundle\Repository\TagRepository; use Wallabag\CoreBundle\Tools\Utils; +use Wallabag\UserBundle\Repository\UserRepository; class ConfigController extends Controller { @@ -35,7 +47,7 @@ class ConfigController extends Controller { $em = $this->getDoctrine()->getManager(); $config = $this->getConfig(); - $userManager = $this->container->get('fos_user.user_manager'); + $userManager = $this->container->get(UserManagerInterface::class); $user = $this->getUser(); // handle basic config detail (this form is defined as a service) @@ -49,7 +61,7 @@ class ConfigController extends Controller $this->addFlash( 'notice', - 'Baggy is deprecated, forced to Material theme.' + 'Baggy is gone, forced to Material theme.' ); } @@ -59,7 +71,7 @@ class ConfigController extends Controller $request->getSession()->set('_locale', $config->getLanguage()); // switch active theme - $activeTheme = $this->get('liip_theme.active_theme'); + $activeTheme = $this->get(ActiveTheme::class); $activeTheme->setName($config->getTheme()); $this->addFlash( @@ -75,7 +87,7 @@ class ConfigController extends Controller $pwdForm->handleRequest($request); if ($pwdForm->isSubmitted() && $pwdForm->isValid()) { - if ($this->get('craue_config')->get('demo_mode_enabled') && $this->get('craue_config')->get('demo_mode_username') === $user->getUsername()) { + if ($this->get(Config::class)->get('demo_mode_enabled') && $this->get(Config::class)->get('demo_mode_username') === $user->getUsername()) { $message = 'flashes.config.notice.password_not_updated_demo'; } else { $message = 'flashes.config.notice.password_updated'; @@ -129,7 +141,7 @@ class ConfigController extends Controller if ($request->query->has('tagging-rule')) { $taggingRule = $this->getDoctrine() - ->getRepository('WallabagCoreBundle:TaggingRule') + ->getRepository(TaggingRule::class) ->find($request->query->get('tagging-rule')); if ($this->getUser()->getId() !== $taggingRule->getConfig()->getUser()->getId()) { @@ -192,7 +204,7 @@ class ConfigController extends Controller if ($request->query->has('ignore-origin-user-rule')) { $ignoreOriginUserRule = $this->getDoctrine() - ->getRepository('WallabagCoreBundle:IgnoreOriginUserRule') + ->getRepository(IgnoreOriginUserRule::class) ->find($request->query->get('ignore-origin-user-rule')); if ($this->getUser()->getId() !== $ignoreOriginUserRule->getConfig()->getUser()->getId()) { @@ -220,7 +232,7 @@ class ConfigController extends Controller return $this->redirect($this->generateUrl('config') . '#set6'); } - return $this->render('WallabagCoreBundle:Config:index.html.twig', [ + return $this->render('@WallabagCore/Config/index.html.twig', [ 'form' => [ 'config' => $configForm->createView(), 'feed' => $feedForm->createView(), @@ -236,7 +248,7 @@ class ConfigController extends Controller ], 'twofactor_auth' => $this->getParameter('twofactor_auth'), 'wallabag_url' => $this->getParameter('domain_name'), - 'enabled_users' => $this->get('wallabag_user.user_repository')->getSumEnabledUsers(), + 'enabled_users' => $this->get(UserRepository::class)->getSumEnabledUsers(), ]); } @@ -254,7 +266,7 @@ class ConfigController extends Controller $user = $this->getUser(); $user->setEmailTwoFactor(false); - $this->container->get('fos_user.user_manager')->updateUser($user, true); + $this->container->get(UserManagerInterface::class)->updateUser($user, true); $this->addFlash( 'notice', @@ -281,7 +293,7 @@ class ConfigController extends Controller $user->setBackupCodes(null); $user->setEmailTwoFactor(true); - $this->container->get('fos_user.user_manager')->updateUser($user, true); + $this->container->get(UserManagerInterface::class)->updateUser($user, true); $this->addFlash( 'notice', @@ -307,7 +319,7 @@ class ConfigController extends Controller $user->setGoogleAuthenticatorSecret(''); $user->setBackupCodes(null); - $this->container->get('fos_user.user_manager')->updateUser($user, true); + $this->container->get(UserManagerInterface::class)->updateUser($user, true); $this->addFlash( 'notice', @@ -329,7 +341,7 @@ class ConfigController extends Controller } $user = $this->getUser(); - $secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret(); + $secret = $this->get(GoogleAuthenticatorInterface::class)->generateSecret(); $user->setGoogleAuthenticatorSecret($secret); $user->setEmailTwoFactor(false); @@ -344,16 +356,16 @@ class ConfigController extends Controller $user->setBackupCodes($backupCodesHashed); - $this->container->get('fos_user.user_manager')->updateUser($user, true); + $this->container->get(UserManagerInterface::class)->updateUser($user, true); $this->addFlash( 'notice', 'flashes.config.notice.otp_enabled' ); - return $this->render('WallabagCoreBundle:Config:otp_app.html.twig', [ + return $this->render('@WallabagCore/Config/otp_app.html.twig', [ 'backupCodes' => $backupCodes, - 'qr_code' => $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user), + 'qr_code' => $this->get(GoogleAuthenticatorInterface::class)->getQRContent($user), 'secret' => $secret, ]); } @@ -373,7 +385,7 @@ class ConfigController extends Controller $user->setGoogleAuthenticatorSecret(null); $user->setBackupCodes(null); - $this->container->get('fos_user.user_manager')->updateUser($user, true); + $this->container->get(UserManagerInterface::class)->updateUser($user, true); return $this->redirect($this->generateUrl('config') . '#set3'); } @@ -385,7 +397,7 @@ class ConfigController extends Controller */ public function otpAppCheckAction(Request $request) { - $isValid = $this->get('scheb_two_factor.security.google_authenticator')->checkCode( + $isValid = $this->get(GoogleAuthenticatorInterface::class)->checkCode( $this->getUser(), $request->get('_auth_code') ); @@ -545,7 +557,7 @@ class ConfigController extends Controller switch ($type) { case 'annotations': $this->getDoctrine() - ->getRepository('WallabagAnnotationBundle:Annotation') + ->getRepository(Annotation::class) ->removeAllByUserId($this->getUser()->getId()); break; case 'tags': @@ -554,24 +566,24 @@ class ConfigController extends Controller case 'entries': // SQLite doesn't care about cascading remove, so we need to manually remove associated stuff // otherwise they won't be removed ... - if ($this->get('doctrine')->getConnection()->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) { - $this->getDoctrine()->getRepository('WallabagAnnotationBundle:Annotation')->removeAllByUserId($this->getUser()->getId()); + if ($this->get(ManagerRegistry::class)->getConnection()->getDatabasePlatform() instanceof SqlitePlatform) { + $this->getDoctrine()->getRepository(Annotation::class)->removeAllByUserId($this->getUser()->getId()); } // manually remove tags to avoid orphan tag $this->removeAllTagsByUserId($this->getUser()->getId()); - $this->get('wallabag_core.entry_repository')->removeAllByUserId($this->getUser()->getId()); + $this->get(EntryRepository::class)->removeAllByUserId($this->getUser()->getId()); break; case 'archived': - if ($this->get('doctrine')->getConnection()->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) { + if ($this->get(ManagerRegistry::class)->getConnection()->getDatabasePlatform() instanceof SqlitePlatform) { $this->removeAnnotationsForArchivedByUserId($this->getUser()->getId()); } // manually remove tags to avoid orphan tag $this->removeTagsForArchivedByUserId($this->getUser()->getId()); - $this->get('wallabag_core.entry_repository')->removeArchivedByUserId($this->getUser()->getId()); + $this->get(EntryRepository::class)->removeArchivedByUserId($this->getUser()->getId()); break; } @@ -590,11 +602,11 @@ class ConfigController extends Controller * * @throws AccessDeniedHttpException * - * @return \Symfony\Component\HttpFoundation\RedirectResponse + * @return RedirectResponse */ public function deleteAccountAction(Request $request) { - $enabledUsers = $this->get('wallabag_user.user_repository') + $enabledUsers = $this->get(UserRepository::class) ->getSumEnabledUsers(); if ($enabledUsers <= 1) { @@ -604,10 +616,10 @@ class ConfigController extends Controller $user = $this->getUser(); // logout current user - $this->get('security.token_storage')->setToken(null); + $this->get(TokenStorageInterface::class)->setToken(null); $request->getSession()->invalidate(); - $em = $this->get('fos_user.user_manager'); + $em = $this->get(UserManagerInterface::class); $em->deleteUser($user); return $this->redirect($this->generateUrl('fos_user_security_login')); @@ -618,7 +630,7 @@ class ConfigController extends Controller * * @Route("/config/view-mode", name="switch_view_mode") * - * @return \Symfony\Component\HttpFoundation\RedirectResponse + * @return RedirectResponse */ public function changeViewModeAction(Request $request) { @@ -639,11 +651,11 @@ class ConfigController extends Controller * * @Route("/locale/{language}", name="changeLocale") * - * @return \Symfony\Component\HttpFoundation\RedirectResponse + * @return RedirectResponse */ public function setLocaleAction(Request $request, $language = null) { - $errors = $this->get('validator')->validate($language, (new LocaleConstraint())); + $errors = $this->get(ValidatorInterface::class)->validate($language, (new LocaleConstraint())); if (0 === \count($errors)) { $request->getSession()->set('_locale', $language); @@ -690,7 +702,7 @@ class ConfigController extends Controller return; } - $this->get('wallabag_core.entry_repository') + $this->get(EntryRepository::class) ->removeTags($userId, $tags); // cleanup orphan tags @@ -712,7 +724,7 @@ class ConfigController extends Controller */ private function removeAllTagsByUserId($userId) { - $tags = $this->get('wallabag_core.tag_repository')->findAllTags($userId); + $tags = $this->get(TagRepository::class)->findAllTags($userId); $this->removeAllTagsByStatusAndUserId($tags, $userId); } @@ -723,7 +735,7 @@ class ConfigController extends Controller */ private function removeTagsForArchivedByUserId($userId) { - $tags = $this->get('wallabag_core.tag_repository')->findForArchivedArticlesByUser($userId); + $tags = $this->get(TagRepository::class)->findForArchivedArticlesByUser($userId); $this->removeAllTagsByStatusAndUserId($tags, $userId); } @@ -732,7 +744,7 @@ class ConfigController extends Controller $em = $this->getDoctrine()->getManager(); $archivedEntriesAnnotations = $this->getDoctrine() - ->getRepository('WallabagAnnotationBundle:Annotation') + ->getRepository(Annotation::class) ->findAllArchivedEntriesByUser($userId); foreach ($archivedEntriesAnnotations as $archivedEntriesAnnotation) { @@ -756,17 +768,17 @@ class ConfigController extends Controller * Retrieve config for the current user. * If no config were found, create a new one. * - * @return Config + * @return ConfigEntity */ private function getConfig() { $config = $this->getDoctrine() - ->getRepository('WallabagCoreBundle:Config') + ->getRepository(ConfigEntity::class) ->findOneByUser($this->getUser()); // should NEVER HAPPEN ... if (!$config) { - $config = new Config($this->getUser()); + $config = new ConfigEntity($this->getUser()); } return $config; diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php index 54ee6bf7e..6c607d4d3 100644 --- a/src/Wallabag/CoreBundle/Controller/EntryController.php +++ b/src/Wallabag/CoreBundle/Controller/EntryController.php @@ -2,45 +2,91 @@ namespace Wallabag\CoreBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Doctrine\ORM\NoResultException; +use Lexik\Bundle\FormFilterBundle\Filter\FilterBuilderUpdaterInterface; use Pagerfanta\Doctrine\ORM\QueryAdapter as DoctrineORMAdapter; use Pagerfanta\Exception\OutOfRangeCurrentPageException; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Entity\Tag; use Wallabag\CoreBundle\Event\EntryDeletedEvent; use Wallabag\CoreBundle\Event\EntrySavedEvent; use Wallabag\CoreBundle\Form\Type\EditEntryType; use Wallabag\CoreBundle\Form\Type\EntryFilterType; use Wallabag\CoreBundle\Form\Type\NewEntryType; use Wallabag\CoreBundle\Form\Type\SearchEntryType; +use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Helper\PreparePagerForEntries; +use Wallabag\CoreBundle\Helper\Redirect; +use Wallabag\CoreBundle\Repository\EntryRepository; +use Wallabag\CoreBundle\Repository\TagRepository; class EntryController extends Controller { /** * @Route("/mass", name="mass_action") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function massAction(Request $request) { $em = $this->getDoctrine()->getManager(); $values = $request->request->all(); + $tagsToAdd = []; + $tagsToRemove = []; + $action = 'toggle-read'; if (isset($values['toggle-star'])) { $action = 'toggle-star'; } elseif (isset($values['delete'])) { $action = 'delete'; + } elseif (isset($values['tag'])) { + $action = 'tag'; + + if (isset($values['tags'])) { + $labels = array_filter(explode(',', $values['tags']), + function ($v) { + $v = trim($v); + + return '' !== $v; + }); + foreach ($labels as $label) { + $remove = false; + if (0 === strpos($label, '-')) { + $label = substr($label, 1); + $remove = true; + } + $tag = $this->get(TagRepository::class)->findOneByLabel($label); + if ($remove) { + if (null !== $tag) { + $tagsToRemove[] = $tag; + } + } else { + if (null === $tag) { + $tag = new Tag(); + $tag->setLabel($label); + } + $tagsToAdd[] = $tag; + } + } + } } if (isset($values['entry-checkbox'])) { foreach ($values['entry-checkbox'] as $id) { /** @var Entry * */ - $entry = $this->get('wallabag_core.entry_repository')->findById((int) $id)[0]; + $entry = $this->get(EntryRepository::class)->findById((int) $id)[0]; $this->checkUserAction($entry); @@ -48,8 +94,15 @@ class EntryController extends Controller $entry->toggleArchive(); } elseif ('toggle-star' === $action) { $entry->toggleStar(); + } elseif ('tag' === $action) { + foreach ($tagsToAdd as $tag) { + $entry->addTag($tag); + } + foreach ($tagsToRemove as $tag) { + $entry->removeTag($tag); + } } elseif ('delete' === $action) { - $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); + $this->get(EventDispatcherInterface::class)->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); $em->remove($entry); } } @@ -57,7 +110,7 @@ class EntryController extends Controller $em->flush(); } - $redirectUrl = $this->get('wallabag_core.helper.redirect')->to($request->headers->get('referer')); + $redirectUrl = $this->get(Redirect::class)->to($request->headers->get('referer')); return $this->redirect($redirectUrl); } @@ -70,7 +123,7 @@ class EntryController extends Controller * Default parameter for page is hardcoded (in duplication of the defaults from the Route) * because this controller is also called inside the layout template without any page as argument * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function searchFormAction(Request $request, $page = 1, $currentRoute = null) { @@ -87,7 +140,7 @@ class EntryController extends Controller return $this->showEntries('search', $request, $page); } - return $this->render('WallabagCoreBundle:Entry:search_form.html.twig', [ + return $this->render('@WallabagCore/Entry/search_form.html.twig', [ 'form' => $form->createView(), 'currentRoute' => $currentRoute, ]); @@ -96,7 +149,7 @@ class EntryController extends Controller /** * @Route("/new-entry", name="new_entry") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function addEntryFormAction(Request $request) { @@ -110,9 +163,9 @@ class EntryController extends Controller $existingEntry = $this->checkIfEntryAlreadyExists($entry); if (false !== $existingEntry) { - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.entry.notice.entry_already_saved', ['%date%' => $existingEntry->getCreatedAt()->format('d-m-Y')]) + $this->get(TranslatorInterface::class)->trans('flashes.entry.notice.entry_already_saved', ['%date%' => $existingEntry->getCreatedAt()->format('d-m-Y')]) ); return $this->redirect($this->generateUrl('view', ['id' => $existingEntry->getId()])); @@ -125,12 +178,12 @@ class EntryController extends Controller $em->flush(); // entry saved, dispatch event about it! - $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); + $this->get(EventDispatcherInterface::class)->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); return $this->redirect($this->generateUrl('homepage')); } - return $this->render('WallabagCoreBundle:Entry:new_form.html.twig', [ + return $this->render('@WallabagCore/Entry/new_form.html.twig', [ 'form' => $form->createView(), ]); } @@ -138,7 +191,7 @@ class EntryController extends Controller /** * @Route("/bookmarklet", name="bookmarklet") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function addEntryViaBookmarkletAction(Request $request) { @@ -153,7 +206,7 @@ class EntryController extends Controller $em->flush(); // entry saved, dispatch event about it! - $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); + $this->get(EventDispatcherInterface::class)->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); } return $this->redirect($this->generateUrl('homepage')); @@ -162,11 +215,11 @@ class EntryController extends Controller /** * @Route("/new", name="new") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function addEntryAction() { - return $this->render('WallabagCoreBundle:Entry:new.html.twig'); + return $this->render('@WallabagCore/Entry/new.html.twig'); } /** @@ -174,7 +227,7 @@ class EntryController extends Controller * * @Route("/edit/{id}", requirements={"id" = "\d+"}, name="edit") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function editEntryAction(Request $request, Entry $entry) { @@ -189,7 +242,7 @@ class EntryController extends Controller $em->persist($entry); $em->flush(); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', 'flashes.entry.notice.entry_updated' ); @@ -197,7 +250,7 @@ class EntryController extends Controller return $this->redirect($this->generateUrl('view', ['id' => $entry->getId()])); } - return $this->render('WallabagCoreBundle:Entry:edit.html.twig', [ + return $this->render('@WallabagCore/Entry/edit.html.twig', [ 'form' => $form->createView(), ]); } @@ -209,7 +262,7 @@ class EntryController extends Controller * * @Route("/all/list/{page}", name="all", defaults={"page" = "1"}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showAllAction(Request $request, $page) { @@ -223,12 +276,12 @@ class EntryController extends Controller * * @Route("/unread/list/{page}", name="unread", defaults={"page" = "1"}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showUnreadAction(Request $request, $page) { // load the quickstart if no entry in database - if (1 === (int) $page && 0 === $this->get('wallabag_core.entry_repository')->countAllEntriesByUser($this->getUser()->getId())) { + if (1 === (int) $page && 0 === $this->get(EntryRepository::class)->countAllEntriesByUser($this->getUser()->getId())) { return $this->redirect($this->generateUrl('quickstart')); } @@ -242,7 +295,7 @@ class EntryController extends Controller * * @Route("/archive/list/{page}", name="archive", defaults={"page" = "1"}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showArchiveAction(Request $request, $page) { @@ -256,7 +309,7 @@ class EntryController extends Controller * * @Route("/starred/list/{page}", name="starred", defaults={"page" = "1"}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showStarredAction(Request $request, $page) { @@ -270,7 +323,7 @@ class EntryController extends Controller * * @Route("/untagged/list/{page}", name="untagged", defaults={"page" = "1"}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showUntaggedEntriesAction(Request $request, $page) { @@ -284,7 +337,7 @@ class EntryController extends Controller * * @Route("/annotated/list/{page}", name="annotated", defaults={"page" = "1"}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showWithAnnotationsEntriesAction(Request $request, $page) { @@ -298,15 +351,15 @@ class EntryController extends Controller * * @Route("/{type}/random", name="random_entry", requirements={"type": "unread|starred|archive|untagged|annotated|all"}) * - * @return \Symfony\Component\HttpFoundation\RedirectResponse + * @return RedirectResponse */ public function redirectRandomEntryAction($type = 'all') { try { - $entry = $this->get('wallabag_core.entry_repository') + $entry = $this->get(EntryRepository::class) ->getRandomEntry($this->getUser()->getId(), $type); } catch (NoResultException $e) { - $bag = $this->get('session')->getFlashBag(); + $bag = $this->get(SessionInterface::class)->getFlashBag(); $bag->clear(); $bag->add('notice', 'flashes.entry.notice.no_random_entry'); @@ -321,14 +374,14 @@ class EntryController extends Controller * * @Route("/view/{id}", requirements={"id" = "\d+"}, name="view") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function viewAction(Entry $entry) { $this->checkUserAction($entry); return $this->render( - 'WallabagCoreBundle:Entry:entry.html.twig', + '@WallabagCore/Entry/entry.html.twig', ['entry' => $entry] ); } @@ -339,7 +392,7 @@ class EntryController extends Controller * * @Route("/reload/{id}", requirements={"id" = "\d+"}, name="reload_entry") * - * @return \Symfony\Component\HttpFoundation\RedirectResponse + * @return RedirectResponse */ public function reloadAction(Entry $entry) { @@ -349,7 +402,7 @@ class EntryController extends Controller // if refreshing entry failed, don't save it if ($this->getParameter('wallabag_core.fetching_error_message') === $entry->getContent()) { - $bag = $this->get('session')->getFlashBag(); + $bag = $this->get(SessionInterface::class)->getFlashBag(); $bag->clear(); $bag->add('notice', 'flashes.entry.notice.entry_reloaded_failed'); @@ -361,7 +414,7 @@ class EntryController extends Controller $em->flush(); // entry saved, dispatch event about it! - $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); + $this->get(EventDispatcherInterface::class)->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); return $this->redirect($this->generateUrl('view', ['id' => $entry->getId()])); } @@ -371,7 +424,7 @@ class EntryController extends Controller * * @Route("/archive/{id}", requirements={"id" = "\d+"}, name="archive_entry") * - * @return \Symfony\Component\HttpFoundation\RedirectResponse + * @return RedirectResponse */ public function toggleArchiveAction(Request $request, Entry $entry) { @@ -385,12 +438,12 @@ class EntryController extends Controller $message = 'flashes.entry.notice.entry_archived'; } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', $message ); - $redirectUrl = $this->get('wallabag_core.helper.redirect')->to($request->headers->get('referer')); + $redirectUrl = $this->get(Redirect::class)->to($request->headers->get('referer')); return $this->redirect($redirectUrl); } @@ -400,7 +453,7 @@ class EntryController extends Controller * * @Route("/star/{id}", requirements={"id" = "\d+"}, name="star_entry") * - * @return \Symfony\Component\HttpFoundation\RedirectResponse + * @return RedirectResponse */ public function toggleStarAction(Request $request, Entry $entry) { @@ -415,12 +468,12 @@ class EntryController extends Controller $message = 'flashes.entry.notice.entry_starred'; } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', $message ); - $redirectUrl = $this->get('wallabag_core.helper.redirect')->to($request->headers->get('referer')); + $redirectUrl = $this->get(Redirect::class)->to($request->headers->get('referer')); return $this->redirect($redirectUrl); } @@ -430,7 +483,7 @@ class EntryController extends Controller * * @Route("/delete/{id}", requirements={"id" = "\d+"}, name="delete_entry") * - * @return \Symfony\Component\HttpFoundation\RedirectResponse + * @return RedirectResponse */ public function deleteEntryAction(Request $request, Entry $entry) { @@ -445,13 +498,13 @@ class EntryController extends Controller ); // entry deleted, dispatch event about it! - $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); + $this->get(EventDispatcherInterface::class)->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); $em = $this->getDoctrine()->getManager(); $em->remove($entry); $em->flush(); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', 'flashes.entry.notice.entry_deleted' ); @@ -460,7 +513,7 @@ class EntryController extends Controller $referer = $request->headers->get('referer'); $to = (1 !== preg_match('#' . $url . '$#i', $referer) ? $referer : null); - $redirectUrl = $this->get('wallabag_core.helper.redirect')->to($to); + $redirectUrl = $this->get(Redirect::class)->to($to); return $this->redirect($redirectUrl); } @@ -470,7 +523,7 @@ class EntryController extends Controller * * @Route("/share/{id}", requirements={"id" = "\d+"}, name="share") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function shareAction(Entry $entry) { @@ -494,7 +547,7 @@ class EntryController extends Controller * * @Route("/share/delete/{id}", requirements={"id" = "\d+"}, name="delete_share") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function deleteShareAction(Entry $entry) { @@ -517,11 +570,11 @@ class EntryController extends Controller * @Route("/share/{uid}", requirements={"uid" = ".+"}, name="share_entry") * @Cache(maxage="25200", smaxage="25200", public=true) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function shareEntryAction(Entry $entry) { - if (!$this->get('craue_config')->get('share_public')) { + if (!$this->get(Config::class)->get('share_public')) { throw $this->createAccessDeniedException('Sharing an entry is disabled for this user.'); } @@ -538,7 +591,7 @@ class EntryController extends Controller * * @Route("/domain/{id}/{page}", requirements={"id" = ".+"}, defaults={"page" = 1}, name="same_domain") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function getSameDomainEntries(Request $request, $page = 1) { @@ -552,11 +605,11 @@ class EntryController extends Controller * @param string $type Entries type: unread, starred or archive * @param int $page * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ private function showEntries($type, Request $request, $page) { - $repository = $this->get('wallabag_core.entry_repository'); + $repository = $this->get(EntryRepository::class); $searchTerm = (isset($request->get('search_entry')['term']) ? $request->get('search_entry')['term'] : ''); $currentRoute = (null !== $request->query->get('currentRoute') ? $request->query->get('currentRoute') : ''); @@ -601,12 +654,12 @@ class EntryController extends Controller $form->submit($request->query->get($form->getName())); // build the query from the given form object - $this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $qb); + $this->get(FilterBuilderUpdaterInterface::class)->addFilterConditions($form, $qb); } $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false); - $entries = $this->get('wallabag_core.helper.prepare_pager_for_entries')->prepare($pagerAdapter); + $entries = $this->get(PreparePagerForEntries::class)->prepare($pagerAdapter); try { $entries->setCurrentPage($page); @@ -616,11 +669,11 @@ class EntryController extends Controller } } - $nbEntriesUntagged = $this->get('wallabag_core.entry_repository') + $nbEntriesUntagged = $this->get(EntryRepository::class) ->countUntaggedEntriesByUser($this->getUser()->getId()); return $this->render( - 'WallabagCoreBundle:Entry:entries.html.twig', [ + '@WallabagCore/Entry/entries.html.twig', [ 'form' => $form->createView(), 'entries' => $entries, 'currentPage' => $page, @@ -642,7 +695,7 @@ class EntryController extends Controller $message = 'flashes.entry.notice.' . $prefixMessage; try { - $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl()); + $this->get(ContentProxy::class)->updateEntry($entry, $entry->getUrl()); } catch (\Exception $e) { $this->get('logger')->error('Error while saving an entry', [ 'exception' => $e, @@ -653,14 +706,14 @@ class EntryController extends Controller } if (empty($entry->getDomainName())) { - $this->get('wallabag_core.content_proxy')->setEntryDomainName($entry); + $this->get(ContentProxy::class)->setEntryDomainName($entry); } if (empty($entry->getTitle())) { - $this->get('wallabag_core.content_proxy')->setDefaultEntryTitle($entry); + $this->get(ContentProxy::class)->setDefaultEntryTitle($entry); } - $this->get('session')->getFlashBag()->add('notice', $message); + $this->get(SessionInterface::class)->getFlashBag()->add('notice', $message); } /** @@ -680,6 +733,6 @@ class EntryController extends Controller */ private function checkIfEntryAlreadyExists(Entry $entry) { - return $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($entry->getUrl(), $this->getUser()->getId()); + return $this->get(EntryRepository::class)->findByUrlAndUserId($entry->getUrl(), $this->getUser()->getId()); } } diff --git a/src/Wallabag/CoreBundle/Controller/ExceptionController.php b/src/Wallabag/CoreBundle/Controller/ExceptionController.php index 461309ea9..ffff3c85f 100644 --- a/src/Wallabag/CoreBundle/Controller/ExceptionController.php +++ b/src/Wallabag/CoreBundle/Controller/ExceptionController.php @@ -20,7 +20,7 @@ class ExceptionController extends BaseExceptionController // For error pages, try to find a template for the specific HTTP status code and format if (!$showException) { - $template = sprintf('WallabagCoreBundle:Exception:%s.%s.twig', $name, $format); + $template = sprintf('@WallabagCore/Exception/%s.%s.twig', $name, $format); if ($this->templateExists($template)) { return $template; } diff --git a/src/Wallabag/CoreBundle/Controller/ExportController.php b/src/Wallabag/CoreBundle/Controller/ExportController.php index 2db335527..5b2325507 100644 --- a/src/Wallabag/CoreBundle/Controller/ExportController.php +++ b/src/Wallabag/CoreBundle/Controller/ExportController.php @@ -4,9 +4,13 @@ namespace Wallabag\CoreBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Annotation\Route; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Helper\EntriesExport; +use Wallabag\CoreBundle\Repository\EntryRepository; +use Wallabag\CoreBundle\Repository\TagRepository; /** * The try/catch can be removed once all formats will be implemented. @@ -24,12 +28,12 @@ class ExportController extends Controller * "id": "\d+" * }) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function downloadEntryAction(Entry $entry, $format) { try { - return $this->get('wallabag_core.helper.entries_export') + return $this->get(EntriesExport::class) ->setEntries($entry) ->updateTitle('entry') ->updateAuthor('entry') @@ -50,17 +54,17 @@ class ExportController extends Controller * "category": "all|unread|starred|archive|tag_entries|untagged|search|annotated|same_domain" * }) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function downloadEntriesAction(Request $request, $format, $category) { $method = ucfirst($category); $methodBuilder = 'getBuilderFor' . $method . 'ByUser'; - $repository = $this->get('wallabag_core.entry_repository'); + $repository = $this->get(EntryRepository::class); $title = $method; if ('tag_entries' === $category) { - $tag = $this->get('wallabag_core.tag_repository')->findOneBySlug($request->query->get('tag')); + $tag = $this->get(TagRepository::class)->findOneBySlug($request->query->get('tag')); $entries = $repository->findAllByTagId( $this->getUser()->getId(), @@ -95,7 +99,7 @@ class ExportController extends Controller } try { - return $this->get('wallabag_core.helper.entries_export') + return $this->get(EntriesExport::class) ->setEntries($entries) ->updateTitle($title) ->updateAuthor($method) diff --git a/src/Wallabag/CoreBundle/Controller/FeedController.php b/src/Wallabag/CoreBundle/Controller/FeedController.php index 5e33839eb..3eed1dad4 100644 --- a/src/Wallabag/CoreBundle/Controller/FeedController.php +++ b/src/Wallabag/CoreBundle/Controller/FeedController.php @@ -14,6 +14,8 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Wallabag\CoreBundle\Entity\Tag; +use Wallabag\CoreBundle\Helper\PreparePagerForEntries; +use Wallabag\CoreBundle\Repository\EntryRepository; use Wallabag\UserBundle\Entity\User; class FeedController extends Controller @@ -23,11 +25,11 @@ class FeedController extends Controller * * @Route("/feed/{username}/{token}/unread/{page}", name="unread_feed", defaults={"page"=1, "_format"="xml"}) * - * @ParamConverter("user", class="WallabagUserBundle:User", converter="username_feed_token_converter") + * @ParamConverter("user", class="Wallabag\UserBundle\Entity\User", converter="username_feed_token_converter") * * @param $page * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showUnreadFeedAction(User $user, $page) { @@ -39,11 +41,11 @@ class FeedController extends Controller * * @Route("/feed/{username}/{token}/archive/{page}", name="archive_feed", defaults={"page"=1, "_format"="xml"}) * - * @ParamConverter("user", class="WallabagUserBundle:User", converter="username_feed_token_converter") + * @ParamConverter("user", class="Wallabag\UserBundle\Entity\User", converter="username_feed_token_converter") * * @param $page * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showArchiveFeedAction(User $user, $page) { @@ -55,11 +57,11 @@ class FeedController extends Controller * * @Route("/feed/{username}/{token}/starred/{page}", name="starred_feed", defaults={"page"=1, "_format"="xml"}) * - * @ParamConverter("user", class="WallabagUserBundle:User", converter="username_feed_token_converter") + * @ParamConverter("user", class="Wallabag\UserBundle\Entity\User", converter="username_feed_token_converter") * * @param $page * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showStarredFeedAction(User $user, $page) { @@ -71,9 +73,9 @@ class FeedController extends Controller * * @Route("/feed/{username}/{token}/all/{page}", name="all_feed", defaults={"page"=1, "_format"="xml"}) * - * @ParamConverter("user", class="WallabagUserBundle:User", converter="username_feed_token_converter") + * @ParamConverter("user", class="Wallabag\UserBundle\Entity\User", converter="username_feed_token_converter") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showAllFeedAction(User $user, $page) { @@ -85,10 +87,10 @@ class FeedController extends Controller * * @Route("/feed/{username}/{token}/tags/{slug}/{page}", name="tag_feed", defaults={"page"=1, "_format"="xml"}) * - * @ParamConverter("user", class="WallabagUserBundle:User", converter="username_feed_token_converter") + * @ParamConverter("user", class="Wallabag\UserBundle\Entity\User", converter="username_feed_token_converter") * @ParamConverter("tag", options={"mapping": {"slug": "slug"}}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showTagsFeedAction(Request $request, User $user, Tag $tag, $page) { @@ -113,7 +115,7 @@ class FeedController extends Controller UrlGeneratorInterface::ABSOLUTE_URL ); - $entriesByTag = $this->get('wallabag_core.entry_repository')->findAllByTagId( + $entriesByTag = $this->get(EntryRepository::class)->findAllByTagId( $user->getId(), $tag->getId(), $sorts[$sort] @@ -121,7 +123,7 @@ class FeedController extends Controller $pagerAdapter = new ArrayAdapter($entriesByTag); - $entries = $this->get('wallabag_core.helper.prepare_pager_for_entries')->prepare( + $entries = $this->get(PreparePagerForEntries::class)->prepare( $pagerAdapter, $user ); @@ -180,11 +182,11 @@ class FeedController extends Controller * @param string $type Entries type: unread, starred or archive * @param int $page * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ private function showEntries($type, User $user, $page = 1) { - $repository = $this->get('wallabag_core.entry_repository'); + $repository = $this->get(EntryRepository::class); switch ($type) { case 'starred': diff --git a/src/Wallabag/CoreBundle/Controller/IgnoreOriginInstanceRuleController.php b/src/Wallabag/CoreBundle/Controller/IgnoreOriginInstanceRuleController.php index ef1f0ed74..22fbf5fa0 100644 --- a/src/Wallabag/CoreBundle/Controller/IgnoreOriginInstanceRuleController.php +++ b/src/Wallabag/CoreBundle/Controller/IgnoreOriginInstanceRuleController.php @@ -3,9 +3,16 @@ namespace Wallabag\CoreBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\Form\Form; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule; +use Wallabag\CoreBundle\Form\Type\IgnoreOriginInstanceRuleType; +use Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository; /** * IgnoreOriginInstanceRuleController controller. @@ -21,9 +28,9 @@ class IgnoreOriginInstanceRuleController extends Controller */ public function indexAction() { - $rules = $this->get('wallabag_core.ignore_origin_instance_rule_repository')->findAll(); + $rules = $this->get(IgnoreOriginInstanceRuleRepository::class)->findAll(); - return $this->render('WallabagCoreBundle:IgnoreOriginInstanceRule:index.html.twig', [ + return $this->render('@WallabagCore/IgnoreOriginInstanceRule/index.html.twig', [ 'rules' => $rules, ]); } @@ -33,13 +40,13 @@ class IgnoreOriginInstanceRuleController extends Controller * * @Route("/new", name="ignore_origin_instance_rules_new", methods={"GET", "POST"}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function newAction(Request $request) { $ignoreOriginInstanceRule = new IgnoreOriginInstanceRule(); - $form = $this->createForm('Wallabag\CoreBundle\Form\Type\IgnoreOriginInstanceRuleType', $ignoreOriginInstanceRule); + $form = $this->createForm(IgnoreOriginInstanceRuleType::class, $ignoreOriginInstanceRule); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { @@ -47,15 +54,15 @@ class IgnoreOriginInstanceRuleController extends Controller $em->persist($ignoreOriginInstanceRule); $em->flush(); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.ignore_origin_instance_rule.notice.added') + $this->get(TranslatorInterface::class)->trans('flashes.ignore_origin_instance_rule.notice.added') ); return $this->redirectToRoute('ignore_origin_instance_rules_index'); } - return $this->render('WallabagCoreBundle:IgnoreOriginInstanceRule:new.html.twig', [ + return $this->render('@WallabagCore/IgnoreOriginInstanceRule/new.html.twig', [ 'rule' => $ignoreOriginInstanceRule, 'form' => $form->createView(), ]); @@ -66,12 +73,12 @@ class IgnoreOriginInstanceRuleController extends Controller * * @Route("/{id}/edit", name="ignore_origin_instance_rules_edit", methods={"GET", "POST"}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function editAction(Request $request, IgnoreOriginInstanceRule $ignoreOriginInstanceRule) { $deleteForm = $this->createDeleteForm($ignoreOriginInstanceRule); - $editForm = $this->createForm('Wallabag\CoreBundle\Form\Type\IgnoreOriginInstanceRuleType', $ignoreOriginInstanceRule); + $editForm = $this->createForm(IgnoreOriginInstanceRuleType::class, $ignoreOriginInstanceRule); $editForm->handleRequest($request); if ($editForm->isSubmitted() && $editForm->isValid()) { @@ -79,15 +86,15 @@ class IgnoreOriginInstanceRuleController extends Controller $em->persist($ignoreOriginInstanceRule); $em->flush(); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.ignore_origin_instance_rule.notice.updated') + $this->get(TranslatorInterface::class)->trans('flashes.ignore_origin_instance_rule.notice.updated') ); return $this->redirectToRoute('ignore_origin_instance_rules_index'); } - return $this->render('WallabagCoreBundle:IgnoreOriginInstanceRule:edit.html.twig', [ + return $this->render('@WallabagCore/IgnoreOriginInstanceRule/edit.html.twig', [ 'rule' => $ignoreOriginInstanceRule, 'edit_form' => $editForm->createView(), 'delete_form' => $deleteForm->createView(), @@ -99,7 +106,7 @@ class IgnoreOriginInstanceRuleController extends Controller * * @Route("/{id}", name="ignore_origin_instance_rules_delete", methods={"DELETE"}) * - * @return \Symfony\Component\HttpFoundation\RedirectResponse + * @return RedirectResponse */ public function deleteAction(Request $request, IgnoreOriginInstanceRule $ignoreOriginInstanceRule) { @@ -107,9 +114,9 @@ class IgnoreOriginInstanceRuleController extends Controller $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.ignore_origin_instance_rule.notice.deleted') + $this->get(TranslatorInterface::class)->trans('flashes.ignore_origin_instance_rule.notice.deleted') ); $em = $this->getDoctrine()->getManager(); @@ -125,7 +132,7 @@ class IgnoreOriginInstanceRuleController extends Controller * * @param IgnoreOriginInstanceRule $ignoreOriginInstanceRule The ignore origin instance rule entity * - * @return \Symfony\Component\Form\Form The form + * @return Form The form */ private function createDeleteForm(IgnoreOriginInstanceRule $ignoreOriginInstanceRule) { diff --git a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php index 4320c5ffe..67b262947 100644 --- a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php +++ b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php @@ -2,10 +2,19 @@ namespace Wallabag\CoreBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\Form\Form; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\CoreBundle\Entity\SiteCredential; +use Wallabag\CoreBundle\Form\Type\SiteCredentialType; +use Wallabag\CoreBundle\Helper\CryptoProxy; +use Wallabag\CoreBundle\Repository\SiteCredentialRepository; use Wallabag\UserBundle\Entity\User; /** @@ -24,9 +33,9 @@ class SiteCredentialController extends Controller { $this->isSiteCredentialsEnabled(); - $credentials = $this->get('wallabag_core.site_credential_repository')->findByUser($this->getUser()); + $credentials = $this->get(SiteCredentialRepository::class)->findByUser($this->getUser()); - return $this->render('WallabagCoreBundle:SiteCredential:index.html.twig', [ + return $this->render('@WallabagCore/SiteCredential/index.html.twig', [ 'credentials' => $credentials, ]); } @@ -36,7 +45,7 @@ class SiteCredentialController extends Controller * * @Route("/new", name="site_credentials_new", methods={"GET", "POST"}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function newAction(Request $request) { @@ -44,26 +53,26 @@ class SiteCredentialController extends Controller $credential = new SiteCredential($this->getUser()); - $form = $this->createForm('Wallabag\CoreBundle\Form\Type\SiteCredentialType', $credential); + $form = $this->createForm(SiteCredentialType::class, $credential); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $credential->setUsername($this->get('wallabag_core.helper.crypto_proxy')->crypt($credential->getUsername())); - $credential->setPassword($this->get('wallabag_core.helper.crypto_proxy')->crypt($credential->getPassword())); + $credential->setUsername($this->get(CryptoProxy::class)->crypt($credential->getUsername())); + $credential->setPassword($this->get(CryptoProxy::class)->crypt($credential->getPassword())); $em = $this->getDoctrine()->getManager(); $em->persist($credential); $em->flush(); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.site_credential.notice.added', ['%host%' => $credential->getHost()]) + $this->get(TranslatorInterface::class)->trans('flashes.site_credential.notice.added', ['%host%' => $credential->getHost()]) ); return $this->redirectToRoute('site_credentials_index'); } - return $this->render('WallabagCoreBundle:SiteCredential:new.html.twig', [ + return $this->render('@WallabagCore/SiteCredential/new.html.twig', [ 'credential' => $credential, 'form' => $form->createView(), ]); @@ -74,7 +83,7 @@ class SiteCredentialController extends Controller * * @Route("/{id}/edit", name="site_credentials_edit", methods={"GET", "POST"}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function editAction(Request $request, SiteCredential $siteCredential) { @@ -83,26 +92,26 @@ class SiteCredentialController extends Controller $this->checkUserAction($siteCredential); $deleteForm = $this->createDeleteForm($siteCredential); - $editForm = $this->createForm('Wallabag\CoreBundle\Form\Type\SiteCredentialType', $siteCredential); + $editForm = $this->createForm(SiteCredentialType::class, $siteCredential); $editForm->handleRequest($request); if ($editForm->isSubmitted() && $editForm->isValid()) { - $siteCredential->setUsername($this->get('wallabag_core.helper.crypto_proxy')->crypt($siteCredential->getUsername())); - $siteCredential->setPassword($this->get('wallabag_core.helper.crypto_proxy')->crypt($siteCredential->getPassword())); + $siteCredential->setUsername($this->get(CryptoProxy::class)->crypt($siteCredential->getUsername())); + $siteCredential->setPassword($this->get(CryptoProxy::class)->crypt($siteCredential->getPassword())); $em = $this->getDoctrine()->getManager(); $em->persist($siteCredential); $em->flush(); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.site_credential.notice.updated', ['%host%' => $siteCredential->getHost()]) + $this->get(TranslatorInterface::class)->trans('flashes.site_credential.notice.updated', ['%host%' => $siteCredential->getHost()]) ); return $this->redirectToRoute('site_credentials_index'); } - return $this->render('WallabagCoreBundle:SiteCredential:edit.html.twig', [ + return $this->render('@WallabagCore/SiteCredential/edit.html.twig', [ 'credential' => $siteCredential, 'edit_form' => $editForm->createView(), 'delete_form' => $deleteForm->createView(), @@ -114,7 +123,7 @@ class SiteCredentialController extends Controller * * @Route("/{id}", name="site_credentials_delete", methods={"DELETE"}) * - * @return \Symfony\Component\HttpFoundation\RedirectResponse + * @return RedirectResponse */ public function deleteAction(Request $request, SiteCredential $siteCredential) { @@ -126,9 +135,9 @@ class SiteCredentialController extends Controller $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.site_credential.notice.deleted', ['%host%' => $siteCredential->getHost()]) + $this->get(TranslatorInterface::class)->trans('flashes.site_credential.notice.deleted', ['%host%' => $siteCredential->getHost()]) ); $em = $this->getDoctrine()->getManager(); @@ -144,7 +153,7 @@ class SiteCredentialController extends Controller */ private function isSiteCredentialsEnabled() { - if (!$this->get('craue_config')->get('restricted_access')) { + if (!$this->get(Config::class)->get('restricted_access')) { throw $this->createNotFoundException('Feature "restricted_access" is disabled, controllers too.'); } } @@ -154,7 +163,7 @@ class SiteCredentialController extends Controller * * @param SiteCredential $siteCredential The site credential entity * - * @return \Symfony\Component\Form\Form The form + * @return Form The form */ private function createDeleteForm(SiteCredential $siteCredential) { diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php index 7df73e8c7..b32f3ad31 100644 --- a/src/Wallabag/CoreBundle/Controller/TagController.php +++ b/src/Wallabag/CoreBundle/Controller/TagController.php @@ -8,18 +8,25 @@ use Pagerfanta\Exception\OutOfRangeCurrentPageException; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Tag; use Wallabag\CoreBundle\Form\Type\NewTagType; use Wallabag\CoreBundle\Form\Type\RenameTagType; +use Wallabag\CoreBundle\Helper\PreparePagerForEntries; +use Wallabag\CoreBundle\Helper\Redirect; +use Wallabag\CoreBundle\Helper\TagsAssigner; +use Wallabag\CoreBundle\Repository\EntryRepository; +use Wallabag\CoreBundle\Repository\TagRepository; class TagController extends Controller { /** * @Route("/new-tag/{entry}", requirements={"entry" = "\d+"}, name="new_tag") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function addTagFormAction(Request $request, Entry $entry) { @@ -27,7 +34,7 @@ class TagController extends Controller $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $this->get('wallabag_core.tags_assigner')->assignTagsToEntry( + $this->get(TagsAssigner::class)->assignTagsToEntry( $entry, $form->get('label')->getData() ); @@ -36,7 +43,7 @@ class TagController extends Controller $em->persist($entry); $em->flush(); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', 'flashes.tag.notice.tag_added' ); @@ -44,7 +51,7 @@ class TagController extends Controller return $this->redirect($this->generateUrl('view', ['id' => $entry->getId()])); } - return $this->render('WallabagCoreBundle:Tag:new_form.html.twig', [ + return $this->render('@WallabagCore/Tag/new_form.html.twig', [ 'form' => $form->createView(), 'entry' => $entry, ]); @@ -55,7 +62,7 @@ class TagController extends Controller * * @Route("/remove-tag/{entry}/{tag}", requirements={"entry" = "\d+", "tag" = "\d+"}, name="remove_tag") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function removeTagFromEntry(Request $request, Entry $entry, Tag $tag) { @@ -69,7 +76,7 @@ class TagController extends Controller $em->flush(); } - $redirectUrl = $this->get('wallabag_core.helper.redirect')->to($request->headers->get('referer'), '', true); + $redirectUrl = $this->get(Redirect::class)->to($request->headers->get('referer'), '', true); return $this->redirect($redirectUrl); } @@ -79,13 +86,13 @@ class TagController extends Controller * * @Route("/tag/list", name="tag") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showTagAction() { - $tags = $this->get('wallabag_core.tag_repository') + $tags = $this->get(TagRepository::class) ->findAllFlatTagsWithNbEntries($this->getUser()->getId()); - $nbEntriesUntagged = $this->get('wallabag_core.entry_repository') + $nbEntriesUntagged = $this->get(EntryRepository::class) ->countUntaggedEntriesByUser($this->getUser()->getId()); $renameForms = []; @@ -93,7 +100,7 @@ class TagController extends Controller $renameForms[$tag['id']] = $this->createForm(RenameTagType::class, new Tag())->createView(); } - return $this->render('WallabagCoreBundle:Tag:tags.html.twig', [ + return $this->render('@WallabagCore/Tag/tags.html.twig', [ 'tags' => $tags, 'renameForms' => $renameForms, 'nbEntriesUntagged' => $nbEntriesUntagged, @@ -106,18 +113,18 @@ class TagController extends Controller * @Route("/tag/list/{slug}/{page}", name="tag_entries", defaults={"page" = "1"}) * @ParamConverter("tag", options={"mapping": {"slug": "slug"}}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function showEntriesForTagAction(Tag $tag, $page, Request $request) { - $entriesByTag = $this->get('wallabag_core.entry_repository')->findAllByTagId( + $entriesByTag = $this->get(EntryRepository::class)->findAllByTagId( $this->getUser()->getId(), $tag->getId() ); $pagerAdapter = new ArrayAdapter($entriesByTag); - $entries = $this->get('wallabag_core.helper.prepare_pager_for_entries')->prepare($pagerAdapter); + $entries = $this->get(PreparePagerForEntries::class)->prepare($pagerAdapter); try { $entries->setCurrentPage($page); @@ -130,7 +137,7 @@ class TagController extends Controller } } - return $this->render('WallabagCoreBundle:Entry:entries.html.twig', [ + return $this->render('@WallabagCore/Entry/entries.html.twig', [ 'form' => null, 'entries' => $entries, 'currentPage' => $page, @@ -145,14 +152,14 @@ class TagController extends Controller * @Route("/tag/rename/{slug}", name="tag_rename") * @ParamConverter("tag", options={"mapping": {"slug": "slug"}}) * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function renameTagAction(Tag $tag, Request $request) { $form = $this->createForm(RenameTagType::class, new Tag()); $form->handleRequest($request); - $redirectUrl = $this->get('wallabag_core.helper.redirect')->to($request->headers->get('referer'), '', true); + $redirectUrl = $this->get(Redirect::class)->to($request->headers->get('referer'), '', true); if ($form->isSubmitted() && $form->isValid()) { $newTag = new Tag(); @@ -162,18 +169,18 @@ class TagController extends Controller return $this->redirect($redirectUrl); } - $tagFromRepo = $this->get('wallabag_core.tag_repository')->findOneByLabel($newTag->getLabel()); + $tagFromRepo = $this->get(TagRepository::class)->findOneByLabel($newTag->getLabel()); if (null !== $tagFromRepo) { $newTag = $tagFromRepo; } - $entries = $this->get('wallabag_core.entry_repository')->findAllByTagId( + $entries = $this->get(EntryRepository::class)->findAllByTagId( $this->getUser()->getId(), $tag->getId() ); foreach ($entries as $entry) { - $this->get('wallabag_core.tags_assigner')->assignTagsToEntry( + $this->get(TagsAssigner::class)->assignTagsToEntry( $entry, $newTag->getLabel(), [$newTag] @@ -183,7 +190,7 @@ class TagController extends Controller $this->getDoctrine()->getManager()->flush(); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', 'flashes.tag.notice.tag_renamed' ); @@ -197,20 +204,20 @@ class TagController extends Controller * * @Route("/tag/search/{filter}", name="tag_this_search") * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function tagThisSearchAction($filter, Request $request) { $currentRoute = $request->query->has('currentRoute') ? $request->query->get('currentRoute') : ''; /** @var QueryBuilder $qb */ - $qb = $this->get('wallabag_core.entry_repository')->getBuilderForSearchByUser($this->getUser()->getId(), $filter, $currentRoute); + $qb = $this->get(EntryRepository::class)->getBuilderForSearchByUser($this->getUser()->getId(), $filter, $currentRoute); $em = $this->getDoctrine()->getManager(); $entries = $qb->getQuery()->getResult(); foreach ($entries as $entry) { - $this->get('wallabag_core.tags_assigner')->assignTagsToEntry( + $this->get(TagsAssigner::class)->assignTagsToEntry( $entry, $filter ); @@ -220,6 +227,32 @@ class TagController extends Controller $em->flush(); - return $this->redirect($this->get('wallabag_core.helper.redirect')->to($request->headers->get('referer'), '', true)); + return $this->redirect($this->get(Redirect::class)->to($request->headers->get('referer'), '', true)); + } + + /** + * Delete a given tag for the current user. + * + * @Route("/tag/delete/{slug}", name="tag_delete") + * @ParamConverter("tag", options={"mapping": {"slug": "slug"}}) + * + * @return Response + */ + public function removeTagAction(Tag $tag, Request $request) + { + foreach ($tag->getEntriesByUserId($this->getUser()->getId()) as $entry) { + $this->get(EntryRepository::class)->removeTag($this->getUser()->getId(), $tag); + } + + // remove orphan tag in case no entries are associated to it + if (0 === \count($tag->getEntries())) { + $em = $this->getDoctrine()->getManager(); + $em->remove($tag); + $em->flush(); + } + + $redirectUrl = $this->get(Redirect::class)->to($request->headers->get('referer'), '', true); + + return $this->redirect($redirectUrl); } } diff --git a/src/Wallabag/CoreBundle/DataFixtures/SiteCredentialFixtures.php b/src/Wallabag/CoreBundle/DataFixtures/SiteCredentialFixtures.php index ffcce7173..68cbe2182 100644 --- a/src/Wallabag/CoreBundle/DataFixtures/SiteCredentialFixtures.php +++ b/src/Wallabag/CoreBundle/DataFixtures/SiteCredentialFixtures.php @@ -8,6 +8,7 @@ use Doctrine\Persistence\ObjectManager; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Wallabag\CoreBundle\Entity\SiteCredential; +use Wallabag\CoreBundle\Helper\CryptoProxy; use Wallabag\UserBundle\DataFixtures\UserFixtures; class SiteCredentialFixtures extends Fixture implements DependentFixtureInterface, ContainerAwareInterface @@ -29,15 +30,15 @@ class SiteCredentialFixtures extends Fixture implements DependentFixtureInterfac { $credential = new SiteCredential($this->getReference('admin-user')); $credential->setHost('.super.com'); - $credential->setUsername($this->container->get('wallabag_core.helper.crypto_proxy')->crypt('.super')); - $credential->setPassword($this->container->get('wallabag_core.helper.crypto_proxy')->crypt('bar')); + $credential->setUsername($this->container->get(CryptoProxy::class)->crypt('.super')); + $credential->setPassword($this->container->get(CryptoProxy::class)->crypt('bar')); $manager->persist($credential); $credential = new SiteCredential($this->getReference('admin-user')); $credential->setHost('paywall.example.com'); - $credential->setUsername($this->container->get('wallabag_core.helper.crypto_proxy')->crypt('paywall.example')); - $credential->setPassword($this->container->get('wallabag_core.helper.crypto_proxy')->crypt('bar')); + $credential->setUsername($this->container->get(CryptoProxy::class)->crypt('paywall.example')); + $credential->setPassword($this->container->get(CryptoProxy::class)->crypt('bar')); $manager->persist($credential); diff --git a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php index af91e5886..ac47656c3 100644 --- a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php +++ b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php @@ -2,9 +2,7 @@ namespace Wallabag\CoreBundle\DependencyInjection; -use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; class WallabagCoreExtension extends Extension @@ -31,10 +29,6 @@ class WallabagCoreExtension extends Extension $container->setParameter('wallabag_core.default_internal_settings', $config['default_internal_settings']); $container->setParameter('wallabag_core.site_credentials.encryption_key_path', $config['encryption_key_path']); $container->setParameter('wallabag_core.default_ignore_origin_instance_rules', $config['default_ignore_origin_instance_rules']); - - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); - $loader->load('services.yml'); - $loader->load('parameters.yml'); } public function getAlias() diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index f4e988e2b..5a00c0dbe 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php @@ -881,7 +881,7 @@ class Entry } /** - * @return \Datetime + * @return \DateTime */ public function getPublishedAt() { @@ -891,7 +891,7 @@ class Entry /** * @return Entry */ - public function setPublishedAt(\Datetime $publishedAt) + public function setPublishedAt(\DateTime $publishedAt) { $this->publishedAt = $publishedAt; diff --git a/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php index ef8d7d3bc..125a6f124 100644 --- a/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php +++ b/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php @@ -2,7 +2,7 @@ namespace Wallabag\CoreBundle\Event\Subscriber; -use Doctrine\ORM\EntityManager; +use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Wallabag\CoreBundle\Entity\Entry; @@ -17,7 +17,7 @@ class DownloadImagesSubscriber implements EventSubscriberInterface private $enabled; private $logger; - public function __construct(EntityManager $em, DownloadImages $downloadImages, $enabled, LoggerInterface $logger) + public function __construct(EntityManagerInterface $em, DownloadImages $downloadImages, $enabled, LoggerInterface $logger) { $this->em = $em; $this->downloadImages = $downloadImages; diff --git a/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php index dcadeedfc..7dd95994a 100644 --- a/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php +++ b/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php @@ -4,6 +4,7 @@ namespace Wallabag\CoreBundle\Event\Subscriber; use Doctrine\Bundle\DoctrineBundle\Registry; use Doctrine\Common\EventSubscriber; +use Doctrine\DBAL\Platforms\SqlitePlatform; use Doctrine\ORM\Event\LifecycleEventArgs; use Wallabag\CoreBundle\Entity\Entry; @@ -40,7 +41,7 @@ class SQLiteCascadeDeleteSubscriber implements EventSubscriber public function preRemove(LifecycleEventArgs $args) { $entity = $args->getEntity(); - if (!$this->doctrine->getConnection()->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform + if (!$this->doctrine->getConnection()->getDatabasePlatform() instanceof SqlitePlatform || !$entity instanceof Entry) { return; } diff --git a/src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php index fb8f225fc..939db34d0 100644 --- a/src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php +++ b/src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php @@ -18,11 +18,11 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo; */ class TablePrefixSubscriber implements EventSubscriber { - protected $prefix = ''; + protected $tablePrefix = ''; - public function __construct($prefix) + public function __construct($tablePrefix) { - $this->prefix = (string) $prefix; + $this->tablePrefix = (string) $tablePrefix; } public function getSubscribedEvents() @@ -39,12 +39,12 @@ class TablePrefixSubscriber implements EventSubscriber return; } - $classMetadata->setPrimaryTable(['name' => $this->prefix . $classMetadata->getTableName()]); + $classMetadata->setPrimaryTable(['name' => $this->tablePrefix . $classMetadata->getTableName()]); foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) { if (ClassMetadataInfo::MANY_TO_MANY === $mapping['type'] && isset($classMetadata->associationMappings[$fieldName]['joinTable']['name'])) { $mappedTableName = $classMetadata->associationMappings[$fieldName]['joinTable']['name']; - $classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName; + $classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->tablePrefix . $mappedTableName; } } } diff --git a/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php b/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php index 81c4a6166..70553a3da 100644 --- a/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php +++ b/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php @@ -8,7 +8,8 @@ use Symfony\Component\Form\Extension\Core\Type\RepeatedType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Security\Core\Validator\Constraints\UserPassword; -use Symfony\Component\Validator\Constraints; +use Symfony\Component\Validator\Constraints\Length; +use Symfony\Component\Validator\Constraints\NotBlank; class ChangePasswordType extends AbstractType { @@ -26,11 +27,11 @@ class ChangePasswordType extends AbstractType 'first_options' => ['label' => 'config.form_password.new_password_label'], 'second_options' => ['label' => 'config.form_password.repeat_new_password_label'], 'constraints' => [ - new Constraints\Length([ + new Length([ 'min' => 8, 'minMessage' => 'validator.password_too_short', ]), - new Constraints\NotBlank(), + new NotBlank(), ], 'label' => 'config.form_password.new_password_label', ]) diff --git a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php index af916b29f..2ea776512 100644 --- a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php +++ b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php @@ -77,7 +77,7 @@ class ConfigType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\CoreBundle\Entity\Config', + 'data_class' => Config::class, ]); } diff --git a/src/Wallabag/CoreBundle/Form/Type/EditEntryType.php b/src/Wallabag/CoreBundle/Form/Type/EditEntryType.php index 2fc4c204b..911616594 100644 --- a/src/Wallabag/CoreBundle/Form/Type/EditEntryType.php +++ b/src/Wallabag/CoreBundle/Form/Type/EditEntryType.php @@ -8,6 +8,7 @@ use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\UrlType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\CoreBundle\Entity\Entry; class EditEntryType extends AbstractType { @@ -39,7 +40,7 @@ class EditEntryType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\CoreBundle\Entity\Entry', + 'data_class' => Entry::class, ]); } diff --git a/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php b/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php index ba2f53662..44448bfb7 100644 --- a/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php +++ b/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php @@ -2,7 +2,6 @@ namespace Wallabag\CoreBundle\Form\Type; -use Doctrine\ORM\EntityRepository; use Lexik\Bundle\FormFilterBundle\Filter\FilterOperands; use Lexik\Bundle\FormFilterBundle\Filter\Form\Type\CheckboxFilterType; use Lexik\Bundle\FormFilterBundle\Filter\Form\Type\ChoiceFilterType; @@ -15,6 +14,7 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Wallabag\CoreBundle\Repository\EntryRepository; class EntryFilterType extends AbstractType { @@ -24,7 +24,7 @@ class EntryFilterType extends AbstractType /** * Repository & user are used to get a list of language entries for this user. */ - public function __construct(EntityRepository $entryRepository, TokenStorageInterface $tokenStorage) + public function __construct(EntryRepository $entryRepository, TokenStorageInterface $tokenStorage) { $this->repository = $entryRepository; diff --git a/src/Wallabag/CoreBundle/Form/Type/FeedType.php b/src/Wallabag/CoreBundle/Form/Type/FeedType.php index 9b34daf4c..b2ebddb38 100644 --- a/src/Wallabag/CoreBundle/Form/Type/FeedType.php +++ b/src/Wallabag/CoreBundle/Form/Type/FeedType.php @@ -6,6 +6,7 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\CoreBundle\Entity\Config; class FeedType extends AbstractType { @@ -25,7 +26,7 @@ class FeedType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\CoreBundle\Entity\Config', + 'data_class' => Config::class, ]); } diff --git a/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginInstanceRuleType.php b/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginInstanceRuleType.php index d2e414fb7..608cbf7cf 100644 --- a/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginInstanceRuleType.php +++ b/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginInstanceRuleType.php @@ -7,6 +7,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule; class IgnoreOriginInstanceRuleType extends AbstractType { @@ -26,7 +27,7 @@ class IgnoreOriginInstanceRuleType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule', + 'data_class' => IgnoreOriginInstanceRule::class, ]); } diff --git a/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginUserRuleType.php b/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginUserRuleType.php index b9110f17b..7e96b144f 100644 --- a/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginUserRuleType.php +++ b/src/Wallabag/CoreBundle/Form/Type/IgnoreOriginUserRuleType.php @@ -7,6 +7,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule; class IgnoreOriginUserRuleType extends AbstractType { @@ -26,7 +27,7 @@ class IgnoreOriginUserRuleType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\CoreBundle\Entity\IgnoreOriginUserRule', + 'data_class' => IgnoreOriginUserRule::class, ]); } diff --git a/src/Wallabag/CoreBundle/Form/Type/NewEntryType.php b/src/Wallabag/CoreBundle/Form/Type/NewEntryType.php index 7af1e5895..ecbd68ba7 100644 --- a/src/Wallabag/CoreBundle/Form/Type/NewEntryType.php +++ b/src/Wallabag/CoreBundle/Form/Type/NewEntryType.php @@ -6,6 +6,7 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\UrlType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\CoreBundle\Entity\Entry; class NewEntryType extends AbstractType { @@ -23,7 +24,7 @@ class NewEntryType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\CoreBundle\Entity\Entry', + 'data_class' => Entry::class, ]); } diff --git a/src/Wallabag/CoreBundle/Form/Type/NewTagType.php b/src/Wallabag/CoreBundle/Form/Type/NewTagType.php index e830ade48..ed4fa67a2 100644 --- a/src/Wallabag/CoreBundle/Form/Type/NewTagType.php +++ b/src/Wallabag/CoreBundle/Form/Type/NewTagType.php @@ -7,6 +7,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\CoreBundle\Entity\Tag; class NewTagType extends AbstractType { @@ -28,7 +29,7 @@ class NewTagType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\CoreBundle\Entity\Tag', + 'data_class' => Tag::class, ]); } diff --git a/src/Wallabag/CoreBundle/Form/Type/RenameTagType.php b/src/Wallabag/CoreBundle/Form/Type/RenameTagType.php index e62700487..a639b4e9e 100644 --- a/src/Wallabag/CoreBundle/Form/Type/RenameTagType.php +++ b/src/Wallabag/CoreBundle/Form/Type/RenameTagType.php @@ -6,6 +6,7 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\CoreBundle\Entity\Tag; class RenameTagType extends AbstractType { @@ -24,7 +25,7 @@ class RenameTagType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\CoreBundle\Entity\Tag', + 'data_class' => Tag::class, ]); } diff --git a/src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php b/src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php index fd409ad2c..0bf1acb60 100644 --- a/src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php +++ b/src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php @@ -8,6 +8,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\CoreBundle\Entity\SiteCredential; class SiteCredentialType extends AbstractType { @@ -33,7 +34,7 @@ class SiteCredentialType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\CoreBundle\Entity\SiteCredential', + 'data_class' => SiteCredential::class, ]); } diff --git a/src/Wallabag/CoreBundle/Form/Type/TaggingRuleType.php b/src/Wallabag/CoreBundle/Form/Type/TaggingRuleType.php index 732606c91..1a356df53 100644 --- a/src/Wallabag/CoreBundle/Form/Type/TaggingRuleType.php +++ b/src/Wallabag/CoreBundle/Form/Type/TaggingRuleType.php @@ -7,6 +7,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\CoreBundle\Entity\TaggingRule; use Wallabag\CoreBundle\Form\DataTransformer\StringToListTransformer; class TaggingRuleType extends AbstractType @@ -35,7 +36,7 @@ class TaggingRuleType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\CoreBundle\Entity\TaggingRule', + 'data_class' => TaggingRule::class, ]); } diff --git a/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php b/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php index 6e4c9154c..c8544e428 100644 --- a/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php +++ b/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php @@ -2,6 +2,7 @@ namespace Wallabag\CoreBundle\Form\Type; +use FOS\UserBundle\Form\Type\RegistrationFormType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\EmailType; @@ -9,6 +10,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\UserBundle\Entity\User; class UserInformationType extends AbstractType { @@ -40,13 +42,13 @@ class UserInformationType extends AbstractType public function getParent() { - return 'FOS\UserBundle\Form\Type\RegistrationFormType'; + return RegistrationFormType::class; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\UserBundle\Entity\User', + 'data_class' => User::class, ]); } diff --git a/src/Wallabag/CoreBundle/Helper/DetectActiveTheme.php b/src/Wallabag/CoreBundle/Helper/DetectActiveTheme.php index ec951be84..347c0d03b 100644 --- a/src/Wallabag/CoreBundle/Helper/DetectActiveTheme.php +++ b/src/Wallabag/CoreBundle/Helper/DetectActiveTheme.php @@ -16,15 +16,18 @@ class DetectActiveTheme implements DeviceDetectionInterface { protected $tokenStorage; protected $defaultTheme; + protected $themes; /** * @param TokenStorageInterface $tokenStorage Needed to retrieve the current user * @param string $defaultTheme Default theme when user isn't logged in + * @param array $themes Themes come from the LiipThemeBundle (liip_theme.themes) */ - public function __construct(TokenStorageInterface $tokenStorage, $defaultTheme) + public function __construct(TokenStorageInterface $tokenStorage, $defaultTheme, $themes) { $this->tokenStorage = $tokenStorage; $this->defaultTheme = $defaultTheme; + $this->themes = $themes; } public function setUserAgent($userAgent) @@ -60,6 +63,10 @@ class DetectActiveTheme implements DeviceDetectionInterface return $this->defaultTheme; } + if (!\in_array($config->getTheme(), $this->themes, true)) { + return $this->defaultTheme; + } + return $config->getTheme(); } } diff --git a/src/Wallabag/CoreBundle/Helper/DownloadImages.php b/src/Wallabag/CoreBundle/Helper/DownloadImages.php index b15b87dfa..970f5522d 100644 --- a/src/Wallabag/CoreBundle/Helper/DownloadImages.php +++ b/src/Wallabag/CoreBundle/Helper/DownloadImages.php @@ -189,7 +189,7 @@ class DownloadImages switch ($ext) { case 'gif': // use Imagick if available to keep GIF animation - if (class_exists('\\Imagick')) { + if (class_exists(\Imagick::class)) { try { $imagick = new \Imagick(); $imagick->readImageBlob($res->getBody()); diff --git a/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php b/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php index ea864acbb..48194c234 100644 --- a/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php +++ b/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php @@ -18,7 +18,7 @@ class HttpClientFactory implements ClientFactory /** @var [\GuzzleHttp\Event\SubscriberInterface] */ private $subscribers = []; - /** @var \GuzzleHttp\Cookie\CookieJar */ + /** @var CookieJar */ private $cookieJar; private $restrictedAccess; diff --git a/src/Wallabag/CoreBundle/Operator/Doctrine/Matches.php b/src/Wallabag/CoreBundle/Operator/Doctrine/Matches.php index e16101619..9ddd6fae1 100644 --- a/src/Wallabag/CoreBundle/Operator/Doctrine/Matches.php +++ b/src/Wallabag/CoreBundle/Operator/Doctrine/Matches.php @@ -10,7 +10,7 @@ namespace Wallabag\CoreBundle\Operator\Doctrine; * * This operator will be used to compile tagging rules in DQL, usable * by Doctrine ORM. - * It's registered in RulerZ using a service (wallabag.operator.doctrine.matches); + * It's registered in RulerZ using a service; */ class Matches { diff --git a/src/Wallabag/CoreBundle/Operator/Doctrine/NotMatches.php b/src/Wallabag/CoreBundle/Operator/Doctrine/NotMatches.php index 8e50f8d67..a106b0f09 100644 --- a/src/Wallabag/CoreBundle/Operator/Doctrine/NotMatches.php +++ b/src/Wallabag/CoreBundle/Operator/Doctrine/NotMatches.php @@ -10,7 +10,7 @@ namespace Wallabag\CoreBundle\Operator\Doctrine; * * This operator will be used to compile tagging rules in DQL, usable * by Doctrine ORM. - * It's registered in RulerZ using a service (wallabag.operator.doctrine.notmatches); + * It's registered in RulerZ using a service; */ class NotMatches { diff --git a/src/Wallabag/CoreBundle/Operator/PHP/Matches.php b/src/Wallabag/CoreBundle/Operator/PHP/Matches.php index bc0c3f8f7..ef553a899 100644 --- a/src/Wallabag/CoreBundle/Operator/PHP/Matches.php +++ b/src/Wallabag/CoreBundle/Operator/PHP/Matches.php @@ -10,7 +10,7 @@ namespace Wallabag\CoreBundle\Operator\PHP; * * This operator will be used to compile tagging rules in PHP, usable * directly on Entry objects for instance. - * It's registered in RulerZ using a service (wallabag.operator.array.matches); + * It's registered in RulerZ using a service; */ class Matches { diff --git a/src/Wallabag/CoreBundle/Operator/PHP/NotMatches.php b/src/Wallabag/CoreBundle/Operator/PHP/NotMatches.php index bd4d887a6..6b383c0f6 100644 --- a/src/Wallabag/CoreBundle/Operator/PHP/NotMatches.php +++ b/src/Wallabag/CoreBundle/Operator/PHP/NotMatches.php @@ -10,7 +10,7 @@ namespace Wallabag\CoreBundle\Operator\PHP; * * This operator will be used to compile tagging rules in PHP, usable * directly on Entry objects for instance. - * It's registered in RulerZ using a service (wallabag.operator.array.notmatches); + * It's registered in RulerZ using a service; */ class NotMatches { diff --git a/src/Wallabag/CoreBundle/Operator/PHP/PatternMatches.php b/src/Wallabag/CoreBundle/Operator/PHP/PatternMatches.php index 532e2bb39..872187434 100644 --- a/src/Wallabag/CoreBundle/Operator/PHP/PatternMatches.php +++ b/src/Wallabag/CoreBundle/Operator/PHP/PatternMatches.php @@ -10,7 +10,7 @@ namespace Wallabag\CoreBundle\Operator\PHP; * * This operator will be used to compile ignore origin rules in PHP, usable * directly on Entry objects for instance. - * It's registered in RulerZ using a service (wallabag.operator.array.pattern_matches); + * It's registered in RulerZ using a service; */ class PatternMatches { diff --git a/src/Wallabag/CoreBundle/Repository/ConfigRepository.php b/src/Wallabag/CoreBundle/Repository/ConfigRepository.php index b2b1f627a..c09aabd19 100644 --- a/src/Wallabag/CoreBundle/Repository/ConfigRepository.php +++ b/src/Wallabag/CoreBundle/Repository/ConfigRepository.php @@ -2,8 +2,14 @@ namespace Wallabag\CoreBundle\Repository; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; +use Wallabag\CoreBundle\Entity\Config; -class ConfigRepository extends EntityRepository +class ConfigRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Config::class); + } } diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index 8bb48a889..7cadb091a 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php @@ -2,17 +2,23 @@ namespace Wallabag\CoreBundle\Repository; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\NoResultException; use Doctrine\ORM\QueryBuilder; +use Doctrine\Persistence\ManagerRegistry; use Pagerfanta\Doctrine\ORM\QueryAdapter as DoctrineORMAdapter; use Pagerfanta\Pagerfanta; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Tag; use Wallabag\CoreBundle\Helper\UrlHasher; -class EntryRepository extends EntityRepository +class EntryRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Entry::class); + } + /** * Retrieves all entries for a user. * diff --git a/src/Wallabag/CoreBundle/Repository/IgnoreOriginInstanceRuleRepository.php b/src/Wallabag/CoreBundle/Repository/IgnoreOriginInstanceRuleRepository.php index 708a0edee..ccf321174 100644 --- a/src/Wallabag/CoreBundle/Repository/IgnoreOriginInstanceRuleRepository.php +++ b/src/Wallabag/CoreBundle/Repository/IgnoreOriginInstanceRuleRepository.php @@ -2,8 +2,14 @@ namespace Wallabag\CoreBundle\Repository; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; +use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule; -class IgnoreOriginInstanceRuleRepository extends EntityRepository +class IgnoreOriginInstanceRuleRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, IgnoreOriginInstanceRule::class); + } } diff --git a/src/Wallabag/CoreBundle/Repository/IgnoreOriginUserRuleRepository.php b/src/Wallabag/CoreBundle/Repository/IgnoreOriginUserRuleRepository.php index 8aa4c2652..f41c5b7b4 100644 --- a/src/Wallabag/CoreBundle/Repository/IgnoreOriginUserRuleRepository.php +++ b/src/Wallabag/CoreBundle/Repository/IgnoreOriginUserRuleRepository.php @@ -2,8 +2,14 @@ namespace Wallabag\CoreBundle\Repository; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; +use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule; -class IgnoreOriginUserRuleRepository extends EntityRepository +class IgnoreOriginUserRuleRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, IgnoreOriginUserRule::class); + } } diff --git a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php index aeadd7704..0c2ad6fb5 100644 --- a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php +++ b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php @@ -2,17 +2,22 @@ namespace Wallabag\CoreBundle\Repository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; +use Wallabag\CoreBundle\Entity\SiteCredential; use Wallabag\CoreBundle\Helper\CryptoProxy; /** * SiteCredentialRepository. */ -class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository +class SiteCredentialRepository extends ServiceEntityRepository { private $cryptoProxy; - public function setCrypto(CryptoProxy $cryptoProxy) + public function __construct(ManagerRegistry $registry, CryptoProxy $cryptoProxy) { + parent::__construct($registry, SiteCredential::class); + $this->cryptoProxy = $cryptoProxy; } diff --git a/src/Wallabag/CoreBundle/Repository/TagRepository.php b/src/Wallabag/CoreBundle/Repository/TagRepository.php index 3e64f8b26..ffa2c0b36 100644 --- a/src/Wallabag/CoreBundle/Repository/TagRepository.php +++ b/src/Wallabag/CoreBundle/Repository/TagRepository.php @@ -2,12 +2,18 @@ namespace Wallabag\CoreBundle\Repository; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\QueryBuilder; +use Doctrine\Persistence\ManagerRegistry; use Wallabag\CoreBundle\Entity\Tag; -class TagRepository extends EntityRepository +class TagRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Tag::class); + } + /** * Count all tags per user. * diff --git a/src/Wallabag/CoreBundle/Repository/TaggingRuleRepository.php b/src/Wallabag/CoreBundle/Repository/TaggingRuleRepository.php index de3807388..3f38dc85d 100644 --- a/src/Wallabag/CoreBundle/Repository/TaggingRuleRepository.php +++ b/src/Wallabag/CoreBundle/Repository/TaggingRuleRepository.php @@ -2,8 +2,14 @@ namespace Wallabag\CoreBundle\Repository; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; +use Wallabag\CoreBundle\Entity\TaggingRule; -class TaggingRuleRepository extends EntityRepository +class TaggingRuleRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, TaggingRule::class); + } } diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml deleted file mode 100644 index 5dfdb9a26..000000000 --- a/src/Wallabag/CoreBundle/Resources/config/services.yml +++ /dev/null @@ -1,270 +0,0 @@ -services: - wallabag_core.helper.detect_active_theme: - class: Wallabag\CoreBundle\Helper\DetectActiveTheme - arguments: - - "@security.token_storage" - - "%wallabag_core.theme%" - - # custom form type - wallabag_core.form.type.config: - class: Wallabag\CoreBundle\Form\Type\ConfigType - arguments: - - "%liip_theme.themes%" - - "%wallabag_core.languages%" - tags: - - { name: form.type } - - wallabag_core.filter.type.entry: - class: Wallabag\CoreBundle\Form\Type\EntryFilterType - arguments: - - "@wallabag_core.entry_repository" - - "@security.token_storage" - tags: - - { name: form.type } - - wallabag_core.param_converter.username_feed_token_converter: - class: Wallabag\CoreBundle\ParamConverter\UsernameFeedTokenConverter - tags: - - { name: request.param_converter, converter: username_feed_token_converter } - arguments: - - "@doctrine" - - wallabag_core.subscriber.table_prefix: - class: Wallabag\CoreBundle\Event\Subscriber\TablePrefixSubscriber - arguments: - - "%database_table_prefix%" - tags: - - { name: doctrine.event_subscriber } - - wallabag_core.graby: - class: Graby\Graby - arguments: - - - error_message: '%wallabag_core.fetching_error_message%' - error_message_title: '%wallabag_core.fetching_error_message_title%' - - "@wallabag_core.http_client" - - "@wallabag_core.graby.config_builder" - calls: - - [ setLogger, [ "@logger" ] ] - tags: - - { name: monolog.logger, channel: graby } - - wallabag_core.graby.config_builder: - class: Graby\SiteConfig\ConfigBuilder - arguments: - - {} - - "@logger" - - wallabag_core.http_client: - alias: 'httplug.client.wallabag_core' - - wallabag_core.guzzle_authenticator.config_builder: - class: Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder - arguments: - - "@wallabag_core.graby.config_builder" - - "@security.token_storage" - - "@wallabag_core.site_credential_repository" - - '@logger' - tags: - - { name: monolog.logger, channel: graby } - - # service alias override - bd_guzzle_site_authenticator.site_config_builder: - alias: wallabag_core.guzzle_authenticator.config_builder - - wallabag_core.http_client_factory: - class: Wallabag\CoreBundle\Helper\HttpClientFactory - arguments: - - "@wallabag_core.guzzle.cookie_jar" - - '@=service(''craue_config'').get(''restricted_access'')' - - '@logger' - calls: - - ["addSubscriber", ["@bd_guzzle_site_authenticator.authenticator_subscriber"]] - - wallabag_core.guzzle.cookie_jar: - class: Wallabag\CoreBundle\Helper\FileCookieJar - arguments: - - "@logger" - - "%kernel.cache_dir%/cookiejar.json" - - wallabag_core.content_proxy: - class: Wallabag\CoreBundle\Helper\ContentProxy - arguments: - - "@wallabag_core.graby" - - "@wallabag_core.rule_based_tagger" - - "@wallabag_core.rule_based_ignore_origin_processor" - - "@validator" - - "@logger" - - '%wallabag_core.fetching_error_message%' - - '@=service(''craue_config'').get(''store_article_headers'')' - - wallabag_core.tags_assigner: - class: Wallabag\CoreBundle\Helper\TagsAssigner - arguments: - - "@wallabag_core.tag_repository" - - wallabag_core.rule_based_tagger: - class: Wallabag\CoreBundle\Helper\RuleBasedTagger - arguments: - - "@rulerz" - - "@wallabag_core.tag_repository" - - "@wallabag_core.entry_repository" - - "@logger" - - wallabag_core.rule_based_ignore_origin_processor: - class: Wallabag\CoreBundle\Helper\RuleBasedIgnoreOriginProcessor - arguments: - - "@rulerz" - - "@logger" - - "@wallabag_core.ignore_origin_instance_rule_repository" - - # repository as a service - wallabag_core.entry_repository: - class: Wallabag\CoreBundle\Repository\EntryRepository - factory: [ "@doctrine.orm.default_entity_manager", getRepository ] - arguments: - - WallabagCoreBundle:Entry - - wallabag_core.tag_repository: - class: Wallabag\CoreBundle\Repository\TagRepository - factory: [ "@doctrine.orm.default_entity_manager", getRepository ] - arguments: - - WallabagCoreBundle:Tag - - wallabag_core.site_credential_repository: - class: Wallabag\CoreBundle\Repository\SiteCredentialRepository - factory: [ "@doctrine.orm.default_entity_manager", getRepository ] - arguments: - - WallabagCoreBundle:SiteCredential - calls: - - [ setCrypto, [ "@wallabag_core.helper.crypto_proxy" ] ] - - wallabag_core.ignore_origin_instance_rule_repository: - class: Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository - factory: [ "@doctrine.orm.default_entity_manager", getRepository ] - arguments: - - WallabagCoreBundle:IgnoreOriginInstanceRule - - wallabag_core.helper.entries_export: - class: Wallabag\CoreBundle\Helper\EntriesExport - arguments: - - "@translator" - - '%domain_name%' - - web/img/appicon/apple-touch-icon-152.png - - "@security.token_storage" - - wallabag.operator.array.matches: - class: Wallabag\CoreBundle\Operator\PHP\Matches - tags: - - { name: rulerz.operator, target: native, operator: matches } - - wallabag.operator.doctrine.matches: - class: Wallabag\CoreBundle\Operator\Doctrine\Matches - tags: - - { name: rulerz.operator, target: doctrine, operator: matches, inline: true } - - wallabag.operator.array.notmatches: - class: Wallabag\CoreBundle\Operator\PHP\NotMatches - tags: - - { name: rulerz.operator, target: native, operator: notmatches } - - wallabag.operator.doctrine.notmatches: - class: Wallabag\CoreBundle\Operator\Doctrine\NotMatches - tags: - - { name: rulerz.operator, target: doctrine, operator: notmatches, inline: true } - - wallabag.operator.array.pattern_matches: - class: Wallabag\CoreBundle\Operator\PHP\PatternMatches - tags: - - { name: rulerz.operator, target: native, operator: "~" } - - wallabag_core.helper.redirect: - class: Wallabag\CoreBundle\Helper\Redirect - arguments: - - "@router" - - "@security.token_storage" - - wallabag_core.helper.prepare_pager_for_entries: - class: Wallabag\CoreBundle\Helper\PreparePagerForEntries - arguments: - - "@security.token_storage" - - "@router" - - wallabag_core.redis.client: - class: Predis\Client - arguments: - - - scheme: '%redis_scheme%' - host: '%redis_host%' - port: '%redis_port%' - path: '%redis_path%' - password: '%redis_password%' - - wallabag_core.exception_controller: - class: Wallabag\CoreBundle\Controller\ExceptionController - public: true - arguments: - - '@twig' - - '%kernel.debug%' - - wallabag_core.subscriber.sqlite_cascade_delete: - class: Wallabag\CoreBundle\Event\Subscriber\SQLiteCascadeDeleteSubscriber - arguments: - - "@doctrine" - tags: - - { name: doctrine.event_subscriber } - - wallabag_core.subscriber.download_images: - class: Wallabag\CoreBundle\Event\Subscriber\DownloadImagesSubscriber - arguments: - - "@doctrine.orm.default_entity_manager" - - "@wallabag_core.entry.download_images" - - '@=service(''craue_config'').get(''download_images_enabled'')' - - "@logger" - tags: - - { name: kernel.event_subscriber } - - wallabag_core.entry.download_images: - class: Wallabag\CoreBundle\Helper\DownloadImages - arguments: - - "@wallabag_core.entry.download_images.client" - - "%kernel.project_dir%/web/assets/images" - - '%domain_name%' - - "@logger" - - wallabag_core.entry.download_images.client: - alias: 'httplug.client.wallabag_core.entry.download_images' - - wallabag_core.helper.crypto_proxy: - class: Wallabag\CoreBundle\Helper\CryptoProxy - arguments: - - "%wallabag_core.site_credentials.encryption_key_path%" - - "@logger" - - wallabag_core.command.clean_duplicates: - class: Wallabag\CoreBundle\Command\CleanDuplicatesCommand - tags: ['console.command'] - - wallabag_core.command.export: - class: Wallabag\CoreBundle\Command\ExportCommand - tags: ['console.command'] - - wallabag_core.command.install: - class: Wallabag\CoreBundle\Command\InstallCommand - tags: ['console.command'] - - wallabag_core.command.list_user: - class: Wallabag\CoreBundle\Command\ListUserCommand - tags: ['console.command'] - - wallabag_core.command.reload_entry: - class: Wallabag\CoreBundle\Command\ReloadEntryCommand - tags: ['console.command'] - - wallabag_core.command.show_user: - class: Wallabag\CoreBundle\Command\ShowUserCommand - tags: ['console.command'] - - wallabag_core.command.tag_all: - class: Wallabag\CoreBundle\Command\TagAllCommand - tags: ['console.command'] diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml index d4d9cf557..defd81ac7 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml @@ -457,6 +457,8 @@ quickstart: email: By email gitter: On Gitter tag: + confirm: + delete: Delete the %name% tag page_title: Tags list: number_on_the_page: '{0} There are no tags.|{1} There is one tag.|]1,Inf[ There are %count% tags.' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml index c3fc7bb90..7adedc13e 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml @@ -458,6 +458,8 @@ quickstart: email: Par courriel gitter: Sur Gitter tag: + confirm: + delete: Supprimer le tag %name% page_title: Étiquettes list: number_on_the_page: '{0} Il n’y a pas d''étiquette.|{1} Il y a une étiquette.|]1,Inf[ Il y a %count% étiquettes.' diff --git a/src/Wallabag/CoreBundle/Resources/views/base.html.twig b/src/Wallabag/CoreBundle/Resources/views/base.html.twig index 9d3352d98..00e66482f 100644 --- a/src/Wallabag/CoreBundle/Resources/views/base.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/base.html.twig @@ -49,7 +49,7 @@ {% endif %} {% block scripts %} - + {% endblock %} {% block title %}{% endblock %} – wallabag diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig deleted file mode 100644 index 3ce48dfa3..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig +++ /dev/null @@ -1,503 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'config.page_title'|trans }}{% endblock %} - -{% block content %} -

{{ 'config.tab_menu.settings'|trans }}

- - {{ form_start(form.config) }} - {{ form_errors(form.config) }} - -
-
- {{ form_label(form.config.theme) }} - {{ form_errors(form.config.theme) }} - {{ form_widget(form.config.theme) }} -
- - live_help - -
- -
-
- {{ form_label(form.config.items_per_page) }} - {{ form_errors(form.config.items_per_page) }} - {{ form_widget(form.config.items_per_page) }} -
- - live_help - -
- -
-
- {{ form_label(form.config.reading_speed) }} - {{ form_errors(form.config.reading_speed) }} - {{ form_widget(form.config.reading_speed) }} -

- {{ 'config.form_settings.reading_speed.help_message'|trans }} - myreadspeed -

-
- - live_help - -
- -
-
- {{ form_label(form.config.action_mark_as_read) }} - {{ form_errors(form.config.action_mark_as_read) }} - {{ form_widget(form.config.action_mark_as_read) }} -
-
- -
-
- {{ form_label(form.config.language) }} - {{ form_errors(form.config.language) }} - {{ form_widget(form.config.language) }} -
- - live_help - -
- -
-
- {{ form_label(form.config.pocket_consumer_key) }} - {{ form_errors(form.config.pocket_consumer_key) }} - {{ form_widget(form.config.pocket_consumer_key) }} -

- » - https://getpocket.com/developer/docs/authentication -

-
- - live_help - -
- -
-
-

{{ 'config.form_settings.android_configuration'|trans }}

- {{ 'config.form_settings.android_instruction' | trans }} -
- {{ 'config.otp.app.qrcode_label' | trans }} - -
-
- - {{ form_rest(form.config) }} - - -

{{ 'config.tab_menu.feed'|trans }}

- - {{ form_start(form.feed) }} - {{ form_errors(form.feed) }} - -
- {{ 'config.form_feed.description'|trans }} -
- -
-
- - {% if feed.token %} - {{ feed.token }} - {% else %} - {{ 'config.form_feed.no_token'|trans }} - {% endif %} - - {% if feed.token %} - – {{ 'config.form_feed.token_reset'|trans }} - – {{ 'config.form_feed.token_revoke'|trans }} - {% else %} - – {{ 'config.form_feed.token_create'|trans }} - {% endif %} -
-
- - {% if feed.token %} -
- -
- {% endif %} - -
-
- {{ form_label(form.feed.feed_limit) }} - {{ form_errors(form.feed.feed_limit) }} - {{ form_widget(form.feed.feed_limit) }} -
-
- - {{ form_rest(form.feed) }} - - -

{{ 'config.tab_menu.user_info'|trans }}

- - {{ form_start(form.user) }} - {{ form_errors(form.user) }} -
-
- - {{ app.user.username }} -
-
- -
-
- {{ form_label(form.user.name) }} - {{ form_errors(form.user.name) }} - {{ form_widget(form.user.name) }} -
-
- -
-
- {{ form_label(form.user.email) }} - {{ form_errors(form.user.email) }} - {{ form_widget(form.user.email) }} -
-
- - {{ form_widget(form.user.save) }} - - {% if twofactor_auth %} -
{{ 'config.otp.page_title'|trans }}
- -
- {{ 'config.form_user.two_factor_description'|trans }} -
- - - - - - - - - - - - - - - - - - - - - - -
{{ 'config.form_user.two_factor.table_method'|trans }}{{ 'config.form_user.two_factor.table_state'|trans }}{{ 'config.form_user.two_factor.table_action'|trans }}
{{ 'config.form_user.two_factor.emailTwoFactor_label'|trans }}{% if app.user.isEmailTwoFactor %}{{ 'config.form_user.two_factor.state_enabled'|trans }}{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}{{ 'config.form_user.two_factor.action_email'|trans }} {% if app.user.isEmailTwoFactor %}Disable{% endif %}
{{ 'config.form_user.two_factor.googleTwoFactor_label'|trans }}{% if app.user.isGoogleTwoFactor %}{{ 'config.form_user.two_factor.state_enabled'|trans }}{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}{{ 'config.form_user.two_factor.action_app'|trans }} {% if app.user.isGoogleTwoFactor %}Disable{% endif %}
- - {% endif %} - - {{ form_widget(form.user._token) }} - - - {% if enabled_users > 1 %} -

{{ 'config.form_user.delete.title'|trans }}

- -

{{ 'config.form_user.delete.description'|trans }}

- - {% endif %} - -

{{ 'config.tab_menu.password'|trans }}

- - {{ form_start(form.pwd) }} - {{ form_errors(form.pwd) }} - -
- {{ 'config.form_password.description'|trans }} -
- -
-
- {{ form_label(form.pwd.old_password) }} - {{ form_errors(form.pwd.old_password) }} - {{ form_widget(form.pwd.old_password) }} -
-
- -
-
- {{ form_label(form.pwd.new_password.first) }} - {{ form_errors(form.pwd.new_password.first) }} - {{ form_widget(form.pwd.new_password.first) }} -
-
- -
-
- {{ form_label(form.pwd.new_password.second) }} - {{ form_errors(form.pwd.new_password.second) }} - {{ form_widget(form.pwd.new_password.second) }} -
-
- - {{ form_rest(form.pwd) }} - - -

{{ 'config.tab_menu.rules'|trans }}

- -
    - {% for tagging_rule in app.user.config.taggingRules %} -
  • - {{ 'config.form_rules.if_label'|trans }} - « {{ tagging_rule.rule }} » - {{ 'config.form_rules.then_tag_as_label'|trans }} - « {{ tagging_rule.tags|join(', ') }} » - - -
  • - {% endfor %} -
- - {{ form_start(form.new_tagging_rule) }} - {{ form_errors(form.new_tagging_rule) }} - -
-
- {{ form_label(form.new_tagging_rule.rule) }} - {{ form_errors(form.new_tagging_rule.rule) }} - {{ form_widget(form.new_tagging_rule.rule) }} -
-
- -
-
- {{ form_label(form.new_tagging_rule.tags) }} - {{ form_errors(form.new_tagging_rule.tags) }} - {{ form_widget(form.new_tagging_rule.tags) }} -
-
- - {{ form_rest(form.new_tagging_rule) }} - - -
-

{{ 'config.form_rules.card.import_tagging_rules'|trans }}

-

{{ 'config.form_rules.card.import_tagging_rules_detail'|trans }}

-
- - {{ form_start(form.import_tagging_rule) }} - {{ form_errors(form.import_tagging_rule) }} - -
-
- {{ form_label(form.import_tagging_rule.file) }} - {{ form_errors(form.import_tagging_rule.file) }} - {{ form_widget(form.import_tagging_rule.file) }} -
-
- - {{ form_rest(form.import_tagging_rule) }} - - - {% if app.user.config.taggingRules is not empty %} -
-

{{ 'config.form_rules.card.export_tagging_rules'|trans }}

-

{{ 'config.form_rules.card.export_tagging_rules_detail'|trans }}

-

{{ 'config.form_rules.export'|trans }}

-
- {% endif %} - -
-
-

{{ 'config.form_rules.faq.title'|trans }}

- -

{{ 'config.form_rules.faq.tagging_rules_definition_title'|trans }}

-

{{ 'config.form_rules.faq.tagging_rules_definition_description'|trans|raw }}

- -

{{ 'config.form_rules.faq.how_to_use_them_title'|trans }}

-

{{ 'config.form_rules.faq.how_to_use_them_description'|trans|raw }}

- -

{{ 'config.form_rules.faq.variables_available_title'|trans }}

-

- {{ 'config.form_rules.faq.variables_available_description'|trans }} -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{ 'config.form_rules.faq.variable_description.label'|trans }}{{ 'config.form_rules.faq.meaning'|trans }}{{ 'config.form_rules.faq.operator_description.label'|trans }}{{ 'config.form_rules.faq.meaning'|trans }}
title{{ 'config.form_rules.faq.variable_description.title'|trans }}<={{ 'config.form_rules.faq.operator_description.less_than'|trans }}
url{{ 'config.form_rules.faq.variable_description.url'|trans }}<{{ 'config.form_rules.faq.operator_description.strictly_less_than'|trans }}
isArchived{{ 'config.form_rules.faq.variable_description.isArchived'|trans }}>={{ 'config.form_rules.faq.operator_description.greater_than'|trans }}
isStarred{{ 'config.form_rules.faq.variable_description.isStarred'|trans }}>{{ 'config.form_rules.faq.operator_description.strictly_greater_than'|trans }}
content{{ 'config.form_rules.faq.variable_description.content'|trans }}={{ 'config.form_rules.faq.operator_description.equal_to'|trans }}
language{{ 'config.form_rules.faq.variable_description.language'|trans }}!={{ 'config.form_rules.faq.operator_description.not_equal_to'|trans }}
mimetype{{ 'config.form_rules.faq.variable_description.mimetype'|trans }}OR{{ 'config.form_rules.faq.operator_description.or'|trans }}
readingTime{{ 'config.form_rules.faq.variable_description.readingTime'|trans }}AND{{ 'config.form_rules.faq.operator_description.and'|trans }}
domainName{{ 'config.form_rules.faq.variable_description.domainName'|trans }}matches{{ 'config.form_rules.faq.operator_description.matches'|trans|raw }}
-
-
- -

{{ 'config.tab_menu.ignore_origin'|trans }}

- -
    - {% for ignore_origin_rule in app.user.config.ignoreOriginRules %} -
  • - {{ 'config.form_rules.if_label'|trans }} - « {{ ignore_origin_rule.rule }} » - - -
  • - {% endfor %} -
- - {{ form_start(form.new_ignore_origin_user_rule) }} - {{ form_errors(form.new_ignore_origin_user_rule) }} - -
-
- {{ form_label(form.new_ignore_origin_user_rule.rule) }} - {{ form_errors(form.new_ignore_origin_user_rule.rule) }} - {{ form_widget(form.new_ignore_origin_user_rule.rule) }} -
-
- - {{ form_rest(form.new_ignore_origin_user_rule) }} - - -
-
-

{{ 'config.form_ignore_origin_rules.faq.title'|trans }}

- -
{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}
-

{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}

- -
{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}
-

{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}

- -
{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}
-

- {{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }} -

- - - - - - - - - - - - - - - - - - - - - - - - - -
{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}
host{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}={{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}
_all{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}~{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}
-
-
- -

{{ 'config.reset.title'|trans }}

-
-

{{ 'config.reset.description'|trans }}

- -
-{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig deleted file mode 100644 index b16e6a050..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/otp_app.html.twig +++ /dev/null @@ -1,55 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'config.page_title'|trans }} > {{ 'config.otp.page_title'|trans }}{% endblock %} - -{% block content %} -
{{ 'config.otp.page_title'|trans }}
- -
    -
  1. -

    {{ 'config.otp.app.two_factor_code_description_1'|trans }}

    -

    {{ 'config.otp.app.two_factor_code_description_2'|trans }}

    - -

    - - -

    -
  2. -
  3. -

    {{ 'config.otp.app.two_factor_code_description_3'|trans }}

    - -

    {{ backupCodes|join("\n")|nl2br }}

    -
  4. -
  5. -

    {{ 'config.otp.app.two_factor_code_description_4'|trans }}

    - - {% for flashMessage in app.session.flashbag.get("two_factor") %} -
    - {{ flashMessage|trans }} -
    - {% endfor %} - -
    -
    -
    -
    - - -
    -
    -
    -
    - - {{ 'config.otp.app.cancel'|trans }} - - -
    -
    -
  6. -
-{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/edit.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/edit.html.twig deleted file mode 100644 index e974fc694..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/edit.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'entry.edit.page_title'|trans }}{% endblock %} - -{% block content %} - {{ form(form) }} -{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig deleted file mode 100644 index 8dc6fd507..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig +++ /dev/null @@ -1,219 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block head %} - {{ parent() }} - {% if tag is defined and app.user.config.feedToken %} - - {% endif %} -{% endblock %} - -{% block title %} - {% set filter = '' %} - {% if tag is defined %} - {% set filter = tag %} - {% endif %} - {% if searchTerm is defined and searchTerm is not empty %} - {% set filter = searchTerm %} - {% endif %} - {% include "@WallabagCore/themes/common/Entry/_title.html.twig" with {'filter': filter} %} -{% endblock %} - -{% block content %} - {% set currentRoute = app.request.attributes.get('_route') %} - {% if currentRoute == 'homepage' %} - {% set currentRoute = 'unread' %} - {% endif %} - {% set listMode = app.user.config.listMode %} -
-
{{ 'entry.list.number_on_the_page'|transchoice(entries.count) }}
- -
- - {% for entry in entries %} -
-

{{ entry.title | striptags | truncate(80, true, '…') | default('entry.default_title'|trans) | raw }}

- - {% set readingTime = entry.readingTime / app.user.config.readingSpeed * 200 %} -
- - {% if readingTime > 0 %} - {{ 'entry.list.reading_time_minutes'|trans({'%readingTime%': readingTime|round}) }} - {% else %} - {{ 'entry.list.reading_time_less_one_minute'|trans|raw }} - {% endif %} - - - - {{ entry.createdAt|date('Y-m-d') }} - - -
- - - {% if (entry.previewPicture is null or listMode == 1) %} - -

{{ entry.content|striptags|slice(0, 300) }}…

- {% else %} - - {{ entry.title|e|raw }} - {% endif %} -
- {% endfor %} - - {% if entries.getNbPages > 1 %} - {{ pagerfanta(entries, 'twitter_bootstrap_translated', {'proximity': 1}) }} - {% endif %} - - - - - - {% if form is not null %} -
-
-

{{ 'entry.filters.title'|trans }}

- × - -
- {% if currentRoute != 'untagged' and nbEntriesUntagged != 0 %} - - {% endif %} - -
- -
-
- {{ form_widget(form.isArchived) }} - {{ form_label(form.isArchived) }} -
- -
- {{ form_widget(form.isStarred) }} - {{ form_label(form.isStarred) }} -
- -
- {{ form_widget(form.isUnread) }} - {{ form_label(form.isUnread) }} -
- -
- {{ form_widget(form.previewPicture) }} - {{ form_label(form.previewPicture) }} -
- -
- {{ form_widget(form.isPublic) }} - {{ form_label(form.isPublic) }} -
-
- -
- {{ form_label(form.language) }} -
- {{ form_widget(form.language) }} -
-
- -
- {{ form_label(form.httpStatus) }} -
- {{ form_widget(form.httpStatus) }} -
-
- -
-
- {{ form_label(form.readingTime) }} -
-
- - {{ form_widget(form.readingTime.left_number, {'type': 'number'}) }} -
-
- - {{ form_widget(form.readingTime.right_number, {'type': 'number'}) }} -
-
- -
- {{ form_label(form.domainName) }} -
- {{ form_widget(form.domainName, {'type': 'text', 'attr' : {'placeholder': 'website.com'} }) }} -
-
- -
-
- {{ form_label(form.createdAt) }} -
-
- - {{ form_widget(form.createdAt.left_date, {'type': 'date', 'attr': {'class': 'datepicker', 'data-value': form.createdAt.left_date.vars.value} }) }} -
-
- - {{ form_widget(form.createdAt.right_date, {'type': 'date', 'attr': {'class': 'datepicker', 'data-value': form.createdAt.right_date.vars.value} }) }} -
-
- -
- - - -
-
-
- {% endif %} -{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig deleted file mode 100644 index 42f33f54e..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig +++ /dev/null @@ -1,116 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ entry.title|e|default('entry.default_title'|trans)|raw }} ({{ entry.domainName|removeWww }}){% endblock %} - -{% block content %} -
-
-

{{ entry.title|e|default('entry.default_title'|trans)|raw }}

-
- -
- -
- -
- - {{ entry.createdAt|date('Y-m-d H:i') }} - - - {% if entry.publishedAt is not null %} - - {{ entry.publishedAt|date('Y-m-d H:i') }} - - {% endif %} - - {% if entry.publishedBy is not empty %} - - {% for author in entry.publishedBy %} - {{ author }}{% if not loop.last %}, {% endif %} - {% endfor %} - - {% endif %} - - - {% set readingTime = entry.readingTime / app.user.config.readingSpeed * 200 %} - {% if readingTime > 0 %} - {{ 'entry.list.reading_time_minutes_short'|trans({'%readingTime%': readingTime|round}) }} - {% else %} - {{ 'entry.list.reading_time_less_one_minute_short'|trans|raw }} - {% endif %} - - - comment {{ 'entry.view.annotations_on_the_entry'|transchoice(entry.annotations | length) }} - - {% if entry.originUrl is not empty %} - launch - - {{ entry.originUrl|striptags|removeSchemeAndWww|truncate(32) }} - - {% endif %} - - -
- - {{ entry.content | raw }} - -
- - -{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/new.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/new.html.twig deleted file mode 100644 index 03768a3d8..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/new.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'entry.new.page_title'|trans }}{% endblock %} - -{% block content %} - {{ render(controller( "WallabagCoreBundle:Entry:addEntryForm" )) }} -{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/new_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/new_form.html.twig deleted file mode 100644 index 8c1290681..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/new_form.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -
- {% if form_errors(form) %} - {{ form_errors(form) }} - {% endif %} - - {% if form_errors(form.url) %} - {{ form_errors(form.url) }} - {% endif %} - - {{ form_label(form.url) }} - {{ form_widget(form.url, { 'attr': {'autocomplete': 'off', 'placeholder': 'entry.new.placeholder'} }) }} - - {{ form_rest(form) }} -
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/search_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/search_form.html.twig deleted file mode 100644 index 20821b6d3..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/search_form.html.twig +++ /dev/null @@ -1,17 +0,0 @@ -
-

{{ 'menu.left.search'|trans }}

- × - {% if form_errors(form) %} - {{ form_errors(form) }} - {% endif %} - - {% if form_errors(form.term) %} - {{ form_errors(form.term) }} - {% endif %} - - - - {{ form_widget(form.term, { 'attr': {'autocomplete': 'off', 'placeholder': 'entry.search.placeholder'} }) }} - - {{ form_rest(form) }} -
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Exception/error.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Exception/error.html.twig deleted file mode 100644 index c6bf24810..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Exception/error.html.twig +++ /dev/null @@ -1,24 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'error.page_title'|trans }}{% endblock %} - -{% block body_class %}login{% endblock %} - -{% block menu %}{% endblock %} -{% block messages %}{% endblock %} -{% block header %}{% endblock %} - -{% block content %} -
-
-
-
wallabag logo
-

{{ status_code }}: {{ status_text }}

-

{{ exception.message }}

-
-
-
-{% endblock %} - -{% block footer %} -{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/edit.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/edit.html.twig deleted file mode 100644 index 30c2a520f..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/edit.html.twig +++ /dev/null @@ -1,87 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %} - -{% block content %} - -
-
-
-
-
-

{{ 'ignore_origin_instance_rule.edit_ignore_origin_instance_rule'|trans }}

- -
- {{ form_start(edit_form) }} - {{ form_errors(edit_form) }} - -
-
- {{ form_label(edit_form.rule) }} - {{ form_errors(edit_form.rule) }} - {{ form_widget(edit_form.rule) }} -
-
- -
- - {{ form_widget(edit_form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} - {{ form_widget(edit_form._token) }} - -

- {{ form_start(delete_form) }} - - {{ form_end(delete_form) }} -

-

{{ 'ignore_origin_instance_rule.form.back_to_list'|trans }}

-
-
-
- -
-
-

{{ 'config.form_ignore_origin_rules.faq.title'|trans }}

- -
{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}
-

{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}

- -
{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}
-

{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}

- -
{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}
-

- {{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }} -

- - - - - - - - - - - - - - - - - - - - - - - - - -
{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}
host{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}={{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}
_all{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}~{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}
-
-
-
-
-
- -{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/index.html.twig deleted file mode 100644 index 2de7cf0a4..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/index.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %} - -{% block content %} - -
-
-
-
-
-

{{ 'ignore_origin_instance_rule.description'|trans|raw }}

- - - - - - - - - - {% for rule in rules %} - - - - - {% endfor %} - -
{{ 'ignore_origin_instance_rule.form.rule_label'|trans }}{{ 'ignore_origin_instance_rule.list.actions'|trans }}
{{ rule.rule }} - {{ 'ignore_origin_instance_rule.list.edit_action'|trans }} -
-
-

- {{ 'ignore_origin_instance_rule.list.create_new_one'|trans }} -

-
-
-
-
-
- -{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/new.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/new.html.twig deleted file mode 100644 index cb052ff05..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/IgnoreOriginInstanceRule/new.html.twig +++ /dev/null @@ -1,80 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'ignore_origin_instance_rule.page_title'|trans }}{% endblock %} - -{% block content %} - -
-
-
-
-
-

{{ 'ignore_origin_instance_rule.new_ignore_origin_instance_rule'|trans }}

- -
- {{ form_start(form) }} - {{ form_errors(form) }} - -
-
- {{ form_label(form.rule) }} - {{ form_errors(form.rule) }} - {{ form_widget(form.rule) }} -
-
- - {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} - {{ form_rest(form) }} - -

{{ 'ignore_origin_instance_rule.form.back_to_list'|trans }}

-
-
-
- -
-
-

{{ 'config.form_ignore_origin_rules.faq.title'|trans }}

- -
{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_title'|trans }}
-

{{ 'config.form_ignore_origin_rules.faq.ignore_origin_rules_definition_description'|trans|raw }}

- -
{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_title'|trans }}
-

{{ 'config.form_ignore_origin_rules.faq.how_to_use_them_description'|trans|raw }}

- -
{{ 'config.form_ignore_origin_rules.faq.variables_available_title'|trans }}
-

- {{ 'config.form_ignore_origin_rules.faq.variables_available_description'|trans }} -

- - - - - - - - - - - - - - - - - - - - - - - - - -
{{ 'config.form_ignore_origin_rules.faq.variable_description.label'|trans }}{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}{{ 'config.form_ignore_origin_rules.faq.operator_description.label'|trans }}{{ 'config.form_ignore_origin_rules.faq.meaning'|trans }}
host{{ 'config.form_ignore_origin_rules.faq.variable_description.host'|trans }}={{ 'config.form_ignore_origin_rules.faq.operator_description.equal_to'|trans }}
_all{{ 'config.form_ignore_origin_rules.faq.variable_description._all'|trans }}~{{ 'config.form_ignore_origin_rules.faq.operator_description.matches'|trans|raw }}
-
-
-
-
-
- -{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Mail/forgotPassword.txt.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Mail/forgotPassword.txt.twig deleted file mode 100644 index 631bcb887..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Mail/forgotPassword.txt.twig +++ /dev/null @@ -1,6 +0,0 @@ -Hello {{username}}! - -To reset your password - please visit {{confirmationUrl}} - -Regards, -Wallabag bot diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/README.md b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/README.md deleted file mode 100644 index 3db078735..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Baggy Theme - -theme created by Thomas LEBEAU alias Courgette http://thomaslebeau.fr/ diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/edit.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/edit.html.twig deleted file mode 100644 index 882be430f..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/edit.html.twig +++ /dev/null @@ -1,60 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'site_credential.page_title'|trans }}{% endblock %} - -{% block content %} - -
-
-
-
-
-

{{ 'site_credential.edit_site_credential'|trans }}

- -
- {{ form_start(edit_form) }} - {{ form_errors(edit_form) }} - -
-
- {{ form_label(edit_form.host) }} - {{ form_errors(edit_form.host) }} - {{ form_widget(edit_form.host) }} -
-
- -
-
- {{ form_label(edit_form.username) }} - {{ form_errors(edit_form.username) }} - {{ form_widget(edit_form.username) }} -
-
- -
-
- {{ form_label(edit_form.password) }} - {{ form_errors(edit_form.password) }} - {{ form_widget(edit_form.password) }} -
-
- -
- - {{ form_widget(edit_form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} - {{ form_widget(edit_form._token) }} - -

- {{ form_start(delete_form) }} - - {{ form_end(delete_form) }} -

-

{{ 'site_credential.form.back_to_list'|trans }}

-
-
-
-
-
-
- -{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig deleted file mode 100644 index 324854add..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'site_credential.page_title'|trans }}{% endblock %} - -{% block content %} - -
-
-
-
-
-

{{ 'site_credential.description'|trans|raw }}

- - - - - - - - - - {% for credential in credentials %} - - - - - {% endfor %} - -
{{ 'site_credential.form.host_label'|trans }}{{ 'site_credential.list.actions'|trans }}
{{ credential.host }} - {{ 'site_credential.list.edit_action'|trans }} -
-
-

- {{ 'site_credential.list.create_new_one'|trans }} -

-
-
-
-
-
- -{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/new.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/new.html.twig deleted file mode 100644 index 3c008cdec..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/new.html.twig +++ /dev/null @@ -1,53 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'site_credential.page_title'|trans }}{% endblock %} - -{% block content %} - -
-
-
-
-
-

{{ 'site_credential.new_site_credential'|trans }}

- -
- {{ form_start(form) }} - {{ form_errors(form) }} - -
-
- {{ form_label(form.host) }} - {{ form_errors(form.host) }} - {{ form_widget(form.host) }} -
-
- -
-
- {{ form_label(form.username) }} - {{ form_errors(form.username) }} - {{ form_widget(form.username) }} -
-
- -
-
- {{ form_label(form.password) }} - {{ form_errors(form.password) }} - {{ form_widget(form.password) }} -
-
- - {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} - {{ form_rest(form) }} - -

{{ 'site_credential.form.back_to_list'|trans }}

-
-
-
-
-
-
- -{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/new_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/new_form.html.twig deleted file mode 100644 index 6e552560e..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/new_form.html.twig +++ /dev/null @@ -1,13 +0,0 @@ -
- {% if form_errors(form) %} - {{ form_errors(form) }} - {% endif %} - - {% if form_errors(form.label) %} - {{ form_errors(form.label) }} - {% endif %} - - {{ form_widget(form.label, { 'attr': {'autocomplete': 'off'} }) }} - - {{ form_rest(form) }} -
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/tags.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/tags.html.twig deleted file mode 100644 index aa17b8428..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/tags.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} - -{% block title %}{{ 'tag.page_title'|trans }}{% endblock %} - -{% block content %} -
-
{{ 'tag.list.number_on_the_page'|transchoice(tags|length) }}
-
- -
    - {% for tag in tags %} -
  • - {{ tag.label }} ({{ tag.nbEntries }}) - - {% if renameForms is defined and renameForms[tag.id] is defined %} - - - mode_edit - - {% endif %} - {% if app.user.config.feedToken %} - - rss_feed - - {% endif %} -
  • - {% endfor %} -
- -
- {% if nbEntriesUntagged == 0 %} - {{ 'tag.list.no_untagged_entries'|trans }} - {% else %} - {{ 'tag.list.see_untagged_entries'|trans }} ({{nbEntriesUntagged}}) - {% endif %} -
-{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig deleted file mode 100644 index d0be1e5cc..000000000 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig +++ /dev/null @@ -1,77 +0,0 @@ -{% extends "WallabagCoreBundle::base.html.twig" %} - -{% block css %} - {{ parent() }} - {% if not app.debug %} - - {% endif %} -{% endblock %} - -{% block scripts %} - {{ parent() }} - -{% endblock %} - -{% block header %} -
-

- {% block logo %} - - wallabag logo - - {% endblock %} -

-
-{% endblock %} - -{% block menu %} - - -{% endblock %} - -{% block messages %} -
-

⚠️ You are using the Baggy theme which is now deprecated.

-

It will be removed in the next version. You can use the Material theme by updating the theme config.

-
- - {% for flashMessage in app.session.flashbag.get('notice') %} -
- × -

{{ flashMessage|trans }}

-
- {% endfor %} -{% endblock %} - -{% block footer %} -
-

{{ 'footer.wallabag.powered_by'|trans }} wallabag

-
-{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/screenshot.jpg b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/screenshot.jpg deleted file mode 100755 index 1aa8f1461..000000000 Binary files a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/screenshot.jpg and /dev/null differ diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/client.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/client.html.twig index 8a5da71a9..2911f6a4e 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/client.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/client.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'developer.client.page_title'|trans }}{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/client_parameters.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/client_parameters.html.twig index 3a3ba0c97..59412a708 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/client_parameters.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/client_parameters.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'developer.client_parameter.page_title'|trans }}{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/howto_app.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/howto_app.html.twig index dcadfa49a..0f40b7914 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/howto_app.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/howto_app.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'developer.howto.page_title'|trans }}{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig index b83bf96fa..1dac14653 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'developer.page_title'|trans }}{% endblock %} @@ -55,10 +55,10 @@ -

{{ 'developer.remove.warn_message_1'|trans({'%name%': client.name }) }}

-

{{ 'developer.remove.warn_message_2'|trans({'%name%': client.name }) }}

+

{{ 'developer.remove.warn_message_1'|trans({'%name%': client.name}) }}

+

{{ 'developer.remove.warn_message_2'|trans({'%name%': client.name}) }}

- {{ 'developer.remove.action'|trans({'%name%': client.name }) }} + {{ 'developer.remove.action'|trans({'%name%': client.name}) }}

diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_feed_link.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_feed_link.html.twig index 6df4c160d..7e84da66d 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_feed_link.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_feed_link.html.twig @@ -1,11 +1,11 @@ {% if tag is defined %} rss_feed -{% elseif currentRoute in ['homepage', 'unread', 'starred', 'archive', 'all'] %} - {% set feedRoute = currentRoute %} - {% if currentRoute == 'homepage' %} - {% set feedRoute = 'unread' %} +{% elseif current_route in ['homepage', 'unread', 'starred', 'archive', 'all'] %} + {% set feed_route = current_route %} + {% if current_route == 'homepage' %} + {% set feed_route = 'unread' %} {% endif %} - {% set feedRoute = feedRoute ~ '_feed' %} + {% set feed_route = feed_route ~ '_feed' %} - rss_feed + rss_feed {% endif %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig index 3c5fad1e9..81f682ef1 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig @@ -1,20 +1,20 @@ -{% set currentRoute = app.request.attributes.get('_route') %} +{% set current_route = app.request.attributes.get('_route') %} -{% if currentRoute == 'starred' %} +{% if current_route == 'starred' %} {{ 'entry.page_titles.starred'|trans }} -{% elseif currentRoute == 'archive' %} +{% elseif current_route == 'archive' %} {{ 'entry.page_titles.archived'|trans }} -{% elseif currentRoute == 'all' %} +{% elseif current_route == 'all' %} {{ isFiltered ? 'entry.page_titles.filtered'|trans : 'entry.page_titles.all'|trans }} -{% elseif currentRoute == 'search' %} +{% elseif current_route == 'search' %} {{ 'entry.page_titles.filtered_search'|trans }} {{ filter }} -{% elseif currentRoute == 'tag_entries' %} +{% elseif current_route == 'tag_entries' %} {{ 'entry.page_titles.filtered_tags'|trans }} {{ filter }} -{% elseif currentRoute == 'untagged' %} +{% elseif current_route == 'untagged' %} {{ 'entry.page_titles.untagged'|trans }} -{% elseif currentRoute == 'same_domain' %} +{% elseif current_route == 'same_domain' %} {{ 'entry.page_titles.same_domain'|trans }} -{% elseif currentRoute == 'annotated' %} +{% elseif current_route == 'annotated' %} {{ 'entry.page_titles.with_annotations'|trans }} {% else %} {{ 'entry.page_titles.unread'|trans }} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig index 4e87942fd..5e8f2dd1d 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig @@ -1,18 +1,18 @@ {% if type != 'tag' %} - wallabag — {{type}} feed + wallabag — {{ type }} feed Atom feed for {{ type }} entries - wallabag:{{ domainName | removeScheme | removeWww }}:{{ user }}:{{ type }} + wallabag:{{ domainName|removeScheme|removeWww }}:{{ user }}:{{ type }} {% else %} - wallabag:{{ domainName | removeScheme | removeWww }}:{{ user }}:{{ type }}:{{ tag }} + wallabag:{{ domainName|removeScheme|removeWww }}:{{ user }}:{{ type }}:{{ tag }} - wallabag — {{type}} {{ tag }} feed + wallabag — {{ type }} {{ tag }} feed Atom feed for entries tagged with {{ tag }} {% endif %} {% if updated %} - {{ updated | date('c') }} {# Indicates the last time the feed was modified in a significant way. #} + {{ updated|date('c') }} {# Indicates the last time the feed was modified in a significant way. #} {% endif %} {% if entries.hasPreviousPage %} @@ -36,7 +36,7 @@ href="{{ url('view', {'id': entry.id}) }}"/> - wallabag:{{ domainName | removeScheme | removeWww }}:{{ user }}:entry:{{ entry.id }} + wallabag:{{ domainName|removeScheme|removeWww }}:{{ user }}:entry:{{ entry.id }} {{ entry.updatedAt|date('c') }} {{ entry.createdAt|date('c') }} {% for tag in entry.tags %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/share.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/share.html.twig index 12af5e268..69b32ccac 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/share.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/share.html.twig @@ -7,13 +7,13 @@ - {% set picturePath = app.request.schemeAndHttpHost ~ asset('img/logo-wallabag.svg') %} + {% set picture_path = app.request.schemeAndHttpHost ~ asset('img/logo-wallabag.svg') %} {% if entry.previewPicture is not null %} - {% set picturePath = entry.previewPicture %} + {% set picture_path = entry.previewPicture %} {% endif %} - + - + @@ -31,7 +31,7 @@

{{ "entry.public.shared_by_wallabag"|trans({'%wallabag_instance%': url('homepage'), '%username%': entry.user.username})|raw }}.

- {{ entry.content | raw }} + {{ entry.content|raw }}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Mail/forgotPassword.txt.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Mail/forgotPassword.txt.twig index 631bcb887..00fd292d8 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Mail/forgotPassword.txt.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Mail/forgotPassword.txt.twig @@ -1,6 +1,6 @@ -Hello {{username}}! +Hello {{ username }}! -To reset your password - please visit {{confirmationUrl}} +To reset your password - please visit {{ confirmationUrl }} Regards, Wallabag bot diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/about.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/about.html.twig index 1cd3485c0..7cac797b1 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/about.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/about.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'about.page_title'|trans }}{% endblock %} @@ -136,9 +136,7 @@ psr/logMIT react/promiseMIT scheb/two-factor-bundleMIT - sensio/distribution-bundleMIT sensio/framework-extra-bundleMIT - sensiolabs/security-checkerMIT simplepie/simplepieBSD-3-Clause smalot/pdfparserGPL-3.0 sonata-project/google-authenticatorMIT diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/howto.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/howto.html.twig index fbd2755a3..eddd2f449 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/howto.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/howto.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'howto.page_title'|trans }}{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/quickstart.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/quickstart.html.twig index 521b3eea6..151993bfd 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/quickstart.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/quickstart.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'quickstart.page_title'|trans }}{% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig index 28ff364cb..5a22253f1 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'config.page_title'|trans }}{% endblock %} @@ -109,8 +109,8 @@
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/new.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/new.html.twig index 03768a3d8..0eff3a11d 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/new.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/new.html.twig @@ -1,7 +1,6 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'entry.new.page_title'|trans }}{% endblock %} {% block content %} - {{ render(controller( "WallabagCoreBundle:Entry:addEntryForm" )) }} {% endblock %} diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/new_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/new_form.html.twig index 4cf811674..e572d9f50 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/new_form.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/new_form.html.twig @@ -1,4 +1,4 @@ - - {{ render(controller("WallabagCoreBundle:Entry:searchForm", {'currentRoute': currentRoute})) }} - {{ render(controller("WallabagCoreBundle:Entry:addEntryForm")) }} + {{ render(controller('Wallabag\\CoreBundle\\Controller\\EntryController::searchFormAction', {'currentRoute': current_route})) }} + {{ render(controller('Wallabag\\CoreBundle\\Controller\\EntryController::addEntryFormAction')) }}
{% endblock %} @@ -166,7 +166,7 @@
-
diff --git a/src/Wallabag/ImportBundle/Command/ImportCommand.php b/src/Wallabag/ImportBundle/Command/ImportCommand.php index 164f274d4..198ab6a72 100644 --- a/src/Wallabag/ImportBundle/Command/ImportCommand.php +++ b/src/Wallabag/ImportBundle/Command/ImportCommand.php @@ -2,13 +2,24 @@ namespace Wallabag\ImportBundle\Command; +use Doctrine\Persistence\ManagerRegistry; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Config\Definition\Exception\Exception; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; +use Wallabag\ImportBundle\Import\ChromeImport; +use Wallabag\ImportBundle\Import\DeliciousImport; +use Wallabag\ImportBundle\Import\FirefoxImport; +use Wallabag\ImportBundle\Import\InstapaperImport; +use Wallabag\ImportBundle\Import\PinboardImport; +use Wallabag\ImportBundle\Import\ReadabilityImport; +use Wallabag\ImportBundle\Import\WallabagV1Import; +use Wallabag\ImportBundle\Import\WallabagV2Import; +use Wallabag\UserBundle\Entity\User; class ImportCommand extends ContainerAwareCommand { @@ -34,14 +45,14 @@ class ImportCommand extends ContainerAwareCommand throw new Exception(sprintf('File "%s" not found', $input->getArgument('filepath'))); } - $em = $this->getContainer()->get('doctrine')->getManager(); + $em = $this->getContainer()->get(ManagerRegistry::class)->getManager(); // Turning off doctrine default logs queries for saving memory $em->getConnection()->getConfiguration()->setSQLLogger(null); if ($input->getOption('useUserId')) { - $entityUser = $em->getRepository('WallabagUserBundle:User')->findOneById($input->getArgument('username')); + $entityUser = $em->getRepository(User::class)->findOneById($input->getArgument('username')); } else { - $entityUser = $em->getRepository('WallabagUserBundle:User')->findOneByUsername($input->getArgument('username')); + $entityUser = $em->getRepository(User::class)->findOneByUsername($input->getArgument('username')); } if (!\is_object($entityUser)) { @@ -55,33 +66,33 @@ class ImportCommand extends ContainerAwareCommand 'main', $entityUser->getRoles()); - $this->getContainer()->get('security.token_storage')->setToken($token); - $user = $this->getContainer()->get('security.token_storage')->getToken()->getUser(); + $this->getContainer()->get(TokenStorageInterface::class)->setToken($token); + $user = $this->getContainer()->get(TokenStorageInterface::class)->getToken()->getUser(); switch ($input->getOption('importer')) { case 'v2': - $import = $this->getContainer()->get('wallabag_import.wallabag_v2.import'); + $import = $this->getContainer()->get(WallabagV2Import::class); break; case 'firefox': - $import = $this->getContainer()->get('wallabag_import.firefox.import'); + $import = $this->getContainer()->get(FirefoxImport::class); break; case 'chrome': - $import = $this->getContainer()->get('wallabag_import.chrome.import'); + $import = $this->getContainer()->get(ChromeImport::class); break; case 'readability': - $import = $this->getContainer()->get('wallabag_import.readability.import'); + $import = $this->getContainer()->get(ReadabilityImport::class); break; case 'instapaper': - $import = $this->getContainer()->get('wallabag_import.instapaper.import'); + $import = $this->getContainer()->get(InstapaperImport::class); break; case 'pinboard': - $import = $this->getContainer()->get('wallabag_import.pinboard.import'); + $import = $this->getContainer()->get(PinboardImport::class); break; case 'delicious': - $import = $this->getContainer()->get('wallabag_import.delicious.import'); + $import = $this->getContainer()->get(DeliciousImport::class); break; default: - $import = $this->getContainer()->get('wallabag_import.wallabag_v1.import'); + $import = $this->getContainer()->get(WallabagV1Import::class); } $import->setMarkAsRead($input->getOption('markAsRead')); diff --git a/src/Wallabag/ImportBundle/Consumer/AbstractConsumer.php b/src/Wallabag/ImportBundle/Consumer/AbstractConsumer.php index e4bfbdf03..17c8561a6 100644 --- a/src/Wallabag/ImportBundle/Consumer/AbstractConsumer.php +++ b/src/Wallabag/ImportBundle/Consumer/AbstractConsumer.php @@ -2,7 +2,7 @@ namespace Wallabag\ImportBundle\Consumer; -use Doctrine\ORM\EntityManager; +use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -20,7 +20,7 @@ abstract class AbstractConsumer protected $eventDispatcher; protected $logger; - public function __construct(EntityManager $em, UserRepository $userRepository, AbstractImport $import, EventDispatcherInterface $eventDispatcher, LoggerInterface $logger = null) + public function __construct(EntityManagerInterface $em, UserRepository $userRepository, AbstractImport $import, EventDispatcherInterface $eventDispatcher, LoggerInterface $logger = null) { $this->em = $em; $this->userRepository = $userRepository; diff --git a/src/Wallabag/ImportBundle/Controller/BrowserController.php b/src/Wallabag/ImportBundle/Controller/BrowserController.php index 8c2bdfe58..52b4cd392 100644 --- a/src/Wallabag/ImportBundle/Controller/BrowserController.php +++ b/src/Wallabag/ImportBundle/Controller/BrowserController.php @@ -5,8 +5,11 @@ namespace Wallabag\ImportBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\ImportBundle\Form\Type\UploadImportType; +use Wallabag\ImportBundle\Import\ImportInterface; abstract class BrowserController extends Controller { @@ -38,13 +41,13 @@ abstract class BrowserController extends Controller if (true === $res) { $summary = $wallabag->getSummary(); - $message = $this->get('translator')->trans('flashes.import.notice.summary', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary', [ '%imported%' => $summary['imported'], '%skipped%' => $summary['skipped'], ]); if (0 < $summary['queued']) { - $message = $this->get('translator')->trans('flashes.import.notice.summary_with_queue', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary_with_queue', [ '%queued%' => $summary['queued'], ]); } @@ -52,14 +55,14 @@ abstract class BrowserController extends Controller unlink($this->getParameter('wallabag_import.resource_dir') . '/' . $name); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', $message ); return $this->redirect($this->generateUrl('homepage')); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', 'flashes.import.notice.failed_on_file' ); @@ -74,7 +77,7 @@ abstract class BrowserController extends Controller /** * Return the service to handle the import. * - * @return \Wallabag\ImportBundle\Import\ImportInterface + * @return ImportInterface */ abstract protected function getImportService(); diff --git a/src/Wallabag/ImportBundle/Controller/ChromeController.php b/src/Wallabag/ImportBundle/Controller/ChromeController.php index 6628cdb0b..4d7cbaf00 100644 --- a/src/Wallabag/ImportBundle/Controller/ChromeController.php +++ b/src/Wallabag/ImportBundle/Controller/ChromeController.php @@ -2,8 +2,10 @@ namespace Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; +use Wallabag\ImportBundle\Import\ChromeImport; class ChromeController extends BrowserController { @@ -20,11 +22,11 @@ class ChromeController extends BrowserController */ protected function getImportService() { - $service = $this->get('wallabag_import.chrome.import'); + $service = $this->get(ChromeImport::class); - if ($this->get('craue_config')->get('import_with_rabbitmq')) { + if ($this->get(Config::class)->get('import_with_rabbitmq')) { $service->setProducer($this->get('old_sound_rabbit_mq.import_chrome_producer')); - } elseif ($this->get('craue_config')->get('import_with_redis')) { + } elseif ($this->get(Config::class)->get('import_with_redis')) { $service->setProducer($this->get('wallabag_import.producer.redis.chrome')); } @@ -36,6 +38,6 @@ class ChromeController extends BrowserController */ protected function getImportTemplate() { - return 'WallabagImportBundle:Chrome:index.html.twig'; + return '@WallabagImport/Chrome/index.html.twig'; } } diff --git a/src/Wallabag/ImportBundle/Controller/DeliciousController.php b/src/Wallabag/ImportBundle/Controller/DeliciousController.php index 63e6c4a15..6891e59ba 100644 --- a/src/Wallabag/ImportBundle/Controller/DeliciousController.php +++ b/src/Wallabag/ImportBundle/Controller/DeliciousController.php @@ -2,10 +2,14 @@ namespace Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\ImportBundle\Form\Type\UploadImportType; +use Wallabag\ImportBundle\Import\DeliciousImport; class DeliciousController extends Controller { @@ -17,12 +21,12 @@ class DeliciousController extends Controller $form = $this->createForm(UploadImportType::class); $form->handleRequest($request); - $delicious = $this->get('wallabag_import.delicious.import'); + $delicious = $this->get(DeliciousImport::class); $delicious->setUser($this->getUser()); - if ($this->get('craue_config')->get('import_with_rabbitmq')) { + if ($this->get(Config::class)->get('import_with_rabbitmq')) { $delicious->setProducer($this->get('old_sound_rabbit_mq.import_delicious_producer')); - } elseif ($this->get('craue_config')->get('import_with_redis')) { + } elseif ($this->get(Config::class)->get('import_with_redis')) { $delicious->setProducer($this->get('wallabag_import.producer.redis.delicious')); } @@ -41,13 +45,13 @@ class DeliciousController extends Controller if (true === $res) { $summary = $delicious->getSummary(); - $message = $this->get('translator')->trans('flashes.import.notice.summary', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary', [ '%imported%' => $summary['imported'], '%skipped%' => $summary['skipped'], ]); if (0 < $summary['queued']) { - $message = $this->get('translator')->trans('flashes.import.notice.summary_with_queue', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary_with_queue', [ '%queued%' => $summary['queued'], ]); } @@ -55,7 +59,7 @@ class DeliciousController extends Controller unlink($this->getParameter('wallabag_import.resource_dir') . '/' . $name); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', $message ); @@ -63,13 +67,13 @@ class DeliciousController extends Controller return $this->redirect($this->generateUrl('homepage')); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', 'flashes.import.notice.failed_on_file' ); } - return $this->render('WallabagImportBundle:Delicious:index.html.twig', [ + return $this->render('@WallabagImport/Delicious/index.html.twig', [ 'form' => $form->createView(), 'import' => $delicious, ]); diff --git a/src/Wallabag/ImportBundle/Controller/ElcuratorController.php b/src/Wallabag/ImportBundle/Controller/ElcuratorController.php index 174c2c963..7806caecb 100644 --- a/src/Wallabag/ImportBundle/Controller/ElcuratorController.php +++ b/src/Wallabag/ImportBundle/Controller/ElcuratorController.php @@ -2,8 +2,10 @@ namespace Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; +use Wallabag\ImportBundle\Import\ElcuratorImport; class ElcuratorController extends WallabagController { @@ -20,11 +22,11 @@ class ElcuratorController extends WallabagController */ protected function getImportService() { - $service = $this->get('wallabag_import.elcurator.import'); + $service = $this->get(ElcuratorImport::class); - if ($this->get('craue_config')->get('import_with_rabbitmq')) { + if ($this->get(Config::class)->get('import_with_rabbitmq')) { $service->setProducer($this->get('old_sound_rabbit_mq.import_elcurator_producer')); - } elseif ($this->get('craue_config')->get('import_with_redis')) { + } elseif ($this->get(Config::class)->get('import_with_redis')) { $service->setProducer($this->get('wallabag_import.producer.redis.elcurator')); } @@ -36,6 +38,6 @@ class ElcuratorController extends WallabagController */ protected function getImportTemplate() { - return 'WallabagImportBundle:Elcurator:index.html.twig'; + return '@WallabagImport/Elcurator/index.html.twig'; } } diff --git a/src/Wallabag/ImportBundle/Controller/FirefoxController.php b/src/Wallabag/ImportBundle/Controller/FirefoxController.php index dce8455f3..cbe5c8380 100644 --- a/src/Wallabag/ImportBundle/Controller/FirefoxController.php +++ b/src/Wallabag/ImportBundle/Controller/FirefoxController.php @@ -2,8 +2,10 @@ namespace Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; +use Wallabag\ImportBundle\Import\FirefoxImport; class FirefoxController extends BrowserController { @@ -20,11 +22,11 @@ class FirefoxController extends BrowserController */ protected function getImportService() { - $service = $this->get('wallabag_import.firefox.import'); + $service = $this->get(FirefoxImport::class); - if ($this->get('craue_config')->get('import_with_rabbitmq')) { + if ($this->get(Config::class)->get('import_with_rabbitmq')) { $service->setProducer($this->get('old_sound_rabbit_mq.import_firefox_producer')); - } elseif ($this->get('craue_config')->get('import_with_redis')) { + } elseif ($this->get(Config::class)->get('import_with_redis')) { $service->setProducer($this->get('wallabag_import.producer.redis.firefox')); } @@ -36,6 +38,6 @@ class FirefoxController extends BrowserController */ protected function getImportTemplate() { - return 'WallabagImportBundle:Firefox:index.html.twig'; + return '@WallabagImport/Firefox/index.html.twig'; } } diff --git a/src/Wallabag/ImportBundle/Controller/ImportController.php b/src/Wallabag/ImportBundle/Controller/ImportController.php index 774017b9c..08af2248a 100644 --- a/src/Wallabag/ImportBundle/Controller/ImportController.php +++ b/src/Wallabag/ImportBundle/Controller/ImportController.php @@ -2,8 +2,12 @@ namespace Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Predis\Client; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Wallabag\ImportBundle\Import\ImportChain; class ImportController extends Controller { @@ -12,8 +16,8 @@ class ImportController extends Controller */ public function importAction() { - return $this->render('WallabagImportBundle:Import:index.html.twig', [ - 'imports' => $this->get('wallabag_import.chain')->getAll(), + return $this->render('@WallabagImport/Import/index.html.twig', [ + 'imports' => $this->get(ImportChain::class)->getAll(), ]); } @@ -28,11 +32,11 @@ class ImportController extends Controller $redisNotInstalled = false; $rabbitNotInstalled = false; - if (!$this->get('security.authorization_checker')->isGranted('ROLE_SUPER_ADMIN')) { - return $this->render('WallabagImportBundle:Import:check_queue.html.twig'); + if (!$this->get(AuthorizationCheckerInterface::class)->isGranted('ROLE_SUPER_ADMIN')) { + return $this->render('@WallabagImport/Import/check_queue.html.twig'); } - if ($this->get('craue_config')->get('import_with_rabbitmq')) { + if ($this->get(Config::class)->get('import_with_rabbitmq')) { // in case rabbit is activated but not installed try { $nbRabbitMessages = $this->getTotalMessageInRabbitQueue('pocket') @@ -49,8 +53,8 @@ class ImportController extends Controller } catch (\Exception $e) { $rabbitNotInstalled = true; } - } elseif ($this->get('craue_config')->get('import_with_redis')) { - $redis = $this->get('wallabag_core.redis.client'); + } elseif ($this->get(Config::class)->get('import_with_redis')) { + $redis = $this->get(Client::class); try { $nbRedisMessages = $redis->llen('wallabag.import.pocket') @@ -69,7 +73,7 @@ class ImportController extends Controller } } - return $this->render('WallabagImportBundle:Import:check_queue.html.twig', [ + return $this->render('@WallabagImport/Import/check_queue.html.twig', [ 'nbRedisMessages' => $nbRedisMessages, 'nbRabbitMessages' => $nbRabbitMessages, 'redisNotInstalled' => $redisNotInstalled, diff --git a/src/Wallabag/ImportBundle/Controller/InstapaperController.php b/src/Wallabag/ImportBundle/Controller/InstapaperController.php index faed3b728..25f6d07da 100644 --- a/src/Wallabag/ImportBundle/Controller/InstapaperController.php +++ b/src/Wallabag/ImportBundle/Controller/InstapaperController.php @@ -2,10 +2,14 @@ namespace Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\ImportBundle\Form\Type\UploadImportType; +use Wallabag\ImportBundle\Import\InstapaperImport; class InstapaperController extends Controller { @@ -17,12 +21,12 @@ class InstapaperController extends Controller $form = $this->createForm(UploadImportType::class); $form->handleRequest($request); - $instapaper = $this->get('wallabag_import.instapaper.import'); + $instapaper = $this->get(InstapaperImport::class); $instapaper->setUser($this->getUser()); - if ($this->get('craue_config')->get('import_with_rabbitmq')) { + if ($this->get(Config::class)->get('import_with_rabbitmq')) { $instapaper->setProducer($this->get('old_sound_rabbit_mq.import_instapaper_producer')); - } elseif ($this->get('craue_config')->get('import_with_redis')) { + } elseif ($this->get(Config::class)->get('import_with_redis')) { $instapaper->setProducer($this->get('wallabag_import.producer.redis.instapaper')); } @@ -41,13 +45,13 @@ class InstapaperController extends Controller if (true === $res) { $summary = $instapaper->getSummary(); - $message = $this->get('translator')->trans('flashes.import.notice.summary', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary', [ '%imported%' => $summary['imported'], '%skipped%' => $summary['skipped'], ]); if (0 < $summary['queued']) { - $message = $this->get('translator')->trans('flashes.import.notice.summary_with_queue', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary_with_queue', [ '%queued%' => $summary['queued'], ]); } @@ -55,7 +59,7 @@ class InstapaperController extends Controller unlink($this->getParameter('wallabag_import.resource_dir') . '/' . $name); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', $message ); @@ -63,13 +67,13 @@ class InstapaperController extends Controller return $this->redirect($this->generateUrl('homepage')); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', 'flashes.import.notice.failed_on_file' ); } - return $this->render('WallabagImportBundle:Instapaper:index.html.twig', [ + return $this->render('@WallabagImport/Instapaper/index.html.twig', [ 'form' => $form->createView(), 'import' => $instapaper, ]); diff --git a/src/Wallabag/ImportBundle/Controller/PinboardController.php b/src/Wallabag/ImportBundle/Controller/PinboardController.php index cc6fae798..523ea52bc 100644 --- a/src/Wallabag/ImportBundle/Controller/PinboardController.php +++ b/src/Wallabag/ImportBundle/Controller/PinboardController.php @@ -2,10 +2,14 @@ namespace Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\ImportBundle\Form\Type\UploadImportType; +use Wallabag\ImportBundle\Import\PinboardImport; class PinboardController extends Controller { @@ -17,12 +21,12 @@ class PinboardController extends Controller $form = $this->createForm(UploadImportType::class); $form->handleRequest($request); - $pinboard = $this->get('wallabag_import.pinboard.import'); + $pinboard = $this->get(PinboardImport::class); $pinboard->setUser($this->getUser()); - if ($this->get('craue_config')->get('import_with_rabbitmq')) { + if ($this->get(Config::class)->get('import_with_rabbitmq')) { $pinboard->setProducer($this->get('old_sound_rabbit_mq.import_pinboard_producer')); - } elseif ($this->get('craue_config')->get('import_with_redis')) { + } elseif ($this->get(Config::class)->get('import_with_redis')) { $pinboard->setProducer($this->get('wallabag_import.producer.redis.pinboard')); } @@ -41,13 +45,13 @@ class PinboardController extends Controller if (true === $res) { $summary = $pinboard->getSummary(); - $message = $this->get('translator')->trans('flashes.import.notice.summary', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary', [ '%imported%' => $summary['imported'], '%skipped%' => $summary['skipped'], ]); if (0 < $summary['queued']) { - $message = $this->get('translator')->trans('flashes.import.notice.summary_with_queue', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary_with_queue', [ '%queued%' => $summary['queued'], ]); } @@ -55,7 +59,7 @@ class PinboardController extends Controller unlink($this->getParameter('wallabag_import.resource_dir') . '/' . $name); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', $message ); @@ -63,13 +67,13 @@ class PinboardController extends Controller return $this->redirect($this->generateUrl('homepage')); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', 'flashes.import.notice.failed_on_file' ); } - return $this->render('WallabagImportBundle:Pinboard:index.html.twig', [ + return $this->render('@WallabagImport/Pinboard/index.html.twig', [ 'form' => $form->createView(), 'import' => $pinboard, ]); diff --git a/src/Wallabag/ImportBundle/Controller/PocketController.php b/src/Wallabag/ImportBundle/Controller/PocketController.php index f952867bd..b403db74c 100644 --- a/src/Wallabag/ImportBundle/Controller/PocketController.php +++ b/src/Wallabag/ImportBundle/Controller/PocketController.php @@ -2,11 +2,15 @@ namespace Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Translation\TranslatorInterface; +use Wallabag\ImportBundle\Import\PocketImport; class PocketController extends Controller { @@ -23,7 +27,7 @@ class PocketController extends Controller ]) ->getForm(); - return $this->render('WallabagImportBundle:Pocket:index.html.twig', [ + return $this->render('@WallabagImport/Pocket/index.html.twig', [ 'import' => $this->getPocketImportService(), 'has_consumer_key' => '' === trim($this->getUser()->getConfig()->getPocketConsumerKey()) ? false : true, 'form' => $form->createView(), @@ -39,7 +43,7 @@ class PocketController extends Controller ->getRequestToken($this->generateUrl('import', [], UrlGeneratorInterface::ABSOLUTE_URL)); if (false === $requestToken) { - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', 'flashes.import.notice.failed' ); @@ -49,9 +53,9 @@ class PocketController extends Controller $form = $request->request->get('form'); - $this->get('session')->set('import.pocket.code', $requestToken); + $this->get(SessionInterface::class)->set('import.pocket.code', $requestToken); if (null !== $form && \array_key_exists('mark_as_read', $form)) { - $this->get('session')->set('mark_as_read', $form['mark_as_read']); + $this->get(SessionInterface::class)->set('mark_as_read', $form['mark_as_read']); } return $this->redirect( @@ -68,12 +72,12 @@ class PocketController extends Controller $message = 'flashes.import.notice.failed'; $pocket = $this->getPocketImportService(); - $markAsRead = $this->get('session')->get('mark_as_read'); - $this->get('session')->remove('mark_as_read'); + $markAsRead = $this->get(SessionInterface::class)->get('mark_as_read'); + $this->get(SessionInterface::class)->remove('mark_as_read'); // something bad happend on pocket side - if (false === $pocket->authorize($this->get('session')->get('import.pocket.code'))) { - $this->get('session')->getFlashBag()->add( + if (false === $pocket->authorize($this->get(SessionInterface::class)->get('import.pocket.code'))) { + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', $message ); @@ -83,19 +87,19 @@ class PocketController extends Controller if (true === $pocket->setMarkAsRead($markAsRead)->import()) { $summary = $pocket->getSummary(); - $message = $this->get('translator')->trans('flashes.import.notice.summary', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary', [ '%imported%' => null !== $summary && \array_key_exists('imported', $summary) ? $summary['imported'] : 0, '%skipped%' => null !== $summary && \array_key_exists('skipped', $summary) ? $summary['skipped'] : 0, ]); if (null !== $summary && \array_key_exists('queued', $summary) && 0 < $summary['queued']) { - $message = $this->get('translator')->trans('flashes.import.notice.summary_with_queue', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary_with_queue', [ '%queued%' => $summary['queued'], ]); } } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', $message ); @@ -106,16 +110,16 @@ class PocketController extends Controller /** * Return Pocket Import Service with or without RabbitMQ enabled. * - * @return \Wallabag\ImportBundle\Import\PocketImport + * @return PocketImport */ private function getPocketImportService() { - $pocket = $this->get('wallabag_import.pocket.import'); + $pocket = $this->get(PocketImport::class); $pocket->setUser($this->getUser()); - if ($this->get('craue_config')->get('import_with_rabbitmq')) { + if ($this->get(Config::class)->get('import_with_rabbitmq')) { $pocket->setProducer($this->get('old_sound_rabbit_mq.import_pocket_producer')); - } elseif ($this->get('craue_config')->get('import_with_redis')) { + } elseif ($this->get(Config::class)->get('import_with_redis')) { $pocket->setProducer($this->get('wallabag_import.producer.redis.pocket')); } diff --git a/src/Wallabag/ImportBundle/Controller/ReadabilityController.php b/src/Wallabag/ImportBundle/Controller/ReadabilityController.php index b120ef967..1c257f895 100644 --- a/src/Wallabag/ImportBundle/Controller/ReadabilityController.php +++ b/src/Wallabag/ImportBundle/Controller/ReadabilityController.php @@ -2,10 +2,14 @@ namespace Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\ImportBundle\Form\Type\UploadImportType; +use Wallabag\ImportBundle\Import\ReadabilityImport; class ReadabilityController extends Controller { @@ -17,12 +21,12 @@ class ReadabilityController extends Controller $form = $this->createForm(UploadImportType::class); $form->handleRequest($request); - $readability = $this->get('wallabag_import.readability.import'); + $readability = $this->get(ReadabilityImport::class); $readability->setUser($this->getUser()); - if ($this->get('craue_config')->get('import_with_rabbitmq')) { + if ($this->get(Config::class)->get('import_with_rabbitmq')) { $readability->setProducer($this->get('old_sound_rabbit_mq.import_readability_producer')); - } elseif ($this->get('craue_config')->get('import_with_redis')) { + } elseif ($this->get(Config::class)->get('import_with_redis')) { $readability->setProducer($this->get('wallabag_import.producer.redis.readability')); } @@ -41,13 +45,13 @@ class ReadabilityController extends Controller if (true === $res) { $summary = $readability->getSummary(); - $message = $this->get('translator')->trans('flashes.import.notice.summary', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary', [ '%imported%' => $summary['imported'], '%skipped%' => $summary['skipped'], ]); if (0 < $summary['queued']) { - $message = $this->get('translator')->trans('flashes.import.notice.summary_with_queue', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary_with_queue', [ '%queued%' => $summary['queued'], ]); } @@ -55,7 +59,7 @@ class ReadabilityController extends Controller unlink($this->getParameter('wallabag_import.resource_dir') . '/' . $name); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', $message ); @@ -63,13 +67,13 @@ class ReadabilityController extends Controller return $this->redirect($this->generateUrl('homepage')); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', 'flashes.import.notice.failed_on_file' ); } - return $this->render('WallabagImportBundle:Readability:index.html.twig', [ + return $this->render('@WallabagImport/Readability/index.html.twig', [ 'form' => $form->createView(), 'import' => $readability, ]); diff --git a/src/Wallabag/ImportBundle/Controller/WallabagController.php b/src/Wallabag/ImportBundle/Controller/WallabagController.php index 5180006d3..db78e671c 100644 --- a/src/Wallabag/ImportBundle/Controller/WallabagController.php +++ b/src/Wallabag/ImportBundle/Controller/WallabagController.php @@ -6,7 +6,10 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\SessionInterface; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\ImportBundle\Form\Type\UploadImportType; +use Wallabag\ImportBundle\Import\ImportInterface; /** * Define Wallabag import for v1 and v2, since there are very similar. @@ -41,13 +44,13 @@ abstract class WallabagController extends Controller if (true === $res) { $summary = $wallabag->getSummary(); - $message = $this->get('translator')->trans('flashes.import.notice.summary', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary', [ '%imported%' => $summary['imported'], '%skipped%' => $summary['skipped'], ]); if (0 < $summary['queued']) { - $message = $this->get('translator')->trans('flashes.import.notice.summary_with_queue', [ + $message = $this->get(TranslatorInterface::class)->trans('flashes.import.notice.summary_with_queue', [ '%queued%' => $summary['queued'], ]); } @@ -55,7 +58,7 @@ abstract class WallabagController extends Controller unlink($this->getParameter('wallabag_import.resource_dir') . '/' . $name); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', $message ); @@ -63,7 +66,7 @@ abstract class WallabagController extends Controller return $this->redirect($this->generateUrl('homepage')); } - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', 'flashes.import.notice.failed_on_file' ); @@ -78,7 +81,7 @@ abstract class WallabagController extends Controller /** * Return the service to handle the import. * - * @return \Wallabag\ImportBundle\Import\ImportInterface + * @return ImportInterface */ abstract protected function getImportService(); diff --git a/src/Wallabag/ImportBundle/Controller/WallabagV1Controller.php b/src/Wallabag/ImportBundle/Controller/WallabagV1Controller.php index e1c353438..cff632fee 100644 --- a/src/Wallabag/ImportBundle/Controller/WallabagV1Controller.php +++ b/src/Wallabag/ImportBundle/Controller/WallabagV1Controller.php @@ -2,8 +2,10 @@ namespace Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; +use Wallabag\ImportBundle\Import\WallabagV1Import; class WallabagV1Controller extends WallabagController { @@ -20,11 +22,11 @@ class WallabagV1Controller extends WallabagController */ protected function getImportService() { - $service = $this->get('wallabag_import.wallabag_v1.import'); + $service = $this->get(WallabagV1Import::class); - if ($this->get('craue_config')->get('import_with_rabbitmq')) { + if ($this->get(Config::class)->get('import_with_rabbitmq')) { $service->setProducer($this->get('old_sound_rabbit_mq.import_wallabag_v1_producer')); - } elseif ($this->get('craue_config')->get('import_with_redis')) { + } elseif ($this->get(Config::class)->get('import_with_redis')) { $service->setProducer($this->get('wallabag_import.producer.redis.wallabag_v1')); } @@ -36,6 +38,6 @@ class WallabagV1Controller extends WallabagController */ protected function getImportTemplate() { - return 'WallabagImportBundle:WallabagV1:index.html.twig'; + return '@WallabagImport/WallabagV1/index.html.twig'; } } diff --git a/src/Wallabag/ImportBundle/Controller/WallabagV2Controller.php b/src/Wallabag/ImportBundle/Controller/WallabagV2Controller.php index c4116c1d0..07eebb92a 100644 --- a/src/Wallabag/ImportBundle/Controller/WallabagV2Controller.php +++ b/src/Wallabag/ImportBundle/Controller/WallabagV2Controller.php @@ -2,8 +2,10 @@ namespace Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; +use Wallabag\ImportBundle\Import\WallabagV2Import; class WallabagV2Controller extends WallabagController { @@ -20,11 +22,11 @@ class WallabagV2Controller extends WallabagController */ protected function getImportService() { - $service = $this->get('wallabag_import.wallabag_v2.import'); + $service = $this->get(WallabagV2Import::class); - if ($this->get('craue_config')->get('import_with_rabbitmq')) { + if ($this->get(Config::class)->get('import_with_rabbitmq')) { $service->setProducer($this->get('old_sound_rabbit_mq.import_wallabag_v2_producer')); - } elseif ($this->get('craue_config')->get('import_with_redis')) { + } elseif ($this->get(Config::class)->get('import_with_redis')) { $service->setProducer($this->get('wallabag_import.producer.redis.wallabag_v2')); } @@ -36,6 +38,6 @@ class WallabagV2Controller extends WallabagController */ protected function getImportTemplate() { - return 'WallabagImportBundle:WallabagV2:index.html.twig'; + return '@WallabagImport/WallabagV2/index.html.twig'; } } diff --git a/src/Wallabag/ImportBundle/DependencyInjection/WallabagImportExtension.php b/src/Wallabag/ImportBundle/DependencyInjection/WallabagImportExtension.php index cab70297b..2aa7d26fa 100644 --- a/src/Wallabag/ImportBundle/DependencyInjection/WallabagImportExtension.php +++ b/src/Wallabag/ImportBundle/DependencyInjection/WallabagImportExtension.php @@ -2,9 +2,7 @@ namespace Wallabag\ImportBundle\DependencyInjection; -use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; class WallabagImportExtension extends Extension @@ -15,9 +13,6 @@ class WallabagImportExtension extends Extension $config = $this->processConfiguration($configuration, $configs); $container->setParameter('wallabag_import.allow_mimetypes', $config['allow_mimetypes']); $container->setParameter('wallabag_import.resource_dir', $config['resource_dir']); - - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); - $loader->load('services.yml'); } public function getAlias() diff --git a/src/Wallabag/ImportBundle/Import/AbstractImport.php b/src/Wallabag/ImportBundle/Import/AbstractImport.php index 1b073e99a..c8be93ed5 100644 --- a/src/Wallabag/ImportBundle/Import/AbstractImport.php +++ b/src/Wallabag/ImportBundle/Import/AbstractImport.php @@ -2,10 +2,9 @@ namespace Wallabag\ImportBundle\Import; -use Doctrine\ORM\EntityManager; +use Doctrine\ORM\EntityManagerInterface; use OldSound\RabbitMqBundle\RabbitMq\ProducerInterface; use Psr\Log\LoggerInterface; -use Psr\Log\NullLogger; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Tag; @@ -29,10 +28,10 @@ abstract class AbstractImport implements ImportInterface protected $importedEntries = 0; protected $queuedEntries = 0; - public function __construct(EntityManager $em, ContentProxy $contentProxy, TagsAssigner $tagsAssigner, EventDispatcherInterface $eventDispatcher) + public function __construct(EntityManagerInterface $em, ContentProxy $contentProxy, TagsAssigner $tagsAssigner, EventDispatcherInterface $eventDispatcher, LoggerInterface $logger) { $this->em = $em; - $this->logger = new NullLogger(); + $this->logger = $logger; $this->contentProxy = $contentProxy; $this->tagsAssigner = $tagsAssigner; $this->eventDispatcher = $eventDispatcher; diff --git a/src/Wallabag/ImportBundle/Import/BrowserImport.php b/src/Wallabag/ImportBundle/Import/BrowserImport.php index ea7afd3dd..3d3979af7 100644 --- a/src/Wallabag/ImportBundle/Import/BrowserImport.php +++ b/src/Wallabag/ImportBundle/Import/BrowserImport.php @@ -108,7 +108,7 @@ abstract class BrowserImport extends AbstractImport $url = \array_key_exists('uri', $importedEntry) ? $importedEntry['uri'] : $importedEntry['url']; $existingEntry = $this->em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findByUrlAndUserId($url, $this->user->getId()); if (false !== $existingEntry) { diff --git a/src/Wallabag/ImportBundle/Import/DeliciousImport.php b/src/Wallabag/ImportBundle/Import/DeliciousImport.php index fa287cce4..9c991748f 100644 --- a/src/Wallabag/ImportBundle/Import/DeliciousImport.php +++ b/src/Wallabag/ImportBundle/Import/DeliciousImport.php @@ -98,7 +98,7 @@ class DeliciousImport extends AbstractImport public function parseEntry(array $importedEntry) { $existingEntry = $this->em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findByUrlAndUserId($importedEntry['url'], $this->user->getId()); if (false !== $existingEntry) { diff --git a/src/Wallabag/ImportBundle/Import/ImportCompilerPass.php b/src/Wallabag/ImportBundle/Import/ImportCompilerPass.php index d7df0a83c..ff23bd19f 100644 --- a/src/Wallabag/ImportBundle/Import/ImportCompilerPass.php +++ b/src/Wallabag/ImportBundle/Import/ImportCompilerPass.php @@ -10,12 +10,12 @@ class ImportCompilerPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - if (!$container->hasDefinition('wallabag_import.chain')) { + if (!$container->hasDefinition(ImportChain::class)) { return; } $definition = $container->getDefinition( - 'wallabag_import.chain' + ImportChain::class ); $taggedServices = $container->findTaggedServiceIds( diff --git a/src/Wallabag/ImportBundle/Import/InstapaperImport.php b/src/Wallabag/ImportBundle/Import/InstapaperImport.php index f7bee9ef0..fbab4f3ad 100644 --- a/src/Wallabag/ImportBundle/Import/InstapaperImport.php +++ b/src/Wallabag/ImportBundle/Import/InstapaperImport.php @@ -126,7 +126,7 @@ class InstapaperImport extends AbstractImport public function parseEntry(array $importedEntry) { $existingEntry = $this->em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findByUrlAndUserId($importedEntry['url'], $this->user->getId()); if (false !== $existingEntry) { diff --git a/src/Wallabag/ImportBundle/Import/PinboardImport.php b/src/Wallabag/ImportBundle/Import/PinboardImport.php index 202eb1b3e..a8b7ced44 100644 --- a/src/Wallabag/ImportBundle/Import/PinboardImport.php +++ b/src/Wallabag/ImportBundle/Import/PinboardImport.php @@ -98,7 +98,7 @@ class PinboardImport extends AbstractImport public function parseEntry(array $importedEntry) { $existingEntry = $this->em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findByUrlAndUserId($importedEntry['href'], $this->user->getId()); if (false !== $existingEntry) { diff --git a/src/Wallabag/ImportBundle/Import/PocketImport.php b/src/Wallabag/ImportBundle/Import/PocketImport.php index 469a8f16c..03103a193 100644 --- a/src/Wallabag/ImportBundle/Import/PocketImport.php +++ b/src/Wallabag/ImportBundle/Import/PocketImport.php @@ -179,7 +179,7 @@ class PocketImport extends AbstractImport $url = isset($importedEntry['resolved_url']) && '' !== $importedEntry['resolved_url'] ? $importedEntry['resolved_url'] : $importedEntry['given_url']; $existingEntry = $this->em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findByUrlAndUserId($url, $this->user->getId()); if (false !== $existingEntry) { diff --git a/src/Wallabag/ImportBundle/Import/ReadabilityImport.php b/src/Wallabag/ImportBundle/Import/ReadabilityImport.php index c5abf1892..2b0829f77 100644 --- a/src/Wallabag/ImportBundle/Import/ReadabilityImport.php +++ b/src/Wallabag/ImportBundle/Import/ReadabilityImport.php @@ -98,7 +98,7 @@ class ReadabilityImport extends AbstractImport public function parseEntry(array $importedEntry) { $existingEntry = $this->em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findByUrlAndUserId($importedEntry['article__url'], $this->user->getId()); if (false !== $existingEntry) { diff --git a/src/Wallabag/ImportBundle/Import/WallabagImport.php b/src/Wallabag/ImportBundle/Import/WallabagImport.php index 75a28fbf5..7a03b9377 100644 --- a/src/Wallabag/ImportBundle/Import/WallabagImport.php +++ b/src/Wallabag/ImportBundle/Import/WallabagImport.php @@ -104,7 +104,7 @@ abstract class WallabagImport extends AbstractImport public function parseEntry(array $importedEntry) { $existingEntry = $this->em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findByUrlAndUserId($importedEntry['url'], $this->user->getId()); if (false !== $existingEntry) { diff --git a/src/Wallabag/ImportBundle/Import/WallabagV1Import.php b/src/Wallabag/ImportBundle/Import/WallabagV1Import.php index e05626117..895fba11c 100644 --- a/src/Wallabag/ImportBundle/Import/WallabagV1Import.php +++ b/src/Wallabag/ImportBundle/Import/WallabagV1Import.php @@ -2,17 +2,23 @@ namespace Wallabag\ImportBundle\Import; +use Doctrine\ORM\EntityManagerInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Helper\TagsAssigner; + class WallabagV1Import extends WallabagImport { protected $fetchingErrorMessage; protected $fetchingErrorMessageTitle; - public function __construct($em, $contentProxy, $tagsAssigner, $eventDispatcher, $fetchingErrorMessageTitle, $fetchingErrorMessage) + public function __construct(EntityManagerInterface $em, ContentProxy $contentProxy, TagsAssigner $tagsAssigner, EventDispatcherInterface $eventDispatcher, LoggerInterface $logger, $fetchingErrorMessageTitle, $fetchingErrorMessage) { $this->fetchingErrorMessageTitle = $fetchingErrorMessageTitle; $this->fetchingErrorMessage = $fetchingErrorMessage; - parent::__construct($em, $contentProxy, $tagsAssigner, $eventDispatcher); + parent::__construct($em, $contentProxy, $tagsAssigner, $eventDispatcher, $logger); } /** diff --git a/src/Wallabag/ImportBundle/Resources/config/rabbit.yml b/src/Wallabag/ImportBundle/Resources/config/rabbit.yml deleted file mode 100644 index 8eb2bbcc8..000000000 --- a/src/Wallabag/ImportBundle/Resources/config/rabbit.yml +++ /dev/null @@ -1,82 +0,0 @@ -# RabbitMQ stuff -services: - wallabag_import.consumer.amqp.pocket: - class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.pocket.import" - - "@event_dispatcher" - - "@logger" - wallabag_import.consumer.amqp.readability: - class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.readability.import" - - "@event_dispatcher" - - "@logger" - wallabag_import.consumer.amqp.instapaper: - class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.instapaper.import" - - "@event_dispatcher" - - "@logger" - wallabag_import.consumer.amqp.pinboard: - class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.pinboard.import" - - "@event_dispatcher" - - "@logger" - wallabag_import.consumer.amqp.delicious: - class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.delicious.import" - - "@event_dispatcher" - - "@logger" - wallabag_import.consumer.amqp.wallabag_v1: - class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.wallabag_v1.import" - - "@event_dispatcher" - - "@logger" - wallabag_import.consumer.amqp.wallabag_v2: - class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.wallabag_v2.import" - - "@event_dispatcher" - - "@logger" - wallabag_import.consumer.amqp.elcurator: - class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.elcurator.import" - - "@event_dispatcher" - - "@logger" - wallabag_import.consumer.amqp.firefox: - class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.firefox.import" - - "@event_dispatcher" - - "@logger" - wallabag_import.consumer.amqp.chrome: - class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_user.user_repository" - - "@wallabag_import.chrome.import" - - "@event_dispatcher" - - "@logger" diff --git a/src/Wallabag/ImportBundle/Resources/config/services.yml b/src/Wallabag/ImportBundle/Resources/config/services.yml deleted file mode 100644 index d9259365c..000000000 --- a/src/Wallabag/ImportBundle/Resources/config/services.yml +++ /dev/null @@ -1,140 +0,0 @@ -imports: - - { resource: rabbit.yml } - - { resource: redis.yml } - -services: - wallabag_import.chain: - class: Wallabag\ImportBundle\Import\ImportChain - - wallabag_import.pocket.client: - alias: 'httplug.client.wallabag_import.pocket.client' - - wallabag_import.pocket.import: - class: Wallabag\ImportBundle\Import\PocketImport - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_core.content_proxy" - - "@wallabag_core.tags_assigner" - - "@event_dispatcher" - calls: - - [ setClient, [ "@wallabag_import.pocket.client" ] ] - - [ setLogger, [ "@logger" ]] - tags: - - { name: wallabag_import.import, alias: pocket } - - wallabag_import.wallabag_v1.import: - class: Wallabag\ImportBundle\Import\WallabagV1Import - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_core.content_proxy" - - "@wallabag_core.tags_assigner" - - "@event_dispatcher" - - "%wallabag_core.fetching_error_message_title%" - - "%wallabag_core.fetching_error_message%" - calls: - - [ setLogger, [ "@logger" ]] - tags: - - { name: wallabag_import.import, alias: wallabag_v1 } - - wallabag_import.wallabag_v2.import: - class: Wallabag\ImportBundle\Import\WallabagV2Import - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_core.content_proxy" - - "@wallabag_core.tags_assigner" - - "@event_dispatcher" - calls: - - [ setLogger, [ "@logger" ]] - tags: - - { name: wallabag_import.import, alias: wallabag_v2 } - - wallabag_import.elcurator.import: - class: Wallabag\ImportBundle\Import\ElcuratorImport - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_core.content_proxy" - - "@wallabag_core.tags_assigner" - - "@event_dispatcher" - calls: - - [ setLogger, [ "@logger" ]] - tags: - - { name: wallabag_import.import, alias: elcurator } - - wallabag_import.readability.import: - class: Wallabag\ImportBundle\Import\ReadabilityImport - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_core.content_proxy" - - "@wallabag_core.tags_assigner" - - "@event_dispatcher" - calls: - - [ setLogger, [ "@logger" ]] - tags: - - { name: wallabag_import.import, alias: readability } - - wallabag_import.instapaper.import: - class: Wallabag\ImportBundle\Import\InstapaperImport - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_core.content_proxy" - - "@wallabag_core.tags_assigner" - - "@event_dispatcher" - calls: - - [ setLogger, [ "@logger" ]] - tags: - - { name: wallabag_import.import, alias: instapaper } - - wallabag_import.pinboard.import: - class: Wallabag\ImportBundle\Import\PinboardImport - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_core.content_proxy" - - "@wallabag_core.tags_assigner" - - "@event_dispatcher" - calls: - - [ setLogger, [ "@logger" ]] - tags: - - { name: wallabag_import.import, alias: pinboard } - - wallabag_import.delicious.import: - class: Wallabag\ImportBundle\Import\DeliciousImport - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_core.content_proxy" - - "@wallabag_core.tags_assigner" - - "@event_dispatcher" - calls: - - [ setLogger, [ "@logger" ]] - tags: - - { name: wallabag_import.import, alias: delicious } - - wallabag_import.firefox.import: - class: Wallabag\ImportBundle\Import\FirefoxImport - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_core.content_proxy" - - "@wallabag_core.tags_assigner" - - "@event_dispatcher" - calls: - - [ setLogger, [ "@logger" ]] - tags: - - { name: wallabag_import.import, alias: firefox } - wallabag_import.chrome.import: - class: Wallabag\ImportBundle\Import\ChromeImport - arguments: - - "@doctrine.orm.entity_manager" - - "@wallabag_core.content_proxy" - - "@wallabag_core.tags_assigner" - - "@event_dispatcher" - calls: - - [ setLogger, [ "@logger" ]] - tags: - - { name: wallabag_import.import, alias: chrome } - - wallabag_import.command.import: - class: Wallabag\ImportBundle\Command\ImportCommand - tags: ['console.command'] - - wallabag_import.command.redis_worker: - class: Wallabag\ImportBundle\Command\RedisWorkerCommand - tags: ['console.command'] diff --git a/src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig index 93b08540f..331251046 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'import.chrome.page_title'|trans }}{% endblock %} @@ -6,7 +6,7 @@
- {% include 'WallabagImportBundle:Import:_information.html.twig' %} + {% include '@WallabagImport/Import/_information.html.twig' %}
{{ import.description|trans|raw }}
@@ -33,7 +33,7 @@
- {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }} + {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} {{ form_rest(form) }} diff --git a/src/Wallabag/ImportBundle/Resources/views/Delicious/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Delicious/index.html.twig index df3ca8eb4..8e5741c45 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Delicious/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Delicious/index.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'import.delicious.page_title'|trans }}{% endblock %} @@ -6,7 +6,7 @@
- {% include 'WallabagImportBundle:Import:_information.html.twig' %} + {% include '@WallabagImport/Import/_information.html.twig' %}
{{ import.description|trans }}
@@ -33,7 +33,7 @@
- {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }} + {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} {{ form_rest(form) }} diff --git a/src/Wallabag/ImportBundle/Resources/views/Elcurator/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Elcurator/index.html.twig index e3a0d709f..2d950c95c 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Elcurator/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Elcurator/index.html.twig @@ -1,3 +1,3 @@ -{% extends "WallabagImportBundle:WallabagV1:index.html.twig" %} +{% extends "@WallabagImport/WallabagV1/index.html.twig" %} {% block title %}{{ 'import.elcurator.page_title'|trans }}{% endblock %} diff --git a/src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig index ced3f0088..e262da8a6 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'import.firefox.page_title'|trans }}{% endblock %} @@ -6,7 +6,7 @@
- {% include 'WallabagImportBundle:Import:_information.html.twig' %} + {% include '@WallabagImport/Import/_information.html.twig' %}
{{ import.description|trans|raw }}
@@ -33,7 +33,7 @@
- {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }} + {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} {{ form_rest(form) }} diff --git a/src/Wallabag/ImportBundle/Resources/views/Import/_information.html.twig b/src/Wallabag/ImportBundle/Resources/views/Import/_information.html.twig index 48bbcfe7d..9d8f760ef 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Import/_information.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Import/_information.html.twig @@ -1,6 +1,6 @@ {% set redis = craue_setting('import_with_redis') %} {% set rabbit = craue_setting('import_with_rabbitmq') %} -{% set downloadImages = craue_setting('download_images_enabled') %} +{% set download_images = craue_setting('download_images_enabled') %} {% if redis or rabbit %}
@@ -8,7 +8,7 @@
{% endif %} -{% if not redis and not rabbit and downloadImages %} +{% if not redis and not rabbit and download_images %}
{{ 'import.worker.download_images_warning'|trans|raw }}
diff --git a/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig index b79a1470b..6903a5fd4 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig @@ -1,9 +1,9 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'import.page_title'|trans }}{% endblock %} {% block messages %} - {{ render(controller("WallabagImportBundle:Import:checkQueue")) }} + {{ render(controller('Wallabag\\ImportBundle\\Controller\\ImportController::checkQueueAction')) }} {{ parent() }} {% endblock %} @@ -12,7 +12,7 @@
- {% include 'WallabagImportBundle:Import:_information.html.twig' %} + {% include '@WallabagImport/Import/_information.html.twig' %} {{ 'import.page_description'|trans }}
    diff --git a/src/Wallabag/ImportBundle/Resources/views/Instapaper/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Instapaper/index.html.twig index 28165d190..38f5eeda6 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Instapaper/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Instapaper/index.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'import.instapaper.page_title'|trans }}{% endblock %} @@ -6,7 +6,7 @@
    - {% include 'WallabagImportBundle:Import:_information.html.twig' %} + {% include '@WallabagImport/Import/_information.html.twig' %}
    {{ import.description|trans }}
    @@ -33,7 +33,7 @@
    - {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }} + {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} {{ form_rest(form) }} diff --git a/src/Wallabag/ImportBundle/Resources/views/Pinboard/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Pinboard/index.html.twig index 43f196ad1..9c79e088c 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Pinboard/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Pinboard/index.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'import.pinboard.page_title'|trans }}{% endblock %} @@ -6,7 +6,7 @@
    - {% include 'WallabagImportBundle:Import:_information.html.twig' %} + {% include '@WallabagImport/Import/_information.html.twig' %}
    {{ import.description|trans }}
    @@ -33,7 +33,7 @@
    - {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }} + {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} {{ form_rest(form) }} diff --git a/src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig index e58358b9c..781b873e1 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'import.pocket.page_title'|trans }}{% endblock %} @@ -6,13 +6,13 @@
    - {% include 'WallabagImportBundle:Import:_information.html.twig' %} + {% include '@WallabagImport/Import/_information.html.twig' %} {% if not has_consumer_key %}
    {{ 'import.pocket.config_missing.description'|trans }} - {{ 'import.pocket.config_missing.admin_message'|trans({'%keyurls%': '', '%keyurle%':''})|raw }} + {{ 'import.pocket.config_missing.admin_message'|trans({'%keyurls%': '', '%keyurle%': ''})|raw }}
    {% endif %} diff --git a/src/Wallabag/ImportBundle/Resources/views/Readability/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Readability/index.html.twig index 737b0adf4..70eceb103 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Readability/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Readability/index.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'import.readability.page_title'|trans }}{% endblock %} @@ -6,7 +6,7 @@
    - {% include 'WallabagImportBundle:Import:_information.html.twig' %} + {% include '@WallabagImport/Import/_information.html.twig' %}
    {{ import.description|trans }}
    @@ -33,7 +33,7 @@
    - {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }} + {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} {{ form_rest(form) }} diff --git a/src/Wallabag/ImportBundle/Resources/views/WallabagV1/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/WallabagV1/index.html.twig index 974b2c73e..6e0598afa 100644 --- a/src/Wallabag/ImportBundle/Resources/views/WallabagV1/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/WallabagV1/index.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'import.wallabag_v1.page_title'|trans }}{% endblock %} @@ -6,7 +6,7 @@
    - {% include 'WallabagImportBundle:Import:_information.html.twig' %} + {% include '@WallabagImport/Import/_information.html.twig' %}
    {{ import.description|trans }}
    @@ -33,7 +33,7 @@
    - {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }} + {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} {{ form_rest(form) }} diff --git a/src/Wallabag/ImportBundle/Resources/views/WallabagV2/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/WallabagV2/index.html.twig index c2905fc64..2521578c8 100644 --- a/src/Wallabag/ImportBundle/Resources/views/WallabagV2/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/WallabagV2/index.html.twig @@ -1,3 +1,3 @@ -{% extends "WallabagImportBundle:WallabagV1:index.html.twig" %} +{% extends "@WallabagImport/WallabagV1/index.html.twig" %} {% block title %}{{ 'import.wallabag_v2.page_title'|trans }}{% endblock %} diff --git a/src/Wallabag/UserBundle/Controller/ManageController.php b/src/Wallabag/UserBundle/Controller/ManageController.php index 353950667..1d2bcbb40 100644 --- a/src/Wallabag/UserBundle/Controller/ManageController.php +++ b/src/Wallabag/UserBundle/Controller/ManageController.php @@ -4,14 +4,23 @@ namespace Wallabag\UserBundle\Controller; use FOS\UserBundle\Event\UserEvent; use FOS\UserBundle\FOSUserEvents; +use FOS\UserBundle\Model\UserManagerInterface; use Pagerfanta\Doctrine\ORM\QueryAdapter as DoctrineORMAdapter; use Pagerfanta\Exception\OutOfRangeCurrentPageException; use Pagerfanta\Pagerfanta; +use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface; use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Form\Form; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Translation\TranslatorInterface; use Wallabag\UserBundle\Entity\User; +use Wallabag\UserBundle\Form\NewUserType; use Wallabag\UserBundle\Form\SearchUserType; +use Wallabag\UserBundle\Form\UserType; /** * User controller. @@ -25,13 +34,13 @@ class ManageController extends Controller */ public function newAction(Request $request) { - $userManager = $this->container->get('fos_user.user_manager'); + $userManager = $this->container->get(UserManagerInterface::class); $user = $userManager->createUser(); // enable created user by default $user->setEnabled(true); - $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user); + $form = $this->createForm(NewUserType::class, $user); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { @@ -39,17 +48,17 @@ class ManageController extends Controller // dispatch a created event so the associated config will be created $event = new UserEvent($user, $request); - $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event); + $this->get(EventDispatcherInterface::class)->dispatch(FOSUserEvents::USER_CREATED, $event); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.user.notice.added', ['%username%' => $user->getUsername()]) + $this->get(TranslatorInterface::class)->trans('flashes.user.notice.added', ['%username%' => $user->getUsername()]) ); return $this->redirectToRoute('user_edit', ['id' => $user->getId()]); } - return $this->render('WallabagUserBundle:Manage:new.html.twig', [ + return $this->render('@WallabagUser/Manage/new.html.twig', [ 'user' => $user, 'form' => $form->createView(), ]); @@ -62,10 +71,10 @@ class ManageController extends Controller */ public function editAction(Request $request, User $user) { - $userManager = $this->container->get('fos_user.user_manager'); + $userManager = $this->container->get(UserManagerInterface::class); $deleteForm = $this->createDeleteForm($user); - $form = $this->createForm('Wallabag\UserBundle\Form\UserType', $user); + $form = $this->createForm(UserType::class, $user); $form->handleRequest($request); // `googleTwoFactor` isn't a field within the User entity, we need to define it's value in a different way @@ -77,7 +86,7 @@ class ManageController extends Controller // handle creation / reset of the OTP secret if checkbox changed from the previous state if ($this->getParameter('twofactor_auth')) { if (true === $form->get('googleTwoFactor')->getData() && false === $user->isGoogleAuthenticatorEnabled()) { - $user->setGoogleAuthenticatorSecret($this->get('scheb_two_factor.security.google_authenticator')->generateSecret()); + $user->setGoogleAuthenticatorSecret($this->get(GoogleAuthenticatorInterface::class)->generateSecret()); $user->setEmailTwoFactor(false); } elseif (false === $form->get('googleTwoFactor')->getData() && true === $user->isGoogleAuthenticatorEnabled()) { $user->setGoogleAuthenticatorSecret(null); @@ -86,15 +95,15 @@ class ManageController extends Controller $userManager->updateUser($user); - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.user.notice.updated', ['%username%' => $user->getUsername()]) + $this->get(TranslatorInterface::class)->trans('flashes.user.notice.updated', ['%username%' => $user->getUsername()]) ); return $this->redirectToRoute('user_edit', ['id' => $user->getId()]); } - return $this->render('WallabagUserBundle:Manage:edit.html.twig', [ + return $this->render('@WallabagUser/Manage/edit.html.twig', [ 'user' => $user, 'edit_form' => $form->createView(), 'delete_form' => $deleteForm->createView(), @@ -113,9 +122,9 @@ class ManageController extends Controller $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $this->get('session')->getFlashBag()->add( + $this->get(SessionInterface::class)->getFlashBag()->add( 'notice', - $this->get('translator')->trans('flashes.user.notice.deleted', ['%username%' => $user->getUsername()]) + $this->get(TranslatorInterface::class)->trans('flashes.user.notice.deleted', ['%username%' => $user->getUsername()]) ); $em = $this->getDoctrine()->getManager(); @@ -134,12 +143,12 @@ class ManageController extends Controller * Default parameter for page is hardcoded (in duplication of the defaults from the Route) * because this controller is also called inside the layout template without any page as argument * - * @return \Symfony\Component\HttpFoundation\Response + * @return Response */ public function searchFormAction(Request $request, $page = 1) { $em = $this->getDoctrine()->getManager(); - $qb = $em->getRepository('WallabagUserBundle:User')->createQueryBuilder('u'); + $qb = $em->getRepository(User::class)->createQueryBuilder('u'); $form = $this->createForm(SearchUserType::class); $form->handleRequest($request); @@ -147,7 +156,7 @@ class ManageController extends Controller if ($form->isSubmitted() && $form->isValid()) { $searchTerm = (isset($request->get('search_user')['term']) ? $request->get('search_user')['term'] : ''); - $qb = $em->getRepository('WallabagUserBundle:User')->getQueryBuilderForSearch($searchTerm); + $qb = $em->getRepository(User::class)->getQueryBuilderForSearch($searchTerm); } $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false); @@ -162,7 +171,7 @@ class ManageController extends Controller } } - return $this->render('WallabagUserBundle:Manage:index.html.twig', [ + return $this->render('@WallabagUser/Manage/index.html.twig', [ 'searchForm' => $form->createView(), 'users' => $pagerFanta, ]); @@ -173,7 +182,7 @@ class ManageController extends Controller * * @param User $user The User entity * - * @return \Symfony\Component\Form\Form The form + * @return Form The form */ private function createDeleteForm(User $user) { diff --git a/src/Wallabag/UserBundle/Controller/RegistrationController.php b/src/Wallabag/UserBundle/Controller/RegistrationController.php deleted file mode 100644 index f81f3a7b4..000000000 --- a/src/Wallabag/UserBundle/Controller/RegistrationController.php +++ /dev/null @@ -1,18 +0,0 @@ -container->getParameter('wallabag_user.registration_enabled')) { - return parent::registerAction($request); - } - - return $this->redirectToRoute('fos_user_security_login', [], 301); - } -} diff --git a/src/Wallabag/UserBundle/Controller/SecurityController.php b/src/Wallabag/UserBundle/Controller/SecurityController.php deleted file mode 100644 index 83fa0b20f..000000000 --- a/src/Wallabag/UserBundle/Controller/SecurityController.php +++ /dev/null @@ -1,21 +0,0 @@ -render('FOSUserBundle:Security:login.html.twig', - array_merge( - $data, - ['registration_enabled' => $this->container->getParameter('wallabag_user.registration_enabled')] - ) - ); - } -} diff --git a/src/Wallabag/UserBundle/DependencyInjection/Configuration.php b/src/Wallabag/UserBundle/DependencyInjection/Configuration.php index 971ce1a0f..4223f8dba 100644 --- a/src/Wallabag/UserBundle/DependencyInjection/Configuration.php +++ b/src/Wallabag/UserBundle/DependencyInjection/Configuration.php @@ -12,14 +12,6 @@ class Configuration implements ConfigurationInterface $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('wallabag_user'); - $rootNode - ->children() - ->booleanNode('registration_enabled') - ->defaultValue(true) - ->end() - ->end() - ; - return $treeBuilder; } } diff --git a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php index 5ca3482e6..569ad6012 100644 --- a/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php +++ b/src/Wallabag/UserBundle/DependencyInjection/WallabagUserExtension.php @@ -2,9 +2,7 @@ namespace Wallabag\UserBundle\DependencyInjection; -use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; class WallabagUserExtension extends Extension @@ -13,10 +11,6 @@ class WallabagUserExtension extends Extension { $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - - $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); - $loader->load('services.yml'); - $container->setParameter('wallabag_user.registration_enabled', $config['registration_enabled']); } public function getAlias() diff --git a/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php b/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php index 81954213f..f208c9efc 100644 --- a/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php +++ b/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php @@ -2,7 +2,7 @@ namespace Wallabag\UserBundle\EventListener; -use Doctrine\ORM\EntityManager; +use Doctrine\ORM\EntityManagerInterface; use FOS\UserBundle\Event\UserEvent; use FOS\UserBundle\FOSUserEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -25,7 +25,7 @@ class CreateConfigListener implements EventSubscriberInterface private $listMode; private $session; - public function __construct(EntityManager $em, $theme, $itemsOnPage, $feedLimit, $language, $readingSpeed, $actionMarkAsRead, $listMode, Session $session) + public function __construct(EntityManagerInterface $em, $theme, $itemsOnPage, $feedLimit, $language, $readingSpeed, $actionMarkAsRead, $listMode, Session $session) { $this->em = $em; $this->theme = $theme; diff --git a/src/Wallabag/UserBundle/EventListener/RegistrationListener.php b/src/Wallabag/UserBundle/EventListener/RegistrationListener.php new file mode 100644 index 000000000..dd928a878 --- /dev/null +++ b/src/Wallabag/UserBundle/EventListener/RegistrationListener.php @@ -0,0 +1,44 @@ +registrationEnabled = $registrationEnabled; + $this->urlGenerator = $urlGenerator; + } + + public static function getSubscribedEvents() + { + return [ + FOSUserEvents::REGISTRATION_INITIALIZE => 'onRegistrationInitialize', + ]; + } + + public function onRegistrationInitialize(GetResponseUserEvent $event) + { + if ($this->registrationEnabled) { + return; + } + + $event->setResponse(new RedirectResponse($this->urlGenerator->generate('fos_user_security_login'), 301)); + } +} diff --git a/src/Wallabag/UserBundle/Form/NewUserType.php b/src/Wallabag/UserBundle/Form/NewUserType.php index ad5a24059..ff63e2906 100644 --- a/src/Wallabag/UserBundle/Form/NewUserType.php +++ b/src/Wallabag/UserBundle/Form/NewUserType.php @@ -10,7 +10,9 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Validator\Constraints; +use Symfony\Component\Validator\Constraints\Length; +use Symfony\Component\Validator\Constraints\NotBlank; +use Wallabag\UserBundle\Entity\User; class NewUserType extends AbstractType { @@ -27,11 +29,11 @@ class NewUserType extends AbstractType 'first_options' => ['label' => 'user.form.password_label'], 'second_options' => ['label' => 'user.form.repeat_new_password_label'], 'constraints' => [ - new Constraints\Length([ + new Length([ 'min' => 8, 'minMessage' => 'validator.password_too_short', ]), - new Constraints\NotBlank(), + new NotBlank(), ], 'label' => 'user.form.plain_password_label', ]) @@ -47,7 +49,7 @@ class NewUserType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\UserBundle\Entity\User', + 'data_class' => User::class, ]); } diff --git a/src/Wallabag/UserBundle/Form/UserType.php b/src/Wallabag/UserBundle/Form/UserType.php index 03fad9717..ab0db2033 100644 --- a/src/Wallabag/UserBundle/Form/UserType.php +++ b/src/Wallabag/UserBundle/Form/UserType.php @@ -9,6 +9,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Wallabag\UserBundle\Entity\User; class UserType extends AbstractType { @@ -49,7 +50,7 @@ class UserType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => 'Wallabag\UserBundle\Entity\User', + 'data_class' => User::class, ]); } } diff --git a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php index 4eea444f2..829e56e5e 100644 --- a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php +++ b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php @@ -77,7 +77,7 @@ class AuthCodeMailer implements AuthCodeMailerInterface */ public function sendAuthCode(TwoFactorInterface $user): void { - $template = $this->twig->loadTemplate('WallabagUserBundle:TwoFactor:email_auth_code.html.twig'); + $template = $this->twig->loadTemplate('@WallabagUser/TwoFactor/email_auth_code.html.twig'); $subject = $template->renderBlock('subject', []); $bodyHtml = $template->renderBlock('body_html', [ diff --git a/src/Wallabag/UserBundle/Repository/UserRepository.php b/src/Wallabag/UserBundle/Repository/UserRepository.php index 4abd55f15..b4333b993 100644 --- a/src/Wallabag/UserBundle/Repository/UserRepository.php +++ b/src/Wallabag/UserBundle/Repository/UserRepository.php @@ -2,12 +2,18 @@ namespace Wallabag\UserBundle\Repository; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\QueryBuilder; +use Doctrine\Persistence\ManagerRegistry; use Wallabag\UserBundle\Entity\User; -class UserRepository extends EntityRepository +class UserRepository extends ServiceEntityRepository { + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, User::class); + } + /** * Find a user by its username and Feed token. * diff --git a/src/Wallabag/UserBundle/Resources/config/services.yml b/src/Wallabag/UserBundle/Resources/config/services.yml deleted file mode 100644 index 2dcf30111..000000000 --- a/src/Wallabag/UserBundle/Resources/config/services.yml +++ /dev/null @@ -1,46 +0,0 @@ -services: - wallabag_user.auth_code_mailer: - class: Wallabag\UserBundle\Mailer\AuthCodeMailer - arguments: - - "@mailer" - - "@twig" - - "%scheb_two_factor.email.sender_email%" - - "%scheb_two_factor.email.sender_name%" - - '@=service(''craue_config'').get(''wallabag_support_url'')' - - '%domain_name%' - - wallabag_user.password_resetting: - class: Wallabag\UserBundle\EventListener\PasswordResettingListener - arguments: - - "@router" - tags: - - { name: kernel.event_subscriber } - - wallabag_user.user_repository: - class: Wallabag\UserBundle\Repository\UserRepository - factory: [ "@doctrine.orm.default_entity_manager", getRepository ] - arguments: - - WallabagUserBundle:User - - wallabag_user.listener.create_config: - class: Wallabag\UserBundle\EventListener\CreateConfigListener - arguments: - - "@doctrine.orm.entity_manager" - - "%wallabag_core.theme%" - - "%wallabag_core.items_on_page%" - - "%wallabag_core.feed_limit%" - - "%wallabag_core.language%" - - "%wallabag_core.reading_speed%" - - "%wallabag_core.action_mark_as_read%" - - "%wallabag_core.list_mode%" - - "@session" - tags: - - { name: kernel.event_subscriber } - - wallabag_user.listener.authentication_failure_event_listener: - class: Wallabag\UserBundle\EventListener\AuthenticationFailureListener - arguments: - - "@request_stack" - - "@logger" - tags: - - { name: kernel.event_listener, event: security.authentication.failure, method: onAuthenticationFailure } diff --git a/src/Wallabag/UserBundle/Resources/views/Authentication/form.html.twig b/src/Wallabag/UserBundle/Resources/views/Authentication/form.html.twig index 22945b51b..e3d1f2f6a 100644 --- a/src/Wallabag/UserBundle/Resources/views/Authentication/form.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Authentication/form.html.twig @@ -1,13 +1,13 @@ {# Override `vendor/scheb/two-factor-bundle/Resources/views/Authentication/form.html.twig` #} -{% extends "FOSUserBundle::layout.html.twig" %} +{% extends "@FOSUser/layout.html.twig" %} {% block fos_user_content %}
    - {% for flashMessage in app.session.flashbag.get("two_factor") %} -

    {{ flashMessage|trans }}

    + {% for flash_message in app.session.flashbag.get("two_factor") %} +

    {{ flash_message|trans }}

    {% endfor %} {# Authentication errors #} diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig index 2de8f3a55..f32dd3df2 100644 --- a/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'user.page_title'|trans }}{% endblock %} diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig index 15002632c..fcf1907d3 100644 --- a/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'user.page_title'|trans }}{% endblock %} @@ -16,7 +16,7 @@
    - + {% if form_errors(searchForm) %} {{ form_errors(searchForm) }} {% endif %} @@ -25,7 +25,7 @@ {{ form_errors(searchForm.term) }} {% endif %} - {{ form_widget(searchForm.term, { 'attr': {'autocomplete': 'off', 'placeholder': 'user.search.placeholder'} }) }} + {{ form_widget(searchForm.term, {'attr': {'autocomplete': 'off', 'placeholder': 'user.search.placeholder'}}) }} {{ form_rest(searchForm) }} @@ -48,7 +48,7 @@ {{ user.email }} {% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %} - {{ 'user.list.edit_action'|trans }} + {{ 'user.list.edit_action'|trans }} {% endfor %} diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/new.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/new.html.twig index 8c894c040..5915e8d3b 100644 --- a/src/Wallabag/UserBundle/Resources/views/Manage/new.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Manage/new.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'user.page_title'|trans }}{% endblock %} diff --git a/src/Wallabag/UserBundle/Resources/views/Resetting/passwordAlreadyRequested.html.twig b/src/Wallabag/UserBundle/Resources/views/Resetting/passwordAlreadyRequested.html.twig index 1e2453727..81f933dee 100644 --- a/src/Wallabag/UserBundle/Resources/views/Resetting/passwordAlreadyRequested.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Resetting/passwordAlreadyRequested.html.twig @@ -1,4 +1,4 @@ -{% extends "FOSUserBundle::layout.html.twig" %} +{% extends "@FOSUser/layout.html.twig" %} {% trans_default_domain 'FOSUserBundle' %} diff --git a/src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig b/src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig index eca5999e3..e98e239de 100644 --- a/src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig @@ -40,7 +40,7 @@ color: purple !important; } table td {border-collapse: collapse;} - table { border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; } + table {border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; } a {color: #373737;} #card { diff --git a/src/Wallabag/UserBundle/Resources/views/manage.html.twig b/src/Wallabag/UserBundle/Resources/views/manage.html.twig index c614c55fd..981e19aaa 100644 --- a/src/Wallabag/UserBundle/Resources/views/manage.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/manage.html.twig @@ -1,4 +1,4 @@ -{% extends "WallabagCoreBundle::layout.html.twig" %} +{% extends "@WallabagCore/layout.html.twig" %} {% block title %}{{ 'user.manage.page_title'|trans }}{% endblock %} diff --git a/tests/Wallabag/AnnotationBundle/Controller/AnnotationControllerTest.php b/tests/Wallabag/AnnotationBundle/Controller/AnnotationControllerTest.php index 260edd770..a31498956 100644 --- a/tests/Wallabag/AnnotationBundle/Controller/AnnotationControllerTest.php +++ b/tests/Wallabag/AnnotationBundle/Controller/AnnotationControllerTest.php @@ -2,9 +2,11 @@ namespace Tests\Wallabag\AnnotationBundle\Controller; +use Doctrine\ORM\EntityManagerInterface; use Tests\Wallabag\AnnotationBundle\WallabagAnnotationTestCase; use Wallabag\AnnotationBundle\Entity\Annotation; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\UserBundle\Entity\User; class AnnotationControllerTest extends WallabagAnnotationTestCase { @@ -28,13 +30,13 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase */ public function testGetAnnotations($prefixUrl) { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUserName('admin'); $entry = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findOneByUsernameAndNotArchived('admin'); $annotation = new Annotation($user); @@ -57,7 +59,7 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase $this->assertSame($annotation->getText(), $content['rows'][0]['text']); // we need to re-fetch the annotation becase after the flush, it has been "detached" from the entity manager - $annotation = $em->getRepository('WallabagAnnotationBundle:Annotation')->findAnnotationById($annotation->getId()); + $annotation = $em->getRepository(Annotation::class)->findAnnotationById($annotation->getId()); $em->remove($annotation); $em->flush(); } @@ -69,7 +71,7 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase */ public function testSetAnnotation($prefixUrl) { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); if ('annotations' === $prefixUrl) { $this->logInAs('admin'); @@ -77,7 +79,7 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase /** @var Entry $entry */ $entry = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findOneByUsernameAndNotArchived('admin'); $headers = ['CONTENT_TYPE' => 'application/json']; @@ -101,7 +103,7 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase /** @var Annotation $annotation */ $annotation = $em - ->getRepository('WallabagAnnotationBundle:Annotation') + ->getRepository(Annotation::class) ->findLastAnnotationByPageId($entry->getId(), 1); $this->assertSame('my annotation', $annotation->getText()); @@ -109,11 +111,11 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase public function testAllowEmptyQuote() { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); /** @var Entry $entry */ $entry = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findOneByUsernameAndNotArchived('admin'); $headers = ['CONTENT_TYPE' => 'application/json']; @@ -138,11 +140,11 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase public function testAllowOmmittedQuote() { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); /** @var Entry $entry */ $entry = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findOneByUsernameAndNotArchived('admin'); $headers = ['CONTENT_TYPE' => 'application/json']; @@ -169,7 +171,7 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase */ public function testSetAnnotationWithQuoteTooLong($prefixUrl) { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); if ('annotations' === $prefixUrl) { $this->logInAs('admin'); @@ -177,7 +179,7 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase /** @var Entry $entry */ $entry = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findOneByUsernameAndNotArchived('admin'); $longQuote = str_repeat('a', 10001); @@ -201,13 +203,13 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase */ public function testEditAnnotation($prefixUrl) { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUserName('admin'); $entry = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findOneByUsernameAndNotArchived('admin'); $annotation = new Annotation($user); @@ -234,7 +236,7 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase /** @var Annotation $annotationUpdated */ $annotationUpdated = $em - ->getRepository('WallabagAnnotationBundle:Annotation') + ->getRepository(Annotation::class) ->findOneById($annotation->getId()); $this->assertSame('a modified annotation', $annotationUpdated->getText()); @@ -249,13 +251,13 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase */ public function testDeleteAnnotation($prefixUrl) { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUserName('admin'); $entry = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findOneByUsernameAndNotArchived('admin'); $annotation = new Annotation($user); @@ -282,7 +284,7 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase $this->assertSame('This is my annotation /o/', $content['text']); $annotationDeleted = $em - ->getRepository('WallabagAnnotationBundle:Annotation') + ->getRepository(Annotation::class) ->findOneById($annotation->getId()); $this->assertNull($annotationDeleted); diff --git a/tests/Wallabag/AnnotationBundle/WallabagAnnotationTestCase.php b/tests/Wallabag/AnnotationBundle/WallabagAnnotationTestCase.php index 180c044d7..d76475acc 100644 --- a/tests/Wallabag/AnnotationBundle/WallabagAnnotationTestCase.php +++ b/tests/Wallabag/AnnotationBundle/WallabagAnnotationTestCase.php @@ -2,18 +2,22 @@ namespace Tests\Wallabag\AnnotationBundle; +use FOS\UserBundle\Model\UserInterface; +use Symfony\Bundle\FrameworkBundle\Client; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\BrowserKit\Cookie; +use Symfony\Component\HttpFoundation\Session\SessionInterface; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; abstract class WallabagAnnotationTestCase extends WebTestCase { /** - * @var \Symfony\Bundle\FrameworkBundle\Client + * @var Client */ protected $client = null; /** - * @var \FOS\UserBundle\Model\UserInterface + * @var UserInterface */ protected $user; @@ -35,7 +39,7 @@ abstract class WallabagAnnotationTestCase extends WebTestCase } /** - * @return \Symfony\Bundle\FrameworkBundle\Client + * @return Client */ protected function createAuthorizedClient() { @@ -52,10 +56,10 @@ abstract class WallabagAnnotationTestCase extends WebTestCase $loginManager->logInUser($firewallName, $this->user); // save the login token into the session and put it in a cookie - $container->get('session')->set('_security_' . $firewallName, serialize($container->get('security.token_storage')->getToken())); - $container->get('session')->save(); + $container->get(SessionInterface::class)->set('_security_' . $firewallName, serialize($container->get(TokenStorageInterface::class)->getToken())); + $container->get(SessionInterface::class)->save(); - $session = $container->get('session'); + $session = $container->get(SessionInterface::class); $client->getCookieJar()->set(new Cookie($session->getName(), $session->getId())); return $client; diff --git a/tests/Wallabag/ApiBundle/Controller/DeveloperControllerTest.php b/tests/Wallabag/ApiBundle/Controller/DeveloperControllerTest.php index fecd616d3..8bd9d39c1 100644 --- a/tests/Wallabag/ApiBundle/Controller/DeveloperControllerTest.php +++ b/tests/Wallabag/ApiBundle/Controller/DeveloperControllerTest.php @@ -2,6 +2,7 @@ namespace Tests\Wallabag\ApiBundle\Controller; +use Doctrine\ORM\EntityManagerInterface; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; use Wallabag\ApiBundle\Entity\Client; @@ -11,8 +12,8 @@ class DeveloperControllerTest extends WallabagCoreTestCase { $this->logInAs('admin'); $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); - $nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); + $em = $client->getContainer()->get(EntityManagerInterface::class); + $nbClients = $em->getRepository(Client::class)->findAll(); $crawler = $client->request('GET', '/developer/client/create'); $this->assertSame(200, $client->getResponse()->getStatusCode()); @@ -27,7 +28,7 @@ class DeveloperControllerTest extends WallabagCoreTestCase $this->assertSame(200, $client->getResponse()->getStatusCode()); - $newNbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); + $newNbClients = $em->getRepository(Client::class)->findAll(); $this->assertGreaterThan(\count($nbClients), \count($newNbClients)); $this->assertGreaterThan(1, $alert = $crawler->filter('.settings table strong')->extract(['_text'])); @@ -74,8 +75,8 @@ class DeveloperControllerTest extends WallabagCoreTestCase { $this->logInAs('admin'); $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); - $nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); + $em = $client->getContainer()->get(EntityManagerInterface::class); + $nbClients = $em->getRepository(Client::class)->findAll(); $crawler = $client->request('GET', '/developer'); $this->assertSame(200, $client->getResponse()->getStatusCode()); @@ -95,7 +96,7 @@ class DeveloperControllerTest extends WallabagCoreTestCase { $client = $this->getClient(); $adminApiClient = $this->createApiClientForUser('admin'); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); // Try to remove an admin's client with a wrong user $this->logInAs('bob'); @@ -120,7 +121,7 @@ class DeveloperControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $this->assertNull( - $em->getRepository('WallabagApiBundle:Client')->find($adminApiClient->getId()), + $em->getRepository(Client::class)->find($adminApiClient->getId()), 'The client should have been removed' ); } @@ -134,7 +135,7 @@ class DeveloperControllerTest extends WallabagCoreTestCase private function createApiClientForUser($username, $grantTypes = ['password']) { $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $userManager = $client->getContainer()->get('fos_user.user_manager.test'); $user = $userManager->findUserBy(['username' => $username]); $apiClient = new Client($user); diff --git a/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php index c18ea30ab..69b3bb7e5 100644 --- a/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php +++ b/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php @@ -2,6 +2,8 @@ namespace Tests\Wallabag\ApiBundle\Controller; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\DependencyInjection\Container; use Tests\Wallabag\ApiBundle\WallabagApiTestCase; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Tag; @@ -13,8 +15,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testGetOneEntry() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneBy(['user' => $this->getUserId(), 'isArchived' => false]); if (!$entry) { @@ -39,8 +41,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testGetOneEntryWithOriginUrl() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneBy(['user' => $this->getUserId(), 'url' => 'http://0.0.0.0/entry2']); if (!$entry) { @@ -58,8 +60,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testExportEntry() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneBy(['user' => $this->getUserId(), 'isArchived' => false]); if (!$entry) { @@ -106,8 +108,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testGetOneEntryWrongUser() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneBy(['user' => $this->getUserId('bob'), 'isArchived' => false]); if (!$entry) { @@ -223,8 +225,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testGetEntriesPublicOnly() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneByUser($this->getUserId()); if (!$entry) { @@ -234,7 +236,7 @@ class EntryRestControllerTest extends WallabagApiTestCase // generate at least one public entry $entry->generateUid(); - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $em->persist($entry); $em->flush(); @@ -440,7 +442,7 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testDeleteEntry() { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $entry = new Entry($em->getReference(User::class, 1)); $entry->setUrl('http://0.0.0.0/test-delete-entry'); $entry->setTitle('Test delete entry'); @@ -474,7 +476,7 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testDeleteEntryExpectId() { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $entry = new Entry($em->getReference(User::class, 1)); $entry->setUrl('http://0.0.0.0/test-delete-entry-id'); $em->persist($entry); @@ -545,7 +547,7 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testPostSameEntry() { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $entry = new Entry($em->getReference(User::class, $this->getUserId())); $entry->setUrl('https://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html'); $entry->setArchived(true); @@ -574,7 +576,7 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testPostEntryWhenFetchContentFails() { - /** @var \Symfony\Component\DependencyInjection\Container $container */ + /** @var Container $container */ $container = $this->client->getContainer(); $contentProxy = $this->getMockBuilder(ContentProxy::class) ->disableOriginalConstructor() @@ -583,7 +585,7 @@ class EntryRestControllerTest extends WallabagApiTestCase $contentProxy->expects($this->any()) ->method('updateEntry') ->willThrowException(new \Exception('Test Fetch content fails')); - $container->set('wallabag_core.content_proxy', $contentProxy); + $container->set(ContentProxy::class, $contentProxy); try { $this->client->request('POST', '/api/entries.json', [ @@ -599,8 +601,8 @@ class EntryRestControllerTest extends WallabagApiTestCase } finally { // Remove the created entry to avoid side effects on other tests if (isset($content['id'])) { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); - $entry = $em->getReference('WallabagCoreBundle:Entry', $content['id']); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); + $entry = $em->getReference(Entry::class, $content['id']); $em->remove($entry); $em->flush(); } @@ -673,8 +675,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testPatchEntry() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneByUser($this->getUserId()); if (!$entry) { @@ -715,8 +717,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testPatchEntryWithoutQuotes() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneByUser($this->getUserId()); if (!$entry) { @@ -749,8 +751,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testPatchEntryWithOriginUrl() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneByUser($this->getUserId()); if (!$entry) { @@ -780,8 +782,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testPatchEntryRemoveOriginUrl() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneByUser($this->getUserId()); if (!$entry) { @@ -812,8 +814,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testPatchEntryNullOriginUrl() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneByUser($this->getUserId()); if (!$entry) { @@ -834,8 +836,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testGetTagsEntry() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneWithTags($this->user->getId()); $entry = $entry[0]; @@ -857,8 +859,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testPostTagsOnEntry() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneByUser($this->getUserId()); if (!$entry) { @@ -879,8 +881,8 @@ class EntryRestControllerTest extends WallabagApiTestCase $this->assertCount($nbTags + 3, $content['tags']); $entryDB = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry->getId()); $tagsInDB = []; @@ -896,8 +898,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testDeleteOneTagEntry() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneWithTags($this->user->getId()); $entry = $entry[0]; @@ -922,8 +924,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testSaveIsArchivedAfterPost() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneBy(['user' => $this->getUserId(), 'isArchived' => true]); if (!$entry) { @@ -944,8 +946,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testSaveIsStarredAfterPost() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneBy(['user' => $this->getUserId(), 'isStarred' => true]); if (!$entry) { @@ -966,8 +968,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testSaveIsArchivedAfterPatch() { $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneBy(['user' => $this->getUserId(), 'isArchived' => true]); if (!$entry) { @@ -992,8 +994,8 @@ class EntryRestControllerTest extends WallabagApiTestCase { $now = new \DateTime(); $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneBy(['user' => $this->getUserId(), 'isStarred' => true]); if (!$entry) { @@ -1153,8 +1155,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testReloadEntryErrorWhileFetching() { - $entry = $this->client->getContainer()->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + $entry = $this->client->getContainer()->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId('http://0.0.0.0/entry4', $this->getUserId()); if (!$entry) { @@ -1189,8 +1191,8 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testPostEntriesTagsListAction() { - $entry = $this->client->getContainer()->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + $entry = $this->client->getContainer()->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId('http://0.0.0.0/entry4', $this->getUserId()); $tags = $entry->getTags(); @@ -1213,8 +1215,8 @@ class EntryRestControllerTest extends WallabagApiTestCase $this->assertIsInt($content[0]['entry']); $this->assertSame('http://0.0.0.0/entry4', $content[0]['url']); - $entry = $this->client->getContainer()->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + $entry = $this->client->getContainer()->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId('http://0.0.0.0/entry4', $this->getUserId()); $tags = $entry->getTags(); @@ -1234,7 +1236,7 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testDeleteEntriesTagsListAction() { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $entry = new Entry($em->getReference(User::class, $this->getUserId())); $entry->setUrl('http://0.0.0.0/test-entry'); $entry->addTag((new Tag())->setLabel('foo-tag')); @@ -1254,7 +1256,7 @@ class EntryRestControllerTest extends WallabagApiTestCase $this->client->request('DELETE', '/api/entries/tags/list?list=' . json_encode($list)); $this->assertSame(200, $this->client->getResponse()->getStatusCode()); - $entry = $em->getRepository('WallabagCoreBundle:Entry')->find($entry->getId()); + $entry = $em->getRepository(Entry::class)->find($entry->getId()); $this->assertCount(0, $entry->getTags()); } @@ -1302,7 +1304,7 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testDeleteEntriesListAction() { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $em->persist((new Entry($em->getReference(User::class, $this->getUserId())))->setUrl('http://0.0.0.0/test-entry1')); $em->flush(); @@ -1360,7 +1362,7 @@ class EntryRestControllerTest extends WallabagApiTestCase public function testRePostEntryAndReUsePublishedAt() { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $entry = new Entry($em->getReference(User::class, $this->getUserId())); $entry->setTitle('Antoine de Caunes : « Je veux avoir le droit de tâtonner »'); $entry->setContent('hihi'); diff --git a/tests/Wallabag/ApiBundle/Controller/TagRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/TagRestControllerTest.php index 6d50891d0..804748afa 100644 --- a/tests/Wallabag/ApiBundle/Controller/TagRestControllerTest.php +++ b/tests/Wallabag/ApiBundle/Controller/TagRestControllerTest.php @@ -2,7 +2,9 @@ namespace Tests\Wallabag\ApiBundle\Controller; +use Doctrine\ORM\EntityManagerInterface; use Tests\Wallabag\ApiBundle\WallabagApiTestCase; +use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Tag; class TagRestControllerTest extends WallabagApiTestCase @@ -31,10 +33,10 @@ class TagRestControllerTest extends WallabagApiTestCase public function testDeleteUserTag() { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneWithTags($this->user->getId()); $entry = $entry[0]; @@ -60,20 +62,20 @@ class TagRestControllerTest extends WallabagApiTestCase $this->assertSame($tag->getLabel(), $content['label']); $this->assertSame($tag->getSlug(), $content['slug']); - $entries = $em->getRepository('WallabagCoreBundle:Entry') + $entries = $em->getRepository(Entry::class) ->findAllByTagId($this->user->getId(), $tag->getId()); $this->assertCount(0, $entries); - $tag = $em->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($tagLabel); + $tag = $em->getRepository(Tag::class)->findOneByLabel($tagLabel); $this->assertNull($tag, $tagLabel . ' was removed because it begun an orphan tag'); } public function testDeleteOtherUserTag() { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); - $tag = $em->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($this->otherUserTagLabel); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); + $tag = $em->getRepository(Tag::class)->findOneByLabel($this->otherUserTagLabel); $this->client->request('DELETE', '/api/tags/' . $tag->getId() . '.json'); @@ -93,10 +95,10 @@ class TagRestControllerTest extends WallabagApiTestCase */ public function testDeleteTagByLabel($useQueryString) { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneWithTags($this->user->getId()); $entry = $entry[0]; @@ -125,8 +127,8 @@ class TagRestControllerTest extends WallabagApiTestCase $this->assertSame($tag->getSlug(), $content['slug']); $entries = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findAllByTagId($this->user->getId(), $tag->getId()); $this->assertCount(0, $entries); @@ -151,10 +153,10 @@ class TagRestControllerTest extends WallabagApiTestCase */ public function testDeleteTagsByLabel($useQueryString) { - $em = $this->client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->client->getContainer()->get(EntityManagerInterface::class); $entry = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneWithTags($this->user->getId()); $entry = $entry[0]; @@ -194,15 +196,15 @@ class TagRestControllerTest extends WallabagApiTestCase $this->assertSame($tag2->getSlug(), $content[1]['slug']); $entries = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findAllByTagId($this->user->getId(), $tag->getId()); $this->assertCount(0, $entries); $entries = $this->client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findAllByTagId($this->user->getId(), $tag2->getId()); $this->assertCount(0, $entries); diff --git a/tests/Wallabag/ApiBundle/Controller/UserRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/UserRestControllerTest.php index 51fac2bd3..ad1e4974f 100644 --- a/tests/Wallabag/ApiBundle/Controller/UserRestControllerTest.php +++ b/tests/Wallabag/ApiBundle/Controller/UserRestControllerTest.php @@ -2,6 +2,7 @@ namespace Tests\Wallabag\ApiBundle\Controller; +use Craue\ConfigBundle\Util\Config; use Tests\Wallabag\ApiBundle\WallabagApiTestCase; class UserRestControllerTest extends WallabagApiTestCase @@ -45,7 +46,7 @@ class UserRestControllerTest extends WallabagApiTestCase public function testCreateNewUser() { - $this->client->getContainer()->get('craue_config')->set('api_user_registration', 1); + $this->client->getContainer()->get(Config::class)->set('api_user_registration', 1); $this->client->request('PUT', '/api/user.json', [ 'username' => 'google', 'password' => 'googlegoogle', @@ -73,14 +74,14 @@ class UserRestControllerTest extends WallabagApiTestCase $this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type')); - $this->client->getContainer()->get('craue_config')->set('api_user_registration', 0); + $this->client->getContainer()->get(Config::class)->set('api_user_registration', 0); } public function testCreateNewUserWithoutAuthentication() { // create a new client instead of using $this->client to be sure client isn't authenticated $client = static::createClient(); - $client->getContainer()->get('craue_config')->set('api_user_registration', 1); + $client->getContainer()->get(Config::class)->set('api_user_registration', 1); $client->request('PUT', '/api/user.json', [ 'username' => 'google', 'password' => 'googlegoogle', @@ -109,13 +110,13 @@ class UserRestControllerTest extends WallabagApiTestCase $this->assertSame('application/json', $client->getResponse()->headers->get('Content-Type')); - $client->getContainer()->get('craue_config')->set('api_user_registration', 0); + $client->getContainer()->get(Config::class)->set('api_user_registration', 0); } public function testCreateNewUserWithExistingEmail() { $client = static::createClient(); - $client->getContainer()->get('craue_config')->set('api_user_registration', 1); + $client->getContainer()->get(Config::class)->set('api_user_registration', 1); $client->request('PUT', '/api/user.json', [ 'username' => 'admin', 'password' => 'googlegoogle', @@ -138,13 +139,13 @@ class UserRestControllerTest extends WallabagApiTestCase $this->assertSame('application/json', $client->getResponse()->headers->get('Content-Type')); - $client->getContainer()->get('craue_config')->set('api_user_registration', 0); + $client->getContainer()->get(Config::class)->set('api_user_registration', 0); } public function testCreateNewUserWithTooShortPassword() { $client = static::createClient(); - $client->getContainer()->get('craue_config')->set('api_user_registration', 1); + $client->getContainer()->get(Config::class)->set('api_user_registration', 1); $client->request('PUT', '/api/user.json', [ 'username' => 'facebook', 'password' => 'face', @@ -162,7 +163,7 @@ class UserRestControllerTest extends WallabagApiTestCase $this->assertSame('application/json', $client->getResponse()->headers->get('Content-Type')); - $client->getContainer()->get('craue_config')->set('api_user_registration', 0); + $client->getContainer()->get(Config::class)->set('api_user_registration', 0); } public function testCreateNewUserWhenRegistrationIsDisabled() diff --git a/tests/Wallabag/ApiBundle/WallabagApiTestCase.php b/tests/Wallabag/ApiBundle/WallabagApiTestCase.php index 49f5bcdc7..20c6bcc2d 100644 --- a/tests/Wallabag/ApiBundle/WallabagApiTestCase.php +++ b/tests/Wallabag/ApiBundle/WallabagApiTestCase.php @@ -2,18 +2,24 @@ namespace Tests\Wallabag\ApiBundle; +use Doctrine\ORM\EntityManagerInterface; +use FOS\UserBundle\Model\UserInterface; +use Symfony\Bundle\FrameworkBundle\Client; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\BrowserKit\Cookie; +use Symfony\Component\HttpFoundation\Session\SessionInterface; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Wallabag\UserBundle\Entity\User; abstract class WallabagApiTestCase extends WebTestCase { /** - * @var \Symfony\Bundle\FrameworkBundle\Client + * @var Client */ protected $client = null; /** - * @var \FOS\UserBundle\Model\UserInterface + * @var UserInterface */ protected $user; @@ -23,7 +29,7 @@ abstract class WallabagApiTestCase extends WebTestCase } /** - * @return \Symfony\Bundle\FrameworkBundle\Client + * @return Client */ protected function createAuthorizedClient() { @@ -40,10 +46,10 @@ abstract class WallabagApiTestCase extends WebTestCase $loginManager->logInUser($firewallName, $this->user); // save the login token into the session and put it in a cookie - $container->get('session')->set('_security_' . $firewallName, serialize($container->get('security.token_storage')->getToken())); - $container->get('session')->save(); + $container->get(SessionInterface::class)->set('_security_' . $firewallName, serialize($container->get(TokenStorageInterface::class)->getToken())); + $container->get(SessionInterface::class)->save(); - $session = $container->get('session'); + $session = $container->get(SessionInterface::class); $client->getCookieJar()->set(new Cookie($session->getName(), $session->getId())); return $client; @@ -62,8 +68,8 @@ abstract class WallabagApiTestCase extends WebTestCase { return $this->client ->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagUserBundle:User') + ->get(EntityManagerInterface::class) + ->getRepository(User::class) ->findOneByUserName($username) ->getId(); } diff --git a/tests/Wallabag/CoreBundle/Command/CleanDuplicatesCommandTest.php b/tests/Wallabag/CoreBundle/Command/CleanDuplicatesCommandTest.php index ab0d3f879..354950030 100644 --- a/tests/Wallabag/CoreBundle/Command/CleanDuplicatesCommandTest.php +++ b/tests/Wallabag/CoreBundle/Command/CleanDuplicatesCommandTest.php @@ -2,25 +2,23 @@ namespace Tests\Wallabag\CoreBundle\Command; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Tester\CommandTester; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; -use Wallabag\CoreBundle\Command\CleanDuplicatesCommand; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\UserBundle\Entity\User; class CleanDuplicatesCommandTest extends WallabagCoreTestCase { public function testRunCleanDuplicates() { $application = new Application($this->getClient()->getKernel()); - $application->add(new CleanDuplicatesCommand()); $command = $application->find('wallabag:clean-duplicates'); $tester = new CommandTester($command); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); $this->assertStringContainsString('Cleaning through 3 user accounts', $tester->getDisplay()); $this->assertStringContainsString('Finished cleaning. 0 duplicates found in total', $tester->getDisplay()); @@ -29,13 +27,11 @@ class CleanDuplicatesCommandTest extends WallabagCoreTestCase public function testRunCleanDuplicatesCommandWithBadUsername() { $application = new Application($this->getClient()->getKernel()); - $application->add(new CleanDuplicatesCommand()); $command = $application->find('wallabag:clean-duplicates'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'unknown', ]); @@ -45,13 +41,11 @@ class CleanDuplicatesCommandTest extends WallabagCoreTestCase public function testRunCleanDuplicatesCommandForUser() { $application = new Application($this->getClient()->getKernel()); - $application->add(new CleanDuplicatesCommand()); $command = $application->find('wallabag:clean-duplicates'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', ]); @@ -62,14 +56,14 @@ class CleanDuplicatesCommandTest extends WallabagCoreTestCase { $url = 'https://www.lemonde.fr/sport/visuel/2017/05/05/rondelle-prison-blanchissage-comprendre-le-hockey-sur-glace_5122587_3242.html'; $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $this->logInAs('admin'); - $nbEntries = $em->getRepository('WallabagCoreBundle:Entry')->findAllByUrlAndUserId($url, $this->getLoggedInUserId()); + $nbEntries = $em->getRepository(Entry::class)->findAllByUrlAndUserId($url, $this->getLoggedInUserId()); $this->assertCount(0, $nbEntries); - $user = $em->getRepository('WallabagUserBundle:User')->findOneById($this->getLoggedInUserId()); + $user = $em->getRepository(User::class)->findOneById($this->getLoggedInUserId()); $entry1 = new Entry($user); $entry1->setUrl($url); @@ -82,23 +76,21 @@ class CleanDuplicatesCommandTest extends WallabagCoreTestCase $em->flush(); - $nbEntries = $em->getRepository('WallabagCoreBundle:Entry')->findAllByUrlAndUserId($url, $this->getLoggedInUserId()); + $nbEntries = $em->getRepository(Entry::class)->findAllByUrlAndUserId($url, $this->getLoggedInUserId()); $this->assertCount(2, $nbEntries); $application = new Application($this->getClient()->getKernel()); - $application->add(new CleanDuplicatesCommand()); $command = $application->find('wallabag:clean-duplicates'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', ]); $this->assertStringContainsString('Cleaned 1 duplicates for user admin', $tester->getDisplay()); - $nbEntries = $em->getRepository('WallabagCoreBundle:Entry')->findAllByUrlAndUserId($url, $this->getLoggedInUserId()); + $nbEntries = $em->getRepository(Entry::class)->findAllByUrlAndUserId($url, $this->getLoggedInUserId()); $this->assertCount(1, $nbEntries); $query = $em->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\Entry e WHERE e.url = :url'); diff --git a/tests/Wallabag/CoreBundle/Command/ExportCommandTest.php b/tests/Wallabag/CoreBundle/Command/ExportCommandTest.php index 318531ff5..ef2c8cd66 100644 --- a/tests/Wallabag/CoreBundle/Command/ExportCommandTest.php +++ b/tests/Wallabag/CoreBundle/Command/ExportCommandTest.php @@ -3,38 +3,33 @@ namespace Tests\Wallabag\CoreBundle\Command; use Symfony\Bundle\FrameworkBundle\Console\Application; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Tester\CommandTester; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; -use Wallabag\CoreBundle\Command\ExportCommand; class ExportCommandTest extends WallabagCoreTestCase { public function testExportCommandWithoutUsername() { - $this->expectException(\Symfony\Component\Console\Exception\RuntimeException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Not enough arguments (missing: "username")'); $application = new Application($this->getClient()->getKernel()); - $application->add(new ExportCommand()); $command = $application->find('wallabag:export'); $tester = new CommandTester($command); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); } public function testExportCommandWithBadUsername() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ExportCommand()); $command = $application->find('wallabag:export'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'unknown', ]); @@ -44,13 +39,11 @@ class ExportCommandTest extends WallabagCoreTestCase public function testExportCommand() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ExportCommand()); $command = $application->find('wallabag:export'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', ]); @@ -62,13 +55,11 @@ class ExportCommandTest extends WallabagCoreTestCase public function testExportCommandWithSpecialPath() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ExportCommand()); $command = $application->find('wallabag:export'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', 'filepath' => 'specialexport.json', ]); diff --git a/tests/Wallabag/CoreBundle/Command/GenerateUrlHashesCommandTest.php b/tests/Wallabag/CoreBundle/Command/GenerateUrlHashesCommandTest.php index 5870a037f..d76cc4b39 100644 --- a/tests/Wallabag/CoreBundle/Command/GenerateUrlHashesCommandTest.php +++ b/tests/Wallabag/CoreBundle/Command/GenerateUrlHashesCommandTest.php @@ -2,25 +2,23 @@ namespace Tests\Wallabag\CoreBundle\Command; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Tester\CommandTester; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; -use Wallabag\CoreBundle\Command\GenerateUrlHashesCommand; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\UserBundle\Entity\User; class GenerateUrlHashesCommandTest extends WallabagCoreTestCase { public function testRunGenerateUrlHashesCommand() { $application = new Application($this->getClient()->getKernel()); - $application->add(new GenerateUrlHashesCommand()); $command = $application->find('wallabag:generate-hashed-urls'); $tester = new CommandTester($command); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); $this->assertStringContainsString('Generating hashed urls for "3" users', $tester->getDisplay()); $this->assertStringContainsString('Finished generated hashed urls', $tester->getDisplay()); @@ -29,13 +27,11 @@ class GenerateUrlHashesCommandTest extends WallabagCoreTestCase public function testRunGenerateUrlHashesCommandWithBadUsername() { $application = new Application($this->getClient()->getKernel()); - $application->add(new GenerateUrlHashesCommand()); $command = $application->find('wallabag:generate-hashed-urls'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'unknown', ]); @@ -45,13 +41,11 @@ class GenerateUrlHashesCommandTest extends WallabagCoreTestCase public function testRunGenerateUrlHashesCommandForUser() { $application = new Application($this->getClient()->getKernel()); - $application->add(new GenerateUrlHashesCommand()); $command = $application->find('wallabag:generate-hashed-urls'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', ]); @@ -62,11 +56,11 @@ class GenerateUrlHashesCommandTest extends WallabagCoreTestCase { $url = 'http://www.lemonde.fr/sport/visuel/2017/05/05/rondelle-prison-blanchissage-comprendre-le-hockey-sur-glace_5122587_3242.html'; $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $this->logInAs('admin'); - $user = $em->getRepository('WallabagUserBundle:User')->findOneById($this->getLoggedInUserId()); + $user = $em->getRepository(User::class)->findOneById($this->getLoggedInUserId()); $entry1 = new Entry($user); $entry1->setUrl($url); @@ -75,19 +69,17 @@ class GenerateUrlHashesCommandTest extends WallabagCoreTestCase $em->flush(); $application = new Application($this->getClient()->getKernel()); - $application->add(new GenerateUrlHashesCommand()); $command = $application->find('wallabag:generate-hashed-urls'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', ]); $this->assertStringContainsString('Generated hashed urls for user: admin', $tester->getDisplay()); - $entry = $em->getRepository('WallabagCoreBundle:Entry')->findOneByUrl($url); + $entry = $em->getRepository(Entry::class)->findOneByUrl($url); $this->assertSame($entry->getHashedUrl(), hash('sha1', $url)); diff --git a/tests/Wallabag/CoreBundle/Command/InstallCommandTest.php b/tests/Wallabag/CoreBundle/Command/InstallCommandTest.php index 5ab1750c3..40f01f1e3 100644 --- a/tests/Wallabag/CoreBundle/Command/InstallCommandTest.php +++ b/tests/Wallabag/CoreBundle/Command/InstallCommandTest.php @@ -3,16 +3,14 @@ namespace Tests\Wallabag\CoreBundle\Command; use DAMA\DoctrineTestBundle\Doctrine\DBAL\StaticDriver; -use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand; -use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand; -use Doctrine\Bundle\MigrationsBundle\Command\MigrationsMigrateDoctrineCommand; +use Doctrine\DBAL\Connection; use Doctrine\DBAL\Platforms\PostgreSqlPlatform; use Doctrine\DBAL\Platforms\SqlitePlatform; +use Doctrine\Persistence\ManagerRegistry; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Tester\CommandTester; -use Tests\Wallabag\CoreBundle\Mock\InstallCommandMock; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; use Wallabag\CoreBundle\Command\InstallCommand; @@ -34,8 +32,8 @@ class InstallCommandTest extends WallabagCoreTestCase { parent::setUp(); - /** @var \Doctrine\DBAL\Connection $connection */ - $connection = $this->getClient()->getContainer()->get('doctrine')->getConnection(); + /** @var Connection $connection */ + $connection = $this->getClient()->getContainer()->get(ManagerRegistry::class)->getConnection(); if ($connection->getDatabasePlatform() instanceof PostgreSqlPlatform) { /* * LOG: statement: CREATE DATABASE "wallabag" @@ -87,9 +85,10 @@ class InstallCommandTest extends WallabagCoreTestCase public function testRunInstallCommand() { $application = new Application($this->getClient()->getKernel()); - $application->add(new InstallCommandMock()); + /** @var InstallCommand $command */ $command = $application->find('wallabag:install'); + $command->disableRunOtherCommands(); $tester = new CommandTester($command); $tester->setInputs([ @@ -99,9 +98,7 @@ class InstallCommandTest extends WallabagCoreTestCase 'password_' . uniqid('', true), // password 'email_' . uniqid('', true) . '@wallabag.it', // email ]); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); $this->assertStringContainsString('Checking system requirements.', $tester->getDisplay()); $this->assertStringContainsString('Setting up database.', $tester->getDisplay()); @@ -112,9 +109,10 @@ class InstallCommandTest extends WallabagCoreTestCase public function testRunInstallCommandWithReset() { $application = new Application($this->getClient()->getKernel()); - $application->add(new InstallCommandMock()); + /** @var InstallCommand $command */ $command = $application->find('wallabag:install'); + $command->disableRunOtherCommands(); $tester = new CommandTester($command); $tester->setInputs([ @@ -124,7 +122,6 @@ class InstallCommandTest extends WallabagCoreTestCase 'email_' . uniqid('', true) . '@wallabag.it', // email ]); $tester->execute([ - 'command' => $command->getName(), '--reset' => true, ]); @@ -142,24 +139,21 @@ class InstallCommandTest extends WallabagCoreTestCase { // skipped SQLite check when database is removed because while testing for the connection, // the driver will create the file (so the database) before testing if database exist - if ($this->getClient()->getContainer()->get('doctrine')->getConnection()->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) { + if ($this->getClient()->getContainer()->get(ManagerRegistry::class)->getConnection()->getDatabasePlatform() instanceof SqlitePlatform) { $this->markTestSkipped('SQLite spotted: can\'t test with database removed.'); } $application = new Application($this->getClient()->getKernel()); - $application->add(new DropDatabaseDoctrineCommand()); // drop database first, so the install command won't ask to reset things $command = $application->find('doctrine:database:drop'); $command->run(new ArrayInput([ - 'command' => 'doctrine:database:drop', '--force' => true, ]), new NullOutput()); // start a new application to avoid lagging connexion to pgsql $client = static::createClient(); $application = new Application($client->getKernel()); - $application->add(new InstallCommand()); $command = $application->find('wallabag:install'); @@ -170,9 +164,7 @@ class InstallCommandTest extends WallabagCoreTestCase 'password_' . uniqid('', true), // password 'email_' . uniqid('', true) . '@wallabag.it', // email ]); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); $this->assertStringContainsString('Checking system requirements.', $tester->getDisplay()); $this->assertStringContainsString('Setting up database.', $tester->getDisplay()); @@ -186,9 +178,10 @@ class InstallCommandTest extends WallabagCoreTestCase public function testRunInstallCommandChooseResetSchema() { $application = new Application($this->getClient()->getKernel()); - $application->add(new InstallCommandMock()); + /** @var InstallCommand $command */ $command = $application->find('wallabag:install'); + $command->disableRunOtherCommands(); $tester = new CommandTester($command); $tester->setInputs([ @@ -196,9 +189,7 @@ class InstallCommandTest extends WallabagCoreTestCase 'y', // do want to reset the schema 'n', // don't want to create a new user ]); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); $this->assertStringContainsString('Checking system requirements.', $tester->getDisplay()); $this->assertStringContainsString('Setting up database.', $tester->getDisplay()); @@ -211,27 +202,17 @@ class InstallCommandTest extends WallabagCoreTestCase public function testRunInstallCommandChooseNothing() { $application = new Application($this->getClient()->getKernel()); - $application->add(new InstallCommand()); - $application->add(new DropDatabaseDoctrineCommand()); - $application->add(new CreateDatabaseDoctrineCommand()); - $application->add(new MigrationsMigrateDoctrineCommand()); // drop database first, so the install command won't ask to reset things - $command = new DropDatabaseDoctrineCommand(); - $command->setApplication($application); + $command = $application->find('doctrine:database:drop'); $command->run(new ArrayInput([ - 'command' => 'doctrine:database:drop', '--force' => true, ]), new NullOutput()); - $this->getClient()->getContainer()->get('doctrine')->getConnection()->close(); + $this->getClient()->getContainer()->get(ManagerRegistry::class)->getConnection()->close(); - $command = new CreateDatabaseDoctrineCommand(); - $command->setApplication($application); - $command->run(new ArrayInput([ - 'command' => 'doctrine:database:create', - '--env' => 'test', - ]), new NullOutput()); + $command = $application->find('doctrine:database:create'); + $command->run(new ArrayInput([]), new NullOutput()); $command = $application->find('wallabag:install'); @@ -240,9 +221,7 @@ class InstallCommandTest extends WallabagCoreTestCase 'n', // don't want to reset the entire database 'n', // don't want to create a new user ]); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); $this->assertStringContainsString('Checking system requirements.', $tester->getDisplay()); $this->assertStringContainsString('Setting up database.', $tester->getDisplay()); @@ -255,14 +234,13 @@ class InstallCommandTest extends WallabagCoreTestCase public function testRunInstallCommandNoInteraction() { $application = new Application($this->getClient()->getKernel()); - $application->add(new InstallCommandMock()); + /** @var InstallCommand $command */ $command = $application->find('wallabag:install'); + $command->disableRunOtherCommands(); $tester = new CommandTester($command); - $tester->execute([ - 'command' => $command->getName(), - ], [ + $tester->execute([], [ 'interactive' => false, ]); diff --git a/tests/Wallabag/CoreBundle/Command/ListUserCommandTest.php b/tests/Wallabag/CoreBundle/Command/ListUserCommandTest.php index 8a4f8a58f..05d73aa4b 100644 --- a/tests/Wallabag/CoreBundle/Command/ListUserCommandTest.php +++ b/tests/Wallabag/CoreBundle/Command/ListUserCommandTest.php @@ -5,21 +5,17 @@ namespace Tests\Wallabag\CoreBundle\Command; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Tester\CommandTester; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; -use Wallabag\CoreBundle\Command\ListUserCommand; class ListUserCommandTest extends WallabagCoreTestCase { public function testRunListUserCommand() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ListUserCommand()); $command = $application->find('wallabag:user:list'); $tester = new CommandTester($command); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); $this->assertStringContainsString('3/3 user(s) displayed.', $tester->getDisplay()); } @@ -27,13 +23,11 @@ class ListUserCommandTest extends WallabagCoreTestCase public function testRunListUserCommandWithLimit() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ListUserCommand()); $command = $application->find('wallabag:user:list'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), '--limit' => 2, ]); @@ -43,13 +37,11 @@ class ListUserCommandTest extends WallabagCoreTestCase public function testRunListUserCommandWithSearch() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ListUserCommand()); $command = $application->find('wallabag:user:list'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'search' => 'boss', ]); @@ -59,13 +51,11 @@ class ListUserCommandTest extends WallabagCoreTestCase public function testRunListUserCommandWithSearchAndLimit() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ListUserCommand()); $command = $application->find('wallabag:user:list'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'search' => 'bo', '--limit' => 1, ]); diff --git a/tests/Wallabag/CoreBundle/Command/ReloadEntryCommandTest.php b/tests/Wallabag/CoreBundle/Command/ReloadEntryCommandTest.php index 0bd4a5780..a91a7e561 100644 --- a/tests/Wallabag/CoreBundle/Command/ReloadEntryCommandTest.php +++ b/tests/Wallabag/CoreBundle/Command/ReloadEntryCommandTest.php @@ -5,7 +5,6 @@ namespace Tests\Wallabag\CoreBundle\Command; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Tester\CommandTester; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; -use Wallabag\CoreBundle\Command\ReloadEntryCommand; use Wallabag\CoreBundle\Entity\Entry; class ReloadEntryCommandTest extends WallabagCoreTestCase @@ -51,13 +50,10 @@ class ReloadEntryCommandTest extends WallabagCoreTestCase public function testRunReloadEntryCommand() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ReloadEntryCommand()); $command = $application->find('wallabag:entry:reload'); $tester = new CommandTester($command); - $tester->execute([ - 'command' => $command->getName(), - ], [ + $tester->execute([], [ 'interactive' => false, ]); @@ -79,12 +75,10 @@ class ReloadEntryCommandTest extends WallabagCoreTestCase public function testRunReloadEntryWithUsernameCommand() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ReloadEntryCommand()); $command = $application->find('wallabag:entry:reload'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', ], [ 'interactive' => false, @@ -104,12 +98,10 @@ class ReloadEntryCommandTest extends WallabagCoreTestCase public function testRunReloadEntryWithoutEntryCommand() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ReloadEntryCommand()); $command = $application->find('wallabag:entry:reload'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'empty', ], [ 'interactive' => false, diff --git a/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php b/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php index 5cdb825d2..d2bb583a3 100644 --- a/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php +++ b/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php @@ -2,40 +2,36 @@ namespace Tests\Wallabag\CoreBundle\Command; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Console\Application; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Tester\CommandTester; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; -use Wallabag\CoreBundle\Command\ShowUserCommand; use Wallabag\UserBundle\Entity\User; class ShowUserCommandTest extends WallabagCoreTestCase { public function testRunShowUserCommandWithoutUsername() { - $this->expectException(\Symfony\Component\Console\Exception\RuntimeException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Not enough arguments'); $application = new Application($this->getClient()->getKernel()); - $application->add(new ShowUserCommand()); $command = $application->find('wallabag:user:show'); $tester = new CommandTester($command); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); } public function testRunShowUserCommandWithBadUsername() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ShowUserCommand()); $command = $application->find('wallabag:user:show'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'unknown', ]); @@ -45,13 +41,11 @@ class ShowUserCommandTest extends WallabagCoreTestCase public function testRunShowUserCommandForUser() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ShowUserCommand()); $command = $application->find('wallabag:user:show'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', ]); @@ -65,12 +59,12 @@ class ShowUserCommandTest extends WallabagCoreTestCase public function testShowUser() { $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $this->logInAs('admin'); /** @var User $user */ - $user = $em->getRepository('WallabagUserBundle:User')->findOneById($this->getLoggedInUserId()); + $user = $em->getRepository(User::class)->findOneById($this->getLoggedInUserId()); $user->setName('Bug boss'); $em->persist($user); @@ -78,13 +72,11 @@ class ShowUserCommandTest extends WallabagCoreTestCase $em->flush(); $application = new Application($this->getClient()->getKernel()); - $application->add(new ShowUserCommand()); $command = $application->find('wallabag:user:show'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', ]); diff --git a/tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php b/tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php index 826570600..d7b3553ac 100644 --- a/tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php +++ b/tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php @@ -3,38 +3,33 @@ namespace Tests\Wallabag\CoreBundle\Command; use Symfony\Bundle\FrameworkBundle\Console\Application; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Tester\CommandTester; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; -use Wallabag\CoreBundle\Command\TagAllCommand; class TagAllCommandTest extends WallabagCoreTestCase { public function testRunTagAllCommandWithoutUsername() { - $this->expectException(\Symfony\Component\Console\Exception\RuntimeException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Not enough arguments (missing: "username")'); $application = new Application($this->getClient()->getKernel()); - $application->add(new TagAllCommand()); $command = $application->find('wallabag:tag:all'); $tester = new CommandTester($command); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); } public function testRunTagAllCommandWithBadUsername() { $application = new Application($this->getClient()->getKernel()); - $application->add(new TagAllCommand()); $command = $application->find('wallabag:tag:all'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'unknown', ]); @@ -44,13 +39,11 @@ class TagAllCommandTest extends WallabagCoreTestCase public function testRunTagAllCommand() { $application = new Application($this->getClient()->getKernel()); - $application->add(new TagAllCommand()); $command = $application->find('wallabag:tag:all'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', ]); diff --git a/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php b/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php index acd8d58e7..50a63a54f 100644 --- a/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php @@ -2,12 +2,18 @@ namespace Tests\Wallabag\CoreBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\HttpFoundation\File\UploadedFile; +use Symfony\Component\HttpFoundation\Session\SessionInterface; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; use Wallabag\AnnotationBundle\Entity\Annotation; -use Wallabag\CoreBundle\Entity\Config; +use Wallabag\CoreBundle\Entity\Config as ConfigEntity; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule; use Wallabag\CoreBundle\Entity\Tag; +use Wallabag\CoreBundle\Entity\TaggingRule; use Wallabag\UserBundle\Entity\User; class ConfigControllerTest extends WallabagCoreTestCase @@ -49,7 +55,7 @@ class ConfigControllerTest extends WallabagCoreTestCase $form = $crawler->filter('button[id=config_save]')->form(); $data = [ - 'config[theme]' => 'baggy', + 'config[theme]' => 'material', 'config[items_per_page]' => '30', 'config[reading_speed]' => '100', 'config[action_mark_as_read]' => '0', @@ -68,7 +74,6 @@ class ConfigControllerTest extends WallabagCoreTestCase public function testChangeReadingSpeed() { $this->logInAs('admin'); - $this->useTheme('baggy'); $client = $this->getClient(); $entry = new Entry($this->getLoggedInUser()); @@ -86,7 +91,7 @@ class ConfigControllerTest extends WallabagCoreTestCase 'entry_filter[readingTime][left_number]' => 22, ]; $crawler = $client->submit($form, $dataFilters); - $this->assertCount(1, $crawler->filter('div[class=entry]')); + $this->assertCount(0, $crawler->filter('div[class=entry]')); // Change reading speed $crawler = $client->request('GET', '/config'); @@ -115,7 +120,7 @@ class ConfigControllerTest extends WallabagCoreTestCase { return [ [[ - 'config[theme]' => 'baggy', + 'config[theme]' => 'material', 'config[items_per_page]' => '', 'config[language]' => 'en', ]], @@ -304,9 +309,9 @@ class ConfigControllerTest extends WallabagCoreTestCase $client = $this->getClient(); // reset the token - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); if (!$user) { @@ -456,7 +461,7 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('flashes.config.notice.tagging_rules_updated', $crawler->filter('body')->extract(['_text'])[0]); - $editLink = $crawler->filter('div[id=set5] a.mode_edit')->last()->link(); + $editLink = $crawler->filter('.mode_edit_tagging_rule')->last()->link(); $crawler = $client->click($editLink); $this->assertSame(302, $client->getResponse()->getStatusCode()); @@ -481,7 +486,7 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('readingTime <= 30', $crawler->filter('body')->extract(['_text'])[0]); - $deleteLink = $crawler->filter('div[id=set5] a.delete')->last()->link(); + $deleteLink = $crawler->filter('.delete_tagging_rule')->last()->link(); $crawler = $client->click($deleteLink); $this->assertSame(302, $client->getResponse()->getStatusCode()); @@ -569,8 +574,8 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->logInAs('bob'); $client = $this->getClient(); - $rule = $client->getContainer()->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:TaggingRule') + $rule = $client->getContainer()->get(EntityManagerInterface::class) + ->getRepository(TaggingRule::class) ->findAll()[0]; $crawler = $client->request('GET', '/tagging-rule/delete/' . $rule->getId()); @@ -585,8 +590,8 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->logInAs('bob'); $client = $this->getClient(); - $rule = $client->getContainer()->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:TaggingRule') + $rule = $client->getContainer()->get(EntityManagerInterface::class) + ->getRepository(TaggingRule::class) ->findAll()[0]; $crawler = $client->request('GET', '/tagging-rule/edit/' . $rule->getId()); @@ -706,8 +711,8 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->logInAs('bob'); $client = $this->getClient(); - $rule = $client->getContainer()->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:IgnoreOriginUserRule') + $rule = $client->getContainer()->get(EntityManagerInterface::class) + ->getRepository(IgnoreOriginUserRule::class) ->findAll()[0]; $crawler = $client->request('GET', '/ignore-origin-user-rule/edit/' . $rule->getId()); @@ -722,8 +727,8 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->logInAs('bob'); $client = $this->getClient(); - $rule = $client->getContainer()->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:IgnoreOriginUserRule') + $rule = $client->getContainer()->get(EntityManagerInterface::class) + ->getRepository(IgnoreOriginUserRule::class) ->findAll()[0]; $crawler = $client->request('GET', '/ignore-origin-user-rule/edit/' . $rule->getId()); @@ -738,7 +743,7 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $config = $client->getContainer()->get('craue_config'); + $config = $client->getContainer()->get(Config::class); $config->set('demo_mode_enabled', 1); $config->set('demo_mode_username', 'admin'); @@ -757,7 +762,7 @@ class ConfigControllerTest extends WallabagCoreTestCase $client->submit($form, $data); $this->assertSame(302, $client->getResponse()->getStatusCode()); - $this->assertStringContainsString('flashes.config.notice.password_not_updated_demo', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]); + $this->assertStringContainsString('flashes.config.notice.password_not_updated_demo', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->get('notice')[0]); $config->set('demo_mode_enabled', 0); $config->set('demo_mode_username', 'wallabag'); @@ -773,16 +778,16 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('config.form_user.delete.button', $body[0]); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('empty'); $user->setEnabled(false); $em->persist($user); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('bob'); $user->setEnabled(false); $em->persist($user); @@ -798,13 +803,13 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->assertSame(403, $client->getResponse()->getStatusCode()); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('empty'); $user->setEnabled(true); $em->persist($user); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('bob'); $user->setEnabled(true); $em->persist($user); @@ -818,7 +823,7 @@ class ConfigControllerTest extends WallabagCoreTestCase public function testDeleteAccount() { $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = new User(); $user->setName('Wallace'); @@ -830,7 +835,7 @@ class ConfigControllerTest extends WallabagCoreTestCase $em->persist($user); - $config = new Config($user); + $config = new ConfigEntity($user); $config->setTheme('material'); $config->setItemsPerPage(30); @@ -865,9 +870,9 @@ class ConfigControllerTest extends WallabagCoreTestCase $client->click($deleteLink); $this->assertSame(302, $client->getResponse()->getStatusCode()); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->createQueryBuilder('u') ->where('u.username = :username')->setParameter('username', 'wallace') ->getQuery() @@ -877,8 +882,8 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->assertNull($user); $entries = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUser($loggedInUserId); $this->assertEmpty($entries); @@ -889,9 +894,9 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->logInAs('empty'); $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); - $user = static::$kernel->getContainer()->get('security.token_storage')->getToken()->getUser(); + $user = static::$kernel->getContainer()->get(TokenStorageInterface::class)->getToken()->getUser(); $tag = new Tag(); $tag->setLabel('super'); @@ -928,10 +933,10 @@ class ConfigControllerTest extends WallabagCoreTestCase $crawler = $client->click($crawler->selectLink('config.reset.annotations')->link()); $this->assertSame(302, $client->getResponse()->getStatusCode()); - $this->assertStringContainsString('flashes.config.notice.annotations_reset', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]); + $this->assertStringContainsString('flashes.config.notice.annotations_reset', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->get('notice')[0]); $annotationsReset = $em - ->getRepository('WallabagAnnotationBundle:Annotation') + ->getRepository(Annotation::class) ->findAnnotationsByPageId($entry->getId(), $user->getId()); $this->assertEmpty($annotationsReset, 'Annotations were reset'); @@ -944,10 +949,10 @@ class ConfigControllerTest extends WallabagCoreTestCase $crawler = $client->click($crawler->selectLink('config.reset.tags')->link()); $this->assertSame(302, $client->getResponse()->getStatusCode()); - $this->assertStringContainsString('flashes.config.notice.tags_reset', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]); + $this->assertStringContainsString('flashes.config.notice.tags_reset', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->get('notice')[0]); $tagReset = $em - ->getRepository('WallabagCoreBundle:Tag') + ->getRepository(Tag::class) ->countAllTags($user->getId()); $this->assertSame(0, $tagReset, 'Tags were reset'); @@ -960,10 +965,10 @@ class ConfigControllerTest extends WallabagCoreTestCase $crawler = $client->click($crawler->selectLink('config.reset.entries')->link()); $this->assertSame(302, $client->getResponse()->getStatusCode()); - $this->assertStringContainsString('flashes.config.notice.entries_reset', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]); + $this->assertStringContainsString('flashes.config.notice.entries_reset', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->get('notice')[0]); $entryReset = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->countAllEntriesByUser($user->getId()); $this->assertSame(0, $entryReset, 'Entries were reset'); @@ -974,9 +979,9 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->logInAs('empty'); $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); - $user = static::$kernel->getContainer()->get('security.token_storage')->getToken()->getUser(); + $user = static::$kernel->getContainer()->get(TokenStorageInterface::class)->getToken()->getUser(); $tag = new Tag(); $tag->setLabel('super'); @@ -1024,22 +1029,22 @@ class ConfigControllerTest extends WallabagCoreTestCase $crawler = $client->click($crawler->selectLink('config.reset.archived')->link()); $this->assertSame(302, $client->getResponse()->getStatusCode()); - $this->assertStringContainsString('flashes.config.notice.archived_reset', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]); + $this->assertStringContainsString('flashes.config.notice.archived_reset', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->get('notice')[0]); $entryReset = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->countAllEntriesByUser($user->getId()); $this->assertSame(1, $entryReset, 'Entries were reset'); $tagReset = $em - ->getRepository('WallabagCoreBundle:Tag') + ->getRepository(Tag::class) ->countAllTags($user->getId()); $this->assertSame(1, $tagReset, 'Tags were reset'); $annotationsReset = $em - ->getRepository('WallabagAnnotationBundle:Annotation') + ->getRepository(Annotation::class) ->findAnnotationsByPageId($annotationArchived->getId(), $user->getId()); $this->assertEmpty($annotationsReset, 'Annotations were reset'); @@ -1050,9 +1055,9 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->logInAs('empty'); $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); - $user = static::$kernel->getContainer()->get('security.token_storage')->getToken()->getUser(); + $user = static::$kernel->getContainer()->get(TokenStorageInterface::class)->getToken()->getUser(); $tag = new Tag(); $tag->setLabel('super'); @@ -1081,22 +1086,22 @@ class ConfigControllerTest extends WallabagCoreTestCase $crawler = $client->click($crawler->selectLink('config.reset.entries')->link()); $this->assertSame(302, $client->getResponse()->getStatusCode()); - $this->assertStringContainsString('flashes.config.notice.entries_reset', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]); + $this->assertStringContainsString('flashes.config.notice.entries_reset', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->get('notice')[0]); $entryReset = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->countAllEntriesByUser($user->getId()); $this->assertSame(0, $entryReset, 'Entries were reset'); $tagReset = $em - ->getRepository('WallabagCoreBundle:Tag') + ->getRepository(Tag::class) ->countAllTags($user->getId()); $this->assertSame(0, $tagReset, 'Tags were reset'); $annotationsReset = $em - ->getRepository('WallabagAnnotationBundle:Annotation') + ->getRepository(Annotation::class) ->findAnnotationsByPageId($entry->getId(), $user->getId()); $this->assertEmpty($annotationsReset, 'Annotations were reset'); @@ -1105,19 +1110,18 @@ class ConfigControllerTest extends WallabagCoreTestCase public function testSwitchViewMode() { $this->logInAs('admin'); - $this->useTheme('baggy'); $client = $this->getClient(); $client->request('GET', '/unread/list'); - $this->assertStringNotContainsString('listmode', $client->getResponse()->getContent()); + $this->assertStringContainsString('row data', $client->getResponse()->getContent()); $client->request('GET', '/config/view-mode'); $crawler = $client->followRedirect(); $client->request('GET', '/unread/list'); - $this->assertStringContainsString('listmode', $client->getResponse()->getContent()); + $this->assertStringContainsString('collection', $client->getResponse()->getContent()); $client->request('GET', '/config/view-mode'); } @@ -1130,7 +1134,7 @@ class ConfigControllerTest extends WallabagCoreTestCase $client->followRedirect(); $this->assertSame('de', $client->getRequest()->getLocale()); - $this->assertSame('de', $client->getContainer()->get('session')->get('_locale')); + $this->assertSame('de', $client->getContainer()->get(SessionInterface::class)->get('_locale')); } public function testChangeLocaleWithReferer() @@ -1142,7 +1146,7 @@ class ConfigControllerTest extends WallabagCoreTestCase $client->followRedirect(); $this->assertSame('de', $client->getRequest()->getLocale()); - $this->assertSame('de', $client->getContainer()->get('session')->get('_locale')); + $this->assertSame('de', $client->getContainer()->get(SessionInterface::class)->get('_locale')); } public function testChangeLocaleToBadLocale() @@ -1154,7 +1158,7 @@ class ConfigControllerTest extends WallabagCoreTestCase $client->followRedirect(); $this->assertNotSame('yuyuyuyu', $client->getRequest()->getLocale()); - $this->assertNotSame('yuyuyuyu', $client->getContainer()->get('session')->get('_locale')); + $this->assertNotSame('yuyuyuyu', $client->getContainer()->get(SessionInterface::class)->get('_locale')); } public function testUserEnable2faEmail() @@ -1174,7 +1178,7 @@ class ConfigControllerTest extends WallabagCoreTestCase // restore user $em = $this->getEntityManager(); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $this->assertTrue($user->isEmailTwoFactor()); @@ -1201,7 +1205,7 @@ class ConfigControllerTest extends WallabagCoreTestCase // restore user $em = $this->getEntityManager(); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $this->assertFalse($user->isEmailTwoFactor()); @@ -1219,7 +1223,7 @@ class ConfigControllerTest extends WallabagCoreTestCase // restore user $em = $this->getEntityManager(); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $this->assertTrue($user->isGoogleTwoFactor()); @@ -1243,7 +1247,7 @@ class ConfigControllerTest extends WallabagCoreTestCase // restore user $em = $this->getEntityManager(); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $this->assertTrue($user->isGoogleTwoFactor()); @@ -1254,7 +1258,7 @@ class ConfigControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $this->assertFalse($user->isGoogleTwoFactor()); @@ -1278,7 +1282,7 @@ class ConfigControllerTest extends WallabagCoreTestCase // restore user $em = $this->getEntityManager(); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $this->assertEmpty($user->getGoogleAuthenticatorSecret()); diff --git a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php index 545e7fb8f..a46281e58 100644 --- a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php @@ -2,13 +2,18 @@ namespace Tests\Wallabag\CoreBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; use Wallabag\AnnotationBundle\Entity\Annotation; -use Wallabag\CoreBundle\Entity\Config; +use Wallabag\CoreBundle\Entity\Config as ConfigEntity; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\SiteCredential; use Wallabag\CoreBundle\Entity\Tag; use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Helper\CryptoProxy; +use Wallabag\UserBundle\Entity\User; class EntryControllerTest extends WallabagCoreTestCase { @@ -26,7 +31,7 @@ class EntryControllerTest extends WallabagCoreTestCase { if ($this->downloadImagesEnabled) { $client = static::createClient(); - $client->getContainer()->get('craue_config')->set('download_images_enabled', 0); + $client->getContainer()->get(Config::class)->set('download_images_enabled', 0); $this->downloadImagesEnabled = false; } @@ -81,7 +86,7 @@ class EntryControllerTest extends WallabagCoreTestCase public function testGetNew() { $this->logInAs('admin'); - $this->useTheme('baggy'); + $this->useTheme('material'); $client = $this->getClient(); $crawler = $client->request('GET', '/new'); @@ -112,9 +117,9 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertCount(5, $crawler->filter($this->entryDataTestAttribute)); $em = $client->getContainer() - ->get('doctrine.orm.entity_manager'); + ->get(EntityManagerInterface::class); $entry = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); $em->remove($entry); $em->flush(); @@ -146,7 +151,7 @@ class EntryControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('store_article_headers', 1); + $client->getContainer()->get(Config::class)->set('store_article_headers', 1); $crawler = $client->request('GET', '/new'); @@ -163,18 +168,18 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); $author = $content->getPublishedBy(); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $this->assertSame($this->url, $content->getUrl()); $this->assertStringContainsString('la cryptomonnaie de Facebook', $content->getTitle()); $this->assertSame('fr', $content->getLanguage()); $this->assertArrayHasKey('x-frame-options', $content->getHeaders()); - $client->getContainer()->get('craue_config')->set('store_article_headers', 0); + $client->getContainer()->get(Config::class)->set('store_article_headers', 0); } /** @@ -200,8 +205,8 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); $tags = $content->getTagsLabel(); @@ -237,11 +242,11 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId($url, $this->getLoggedInUserId()); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $authors = $content->getPublishedBy(); $this->assertSame('2017-04-05', $content->getPublishedAt()->format('Y-m-d')); $this->assertSame('fr', $content->getLanguage()); @@ -376,9 +381,9 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('/', $client->getResponse()->getTargetUrl()); $em = $client->getContainer() - ->get('doctrine.orm.entity_manager'); + ->get(EntityManagerInterface::class); $entry = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findOneByUrl($url); $tags = $entry->getTagsLabel(); @@ -407,7 +412,7 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('/', $client->getResponse()->getTargetUrl()); $entry = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findOneByUrl($url); $tags = $entry->getTagsLabel(); @@ -510,7 +515,7 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $entry = $this->getEntityManager() - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->find($entry->getId()); $this->assertNotEmpty($entry->getContent()); @@ -534,7 +539,7 @@ class EntryControllerTest extends WallabagCoreTestCase // otherwise, retrieve the same entity will retrieve change from the previous request :0 $this->getEntityManager()->clear(); $newContent = $this->getEntityManager() - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->find($entry->getId()); $this->assertNotSame($client->getContainer()->getParameter('wallabag_core.fetching_error_message'), $newContent->getContent()); @@ -643,8 +648,8 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $res = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry->getId()); $this->assertSame(1, $res->isArchived()); @@ -666,8 +671,8 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $res = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneById($entry->getId()); $this->assertSame(1, $res->isStarred()); @@ -705,11 +710,11 @@ class EntryControllerTest extends WallabagCoreTestCase $client = $this->getClient(); $em = $client->getContainer() - ->get('doctrine.orm.entity_manager'); + ->get(EntityManagerInterface::class); // add a new content to be removed later $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUserName('admin'); $content = new Entry($user); @@ -741,8 +746,8 @@ class EntryControllerTest extends WallabagCoreTestCase $client = $this->getClient(); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneByUsernameAndNotArchived('bob'); $client->request('GET', '/view/' . $content->getId()); @@ -946,9 +951,9 @@ class EntryControllerTest extends WallabagCoreTestCase $entry = new Entry($this->getLoggedInUser()); $entry->setUrl($this->url); - $em = $this->getClient()->getContainer()->get('doctrine.orm.entity_manager'); + $em = $this->getClient()->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUserName('admin'); $annotation = new Annotation($user); @@ -1132,7 +1137,7 @@ class EntryControllerTest extends WallabagCoreTestCase $client = $this->getClient(); // sharing is enabled - $client->getContainer()->get('craue_config')->set('share_public', 1); + $client->getContainer()->get(Config::class)->set('share_public', 1); $content = new Entry($this->getLoggedInUser()); $content->setUrl($this->url); @@ -1166,7 +1171,7 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('og:image', $client->getResponse()->getContent()); // sharing is now disabled - $client->getContainer()->get('craue_config')->set('share_public', 0); + $client->getContainer()->get(Config::class)->set('share_public', 0); $client->request('GET', '/share/' . $content->getUid()); $this->assertSame(404, $client->getResponse()->getStatusCode()); @@ -1189,7 +1194,7 @@ class EntryControllerTest extends WallabagCoreTestCase $client = $this->getClient(); $url = self::AN_URL_CONTAINING_AN_ARTICLE_WITH_IMAGE; - $client->getContainer()->get('craue_config')->set('download_images_enabled', 1); + $client->getContainer()->get(Config::class)->set('download_images_enabled', 1); $crawler = $client->request('GET', '/new'); @@ -1206,19 +1211,19 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $em = $client->getContainer() - ->get('doctrine.orm.entity_manager'); + ->get(EntityManagerInterface::class); $entry = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findByUrlAndUserId($url, $this->getLoggedInUserId()); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $entry); + $this->assertInstanceOf(Entry::class, $entry); $this->assertSame($url, $entry->getUrl()); $this->assertStringContainsString('Judo', $entry->getTitle()); // instead of checking for the filename (which might change) check that the image is now local $this->assertStringContainsString(rtrim($client->getContainer()->getParameter('domain_name'), '/') . '/assets/images/', $entry->getContent()); - $client->getContainer()->get('craue_config')->set('download_images_enabled', 0); + $client->getContainer()->get(Config::class)->set('download_images_enabled', 0); } /** @@ -1231,7 +1236,7 @@ class EntryControllerTest extends WallabagCoreTestCase $client = $this->getClient(); $url = self::AN_URL_CONTAINING_AN_ARTICLE_WITH_IMAGE; - $client->getContainer()->get('craue_config')->set('download_images_enabled', 1); + $client->getContainer()->get(Config::class)->set('download_images_enabled', 1); $crawler = $client->request('GET', '/new'); @@ -1248,15 +1253,15 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId($url, $this->getLoggedInUserId()); $client->request('GET', '/delete/' . $content->getId()); $this->assertSame(302, $client->getResponse()->getStatusCode()); - $client->getContainer()->get('craue_config')->set('download_images_enabled', 0); + $client->getContainer()->get(Config::class)->set('download_images_enabled', 0); } public function testRedirectToHomepage() @@ -1266,7 +1271,7 @@ class EntryControllerTest extends WallabagCoreTestCase // Redirect to homepage $config = $this->getLoggedInUser()->getConfig(); - $config->setActionMarkAsRead(Config::REDIRECT_TO_HOMEPAGE); + $config->setActionMarkAsRead(ConfigEntity::REDIRECT_TO_HOMEPAGE); $this->getEntityManager()->persist($config); $entry = new Entry($this->getLoggedInUser()); @@ -1289,7 +1294,7 @@ class EntryControllerTest extends WallabagCoreTestCase // Redirect to current page $config = $this->getLoggedInUser()->getConfig(); - $config->setActionMarkAsRead(Config::REDIRECT_TO_CURRENT_PAGE); + $config->setActionMarkAsRead(ConfigEntity::REDIRECT_TO_CURRENT_PAGE); $this->getEntityManager()->persist($config); $entry = new Entry($this->getLoggedInUser()); @@ -1527,11 +1532,11 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId($url, $this->getLoggedInUserId()); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $this->assertSame($url, $content->getUrl()); $this->assertSame($expectedLanguage, $content->getLanguage()); } @@ -1544,17 +1549,17 @@ class EntryControllerTest extends WallabagCoreTestCase $url = 'https://www.monde-diplomatique.fr/2017/05/BONNET/57476'; $this->logInAs('admin'); $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); // enable restricted access - $client->getContainer()->get('craue_config')->set('restricted_access', 1); + $client->getContainer()->get(Config::class)->set('restricted_access', 1); // create a new site_credential - $user = $client->getContainer()->get('security.token_storage')->getToken()->getUser(); + $user = $client->getContainer()->get(TokenStorageInterface::class)->getToken()->getUser(); $credential = new SiteCredential($user); $credential->setHost('monde-diplomatique.fr'); - $credential->setUsername($client->getContainer()->get('wallabag_core.helper.crypto_proxy')->crypt('foo')); - $credential->setPassword($client->getContainer()->get('wallabag_core.helper.crypto_proxy')->crypt('bar')); + $credential->setUsername($client->getContainer()->get(CryptoProxy::class)->crypt('foo')); + $credential->setPassword($client->getContainer()->get(CryptoProxy::class)->crypt('bar')); $em->persist($credential); $em->flush(); @@ -1579,13 +1584,13 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('flashes.entry.notice.entry_saved', $crawler->filter('body')->extract(['_text'])[0]); $content = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->findByUrlAndUserId($url, $this->getLoggedInUserId()); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $this->assertSame('Quand Manille manœuvre', $content->getTitle()); - $client->getContainer()->get('craue_config')->set('restricted_access', 0); + $client->getContainer()->get(Config::class)->set('restricted_access', 0); } public function testPostEntryWhenFetchFails() @@ -1621,14 +1626,14 @@ class EntryControllerTest extends WallabagCoreTestCase $cookie = $client->getCookieJar()->all(); $client = $this->getNewClient(); $client->getCookieJar()->set($cookie[0]); - $client->getContainer()->set('wallabag_core.content_proxy', $contentProxy); + $client->getContainer()->set(ContentProxy::class, $contentProxy); $client->submit($form, $data); $this->assertSame(302, $client->getResponse()->getStatusCode()); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId($url, $this->getLoggedInUserId()); $authors = $content->getPublishedBy(); @@ -1641,8 +1646,8 @@ class EntryControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); - $entry = $em->getRepository('WallabagCoreBundle:Entry')->findByUrlAndUserId('http://0.0.0.0/entry1', $this->getLoggedInUserId()); + $em = $client->getContainer()->get(EntityManagerInterface::class); + $entry = $em->getRepository(Entry::class)->findByUrlAndUserId('http://0.0.0.0/entry1', $this->getLoggedInUserId()); $tag = $entry->getTags()[0]; $crawler = $client->request('GET', '/view/' . $entry->getId()); @@ -1698,6 +1703,10 @@ class EntryControllerTest extends WallabagCoreTestCase $entry2->setUrl($this->url); $this->getEntityManager()->persist($entry2); + $entry3 = new Entry($this->getLoggedInUser()); + $entry3->setUrl($this->url); + $this->getEntityManager()->persist($entry3); + $this->getEntityManager()->flush(); $this->getEntityManager()->clear(); @@ -1714,15 +1723,15 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $res = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry1->getId()); $this->assertSame(1, $res->isArchived()); $res = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry2->getId()); $this->assertSame(1, $res->isArchived()); @@ -1736,19 +1745,49 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $res = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry1->getId()); $this->assertSame(1, $res->isStarred()); $res = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry2->getId()); $this->assertSame(1, $res->isStarred()); + // Mass actions : tag + $client->request('POST', '/mass', [ + 'tag' => '', + 'tags' => 'foo', + 'entry-checkbox' => $entries, + ]); + + $this->assertSame(302, $client->getResponse()->getStatusCode()); + + $res = $client->getContainer() + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) + ->find($entry1->getId()); + + $this->assertContains('foo', $res->getTagsLabel()); + + $res = $client->getContainer() + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) + ->find($entry2->getId()); + + $this->assertContains('foo', $res->getTagsLabel()); + + $res = $client->getContainer() + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) + ->find($entry3->getId()); + + $this->assertNotContains('foo', $res->getTagsLabel()); + // Mass actions : delete $client->request('POST', '/mass', [ 'delete' => '', diff --git a/tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php b/tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php index 41b995efa..c2adec3af 100644 --- a/tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php @@ -2,6 +2,7 @@ namespace Tests\Wallabag\CoreBundle\Controller; +use Doctrine\ORM\EntityManagerInterface; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; use Wallabag\CoreBundle\Entity\Entry; @@ -49,8 +50,8 @@ class ExportControllerTest extends WallabagCoreTestCase $this->assertSame(404, $client->getResponse()->getStatusCode()); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneByUsernameAndNotArchived('admin'); $client->request('GET', '/export/' . $content->getId() . '.doc'); @@ -90,8 +91,8 @@ class ExportControllerTest extends WallabagCoreTestCase $client = $this->getClient(); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findOneByUsernameAndNotArchived('admin'); ob_start(); @@ -158,8 +159,8 @@ class ExportControllerTest extends WallabagCoreTestCase // to be sure results are the same $contentInDB = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->createQueryBuilder('e') ->select('e, t') ->leftJoin('e.user', 'u') @@ -204,8 +205,8 @@ class ExportControllerTest extends WallabagCoreTestCase $client = $this->getClient(); $contentInDB = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId('http://0.0.0.0/entry1', $this->getLoggedInUserId()); ob_start(); @@ -278,8 +279,8 @@ class ExportControllerTest extends WallabagCoreTestCase // to be sure results are the same $contentInDB = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->createQueryBuilder('e') ->leftJoin('e.user', 'u') ->where('u.username = :username')->setParameter('username', 'admin') diff --git a/tests/Wallabag/CoreBundle/Controller/FeedControllerTest.php b/tests/Wallabag/CoreBundle/Controller/FeedControllerTest.php index e35a636e3..8878822ca 100644 --- a/tests/Wallabag/CoreBundle/Controller/FeedControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/FeedControllerTest.php @@ -2,7 +2,10 @@ namespace Tests\Wallabag\CoreBundle\Controller; +use Doctrine\ORM\EntityManagerInterface; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\UserBundle\Entity\User; class FeedControllerTest extends WallabagCoreTestCase { @@ -89,9 +92,9 @@ class FeedControllerTest extends WallabagCoreTestCase public function testUnread() { $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $config = $user->getConfig(); @@ -110,9 +113,9 @@ class FeedControllerTest extends WallabagCoreTestCase public function testStarred() { $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $config = $user->getConfig(); @@ -132,9 +135,9 @@ class FeedControllerTest extends WallabagCoreTestCase public function testArchives() { $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $config = $user->getConfig(); @@ -154,9 +157,9 @@ class FeedControllerTest extends WallabagCoreTestCase public function testAll() { $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $config = $user->getConfig(); @@ -176,9 +179,9 @@ class FeedControllerTest extends WallabagCoreTestCase public function testPagination() { $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $config = $user->getConfig(); @@ -204,9 +207,9 @@ class FeedControllerTest extends WallabagCoreTestCase public function testTags() { $client = $this->getClient(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $config = $user->getConfig(); @@ -215,12 +218,12 @@ class FeedControllerTest extends WallabagCoreTestCase $em->persist($config); $entry1 = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->find(1) ; $entry4 = $em - ->getRepository('WallabagCoreBundle:Entry') + ->getRepository(Entry::class) ->find(4) ; diff --git a/tests/Wallabag/CoreBundle/Controller/SecurityControllerTest.php b/tests/Wallabag/CoreBundle/Controller/SecurityControllerTest.php index 9730dce9d..39269f898 100644 --- a/tests/Wallabag/CoreBundle/Controller/SecurityControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/SecurityControllerTest.php @@ -2,7 +2,9 @@ namespace Tests\Wallabag\CoreBundle\Controller; +use Doctrine\ORM\EntityManagerInterface; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\UserBundle\Entity\User; class SecurityControllerTest extends WallabagCoreTestCase { @@ -38,9 +40,9 @@ class SecurityControllerTest extends WallabagCoreTestCase $client->followRedirects(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $user->setEmailTwoFactor(true); $em->persist($user); @@ -52,7 +54,7 @@ class SecurityControllerTest extends WallabagCoreTestCase // restore user $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $user->setEmailTwoFactor(false); $em->persist($user); @@ -71,9 +73,9 @@ class SecurityControllerTest extends WallabagCoreTestCase $client->followRedirects(); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $user->setGoogleAuthenticatorSecret('26LDIHYGHNELOQEM'); $em->persist($user); @@ -85,7 +87,7 @@ class SecurityControllerTest extends WallabagCoreTestCase // restore user $user = $em - ->getRepository('WallabagUserBundle:User') + ->getRepository(User::class) ->findOneByUsername('admin'); $user->setGoogleAuthenticatorSecret(null); $em->persist($user); diff --git a/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php b/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php index 52fcd8f85..c7ca9b785 100644 --- a/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php @@ -2,6 +2,8 @@ namespace Tests\Wallabag\CoreBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Client; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; use Wallabag\CoreBundle\Entity\SiteCredential; @@ -13,13 +15,13 @@ class SiteCredentialControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('restricted_access', 0); + $client->getContainer()->get(Config::class)->set('restricted_access', 0); $client->request('GET', '/site-credentials/'); $this->assertSame(404, $client->getResponse()->getStatusCode()); - $client->getContainer()->get('craue_config')->set('restricted_access', 1); + $client->getContainer()->get(Config::class)->set('restricted_access', 1); } public function testListSiteCredential() @@ -144,7 +146,7 @@ class SiteCredentialControllerTest extends WallabagCoreTestCase $credential->setUsername('sergei'); $credential->setPassword('microsoft'); - $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $em = $client->getContainer()->get(EntityManagerInterface::class); $em->persist($credential); $em->flush(); diff --git a/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php b/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php index e3d3ff5e0..5f67c749c 100644 --- a/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php @@ -2,10 +2,15 @@ namespace Tests\Wallabag\CoreBundle\Controller; +use Doctrine\ORM\EntityManagerInterface; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Tag; +use Wallabag\UserBundle\Entity\User; +/** + * @group Tag + */ class TagControllerTest extends WallabagCoreTestCase { public $tagName = 'opensource'; @@ -73,8 +78,8 @@ class TagControllerTest extends WallabagCoreTestCase $client = $this->getClient(); $entry = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId('http://0.0.0.0/entry2', $this->getLoggedInUserId()); $crawler = $client->request('GET', '/view/' . $entry->getId()); @@ -89,8 +94,8 @@ class TagControllerTest extends WallabagCoreTestCase $this->assertSame(302, $client->getResponse()->getStatusCode()); $newEntry = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry->getId()); $tags = $newEntry->getTags()->toArray(); @@ -134,26 +139,75 @@ class TagControllerTest extends WallabagCoreTestCase $this->assertSame(404, $client->getResponse()->getStatusCode()); $tag = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Tag') + ->get(EntityManagerInterface::class) + ->getRepository(Tag::class) ->findOneByLabel($this->tagName); $this->assertNull($tag, $this->tagName . ' was removed because it begun an orphan tag'); } + public function testRemoveTag() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $tag = new Tag(); + $tag->setLabel($this->tagName); + + $entry = new Entry($this->getLoggedInUser()); + $entry->setUrl('http://0.0.0.0/foo'); + $entry->addTag($tag); + $this->getEntityManager()->persist($entry); + + $entry2 = new Entry($this->getLoggedInUser()); + $entry2->setUrl('http://0.0.0.0/bar'); + $entry2->addTag($tag); + $this->getEntityManager()->persist($entry2); + $this->getEntityManager()->flush(); + $this->getEntityManager()->clear(); + + $crawler = $client->request('GET', '/tag/list'); + $link = $crawler->filter('a[id="delete-' . $tag->getSlug() . '"]')->link(); + $client->click($link); + + $tag = $client->getContainer() + ->get(EntityManagerInterface::class) + ->getRepository(Tag::class) + ->findOneByLabel($this->tagName); + + $this->assertNull($tag, $this->tagName . ' was removed because it begun an orphan tag'); + + $user = $this->getEntityManager() + ->getRepository(User::class) + ->findOneByUserName('admin'); + + $entry = $client->getContainer() + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) + ->findByUrlAndUserId('http://0.0.0.0/foo', $user->getId()); + + $entry2 = $client->getContainer() + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) + ->findByUrlAndUserId('http://0.0.0.0/bar', $user->getId()); + + $this->assertEmpty($entry->getTagsLabel()); + $this->assertEmpty($entry2->getTagsLabel()); + } + public function testShowEntriesForTagAction() { $this->logInAs('admin'); $client = $this->getClient(); $em = $client->getContainer() - ->get('doctrine.orm.entity_manager'); + ->get(EntityManagerInterface::class); $tag = new Tag(); $tag->setLabel($this->tagName); $entry = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId('http://0.0.0.0/entry4', $this->getLoggedInUserId()); $tag->addEntry($entry); @@ -163,8 +217,8 @@ class TagControllerTest extends WallabagCoreTestCase $em->flush(); $tag = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Tag') + ->get(EntityManagerInterface::class) + ->getRepository(Tag::class) ->findOneByEntryAndTagLabel($entry, $this->tagName); $crawler = $client->request('GET', '/tag/list/' . $tag->getSlug()); @@ -216,13 +270,13 @@ class TagControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('flashes.tag.notice.tag_renamed', $crawler->filter('body')->extract(['_text'])[0]); $freshEntry = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry->getId()); $freshEntry2 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry2->getId()); $tags = []; @@ -240,8 +294,8 @@ class TagControllerTest extends WallabagCoreTestCase $this->assertFalse(array_search($tag->getLabel(), $tags, true), 'Previous tag is not attach to entries anymore.'); $newTag = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Tag') + ->get(EntityManagerInterface::class) + ->getRepository(Tag::class) ->findByLabel($newTagLabel); $this->assertCount(1, $newTag, 'New tag exists.'); @@ -280,8 +334,8 @@ class TagControllerTest extends WallabagCoreTestCase $this->assertStringNotContainsString('flashes.tag.notice.tag_renamed', $crawler->filter('body')->extract(['_text'])[0]); $freshEntry = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry->getId()); $tags = []; @@ -294,8 +348,8 @@ class TagControllerTest extends WallabagCoreTestCase $this->assertNotFalse(array_search($tag->getLabel(), $tags, true), 'Tag is still assigned to the entry.'); $newTag = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Tag') + ->get(EntityManagerInterface::class) + ->getRepository(Tag::class) ->findByLabel($tagLabel); $this->assertCount(1, $newTag); @@ -335,8 +389,8 @@ class TagControllerTest extends WallabagCoreTestCase $this->assertStringNotContainsString('flashes.tag.notice.tag_renamed', $crawler->filter('body')->extract(['_text'])[0]); $freshEntry = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry->getId()); $tags = []; @@ -349,13 +403,13 @@ class TagControllerTest extends WallabagCoreTestCase $this->assertFalse(array_search($newTagLabel, $tags, true)); $tagFromRepo = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Tag') + ->get(EntityManagerInterface::class) + ->getRepository(Tag::class) ->findByLabel($tagLabel); $newTagFromRepo = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Tag') + ->get(EntityManagerInterface::class) + ->getRepository(Tag::class) ->findByLabel($newTagLabel); $this->assertCount(0, $newTagFromRepo); @@ -405,23 +459,23 @@ class TagControllerTest extends WallabagCoreTestCase $this->assertStringNotContainsString('flashes.tag.notice.tag_renamed', $crawler->filter('body')->extract(['_text'])[0]); $freshEntry1 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry1->getId()); $freshEntry2 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry2->getId()); $tagFromRepo = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Tag') + ->get(EntityManagerInterface::class) + ->getRepository(Tag::class) ->findByLabel($tagLabel); $previousTagFromRepo = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Tag') + ->get(EntityManagerInterface::class) + ->getRepository(Tag::class) ->findByLabel($previousTagLabel); $this->assertCount(1, $tagFromRepo); @@ -463,8 +517,8 @@ class TagControllerTest extends WallabagCoreTestCase $client->submit($form, $data); $newEntry = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->find($entry->getId()); $tags = $newEntry->getTags()->toArray(); @@ -496,8 +550,8 @@ class TagControllerTest extends WallabagCoreTestCase $client->followRedirect(); $entries = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->getBuilderForSearchByUser($this->getLoggedInUserId(), 'title', 'unread') ->getQuery()->getResult(); diff --git a/tests/Wallabag/CoreBundle/Event/Listener/LocaleListenerTest.php b/tests/Wallabag/CoreBundle/Event/Listener/LocaleListenerTest.php index bc35d1000..2d0b87ae1 100644 --- a/tests/Wallabag/CoreBundle/Event/Listener/LocaleListenerTest.php +++ b/tests/Wallabag/CoreBundle/Event/Listener/LocaleListenerTest.php @@ -78,7 +78,7 @@ class LocaleListenerTest extends TestCase private function getEvent(Request $request) { - $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface') + $kernel = $this->getMockBuilder(HttpKernelInterface::class) ->disableOriginalConstructor() ->getMock(); diff --git a/tests/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriberTest.php b/tests/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriberTest.php index 06f852373..6a22a84e1 100644 --- a/tests/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriberTest.php +++ b/tests/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriberTest.php @@ -3,31 +3,36 @@ namespace Tests\Wallabag\CoreBundle\Event\Subscriber; use Doctrine\Common\EventManager; +use Doctrine\DBAL\Platforms\MySqlPlatform; +use Doctrine\DBAL\Platforms\PostgreSqlPlatform; +use Doctrine\DBAL\Platforms\SqlitePlatform; +use Doctrine\ORM\EntityManager; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Mapping\ClassMetadata; use PHPUnit\Framework\TestCase; use Wallabag\CoreBundle\Event\Subscriber\TablePrefixSubscriber; +use Wallabag\UserBundle\Entity\User; class TablePrefixSubscriberTest extends TestCase { public function dataForPrefix() { return [ - ['wallabag_', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'wallabag_user', '"wallabag_user"', new \Doctrine\DBAL\Platforms\PostgreSqlPlatform()], - ['wallabag_', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'wallabag_user', '`wallabag_user`', new \Doctrine\DBAL\Platforms\MySqlPlatform()], - ['wallabag_', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'wallabag_user', '"wallabag_user"', new \Doctrine\DBAL\Platforms\SqlitePlatform()], + ['wallabag_', User::class, '`user`', 'user', 'wallabag_user', '"wallabag_user"', new PostgreSqlPlatform()], + ['wallabag_', User::class, '`user`', 'user', 'wallabag_user', '`wallabag_user`', new MySqlPlatform()], + ['wallabag_', User::class, '`user`', 'user', 'wallabag_user', '"wallabag_user"', new SqlitePlatform()], - ['wallabag_', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'wallabag_user', 'wallabag_user', new \Doctrine\DBAL\Platforms\PostgreSqlPlatform()], - ['wallabag_', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'wallabag_user', 'wallabag_user', new \Doctrine\DBAL\Platforms\MySqlPlatform()], - ['wallabag_', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'wallabag_user', 'wallabag_user', new \Doctrine\DBAL\Platforms\SqlitePlatform()], + ['wallabag_', User::class, 'user', 'user', 'wallabag_user', 'wallabag_user', new PostgreSqlPlatform()], + ['wallabag_', User::class, 'user', 'user', 'wallabag_user', 'wallabag_user', new MySqlPlatform()], + ['wallabag_', User::class, 'user', 'user', 'wallabag_user', 'wallabag_user', new SqlitePlatform()], - ['', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'user', '"user"', new \Doctrine\DBAL\Platforms\PostgreSqlPlatform()], - ['', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'user', '`user`', new \Doctrine\DBAL\Platforms\MySqlPlatform()], - ['', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'user', '"user"', new \Doctrine\DBAL\Platforms\SqlitePlatform()], + ['', User::class, '`user`', 'user', 'user', '"user"', new PostgreSqlPlatform()], + ['', User::class, '`user`', 'user', 'user', '`user`', new MySqlPlatform()], + ['', User::class, '`user`', 'user', 'user', '"user"', new SqlitePlatform()], - ['', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'user', 'user', new \Doctrine\DBAL\Platforms\PostgreSqlPlatform()], - ['', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'user', 'user', new \Doctrine\DBAL\Platforms\MySqlPlatform()], - ['', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'user', 'user', new \Doctrine\DBAL\Platforms\SqlitePlatform()], + ['', User::class, 'user', 'user', 'user', 'user', new PostgreSqlPlatform()], + ['', User::class, 'user', 'user', 'user', 'user', new MySqlPlatform()], + ['', User::class, 'user', 'user', 'user', 'user', new SqlitePlatform()], ]; } @@ -36,7 +41,7 @@ class TablePrefixSubscriberTest extends TestCase */ public function testPrefix($prefix, $entityName, $tableName, $tableNameExpected, $finalTableName, $finalTableNameQuoted, $platform) { - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); @@ -60,7 +65,7 @@ class TablePrefixSubscriberTest extends TestCase */ public function testSubscribedEvents($prefix, $entityName, $tableName, $tableNameExpected, $finalTableName, $finalTableNameQuoted, $platform) { - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); @@ -82,7 +87,7 @@ class TablePrefixSubscriberTest extends TestCase public function testPrefixManyToMany() { - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); @@ -110,6 +115,6 @@ class TablePrefixSubscriberTest extends TestCase $this->assertSame('yo_entry', $metaDataEvent->getClassMetadata()->getTableName()); $this->assertSame('yo_entry_tag', $metaDataEvent->getClassMetadata()->associationMappings['tags']['joinTable']['name']); - $this->assertSame('yo_entry', $metaDataEvent->getClassMetadata()->getQuotedTableName(new \Doctrine\DBAL\Platforms\MySqlPlatform())); + $this->assertSame('yo_entry', $metaDataEvent->getClassMetadata()->getQuotedTableName(new MySqlPlatform())); } } diff --git a/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php b/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php index 9e0a91365..d22764250 100644 --- a/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php +++ b/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php @@ -2,6 +2,7 @@ namespace Tests\Wallabag\CoreBundle\GuzzleSiteAuthenticator; +use Graby\SiteConfig\ConfigBuilder; use Graby\SiteConfig\SiteConfig as GrabySiteConfig; use Monolog\Handler\TestHandler; use Monolog\Logger; @@ -9,6 +10,8 @@ use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; use Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder; +use Wallabag\CoreBundle\Repository\SiteCredentialRepository; +use Wallabag\UserBundle\Entity\User; class GrabySiteConfigBuilderTest extends WallabagCoreTestCase { @@ -16,7 +19,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase public function testBuildConfigExists() { - $grabyConfigBuilderMock = $this->getMockBuilder('Graby\SiteConfig\ConfigBuilder') + $grabyConfigBuilderMock = $this->getMockBuilder(ConfigBuilder::class) ->disableOriginalConstructor() ->getMock(); @@ -37,7 +40,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase $handler = new TestHandler(); $logger->pushHandler($handler); - $siteCrentialRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\SiteCredentialRepository') + $siteCrentialRepo = $this->getMockBuilder(SiteCredentialRepository::class) ->disableOriginalConstructor() ->getMock(); $siteCrentialRepo->expects($this->once()) @@ -45,7 +48,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase ->with(['api.example.com', '.example.com'], 1) ->willReturn(['username' => 'foo', 'password' => 'bar']); - $user = $this->getMockBuilder('Wallabag\UserBundle\Entity\User') + $user = $this->getMockBuilder(User::class) ->disableOriginalConstructor() ->getMock(); $user->expects($this->once()) @@ -83,7 +86,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase public function testBuildConfigDoesntExist() { - $grabyConfigBuilderMock = $this->getMockBuilder('\Graby\SiteConfig\ConfigBuilder') + $grabyConfigBuilderMock = $this->getMockBuilder(ConfigBuilder::class) ->disableOriginalConstructor() ->getMock(); @@ -96,7 +99,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase $handler = new TestHandler(); $logger->pushHandler($handler); - $siteCrentialRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\SiteCredentialRepository') + $siteCrentialRepo = $this->getMockBuilder(SiteCredentialRepository::class) ->disableOriginalConstructor() ->getMock(); $siteCrentialRepo->expects($this->once()) @@ -104,7 +107,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase ->with(['unknown.com', '.com'], 1) ->willReturn(null); - $user = $this->getMockBuilder('Wallabag\UserBundle\Entity\User') + $user = $this->getMockBuilder(User::class) ->disableOriginalConstructor() ->getMock(); $user->expects($this->once()) @@ -134,7 +137,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase public function testBuildConfigWithBadExtraFields() { - $grabyConfigBuilderMock = $this->getMockBuilder('Graby\SiteConfig\ConfigBuilder') + $grabyConfigBuilderMock = $this->getMockBuilder(ConfigBuilder::class) ->disableOriginalConstructor() ->getMock(); @@ -155,7 +158,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase $handler = new TestHandler(); $logger->pushHandler($handler); - $siteCrentialRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\SiteCredentialRepository') + $siteCrentialRepo = $this->getMockBuilder(SiteCredentialRepository::class) ->disableOriginalConstructor() ->getMock(); $siteCrentialRepo->expects($this->once()) @@ -163,7 +166,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase ->with(['example.com', '.com'], 1) ->willReturn(['username' => 'foo', 'password' => 'bar']); - $user = $this->getMockBuilder('Wallabag\UserBundle\Entity\User') + $user = $this->getMockBuilder(User::class) ->disableOriginalConstructor() ->getMock(); $user->expects($this->once()) @@ -201,7 +204,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase public function testBuildConfigUserNotDefined() { - $grabyConfigBuilderMock = $this->getMockBuilder('\Graby\SiteConfig\ConfigBuilder') + $grabyConfigBuilderMock = $this->getMockBuilder(ConfigBuilder::class) ->disableOriginalConstructor() ->getMock(); @@ -214,7 +217,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase $handler = new TestHandler(); $logger->pushHandler($handler); - $siteCrentialRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\SiteCredentialRepository') + $siteCrentialRepo = $this->getMockBuilder(SiteCredentialRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -264,7 +267,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase */ public function testBuildConfigWithDbAccess($host, $expectedUsername = null, $expectedPassword = null) { - $grabyConfigBuilderMock = $this->getMockBuilder('Graby\SiteConfig\ConfigBuilder') + $grabyConfigBuilderMock = $this->getMockBuilder(ConfigBuilder::class) ->disableOriginalConstructor() ->getMock(); @@ -281,7 +284,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase ->with($host) ->willReturn($grabySiteConfig); - $user = $this->getMockBuilder('Wallabag\UserBundle\Entity\User') + $user = $this->getMockBuilder(User::class) ->disableOriginalConstructor() ->getMock(); $user->expects($this->once()) @@ -300,7 +303,7 @@ class GrabySiteConfigBuilderTest extends WallabagCoreTestCase $builder = new GrabySiteConfigBuilder( $grabyConfigBuilderMock, $tokenStorage, - $this->getClient()->getContainer()->get('wallabag_core.site_credential_repository'), + $this->getClient()->getContainer()->get(SiteCredentialRepository::class), $logger ); diff --git a/tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php b/tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php index 54c992cc0..ef6e7aebe 100644 --- a/tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php +++ b/tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php @@ -28,7 +28,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -67,7 +67,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -106,7 +106,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -150,7 +150,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor->expects($this->once()) ->method('process'); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -195,7 +195,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor->expects($this->once()) ->method('process'); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -240,7 +240,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor->expects($this->once()) ->method('process'); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -284,7 +284,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor->expects($this->once()) ->method('process'); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -333,7 +333,7 @@ class ContentProxyTest extends TestCase ->method('validate') ->willReturn(new ConstraintViolationList([new ConstraintViolation('oops', 'oops', [], 'oops', 'language', 'dontexist')])); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -383,7 +383,7 @@ class ContentProxyTest extends TestCase new ConstraintViolationList([new ConstraintViolation('oops', 'oops', [], 'oops', 'url', 'https://')]) )); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -462,7 +462,7 @@ class ContentProxyTest extends TestCase $this->assertContains('no-cache', $entry->getHeaders()); } - public function testWithForcedContentAndDatetime() + public function testWithForcedContentAndDateTime() { $tagger = $this->getTaggerMock(); $tagger->expects($this->once()) @@ -635,7 +635,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -678,7 +678,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -717,7 +717,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -755,7 +755,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -793,7 +793,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -831,7 +831,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); @@ -870,7 +870,7 @@ class ContentProxyTest extends TestCase $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); - $graby = $this->getMockBuilder('Graby\Graby') + $graby = $this->getMockBuilder(Graby::class) ->setMethods(['fetchContent']) ->disableOriginalConstructor() ->getMock(); diff --git a/tests/Wallabag/CoreBundle/Helper/RedirectTest.php b/tests/Wallabag/CoreBundle/Helper/RedirectTest.php index 4a8864e3c..57a46dc14 100644 --- a/tests/Wallabag/CoreBundle/Helper/RedirectTest.php +++ b/tests/Wallabag/CoreBundle/Helper/RedirectTest.php @@ -3,6 +3,7 @@ namespace Tests\Wallabag\CoreBundle\Helper; use PHPUnit\Framework\TestCase; +use Symfony\Component\Routing\Router; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Wallabag\CoreBundle\Entity\Config; @@ -22,7 +23,7 @@ class RedirectTest extends TestCase protected function setUp(): void { - $this->routerMock = $this->getMockBuilder('Symfony\Component\Routing\Router') + $this->routerMock = $this->getMockBuilder(Router::class) ->disableOriginalConstructor() ->getMock(); diff --git a/tests/Wallabag/CoreBundle/Helper/RuleBasedIgnoreOriginProcessorTest.php b/tests/Wallabag/CoreBundle/Helper/RuleBasedIgnoreOriginProcessorTest.php index afe8502f7..4bd62ba4e 100644 --- a/tests/Wallabag/CoreBundle/Helper/RuleBasedIgnoreOriginProcessorTest.php +++ b/tests/Wallabag/CoreBundle/Helper/RuleBasedIgnoreOriginProcessorTest.php @@ -5,11 +5,13 @@ namespace Tests\Wallabag\CoreBundle\Helper; use Monolog\Handler\TestHandler; use Monolog\Logger; use PHPUnit\Framework\TestCase; +use RulerZ\RulerZ; use Wallabag\CoreBundle\Entity\Config; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\IgnoreOriginInstanceRule; use Wallabag\CoreBundle\Entity\IgnoreOriginUserRule; use Wallabag\CoreBundle\Helper\RuleBasedIgnoreOriginProcessor; +use Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository; use Wallabag\UserBundle\Entity\User; class RuleBasedIgnoreOriginProcessorTest extends TestCase @@ -193,14 +195,14 @@ class RuleBasedIgnoreOriginProcessorTest extends TestCase private function getRulerZMock() { - return $this->getMockBuilder('RulerZ\RulerZ') + return $this->getMockBuilder(RulerZ::class) ->disableOriginalConstructor() ->getMock(); } private function getIgnoreOriginInstanceRuleRepositoryMock() { - return $this->getMockBuilder('Wallabag\CoreBundle\Repository\IgnoreOriginInstanceRuleRepository') + return $this->getMockBuilder(IgnoreOriginInstanceRuleRepository::class) ->disableOriginalConstructor() ->getMock(); } diff --git a/tests/Wallabag/CoreBundle/Helper/RuleBasedTaggerTest.php b/tests/Wallabag/CoreBundle/Helper/RuleBasedTaggerTest.php index f85b8d07b..da11737ca 100644 --- a/tests/Wallabag/CoreBundle/Helper/RuleBasedTaggerTest.php +++ b/tests/Wallabag/CoreBundle/Helper/RuleBasedTaggerTest.php @@ -2,14 +2,19 @@ namespace Tests\Wallabag\CoreBundle\Helper; +use Doctrine\ORM\AbstractQuery; +use Doctrine\ORM\QueryBuilder; use Monolog\Handler\TestHandler; use Monolog\Logger; use PHPUnit\Framework\TestCase; +use RulerZ\RulerZ; use Wallabag\CoreBundle\Entity\Config; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Tag; use Wallabag\CoreBundle\Entity\TaggingRule; use Wallabag\CoreBundle\Helper\RuleBasedTagger; +use Wallabag\CoreBundle\Repository\EntryRepository; +use Wallabag\CoreBundle\Repository\TagRepository; use Wallabag\UserBundle\Entity\User; class RuleBasedTaggerTest extends TestCase @@ -202,7 +207,7 @@ class RuleBasedTaggerTest extends TestCase ->method('satisfies') ->willReturn(true); - $query = $this->getMockBuilder('Doctrine\ORM\AbstractQuery') + $query = $this->getMockBuilder(AbstractQuery::class) ->disableOriginalConstructor() ->getMock(); @@ -211,7 +216,7 @@ class RuleBasedTaggerTest extends TestCase ->method('getResult') ->willReturn([new Entry($user), new Entry($user)]); - $qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder') + $qb = $this->getMockBuilder(QueryBuilder::class) ->disableOriginalConstructor() ->getMock(); @@ -263,21 +268,21 @@ class RuleBasedTaggerTest extends TestCase private function getRulerZMock() { - return $this->getMockBuilder('RulerZ\RulerZ') + return $this->getMockBuilder(RulerZ::class) ->disableOriginalConstructor() ->getMock(); } private function getTagRepositoryMock() { - return $this->getMockBuilder('Wallabag\CoreBundle\Repository\TagRepository') + return $this->getMockBuilder(TagRepository::class) ->disableOriginalConstructor() ->getMock(); } private function getEntryRepositoryMock() { - return $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + return $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); } diff --git a/tests/Wallabag/CoreBundle/Mock/InstallCommandMock.php b/tests/Wallabag/CoreBundle/Mock/InstallCommandMock.php deleted file mode 100644 index 5806bd4d5..000000000 --- a/tests/Wallabag/CoreBundle/Mock/InstallCommandMock.php +++ /dev/null @@ -1,22 +0,0 @@ -getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + $registry = $this->getMockBuilder(ManagerRegistry::class) ->disableOriginalConstructor() ->getMock(); @@ -36,7 +41,7 @@ class UsernameFeedTokenConverterTest extends TestCase public function testSupportsWithNoConfigurationClass() { - $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + $registry = $this->getMockBuilder(ManagerRegistry::class) ->disableOriginalConstructor() ->getMock(); @@ -52,7 +57,7 @@ class UsernameFeedTokenConverterTest extends TestCase public function testSupportsWithNotTheGoodClass() { - $meta = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata') + $meta = $this->getMockBuilder(ClassMetadata::class) ->disableOriginalConstructor() ->getMock(); @@ -60,7 +65,7 @@ class UsernameFeedTokenConverterTest extends TestCase ->method('getName') ->willReturn('nothingrelated'); - $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager') + $em = $this->getMockBuilder(ObjectManager::class) ->disableOriginalConstructor() ->getMock(); @@ -69,7 +74,7 @@ class UsernameFeedTokenConverterTest extends TestCase ->with('superclass') ->willReturn($meta); - $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + $registry = $this->getMockBuilder(ManagerRegistry::class) ->disableOriginalConstructor() ->getMock(); @@ -90,24 +95,24 @@ class UsernameFeedTokenConverterTest extends TestCase public function testSupportsWithGoodClass() { - $meta = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata') + $meta = $this->getMockBuilder(ClassMetadata::class) ->disableOriginalConstructor() ->getMock(); $meta->expects($this->once()) ->method('getName') - ->willReturn('Wallabag\UserBundle\Entity\User'); + ->willReturn(User::class); - $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager') + $em = $this->getMockBuilder(ObjectManager::class) ->disableOriginalConstructor() ->getMock(); $em->expects($this->once()) ->method('getClassMetadata') - ->with('WallabagUserBundle:User') + ->with(User::class) ->willReturn($meta); - $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + $registry = $this->getMockBuilder(ManagerRegistry::class) ->disableOriginalConstructor() ->getMock(); @@ -117,10 +122,10 @@ class UsernameFeedTokenConverterTest extends TestCase $registry->expects($this->once()) ->method('getManagerForClass') - ->with('WallabagUserBundle:User') + ->with(User::class) ->willReturn($em); - $params = new ParamConverter(['class' => 'WallabagUserBundle:User']); + $params = new ParamConverter(['class' => User::class]); $converter = new UsernameFeedTokenConverter($registry); $this->assertTrue($converter->supports($params)); @@ -138,10 +143,10 @@ class UsernameFeedTokenConverterTest extends TestCase public function testApplyUserNotFound() { - $this->expectException(\Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class); + $this->expectException(NotFoundHttpException::class); $this->expectExceptionMessage('User not found'); - $repo = $this->getMockBuilder('Wallabag\UserBundle\Repository\UserRepository') + $repo = $this->getMockBuilder(UserRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -150,25 +155,25 @@ class UsernameFeedTokenConverterTest extends TestCase ->with('test', 'test') ->willReturn(null); - $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager') + $em = $this->getMockBuilder(ObjectManager::class) ->disableOriginalConstructor() ->getMock(); $em->expects($this->once()) ->method('getRepository') - ->with('WallabagUserBundle:User') + ->with(User::class) ->willReturn($repo); - $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + $registry = $this->getMockBuilder(ManagerRegistry::class) ->disableOriginalConstructor() ->getMock(); $registry->expects($this->once()) ->method('getManagerForClass') - ->with('WallabagUserBundle:User') + ->with(User::class) ->willReturn($em); - $params = new ParamConverter(['class' => 'WallabagUserBundle:User']); + $params = new ParamConverter(['class' => User::class]); $converter = new UsernameFeedTokenConverter($registry); $request = new Request([], [], ['username' => 'test', 'token' => 'test']); @@ -179,7 +184,7 @@ class UsernameFeedTokenConverterTest extends TestCase { $user = new User(); - $repo = $this->getMockBuilder('Wallabag\UserBundle\Repository\UserRepository') + $repo = $this->getMockBuilder(UserRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -188,25 +193,25 @@ class UsernameFeedTokenConverterTest extends TestCase ->with('test', 'test') ->willReturn($user); - $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager') + $em = $this->getMockBuilder(ObjectManager::class) ->disableOriginalConstructor() ->getMock(); $em->expects($this->once()) ->method('getRepository') - ->with('WallabagUserBundle:User') + ->with(User::class) ->willReturn($repo); - $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + $registry = $this->getMockBuilder(ManagerRegistry::class) ->disableOriginalConstructor() ->getMock(); $registry->expects($this->once()) ->method('getManagerForClass') - ->with('WallabagUserBundle:User') + ->with(User::class) ->willReturn($em); - $params = new ParamConverter(['class' => 'WallabagUserBundle:User', 'name' => 'user']); + $params = new ParamConverter(['class' => User::class, 'name' => 'user']); $converter = new UsernameFeedTokenConverter($registry); $request = new Request([], [], ['username' => 'test', 'token' => 'test']); diff --git a/tests/Wallabag/CoreBundle/Twig/WallabagExtensionTest.php b/tests/Wallabag/CoreBundle/Twig/WallabagExtensionTest.php index db02cb9cf..ddb4806b0 100644 --- a/tests/Wallabag/CoreBundle/Twig/WallabagExtensionTest.php +++ b/tests/Wallabag/CoreBundle/Twig/WallabagExtensionTest.php @@ -3,25 +3,29 @@ namespace Tests\Wallabag\CoreBundle\Twig; use PHPUnit\Framework\TestCase; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Translation\TranslatorInterface; +use Wallabag\CoreBundle\Repository\EntryRepository; +use Wallabag\CoreBundle\Repository\TagRepository; use Wallabag\CoreBundle\Twig\WallabagExtension; class WallabagExtensionTest extends TestCase { public function testRemoveWww() { - $entryRepository = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepository = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); - $tagRepository = $this->getMockBuilder('Wallabag\CoreBundle\Repository\TagRepository') + $tagRepository = $this->getMockBuilder(TagRepository::class) ->disableOriginalConstructor() ->getMock(); - $tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface') + $tokenStorage = $this->getMockBuilder(TokenStorageInterface::class) ->disableOriginalConstructor() ->getMock(); - $translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface') + $translator = $this->getMockBuilder(TranslatorInterface::class) ->disableOriginalConstructor() ->getMock(); @@ -34,19 +38,19 @@ class WallabagExtensionTest extends TestCase public function testRemoveScheme() { - $entryRepository = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepository = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); - $tagRepository = $this->getMockBuilder('Wallabag\CoreBundle\Repository\TagRepository') + $tagRepository = $this->getMockBuilder(TagRepository::class) ->disableOriginalConstructor() ->getMock(); - $tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface') + $tokenStorage = $this->getMockBuilder(TokenStorageInterface::class) ->disableOriginalConstructor() ->getMock(); - $translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface') + $translator = $this->getMockBuilder(TranslatorInterface::class) ->disableOriginalConstructor() ->getMock(); @@ -59,19 +63,19 @@ class WallabagExtensionTest extends TestCase public function testRemoveSchemeAndWww() { - $entryRepository = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepository = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); - $tagRepository = $this->getMockBuilder('Wallabag\CoreBundle\Repository\TagRepository') + $tagRepository = $this->getMockBuilder(TagRepository::class) ->disableOriginalConstructor() ->getMock(); - $tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface') + $tokenStorage = $this->getMockBuilder(TokenStorageInterface::class) ->disableOriginalConstructor() ->getMock(); - $translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface') + $translator = $this->getMockBuilder(TranslatorInterface::class) ->disableOriginalConstructor() ->getMock(); diff --git a/tests/Wallabag/CoreBundle/WallabagCoreTestCase.php b/tests/Wallabag/CoreBundle/WallabagCoreTestCase.php index a4cd83e4a..4098eb116 100644 --- a/tests/Wallabag/CoreBundle/WallabagCoreTestCase.php +++ b/tests/Wallabag/CoreBundle/WallabagCoreTestCase.php @@ -2,12 +2,15 @@ namespace Tests\Wallabag\CoreBundle; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Client; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\BrowserKit\Cookie; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; +use Symfony\Component\HttpFoundation\Session\SessionInterface; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Wallabag\CoreBundle\Entity\Config; use Wallabag\UserBundle\Entity\User; @@ -70,7 +73,7 @@ abstract class WallabagCoreTestCase extends WebTestCase public function getEntityManager() { - return $this->client->getContainer()->get('doctrine.orm.entity_manager'); + return $this->client->getContainer()->get(EntityManagerInterface::class); } /** @@ -82,7 +85,7 @@ abstract class WallabagCoreTestCase extends WebTestCase public function logInAs($username) { $container = $this->client->getContainer(); - $session = $container->get('session'); + $session = $container->get(SessionInterface::class); $userManager = $container->get('fos_user.user_manager.test'); $loginManager = $container->get('fos_user.security.login_manager.test'); @@ -96,7 +99,7 @@ abstract class WallabagCoreTestCase extends WebTestCase $loginManager->logInUser($firewallName, $user); - $session->set('_security_' . $firewallName, serialize($container->get('security.token_storage')->getToken())); + $session->set('_security_' . $firewallName, serialize($container->get(TokenStorageInterface::class)->getToken())); $session->save(); $cookie = new Cookie($session->getName(), $session->getId()); @@ -129,7 +132,7 @@ abstract class WallabagCoreTestCase extends WebTestCase */ public function getLoggedInUser() { - $token = static::$kernel->getContainer()->get('security.token_storage')->getToken(); + $token = static::$kernel->getContainer()->get(TokenStorageInterface::class)->getToken(); if (null !== $token) { return $token->getUser(); @@ -164,7 +167,7 @@ abstract class WallabagCoreTestCase extends WebTestCase protected function checkRedis() { try { - $this->client->getContainer()->get('wallabag_core.redis.client')->connect(); + $this->client->getContainer()->get(\Predis\Client::class)->connect(); } catch (\Exception $e) { $this->markTestSkipped('Redis is not installed/activated'); } diff --git a/tests/Wallabag/ImportBundle/Command/ImportCommandTest.php b/tests/Wallabag/ImportBundle/Command/ImportCommandTest.php index 1e1a38fd1..ec3df0f7a 100644 --- a/tests/Wallabag/ImportBundle/Command/ImportCommandTest.php +++ b/tests/Wallabag/ImportBundle/Command/ImportCommandTest.php @@ -2,42 +2,39 @@ namespace Tests\Wallabag\ImportBundle\Command; +use Doctrine\ORM\NoResultException; use Symfony\Bundle\FrameworkBundle\Console\Application; +use Symfony\Component\Config\Definition\Exception\Exception; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Tester\CommandTester; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; -use Wallabag\ImportBundle\Command\ImportCommand; class ImportCommandTest extends WallabagCoreTestCase { public function testRunImportCommandWithoutArguments() { - $this->expectException(\Symfony\Component\Console\Exception\RuntimeException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Not enough arguments'); $application = new Application($this->getClient()->getKernel()); - $application->add(new ImportCommand()); $command = $application->find('wallabag:import'); $tester = new CommandTester($command); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); } public function testRunImportCommandWithoutFilepath() { - $this->expectException(\Symfony\Component\Config\Definition\Exception\Exception::class); + $this->expectException(Exception::class); $this->expectExceptionMessage('not found'); $application = new Application($this->getClient()->getKernel()); - $application->add(new ImportCommand()); $command = $application->find('wallabag:import'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', 'filepath' => 1, ]); @@ -45,16 +42,14 @@ class ImportCommandTest extends WallabagCoreTestCase public function testRunImportCommandWithWrongUsername() { - $this->expectException(\Doctrine\ORM\NoResultException::class); + $this->expectException(NoResultException::class); $application = new Application($this->getClient()->getKernel()); - $application->add(new ImportCommand()); $command = $application->find('wallabag:import'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'random', 'filepath' => './', ]); @@ -63,13 +58,11 @@ class ImportCommandTest extends WallabagCoreTestCase public function testRunImportCommand() { $application = new Application($this->getClient()->getKernel()); - $application->add(new ImportCommand()); $command = $application->find('wallabag:import'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => 'admin', 'filepath' => $application->getKernel()->getContainer()->getParameter('kernel.project_dir') . '/tests/Wallabag/ImportBundle/fixtures/wallabag-v2-read.json', '--importer' => 'v2', @@ -84,13 +77,11 @@ class ImportCommandTest extends WallabagCoreTestCase $this->logInAs('admin'); $application = new Application($this->getClient()->getKernel()); - $application->add(new ImportCommand()); $command = $application->find('wallabag:import'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'username' => $this->getLoggedInUserId(), 'filepath' => $application->getKernel()->getContainer()->getParameter('kernel.project_dir') . '/tests/Wallabag/ImportBundle/fixtures/wallabag-v2-read.json', '--useUserId' => true, diff --git a/tests/Wallabag/ImportBundle/Command/RedisWorkerCommandTest.php b/tests/Wallabag/ImportBundle/Command/RedisWorkerCommandTest.php index 67ab757e2..aebeaab5d 100644 --- a/tests/Wallabag/ImportBundle/Command/RedisWorkerCommandTest.php +++ b/tests/Wallabag/ImportBundle/Command/RedisWorkerCommandTest.php @@ -3,42 +3,39 @@ namespace Tests\Wallabag\ImportBundle\Command; use M6Web\Component\RedisMock\RedisMockFactory; +use Predis\Client; use Symfony\Bundle\FrameworkBundle\Console\Application; +use Symfony\Component\Config\Definition\Exception\Exception; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Tester\CommandTester; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; -use Wallabag\ImportBundle\Command\RedisWorkerCommand; class RedisWorkerCommandTest extends WallabagCoreTestCase { public function testRunRedisWorkerCommandWithoutArguments() { - $this->expectException(\Symfony\Component\Console\Exception\RuntimeException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Not enough arguments (missing: "serviceName")'); $application = new Application($this->getClient()->getKernel()); - $application->add(new RedisWorkerCommand()); $command = $application->find('wallabag:import:redis-worker'); $tester = new CommandTester($command); - $tester->execute([ - 'command' => $command->getName(), - ]); + $tester->execute([]); } public function testRunRedisWorkerCommandWithBadService() { - $this->expectException(\Symfony\Component\Config\Definition\Exception\Exception::class); + $this->expectException(Exception::class); $this->expectExceptionMessage('No queue or consumer found for service name'); $application = new Application($this->getClient()->getKernel()); - $application->add(new RedisWorkerCommand()); $command = $application->find('wallabag:import:redis-worker'); $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'serviceName' => 'YOMONSERVICE', ]); } @@ -46,12 +43,11 @@ class RedisWorkerCommandTest extends WallabagCoreTestCase public function testRunRedisWorkerCommand() { $application = new Application($this->getClient()->getKernel()); - $application->add(new RedisWorkerCommand()); $factory = new RedisMockFactory(); - $redisMock = $factory->getAdapter('Predis\Client', true); + $redisMock = $factory->getAdapter(Client::class, true); - $application->getKernel()->getContainer()->set('wallabag_core.redis.client', $redisMock); + $application->getKernel()->getContainer()->set(Client::class, $redisMock); // put a fake message in the queue so the worker will stop after reading that message // instead of waiting for others @@ -61,7 +57,6 @@ class RedisWorkerCommandTest extends WallabagCoreTestCase $tester = new CommandTester($command); $tester->execute([ - 'command' => $command->getName(), 'serviceName' => 'readability', '--maxIterations' => 1, ]); diff --git a/tests/Wallabag/ImportBundle/Consumer/AMQPEntryConsumerTest.php b/tests/Wallabag/ImportBundle/Consumer/AMQPEntryConsumerTest.php index b7f6192d3..c02bb366f 100644 --- a/tests/Wallabag/ImportBundle/Consumer/AMQPEntryConsumerTest.php +++ b/tests/Wallabag/ImportBundle/Consumer/AMQPEntryConsumerTest.php @@ -2,17 +2,21 @@ namespace Tests\Wallabag\ImportBundle\Consumer; +use Doctrine\ORM\EntityManager; use PhpAmqpLib\Message\AMQPMessage; use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\EventDispatcher; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\ImportBundle\Consumer\AMQPEntryConsumer; +use Wallabag\ImportBundle\Import\AbstractImport; use Wallabag\UserBundle\Entity\User; +use Wallabag\UserBundle\Repository\UserRepository; class AMQPEntryConsumerTest extends TestCase { public function testMessageOk() { - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); @@ -87,7 +91,7 @@ JSON; $user = new User(); $entry = new Entry($user); - $userRepository = $this->getMockBuilder('Wallabag\UserBundle\Repository\UserRepository') + $userRepository = $this->getMockBuilder(UserRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -98,7 +102,7 @@ JSON; ->with(1) ->willReturn($user); - $import = $this->getMockBuilder('Wallabag\ImportBundle\Import\AbstractImport') + $import = $this->getMockBuilder(AbstractImport::class) ->disableOriginalConstructor() ->getMock(); @@ -113,7 +117,7 @@ JSON; ->with(json_decode($body, true)) ->willReturn($entry); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); @@ -135,7 +139,7 @@ JSON; public function testMessageWithBadUser() { - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); @@ -152,7 +156,7 @@ JSON; $user = new User(); $entry = new Entry($user); - $userRepository = $this->getMockBuilder('Wallabag\UserBundle\Repository\UserRepository') + $userRepository = $this->getMockBuilder(UserRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -163,11 +167,11 @@ JSON; ->with(123) ->willReturn(null); - $import = $this->getMockBuilder('Wallabag\ImportBundle\Import\AbstractImport') + $import = $this->getMockBuilder(AbstractImport::class) ->disableOriginalConstructor() ->getMock(); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); @@ -191,7 +195,7 @@ JSON; public function testMessageWithEntryProcessed() { - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); @@ -207,7 +211,7 @@ JSON; $user = new User(); - $userRepository = $this->getMockBuilder('Wallabag\UserBundle\Repository\UserRepository') + $userRepository = $this->getMockBuilder(UserRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -218,7 +222,7 @@ JSON; ->with(123) ->willReturn($user); - $import = $this->getMockBuilder('Wallabag\ImportBundle\Import\AbstractImport') + $import = $this->getMockBuilder(AbstractImport::class) ->disableOriginalConstructor() ->getMock(); @@ -233,7 +237,7 @@ JSON; ->with(json_decode($body, true)) ->willReturn(null); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); diff --git a/tests/Wallabag/ImportBundle/Consumer/RedisEntryConsumerTest.php b/tests/Wallabag/ImportBundle/Consumer/RedisEntryConsumerTest.php index e1bd88272..7213c27cc 100644 --- a/tests/Wallabag/ImportBundle/Consumer/RedisEntryConsumerTest.php +++ b/tests/Wallabag/ImportBundle/Consumer/RedisEntryConsumerTest.php @@ -2,16 +2,20 @@ namespace Tests\Wallabag\ImportBundle\Consumer; +use Doctrine\ORM\EntityManager; use PHPUnit\Framework\TestCase; +use Symfony\Component\EventDispatcher\EventDispatcher; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\ImportBundle\Consumer\RedisEntryConsumer; +use Wallabag\ImportBundle\Import\AbstractImport; use Wallabag\UserBundle\Entity\User; +use Wallabag\UserBundle\Repository\UserRepository; class RedisEntryConsumerTest extends TestCase { public function testMessageOk() { - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); @@ -86,7 +90,7 @@ JSON; $user = new User(); $entry = new Entry($user); - $userRepository = $this->getMockBuilder('Wallabag\UserBundle\Repository\UserRepository') + $userRepository = $this->getMockBuilder(UserRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -97,7 +101,7 @@ JSON; ->with(1) ->willReturn($user); - $import = $this->getMockBuilder('Wallabag\ImportBundle\Import\AbstractImport') + $import = $this->getMockBuilder(AbstractImport::class) ->disableOriginalConstructor() ->getMock(); @@ -112,7 +116,7 @@ JSON; ->with(json_decode($body, true)) ->willReturn($entry); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); @@ -134,7 +138,7 @@ JSON; public function testMessageWithBadUser() { - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); @@ -151,7 +155,7 @@ JSON; $user = new User(); $entry = new Entry($user); - $userRepository = $this->getMockBuilder('Wallabag\UserBundle\Repository\UserRepository') + $userRepository = $this->getMockBuilder(UserRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -162,11 +166,11 @@ JSON; ->with(123) ->willReturn(null); - $import = $this->getMockBuilder('Wallabag\ImportBundle\Import\AbstractImport') + $import = $this->getMockBuilder(AbstractImport::class) ->disableOriginalConstructor() ->getMock(); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); @@ -188,7 +192,7 @@ JSON; public function testMessageWithEntryProcessed() { - $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); @@ -204,7 +208,7 @@ JSON; $user = new User(); - $userRepository = $this->getMockBuilder('Wallabag\UserBundle\Repository\UserRepository') + $userRepository = $this->getMockBuilder(UserRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -215,7 +219,7 @@ JSON; ->with(123) ->willReturn($user); - $import = $this->getMockBuilder('Wallabag\ImportBundle\Import\AbstractImport') + $import = $this->getMockBuilder(AbstractImport::class) ->disableOriginalConstructor() ->getMock(); @@ -230,7 +234,7 @@ JSON; ->with(json_decode($body, true)) ->willReturn(null); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); diff --git a/tests/Wallabag/ImportBundle/Controller/ChromeControllerTest.php b/tests/Wallabag/ImportBundle/Controller/ChromeControllerTest.php index 50f2a6383..997318e6a 100644 --- a/tests/Wallabag/ImportBundle/Controller/ChromeControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/ChromeControllerTest.php @@ -2,8 +2,12 @@ namespace Tests\Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; +use Predis\Client; use Symfony\Component\HttpFoundation\File\UploadedFile; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\CoreBundle\Entity\Entry; class ChromeControllerTest extends WallabagCoreTestCase { @@ -24,7 +28,7 @@ class ChromeControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1); $crawler = $client->request('GET', '/import/chrome'); @@ -32,7 +36,7 @@ class ChromeControllerTest extends WallabagCoreTestCase $this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count()); $this->assertSame(1, $crawler->filter('input[type=file]')->count()); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0); } public function testImportChromeBadFile() @@ -57,7 +61,7 @@ class ChromeControllerTest extends WallabagCoreTestCase $this->checkRedis(); $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_redis', 1); + $client->getContainer()->get(Config::class)->set('import_with_redis', 1); $crawler = $client->request('GET', '/import/chrome'); @@ -82,9 +86,9 @@ class ChromeControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertNotEmpty($client->getContainer()->get('wallabag_core.redis.client')->lpop('wallabag.import.chrome')); + $this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.chrome')); - $client->getContainer()->get('craue_config')->set('import_with_redis', 0); + $client->getContainer()->get(Config::class)->set('import_with_redis', 0); } public function testImportWallabagWithChromeFile() @@ -111,14 +115,14 @@ class ChromeControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://www.20minutes.fr/sport/3256363-20220321-tournoi-vi-nations-trophee-gagne-xv-france-fini-fond-seine', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.20minutes.fr is ok'); $this->assertNotEmpty($content->getLanguage(), 'Language for https://www.20minutes.fr is ok'); $this->assertCount(1, $content->getTags()); diff --git a/tests/Wallabag/ImportBundle/Controller/DeliciousControllerTest.php b/tests/Wallabag/ImportBundle/Controller/DeliciousControllerTest.php index 1d14d1d8a..bb710b18f 100644 --- a/tests/Wallabag/ImportBundle/Controller/DeliciousControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/DeliciousControllerTest.php @@ -2,8 +2,12 @@ namespace Tests\Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; +use Predis\Client; use Symfony\Component\HttpFoundation\File\UploadedFile; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\CoreBundle\Entity\Entry; class DeliciousControllerTest extends WallabagCoreTestCase { @@ -24,7 +28,7 @@ class DeliciousControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1); $crawler = $client->request('GET', '/import/delicious'); @@ -32,7 +36,7 @@ class DeliciousControllerTest extends WallabagCoreTestCase $this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count()); $this->assertSame(1, $crawler->filter('input[type=file]')->count()); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0); } public function testImportDeliciousBadFile() @@ -57,7 +61,7 @@ class DeliciousControllerTest extends WallabagCoreTestCase $this->checkRedis(); $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_redis', 1); + $client->getContainer()->get(Config::class)->set('import_with_redis', 1); $crawler = $client->request('GET', '/import/delicious'); @@ -82,9 +86,9 @@ class DeliciousControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertNotEmpty($client->getContainer()->get('wallabag_core.redis.client')->lpop('wallabag.import.delicious')); + $this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.delicious')); - $client->getContainer()->get('craue_config')->set('import_with_redis', 0); + $client->getContainer()->get(Config::class)->set('import_with_redis', 0); } public function testImportDeliciousWithFile() @@ -108,8 +112,8 @@ class DeliciousControllerTest extends WallabagCoreTestCase $crawler = $client->followRedirect(); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://feross.org/spoofmac/', $this->getLoggedInUserId() @@ -118,7 +122,7 @@ class DeliciousControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $tags = $content->getTagsLabel(); $this->assertContains('osx', $tags, 'It includes the "osx" tag'); @@ -150,24 +154,24 @@ class DeliciousControllerTest extends WallabagCoreTestCase $crawler = $client->followRedirect(); $content1 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://stackoverflow.com/review/', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content1); + $this->assertInstanceOf(Entry::class, $content1); $content2 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://addyosmani.com/basket.js/', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content2); + $this->assertInstanceOf(Entry::class, $content2); $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); diff --git a/tests/Wallabag/ImportBundle/Controller/ElcuratorControllerTest.php b/tests/Wallabag/ImportBundle/Controller/ElcuratorControllerTest.php index a3dfe1750..188d2798e 100644 --- a/tests/Wallabag/ImportBundle/Controller/ElcuratorControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/ElcuratorControllerTest.php @@ -2,8 +2,12 @@ namespace Tests\Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; +use Predis\Client; use Symfony\Component\HttpFoundation\File\UploadedFile; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\CoreBundle\Entity\Entry; class ElcuratorControllerTest extends WallabagCoreTestCase { @@ -24,7 +28,7 @@ class ElcuratorControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1); $crawler = $client->request('GET', '/import/elcurator'); @@ -32,7 +36,7 @@ class ElcuratorControllerTest extends WallabagCoreTestCase $this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count()); $this->assertSame(1, $crawler->filter('input[type=file]')->count()); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0); } public function testImportElcuratorBadFile() @@ -58,7 +62,7 @@ class ElcuratorControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_redis', 1); + $client->getContainer()->get(Config::class)->set('import_with_redis', 1); $crawler = $client->request('GET', '/import/elcurator'); @@ -83,9 +87,9 @@ class ElcuratorControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertNotEmpty($client->getContainer()->get('wallabag_core.redis.client')->lpop('wallabag.import.elcurator')); + $this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.elcurator')); - $client->getContainer()->get('craue_config')->set('import_with_redis', 0); + $client->getContainer()->get(Config::class)->set('import_with_redis', 0); } public function testImportElcuratorWithFile() @@ -112,14 +116,14 @@ class ElcuratorControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://devblog.lexik.fr/git/qualite-de-code-integration-de-php-git-hooks-dans-symfony2-2842', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $this->assertStringContainsString('Qualité de code - Intégration de php-git-hooks dans Symfony2', $content->getTitle()); $this->assertSame('2015-09-09', $content->getCreatedAt()->format('Y-m-d')); diff --git a/tests/Wallabag/ImportBundle/Controller/FirefoxControllerTest.php b/tests/Wallabag/ImportBundle/Controller/FirefoxControllerTest.php index b8d201e41..ff1d602e9 100644 --- a/tests/Wallabag/ImportBundle/Controller/FirefoxControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/FirefoxControllerTest.php @@ -2,8 +2,12 @@ namespace Tests\Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; +use Predis\Client; use Symfony\Component\HttpFoundation\File\UploadedFile; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\CoreBundle\Entity\Entry; class FirefoxControllerTest extends WallabagCoreTestCase { @@ -24,7 +28,7 @@ class FirefoxControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1); $crawler = $client->request('GET', '/import/firefox'); @@ -32,7 +36,7 @@ class FirefoxControllerTest extends WallabagCoreTestCase $this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count()); $this->assertSame(1, $crawler->filter('input[type=file]')->count()); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0); } public function testImportFirefoxBadFile() @@ -57,7 +61,7 @@ class FirefoxControllerTest extends WallabagCoreTestCase $this->checkRedis(); $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_redis', 1); + $client->getContainer()->get(Config::class)->set('import_with_redis', 1); $crawler = $client->request('GET', '/import/firefox'); @@ -82,9 +86,9 @@ class FirefoxControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertNotEmpty($client->getContainer()->get('wallabag_core.redis.client')->lpop('wallabag.import.firefox')); + $this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.firefox')); - $client->getContainer()->get('craue_config')->set('import_with_redis', 0); + $client->getContainer()->get(Config::class)->set('import_with_redis', 0); } public function testImportWallabagWithFirefoxFile() @@ -111,28 +115,28 @@ class FirefoxControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://www.20minutes.fr/sport/4002755-20220928-tarn-lapins-ravagent-terrain-match-rugby-doit-etre-annule', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); - $this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.20minutes.fr is ok'); - $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.20minutes.fr is ok'); - $this->assertNotEmpty($content->getLanguage(), 'Language for https://www.20minutes.fr is ok'); + $this->assertInstanceOf(Entry::class, $content); + $this->assertNotEmpty($content->getMimetype(), 'Mimetype for http://lexpansion.lexpress.fr is ok'); + $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for http://lexpansion.lexpress.fr is ok'); + $this->assertNotEmpty($content->getLanguage(), 'Language for http://lexpansion.lexpress.fr is ok'); $this->assertCount(3, $content->getTags()); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://www.lemonde.fr/disparitions/article/2018/07/05/le-journaliste-et-cineaste-claude-lanzmann-est-mort_5326313_3382.html', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.lemonde.fr is ok'); $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.lemonde.fr is ok'); $this->assertNotEmpty($content->getLanguage(), 'Language for https://www.lemonde.fr is ok'); diff --git a/tests/Wallabag/ImportBundle/Controller/InstapaperControllerTest.php b/tests/Wallabag/ImportBundle/Controller/InstapaperControllerTest.php index 94aa3c664..8a1616564 100644 --- a/tests/Wallabag/ImportBundle/Controller/InstapaperControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/InstapaperControllerTest.php @@ -2,8 +2,12 @@ namespace Tests\Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; +use Predis\Client; use Symfony\Component\HttpFoundation\File\UploadedFile; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\CoreBundle\Entity\Entry; class InstapaperControllerTest extends WallabagCoreTestCase { @@ -24,7 +28,7 @@ class InstapaperControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1); $crawler = $client->request('GET', '/import/instapaper'); @@ -32,7 +36,7 @@ class InstapaperControllerTest extends WallabagCoreTestCase $this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count()); $this->assertSame(1, $crawler->filter('input[type=file]')->count()); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0); } public function testImportInstapaperBadFile() @@ -57,7 +61,7 @@ class InstapaperControllerTest extends WallabagCoreTestCase $this->checkRedis(); $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_redis', 1); + $client->getContainer()->get(Config::class)->set('import_with_redis', 1); $crawler = $client->request('GET', '/import/instapaper'); @@ -82,9 +86,9 @@ class InstapaperControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertNotEmpty($client->getContainer()->get('wallabag_core.redis.client')->lpop('wallabag.import.instapaper')); + $this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.instapaper')); - $client->getContainer()->get('craue_config')->set('import_with_redis', 0); + $client->getContainer()->get(Config::class)->set('import_with_redis', 0); } public function testImportInstapaperWithFile() @@ -111,14 +115,14 @@ class InstapaperControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://www.liberation.fr/societe/police-justice/cours-dassises-on-efface-le-peuple-dun-processus-judiciaire-dont-il-est-pourtant-le-coeur-battant-20210414_FYUNIZENHRGHZLAZEKSMKZYEPI/', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.liberation.fr is ok'); $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.liberation.fr is ok'); @@ -128,8 +132,8 @@ class InstapaperControllerTest extends WallabagCoreTestCase $this->assertInstanceOf(\DateTime::class, $content->getCreatedAt()); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://www.20minutes.fr/high-tech/2077615-20170531-quoi-exactement-tweet-covfefe-donald-trump-persiste-signe', $this->getLoggedInUserId() @@ -163,8 +167,8 @@ class InstapaperControllerTest extends WallabagCoreTestCase $crawler = $client->followRedirect(); $content1 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://redditblog.com/2016/09/20/amp-and-reactredux/', $this->getLoggedInUserId() @@ -173,8 +177,8 @@ class InstapaperControllerTest extends WallabagCoreTestCase $this->assertTrue($content1->isArchived()); $content2 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://medium.com/@the_minh/why-foursquare-swarm-is-still-my-favourite-social-network-e38228493e6c', $this->getLoggedInUserId() diff --git a/tests/Wallabag/ImportBundle/Controller/PinboardControllerTest.php b/tests/Wallabag/ImportBundle/Controller/PinboardControllerTest.php index 076dd7f97..ce030e471 100644 --- a/tests/Wallabag/ImportBundle/Controller/PinboardControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/PinboardControllerTest.php @@ -2,8 +2,12 @@ namespace Tests\Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; +use Predis\Client; use Symfony\Component\HttpFoundation\File\UploadedFile; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\CoreBundle\Entity\Entry; class PinboardControllerTest extends WallabagCoreTestCase { @@ -24,7 +28,7 @@ class PinboardControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1); $crawler = $client->request('GET', '/import/pinboard'); @@ -32,7 +36,7 @@ class PinboardControllerTest extends WallabagCoreTestCase $this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count()); $this->assertSame(1, $crawler->filter('input[type=file]')->count()); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0); } public function testImportPinboardBadFile() @@ -57,7 +61,7 @@ class PinboardControllerTest extends WallabagCoreTestCase $this->checkRedis(); $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_redis', 1); + $client->getContainer()->get(Config::class)->set('import_with_redis', 1); $crawler = $client->request('GET', '/import/pinboard'); @@ -82,9 +86,9 @@ class PinboardControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertNotEmpty($client->getContainer()->get('wallabag_core.redis.client')->lpop('wallabag.import.pinboard')); + $this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.pinboard')); - $client->getContainer()->get('craue_config')->set('import_with_redis', 0); + $client->getContainer()->get(Config::class)->set('import_with_redis', 0); } public function testImportPinboardWithFile() @@ -108,8 +112,8 @@ class PinboardControllerTest extends WallabagCoreTestCase $crawler = $client->followRedirect(); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://ma.ttias.be/varnish-explained/', $this->getLoggedInUserId() @@ -118,7 +122,7 @@ class PinboardControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://ma.ttias.be is ok'); $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://ma.ttias.be is ok'); $this->assertNotEmpty($content->getLanguage(), 'Language for https://ma.ttias.be is ok'); @@ -155,25 +159,25 @@ class PinboardControllerTest extends WallabagCoreTestCase $crawler = $client->followRedirect(); $content1 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://ilia.ws/files/nginx_torontophpug.pdf', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content1); + $this->assertInstanceOf(Entry::class, $content1); $this->assertTrue($content1->isArchived()); $content2 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://developers.google.com/web/updates/2016/07/infinite-scroller', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content2); + $this->assertInstanceOf(Entry::class, $content2); $this->assertTrue($content2->isArchived()); $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); diff --git a/tests/Wallabag/ImportBundle/Controller/PocketControllerTest.php b/tests/Wallabag/ImportBundle/Controller/PocketControllerTest.php index bc66ad734..1bd57a62b 100644 --- a/tests/Wallabag/ImportBundle/Controller/PocketControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/PocketControllerTest.php @@ -2,7 +2,10 @@ namespace Tests\Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\ImportBundle\Import\PocketImport; class PocketControllerTest extends WallabagCoreTestCase { @@ -22,14 +25,14 @@ class PocketControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1); $crawler = $client->request('GET', '/import/pocket'); $this->assertSame(200, $client->getResponse()->getStatusCode()); $this->assertSame(1, $crawler->filter('button[name=action]')->count()); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0); } public function testImportPocketWithRedisEnabled() @@ -38,14 +41,14 @@ class PocketControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_redis', 1); + $client->getContainer()->get(Config::class)->set('import_with_redis', 1); $crawler = $client->request('GET', '/import/pocket'); $this->assertSame(200, $client->getResponse()->getStatusCode()); $this->assertSame(1, $crawler->filter('button[name=action]')->count()); - $client->getContainer()->get('craue_config')->set('import_with_redis', 0); + $client->getContainer()->get(Config::class)->set('import_with_redis', 0); } public function testImportPocketAuthBadToken() @@ -63,7 +66,7 @@ class PocketControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $pocketImport = $this->getMockBuilder('Wallabag\ImportBundle\Import\PocketImport') + $pocketImport = $this->getMockBuilder(PocketImport::class) ->disableOriginalConstructor() ->getMock(); @@ -72,7 +75,7 @@ class PocketControllerTest extends WallabagCoreTestCase ->method('getRequestToken') ->willReturn('token'); - static::$kernel->getContainer()->set('wallabag_import.pocket.import', $pocketImport); + static::$kernel->getContainer()->set(PocketImport::class, $pocketImport); $client->request('GET', '/import/pocket/auth'); @@ -85,7 +88,7 @@ class PocketControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $pocketImport = $this->getMockBuilder('Wallabag\ImportBundle\Import\PocketImport') + $pocketImport = $this->getMockBuilder(PocketImport::class) ->disableOriginalConstructor() ->getMock(); @@ -94,13 +97,13 @@ class PocketControllerTest extends WallabagCoreTestCase ->method('authorize') ->willReturn(false); - static::$kernel->getContainer()->set('wallabag_import.pocket.import', $pocketImport); + static::$kernel->getContainer()->set(PocketImport::class, $pocketImport); $client->request('GET', '/import/pocket/callback'); $this->assertSame(302, $client->getResponse()->getStatusCode()); $this->assertStringContainsString('/', $client->getResponse()->headers->get('location'), 'Import is ok, redirect to homepage'); - $this->assertSame('flashes.import.notice.failed', $client->getContainer()->get('session')->getFlashBag()->peek('notice')[0]); + $this->assertSame('flashes.import.notice.failed', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->peek('notice')[0]); } public function testImportPocketCallback() @@ -108,7 +111,7 @@ class PocketControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $pocketImport = $this->getMockBuilder('Wallabag\ImportBundle\Import\PocketImport') + $pocketImport = $this->getMockBuilder(PocketImport::class) ->disableOriginalConstructor() ->getMock(); @@ -128,12 +131,12 @@ class PocketControllerTest extends WallabagCoreTestCase ->method('import') ->willReturn(true); - static::$kernel->getContainer()->set('wallabag_import.pocket.import', $pocketImport); + static::$kernel->getContainer()->set(PocketImport::class, $pocketImport); $client->request('GET', '/import/pocket/callback'); $this->assertSame(302, $client->getResponse()->getStatusCode()); $this->assertStringContainsString('/', $client->getResponse()->headers->get('location'), 'Import is ok, redirect to homepage'); - $this->assertSame('flashes.import.notice.summary', $client->getContainer()->get('session')->getFlashBag()->peek('notice')[0]); + $this->assertSame('flashes.import.notice.summary', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->peek('notice')[0]); } } diff --git a/tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php b/tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php index 8cd358e73..75134a247 100644 --- a/tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php @@ -2,8 +2,12 @@ namespace Tests\Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; +use Predis\Client; use Symfony\Component\HttpFoundation\File\UploadedFile; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\CoreBundle\Entity\Entry; class ReadabilityControllerTest extends WallabagCoreTestCase { @@ -24,7 +28,7 @@ class ReadabilityControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1); $crawler = $client->request('GET', '/import/readability'); @@ -32,7 +36,7 @@ class ReadabilityControllerTest extends WallabagCoreTestCase $this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count()); $this->assertSame(1, $crawler->filter('input[type=file]')->count()); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0); } public function testImportReadabilityBadFile() @@ -57,7 +61,7 @@ class ReadabilityControllerTest extends WallabagCoreTestCase $this->checkRedis(); $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_redis', 1); + $client->getContainer()->get(Config::class)->set('import_with_redis', 1); $crawler = $client->request('GET', '/import/readability'); @@ -82,9 +86,9 @@ class ReadabilityControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertNotEmpty($client->getContainer()->get('wallabag_core.redis.client')->lpop('wallabag.import.readability')); + $this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.readability')); - $client->getContainer()->get('craue_config')->set('import_with_redis', 0); + $client->getContainer()->get(Config::class)->set('import_with_redis', 0); } public function testImportReadabilityWithFile() @@ -108,8 +112,8 @@ class ReadabilityControllerTest extends WallabagCoreTestCase $crawler = $client->followRedirect(); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://www.20minutes.fr/bordeaux/2120479-20170823-bordeaux-poche-chocolatine-association-traduit-etudiants-etrangers-mots-sud-ouest', $this->getLoggedInUserId() @@ -118,7 +122,7 @@ class ReadabilityControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.20minutes.fr is ok'); $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.20minutes.fr is ok'); $this->assertNotEmpty($content->getLanguage(), 'Language for https://www.20minutes.fr is ok'); @@ -153,25 +157,25 @@ class ReadabilityControllerTest extends WallabagCoreTestCase $crawler = $client->followRedirect(); $content1 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://blog.travis-ci.com/2016-07-28-what-we-learned-from-analyzing-2-million-travis-builds/', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content1); + $this->assertInstanceOf(Entry::class, $content1); $this->assertTrue($content1->isArchived()); $content2 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://facebook.github.io/graphql/October2016/', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content2); + $this->assertInstanceOf(Entry::class, $content2); $this->assertTrue($content2->isArchived()); $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); diff --git a/tests/Wallabag/ImportBundle/Controller/WallabagV1ControllerTest.php b/tests/Wallabag/ImportBundle/Controller/WallabagV1ControllerTest.php index 373c5cdd1..0fa171f66 100644 --- a/tests/Wallabag/ImportBundle/Controller/WallabagV1ControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/WallabagV1ControllerTest.php @@ -2,8 +2,12 @@ namespace Tests\Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; +use Predis\Client; use Symfony\Component\HttpFoundation\File\UploadedFile; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\CoreBundle\Entity\Entry; class WallabagV1ControllerTest extends WallabagCoreTestCase { @@ -24,7 +28,7 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1); $crawler = $client->request('GET', '/import/wallabag-v1'); @@ -32,7 +36,7 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase $this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count()); $this->assertSame(1, $crawler->filter('input[type=file]')->count()); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0); } public function testImportWallabagBadFile() @@ -58,7 +62,7 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_redis', 1); + $client->getContainer()->get(Config::class)->set('import_with_redis', 1); $crawler = $client->request('GET', '/import/wallabag-v1'); @@ -83,9 +87,9 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertNotEmpty($client->getContainer()->get('wallabag_core.redis.client')->lpop('wallabag.import.wallabag_v1')); + $this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.wallabag_v1')); - $client->getContainer()->get('craue_config')->set('import_with_redis', 0); + $client->getContainer()->get(Config::class)->set('import_with_redis', 0); } public function testImportWallabagWithFile() @@ -109,8 +113,8 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase $crawler = $client->followRedirect(); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'http://www.framablog.org/index.php/post/2014/02/05/Framabag-service-libre-gratuit-interview-developpeur', $this->getLoggedInUserId() @@ -119,7 +123,7 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $this->assertEmpty($content->getMimetype(), 'Mimetype for http://www.framablog.org is empty'); $this->assertSame($content->getPreviewPicture(), 'http://www.framablog.org/public/_img/framablog/wallaby_baby.jpg'); $this->assertEmpty($content->getLanguage(), 'Language for http://www.framablog.org is empty'); @@ -154,25 +158,25 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase $crawler = $client->followRedirect(); $content1 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'http://gilbert.pellegrom.me/recreating-the-square-slider', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content1); + $this->assertInstanceOf(Entry::class, $content1); $this->assertTrue($content1->isArchived()); $content2 = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://www.wallabag.org/features/', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content2); + $this->assertInstanceOf(Entry::class, $content2); $this->assertTrue($content2->isArchived()); $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); diff --git a/tests/Wallabag/ImportBundle/Controller/WallabagV2ControllerTest.php b/tests/Wallabag/ImportBundle/Controller/WallabagV2ControllerTest.php index 220415215..31824f437 100644 --- a/tests/Wallabag/ImportBundle/Controller/WallabagV2ControllerTest.php +++ b/tests/Wallabag/ImportBundle/Controller/WallabagV2ControllerTest.php @@ -2,8 +2,12 @@ namespace Tests\Wallabag\ImportBundle\Controller; +use Craue\ConfigBundle\Util\Config; +use Doctrine\ORM\EntityManagerInterface; +use Predis\Client; use Symfony\Component\HttpFoundation\File\UploadedFile; use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; +use Wallabag\CoreBundle\Entity\Entry; class WallabagV2ControllerTest extends WallabagCoreTestCase { @@ -24,7 +28,7 @@ class WallabagV2ControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1); $crawler = $client->request('GET', '/import/wallabag-v2'); @@ -32,7 +36,7 @@ class WallabagV2ControllerTest extends WallabagCoreTestCase $this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count()); $this->assertSame(1, $crawler->filter('input[type=file]')->count()); - $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0); + $client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0); } public function testImportWallabagBadFile() @@ -58,7 +62,7 @@ class WallabagV2ControllerTest extends WallabagCoreTestCase $this->logInAs('admin'); $client = $this->getClient(); - $client->getContainer()->get('craue_config')->set('import_with_redis', 1); + $client->getContainer()->get(Config::class)->set('import_with_redis', 1); $crawler = $client->request('GET', '/import/wallabag-v2'); @@ -83,9 +87,9 @@ class WallabagV2ControllerTest extends WallabagCoreTestCase $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); - $this->assertNotEmpty($client->getContainer()->get('wallabag_core.redis.client')->lpop('wallabag.import.wallabag_v2')); + $this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.wallabag_v2')); - $client->getContainer()->get('craue_config')->set('import_with_redis', 0); + $client->getContainer()->get(Config::class)->set('import_with_redis', 0); } public function testImportWallabagWithFile() @@ -112,14 +116,14 @@ class WallabagV2ControllerTest extends WallabagCoreTestCase $this->assertStringContainsString('flashes.import.notice.summary', $body[0]); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://www.liberation.fr/planete/2015/10/26/refugies-l-ue-va-creer-100-000-places-d-accueil-dans-les-balkans_1408867', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); // empty because it wasn't re-imported $this->assertEmpty($content->getMimetype(), 'Mimetype for https://www.liberation.fr is empty'); @@ -131,14 +135,14 @@ class WallabagV2ControllerTest extends WallabagCoreTestCase $this->assertCount(1, $tags); $content = $client->getContainer() - ->get('doctrine.orm.entity_manager') - ->getRepository('WallabagCoreBundle:Entry') + ->get(EntityManagerInterface::class) + ->getRepository(Entry::class) ->findByUrlAndUserId( 'https://www.mediapart.fr/', $this->getLoggedInUserId() ); - $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertInstanceOf(Entry::class, $content); $this->assertNotEmpty($content->getMimetype(), 'Mimetype for https://www.mediapart.fr is ok'); $this->assertNotEmpty($content->getPreviewPicture(), 'Preview picture for https://www.mediapart.fr is ok'); $this->assertNotEmpty($content->getLanguage(), 'Language for https://www.mediapart.fr is ok'); diff --git a/tests/Wallabag/ImportBundle/Import/ChromeImportTest.php b/tests/Wallabag/ImportBundle/Import/ChromeImportTest.php index 3b4adbb53..2829466c0 100644 --- a/tests/Wallabag/ImportBundle/Import/ChromeImportTest.php +++ b/tests/Wallabag/ImportBundle/Import/ChromeImportTest.php @@ -2,12 +2,18 @@ namespace Tests\Wallabag\ImportBundle\Import; +use Doctrine\ORM\EntityManager; use M6Web\Component\RedisMock\RedisMockFactory; use Monolog\Handler\TestHandler; use Monolog\Logger; use PHPUnit\Framework\TestCase; +use Predis\Client; use Simpleue\Queue\RedisQueue; +use Symfony\Component\EventDispatcher\EventDispatcher; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Helper\TagsAssigner; +use Wallabag\CoreBundle\Repository\EntryRepository; use Wallabag\ImportBundle\Import\ChromeImport; use Wallabag\ImportBundle\Redis\Producer; use Wallabag\UserBundle\Entity\User; @@ -34,7 +40,7 @@ class ChromeImportTest extends TestCase $chromeImport = $this->getChromeImport(false, 1); $chromeImport->setFilepath(__DIR__ . '/../fixtures/chrome-bookmarks'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -47,7 +53,7 @@ class ChromeImportTest extends TestCase ->method('getRepository') ->willReturn($entryRepo); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -67,7 +73,7 @@ class ChromeImportTest extends TestCase $chromeImport = $this->getChromeImport(false, 1); $chromeImport->setFilepath(__DIR__ . '/../fixtures/chrome-bookmarks'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -105,7 +111,7 @@ class ChromeImportTest extends TestCase $chromeImport = $this->getChromeImport(); $chromeImport->setFilepath(__DIR__ . '/../fixtures/chrome-bookmarks'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -116,7 +122,7 @@ class ChromeImportTest extends TestCase ->expects($this->never()) ->method('getRepository'); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -124,7 +130,7 @@ class ChromeImportTest extends TestCase ->expects($this->never()) ->method('updateEntry'); - $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer') + $producer = $this->getMockBuilder(\OldSound\RabbitMqBundle\RabbitMq\Producer::class) ->disableOriginalConstructor() ->getMock(); @@ -145,7 +151,7 @@ class ChromeImportTest extends TestCase $chromeImport = $this->getChromeImport(); $chromeImport->setFilepath(__DIR__ . '/../fixtures/chrome-bookmarks'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -156,7 +162,7 @@ class ChromeImportTest extends TestCase ->expects($this->never()) ->method('getRepository'); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -165,7 +171,7 @@ class ChromeImportTest extends TestCase ->method('updateEntry'); $factory = new RedisMockFactory(); - $redisMock = $factory->getAdapter('Predis\Client', true); + $redisMock = $factory->getAdapter(Client::class, true); $queue = new RedisQueue($redisMock, 'chrome'); $producer = new Producer($queue); @@ -212,19 +218,19 @@ class ChromeImportTest extends TestCase { $this->user = new User(); - $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $this->em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); - $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') + $this->contentProxy = $this->getMockBuilder(ContentProxy::class) ->disableOriginalConstructor() ->getMock(); - $this->tagsAssigner = $this->getMockBuilder('Wallabag\CoreBundle\Helper\TagsAssigner') + $this->tagsAssigner = $this->getMockBuilder(TagsAssigner::class) ->disableOriginalConstructor() ->getMock(); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); @@ -232,11 +238,10 @@ class ChromeImportTest extends TestCase ->expects($this->exactly($dispatched)) ->method('dispatch'); - $wallabag = new ChromeImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher); - $this->logHandler = new TestHandler(); $logger = new Logger('test', [$this->logHandler]); - $wallabag->setLogger($logger); + + $wallabag = new ChromeImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher, $logger); if (false === $unsetUser) { $wallabag->setUser($this->user); diff --git a/tests/Wallabag/ImportBundle/Import/FirefoxImportTest.php b/tests/Wallabag/ImportBundle/Import/FirefoxImportTest.php index 69d7d4fb5..362c2ee05 100644 --- a/tests/Wallabag/ImportBundle/Import/FirefoxImportTest.php +++ b/tests/Wallabag/ImportBundle/Import/FirefoxImportTest.php @@ -2,12 +2,18 @@ namespace Tests\Wallabag\ImportBundle\Import; +use Doctrine\ORM\EntityManager; use M6Web\Component\RedisMock\RedisMockFactory; use Monolog\Handler\TestHandler; use Monolog\Logger; use PHPUnit\Framework\TestCase; +use Predis\Client; use Simpleue\Queue\RedisQueue; +use Symfony\Component\EventDispatcher\EventDispatcher; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Helper\TagsAssigner; +use Wallabag\CoreBundle\Repository\EntryRepository; use Wallabag\ImportBundle\Import\FirefoxImport; use Wallabag\ImportBundle\Redis\Producer; use Wallabag\UserBundle\Entity\User; @@ -34,7 +40,7 @@ class FirefoxImportTest extends TestCase $firefoxImport = $this->getFirefoxImport(false, 2); $firefoxImport->setFilepath(__DIR__ . '/../fixtures/firefox-bookmarks.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -47,7 +53,7 @@ class FirefoxImportTest extends TestCase ->method('getRepository') ->willReturn($entryRepo); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -67,7 +73,7 @@ class FirefoxImportTest extends TestCase $firefoxImport = $this->getFirefoxImport(false, 1); $firefoxImport->setFilepath(__DIR__ . '/../fixtures/firefox-bookmarks.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -105,7 +111,7 @@ class FirefoxImportTest extends TestCase $firefoxImport = $this->getFirefoxImport(); $firefoxImport->setFilepath(__DIR__ . '/../fixtures/firefox-bookmarks.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -116,7 +122,7 @@ class FirefoxImportTest extends TestCase ->expects($this->never()) ->method('getRepository'); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -124,7 +130,7 @@ class FirefoxImportTest extends TestCase ->expects($this->never()) ->method('updateEntry'); - $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer') + $producer = $this->getMockBuilder(\OldSound\RabbitMqBundle\RabbitMq\Producer::class) ->disableOriginalConstructor() ->getMock(); @@ -145,7 +151,7 @@ class FirefoxImportTest extends TestCase $firefoxImport = $this->getFirefoxImport(); $firefoxImport->setFilepath(__DIR__ . '/../fixtures/firefox-bookmarks.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -156,7 +162,7 @@ class FirefoxImportTest extends TestCase ->expects($this->never()) ->method('getRepository'); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -165,7 +171,7 @@ class FirefoxImportTest extends TestCase ->method('updateEntry'); $factory = new RedisMockFactory(); - $redisMock = $factory->getAdapter('Predis\Client', true); + $redisMock = $factory->getAdapter(Client::class, true); $queue = new RedisQueue($redisMock, 'firefox'); $producer = new Producer($queue); @@ -212,19 +218,19 @@ class FirefoxImportTest extends TestCase { $this->user = new User(); - $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $this->em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); - $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') + $this->contentProxy = $this->getMockBuilder(ContentProxy::class) ->disableOriginalConstructor() ->getMock(); - $this->tagsAssigner = $this->getMockBuilder('Wallabag\CoreBundle\Helper\TagsAssigner') + $this->tagsAssigner = $this->getMockBuilder(TagsAssigner::class) ->disableOriginalConstructor() ->getMock(); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); @@ -232,11 +238,10 @@ class FirefoxImportTest extends TestCase ->expects($this->exactly($dispatched)) ->method('dispatch'); - $wallabag = new FirefoxImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher); - $this->logHandler = new TestHandler(); $logger = new Logger('test', [$this->logHandler]); - $wallabag->setLogger($logger); + + $wallabag = new FirefoxImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher, $logger); if (false === $unsetUser) { $wallabag->setUser($this->user); diff --git a/tests/Wallabag/ImportBundle/Import/ImportChainTest.php b/tests/Wallabag/ImportBundle/Import/ImportChainTest.php index f27826f40..c3984fa63 100644 --- a/tests/Wallabag/ImportBundle/Import/ImportChainTest.php +++ b/tests/Wallabag/ImportBundle/Import/ImportChainTest.php @@ -4,12 +4,13 @@ namespace Tests\Wallabag\ImportBundle\Import; use PHPUnit\Framework\TestCase; use Wallabag\ImportBundle\Import\ImportChain; +use Wallabag\ImportBundle\Import\ImportInterface; class ImportChainTest extends TestCase { public function testGetAll() { - $import = $this->getMockBuilder('Wallabag\ImportBundle\Import\ImportInterface') + $import = $this->getMockBuilder(ImportInterface::class) ->disableOriginalConstructor() ->getMock(); diff --git a/tests/Wallabag/ImportBundle/Import/ImportCompilerPassTest.php b/tests/Wallabag/ImportBundle/Import/ImportCompilerPassTest.php index e0e90ae3e..e77ffc9f0 100644 --- a/tests/Wallabag/ImportBundle/Import/ImportCompilerPassTest.php +++ b/tests/Wallabag/ImportBundle/Import/ImportCompilerPassTest.php @@ -4,6 +4,7 @@ namespace Tests\Wallabag\ImportBundle\Import; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Wallabag\ImportBundle\Import\ImportChain; use Wallabag\ImportBundle\Import\ImportCompilerPass; class ImportCompilerPassTest extends TestCase @@ -20,7 +21,7 @@ class ImportCompilerPassTest extends TestCase { $container = new ContainerBuilder(); $container - ->register('wallabag_import.chain') + ->register(ImportChain::class) ->setPublic(false) ; @@ -31,9 +32,9 @@ class ImportCompilerPassTest extends TestCase $this->process($container); - $this->assertTrue($container->hasDefinition('wallabag_import.chain')); + $this->assertTrue($container->hasDefinition(ImportChain::class)); - $definition = $container->getDefinition('wallabag_import.chain'); + $definition = $container->getDefinition(ImportChain::class); $this->assertTrue($definition->hasMethodCall('addImport')); $calls = $definition->getMethodCalls(); diff --git a/tests/Wallabag/ImportBundle/Import/InstapaperImportTest.php b/tests/Wallabag/ImportBundle/Import/InstapaperImportTest.php index 8ef9a4684..84900d3fb 100644 --- a/tests/Wallabag/ImportBundle/Import/InstapaperImportTest.php +++ b/tests/Wallabag/ImportBundle/Import/InstapaperImportTest.php @@ -2,12 +2,19 @@ namespace Tests\Wallabag\ImportBundle\Import; +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\UnitOfWork; use M6Web\Component\RedisMock\RedisMockFactory; use Monolog\Handler\TestHandler; use Monolog\Logger; use PHPUnit\Framework\TestCase; +use Predis\Client; use Simpleue\Queue\RedisQueue; +use Symfony\Component\EventDispatcher\EventDispatcher; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Helper\TagsAssigner; +use Wallabag\CoreBundle\Repository\EntryRepository; use Wallabag\ImportBundle\Import\InstapaperImport; use Wallabag\ImportBundle\Redis\Producer; use Wallabag\UserBundle\Entity\User; @@ -35,7 +42,7 @@ class InstapaperImportTest extends TestCase $instapaperImport = $this->getInstapaperImport(false, 4); $instapaperImport->setFilepath(__DIR__ . '/../fixtures/instapaper-export.csv'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -48,7 +55,7 @@ class InstapaperImportTest extends TestCase ->method('getRepository') ->willReturn($entryRepo); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -68,7 +75,7 @@ class InstapaperImportTest extends TestCase $instapaperImport = $this->getInstapaperImport(false, 1); $instapaperImport->setFilepath(__DIR__ . '/../fixtures/instapaper-export.csv'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -106,7 +113,7 @@ class InstapaperImportTest extends TestCase $instapaperImport = $this->getInstapaperImport(); $instapaperImport->setFilepath(__DIR__ . '/../fixtures/instapaper-export.csv'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -117,7 +124,7 @@ class InstapaperImportTest extends TestCase ->expects($this->never()) ->method('getRepository'); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -125,7 +132,7 @@ class InstapaperImportTest extends TestCase ->expects($this->never()) ->method('updateEntry'); - $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer') + $producer = $this->getMockBuilder(\OldSound\RabbitMqBundle\RabbitMq\Producer::class) ->disableOriginalConstructor() ->getMock(); @@ -146,7 +153,7 @@ class InstapaperImportTest extends TestCase $instapaperImport = $this->getInstapaperImport(); $instapaperImport->setFilepath(__DIR__ . '/../fixtures/instapaper-export.csv'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -157,7 +164,7 @@ class InstapaperImportTest extends TestCase ->expects($this->never()) ->method('getRepository'); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -166,7 +173,7 @@ class InstapaperImportTest extends TestCase ->method('updateEntry'); $factory = new RedisMockFactory(); - $redisMock = $factory->getAdapter('Predis\Client', true); + $redisMock = $factory->getAdapter(Client::class, true); $queue = new RedisQueue($redisMock, 'instapaper'); $producer = new Producer($queue); @@ -213,11 +220,11 @@ class InstapaperImportTest extends TestCase { $this->user = new User(); - $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $this->em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); - $this->uow = $this->getMockBuilder('Doctrine\ORM\UnitOfWork') + $this->uow = $this->getMockBuilder(UnitOfWork::class) ->disableOriginalConstructor() ->getMock(); @@ -231,15 +238,15 @@ class InstapaperImportTest extends TestCase ->method('getScheduledEntityInsertions') ->willReturn([]); - $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') + $this->contentProxy = $this->getMockBuilder(ContentProxy::class) ->disableOriginalConstructor() ->getMock(); - $this->tagsAssigner = $this->getMockBuilder('Wallabag\CoreBundle\Helper\TagsAssigner') + $this->tagsAssigner = $this->getMockBuilder(TagsAssigner::class) ->disableOriginalConstructor() ->getMock(); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); @@ -247,11 +254,10 @@ class InstapaperImportTest extends TestCase ->expects($this->exactly($dispatched)) ->method('dispatch'); - $import = new InstapaperImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher); - $this->logHandler = new TestHandler(); $logger = new Logger('test', [$this->logHandler]); - $import->setLogger($logger); + + $import = new InstapaperImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher, $logger); if (false === $unsetUser) { $import->setUser($this->user); diff --git a/tests/Wallabag/ImportBundle/Import/PocketImportTest.php b/tests/Wallabag/ImportBundle/Import/PocketImportTest.php index 259280e4f..fe92b34c1 100644 --- a/tests/Wallabag/ImportBundle/Import/PocketImportTest.php +++ b/tests/Wallabag/ImportBundle/Import/PocketImportTest.php @@ -2,15 +2,22 @@ namespace Tests\Wallabag\ImportBundle\Import; +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\UnitOfWork; use GuzzleHttp\Psr7\Response; use Http\Mock\Client as HttpMockClient; use M6Web\Component\RedisMock\RedisMockFactory; use Monolog\Handler\TestHandler; use Monolog\Logger; use PHPUnit\Framework\TestCase; +use Predis\Client; use Simpleue\Queue\RedisQueue; +use Symfony\Component\EventDispatcher\EventDispatcher; use Wallabag\CoreBundle\Entity\Config; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Helper\TagsAssigner; +use Wallabag\CoreBundle\Repository\EntryRepository; use Wallabag\ImportBundle\Import\PocketImport; use Wallabag\ImportBundle\Redis\Producer; use Wallabag\UserBundle\Entity\User; @@ -187,7 +194,7 @@ JSON $pocketImport = $this->getPocketImport('ConsumerKey', 1); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -277,7 +284,7 @@ JSON $pocketImport = $this->getPocketImport('ConsumerKey', 2); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -357,7 +364,7 @@ JSON $pocketImport = $this->getPocketImport(); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -374,7 +381,7 @@ JSON ->expects($this->never()) ->method('updateEntry'); - $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer') + $producer = $this->getMockBuilder(\OldSound\RabbitMqBundle\RabbitMq\Producer::class) ->disableOriginalConstructor() ->getMock(); @@ -440,7 +447,7 @@ JSON $pocketImport = $this->getPocketImport(); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -458,7 +465,7 @@ JSON ->method('updateEntry'); $factory = new RedisMockFactory(); - $redisMock = $factory->getAdapter('Predis\Client', true); + $redisMock = $factory->getAdapter(Client::class, true); $queue = new RedisQueue($redisMock, 'pocket'); $producer = new Producer($queue); @@ -517,7 +524,7 @@ JSON $pocketImport = $this->getPocketImport('ConsumerKey', 1); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -555,19 +562,19 @@ JSON $this->user->setConfig($config); - $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') + $this->contentProxy = $this->getMockBuilder(ContentProxy::class) ->disableOriginalConstructor() ->getMock(); - $this->tagsAssigner = $this->getMockBuilder('Wallabag\CoreBundle\Helper\TagsAssigner') + $this->tagsAssigner = $this->getMockBuilder(TagsAssigner::class) ->disableOriginalConstructor() ->getMock(); - $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $this->em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); - $this->uow = $this->getMockBuilder('Doctrine\ORM\UnitOfWork') + $this->uow = $this->getMockBuilder(UnitOfWork::class) ->disableOriginalConstructor() ->getMock(); @@ -581,7 +588,7 @@ JSON ->method('getScheduledEntityInsertions') ->willReturn([]); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); @@ -589,12 +596,11 @@ JSON ->expects($this->exactly($dispatched)) ->method('dispatch'); - $pocket = new PocketImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher); - $pocket->setUser($this->user); - $this->logHandler = new TestHandler(); $logger = new Logger('test', [$this->logHandler]); - $pocket->setLogger($logger); + + $pocket = new PocketImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher, $logger); + $pocket->setUser($this->user); return $pocket; } diff --git a/tests/Wallabag/ImportBundle/Import/ReadabilityImportTest.php b/tests/Wallabag/ImportBundle/Import/ReadabilityImportTest.php index 96097f782..6b2622ccb 100644 --- a/tests/Wallabag/ImportBundle/Import/ReadabilityImportTest.php +++ b/tests/Wallabag/ImportBundle/Import/ReadabilityImportTest.php @@ -2,12 +2,18 @@ namespace Tests\Wallabag\ImportBundle\Import; +use Doctrine\ORM\EntityManager; use M6Web\Component\RedisMock\RedisMockFactory; use Monolog\Handler\TestHandler; use Monolog\Logger; use PHPUnit\Framework\TestCase; +use Predis\Client; use Simpleue\Queue\RedisQueue; +use Symfony\Component\EventDispatcher\EventDispatcher; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Helper\TagsAssigner; +use Wallabag\CoreBundle\Repository\EntryRepository; use Wallabag\ImportBundle\Import\ReadabilityImport; use Wallabag\ImportBundle\Redis\Producer; use Wallabag\UserBundle\Entity\User; @@ -34,7 +40,7 @@ class ReadabilityImportTest extends TestCase $readabilityImport = $this->getReadabilityImport(false, 3); $readabilityImport->setFilepath(__DIR__ . '/../fixtures/readability.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -47,7 +53,7 @@ class ReadabilityImportTest extends TestCase ->method('getRepository') ->willReturn($entryRepo); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -67,7 +73,7 @@ class ReadabilityImportTest extends TestCase $readabilityImport = $this->getReadabilityImport(false, 1); $readabilityImport->setFilepath(__DIR__ . '/../fixtures/readability-read.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -105,7 +111,7 @@ class ReadabilityImportTest extends TestCase $readabilityImport = $this->getReadabilityImport(); $readabilityImport->setFilepath(__DIR__ . '/../fixtures/readability.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -116,7 +122,7 @@ class ReadabilityImportTest extends TestCase ->expects($this->never()) ->method('getRepository'); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -124,7 +130,7 @@ class ReadabilityImportTest extends TestCase ->expects($this->never()) ->method('updateEntry'); - $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer') + $producer = $this->getMockBuilder(\OldSound\RabbitMqBundle\RabbitMq\Producer::class) ->disableOriginalConstructor() ->getMock(); @@ -145,7 +151,7 @@ class ReadabilityImportTest extends TestCase $readabilityImport = $this->getReadabilityImport(); $readabilityImport->setFilepath(__DIR__ . '/../fixtures/readability.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -156,7 +162,7 @@ class ReadabilityImportTest extends TestCase ->expects($this->never()) ->method('getRepository'); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -165,7 +171,7 @@ class ReadabilityImportTest extends TestCase ->method('updateEntry'); $factory = new RedisMockFactory(); - $redisMock = $factory->getAdapter('Predis\Client', true); + $redisMock = $factory->getAdapter(Client::class, true); $queue = new RedisQueue($redisMock, 'readability'); $producer = new Producer($queue); @@ -212,19 +218,19 @@ class ReadabilityImportTest extends TestCase { $this->user = new User(); - $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $this->em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); - $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') + $this->contentProxy = $this->getMockBuilder(ContentProxy::class) ->disableOriginalConstructor() ->getMock(); - $this->tagsAssigner = $this->getMockBuilder('Wallabag\CoreBundle\Helper\TagsAssigner') + $this->tagsAssigner = $this->getMockBuilder(TagsAssigner::class) ->disableOriginalConstructor() ->getMock(); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); @@ -232,11 +238,10 @@ class ReadabilityImportTest extends TestCase ->expects($this->exactly($dispatched)) ->method('dispatch'); - $wallabag = new ReadabilityImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher); - $this->logHandler = new TestHandler(); $logger = new Logger('test', [$this->logHandler]); - $wallabag->setLogger($logger); + + $wallabag = new ReadabilityImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher, $logger); if (false === $unsetUser) { $wallabag->setUser($this->user); diff --git a/tests/Wallabag/ImportBundle/Import/WallabagV1ImportTest.php b/tests/Wallabag/ImportBundle/Import/WallabagV1ImportTest.php index 1b385c114..5da4aa658 100644 --- a/tests/Wallabag/ImportBundle/Import/WallabagV1ImportTest.php +++ b/tests/Wallabag/ImportBundle/Import/WallabagV1ImportTest.php @@ -2,12 +2,19 @@ namespace Tests\Wallabag\ImportBundle\Import; +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\UnitOfWork; use M6Web\Component\RedisMock\RedisMockFactory; use Monolog\Handler\TestHandler; use Monolog\Logger; use PHPUnit\Framework\TestCase; +use Predis\Client; use Simpleue\Queue\RedisQueue; +use Symfony\Component\EventDispatcher\EventDispatcher; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Helper\TagsAssigner; +use Wallabag\CoreBundle\Repository\EntryRepository; use Wallabag\ImportBundle\Import\WallabagV1Import; use Wallabag\ImportBundle\Redis\Producer; use Wallabag\UserBundle\Entity\User; @@ -37,7 +44,7 @@ class WallabagV1ImportTest extends TestCase $wallabagV1Import = $this->getWallabagV1Import(false, 1); $wallabagV1Import->setFilepath(__DIR__ . '/../fixtures/wallabag-v1.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -50,7 +57,7 @@ class WallabagV1ImportTest extends TestCase ->method('getRepository') ->willReturn($entryRepo); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -70,7 +77,7 @@ class WallabagV1ImportTest extends TestCase $wallabagV1Import = $this->getWallabagV1Import(false, 3); $wallabagV1Import->setFilepath(__DIR__ . '/../fixtures/wallabag-v1-read.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -108,7 +115,7 @@ class WallabagV1ImportTest extends TestCase $wallabagV1Import = $this->getWallabagV1Import(); $wallabagV1Import->setFilepath(__DIR__ . '/../fixtures/wallabag-v1.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -119,7 +126,7 @@ class WallabagV1ImportTest extends TestCase ->expects($this->never()) ->method('getRepository'); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -127,7 +134,7 @@ class WallabagV1ImportTest extends TestCase ->expects($this->never()) ->method('updateEntry'); - $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer') + $producer = $this->getMockBuilder(\OldSound\RabbitMqBundle\RabbitMq\Producer::class) ->disableOriginalConstructor() ->getMock(); @@ -148,7 +155,7 @@ class WallabagV1ImportTest extends TestCase $wallabagV1Import = $this->getWallabagV1Import(); $wallabagV1Import->setFilepath(__DIR__ . '/../fixtures/wallabag-v1.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -159,7 +166,7 @@ class WallabagV1ImportTest extends TestCase ->expects($this->never()) ->method('getRepository'); - $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry') + $entry = $this->getMockBuilder(Entry::class) ->disableOriginalConstructor() ->getMock(); @@ -168,7 +175,7 @@ class WallabagV1ImportTest extends TestCase ->method('updateEntry'); $factory = new RedisMockFactory(); - $redisMock = $factory->getAdapter('Predis\Client', true); + $redisMock = $factory->getAdapter(Client::class, true); $queue = new RedisQueue($redisMock, 'wallabag_v1'); $producer = new Producer($queue); @@ -215,11 +222,11 @@ class WallabagV1ImportTest extends TestCase { $this->user = new User(); - $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $this->em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); - $this->uow = $this->getMockBuilder('Doctrine\ORM\UnitOfWork') + $this->uow = $this->getMockBuilder(UnitOfWork::class) ->disableOriginalConstructor() ->getMock(); @@ -233,15 +240,15 @@ class WallabagV1ImportTest extends TestCase ->method('getScheduledEntityInsertions') ->willReturn([]); - $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') + $this->contentProxy = $this->getMockBuilder(ContentProxy::class) ->disableOriginalConstructor() ->getMock(); - $this->tagsAssigner = $this->getMockBuilder('Wallabag\CoreBundle\Helper\TagsAssigner') + $this->tagsAssigner = $this->getMockBuilder(TagsAssigner::class) ->disableOriginalConstructor() ->getMock(); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); @@ -249,19 +256,19 @@ class WallabagV1ImportTest extends TestCase ->expects($this->exactly($dispatched)) ->method('dispatch'); + $this->logHandler = new TestHandler(); + $logger = new Logger('test', [$this->logHandler]); + $wallabag = new WallabagV1Import( $this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher, + $logger, $this->fetchingErrorMessageTitle, $this->fetchingErrorMessage ); - $this->logHandler = new TestHandler(); - $logger = new Logger('test', [$this->logHandler]); - $wallabag->setLogger($logger); - if (false === $unsetUser) { $wallabag->setUser($this->user); } diff --git a/tests/Wallabag/ImportBundle/Import/WallabagV2ImportTest.php b/tests/Wallabag/ImportBundle/Import/WallabagV2ImportTest.php index bc6ba66d4..59173f58a 100644 --- a/tests/Wallabag/ImportBundle/Import/WallabagV2ImportTest.php +++ b/tests/Wallabag/ImportBundle/Import/WallabagV2ImportTest.php @@ -2,12 +2,19 @@ namespace Tests\Wallabag\ImportBundle\Import; +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\UnitOfWork; use M6Web\Component\RedisMock\RedisMockFactory; use Monolog\Handler\TestHandler; use Monolog\Logger; use PHPUnit\Framework\TestCase; +use Predis\Client; use Simpleue\Queue\RedisQueue; +use Symfony\Component\EventDispatcher\EventDispatcher; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Helper\ContentProxy; +use Wallabag\CoreBundle\Helper\TagsAssigner; +use Wallabag\CoreBundle\Repository\EntryRepository; use Wallabag\ImportBundle\Import\WallabagV2Import; use Wallabag\ImportBundle\Redis\Producer; use Wallabag\UserBundle\Entity\User; @@ -35,7 +42,7 @@ class WallabagV2ImportTest extends TestCase $wallabagV2Import = $this->getWallabagV2Import(false, 2); $wallabagV2Import->setFilepath(__DIR__ . '/../fixtures/wallabag-v2.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -64,7 +71,7 @@ class WallabagV2ImportTest extends TestCase $wallabagV2Import = $this->getWallabagV2Import(false, 2); $wallabagV2Import->setFilepath(__DIR__ . '/../fixtures/wallabag-v2-read.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -102,7 +109,7 @@ class WallabagV2ImportTest extends TestCase $wallabagV2Import = $this->getWallabagV2Import(); $wallabagV2Import->setFilepath(__DIR__ . '/../fixtures/wallabag-v2.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -117,7 +124,7 @@ class WallabagV2ImportTest extends TestCase ->expects($this->never()) ->method('updateEntry'); - $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer') + $producer = $this->getMockBuilder(\OldSound\RabbitMqBundle\RabbitMq\Producer::class) ->disableOriginalConstructor() ->getMock(); @@ -138,7 +145,7 @@ class WallabagV2ImportTest extends TestCase $wallabagV2Import = $this->getWallabagV2Import(); $wallabagV2Import->setFilepath(__DIR__ . '/../fixtures/wallabag-v2.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -154,7 +161,7 @@ class WallabagV2ImportTest extends TestCase ->method('updateEntry'); $factory = new RedisMockFactory(); - $redisMock = $factory->getAdapter('Predis\Client', true); + $redisMock = $factory->getAdapter(Client::class, true); $queue = new RedisQueue($redisMock, 'wallabag_v2'); $producer = new Producer($queue); @@ -213,7 +220,7 @@ class WallabagV2ImportTest extends TestCase $wallabagV2Import = $this->getWallabagV2Import(false, 2); $wallabagV2Import->setFilepath(__DIR__ . '/../fixtures/wallabag-v2.json'); - $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + $entryRepo = $this->getMockBuilder(EntryRepository::class) ->disableOriginalConstructor() ->getMock(); @@ -241,11 +248,11 @@ class WallabagV2ImportTest extends TestCase { $this->user = new User(); - $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $this->em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); - $this->uow = $this->getMockBuilder('Doctrine\ORM\UnitOfWork') + $this->uow = $this->getMockBuilder(UnitOfWork::class) ->disableOriginalConstructor() ->getMock(); @@ -259,15 +266,15 @@ class WallabagV2ImportTest extends TestCase ->method('getScheduledEntityInsertions') ->willReturn([]); - $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy') + $this->contentProxy = $this->getMockBuilder(ContentProxy::class) ->disableOriginalConstructor() ->getMock(); - $this->tagsAssigner = $this->getMockBuilder('Wallabag\CoreBundle\Helper\TagsAssigner') + $this->tagsAssigner = $this->getMockBuilder(TagsAssigner::class) ->disableOriginalConstructor() ->getMock(); - $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher') + $dispatcher = $this->getMockBuilder(EventDispatcher::class) ->disableOriginalConstructor() ->getMock(); @@ -275,11 +282,10 @@ class WallabagV2ImportTest extends TestCase ->expects($this->exactly($dispatched)) ->method('dispatch'); - $wallabag = new WallabagV2Import($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher); - $this->logHandler = new TestHandler(); $logger = new Logger('test', [$this->logHandler]); - $wallabag->setLogger($logger); + + $wallabag = new WallabagV2Import($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher, $logger); if (false === $unsetUser) { $wallabag->setUser($this->user); diff --git a/tests/Wallabag/UserBundle/EventListener/AuthenticationFailureListenerTest.php b/tests/Wallabag/UserBundle/EventListener/AuthenticationFailureListenerTest.php index 54384f26b..8518373c2 100644 --- a/tests/Wallabag/UserBundle/EventListener/AuthenticationFailureListenerTest.php +++ b/tests/Wallabag/UserBundle/EventListener/AuthenticationFailureListenerTest.php @@ -8,8 +8,10 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\AuthenticationEvents; use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent; +use Symfony\Component\Security\Core\Exception\AuthenticationException; use Wallabag\UserBundle\EventListener\AuthenticationFailureListener; class AuthenticationFailureListenerTest extends TestCase @@ -41,11 +43,11 @@ class AuthenticationFailureListenerTest extends TestCase public function testOnAuthenticationFailure() { - $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface') + $token = $this->getMockBuilder(TokenInterface::class) ->disableOriginalConstructor() ->getMock(); - $exception = $this->getMockBuilder('Symfony\Component\Security\Core\Exception\AuthenticationException') + $exception = $this->getMockBuilder(AuthenticationException::class) ->disableOriginalConstructor() ->getMock(); diff --git a/tests/Wallabag/UserBundle/EventListener/CreateConfigListenerTest.php b/tests/Wallabag/UserBundle/EventListener/CreateConfigListenerTest.php index 7a685f990..11933b6ce 100644 --- a/tests/Wallabag/UserBundle/EventListener/CreateConfigListenerTest.php +++ b/tests/Wallabag/UserBundle/EventListener/CreateConfigListenerTest.php @@ -2,6 +2,7 @@ namespace Tests\Wallabag\UserBundle\EventListener; +use Doctrine\ORM\EntityManager; use FOS\UserBundle\Event\FilterUserResponseEvent; use FOS\UserBundle\FOSUserEvents; use PHPUnit\Framework\TestCase; @@ -25,13 +26,13 @@ class CreateConfigListenerTest extends TestCase protected function setUp(): void { $session = new Session(new MockArraySessionStorage()); - $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + $this->em = $this->getMockBuilder(EntityManager::class) ->disableOriginalConstructor() ->getMock(); $this->listener = new CreateConfigListener( $this->em, - 'baggy', + 'material', 20, 50, 'fr', @@ -60,7 +61,7 @@ class CreateConfigListenerTest extends TestCase ); $config = new Config($user); - $config->setTheme('baggy'); + $config->setTheme('material'); $config->setItemsPerPage(20); $config->setFeedLimit(50); $config->setLanguage('fr'); diff --git a/tests/Wallabag/UserBundle/Mailer/AuthCodeMailerTest.php b/tests/Wallabag/UserBundle/Mailer/AuthCodeMailerTest.php index 90248df8f..e1a30749b 100644 --- a/tests/Wallabag/UserBundle/Mailer/AuthCodeMailerTest.php +++ b/tests/Wallabag/UserBundle/Mailer/AuthCodeMailerTest.php @@ -29,7 +29,7 @@ class AuthCodeMailerTest extends TestCase {% block body_text %}text body {{ support_url }}{% endblock %} TWIG; - $this->twig = new Environment(new ArrayLoader(['WallabagUserBundle:TwoFactor:email_auth_code.html.twig' => $twigTemplate])); + $this->twig = new Environment(new ArrayLoader(['@WallabagUser/TwoFactor/email_auth_code.html.twig' => $twigTemplate])); } public function testSendEmail() diff --git a/var/SymfonyRequirements.php b/var/SymfonyRequirements.php deleted file mode 100644 index 4a1fcc621..000000000 --- a/var/SymfonyRequirements.php +++ /dev/null @@ -1,810 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/* - * Users of PHP 5.2 should be able to run the requirements checks. - * This is why the file and all classes must be compatible with PHP 5.2+ - * (e.g. not using namespaces and closures). - * - * ************** CAUTION ************** - * - * DO NOT EDIT THIS FILE as it will be overridden by Composer as part of - * the installation/update process. The original file resides in the - * SensioDistributionBundle. - * - * ************** CAUTION ************** - */ - -/** - * Represents a single PHP requirement, e.g. an installed extension. - * It can be a mandatory requirement or an optional recommendation. - * There is a special subclass, named PhpIniRequirement, to check a php.ini configuration. - * - * @author Tobias Schultze - */ -class Requirement -{ - private $fulfilled; - private $testMessage; - private $helpText; - private $helpHtml; - private $optional; - - /** - * Constructor that initializes the requirement. - * - * @param bool $fulfilled Whether the requirement is fulfilled - * @param string $testMessage The message for testing the requirement - * @param string $helpHtml The help text formatted in HTML for resolving the problem - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement - */ - public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false) - { - $this->fulfilled = (bool) $fulfilled; - $this->testMessage = (string) $testMessage; - $this->helpHtml = (string) $helpHtml; - $this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText; - $this->optional = (bool) $optional; - } - - /** - * Returns whether the requirement is fulfilled. - * - * @return bool true if fulfilled, otherwise false - */ - public function isFulfilled() - { - return $this->fulfilled; - } - - /** - * Returns the message for testing the requirement. - * - * @return string The test message - */ - public function getTestMessage() - { - return $this->testMessage; - } - - /** - * Returns the help text for resolving the problem. - * - * @return string The help text - */ - public function getHelpText() - { - return $this->helpText; - } - - /** - * Returns the help text formatted in HTML. - * - * @return string The HTML help - */ - public function getHelpHtml() - { - return $this->helpHtml; - } - - /** - * Returns whether this is only an optional recommendation and not a mandatory requirement. - * - * @return bool true if optional, false if mandatory - */ - public function isOptional() - { - return $this->optional; - } -} - -/** - * Represents a PHP requirement in form of a php.ini configuration. - * - * @author Tobias Schultze - */ -class PhpIniRequirement extends Requirement -{ - /** - * Constructor that initializes the requirement. - * - * @param string $cfgName The configuration name used for ini_get() - * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, - * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement - * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. - * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. - * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. - * @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) - * @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement - */ - public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false) - { - $cfgValue = ini_get($cfgName); - - if (is_callable($evaluation)) { - if (null === $testMessage || null === $helpHtml) { - throw new InvalidArgumentException('You must provide the parameters testMessage and helpHtml for a callback evaluation.'); - } - - $fulfilled = call_user_func($evaluation, $cfgValue); - } else { - if (null === $testMessage) { - $testMessage = sprintf('%s %s be %s in php.ini', - $cfgName, - $optional ? 'should' : 'must', - $evaluation ? 'enabled' : 'disabled' - ); - } - - if (null === $helpHtml) { - $helpHtml = sprintf('Set %s to %s in php.ini*.', - $cfgName, - $evaluation ? 'on' : 'off' - ); - } - - $fulfilled = $evaluation == $cfgValue; - } - - parent::__construct($fulfilled || ($approveCfgAbsence && false === $cfgValue), $testMessage, $helpHtml, $helpText, $optional); - } -} - -/** - * A RequirementCollection represents a set of Requirement instances. - * - * @author Tobias Schultze - */ -class RequirementCollection implements IteratorAggregate -{ - /** - * @var Requirement[] - */ - private $requirements = array(); - - /** - * Gets the current RequirementCollection as an Iterator. - * - * @return Traversable A Traversable interface - */ - public function getIterator() - { - return new ArrayIterator($this->requirements); - } - - /** - * Adds a Requirement. - * - * @param Requirement $requirement A Requirement instance - */ - public function add(Requirement $requirement) - { - $this->requirements[] = $requirement; - } - - /** - * Adds a mandatory requirement. - * - * @param bool $fulfilled Whether the requirement is fulfilled - * @param string $testMessage The message for testing the requirement - * @param string $helpHtml The help text formatted in HTML for resolving the problem - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - */ - public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null) - { - $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, false)); - } - - /** - * Adds an optional recommendation. - * - * @param bool $fulfilled Whether the recommendation is fulfilled - * @param string $testMessage The message for testing the recommendation - * @param string $helpHtml The help text formatted in HTML for resolving the problem - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - */ - public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null) - { - $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, true)); - } - - /** - * Adds a mandatory requirement in form of a php.ini configuration. - * - * @param string $cfgName The configuration name used for ini_get() - * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, - * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement - * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. - * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. - * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. - * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) - * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - */ - public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) - { - $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, false)); - } - - /** - * Adds an optional recommendation in form of a php.ini configuration. - * - * @param string $cfgName The configuration name used for ini_get() - * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false, - * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement - * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. - * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. - * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. - * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived) - * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived) - * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) - */ - public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) - { - $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, true)); - } - - /** - * Adds a requirement collection to the current set of requirements. - * - * @param RequirementCollection $collection A RequirementCollection instance - */ - public function addCollection(RequirementCollection $collection) - { - $this->requirements = array_merge($this->requirements, $collection->all()); - } - - /** - * Returns both requirements and recommendations. - * - * @return Requirement[] - */ - public function all() - { - return $this->requirements; - } - - /** - * Returns all mandatory requirements. - * - * @return Requirement[] - */ - public function getRequirements() - { - $array = array(); - foreach ($this->requirements as $req) { - if (!$req->isOptional()) { - $array[] = $req; - } - } - - return $array; - } - - /** - * Returns the mandatory requirements that were not met. - * - * @return Requirement[] - */ - public function getFailedRequirements() - { - $array = array(); - foreach ($this->requirements as $req) { - if (!$req->isFulfilled() && !$req->isOptional()) { - $array[] = $req; - } - } - - return $array; - } - - /** - * Returns all optional recommendations. - * - * @return Requirement[] - */ - public function getRecommendations() - { - $array = array(); - foreach ($this->requirements as $req) { - if ($req->isOptional()) { - $array[] = $req; - } - } - - return $array; - } - - /** - * Returns the recommendations that were not met. - * - * @return Requirement[] - */ - public function getFailedRecommendations() - { - $array = array(); - foreach ($this->requirements as $req) { - if (!$req->isFulfilled() && $req->isOptional()) { - $array[] = $req; - } - } - - return $array; - } - - /** - * Returns whether a php.ini configuration is not correct. - * - * @return bool php.ini configuration problem? - */ - public function hasPhpIniConfigIssue() - { - foreach ($this->requirements as $req) { - if (!$req->isFulfilled() && $req instanceof PhpIniRequirement) { - return true; - } - } - - return false; - } - - /** - * Returns the PHP configuration file (php.ini) path. - * - * @return string|false php.ini file path - */ - public function getPhpIniConfigPath() - { - return get_cfg_var('cfg_file_path'); - } -} - -/** - * This class specifies all requirements and optional recommendations that - * are necessary to run the Symfony Standard Edition. - * - * @author Tobias Schultze - * @author Fabien Potencier - */ -class SymfonyRequirements extends RequirementCollection -{ - const LEGACY_REQUIRED_PHP_VERSION = '5.3.3'; - const REQUIRED_PHP_VERSION = '5.5.9'; - - /** - * Constructor that initializes the requirements. - */ - public function __construct() - { - /* mandatory requirements follow */ - - $installedPhpVersion = PHP_VERSION; - $requiredPhpVersion = $this->getPhpRequiredVersion(); - - $this->addRecommendation( - $requiredPhpVersion, - 'Vendors should be installed in order to check all requirements.', - 'Run the composer install command.', - 'Run the "composer install" command.' - ); - - if (false !== $requiredPhpVersion) { - $this->addRequirement( - version_compare($installedPhpVersion, $requiredPhpVersion, '>='), - sprintf('PHP version must be at least %s (%s installed)', $requiredPhpVersion, $installedPhpVersion), - sprintf('You are running PHP version "%s", but Symfony needs at least PHP "%s" to run. - Before using Symfony, upgrade your PHP installation, preferably to the latest version.', - $installedPhpVersion, $requiredPhpVersion), - sprintf('Install PHP %s or newer (installed version is %s)', $requiredPhpVersion, $installedPhpVersion) - ); - } - - $this->addRequirement( - version_compare($installedPhpVersion, '5.3.16', '!='), - 'PHP version must not be 5.3.16 as Symfony won\'t work properly with it', - 'Install PHP 5.3.17 or newer (or downgrade to an earlier PHP version)' - ); - - $this->addRequirement( - is_dir(__DIR__.'/../vendor/composer'), - 'Vendor libraries must be installed', - 'Vendor libraries are missing. Install composer following instructions from http://getcomposer.org/. '. - 'Then run "php composer.phar install" to install them.' - ); - - $cacheDir = is_dir(__DIR__.'/../var/cache') ? __DIR__.'/../var/cache' : __DIR__.'/cache'; - - $this->addRequirement( - is_writable($cacheDir), - 'app/cache/ or var/cache/ directory must be writable', - 'Change the permissions of either "app/cache/" or "var/cache/" directory so that the web server can write into it.' - ); - - $logsDir = is_dir(__DIR__.'/../var/logs') ? __DIR__.'/../var/logs' : __DIR__.'/logs'; - - $this->addRequirement( - is_writable($logsDir), - 'app/logs/ or var/logs/ directory must be writable', - 'Change the permissions of either "app/logs/" or "var/logs/" directory so that the web server can write into it.' - ); - - if (version_compare($installedPhpVersion, '7.0.0', '<')) { - $this->addPhpIniRequirement( - 'date.timezone', true, false, - 'date.timezone setting must be set', - 'Set the "date.timezone" setting in php.ini* (like Europe/Paris).' - ); - } - - if (false !== $requiredPhpVersion && version_compare($installedPhpVersion, $requiredPhpVersion, '>=')) { - $this->addRequirement( - in_array(@date_default_timezone_get(), DateTimeZone::listIdentifiers(), true), - sprintf('Configured default timezone "%s" must be supported by your installation of PHP', @date_default_timezone_get()), - 'Your default timezone is not supported by PHP. Check for typos in your php.ini file and have a look at the list of deprecated timezones at http://php.net/manual/en/timezones.others.php.' - ); - } - - $this->addRequirement( - function_exists('iconv'), - 'iconv() must be available', - 'Install and enable the iconv extension.' - ); - - $this->addRequirement( - function_exists('json_encode'), - 'json_encode() must be available', - 'Install and enable the JSON extension.' - ); - - $this->addRequirement( - function_exists('session_start'), - 'session_start() must be available', - 'Install and enable the session extension.' - ); - - $this->addRequirement( - function_exists('ctype_alpha'), - 'ctype_alpha() must be available', - 'Install and enable the ctype extension.' - ); - - $this->addRequirement( - function_exists('token_get_all'), - 'token_get_all() must be available', - 'Install and enable the Tokenizer extension.' - ); - - $this->addRequirement( - function_exists('simplexml_import_dom'), - 'simplexml_import_dom() must be available', - 'Install and enable the SimpleXML extension.' - ); - - if (function_exists('apc_store') && ini_get('apc.enabled')) { - if (version_compare($installedPhpVersion, '5.4.0', '>=')) { - $this->addRequirement( - version_compare(phpversion('apc'), '3.1.13', '>='), - 'APC version must be at least 3.1.13 when using PHP 5.4', - 'Upgrade your APC extension (3.1.13+).' - ); - } else { - $this->addRequirement( - version_compare(phpversion('apc'), '3.0.17', '>='), - 'APC version must be at least 3.0.17', - 'Upgrade your APC extension (3.0.17+).' - ); - } - } - - $this->addPhpIniRequirement('detect_unicode', false); - - if (extension_loaded('suhosin')) { - $this->addPhpIniRequirement( - 'suhosin.executor.include.whitelist', - create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'), - false, - 'suhosin.executor.include.whitelist must be configured correctly in php.ini', - 'Add "phar" to suhosin.executor.include.whitelist in php.ini*.' - ); - } - - if (extension_loaded('xdebug')) { - $this->addPhpIniRequirement( - 'xdebug.show_exception_trace', false, true - ); - - $this->addPhpIniRequirement( - 'xdebug.scream', false, true - ); - - $this->addPhpIniRecommendation( - 'xdebug.max_nesting_level', - create_function('$cfgValue', 'return $cfgValue > 100;'), - true, - 'xdebug.max_nesting_level should be above 100 in php.ini', - 'Set "xdebug.max_nesting_level" to e.g. "250" in php.ini* to stop Xdebug\'s infinite recursion protection erroneously throwing a fatal error in your project.' - ); - } - - $pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null; - - $this->addRequirement( - null !== $pcreVersion, - 'PCRE extension must be available', - 'Install the PCRE extension (version 8.0+).' - ); - - if (extension_loaded('mbstring')) { - $this->addPhpIniRequirement( - 'mbstring.func_overload', - create_function('$cfgValue', 'return (int) $cfgValue === 0;'), - true, - 'string functions should not be overloaded', - 'Set "mbstring.func_overload" to 0 in php.ini* to disable function overloading by the mbstring extension.' - ); - } - - /* optional recommendations follow */ - - if (file_exists(__DIR__.'/../vendor/composer')) { - require_once __DIR__.'/../vendor/autoload.php'; - - try { - $r = new ReflectionClass('Sensio\Bundle\DistributionBundle\SensioDistributionBundle'); - - $contents = file_get_contents(dirname($r->getFileName()).'/Resources/skeleton/app/SymfonyRequirements.php'); - } catch (ReflectionException $e) { - $contents = ''; - } - $this->addRecommendation( - file_get_contents(__FILE__) === $contents, - 'Requirements file should be up-to-date', - 'Your requirements file is outdated. Run composer install and re-check your configuration.' - ); - } - - $this->addRecommendation( - version_compare($installedPhpVersion, '5.3.4', '>='), - 'You should use at least PHP 5.3.4 due to PHP bug #52083 in earlier versions', - 'Your project might malfunction randomly due to PHP bug #52083 ("Notice: Trying to get property of non-object"). Install PHP 5.3.4 or newer.' - ); - - $this->addRecommendation( - version_compare($installedPhpVersion, '5.3.8', '>='), - 'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156', - 'Install PHP 5.3.8 or newer if your project uses annotations.' - ); - - $this->addRecommendation( - version_compare($installedPhpVersion, '5.4.0', '!='), - 'You should not use PHP 5.4.0 due to the PHP bug #61453', - 'Your project might not work properly due to the PHP bug #61453 ("Cannot dump definitions which have method calls"). Install PHP 5.4.1 or newer.' - ); - - $this->addRecommendation( - version_compare($installedPhpVersion, '5.4.11', '>='), - 'When using the logout handler from the Symfony Security Component, you should have at least PHP 5.4.11 due to PHP bug #63379 (as a workaround, you can also set invalidate_session to false in the security logout handler configuration)', - 'Install PHP 5.4.11 or newer if your project uses the logout handler from the Symfony Security Component.' - ); - - $this->addRecommendation( - (version_compare($installedPhpVersion, '5.3.18', '>=') && version_compare($installedPhpVersion, '5.4.0', '<')) - || - version_compare($installedPhpVersion, '5.4.8', '>='), - 'You should use PHP 5.3.18+ or PHP 5.4.8+ to always get nice error messages for fatal errors in the development environment due to PHP bug #61767/#60909', - 'Install PHP 5.3.18+ or PHP 5.4.8+ if you want nice error messages for all fatal errors in the development environment.' - ); - - if (null !== $pcreVersion) { - $this->addRecommendation( - $pcreVersion >= 8.0, - sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion), - 'PCRE 8.0+ is preconfigured in PHP since 5.3.2 but you are using an outdated version of it. Symfony probably works anyway but it is recommended to upgrade your PCRE extension.' - ); - } - - $this->addRecommendation( - class_exists('DomDocument'), - 'PHP-DOM and PHP-XML modules should be installed', - 'Install and enable the PHP-DOM and the PHP-XML modules.' - ); - - $this->addRecommendation( - function_exists('mb_strlen'), - 'mb_strlen() should be available', - 'Install and enable the mbstring extension.' - ); - - $this->addRecommendation( - function_exists('utf8_decode'), - 'utf8_decode() should be available', - 'Install and enable the XML extension.' - ); - - $this->addRecommendation( - function_exists('filter_var'), - 'filter_var() should be available', - 'Install and enable the filter extension.' - ); - - if (!defined('PHP_WINDOWS_VERSION_BUILD')) { - $this->addRecommendation( - function_exists('posix_isatty'), - 'posix_isatty() should be available', - 'Install and enable the php_posix extension (used to colorize the CLI output).' - ); - } - - $this->addRecommendation( - extension_loaded('intl'), - 'intl extension should be available', - 'Install and enable the intl extension (used for validators).' - ); - - if (extension_loaded('intl')) { - // in some WAMP server installations, new Collator() returns null - $this->addRecommendation( - null !== new Collator('fr_FR'), - 'intl extension should be correctly configured', - 'The intl extension does not behave properly. This problem is typical on PHP 5.3.X x64 WIN builds.' - ); - - // check for compatible ICU versions (only done when you have the intl extension) - if (defined('INTL_ICU_VERSION')) { - $version = INTL_ICU_VERSION; - } else { - $reflector = new ReflectionExtension('intl'); - - ob_start(); - $reflector->info(); - $output = strip_tags(ob_get_clean()); - - preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches); - $version = $matches[1]; - } - - $this->addRecommendation( - version_compare($version, '4.0', '>='), - 'intl ICU version should be at least 4+', - 'Upgrade your intl extension with a newer ICU version (4+).' - ); - - if (class_exists('Symfony\Component\Intl\Intl')) { - $this->addRecommendation( - \Symfony\Component\Intl\Intl::getIcuDataVersion() <= \Symfony\Component\Intl\Intl::getIcuVersion(), - sprintf('intl ICU version installed on your system is outdated (%s) and does not match the ICU data bundled with Symfony (%s)', \Symfony\Component\Intl\Intl::getIcuVersion(), \Symfony\Component\Intl\Intl::getIcuDataVersion()), - 'To get the latest internationalization data upgrade the ICU system package and the intl PHP extension.' - ); - if (\Symfony\Component\Intl\Intl::getIcuDataVersion() <= \Symfony\Component\Intl\Intl::getIcuVersion()) { - $this->addRecommendation( - \Symfony\Component\Intl\Intl::getIcuDataVersion() === \Symfony\Component\Intl\Intl::getIcuVersion(), - sprintf('intl ICU version installed on your system (%s) does not match the ICU data bundled with Symfony (%s)', \Symfony\Component\Intl\Intl::getIcuVersion(), \Symfony\Component\Intl\Intl::getIcuDataVersion()), - 'To avoid internationalization data inconsistencies upgrade the symfony/intl component.' - ); - } - } - - $this->addPhpIniRecommendation( - 'intl.error_level', - create_function('$cfgValue', 'return (int) $cfgValue === 0;'), - true, - 'intl.error_level should be 0 in php.ini', - 'Set "intl.error_level" to "0" in php.ini* to inhibit the messages when an error occurs in ICU functions.' - ); - } - - $accelerator = - (extension_loaded('eaccelerator') && ini_get('eaccelerator.enable')) - || - (extension_loaded('apc') && ini_get('apc.enabled')) - || - (extension_loaded('Zend Optimizer+') && ini_get('zend_optimizerplus.enable')) - || - (extension_loaded('Zend OPcache') && ini_get('opcache.enable')) - || - (extension_loaded('xcache') && ini_get('xcache.cacher')) - || - (extension_loaded('wincache') && ini_get('wincache.ocenabled')) - ; - - $this->addRecommendation( - $accelerator, - 'a PHP accelerator should be installed', - 'Install and/or enable a PHP accelerator (highly recommended).' - ); - - if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) { - $this->addRecommendation( - $this->getRealpathCacheSize() >= 5 * 1024 * 1024, - 'realpath_cache_size should be at least 5M in php.ini', - 'Setting "realpath_cache_size" to e.g. "5242880" or "5M" in php.ini* may improve performance on Windows significantly in some cases.' - ); - } - - $this->addPhpIniRecommendation('short_open_tag', false); - - $this->addPhpIniRecommendation('magic_quotes_gpc', false, true); - - $this->addPhpIniRecommendation('register_globals', false, true); - - $this->addPhpIniRecommendation('session.auto_start', false); - - $this->addRecommendation( - class_exists('PDO'), - 'PDO should be installed', - 'Install PDO (mandatory for Doctrine).' - ); - - if (class_exists('PDO')) { - $drivers = PDO::getAvailableDrivers(); - $this->addRecommendation( - count($drivers) > 0, - sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'), - 'Install PDO drivers (mandatory for Doctrine).' - ); - } - } - - /** - * Loads realpath_cache_size from php.ini and converts it to int. - * - * (e.g. 16k is converted to 16384 int) - * - * @return int - */ - protected function getRealpathCacheSize() - { - $size = ini_get('realpath_cache_size'); - $size = trim($size); - $unit = ''; - if (!ctype_digit($size)) { - $unit = strtolower(substr($size, -1, 1)); - $size = (int) substr($size, 0, -1); - } - switch ($unit) { - case 'g': - return $size * 1024 * 1024 * 1024; - case 'm': - return $size * 1024 * 1024; - case 'k': - return $size * 1024; - default: - return (int) $size; - } - } - - /** - * Defines PHP required version from Symfony version. - * - * @return string|false The PHP required version or false if it could not be guessed - */ - protected function getPhpRequiredVersion() - { - if (!file_exists($path = __DIR__.'/../composer.lock')) { - return false; - } - - $composerLock = json_decode(file_get_contents($path), true); - foreach ($composerLock['packages'] as $package) { - $name = $package['name']; - if ('symfony/symfony' !== $name && 'symfony/http-kernel' !== $name) { - continue; - } - - return (int) $package['version'][1] > 2 ? self::REQUIRED_PHP_VERSION : self::LEGACY_REQUIRED_PHP_VERSION; - } - - return false; - } -} diff --git a/web/wallassets/baggy.css b/web/wallassets/baggy.css deleted file mode 100644 index 9b86d45f3..000000000 --- a/web/wallassets/baggy.css +++ /dev/null @@ -1,10 +0,0 @@ -.annotator-notice,.annotator-filter *,.annotator-widget *{font-family:"Helvetica Neue",Arial,Helvetica,sans-serif;font-weight:normal;text-align:left;margin:0;padding:0;background:none;transition:none;-o-box-shadow:none;box-shadow:none;color:#909090}.annotator-adder{background-image:url(img/annotator-icon-sprite.png);background-repeat:no-repeat}.annotator-resize,.annotator-widget:after,.annotator-editor a:after,.annotator-viewer .annotator-controls button,.annotator-viewer .annotator-controls a,.annotator-filter .annotator-filter-navigation button:after,.annotator-filter .annotator-filter-property .annotator-filter-clear{background-image:url(img/annotator-glyph-sprite.png);background-repeat:no-repeat}.annotator-hl{background:#ffff0a;background:rgba(255,255,10,.3);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4DFFFF0A, endColorstr=#4DFFFF0A)"}.annotator-hl-temporary{background:#007cff;background:rgba(0,124,255,.3);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4D007CFF, endColorstr=#4D007CFF)"}.annotator-wrapper{position:relative}.annotator-adder,.annotator-outer,.annotator-notice{z-index:1020}.annotator-filter{z-index:1010}.annotator-adder,.annotator-outer,.annotator-widget,.annotator-notice{position:absolute;font-size:10px;line-height:1}.annotator-hide{display:none;visibility:hidden}.annotator-adder{margin-top:-48px;margin-left:-24px;width:48px;height:48px;background-position:left top}.annotator-adder:hover{background-position:center top}.annotator-adder:active{background-position:center right}.annotator-adder button{display:block;width:36px;height:41px;margin:0 auto;border:none;background:none;text-indent:-999em;cursor:pointer}.annotator-outer{width:0;height:0}.annotator-widget{margin:0;padding:0;bottom:15px;left:-18px;min-width:265px;background-color:#fbfbfb;background-color:rgba(251,251,251,.98);border:1px solid #7a7a7a;border:1px solid rgba(122,122,122,.6);border-radius:5px;-o-box-shadow:0 5px 15px rgba(0,0,0,.2);box-shadow:0 5px 15px rgba(0,0,0,.2)}.annotator-invert-x .annotator-widget{left:auto;right:-18px}.annotator-invert-y .annotator-widget{bottom:auto;top:8px}.annotator-widget strong{font-weight:bold}.annotator-widget .annotator-listing,.annotator-widget .annotator-item{padding:0;margin:0;list-style:none}.annotator-widget:after{content:"";display:block;width:18px;height:10px;background-position:0 0;position:absolute;bottom:-10px;left:8px}.annotator-invert-x .annotator-widget:after{left:auto;right:8px}.annotator-invert-y .annotator-widget:after{background-position:0 -15px;bottom:auto;top:-9px}.annotator-widget .annotator-item,.annotator-editor .annotator-item input,.annotator-editor .annotator-item textarea{position:relative;font-size:12px}.annotator-viewer .annotator-item{border-top:2px solid #7a7a7a;border-top:2px solid rgba(122,122,122,.2)}.annotator-widget .annotator-item:first-child{border-top:none}.annotator-editor .annotator-item,.annotator-viewer div{border-top:1px solid #858585;border-top:1px solid rgba(133,133,133,.11)}.annotator-viewer div{padding:6px 6px}.annotator-viewer .annotator-item ol,.annotator-viewer .annotator-item ul{padding:4px 16px}.annotator-viewer div:first-of-type,.annotator-editor .annotator-item:first-child textarea{padding-top:12px;padding-bottom:12px;color:#3c3c3c;font-size:13px;font-style:italic;line-height:1.3;border-top:none}.annotator-viewer .annotator-controls{position:relative;top:5px;right:5px;padding-left:5px;opacity:0;transition:opacity .2s ease-in;float:right}.annotator-viewer li:hover .annotator-controls,.annotator-viewer li .annotator-controls.annotator-visible{opacity:1}.annotator-viewer .annotator-controls button,.annotator-viewer .annotator-controls a{cursor:pointer;display:inline-block;width:13px;height:13px;margin-left:2px;border:none;opacity:.2;text-indent:-900em;background-color:rgba(0,0,0,0);outline:none}.annotator-viewer .annotator-controls button:hover,.annotator-viewer .annotator-controls button:focus,.annotator-viewer .annotator-controls a:hover,.annotator-viewer .annotator-controls a:focus{opacity:.9}.annotator-viewer .annotator-controls button:active,.annotator-viewer .annotator-controls a:active{opacity:1}.annotator-viewer .annotator-controls button[disabled]{display:none}.annotator-viewer .annotator-controls .annotator-edit{background-position:0 -60px}.annotator-viewer .annotator-controls .annotator-delete{background-position:0 -75px}.annotator-viewer .annotator-controls .annotator-link{background-position:0 -270px}.annotator-editor .annotator-item{position:relative}.annotator-editor .annotator-item label{top:0;display:inline;cursor:pointer;font-size:12px}.annotator-editor .annotator-item input,.annotator-editor .annotator-item textarea{display:block;min-width:100%;padding:10px 8px;border:none;margin:0;color:#3c3c3c;background:none;-o-box-sizing:border-box;box-sizing:border-box;resize:none}.annotator-editor .annotator-item textarea::-webkit-scrollbar{height:8px;width:8px}.annotator-editor .annotator-item textarea::-webkit-scrollbar-track-piece{margin:13px 0 3px;background-color:#e5e5e5;-webkit-border-radius:4px}.annotator-editor .annotator-item textarea::-webkit-scrollbar-thumb:vertical{height:25px;background-color:#ccc;-webkit-border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.1)}.annotator-editor .annotator-item textarea::-webkit-scrollbar-thumb:horizontal{width:25px;background-color:#ccc;-webkit-border-radius:4px}.annotator-editor .annotator-item:first-child textarea{min-height:5.5em;border-radius:5px 5px 0 0}.annotator-editor .annotator-item input:focus,.annotator-editor .annotator-item textarea:focus{background-color:#f3f3f3;outline:none}.annotator-editor .annotator-item input[type=radio],.annotator-editor .annotator-item input[type=checkbox]{width:auto;min-width:0;padding:0;display:inline;margin:0 4px 0 0;cursor:pointer}.annotator-editor .annotator-checkbox{padding:8px 6px}.annotator-filter,.annotator-filter .annotator-filter-navigation button,.annotator-editor .annotator-controls{text-align:right;padding:3px;border-top:1px solid #d4d4d4;background-color:#d4d4d4;background-image:linear-gradient(to bottom, rgb(245, 245, 245), rgb(220, 220, 220) 60%, rgb(210, 210, 210));-o-box-shadow:inset 1px 0 0 rgba(255,255,255,.7),inset -1px 0 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);box-shadow:inset 1px 0 0 rgba(255,255,255,.7),inset -1px 0 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);border-radius:0 0 5px 5px}.annotator-editor.annotator-invert-y .annotator-controls{border-top:none;border-bottom:1px solid #b4b4b4;border-radius:5px 5px 0 0}.annotator-editor a,.annotator-filter .annotator-filter-property label{position:relative;display:inline-block;padding:0 6px 0 22px;color:#363636;text-shadow:0 1px 0 rgba(255,255,255,.75);text-decoration:none;line-height:24px;font-size:12px;font-weight:bold;border:1px solid #a2a2a2;background-color:#d4d4d4;background-image:linear-gradient(to bottom, rgb(245, 245, 245), rgb(210, 210, 210) 50%, rgb(190, 190, 190) 50%, rgb(210, 210, 210));-o-box-shadow:inset 0 0 5px rgba(255,255,255,.2),inset 0 0 1px rgba(255,255,255,.8);box-shadow:inset 0 0 5px rgba(255,255,255,.2),inset 0 0 1px rgba(255,255,255,.8);border-radius:5px}.annotator-editor a:after{position:absolute;top:50%;left:5px;display:block;content:"";width:15px;height:15px;margin-top:-7px;background-position:0 -90px}.annotator-editor a:hover,.annotator-editor a:focus,.annotator-editor a.annotator-focus,.annotator-filter .annotator-filter-active label,.annotator-filter .annotator-filter-navigation button:hover{outline:none;border-color:#435aa0;background-color:#3865f9;background-image:linear-gradient(to bottom, rgb(118, 145, 251), rgb(80, 117, 251) 50%, rgb(56, 101, 249) 50%, rgb(54, 101, 250));color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.42)}.annotator-editor a:hover:after,.annotator-editor a:focus:after{margin-top:-8px;background-position:0 -105px}.annotator-editor a:active,.annotator-filter .annotator-filter-navigation button:active{border-color:#700c49;background-color:#d12e8e;background-image:linear-gradient(to bottom, rgb(252, 124, 202), rgb(232, 93, 178) 50%, rgb(209, 46, 142) 50%, rgb(255, 0, 156))}.annotator-editor a.annotator-save:after{background-position:0 -120px}.annotator-editor a.annotator-save:hover:after,.annotator-editor a.annotator-save:focus:after,.annotator-editor a.annotator-save.annotator-focus:after{margin-top:-8px;background-position:0 -135px}.annotator-editor .annotator-widget:after{background-position:0 -30px}.annotator-editor.annotator-invert-y .annotator-widget .annotator-controls{background-color:#f2f2f2}.annotator-editor.annotator-invert-y .annotator-widget:after{background-position:0 -45px;height:11px}.annotator-resize{position:absolute;top:0;right:0;width:12px;height:12px;background-position:2px -150px}.annotator-invert-x .annotator-resize{right:auto;left:0;background-position:0 -195px}.annotator-invert-y .annotator-resize{top:auto;bottom:0;background-position:2px -165px}.annotator-invert-y.annotator-invert-x .annotator-resize{background-position:0 -180px}.annotator-notice{color:#fff;position:fixed;top:-54px;left:0;width:100%;font-size:14px;line-height:50px;text-align:center;background:#000;background:rgba(0,0,0,.9);border-bottom:4px solid #d4d4d4;transition:top .4s ease-out}.annotator-notice-success{border-color:#3665f9}.annotator-notice-error{border-color:#ff7e00}.annotator-notice p{margin:0}.annotator-notice a{color:#fff}.annotator-notice-show{top:0}.annotator-tags{margin-bottom:-2px}.annotator-tags .annotator-tag{display:inline-block;padding:0 8px;margin-bottom:2px;line-height:1.6;font-weight:bold;background-color:#e6e6e6;border-radius:8px}.annotator-filter{position:fixed;top:0;right:0;left:0;text-align:left;line-height:0;border:none;border-bottom:1px solid #878787;padding-left:10px;padding-right:10px;border-radius:0;-o-box-shadow:inset 0 -1px 0 rgba(255,255,255,.3);box-shadow:inset 0 -1px 0 rgba(255,255,255,.3)}.annotator-filter strong{font-size:12px;font-weight:bold;color:#3c3c3c;text-shadow:0 1px 0 rgba(255,255,255,.7);position:relative;top:-9px}.annotator-filter .annotator-filter-property,.annotator-filter .annotator-filter-navigation{position:relative;display:inline-block;overflow:hidden;line-height:10px;padding:2px 0;margin-right:8px}.annotator-filter .annotator-filter-property label,.annotator-filter .annotator-filter-navigation button{text-align:left;display:block;float:left;line-height:20px;border-radius:10px 0 0 10px}.annotator-filter .annotator-filter-property label{padding-left:8px}.annotator-filter .annotator-filter-property input{display:block;float:right;-webkit-appearance:none;background-color:#fff;border:1px solid #878787;border-left:none;padding:2px 4px;line-height:16px;min-height:16px;font-size:12px;width:150px;color:#333;background-color:#f8f8f8;border-radius:0 10px 10px 0;-o-box-shadow:inset 0 1px 1px rgba(0,0,0,.2);box-shadow:inset 0 1px 1px rgba(0,0,0,.2)}.annotator-filter .annotator-filter-property input:focus{outline:none;background-color:#fff}.annotator-filter .annotator-filter-clear{position:absolute;right:3px;top:6px;border:none;text-indent:-900em;width:15px;height:15px;background-position:0 -90px;opacity:.4}.annotator-filter .annotator-filter-clear:hover,.annotator-filter .annotator-filter-clear:focus{opacity:.8}.annotator-filter .annotator-filter-clear:active{opacity:1}.annotator-filter .annotator-filter-navigation button{border:1px solid #a2a2a2;padding:0;text-indent:-900px;width:20px;min-height:22px;-o-box-shadow:inset 0 0 5px rgba(255,255,255,.2),inset 0 0 1px rgba(255,255,255,.8);box-shadow:inset 0 0 5px rgba(255,255,255,.2),inset 0 0 1px rgba(255,255,255,.8)}.annotator-filter .annotator-filter-navigation button,.annotator-filter .annotator-filter-navigation button:hover,.annotator-filter .annotator-filter-navigation button:focus{color:rgba(0,0,0,0)}.annotator-filter .annotator-filter-navigation button:after{position:absolute;top:8px;left:8px;content:"";display:block;width:9px;height:9px;background-position:0 -210px}.annotator-filter .annotator-filter-navigation button:hover:after{background-position:0 -225px}.annotator-filter .annotator-filter-navigation .annotator-filter-next{border-radius:0 10px 10px 0;border-left:none}.annotator-filter .annotator-filter-navigation .annotator-filter-next:after{left:auto;right:7px;background-position:0 -240px}.annotator-filter .annotator-filter-navigation .annotator-filter-next:hover:after{background-position:0 -255px}.annotator-hl-active{background:#ffff0a;background:rgba(255,255,10,.8);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#CCFFFF0A, endColorstr=#CCFFFF0A)"}.annotator-hl-filtered{background-color:rgba(0,0,0,0)} -@font-face{font-family:"Material Icons";font-style:normal;font-weight:400;font-display:block;src:url(fonts/MaterialIcons-Regular.eot);src:local("☺"),url(fonts/MaterialIcons-Regular.woff2) format("woff2"),url(fonts/MaterialIcons-Regular.woff) format("woff"),url(fonts/MaterialIcons-Regular.ttf) format("truetype")}.material-icons{font-family:"Material Icons";font-weight:normal;font-style:normal;font-size:24px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:inherit;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:"liga"}.material-icons._10k:before{content:""}.material-icons._10mp:before{content:""}.material-icons._11mp:before{content:""}.material-icons._123:before{content:""}.material-icons._12mp:before{content:""}.material-icons._13mp:before{content:""}.material-icons._14mp:before{content:""}.material-icons._15mp:before{content:""}.material-icons._16mp:before{content:""}.material-icons._17mp:before{content:""}.material-icons._18_up_rating:before{content:""}.material-icons._18mp:before{content:""}.material-icons._19mp:before{content:""}.material-icons._1k:before{content:""}.material-icons._1k_plus:before{content:""}.material-icons._1x_mobiledata:before{content:""}.material-icons._20mp:before{content:""}.material-icons._21mp:before{content:""}.material-icons._22mp:before{content:""}.material-icons._23mp:before{content:""}.material-icons._24mp:before{content:""}.material-icons._2k:before{content:""}.material-icons._2k_plus:before{content:""}.material-icons._2mp:before{content:""}.material-icons._30fps:before{content:""}.material-icons._30fps_select:before{content:""}.material-icons._360:before{content:""}.material-icons._3d_rotation:before{content:""}.material-icons._3g_mobiledata:before{content:""}.material-icons._3k:before{content:""}.material-icons._3k_plus:before{content:""}.material-icons._3mp:before{content:""}.material-icons._3p:before{content:""}.material-icons._4g_mobiledata:before{content:""}.material-icons._4g_plus_mobiledata:before{content:""}.material-icons._4k:before{content:""}.material-icons._4k_plus:before{content:""}.material-icons._4mp:before{content:""}.material-icons._5g:before{content:""}.material-icons._5k:before{content:""}.material-icons._5k_plus:before{content:""}.material-icons._5mp:before{content:""}.material-icons._60fps:before{content:""}.material-icons._60fps_select:before{content:""}.material-icons._6_ft_apart:before{content:""}.material-icons._6k:before{content:""}.material-icons._6k_plus:before{content:""}.material-icons._6mp:before{content:""}.material-icons._7k:before{content:""}.material-icons._7k_plus:before{content:""}.material-icons._7mp:before{content:""}.material-icons._8k:before{content:""}.material-icons._8k_plus:before{content:""}.material-icons._8mp:before{content:""}.material-icons._9k:before{content:""}.material-icons._9k_plus:before{content:""}.material-icons._9mp:before{content:""}.material-icons.abc:before{content:""}.material-icons.ac_unit:before{content:""}.material-icons.access_alarm:before{content:""}.material-icons.access_alarms:before{content:""}.material-icons.access_time:before{content:""}.material-icons.access_time_filled:before{content:""}.material-icons.accessibility:before{content:""}.material-icons.accessibility_new:before{content:""}.material-icons.accessible:before{content:""}.material-icons.accessible_forward:before{content:""}.material-icons.account_balance:before{content:""}.material-icons.account_balance_wallet:before{content:""}.material-icons.account_box:before{content:""}.material-icons.account_circle:before{content:""}.material-icons.account_tree:before{content:""}.material-icons.ad_units:before{content:""}.material-icons.adb:before{content:""}.material-icons.add:before{content:""}.material-icons.add_a_photo:before{content:""}.material-icons.add_alarm:before{content:""}.material-icons.add_alert:before{content:""}.material-icons.add_box:before{content:""}.material-icons.add_business:before{content:""}.material-icons.add_call:before{content:""}.material-icons.add_card:before{content:""}.material-icons.add_chart:before{content:""}.material-icons.add_circle:before{content:""}.material-icons.add_circle_outline:before{content:""}.material-icons.add_comment:before{content:""}.material-icons.add_home:before{content:""}.material-icons.add_home_work:before{content:""}.material-icons.add_ic_call:before{content:""}.material-icons.add_link:before{content:""}.material-icons.add_location:before{content:""}.material-icons.add_location_alt:before{content:""}.material-icons.add_moderator:before{content:""}.material-icons.add_photo_alternate:before{content:""}.material-icons.add_reaction:before{content:""}.material-icons.add_road:before{content:""}.material-icons.add_shopping_cart:before{content:""}.material-icons.add_task:before{content:""}.material-icons.add_to_drive:before{content:""}.material-icons.add_to_home_screen:before{content:""}.material-icons.add_to_photos:before{content:""}.material-icons.add_to_queue:before{content:""}.material-icons.addchart:before{content:""}.material-icons.adf_scanner:before{content:""}.material-icons.adjust:before{content:""}.material-icons.admin_panel_settings:before{content:""}.material-icons.adobe:before{content:""}.material-icons.ads_click:before{content:""}.material-icons.agriculture:before{content:""}.material-icons.air:before{content:""}.material-icons.airline_seat_flat:before{content:""}.material-icons.airline_seat_flat_angled:before{content:""}.material-icons.airline_seat_individual_suite:before{content:""}.material-icons.airline_seat_legroom_extra:before{content:""}.material-icons.airline_seat_legroom_normal:before{content:""}.material-icons.airline_seat_legroom_reduced:before{content:""}.material-icons.airline_seat_recline_extra:before{content:""}.material-icons.airline_seat_recline_normal:before{content:""}.material-icons.airline_stops:before{content:""}.material-icons.airlines:before{content:""}.material-icons.airplane_ticket:before{content:""}.material-icons.airplanemode_active:before{content:""}.material-icons.airplanemode_inactive:before{content:""}.material-icons.airplanemode_off:before{content:""}.material-icons.airplanemode_on:before{content:""}.material-icons.airplay:before{content:""}.material-icons.airport_shuttle:before{content:""}.material-icons.alarm:before{content:""}.material-icons.alarm_add:before{content:""}.material-icons.alarm_off:before{content:""}.material-icons.alarm_on:before{content:""}.material-icons.album:before{content:""}.material-icons.align_horizontal_center:before{content:""}.material-icons.align_horizontal_left:before{content:""}.material-icons.align_horizontal_right:before{content:""}.material-icons.align_vertical_bottom:before{content:""}.material-icons.align_vertical_center:before{content:""}.material-icons.align_vertical_top:before{content:""}.material-icons.all_inbox:before{content:""}.material-icons.all_inclusive:before{content:""}.material-icons.all_out:before{content:""}.material-icons.alt_route:before{content:""}.material-icons.alternate_email:before{content:""}.material-icons.amp_stories:before{content:""}.material-icons.analytics:before{content:""}.material-icons.anchor:before{content:""}.material-icons.android:before{content:""}.material-icons.animation:before{content:""}.material-icons.announcement:before{content:""}.material-icons.aod:before{content:""}.material-icons.apartment:before{content:""}.material-icons.api:before{content:""}.material-icons.app_blocking:before{content:""}.material-icons.app_registration:before{content:""}.material-icons.app_settings_alt:before{content:""}.material-icons.app_shortcut:before{content:""}.material-icons.apple:before{content:""}.material-icons.approval:before{content:""}.material-icons.apps:before{content:""}.material-icons.apps_outage:before{content:""}.material-icons.architecture:before{content:""}.material-icons.archive:before{content:""}.material-icons.area_chart:before{content:""}.material-icons.arrow_back:before{content:""}.material-icons.arrow_back_ios:before{content:""}.material-icons.arrow_back_ios_new:before{content:""}.material-icons.arrow_circle_down:before{content:""}.material-icons.arrow_circle_left:before{content:""}.material-icons.arrow_circle_right:before{content:""}.material-icons.arrow_circle_up:before{content:""}.material-icons.arrow_downward:before{content:""}.material-icons.arrow_drop_down:before{content:""}.material-icons.arrow_drop_down_circle:before{content:""}.material-icons.arrow_drop_up:before{content:""}.material-icons.arrow_forward:before{content:""}.material-icons.arrow_forward_ios:before{content:""}.material-icons.arrow_left:before{content:""}.material-icons.arrow_right:before{content:""}.material-icons.arrow_right_alt:before{content:""}.material-icons.arrow_upward:before{content:""}.material-icons.art_track:before{content:""}.material-icons.article:before{content:""}.material-icons.aspect_ratio:before{content:""}.material-icons.assessment:before{content:""}.material-icons.assignment:before{content:""}.material-icons.assignment_ind:before{content:""}.material-icons.assignment_late:before{content:""}.material-icons.assignment_return:before{content:""}.material-icons.assignment_returned:before{content:""}.material-icons.assignment_turned_in:before{content:""}.material-icons.assistant:before{content:""}.material-icons.assistant_direction:before{content:""}.material-icons.assistant_navigation:before{content:""}.material-icons.assistant_photo:before{content:""}.material-icons.assured_workload:before{content:""}.material-icons.atm:before{content:""}.material-icons.attach_email:before{content:""}.material-icons.attach_file:before{content:""}.material-icons.attach_money:before{content:""}.material-icons.attachment:before{content:""}.material-icons.attractions:before{content:""}.material-icons.attribution:before{content:""}.material-icons.audio_file:before{content:""}.material-icons.audiotrack:before{content:""}.material-icons.auto_awesome:before{content:""}.material-icons.auto_awesome_mosaic:before{content:""}.material-icons.auto_awesome_motion:before{content:""}.material-icons.auto_delete:before{content:""}.material-icons.auto_fix_high:before{content:""}.material-icons.auto_fix_normal:before{content:""}.material-icons.auto_fix_off:before{content:""}.material-icons.auto_graph:before{content:""}.material-icons.auto_mode:before{content:""}.material-icons.auto_stories:before{content:""}.material-icons.autofps_select:before{content:""}.material-icons.autorenew:before{content:""}.material-icons.av_timer:before{content:""}.material-icons.baby_changing_station:before{content:""}.material-icons.back_hand:before{content:""}.material-icons.backpack:before{content:""}.material-icons.backspace:before{content:""}.material-icons.backup:before{content:""}.material-icons.backup_table:before{content:""}.material-icons.badge:before{content:""}.material-icons.bakery_dining:before{content:""}.material-icons.balance:before{content:""}.material-icons.balcony:before{content:""}.material-icons.ballot:before{content:""}.material-icons.bar_chart:before{content:""}.material-icons.batch_prediction:before{content:""}.material-icons.bathroom:before{content:""}.material-icons.bathtub:before{content:""}.material-icons.battery_0_bar:before{content:""}.material-icons.battery_1_bar:before{content:""}.material-icons.battery_2_bar:before{content:""}.material-icons.battery_3_bar:before{content:""}.material-icons.battery_4_bar:before{content:""}.material-icons.battery_5_bar:before{content:""}.material-icons.battery_6_bar:before{content:""}.material-icons.battery_alert:before{content:""}.material-icons.battery_charging_full:before{content:""}.material-icons.battery_full:before{content:""}.material-icons.battery_saver:before{content:""}.material-icons.battery_std:before{content:""}.material-icons.battery_unknown:before{content:""}.material-icons.beach_access:before{content:""}.material-icons.bed:before{content:""}.material-icons.bedroom_baby:before{content:""}.material-icons.bedroom_child:before{content:""}.material-icons.bedroom_parent:before{content:""}.material-icons.bedtime:before{content:""}.material-icons.bedtime_off:before{content:""}.material-icons.beenhere:before{content:""}.material-icons.bento:before{content:""}.material-icons.bike_scooter:before{content:""}.material-icons.biotech:before{content:""}.material-icons.blender:before{content:""}.material-icons.blinds:before{content:""}.material-icons.blinds_closed:before{content:""}.material-icons.block:before{content:""}.material-icons.block_flipped:before{content:""}.material-icons.bloodtype:before{content:""}.material-icons.bluetooth:before{content:""}.material-icons.bluetooth_audio:before{content:""}.material-icons.bluetooth_connected:before{content:""}.material-icons.bluetooth_disabled:before{content:""}.material-icons.bluetooth_drive:before{content:""}.material-icons.bluetooth_searching:before{content:""}.material-icons.blur_circular:before{content:""}.material-icons.blur_linear:before{content:""}.material-icons.blur_off:before{content:""}.material-icons.blur_on:before{content:""}.material-icons.bolt:before{content:""}.material-icons.book:before{content:""}.material-icons.book_online:before{content:""}.material-icons.bookmark:before{content:""}.material-icons.bookmark_add:before{content:""}.material-icons.bookmark_added:before{content:""}.material-icons.bookmark_border:before{content:""}.material-icons.bookmark_outline:before{content:""}.material-icons.bookmark_remove:before{content:""}.material-icons.bookmarks:before{content:""}.material-icons.border_all:before{content:""}.material-icons.border_bottom:before{content:""}.material-icons.border_clear:before{content:""}.material-icons.border_color:before{content:""}.material-icons.border_horizontal:before{content:""}.material-icons.border_inner:before{content:""}.material-icons.border_left:before{content:""}.material-icons.border_outer:before{content:""}.material-icons.border_right:before{content:""}.material-icons.border_style:before{content:""}.material-icons.border_top:before{content:""}.material-icons.border_vertical:before{content:""}.material-icons.boy:before{content:""}.material-icons.branding_watermark:before{content:""}.material-icons.breakfast_dining:before{content:""}.material-icons.brightness_1:before{content:""}.material-icons.brightness_2:before{content:""}.material-icons.brightness_3:before{content:""}.material-icons.brightness_4:before{content:""}.material-icons.brightness_5:before{content:""}.material-icons.brightness_6:before{content:""}.material-icons.brightness_7:before{content:""}.material-icons.brightness_auto:before{content:""}.material-icons.brightness_high:before{content:""}.material-icons.brightness_low:before{content:""}.material-icons.brightness_medium:before{content:""}.material-icons.broadcast_on_home:before{content:""}.material-icons.broadcast_on_personal:before{content:""}.material-icons.broken_image:before{content:""}.material-icons.browse_gallery:before{content:""}.material-icons.browser_not_supported:before{content:""}.material-icons.browser_updated:before{content:""}.material-icons.brunch_dining:before{content:""}.material-icons.brush:before{content:""}.material-icons.bubble_chart:before{content:""}.material-icons.bug_report:before{content:""}.material-icons.build:before{content:""}.material-icons.build_circle:before{content:""}.material-icons.bungalow:before{content:""}.material-icons.burst_mode:before{content:""}.material-icons.bus_alert:before{content:""}.material-icons.business:before{content:""}.material-icons.business_center:before{content:""}.material-icons.cabin:before{content:""}.material-icons.cable:before{content:""}.material-icons.cached:before{content:""}.material-icons.cake:before{content:""}.material-icons.calculate:before{content:""}.material-icons.calendar_month:before{content:""}.material-icons.calendar_today:before{content:""}.material-icons.calendar_view_day:before{content:""}.material-icons.calendar_view_month:before{content:""}.material-icons.calendar_view_week:before{content:""}.material-icons.call:before{content:""}.material-icons.call_end:before{content:""}.material-icons.call_made:before{content:""}.material-icons.call_merge:before{content:""}.material-icons.call_missed:before{content:""}.material-icons.call_missed_outgoing:before{content:""}.material-icons.call_received:before{content:""}.material-icons.call_split:before{content:""}.material-icons.call_to_action:before{content:""}.material-icons.camera:before{content:""}.material-icons.camera_alt:before{content:""}.material-icons.camera_enhance:before{content:""}.material-icons.camera_front:before{content:""}.material-icons.camera_indoor:before{content:""}.material-icons.camera_outdoor:before{content:""}.material-icons.camera_rear:before{content:""}.material-icons.camera_roll:before{content:""}.material-icons.cameraswitch:before{content:""}.material-icons.campaign:before{content:""}.material-icons.cancel:before{content:""}.material-icons.cancel_presentation:before{content:""}.material-icons.cancel_schedule_send:before{content:""}.material-icons.candlestick_chart:before{content:""}.material-icons.car_crash:before{content:""}.material-icons.car_rental:before{content:""}.material-icons.car_repair:before{content:""}.material-icons.card_giftcard:before{content:""}.material-icons.card_membership:before{content:""}.material-icons.card_travel:before{content:""}.material-icons.carpenter:before{content:""}.material-icons.cases:before{content:""}.material-icons.casino:before{content:""}.material-icons.cast:before{content:""}.material-icons.cast_connected:before{content:""}.material-icons.cast_for_education:before{content:""}.material-icons.castle:before{content:""}.material-icons.catching_pokemon:before{content:""}.material-icons.category:before{content:""}.material-icons.celebration:before{content:""}.material-icons.cell_tower:before{content:""}.material-icons.cell_wifi:before{content:""}.material-icons.center_focus_strong:before{content:""}.material-icons.center_focus_weak:before{content:""}.material-icons.chair:before{content:""}.material-icons.chair_alt:before{content:""}.material-icons.chalet:before{content:""}.material-icons.change_circle:before{content:""}.material-icons.change_history:before{content:""}.material-icons.charging_station:before{content:""}.material-icons.chat:before{content:""}.material-icons.chat_bubble:before{content:""}.material-icons.chat_bubble_outline:before{content:""}.material-icons.check:before{content:""}.material-icons.check_box:before{content:""}.material-icons.check_box_outline_blank:before{content:""}.material-icons.check_circle:before{content:""}.material-icons.check_circle_outline:before{content:""}.material-icons.checklist:before{content:""}.material-icons.checklist_rtl:before{content:""}.material-icons.checkroom:before{content:""}.material-icons.chevron_left:before{content:""}.material-icons.chevron_right:before{content:""}.material-icons.child_care:before{content:""}.material-icons.child_friendly:before{content:""}.material-icons.chrome_reader_mode:before{content:""}.material-icons.church:before{content:""}.material-icons.circle:before{content:""}.material-icons.circle_notifications:before{content:""}.material-icons.class:before{content:""}.material-icons.clean_hands:before{content:""}.material-icons.cleaning_services:before{content:""}.material-icons.clear:before{content:""}.material-icons.clear_all:before{content:""}.material-icons.close:before{content:""}.material-icons.close_fullscreen:before{content:""}.material-icons.closed_caption:before{content:""}.material-icons.closed_caption_disabled:before{content:""}.material-icons.closed_caption_off:before{content:""}.material-icons.cloud:before{content:""}.material-icons.cloud_circle:before{content:""}.material-icons.cloud_done:before{content:""}.material-icons.cloud_download:before{content:""}.material-icons.cloud_off:before{content:""}.material-icons.cloud_queue:before{content:""}.material-icons.cloud_sync:before{content:""}.material-icons.cloud_upload:before{content:""}.material-icons.cloudy_snowing:before{content:""}.material-icons.co2:before{content:""}.material-icons.co_present:before{content:""}.material-icons.code:before{content:""}.material-icons.code_off:before{content:""}.material-icons.coffee:before{content:""}.material-icons.coffee_maker:before{content:""}.material-icons.collections:before{content:""}.material-icons.collections_bookmark:before{content:""}.material-icons.color_lens:before{content:""}.material-icons.colorize:before{content:""}.material-icons.comment:before{content:""}.material-icons.comment_bank:before{content:""}.material-icons.comments_disabled:before{content:""}.material-icons.commit:before{content:""}.material-icons.commute:before{content:""}.material-icons.compare:before{content:""}.material-icons.compare_arrows:before{content:""}.material-icons.compass_calibration:before{content:""}.material-icons.compost:before{content:""}.material-icons.compress:before{content:""}.material-icons.computer:before{content:""}.material-icons.confirmation_num:before{content:""}.material-icons.confirmation_number:before{content:""}.material-icons.connect_without_contact:before{content:""}.material-icons.connected_tv:before{content:""}.material-icons.connecting_airports:before{content:""}.material-icons.construction:before{content:""}.material-icons.contact_mail:before{content:""}.material-icons.contact_page:before{content:""}.material-icons.contact_phone:before{content:""}.material-icons.contact_support:before{content:""}.material-icons.contactless:before{content:""}.material-icons.contacts:before{content:""}.material-icons.content_copy:before{content:""}.material-icons.content_cut:before{content:""}.material-icons.content_paste:before{content:""}.material-icons.content_paste_go:before{content:""}.material-icons.content_paste_off:before{content:""}.material-icons.content_paste_search:before{content:""}.material-icons.contrast:before{content:""}.material-icons.control_camera:before{content:""}.material-icons.control_point:before{content:""}.material-icons.control_point_duplicate:before{content:""}.material-icons.cookie:before{content:""}.material-icons.copy_all:before{content:""}.material-icons.copyright:before{content:""}.material-icons.coronavirus:before{content:""}.material-icons.corporate_fare:before{content:""}.material-icons.cottage:before{content:""}.material-icons.countertops:before{content:""}.material-icons.create:before{content:""}.material-icons.create_new_folder:before{content:""}.material-icons.credit_card:before{content:""}.material-icons.credit_card_off:before{content:""}.material-icons.credit_score:before{content:""}.material-icons.crib:before{content:""}.material-icons.crisis_alert:before{content:""}.material-icons.crop:before{content:""}.material-icons.crop_16_9:before{content:""}.material-icons.crop_3_2:before{content:""}.material-icons.crop_5_4:before{content:""}.material-icons.crop_7_5:before{content:""}.material-icons.crop_din:before{content:""}.material-icons.crop_free:before{content:""}.material-icons.crop_landscape:before{content:""}.material-icons.crop_original:before{content:""}.material-icons.crop_portrait:before{content:""}.material-icons.crop_rotate:before{content:""}.material-icons.crop_square:before{content:""}.material-icons.cruelty_free:before{content:""}.material-icons.css:before{content:""}.material-icons.currency_bitcoin:before{content:""}.material-icons.currency_exchange:before{content:""}.material-icons.currency_franc:before{content:""}.material-icons.currency_lira:before{content:""}.material-icons.currency_pound:before{content:""}.material-icons.currency_ruble:before{content:""}.material-icons.currency_rupee:before{content:""}.material-icons.currency_yen:before{content:""}.material-icons.currency_yuan:before{content:""}.material-icons.curtains:before{content:""}.material-icons.curtains_closed:before{content:""}.material-icons.cyclone:before{content:""}.material-icons.dangerous:before{content:""}.material-icons.dark_mode:before{content:""}.material-icons.dashboard:before{content:""}.material-icons.dashboard_customize:before{content:""}.material-icons.data_array:before{content:""}.material-icons.data_exploration:before{content:""}.material-icons.data_object:before{content:""}.material-icons.data_saver_off:before{content:""}.material-icons.data_saver_on:before{content:""}.material-icons.data_thresholding:before{content:""}.material-icons.data_usage:before{content:""}.material-icons.dataset:before{content:""}.material-icons.dataset_linked:before{content:""}.material-icons.date_range:before{content:""}.material-icons.deblur:before{content:""}.material-icons.deck:before{content:""}.material-icons.dehaze:before{content:""}.material-icons.delete:before{content:""}.material-icons.delete_forever:before{content:""}.material-icons.delete_outline:before{content:""}.material-icons.delete_sweep:before{content:""}.material-icons.delivery_dining:before{content:""}.material-icons.density_large:before{content:""}.material-icons.density_medium:before{content:""}.material-icons.density_small:before{content:""}.material-icons.departure_board:before{content:""}.material-icons.description:before{content:""}.material-icons.deselect:before{content:""}.material-icons.design_services:before{content:""}.material-icons.desk:before{content:""}.material-icons.desktop_access_disabled:before{content:""}.material-icons.desktop_mac:before{content:""}.material-icons.desktop_windows:before{content:""}.material-icons.details:before{content:""}.material-icons.developer_board:before{content:""}.material-icons.developer_board_off:before{content:""}.material-icons.developer_mode:before{content:""}.material-icons.device_hub:before{content:""}.material-icons.device_thermostat:before{content:""}.material-icons.device_unknown:before{content:""}.material-icons.devices:before{content:""}.material-icons.devices_fold:before{content:""}.material-icons.devices_other:before{content:""}.material-icons.dialer_sip:before{content:""}.material-icons.dialpad:before{content:""}.material-icons.diamond:before{content:""}.material-icons.difference:before{content:""}.material-icons.dining:before{content:""}.material-icons.dinner_dining:before{content:""}.material-icons.directions:before{content:""}.material-icons.directions_bike:before{content:""}.material-icons.directions_boat:before{content:""}.material-icons.directions_boat_filled:before{content:""}.material-icons.directions_bus:before{content:""}.material-icons.directions_bus_filled:before{content:""}.material-icons.directions_car:before{content:""}.material-icons.directions_car_filled:before{content:""}.material-icons.directions_ferry:before{content:""}.material-icons.directions_off:before{content:""}.material-icons.directions_railway:before{content:""}.material-icons.directions_railway_filled:before{content:""}.material-icons.directions_run:before{content:""}.material-icons.directions_subway:before{content:""}.material-icons.directions_subway_filled:before{content:""}.material-icons.directions_train:before{content:""}.material-icons.directions_transit:before{content:""}.material-icons.directions_transit_filled:before{content:""}.material-icons.directions_walk:before{content:""}.material-icons.dirty_lens:before{content:""}.material-icons.disabled_by_default:before{content:""}.material-icons.disabled_visible:before{content:""}.material-icons.disc_full:before{content:""}.material-icons.discord:before{content:""}.material-icons.discount:before{content:""}.material-icons.display_settings:before{content:""}.material-icons.dnd_forwardslash:before{content:""}.material-icons.dns:before{content:""}.material-icons.do_disturb:before{content:""}.material-icons.do_disturb_alt:before{content:""}.material-icons.do_disturb_off:before{content:""}.material-icons.do_disturb_on:before{content:""}.material-icons.do_not_disturb:before{content:""}.material-icons.do_not_disturb_alt:before{content:""}.material-icons.do_not_disturb_off:before{content:""}.material-icons.do_not_disturb_on:before{content:""}.material-icons.do_not_disturb_on_total_silence:before{content:""}.material-icons.do_not_step:before{content:""}.material-icons.do_not_touch:before{content:""}.material-icons.dock:before{content:""}.material-icons.document_scanner:before{content:""}.material-icons.domain:before{content:""}.material-icons.domain_add:before{content:""}.material-icons.domain_disabled:before{content:""}.material-icons.domain_verification:before{content:""}.material-icons.done:before{content:""}.material-icons.done_all:before{content:""}.material-icons.done_outline:before{content:""}.material-icons.donut_large:before{content:""}.material-icons.donut_small:before{content:""}.material-icons.door_back:before{content:""}.material-icons.door_front:before{content:""}.material-icons.door_sliding:before{content:""}.material-icons.doorbell:before{content:""}.material-icons.double_arrow:before{content:""}.material-icons.downhill_skiing:before{content:""}.material-icons.download:before{content:""}.material-icons.download_done:before{content:""}.material-icons.download_for_offline:before{content:""}.material-icons.downloading:before{content:""}.material-icons.drafts:before{content:""}.material-icons.drag_handle:before{content:""}.material-icons.drag_indicator:before{content:""}.material-icons.draw:before{content:""}.material-icons.drive_eta:before{content:""}.material-icons.drive_file_move:before{content:""}.material-icons.drive_file_move_outline:before{content:""}.material-icons.drive_file_move_rtl:before{content:""}.material-icons.drive_file_rename_outline:before{content:""}.material-icons.drive_folder_upload:before{content:""}.material-icons.dry:before{content:""}.material-icons.dry_cleaning:before{content:""}.material-icons.duo:before{content:""}.material-icons.dvr:before{content:""}.material-icons.dynamic_feed:before{content:""}.material-icons.dynamic_form:before{content:""}.material-icons.e_mobiledata:before{content:""}.material-icons.earbuds:before{content:""}.material-icons.earbuds_battery:before{content:""}.material-icons.east:before{content:""}.material-icons.eco:before{content:""}.material-icons.edgesensor_high:before{content:""}.material-icons.edgesensor_low:before{content:""}.material-icons.edit:before{content:""}.material-icons.edit_attributes:before{content:""}.material-icons.edit_calendar:before{content:""}.material-icons.edit_location:before{content:""}.material-icons.edit_location_alt:before{content:""}.material-icons.edit_note:before{content:""}.material-icons.edit_notifications:before{content:""}.material-icons.edit_off:before{content:""}.material-icons.edit_road:before{content:""}.material-icons.egg:before{content:""}.material-icons.egg_alt:before{content:""}.material-icons.eject:before{content:""}.material-icons.elderly:before{content:""}.material-icons.elderly_woman:before{content:""}.material-icons.electric_bike:before{content:""}.material-icons.electric_bolt:before{content:""}.material-icons.electric_car:before{content:""}.material-icons.electric_meter:before{content:""}.material-icons.electric_moped:before{content:""}.material-icons.electric_rickshaw:before{content:""}.material-icons.electric_scooter:before{content:""}.material-icons.electrical_services:before{content:""}.material-icons.elevator:before{content:""}.material-icons.email:before{content:""}.material-icons.emergency:before{content:""}.material-icons.emergency_recording:before{content:""}.material-icons.emergency_share:before{content:""}.material-icons.emoji_emotions:before{content:""}.material-icons.emoji_events:before{content:""}.material-icons.emoji_flags:before{content:""}.material-icons.emoji_food_beverage:before{content:""}.material-icons.emoji_nature:before{content:""}.material-icons.emoji_objects:before{content:""}.material-icons.emoji_people:before{content:""}.material-icons.emoji_symbols:before{content:""}.material-icons.emoji_transportation:before{content:""}.material-icons.energy_savings_leaf:before{content:""}.material-icons.engineering:before{content:""}.material-icons.enhance_photo_translate:before{content:""}.material-icons.enhanced_encryption:before{content:""}.material-icons.equalizer:before{content:""}.material-icons.error:before{content:""}.material-icons.error_outline:before{content:""}.material-icons.escalator:before{content:""}.material-icons.escalator_warning:before{content:""}.material-icons.euro:before{content:""}.material-icons.euro_symbol:before{content:""}.material-icons.ev_station:before{content:""}.material-icons.event:before{content:""}.material-icons.event_available:before{content:""}.material-icons.event_busy:before{content:""}.material-icons.event_note:before{content:""}.material-icons.event_repeat:before{content:""}.material-icons.event_seat:before{content:""}.material-icons.exit_to_app:before{content:""}.material-icons.expand:before{content:""}.material-icons.expand_circle_down:before{content:""}.material-icons.expand_less:before{content:""}.material-icons.expand_more:before{content:""}.material-icons.explicit:before{content:""}.material-icons.explore:before{content:""}.material-icons.explore_off:before{content:""}.material-icons.exposure:before{content:""}.material-icons.exposure_minus_1:before{content:""}.material-icons.exposure_minus_2:before{content:""}.material-icons.exposure_neg_1:before{content:""}.material-icons.exposure_neg_2:before{content:""}.material-icons.exposure_plus_1:before{content:""}.material-icons.exposure_plus_2:before{content:""}.material-icons.exposure_zero:before{content:""}.material-icons.extension:before{content:""}.material-icons.extension_off:before{content:""}.material-icons.face:before{content:""}.material-icons.face_retouching_natural:before{content:""}.material-icons.face_retouching_off:before{content:""}.material-icons.facebook:before{content:""}.material-icons.fact_check:before{content:""}.material-icons.factory:before{content:""}.material-icons.family_restroom:before{content:""}.material-icons.fast_forward:before{content:""}.material-icons.fast_rewind:before{content:""}.material-icons.fastfood:before{content:""}.material-icons.favorite:before{content:""}.material-icons.favorite_border:before{content:""}.material-icons.favorite_outline:before{content:""}.material-icons.fax:before{content:""}.material-icons.featured_play_list:before{content:""}.material-icons.featured_video:before{content:""}.material-icons.feed:before{content:""}.material-icons.feedback:before{content:""}.material-icons.female:before{content:""}.material-icons.fence:before{content:""}.material-icons.festival:before{content:""}.material-icons.fiber_dvr:before{content:""}.material-icons.fiber_manual_record:before{content:""}.material-icons.fiber_new:before{content:""}.material-icons.fiber_pin:before{content:""}.material-icons.fiber_smart_record:before{content:""}.material-icons.file_copy:before{content:""}.material-icons.file_download:before{content:""}.material-icons.file_download_done:before{content:""}.material-icons.file_download_off:before{content:""}.material-icons.file_open:before{content:""}.material-icons.file_present:before{content:""}.material-icons.file_upload:before{content:""}.material-icons.filter:before{content:""}.material-icons.filter_1:before{content:""}.material-icons.filter_2:before{content:""}.material-icons.filter_3:before{content:""}.material-icons.filter_4:before{content:""}.material-icons.filter_5:before{content:""}.material-icons.filter_6:before{content:""}.material-icons.filter_7:before{content:""}.material-icons.filter_8:before{content:""}.material-icons.filter_9:before{content:""}.material-icons.filter_9_plus:before{content:""}.material-icons.filter_alt:before{content:""}.material-icons.filter_alt_off:before{content:""}.material-icons.filter_b_and_w:before{content:""}.material-icons.filter_center_focus:before{content:""}.material-icons.filter_drama:before{content:""}.material-icons.filter_frames:before{content:""}.material-icons.filter_hdr:before{content:""}.material-icons.filter_list:before{content:""}.material-icons.filter_list_alt:before{content:""}.material-icons.filter_list_off:before{content:""}.material-icons.filter_none:before{content:""}.material-icons.filter_tilt_shift:before{content:""}.material-icons.filter_vintage:before{content:""}.material-icons.find_in_page:before{content:""}.material-icons.find_replace:before{content:""}.material-icons.fingerprint:before{content:""}.material-icons.fire_extinguisher:before{content:""}.material-icons.fire_hydrant:before{content:""}.material-icons.fire_hydrant_alt:before{content:""}.material-icons.fire_truck:before{content:""}.material-icons.fireplace:before{content:""}.material-icons.first_page:before{content:""}.material-icons.fit_screen:before{content:""}.material-icons.fitbit:before{content:""}.material-icons.fitness_center:before{content:""}.material-icons.flag:before{content:""}.material-icons.flag_circle:before{content:""}.material-icons.flaky:before{content:""}.material-icons.flare:before{content:""}.material-icons.flash_auto:before{content:""}.material-icons.flash_off:before{content:""}.material-icons.flash_on:before{content:""}.material-icons.flashlight_off:before{content:""}.material-icons.flashlight_on:before{content:""}.material-icons.flatware:before{content:""}.material-icons.flight:before{content:""}.material-icons.flight_class:before{content:""}.material-icons.flight_land:before{content:""}.material-icons.flight_takeoff:before{content:""}.material-icons.flip:before{content:""}.material-icons.flip_camera_android:before{content:""}.material-icons.flip_camera_ios:before{content:""}.material-icons.flip_to_back:before{content:""}.material-icons.flip_to_front:before{content:""}.material-icons.flood:before{content:""}.material-icons.flourescent:before{content:""}.material-icons.flutter_dash:before{content:""}.material-icons.fmd_bad:before{content:""}.material-icons.fmd_good:before{content:""}.material-icons.foggy:before{content:""}.material-icons.folder:before{content:""}.material-icons.folder_copy:before{content:""}.material-icons.folder_delete:before{content:""}.material-icons.folder_off:before{content:""}.material-icons.folder_open:before{content:""}.material-icons.folder_shared:before{content:""}.material-icons.folder_special:before{content:""}.material-icons.folder_zip:before{content:""}.material-icons.follow_the_signs:before{content:""}.material-icons.font_download:before{content:""}.material-icons.font_download_off:before{content:""}.material-icons.food_bank:before{content:""}.material-icons.forest:before{content:""}.material-icons.fork_left:before{content:""}.material-icons.fork_right:before{content:""}.material-icons.format_align_center:before{content:""}.material-icons.format_align_justify:before{content:""}.material-icons.format_align_left:before{content:""}.material-icons.format_align_right:before{content:""}.material-icons.format_bold:before{content:""}.material-icons.format_clear:before{content:""}.material-icons.format_color_fill:before{content:""}.material-icons.format_color_reset:before{content:""}.material-icons.format_color_text:before{content:""}.material-icons.format_indent_decrease:before{content:""}.material-icons.format_indent_increase:before{content:""}.material-icons.format_italic:before{content:""}.material-icons.format_line_spacing:before{content:""}.material-icons.format_list_bulleted:before{content:""}.material-icons.format_list_numbered:before{content:""}.material-icons.format_list_numbered_rtl:before{content:""}.material-icons.format_overline:before{content:""}.material-icons.format_paint:before{content:""}.material-icons.format_quote:before{content:""}.material-icons.format_shapes:before{content:""}.material-icons.format_size:before{content:""}.material-icons.format_strikethrough:before{content:""}.material-icons.format_textdirection_l_to_r:before{content:""}.material-icons.format_textdirection_r_to_l:before{content:""}.material-icons.format_underline:before{content:""}.material-icons.format_underlined:before{content:""}.material-icons.fort:before{content:""}.material-icons.forum:before{content:""}.material-icons.forward:before{content:""}.material-icons.forward_10:before{content:""}.material-icons.forward_30:before{content:""}.material-icons.forward_5:before{content:""}.material-icons.forward_to_inbox:before{content:""}.material-icons.foundation:before{content:""}.material-icons.free_breakfast:before{content:""}.material-icons.free_cancellation:before{content:""}.material-icons.front_hand:before{content:""}.material-icons.fullscreen:before{content:""}.material-icons.fullscreen_exit:before{content:""}.material-icons.functions:before{content:""}.material-icons.g_mobiledata:before{content:""}.material-icons.g_translate:before{content:""}.material-icons.gamepad:before{content:""}.material-icons.games:before{content:""}.material-icons.garage:before{content:""}.material-icons.gas_meter:before{content:""}.material-icons.gavel:before{content:""}.material-icons.generating_tokens:before{content:""}.material-icons.gesture:before{content:""}.material-icons.get_app:before{content:""}.material-icons.gif:before{content:""}.material-icons.gif_box:before{content:""}.material-icons.girl:before{content:""}.material-icons.gite:before{content:""}.material-icons.goat:before{content:""}.material-icons.golf_course:before{content:""}.material-icons.gpp_bad:before{content:""}.material-icons.gpp_good:before{content:""}.material-icons.gpp_maybe:before{content:""}.material-icons.gps_fixed:before{content:""}.material-icons.gps_not_fixed:before{content:""}.material-icons.gps_off:before{content:""}.material-icons.grade:before{content:""}.material-icons.gradient:before{content:""}.material-icons.grading:before{content:""}.material-icons.grain:before{content:""}.material-icons.graphic_eq:before{content:""}.material-icons.grass:before{content:""}.material-icons.grid_3x3:before{content:""}.material-icons.grid_4x4:before{content:""}.material-icons.grid_goldenratio:before{content:""}.material-icons.grid_off:before{content:""}.material-icons.grid_on:before{content:""}.material-icons.grid_view:before{content:""}.material-icons.group:before{content:""}.material-icons.group_add:before{content:""}.material-icons.group_off:before{content:""}.material-icons.group_remove:before{content:""}.material-icons.group_work:before{content:""}.material-icons.groups:before{content:""}.material-icons.h_mobiledata:before{content:""}.material-icons.h_plus_mobiledata:before{content:""}.material-icons.hail:before{content:""}.material-icons.handshake:before{content:""}.material-icons.handyman:before{content:""}.material-icons.hardware:before{content:""}.material-icons.hd:before{content:""}.material-icons.hdr_auto:before{content:""}.material-icons.hdr_auto_select:before{content:""}.material-icons.hdr_enhanced_select:before{content:""}.material-icons.hdr_off:before{content:""}.material-icons.hdr_off_select:before{content:""}.material-icons.hdr_on:before{content:""}.material-icons.hdr_on_select:before{content:""}.material-icons.hdr_plus:before{content:""}.material-icons.hdr_strong:before{content:""}.material-icons.hdr_weak:before{content:""}.material-icons.headphones:before{content:""}.material-icons.headphones_battery:before{content:""}.material-icons.headset:before{content:""}.material-icons.headset_mic:before{content:""}.material-icons.headset_off:before{content:""}.material-icons.healing:before{content:""}.material-icons.health_and_safety:before{content:""}.material-icons.hearing:before{content:""}.material-icons.hearing_disabled:before{content:""}.material-icons.heart_broken:before{content:""}.material-icons.heat_pump:before{content:""}.material-icons.height:before{content:""}.material-icons.help:before{content:""}.material-icons.help_center:before{content:""}.material-icons.help_outline:before{content:""}.material-icons.hevc:before{content:""}.material-icons.hexagon:before{content:""}.material-icons.hide_image:before{content:""}.material-icons.hide_source:before{content:""}.material-icons.high_quality:before{content:""}.material-icons.highlight:before{content:""}.material-icons.highlight_alt:before{content:""}.material-icons.highlight_off:before{content:""}.material-icons.highlight_remove:before{content:""}.material-icons.hiking:before{content:""}.material-icons.history:before{content:""}.material-icons.history_edu:before{content:""}.material-icons.history_toggle_off:before{content:""}.material-icons.hive:before{content:""}.material-icons.hls:before{content:""}.material-icons.hls_off:before{content:""}.material-icons.holiday_village:before{content:""}.material-icons.home:before{content:""}.material-icons.home_filled:before{content:""}.material-icons.home_max:before{content:""}.material-icons.home_mini:before{content:""}.material-icons.home_repair_service:before{content:""}.material-icons.home_work:before{content:""}.material-icons.horizontal_distribute:before{content:""}.material-icons.horizontal_rule:before{content:""}.material-icons.horizontal_split:before{content:""}.material-icons.hot_tub:before{content:""}.material-icons.hotel:before{content:""}.material-icons.hotel_class:before{content:""}.material-icons.hourglass_bottom:before{content:""}.material-icons.hourglass_disabled:before{content:""}.material-icons.hourglass_empty:before{content:""}.material-icons.hourglass_full:before{content:""}.material-icons.hourglass_top:before{content:""}.material-icons.house:before{content:""}.material-icons.house_siding:before{content:""}.material-icons.houseboat:before{content:""}.material-icons.how_to_reg:before{content:""}.material-icons.how_to_vote:before{content:""}.material-icons.html:before{content:""}.material-icons.http:before{content:""}.material-icons.https:before{content:""}.material-icons.hub:before{content:""}.material-icons.hvac:before{content:""}.material-icons.ice_skating:before{content:""}.material-icons.icecream:before{content:""}.material-icons.image:before{content:""}.material-icons.image_aspect_ratio:before{content:""}.material-icons.image_not_supported:before{content:""}.material-icons.image_search:before{content:""}.material-icons.imagesearch_roller:before{content:""}.material-icons.import_contacts:before{content:""}.material-icons.import_export:before{content:""}.material-icons.important_devices:before{content:""}.material-icons.inbox:before{content:""}.material-icons.incomplete_circle:before{content:""}.material-icons.indeterminate_check_box:before{content:""}.material-icons.info:before{content:""}.material-icons.info_outline:before{content:""}.material-icons.input:before{content:""}.material-icons.insert_chart:before{content:""}.material-icons.insert_chart_outlined:before{content:""}.material-icons.insert_comment:before{content:""}.material-icons.insert_drive_file:before{content:""}.material-icons.insert_emoticon:before{content:""}.material-icons.insert_invitation:before{content:""}.material-icons.insert_link:before{content:""}.material-icons.insert_page_break:before{content:""}.material-icons.insert_photo:before{content:""}.material-icons.insights:before{content:""}.material-icons.install_desktop:before{content:""}.material-icons.install_mobile:before{content:""}.material-icons.integration_instructions:before{content:""}.material-icons.interests:before{content:""}.material-icons.interpreter_mode:before{content:""}.material-icons.inventory:before{content:""}.material-icons.inventory_2:before{content:""}.material-icons.invert_colors:before{content:""}.material-icons.invert_colors_off:before{content:""}.material-icons.invert_colors_on:before{content:""}.material-icons.ios_share:before{content:""}.material-icons.iron:before{content:""}.material-icons.iso:before{content:""}.material-icons.javascript:before{content:""}.material-icons.join_full:before{content:""}.material-icons.join_inner:before{content:""}.material-icons.join_left:before{content:""}.material-icons.join_right:before{content:""}.material-icons.kayaking:before{content:""}.material-icons.kebab_dining:before{content:""}.material-icons.key:before{content:""}.material-icons.key_off:before{content:""}.material-icons.keyboard:before{content:""}.material-icons.keyboard_alt:before{content:""}.material-icons.keyboard_arrow_down:before{content:""}.material-icons.keyboard_arrow_left:before{content:""}.material-icons.keyboard_arrow_right:before{content:""}.material-icons.keyboard_arrow_up:before{content:""}.material-icons.keyboard_backspace:before{content:""}.material-icons.keyboard_capslock:before{content:""}.material-icons.keyboard_command:before{content:""}.material-icons.keyboard_command_key:before{content:""}.material-icons.keyboard_control:before{content:""}.material-icons.keyboard_control_key:before{content:""}.material-icons.keyboard_double_arrow_down:before{content:""}.material-icons.keyboard_double_arrow_left:before{content:""}.material-icons.keyboard_double_arrow_right:before{content:""}.material-icons.keyboard_double_arrow_up:before{content:""}.material-icons.keyboard_hide:before{content:""}.material-icons.keyboard_option:before{content:""}.material-icons.keyboard_option_key:before{content:""}.material-icons.keyboard_return:before{content:""}.material-icons.keyboard_tab:before{content:""}.material-icons.keyboard_voice:before{content:""}.material-icons.king_bed:before{content:""}.material-icons.kitchen:before{content:""}.material-icons.kitesurfing:before{content:""}.material-icons.label:before{content:""}.material-icons.label_important:before{content:""}.material-icons.label_important_outline:before{content:""}.material-icons.label_off:before{content:""}.material-icons.label_outline:before{content:""}.material-icons.lan:before{content:""}.material-icons.landscape:before{content:""}.material-icons.landslide:before{content:""}.material-icons.language:before{content:""}.material-icons.laptop:before{content:""}.material-icons.laptop_chromebook:before{content:""}.material-icons.laptop_mac:before{content:""}.material-icons.laptop_windows:before{content:""}.material-icons.last_page:before{content:""}.material-icons.launch:before{content:""}.material-icons.layers:before{content:""}.material-icons.layers_clear:before{content:""}.material-icons.leaderboard:before{content:""}.material-icons.leak_add:before{content:""}.material-icons.leak_remove:before{content:""}.material-icons.leave_bags_at_home:before{content:""}.material-icons.legend_toggle:before{content:""}.material-icons.lens:before{content:""}.material-icons.lens_blur:before{content:""}.material-icons.library_add:before{content:""}.material-icons.library_add_check:before{content:""}.material-icons.library_books:before{content:""}.material-icons.library_music:before{content:""}.material-icons.light:before{content:""}.material-icons.light_mode:before{content:""}.material-icons.lightbulb:before{content:""}.material-icons.lightbulb_circle:before{content:""}.material-icons.lightbulb_outline:before{content:""}.material-icons.line_axis:before{content:""}.material-icons.line_style:before{content:""}.material-icons.line_weight:before{content:""}.material-icons.linear_scale:before{content:""}.material-icons.link:before{content:""}.material-icons.link_off:before{content:""}.material-icons.linked_camera:before{content:""}.material-icons.liquor:before{content:""}.material-icons.list:before{content:""}.material-icons.list_alt:before{content:""}.material-icons.live_help:before{content:""}.material-icons.live_tv:before{content:""}.material-icons.living:before{content:""}.material-icons.local_activity:before{content:""}.material-icons.local_airport:before{content:""}.material-icons.local_atm:before{content:""}.material-icons.local_attraction:before{content:""}.material-icons.local_bar:before{content:""}.material-icons.local_cafe:before{content:""}.material-icons.local_car_wash:before{content:""}.material-icons.local_convenience_store:before{content:""}.material-icons.local_dining:before{content:""}.material-icons.local_drink:before{content:""}.material-icons.local_fire_department:before{content:""}.material-icons.local_florist:before{content:""}.material-icons.local_gas_station:before{content:""}.material-icons.local_grocery_store:before{content:""}.material-icons.local_hospital:before{content:""}.material-icons.local_hotel:before{content:""}.material-icons.local_laundry_service:before{content:""}.material-icons.local_library:before{content:""}.material-icons.local_mall:before{content:""}.material-icons.local_movies:before{content:""}.material-icons.local_offer:before{content:""}.material-icons.local_parking:before{content:""}.material-icons.local_pharmacy:before{content:""}.material-icons.local_phone:before{content:""}.material-icons.local_pizza:before{content:""}.material-icons.local_play:before{content:""}.material-icons.local_police:before{content:""}.material-icons.local_post_office:before{content:""}.material-icons.local_print_shop:before{content:""}.material-icons.local_printshop:before{content:""}.material-icons.local_restaurant:before{content:""}.material-icons.local_see:before{content:""}.material-icons.local_shipping:before{content:""}.material-icons.local_taxi:before{content:""}.material-icons.location_city:before{content:""}.material-icons.location_disabled:before{content:""}.material-icons.location_history:before{content:""}.material-icons.location_off:before{content:""}.material-icons.location_on:before{content:""}.material-icons.location_pin:before{content:""}.material-icons.location_searching:before{content:""}.material-icons.lock:before{content:""}.material-icons.lock_clock:before{content:""}.material-icons.lock_open:before{content:""}.material-icons.lock_outline:before{content:""}.material-icons.lock_person:before{content:""}.material-icons.lock_reset:before{content:""}.material-icons.login:before{content:""}.material-icons.logo_dev:before{content:""}.material-icons.logout:before{content:""}.material-icons.looks:before{content:""}.material-icons.looks_3:before{content:""}.material-icons.looks_4:before{content:""}.material-icons.looks_5:before{content:""}.material-icons.looks_6:before{content:""}.material-icons.looks_one:before{content:""}.material-icons.looks_two:before{content:""}.material-icons.loop:before{content:""}.material-icons.loupe:before{content:""}.material-icons.low_priority:before{content:""}.material-icons.loyalty:before{content:""}.material-icons.lte_mobiledata:before{content:""}.material-icons.lte_plus_mobiledata:before{content:""}.material-icons.luggage:before{content:""}.material-icons.lunch_dining:before{content:""}.material-icons.lyrics:before{content:""}.material-icons.mail:before{content:""}.material-icons.mail_lock:before{content:""}.material-icons.mail_outline:before{content:""}.material-icons.male:before{content:""}.material-icons.man:before{content:""}.material-icons.manage_accounts:before{content:""}.material-icons.manage_history:before{content:""}.material-icons.manage_search:before{content:""}.material-icons.map:before{content:""}.material-icons.maps_home_work:before{content:""}.material-icons.maps_ugc:before{content:""}.material-icons.margin:before{content:""}.material-icons.mark_as_unread:before{content:""}.material-icons.mark_chat_read:before{content:""}.material-icons.mark_chat_unread:before{content:""}.material-icons.mark_email_read:before{content:""}.material-icons.mark_email_unread:before{content:""}.material-icons.mark_unread_chat_alt:before{content:""}.material-icons.markunread:before{content:""}.material-icons.markunread_mailbox:before{content:""}.material-icons.masks:before{content:""}.material-icons.maximize:before{content:""}.material-icons.media_bluetooth_off:before{content:""}.material-icons.media_bluetooth_on:before{content:""}.material-icons.mediation:before{content:""}.material-icons.medical_information:before{content:""}.material-icons.medical_services:before{content:""}.material-icons.medication:before{content:""}.material-icons.medication_liquid:before{content:""}.material-icons.meeting_room:before{content:""}.material-icons.memory:before{content:""}.material-icons.menu:before{content:""}.material-icons.menu_book:before{content:""}.material-icons.menu_open:before{content:""}.material-icons.merge:before{content:""}.material-icons.merge_type:before{content:""}.material-icons.message:before{content:""}.material-icons.messenger:before{content:""}.material-icons.messenger_outline:before{content:""}.material-icons.mic:before{content:""}.material-icons.mic_external_off:before{content:""}.material-icons.mic_external_on:before{content:""}.material-icons.mic_none:before{content:""}.material-icons.mic_off:before{content:""}.material-icons.microwave:before{content:""}.material-icons.military_tech:before{content:""}.material-icons.minimize:before{content:""}.material-icons.minor_crash:before{content:""}.material-icons.miscellaneous_services:before{content:""}.material-icons.missed_video_call:before{content:""}.material-icons.mms:before{content:""}.material-icons.mobile_friendly:before{content:""}.material-icons.mobile_off:before{content:""}.material-icons.mobile_screen_share:before{content:""}.material-icons.mobiledata_off:before{content:""}.material-icons.mode:before{content:""}.material-icons.mode_comment:before{content:""}.material-icons.mode_edit:before{content:""}.material-icons.mode_edit_outline:before{content:""}.material-icons.mode_fan_off:before{content:""}.material-icons.mode_night:before{content:""}.material-icons.mode_of_travel:before{content:""}.material-icons.mode_standby:before{content:""}.material-icons.model_training:before{content:""}.material-icons.monetization_on:before{content:""}.material-icons.money:before{content:""}.material-icons.money_off:before{content:""}.material-icons.money_off_csred:before{content:""}.material-icons.monitor:before{content:""}.material-icons.monitor_heart:before{content:""}.material-icons.monitor_weight:before{content:""}.material-icons.monochrome_photos:before{content:""}.material-icons.mood:before{content:""}.material-icons.mood_bad:before{content:""}.material-icons.moped:before{content:""}.material-icons.more:before{content:""}.material-icons.more_horiz:before{content:""}.material-icons.more_time:before{content:""}.material-icons.more_vert:before{content:""}.material-icons.mosque:before{content:""}.material-icons.motion_photos_auto:before{content:""}.material-icons.motion_photos_off:before{content:""}.material-icons.motion_photos_on:before{content:""}.material-icons.motion_photos_pause:before{content:""}.material-icons.motion_photos_paused:before{content:""}.material-icons.motorcycle:before{content:""}.material-icons.mouse:before{content:""}.material-icons.move_down:before{content:""}.material-icons.move_to_inbox:before{content:""}.material-icons.move_up:before{content:""}.material-icons.movie:before{content:""}.material-icons.movie_creation:before{content:""}.material-icons.movie_filter:before{content:""}.material-icons.moving:before{content:""}.material-icons.mp:before{content:""}.material-icons.multiline_chart:before{content:""}.material-icons.multiple_stop:before{content:""}.material-icons.multitrack_audio:before{content:""}.material-icons.museum:before{content:""}.material-icons.music_note:before{content:""}.material-icons.music_off:before{content:""}.material-icons.music_video:before{content:""}.material-icons.my_library_add:before{content:""}.material-icons.my_library_books:before{content:""}.material-icons.my_library_music:before{content:""}.material-icons.my_location:before{content:""}.material-icons.nat:before{content:""}.material-icons.nature:before{content:""}.material-icons.nature_people:before{content:""}.material-icons.navigate_before:before{content:""}.material-icons.navigate_next:before{content:""}.material-icons.navigation:before{content:""}.material-icons.near_me:before{content:""}.material-icons.near_me_disabled:before{content:""}.material-icons.nearby_error:before{content:""}.material-icons.nearby_off:before{content:""}.material-icons.nest_cam_wired_stand:before{content:""}.material-icons.network_cell:before{content:""}.material-icons.network_check:before{content:""}.material-icons.network_locked:before{content:""}.material-icons.network_ping:before{content:""}.material-icons.network_wifi:before{content:""}.material-icons.network_wifi_1_bar:before{content:""}.material-icons.network_wifi_2_bar:before{content:""}.material-icons.network_wifi_3_bar:before{content:""}.material-icons.new_label:before{content:""}.material-icons.new_releases:before{content:""}.material-icons.newspaper:before{content:""}.material-icons.next_plan:before{content:""}.material-icons.next_week:before{content:""}.material-icons.nfc:before{content:""}.material-icons.night_shelter:before{content:""}.material-icons.nightlife:before{content:""}.material-icons.nightlight:before{content:""}.material-icons.nightlight_round:before{content:""}.material-icons.nights_stay:before{content:""}.material-icons.no_accounts:before{content:""}.material-icons.no_adult_content:before{content:""}.material-icons.no_backpack:before{content:""}.material-icons.no_cell:before{content:""}.material-icons.no_crash:before{content:""}.material-icons.no_drinks:before{content:""}.material-icons.no_encryption:before{content:""}.material-icons.no_encryption_gmailerrorred:before{content:""}.material-icons.no_flash:before{content:""}.material-icons.no_food:before{content:""}.material-icons.no_luggage:before{content:""}.material-icons.no_meals:before{content:""}.material-icons.no_meals_ouline:before{content:""}.material-icons.no_meeting_room:before{content:""}.material-icons.no_photography:before{content:""}.material-icons.no_sim:before{content:""}.material-icons.no_stroller:before{content:""}.material-icons.no_transfer:before{content:""}.material-icons.noise_aware:before{content:""}.material-icons.noise_control_off:before{content:""}.material-icons.nordic_walking:before{content:""}.material-icons.north:before{content:""}.material-icons.north_east:before{content:""}.material-icons.north_west:before{content:""}.material-icons.not_accessible:before{content:""}.material-icons.not_interested:before{content:""}.material-icons.not_listed_location:before{content:""}.material-icons.not_started:before{content:""}.material-icons.note:before{content:""}.material-icons.note_add:before{content:""}.material-icons.note_alt:before{content:""}.material-icons.notes:before{content:""}.material-icons.notification_add:before{content:""}.material-icons.notification_important:before{content:""}.material-icons.notifications:before{content:""}.material-icons.notifications_active:before{content:""}.material-icons.notifications_none:before{content:""}.material-icons.notifications_off:before{content:""}.material-icons.notifications_on:before{content:""}.material-icons.notifications_paused:before{content:""}.material-icons.now_wallpaper:before{content:""}.material-icons.now_widgets:before{content:""}.material-icons.numbers:before{content:""}.material-icons.offline_bolt:before{content:""}.material-icons.offline_pin:before{content:""}.material-icons.offline_share:before{content:""}.material-icons.oil_barrel:before{content:""}.material-icons.on_device_training:before{content:""}.material-icons.ondemand_video:before{content:""}.material-icons.online_prediction:before{content:""}.material-icons.opacity:before{content:""}.material-icons.open_in_browser:before{content:""}.material-icons.open_in_full:before{content:""}.material-icons.open_in_new:before{content:""}.material-icons.open_in_new_off:before{content:""}.material-icons.open_with:before{content:""}.material-icons.other_houses:before{content:""}.material-icons.outbond:before{content:""}.material-icons.outbound:before{content:""}.material-icons.outbox:before{content:""}.material-icons.outdoor_grill:before{content:""}.material-icons.outgoing_mail:before{content:""}.material-icons.outlet:before{content:""}.material-icons.outlined_flag:before{content:""}.material-icons.output:before{content:""}.material-icons.padding:before{content:""}.material-icons.pages:before{content:""}.material-icons.pageview:before{content:""}.material-icons.paid:before{content:""}.material-icons.palette:before{content:""}.material-icons.pan_tool:before{content:""}.material-icons.pan_tool_alt:before{content:""}.material-icons.panorama:before{content:""}.material-icons.panorama_fish_eye:before{content:""}.material-icons.panorama_fisheye:before{content:""}.material-icons.panorama_horizontal:before{content:""}.material-icons.panorama_horizontal_select:before{content:""}.material-icons.panorama_photosphere:before{content:""}.material-icons.panorama_photosphere_select:before{content:""}.material-icons.panorama_vertical:before{content:""}.material-icons.panorama_vertical_select:before{content:""}.material-icons.panorama_wide_angle:before{content:""}.material-icons.panorama_wide_angle_select:before{content:""}.material-icons.paragliding:before{content:""}.material-icons.park:before{content:""}.material-icons.party_mode:before{content:""}.material-icons.password:before{content:""}.material-icons.pattern:before{content:""}.material-icons.pause:before{content:""}.material-icons.pause_circle:before{content:""}.material-icons.pause_circle_filled:before{content:""}.material-icons.pause_circle_outline:before{content:""}.material-icons.pause_presentation:before{content:""}.material-icons.payment:before{content:""}.material-icons.payments:before{content:""}.material-icons.paypal:before{content:""}.material-icons.pedal_bike:before{content:""}.material-icons.pending:before{content:""}.material-icons.pending_actions:before{content:""}.material-icons.pentagon:before{content:""}.material-icons.people:before{content:""}.material-icons.people_alt:before{content:""}.material-icons.people_outline:before{content:""}.material-icons.percent:before{content:""}.material-icons.perm_camera_mic:before{content:""}.material-icons.perm_contact_cal:before{content:""}.material-icons.perm_contact_calendar:before{content:""}.material-icons.perm_data_setting:before{content:""}.material-icons.perm_device_info:before{content:""}.material-icons.perm_device_information:before{content:""}.material-icons.perm_identity:before{content:""}.material-icons.perm_media:before{content:""}.material-icons.perm_phone_msg:before{content:""}.material-icons.perm_scan_wifi:before{content:""}.material-icons.person:before{content:""}.material-icons.person_add:before{content:""}.material-icons.person_add_alt:before{content:""}.material-icons.person_add_alt_1:before{content:""}.material-icons.person_add_disabled:before{content:""}.material-icons.person_off:before{content:""}.material-icons.person_outline:before{content:""}.material-icons.person_pin:before{content:""}.material-icons.person_pin_circle:before{content:""}.material-icons.person_remove:before{content:""}.material-icons.person_remove_alt_1:before{content:""}.material-icons.person_search:before{content:""}.material-icons.personal_injury:before{content:""}.material-icons.personal_video:before{content:""}.material-icons.pest_control:before{content:""}.material-icons.pest_control_rodent:before{content:""}.material-icons.pets:before{content:""}.material-icons.phishing:before{content:""}.material-icons.phone:before{content:""}.material-icons.phone_android:before{content:""}.material-icons.phone_bluetooth_speaker:before{content:""}.material-icons.phone_callback:before{content:""}.material-icons.phone_disabled:before{content:""}.material-icons.phone_enabled:before{content:""}.material-icons.phone_forwarded:before{content:""}.material-icons.phone_in_talk:before{content:""}.material-icons.phone_iphone:before{content:""}.material-icons.phone_locked:before{content:""}.material-icons.phone_missed:before{content:""}.material-icons.phone_paused:before{content:""}.material-icons.phonelink:before{content:""}.material-icons.phonelink_erase:before{content:""}.material-icons.phonelink_lock:before{content:""}.material-icons.phonelink_off:before{content:""}.material-icons.phonelink_ring:before{content:""}.material-icons.phonelink_setup:before{content:""}.material-icons.photo:before{content:""}.material-icons.photo_album:before{content:""}.material-icons.photo_camera:before{content:""}.material-icons.photo_camera_back:before{content:""}.material-icons.photo_camera_front:before{content:""}.material-icons.photo_filter:before{content:""}.material-icons.photo_library:before{content:""}.material-icons.photo_size_select_actual:before{content:""}.material-icons.photo_size_select_large:before{content:""}.material-icons.photo_size_select_small:before{content:""}.material-icons.php:before{content:""}.material-icons.piano:before{content:""}.material-icons.piano_off:before{content:""}.material-icons.picture_as_pdf:before{content:""}.material-icons.picture_in_picture:before{content:""}.material-icons.picture_in_picture_alt:before{content:""}.material-icons.pie_chart:before{content:""}.material-icons.pie_chart_outline:before{content:""}.material-icons.pie_chart_outlined:before{content:""}.material-icons.pin:before{content:""}.material-icons.pin_drop:before{content:""}.material-icons.pin_end:before{content:""}.material-icons.pin_invoke:before{content:""}.material-icons.pinch:before{content:""}.material-icons.pivot_table_chart:before{content:""}.material-icons.pix:before{content:""}.material-icons.place:before{content:""}.material-icons.plagiarism:before{content:""}.material-icons.play_arrow:before{content:""}.material-icons.play_circle:before{content:""}.material-icons.play_circle_fill:before{content:""}.material-icons.play_circle_filled:before{content:""}.material-icons.play_circle_outline:before{content:""}.material-icons.play_disabled:before{content:""}.material-icons.play_for_work:before{content:""}.material-icons.play_lesson:before{content:""}.material-icons.playlist_add:before{content:""}.material-icons.playlist_add_check:before{content:""}.material-icons.playlist_add_check_circle:before{content:""}.material-icons.playlist_add_circle:before{content:""}.material-icons.playlist_play:before{content:""}.material-icons.playlist_remove:before{content:""}.material-icons.plumbing:before{content:""}.material-icons.plus_one:before{content:""}.material-icons.podcasts:before{content:""}.material-icons.point_of_sale:before{content:""}.material-icons.policy:before{content:""}.material-icons.poll:before{content:""}.material-icons.polyline:before{content:""}.material-icons.polymer:before{content:""}.material-icons.pool:before{content:""}.material-icons.portable_wifi_off:before{content:""}.material-icons.portrait:before{content:""}.material-icons.post_add:before{content:""}.material-icons.power:before{content:""}.material-icons.power_input:before{content:""}.material-icons.power_off:before{content:""}.material-icons.power_settings_new:before{content:""}.material-icons.precision_manufacturing:before{content:""}.material-icons.pregnant_woman:before{content:""}.material-icons.present_to_all:before{content:""}.material-icons.preview:before{content:""}.material-icons.price_change:before{content:""}.material-icons.price_check:before{content:""}.material-icons.print:before{content:""}.material-icons.print_disabled:before{content:""}.material-icons.priority_high:before{content:""}.material-icons.privacy_tip:before{content:""}.material-icons.private_connectivity:before{content:""}.material-icons.production_quantity_limits:before{content:""}.material-icons.propane:before{content:""}.material-icons.propane_tank:before{content:""}.material-icons.psychology:before{content:""}.material-icons.psychology_alt:before{content:""}.material-icons.public:before{content:""}.material-icons.public_off:before{content:""}.material-icons.publish:before{content:""}.material-icons.published_with_changes:before{content:""}.material-icons.punch_clock:before{content:""}.material-icons.push_pin:before{content:""}.material-icons.qr_code:before{content:""}.material-icons.qr_code_2:before{content:""}.material-icons.qr_code_scanner:before{content:""}.material-icons.query_builder:before{content:""}.material-icons.query_stats:before{content:""}.material-icons.question_answer:before{content:""}.material-icons.question_mark:before{content:""}.material-icons.queue:before{content:""}.material-icons.queue_music:before{content:""}.material-icons.queue_play_next:before{content:""}.material-icons.quick_contacts_dialer:before{content:""}.material-icons.quick_contacts_mail:before{content:""}.material-icons.quickreply:before{content:""}.material-icons.quiz:before{content:""}.material-icons.quora:before{content:""}.material-icons.r_mobiledata:before{content:""}.material-icons.radar:before{content:""}.material-icons.radio:before{content:""}.material-icons.radio_button_checked:before{content:""}.material-icons.radio_button_off:before{content:""}.material-icons.radio_button_on:before{content:""}.material-icons.radio_button_unchecked:before{content:""}.material-icons.railway_alert:before{content:""}.material-icons.ramen_dining:before{content:""}.material-icons.ramp_left:before{content:""}.material-icons.ramp_right:before{content:""}.material-icons.rate_review:before{content:""}.material-icons.raw_off:before{content:""}.material-icons.raw_on:before{content:""}.material-icons.read_more:before{content:""}.material-icons.real_estate_agent:before{content:""}.material-icons.receipt:before{content:""}.material-icons.receipt_long:before{content:""}.material-icons.recent_actors:before{content:""}.material-icons.recommend:before{content:""}.material-icons.record_voice_over:before{content:""}.material-icons.rectangle:before{content:""}.material-icons.recycling:before{content:""}.material-icons.reddit:before{content:""}.material-icons.redeem:before{content:""}.material-icons.redo:before{content:""}.material-icons.reduce_capacity:before{content:""}.material-icons.refresh:before{content:""}.material-icons.remember_me:before{content:""}.material-icons.remove:before{content:""}.material-icons.remove_circle:before{content:""}.material-icons.remove_circle_outline:before{content:""}.material-icons.remove_done:before{content:""}.material-icons.remove_from_queue:before{content:""}.material-icons.remove_moderator:before{content:""}.material-icons.remove_red_eye:before{content:""}.material-icons.remove_road:before{content:""}.material-icons.remove_shopping_cart:before{content:""}.material-icons.reorder:before{content:""}.material-icons.repartition:before{content:""}.material-icons.repeat:before{content:""}.material-icons.repeat_on:before{content:""}.material-icons.repeat_one:before{content:""}.material-icons.repeat_one_on:before{content:""}.material-icons.replay:before{content:""}.material-icons.replay_10:before{content:""}.material-icons.replay_30:before{content:""}.material-icons.replay_5:before{content:""}.material-icons.replay_circle_filled:before{content:""}.material-icons.reply:before{content:""}.material-icons.reply_all:before{content:""}.material-icons.report:before{content:""}.material-icons.report_gmailerrorred:before{content:""}.material-icons.report_off:before{content:""}.material-icons.report_problem:before{content:""}.material-icons.request_page:before{content:""}.material-icons.request_quote:before{content:""}.material-icons.reset_tv:before{content:""}.material-icons.restart_alt:before{content:""}.material-icons.restaurant:before{content:""}.material-icons.restaurant_menu:before{content:""}.material-icons.restore:before{content:""}.material-icons.restore_from_trash:before{content:""}.material-icons.restore_page:before{content:""}.material-icons.reviews:before{content:""}.material-icons.rice_bowl:before{content:""}.material-icons.ring_volume:before{content:""}.material-icons.rocket:before{content:""}.material-icons.rocket_launch:before{content:""}.material-icons.roller_shades:before{content:""}.material-icons.roller_shades_closed:before{content:""}.material-icons.roller_skating:before{content:""}.material-icons.roofing:before{content:""}.material-icons.room:before{content:""}.material-icons.room_preferences:before{content:""}.material-icons.room_service:before{content:""}.material-icons.rotate_90_degrees_ccw:before{content:""}.material-icons.rotate_90_degrees_cw:before{content:""}.material-icons.rotate_left:before{content:""}.material-icons.rotate_right:before{content:""}.material-icons.roundabout_left:before{content:""}.material-icons.roundabout_right:before{content:""}.material-icons.rounded_corner:before{content:""}.material-icons.route:before{content:""}.material-icons.router:before{content:""}.material-icons.rowing:before{content:""}.material-icons.rss_feed:before{content:""}.material-icons.rsvp:before{content:""}.material-icons.rtt:before{content:""}.material-icons.rule:before{content:""}.material-icons.rule_folder:before{content:""}.material-icons.run_circle:before{content:""}.material-icons.running_with_errors:before{content:""}.material-icons.rv_hookup:before{content:""}.material-icons.safety_check:before{content:""}.material-icons.safety_divider:before{content:""}.material-icons.sailing:before{content:""}.material-icons.sanitizer:before{content:""}.material-icons.satellite:before{content:""}.material-icons.satellite_alt:before{content:""}.material-icons.save:before{content:""}.material-icons.save_alt:before{content:""}.material-icons.save_as:before{content:""}.material-icons.saved_search:before{content:""}.material-icons.savings:before{content:""}.material-icons.scale:before{content:""}.material-icons.scanner:before{content:""}.material-icons.scatter_plot:before{content:""}.material-icons.schedule:before{content:""}.material-icons.schedule_send:before{content:""}.material-icons.schema:before{content:""}.material-icons.school:before{content:""}.material-icons.science:before{content:""}.material-icons.score:before{content:""}.material-icons.scoreboard:before{content:""}.material-icons.screen_lock_landscape:before{content:""}.material-icons.screen_lock_portrait:before{content:""}.material-icons.screen_lock_rotation:before{content:""}.material-icons.screen_rotation:before{content:""}.material-icons.screen_rotation_alt:before{content:""}.material-icons.screen_search_desktop:before{content:""}.material-icons.screen_share:before{content:""}.material-icons.screenshot:before{content:""}.material-icons.screenshot_monitor:before{content:""}.material-icons.scuba_diving:before{content:""}.material-icons.sd:before{content:""}.material-icons.sd_card:before{content:""}.material-icons.sd_card_alert:before{content:""}.material-icons.sd_storage:before{content:""}.material-icons.search:before{content:""}.material-icons.search_off:before{content:""}.material-icons.security:before{content:""}.material-icons.security_update:before{content:""}.material-icons.security_update_good:before{content:""}.material-icons.security_update_warning:before{content:""}.material-icons.segment:before{content:""}.material-icons.select_all:before{content:""}.material-icons.self_improvement:before{content:""}.material-icons.sell:before{content:""}.material-icons.send:before{content:""}.material-icons.send_and_archive:before{content:""}.material-icons.send_time_extension:before{content:""}.material-icons.send_to_mobile:before{content:""}.material-icons.sensor_door:before{content:""}.material-icons.sensor_occupied:before{content:""}.material-icons.sensor_window:before{content:""}.material-icons.sensors:before{content:""}.material-icons.sensors_off:before{content:""}.material-icons.sentiment_dissatisfied:before{content:""}.material-icons.sentiment_neutral:before{content:""}.material-icons.sentiment_satisfied:before{content:""}.material-icons.sentiment_satisfied_alt:before{content:""}.material-icons.sentiment_very_dissatisfied:before{content:""}.material-icons.sentiment_very_satisfied:before{content:""}.material-icons.set_meal:before{content:""}.material-icons.settings:before{content:""}.material-icons.settings_accessibility:before{content:""}.material-icons.settings_applications:before{content:""}.material-icons.settings_backup_restore:before{content:""}.material-icons.settings_bluetooth:before{content:""}.material-icons.settings_brightness:before{content:""}.material-icons.settings_cell:before{content:""}.material-icons.settings_display:before{content:""}.material-icons.settings_ethernet:before{content:""}.material-icons.settings_input_antenna:before{content:""}.material-icons.settings_input_component:before{content:""}.material-icons.settings_input_composite:before{content:""}.material-icons.settings_input_hdmi:before{content:""}.material-icons.settings_input_svideo:before{content:""}.material-icons.settings_overscan:before{content:""}.material-icons.settings_phone:before{content:""}.material-icons.settings_power:before{content:""}.material-icons.settings_remote:before{content:""}.material-icons.settings_suggest:before{content:""}.material-icons.settings_system_daydream:before{content:""}.material-icons.settings_voice:before{content:""}.material-icons.severe_cold:before{content:""}.material-icons.share:before{content:""}.material-icons.share_arrival_time:before{content:""}.material-icons.share_location:before{content:""}.material-icons.shield:before{content:""}.material-icons.shield_moon:before{content:""}.material-icons.shop:before{content:""}.material-icons.shop_2:before{content:""}.material-icons.shop_two:before{content:""}.material-icons.shopify:before{content:""}.material-icons.shopping_bag:before{content:""}.material-icons.shopping_basket:before{content:""}.material-icons.shopping_cart:before{content:""}.material-icons.shopping_cart_checkout:before{content:""}.material-icons.short_text:before{content:""}.material-icons.shortcut:before{content:""}.material-icons.show_chart:before{content:""}.material-icons.shower:before{content:""}.material-icons.shuffle:before{content:""}.material-icons.shuffle_on:before{content:""}.material-icons.shutter_speed:before{content:""}.material-icons.sick:before{content:""}.material-icons.sign_language:before{content:""}.material-icons.signal_cellular_0_bar:before{content:""}.material-icons.signal_cellular_4_bar:before{content:""}.material-icons.signal_cellular_alt:before{content:""}.material-icons.signal_cellular_alt_1_bar:before{content:""}.material-icons.signal_cellular_alt_2_bar:before{content:""}.material-icons.signal_cellular_connected_no_internet_0_bar:before{content:""}.material-icons.signal_cellular_connected_no_internet_4_bar:before{content:""}.material-icons.signal_cellular_no_sim:before{content:""}.material-icons.signal_cellular_nodata:before{content:""}.material-icons.signal_cellular_null:before{content:""}.material-icons.signal_cellular_off:before{content:""}.material-icons.signal_wifi_0_bar:before{content:""}.material-icons.signal_wifi_4_bar:before{content:""}.material-icons.signal_wifi_4_bar_lock:before{content:""}.material-icons.signal_wifi_bad:before{content:""}.material-icons.signal_wifi_connected_no_internet_4:before{content:""}.material-icons.signal_wifi_off:before{content:""}.material-icons.signal_wifi_statusbar_4_bar:before{content:""}.material-icons.signal_wifi_statusbar_connected_no_internet_4:before{content:""}.material-icons.signal_wifi_statusbar_null:before{content:""}.material-icons.signpost:before{content:""}.material-icons.sim_card:before{content:""}.material-icons.sim_card_alert:before{content:""}.material-icons.sim_card_download:before{content:""}.material-icons.single_bed:before{content:""}.material-icons.sip:before{content:""}.material-icons.skateboarding:before{content:""}.material-icons.skip_next:before{content:""}.material-icons.skip_previous:before{content:""}.material-icons.sledding:before{content:""}.material-icons.slideshow:before{content:""}.material-icons.slow_motion_video:before{content:""}.material-icons.smart_button:before{content:""}.material-icons.smart_display:before{content:""}.material-icons.smart_screen:before{content:""}.material-icons.smart_toy:before{content:""}.material-icons.smartphone:before{content:""}.material-icons.smoke_free:before{content:""}.material-icons.smoking_rooms:before{content:""}.material-icons.sms:before{content:""}.material-icons.sms_failed:before{content:""}.material-icons.snapchat:before{content:""}.material-icons.snippet_folder:before{content:""}.material-icons.snooze:before{content:""}.material-icons.snowboarding:before{content:""}.material-icons.snowing:before{content:""}.material-icons.snowmobile:before{content:""}.material-icons.snowshoeing:before{content:""}.material-icons.soap:before{content:""}.material-icons.social_distance:before{content:""}.material-icons.solar_power:before{content:""}.material-icons.sort:before{content:""}.material-icons.sort_by_alpha:before{content:""}.material-icons.sos:before{content:""}.material-icons.soup_kitchen:before{content:""}.material-icons.source:before{content:""}.material-icons.south:before{content:""}.material-icons.south_america:before{content:""}.material-icons.south_east:before{content:""}.material-icons.south_west:before{content:""}.material-icons.spa:before{content:""}.material-icons.space_bar:before{content:""}.material-icons.space_dashboard:before{content:""}.material-icons.spatial_audio:before{content:""}.material-icons.spatial_audio_off:before{content:""}.material-icons.spatial_tracking:before{content:""}.material-icons.speaker:before{content:""}.material-icons.speaker_group:before{content:""}.material-icons.speaker_notes:before{content:""}.material-icons.speaker_notes_off:before{content:""}.material-icons.speaker_phone:before{content:""}.material-icons.speed:before{content:""}.material-icons.spellcheck:before{content:""}.material-icons.splitscreen:before{content:""}.material-icons.spoke:before{content:""}.material-icons.sports:before{content:""}.material-icons.sports_bar:before{content:""}.material-icons.sports_baseball:before{content:""}.material-icons.sports_basketball:before{content:""}.material-icons.sports_cricket:before{content:""}.material-icons.sports_esports:before{content:""}.material-icons.sports_football:before{content:""}.material-icons.sports_golf:before{content:""}.material-icons.sports_gymnastics:before{content:""}.material-icons.sports_handball:before{content:""}.material-icons.sports_hockey:before{content:""}.material-icons.sports_kabaddi:before{content:""}.material-icons.sports_martial_arts:before{content:""}.material-icons.sports_mma:before{content:""}.material-icons.sports_motorsports:before{content:""}.material-icons.sports_rugby:before{content:""}.material-icons.sports_score:before{content:""}.material-icons.sports_soccer:before{content:""}.material-icons.sports_tennis:before{content:""}.material-icons.sports_volleyball:before{content:""}.material-icons.square:before{content:""}.material-icons.square_foot:before{content:""}.material-icons.ssid_chart:before{content:""}.material-icons.stacked_bar_chart:before{content:""}.material-icons.stacked_line_chart:before{content:""}.material-icons.stadium:before{content:""}.material-icons.stairs:before{content:""}.material-icons.star:before{content:""}.material-icons.star_border:before{content:""}.material-icons.star_border_purple500:before{content:""}.material-icons.star_half:before{content:""}.material-icons.star_outline:before{content:""}.material-icons.star_purple500:before{content:""}.material-icons.star_rate:before{content:""}.material-icons.stars:before{content:""}.material-icons.start:before{content:""}.material-icons.stay_current_landscape:before{content:""}.material-icons.stay_current_portrait:before{content:""}.material-icons.stay_primary_landscape:before{content:""}.material-icons.stay_primary_portrait:before{content:""}.material-icons.sticky_note_2:before{content:""}.material-icons.stop:before{content:""}.material-icons.stop_circle:before{content:""}.material-icons.stop_screen_share:before{content:""}.material-icons.storage:before{content:""}.material-icons.store:before{content:""}.material-icons.store_mall_directory:before{content:""}.material-icons.storefront:before{content:""}.material-icons.storm:before{content:""}.material-icons.straight:before{content:""}.material-icons.straighten:before{content:""}.material-icons.stream:before{content:""}.material-icons.streetview:before{content:""}.material-icons.strikethrough_s:before{content:""}.material-icons.stroller:before{content:""}.material-icons.style:before{content:""}.material-icons.subdirectory_arrow_left:before{content:""}.material-icons.subdirectory_arrow_right:before{content:""}.material-icons.subject:before{content:""}.material-icons.subscript:before{content:""}.material-icons.subscriptions:before{content:""}.material-icons.subtitles:before{content:""}.material-icons.subtitles_off:before{content:""}.material-icons.subway:before{content:""}.material-icons.summarize:before{content:""}.material-icons.sunny:before{content:""}.material-icons.sunny_snowing:before{content:""}.material-icons.superscript:before{content:""}.material-icons.supervised_user_circle:before{content:""}.material-icons.supervisor_account:before{content:""}.material-icons.support:before{content:""}.material-icons.support_agent:before{content:""}.material-icons.surfing:before{content:""}.material-icons.surround_sound:before{content:""}.material-icons.swap_calls:before{content:""}.material-icons.swap_horiz:before{content:""}.material-icons.swap_horizontal_circle:before{content:""}.material-icons.swap_vert:before{content:""}.material-icons.swap_vert_circle:before{content:""}.material-icons.swap_vertical_circle:before{content:""}.material-icons.swipe:before{content:""}.material-icons.swipe_down:before{content:""}.material-icons.swipe_down_alt:before{content:""}.material-icons.swipe_left:before{content:""}.material-icons.swipe_left_alt:before{content:""}.material-icons.swipe_right:before{content:""}.material-icons.swipe_right_alt:before{content:""}.material-icons.swipe_up:before{content:""}.material-icons.swipe_up_alt:before{content:""}.material-icons.swipe_vertical:before{content:""}.material-icons.switch_access_shortcut:before{content:""}.material-icons.switch_access_shortcut_add:before{content:""}.material-icons.switch_account:before{content:""}.material-icons.switch_camera:before{content:""}.material-icons.switch_left:before{content:""}.material-icons.switch_right:before{content:""}.material-icons.switch_video:before{content:""}.material-icons.synagogue:before{content:""}.material-icons.sync:before{content:""}.material-icons.sync_alt:before{content:""}.material-icons.sync_disabled:before{content:""}.material-icons.sync_lock:before{content:""}.material-icons.sync_problem:before{content:""}.material-icons.system_security_update:before{content:""}.material-icons.system_security_update_good:before{content:""}.material-icons.system_security_update_warning:before{content:""}.material-icons.system_update:before{content:""}.material-icons.system_update_alt:before{content:""}.material-icons.system_update_tv:before{content:""}.material-icons.tab:before{content:""}.material-icons.tab_unselected:before{content:""}.material-icons.table_bar:before{content:""}.material-icons.table_chart:before{content:""}.material-icons.table_restaurant:before{content:""}.material-icons.table_rows:before{content:""}.material-icons.table_view:before{content:""}.material-icons.tablet:before{content:""}.material-icons.tablet_android:before{content:""}.material-icons.tablet_mac:before{content:""}.material-icons.tag:before{content:""}.material-icons.tag_faces:before{content:""}.material-icons.takeout_dining:before{content:""}.material-icons.tap_and_play:before{content:""}.material-icons.tapas:before{content:""}.material-icons.task:before{content:""}.material-icons.task_alt:before{content:""}.material-icons.taxi_alert:before{content:""}.material-icons.telegram:before{content:""}.material-icons.temple_buddhist:before{content:""}.material-icons.temple_hindu:before{content:""}.material-icons.terminal:before{content:""}.material-icons.terrain:before{content:""}.material-icons.text_decrease:before{content:""}.material-icons.text_fields:before{content:""}.material-icons.text_format:before{content:""}.material-icons.text_increase:before{content:""}.material-icons.text_rotate_up:before{content:""}.material-icons.text_rotate_vertical:before{content:""}.material-icons.text_rotation_angledown:before{content:""}.material-icons.text_rotation_angleup:before{content:""}.material-icons.text_rotation_down:before{content:""}.material-icons.text_rotation_none:before{content:""}.material-icons.text_snippet:before{content:""}.material-icons.textsms:before{content:""}.material-icons.texture:before{content:""}.material-icons.theater_comedy:before{content:""}.material-icons.theaters:before{content:""}.material-icons.thermostat:before{content:""}.material-icons.thermostat_auto:before{content:""}.material-icons.thumb_down:before{content:""}.material-icons.thumb_down_alt:before{content:""}.material-icons.thumb_down_off_alt:before{content:""}.material-icons.thumb_up:before{content:""}.material-icons.thumb_up_alt:before{content:""}.material-icons.thumb_up_off_alt:before{content:""}.material-icons.thumbs_up_down:before{content:""}.material-icons.thunderstorm:before{content:""}.material-icons.tiktok:before{content:""}.material-icons.time_to_leave:before{content:""}.material-icons.timelapse:before{content:""}.material-icons.timeline:before{content:""}.material-icons.timer:before{content:""}.material-icons.timer_10:before{content:""}.material-icons.timer_10_select:before{content:""}.material-icons.timer_3:before{content:""}.material-icons.timer_3_select:before{content:""}.material-icons.timer_off:before{content:""}.material-icons.tips_and_updates:before{content:""}.material-icons.tire_repair:before{content:""}.material-icons.title:before{content:""}.material-icons.toc:before{content:""}.material-icons.today:before{content:""}.material-icons.toggle_off:before{content:""}.material-icons.toggle_on:before{content:""}.material-icons.token:before{content:""}.material-icons.toll:before{content:""}.material-icons.tonality:before{content:""}.material-icons.topic:before{content:""}.material-icons.tornado:before{content:""}.material-icons.touch_app:before{content:""}.material-icons.tour:before{content:""}.material-icons.toys:before{content:""}.material-icons.track_changes:before{content:""}.material-icons.traffic:before{content:""}.material-icons.train:before{content:""}.material-icons.tram:before{content:""}.material-icons.transcribe:before{content:""}.material-icons.transfer_within_a_station:before{content:""}.material-icons.transform:before{content:""}.material-icons.transgender:before{content:""}.material-icons.transit_enterexit:before{content:""}.material-icons.translate:before{content:""}.material-icons.travel_explore:before{content:""}.material-icons.trending_down:before{content:""}.material-icons.trending_flat:before{content:""}.material-icons.trending_neutral:before{content:""}.material-icons.trending_up:before{content:""}.material-icons.trip_origin:before{content:""}.material-icons.troubleshoot:before{content:""}.material-icons.try:before{content:""}.material-icons.tsunami:before{content:""}.material-icons.tty:before{content:""}.material-icons.tune:before{content:""}.material-icons.tungsten:before{content:""}.material-icons.turn_left:before{content:""}.material-icons.turn_right:before{content:""}.material-icons.turn_sharp_left:before{content:""}.material-icons.turn_sharp_right:before{content:""}.material-icons.turn_slight_left:before{content:""}.material-icons.turn_slight_right:before{content:""}.material-icons.turned_in:before{content:""}.material-icons.turned_in_not:before{content:""}.material-icons.tv:before{content:""}.material-icons.tv_off:before{content:""}.material-icons.two_wheeler:before{content:""}.material-icons.type_specimen:before{content:""}.material-icons.u_turn_left:before{content:""}.material-icons.u_turn_right:before{content:""}.material-icons.umbrella:before{content:""}.material-icons.unarchive:before{content:""}.material-icons.undo:before{content:""}.material-icons.unfold_less:before{content:""}.material-icons.unfold_more:before{content:""}.material-icons.unpublished:before{content:""}.material-icons.unsubscribe:before{content:""}.material-icons.upcoming:before{content:""}.material-icons.update:before{content:""}.material-icons.update_disabled:before{content:""}.material-icons.upgrade:before{content:""}.material-icons.upload:before{content:""}.material-icons.upload_file:before{content:""}.material-icons.usb:before{content:""}.material-icons.usb_off:before{content:""}.material-icons.vaccines:before{content:""}.material-icons.vape_free:before{content:""}.material-icons.vaping_rooms:before{content:""}.material-icons.verified:before{content:""}.material-icons.verified_user:before{content:""}.material-icons.vertical_align_bottom:before{content:""}.material-icons.vertical_align_center:before{content:""}.material-icons.vertical_align_top:before{content:""}.material-icons.vertical_distribute:before{content:""}.material-icons.vertical_shades:before{content:""}.material-icons.vertical_shades_closed:before{content:""}.material-icons.vertical_split:before{content:""}.material-icons.vibration:before{content:""}.material-icons.video_call:before{content:""}.material-icons.video_camera_back:before{content:""}.material-icons.video_camera_front:before{content:""}.material-icons.video_collection:before{content:""}.material-icons.video_file:before{content:""}.material-icons.video_label:before{content:""}.material-icons.video_library:before{content:""}.material-icons.video_settings:before{content:""}.material-icons.video_stable:before{content:""}.material-icons.videocam:before{content:""}.material-icons.videocam_off:before{content:""}.material-icons.videogame_asset:before{content:""}.material-icons.videogame_asset_off:before{content:""}.material-icons.view_agenda:before{content:""}.material-icons.view_array:before{content:""}.material-icons.view_carousel:before{content:""}.material-icons.view_column:before{content:""}.material-icons.view_comfortable:before{content:""}.material-icons.view_comfy:before{content:""}.material-icons.view_comfy_alt:before{content:""}.material-icons.view_compact:before{content:""}.material-icons.view_compact_alt:before{content:""}.material-icons.view_cozy:before{content:""}.material-icons.view_day:before{content:""}.material-icons.view_headline:before{content:""}.material-icons.view_in_ar:before{content:""}.material-icons.view_kanban:before{content:""}.material-icons.view_list:before{content:""}.material-icons.view_module:before{content:""}.material-icons.view_quilt:before{content:""}.material-icons.view_sidebar:before{content:""}.material-icons.view_stream:before{content:""}.material-icons.view_timeline:before{content:""}.material-icons.view_week:before{content:""}.material-icons.vignette:before{content:""}.material-icons.villa:before{content:""}.material-icons.visibility:before{content:""}.material-icons.visibility_off:before{content:""}.material-icons.voice_chat:before{content:""}.material-icons.voice_over_off:before{content:""}.material-icons.voicemail:before{content:""}.material-icons.volcano:before{content:""}.material-icons.volume_down:before{content:""}.material-icons.volume_down_alt:before{content:""}.material-icons.volume_mute:before{content:""}.material-icons.volume_off:before{content:""}.material-icons.volume_up:before{content:""}.material-icons.volunteer_activism:before{content:""}.material-icons.vpn_key:before{content:""}.material-icons.vpn_key_off:before{content:""}.material-icons.vpn_lock:before{content:""}.material-icons.vrpano:before{content:""}.material-icons.wallet:before{content:""}.material-icons.wallet_giftcard:before{content:""}.material-icons.wallet_membership:before{content:""}.material-icons.wallet_travel:before{content:""}.material-icons.wallpaper:before{content:""}.material-icons.warehouse:before{content:""}.material-icons.warning:before{content:""}.material-icons.warning_amber:before{content:""}.material-icons.wash:before{content:""}.material-icons.watch:before{content:""}.material-icons.watch_later:before{content:""}.material-icons.watch_off:before{content:""}.material-icons.water:before{content:""}.material-icons.water_damage:before{content:""}.material-icons.water_drop:before{content:""}.material-icons.waterfall_chart:before{content:""}.material-icons.waves:before{content:""}.material-icons.waving_hand:before{content:""}.material-icons.wb_auto:before{content:""}.material-icons.wb_cloudy:before{content:""}.material-icons.wb_incandescent:before{content:""}.material-icons.wb_iridescent:before{content:""}.material-icons.wb_shade:before{content:""}.material-icons.wb_sunny:before{content:""}.material-icons.wb_twighlight:before{content:""}.material-icons.wb_twilight:before{content:""}.material-icons.wc:before{content:""}.material-icons.web:before{content:""}.material-icons.web_asset:before{content:""}.material-icons.web_asset_off:before{content:""}.material-icons.web_stories:before{content:""}.material-icons.webhook:before{content:""}.material-icons.wechat:before{content:""}.material-icons.weekend:before{content:""}.material-icons.west:before{content:""}.material-icons.whatsapp:before{content:""}.material-icons.whatshot:before{content:""}.material-icons.wheelchair_pickup:before{content:""}.material-icons.where_to_vote:before{content:""}.material-icons.widgets:before{content:""}.material-icons.width_full:before{content:""}.material-icons.width_normal:before{content:""}.material-icons.width_wide:before{content:""}.material-icons.wifi:before{content:""}.material-icons.wifi_1_bar:before{content:""}.material-icons.wifi_2_bar:before{content:""}.material-icons.wifi_calling:before{content:""}.material-icons.wifi_calling_3:before{content:""}.material-icons.wifi_channel:before{content:""}.material-icons.wifi_find:before{content:""}.material-icons.wifi_lock:before{content:""}.material-icons.wifi_off:before{content:""}.material-icons.wifi_password:before{content:""}.material-icons.wifi_protected_setup:before{content:""}.material-icons.wifi_tethering:before{content:""}.material-icons.wifi_tethering_error:before{content:""}.material-icons.wifi_tethering_error_rounded:before{content:""}.material-icons.wifi_tethering_off:before{content:""}.material-icons.wind_power:before{content:""}.material-icons.window:before{content:""}.material-icons.wine_bar:before{content:""}.material-icons.woman:before{content:""}.material-icons.woo_commerce:before{content:""}.material-icons.wordpress:before{content:""}.material-icons.work:before{content:""}.material-icons.work_history:before{content:""}.material-icons.work_off:before{content:""}.material-icons.work_outline:before{content:""}.material-icons.workspace_premium:before{content:""}.material-icons.workspaces:before{content:""}.material-icons.workspaces_filled:before{content:""}.material-icons.workspaces_outline:before{content:""}.material-icons.wrap_text:before{content:""}.material-icons.wrong_location:before{content:""}.material-icons.wysiwyg:before{content:""}.material-icons.yard:before{content:""}.material-icons.youtube_searched_for:before{content:""}.material-icons.zoom_in:before{content:""}.material-icons.zoom_in_map:before{content:""}.material-icons.zoom_out:before{content:""}.material-icons.zoom_out_map:before{content:""} -/*! - Lato font. -*/@font-face{font-family:Lato;font-weight:100;font-style:normal;text-rendering:optimizeLegibility;src:url(fonts/lato-hairline.woff2) format("woff2"),url(fonts/lato-hairline.woff) format("woff")}@font-face{font-family:Lato;font-weight:100;font-style:italic;text-rendering:optimizeLegibility;src:url(fonts/lato-hairline-italic.woff2) format("woff2"),url(fonts/lato-hairline-italic.woff) format("woff")}@font-face{font-family:Lato;font-weight:200;font-style:normal;text-rendering:optimizeLegibility;src:url(fonts/lato-thin.woff2) format("woff2"),url(fonts/lato-thin.woff) format("woff")}@font-face{font-family:Lato;font-weight:200;font-style:italic;text-rendering:optimizeLegibility;src:url(fonts/lato-thin-italic.woff2) format("woff2"),url(fonts/lato-thin-italic.woff) format("woff")}@font-face{font-family:Lato;font-weight:300;font-style:normal;text-rendering:optimizeLegibility;src:url(fonts/lato-light.woff2) format("woff2"),url(fonts/lato-light.woff) format("woff")}@font-face{font-family:Lato;font-weight:300;font-style:italic;text-rendering:optimizeLegibility;src:url(fonts/lato-light-italic.woff2) format("woff2"),url(fonts/lato-light-italic.woff) format("woff")}@font-face{font-family:Lato;font-weight:400;font-style:normal;text-rendering:optimizeLegibility;src:url(fonts/lato-normal.woff2) format("woff2"),url(fonts/lato-normal.woff) format("woff")}@font-face{font-family:Lato;font-weight:400;font-style:italic;text-rendering:optimizeLegibility;src:url(fonts/lato-normal-italic.woff2) format("woff2"),url(fonts/lato-normal-italic.woff) format("woff")}@font-face{font-family:"Lato Medium";font-weight:400;font-style:normal;text-rendering:optimizeLegibility;src:url(fonts/lato-medium.woff2) format("woff2"),url(fonts/lato-medium.woff) format("woff")}@font-face{font-family:"Lato Medium";font-weight:400;font-style:italic;text-rendering:optimizeLegibility;src:url(fonts/lato-medium-italic.woff2) format("woff2"),url(fonts/lato-medium-italic.woff) format("woff")}@font-face{font-family:Lato;font-weight:500;font-style:normal;text-rendering:optimizeLegibility;src:url(fonts/lato-semibold.woff2) format("woff2"),url(fonts/lato-semibold.woff) format("woff")}@font-face{font-family:Lato;font-weight:500;font-style:italic;text-rendering:optimizeLegibility;src:url(fonts/lato-semibold-italic.woff2) format("woff2"),url(fonts/lato-semibold-italic.woff) format("woff")}@font-face{font-family:Lato;font-weight:600;font-style:normal;text-rendering:optimizeLegibility;src:url(fonts/lato-bold.woff2) format("woff2"),url(fonts/lato-bold.woff) format("woff")}@font-face{font-family:Lato;font-weight:600;font-style:italic;text-rendering:optimizeLegibility;src:url(fonts/lato-bold-italic.woff2) format("woff2"),url(fonts/lato-bold-italic.woff) format("woff")}@font-face{font-family:Lato;font-weight:800;font-style:normal;text-rendering:optimizeLegibility;src:url(fonts/lato-heavy.woff2) format("woff2"),url(fonts/lato-heavy.woff) format("woff")}@font-face{font-family:Lato;font-weight:800;font-style:italic;text-rendering:optimizeLegibility;src:url(fonts/lato-heavy-italic.woff2) format("woff2"),url(fonts/lato-heavy-italic.woff) format("woff")}@font-face{font-family:Lato;font-weight:900;font-style:normal;text-rendering:optimizeLegibility;src:url(fonts/lato-black.woff2) format("woff2"),url(fonts/lato-black.woff) format("woff")}@font-face{font-family:Lato;font-weight:900;font-style:italic;text-rendering:optimizeLegibility;src:url(fonts/lato-black-italic.woff2) format("woff2"),url(fonts/lato-black-italic.woff) format("woff")} -.material-icons.md-18{font-size:18px}.material-icons.md-24{font-size:24px}.material-icons.md-36{font-size:36px}.material-icons.md-48{font-size:48px}.material-icons.md-dark{color:rgba(0,0,0,.54)}.material-icons.md-dark.md-inactive{color:rgba(0,0,0,.26)}.material-icons.md-light{color:#fff}.material-icons.md-light.md-inactive{color:rgba(255,255,255,.3)} -pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#383a42;background:#fafafa}.hljs-comment,.hljs-quote{color:#a0a1a7;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#a626a4}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e45649}.hljs-literal{color:#0184bb}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#50a14f}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#986801}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#4078f2}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#c18401}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline} -::-moz-selection{color:#fff;background-color:#000}::selection{color:#fff;background-color:#000}.desktopHide{display:none}.logo{position:fixed;z-index:20;top:.4em;left:.6em}h2,h3,h4{font-family:"PT Sans",sans-serif;text-transform:uppercase}p,li,label{color:#666}a{color:#000;font-weight:bold}a.nostyle{text-decoration:none}a:hover,a:focus{text-decoration:none}form fieldset{border:0;padding:0;margin:0}form input[type=text],form input[type=number],select,form input[type=password],form input[type=url],form input[type=email]{border:1px solid #999;padding:.5em 1em;min-width:12em;color:#666}@media screen{select{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:0;background:#fff url(themes/_global/img/bg-select.png) no-repeat right center}}.inline .row{display:inline-block;margin-right:.5em}.inline label{min-width:6em}fieldset label{display:inline-block;min-width:12.5em;color:#666}label{margin-right:.5em}form .row{margin-bottom:.5em}form button,input[type=submit]{cursor:pointer;background-color:#000;color:#fff;padding:.5em 1em;display:inline-block;border:1px solid #000}form button:hover,form button:focus,input[type=submit]:hover,input[type=submit]:focus{background-color:#fff;color:#000;transition:all .5s ease}#bookmarklet{cursor:move}h2::after{content:"";height:4px;width:20%;background-color:#000;display:block}.links{padding:0;margin:0}.links li{list-style:none;margin:0;padding:0}#links{position:fixed;top:0;width:10em;left:0;text-align:right;background-color:#333;padding-top:9.5em;height:100%;box-shadow:inset -4px 0 20px rgba(0,0,0,.6);z-index:15}#links>li>a{display:block;padding:.5em 2em .5em 1em;color:#fff;position:relative;text-transform:uppercase;text-decoration:none;font-weight:normal;font-family:"PT Sans",sans-serif;transition:all .5s ease}#links>li>a:hover,#links>li>a:focus{background-color:#999;color:#000}#links .current::after{content:"";width:0;height:0;position:absolute;border:10px solid rgba(0,0,0,0);border-right-color:#eee;right:0;top:50%;margin-top:-10px}#links li:last-child{position:fixed;bottom:1em;width:10em}#links li:last-child a::before{font-size:1.2em;position:relative;top:2px}#main{margin-left:12em;position:relative;z-index:10;padding-right:5%;padding-bottom:1em}#sort{padding:0;list-style-type:none;opacity:.5;display:inline-block}#sort li{display:inline;font-size:.9em}#sort li+li{margin-left:10px}#sort a{padding:2px 2px 0;vertical-align:middle}#sort img{vertical-align:baseline}#sort img :hover{cursor:pointer}#display-mode{float:right;margin-top:10px;margin-bottom:10px;opacity:.5}#listmode{width:16px;display:inline-block;text-decoration:none}#listmode.tablemode{background:url(themes/_global/img/table.png) no-repeat bottom}#listmode .listmode{background:url(themes/_global/img/list.png) no-repeat bottom}#warning_message{position:fixed;background-color:tomato;z-index:1000;bottom:0;left:0;width:100%;color:#000}#content{margin-top:2em;min-height:30em}footer{text-align:right;position:relative;bottom:0;right:5em;color:#999;font-size:.8em;font-style:italic;z-index:20}footer a{color:#999;font-weight:normal}.list-entries{letter-spacing:-5px}.listmode.entry{width:100%;height:inherit}.card-entry-tags{max-height:2em;overflow-y:hidden;padding:0;margin:0}.card-entry-tags li,.card-entry-tags span{display:inline-block;margin:0 5px;padding:5px 12px;background-color:rgba(0,0,0,.6);border-radius:3px;max-height:2em;overflow:hidden;text-overflow:ellipsis}.card-entry-tags a,.card-entry-labels a{text-decoration:none;font-weight:normal;color:#fff}.nav-panel-add-tag{margin-top:10px}.list-entries+.results{margin-bottom:2em}.reading-time,.created-at{color:#999;font-style:italic;font-weight:normal;font-size:.9em}.estimatedTime small{position:relative;top:-1px}.entry{background-color:#fff;letter-spacing:normal;box-shadow:0 3px 7px rgba(0,0,0,.3);display:inline-block;width:32%;margin-bottom:1.5em;vertical-align:top;margin-right:1%;position:relative;overflow:hidden;padding:1.5em 0 3em;height:440px}.entry img.preview{width:100%;-o-object-fit:cover;object-fit:cover;height:100%}.entry::before{content:"";width:0;height:0;border:10px solid rgba(0,0,0,0);border-bottom-color:#000;position:absolute;bottom:.7em;z-index:10;right:1.5em;transition:all .5s ease}.entry::after{content:"";position:absolute;height:7px;width:100%;bottom:0;left:0;background-color:#000;transition:all .5s ease}.entry:hover{box-shadow:0 3px 10px #000}.entry:hover::after{height:40px}.entry:hover::before{bottom:2.3em}.entry:hover h2 a{color:#666}.entry:hover .tools{bottom:0}.entry h2{text-transform:none;margin-bottom:0;line-height:1.2;margin-left:5px}.entry::after{content:none}.entry a{display:block;text-decoration:none;color:#000;word-wrap:break-word;transition:all .5s ease}.entry p{color:#666;font-size:.9em;line-height:1.7;margin:5px 5px auto}.entry h2 a::first-letter{text-transform:uppercase}.entry .tools{position:absolute;bottom:-40px;left:0;background:#000;width:100%;z-index:10;padding-right:.5em;text-align:right;transition:all .5s ease}.entry .tools a{color:#666;text-decoration:none;display:block;padding:.4em}.entry .tools a:hover{color:#fff}.entry .tools li{display:inline-block;margin-top:10px}.entry .tools li:first-child{float:left;font-size:.9em;max-width:calc(100% - 160px);text-overflow:ellipsis;overflow:hidden;white-space:nowrap;max-height:2em;margin-left:10px}.entry .card-entry-labels{position:absolute;top:100px;left:-1em;z-index:90;max-width:50%;padding-left:0}.entry .card-entry-labels li{margin:10px 10px 10px auto;padding:5px 12px 5px 25px;background-color:rgba(0,0,0,.6);border-radius:0 3px 3px 0;color:#fff;cursor:default;max-height:2em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.entry .card-entry-labels li a{color:#fff}.entry:nth-child(3n+1){margin-left:0}.results{letter-spacing:-5px;padding:0 0 .5em}.results>*{display:inline-block;vertical-align:top;letter-spacing:normal;width:50%;text-align:right}div.pagination ul{text-align:right}.nb-results{text-align:left;font-style:italic;color:#999;display:inline-flex}div.pagination ul a{color:#999;text-decoration:none}div.pagination ul a:hover,div.pagination ul a:focus{text-decoration:underline}div.pagination ul>*{display:inline-block;margin-left:.5em}div.pagination ul .prev.disabled,div.pagination ul .next.disabled{display:none}div.pagination ul .current{height:25px;padding:4px 8px;border:1px solid #d5d5d5;text-decoration:none;font-weight:bold;color:#000;background-color:#ccc}.card-tag-form{display:inline-block}.card-tag-form input[type=text]{min-width:20em}.hide,.hidden{display:none}#article{width:70%;margin-bottom:3em;text-align:justify}#article .tags{margin-bottom:1em}#article i{font-style:normal}#article h1{text-align:left}#article h2::after{content:none}#article h2,#article h3,#article h4{text-transform:none}blockquote{border:1px solid #999;background-color:#fff;padding:1em;margin:0}.topPosF{position:fixed;right:20%;bottom:2em;font-size:1.5em}#article_toolbar{margin-bottom:1em}#article_toolbar li{display:inline-block;margin:3px auto}#article_toolbar a{background-color:#000;padding:.3em .5em .2em;color:#fff;text-decoration:none}#article_toolbar a:hover,#article_toolbar a:focus{background-color:#999}#nav-btn-add-tag{cursor:pointer}.shaarli::before{content:"*"}.return{text-decoration:none;margin-top:1em;display:block}.return::before{margin-right:.5em}.notags{font-style:italic;color:#999}.icon-feed{background-color:#000;color:#fff;padding:.2em .5em}.icon-feed::before{position:relative;top:2px}.list-tags li{margin-bottom:.5em}.list-tags .icon-feed:hover,.list-tags .icon-feed:focus{background-color:#fff;color:#000;text-decoration:none}.list-tags a{text-decoration:none}.list-tags a:hover,.list-tags a:focus{text-decoration:underline}pre code{font-family:"Courier New",Courier,monospace}#filters{position:fixed;width:20%;height:100%;top:0;right:0;background-color:#fff;padding:30px 30px 15px 15px;border-left:1px #333 solid;z-index:12;min-width:300px}#filters form .filter-group{margin:5px}#download-form{position:fixed;width:10%;height:100%;top:0;right:0;background-color:#fff;padding:30px 30px 15px 15px;border-left:1px #333 solid;z-index:12;min-width:200px}#download-form li{display:block;padding:.5em 2em .5em 1em;color:#fff;position:relative;text-transform:uppercase;text-decoration:none;font-weight:400;font-family:"PT Sans",sans-serif;transition:all .5s ease}@font-face{font-family:icomoon;src:url(fonts/IcoMoon-Free.ttf);font-weight:normal;font-style:normal}.material-icons{font-family:"Material Icons";font-weight:normal;font-style:normal;font-size:1em;width:1em;height:1em;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:"liga"}.material-icons .md-18{font-size:18px}.material-icons .md-24{font-size:24px}.material-icons .md-36{font-size:36px}.material-icons .md-48{font-size:48px}.material-icons .vertical-align-middle{vertical-align:middle !important}.icon span,.icon-image span{position:absolute;top:-9999px}[class^=icon-]::before,[class*=" icon-"]::before{font-family:icomoon;speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;letter-spacing:0;font-feature-settings:"liga";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-flattr::before{content:""}.icon-mail::before{content:""}.icon-up-open::before{content:""}.icon-star::before{content:""}.icon-check::before{content:""}.icon-link::before{content:""}.icon-reply::before{content:""}.icon-menu::before{content:""}.icon-clock::before{content:""}.icon-twitter::before{content:""}.icon-down-open::before{content:""}.icon-trash::before{content:""}.icon-delete::before{content:""}.icon-power::before{content:""}.icon-arrow-up-thick::before{content:""}.icon-feed::before{content:""}.icon-print::before{content:""}.icon-reload::before{content:""}.icon-price-tags::before{content:""}.icon-eye::before{content:""}.icon-no-eye::before{content:""}.icon-calendar::before{content:""}.icon-time::before{content:""}.icon-image{background:no-repeat center/80%;padding-right:1em !important;padding-left:1em !important}.icon-image--carrot{background-image:url(themes/_global/img/icons/carrot-icon--white.png)}.icon-image--diaspora{background-image:url(themes/_global/img/icons/Diaspora-asterisk.svg)}.icon-image--unmark{background-image:url(themes/_global/img/icons/unmark-icon--black.png)}.icon-image--shaarli{background-image:url(themes/_global/img/icons/shaarli.png)}.icon-star.fav::before{color:#fff}.icon-check.archive::before{color:#fff}.login{background-color:#333}.login #main{padding:0;margin:0}.login form{background-color:#fff;padding:1.5em;box-shadow:0 1px 8px rgba(0,0,0,.9);width:20em;position:absolute;top:8em;left:50%;margin-left:-10em}.login .logo{position:absolute;top:2em;left:50%;margin-left:-55px}.popup-form{background:rgba(0,0,0,.5);position:absolute;top:0;left:10em;z-index:20;height:100%;width:100%;margin:0;margin-top:-30% !important;padding:2em;display:none;border-left:1px #eee solid}.popup-form form{background-color:#fff;position:absolute;top:0;left:0;z-index:20;border:10px solid #000;width:400px;height:200px;padding:2em}#bagit-form-form .addurl{margin-left:0}.closeMessage,.close-button{background-color:#000;color:#fff;font-size:1.2em;line-height:1.6;width:1.6em;height:1.6em;text-align:center;text-decoration:none}.closeMessage:hover,.closeMessage:focus,.close-button:hover,.close-button:focus{background-color:#999;color:#000}.close-button--popup{display:inline-block;position:absolute;top:0;right:0;font-size:1.4em}.active-current{background-color:#999}.active-current::after{content:"";width:0;height:0;position:absolute;border:10px solid rgba(0,0,0,0);border-right-color:#eee;right:0;top:50%;margin-top:-10px}.opacity03{opacity:.3}.add-to-wallabag-link-after{background-color:#000;color:#fff;padding:0 3px 2px}a.add-to-wallabag-link-after{visibility:hidden;position:absolute;opacity:0;transition-duration:2s;transition-timing-function:ease-out}#article article a:hover+a.add-to-wallabag-link-after,a.add-to-wallabag-link-after:hover{opacity:1;visibility:visible;transition-duration:.3s;transition-timing-function:ease-in}a.add-to-wallabag-link-after::after{content:"w"}#add-link-result{font-weight:bold;font-size:.9em}.btn-clickable{cursor:pointer}.messages{text-align:left;width:60%;margin:auto 17%}.messages>*{display:inline-block}.messages .install{text-align:left}.messages .install.error{border:1px solid #c42608;color:#c00 !important;background:#fff0ef}.messages .install.notice{border:1px solid #ebcd41;color:#000;background:#fffcd3}.messages .install.success{border:1px solid #6dc70c;background:#e0fbcc !important}.warning{font-weight:bold;display:block;width:100%}.more-info{font-size:.85em;line-height:1.5;color:#aaa}.more-info a{color:#aaa}@media screen and (max-width: 1050px){.entry{width:49%}.entry:nth-child(3n+1){margin-left:1.5%}.entry:nth-child(2n+1){margin-left:0}}@media screen and (max-width: 900px){#article{width:80%}.topPosF{right:2.5em}}@media screen and (max-width: 700px){.entry{width:100%;margin-left:0}#display-mode{display:none}}@media screen and (max-height: 770px){.menu.users,.menu.internal,.menu.developer{display:none}}@media screen and (max-width: 500px){.entry{width:100%;margin-left:0}body>header{background-color:#333;position:fixed;top:0;width:100%;height:3em;z-index:11}#links li:last-child{position:static;width:auto}#links li:last-child a::before{content:none}.logo{width:1.25em;height:1.25em;left:0;top:0}.login>header{position:static}.login form{width:100%;position:static;margin-left:0}.login .logo{height:auto;top:.5em;width:75px;margin-left:-37.5px}.desktopHide{display:block;position:fixed;z-index:20;top:0;right:0;border:0;width:2.5em;height:2.5em;cursor:pointer;background-color:#999;font-size:1.2em}.desktopHide:hover,.desktopHide:focus{background-color:#fff}#links{display:none;width:100%;height:auto;padding-top:3em}#links.menu--open{display:block}footer{position:static;margin-right:3em}#main{margin-left:1.5em;padding-right:1.5em;position:static;margin-top:3em}.card-entry-labels{display:none}#article_toolbar .topPosF{display:none}#article{width:100%}#article h1{font-size:1.5em}#article_toolbar a{padding:.3em .4em .2em}#display-mode{display:none}.popup-form,#bagit-form,#search-form{left:0;width:100%;border-left:none}.popup-form form,#bagit-form form,#search-form form{width:100%}}@media only print{header h1.logo{display:none}}@media print{body{font-family:serif;background-color:#fff}@page{margin:1cm}img{max-width:100% !important}body>.logo,#article_toolbar,#links,#sort,body>footer,.top_link,div.tools,header div,.messages,.entrie+.results,#article .mbm a,#article-informations{display:none !important}article{border:none !important}.vieworiginal a::after{content:" (" attr(href) ")"}abbr[title]::after{content:" (" attr(title) ")"}.pagination span.current{border-style:dashed}#main{width:100%;margin:0;padding:0}#article{width:100%}}*{box-sizing:border-box}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%}body{font-size:1em;line-height:1.5;margin:0}h1:first-child,h2:first-child,h3:first-child,h4:first-child,h5:first-child,h6:first-child,p:first-child,ul:first-child,ol:first-child,dl:first-child{margin-top:0}code,kbd,pre,samp{font-family:monospace,serif}pre{white-space:pre-wrap}.upper{text-transform:uppercase}.bold{font-weight:bold}.inner{margin:0 auto;max-width:61.25em}table,img,figure{max-width:100%;height:auto}iframe{max-width:100%}.fl{float:left}.fr{float:right}table{border-collapse:collapse}figure{margin:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}input[type=search]{-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield}.dib{display:inline-block;vertical-align:middle}.dnone{display:none}.dtable{display:table}.dtable>*{display:table-row}.dtable>*>*{display:table-cell}.element-invisible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.small{font-size:.8em}.big{font-size:1.2em}.w100{width:100%}.w90{width:90%}.w80{width:80%}.w70{width:70%}.w60{width:60%}.w50{width:50%}.w40{width:40%}.w30{width:30%}.w20{width:20%}.w10{width:10%}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}@media screen{select{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:0}} - -/*# sourceMappingURL=baggy.css.map*/ \ No newline at end of file diff --git a/web/wallassets/baggy.css.map b/web/wallassets/baggy.css.map deleted file mode 100644 index bd69a86ec..000000000 --- a/web/wallassets/baggy.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"baggy.css","mappings":"AAGA,0DAGC,wDACA,mBACA,gBACA,SACA,UACA,gBAIA,gBAGA,mBACA,gBACA,cAMD,iBACC,yDACA,4BAGD,0RAOC,yDACA,4BAMD,cACC,mBACA,+BACA,wGAGD,wBACC,mBACA,8BACA,wGAMD,mBACC,kBAKD,oDAGC,aAGD,kBACC,aAGD,sEAIC,kBACA,eACA,cAGD,gBACC,aACA,kBAMD,iBACC,iBACA,kBACA,WACA,YACA,6BAGD,uBACC,+BAGD,wBACC,iCAGD,wBACC,cACA,WACA,YACA,cACA,YACA,gBACA,mBACA,eAQD,iBACC,QACA,SAGD,kBACC,SACA,UACA,YACA,WACA,gBACA,yBACA,uCACA,yBACA,sCAGA,kBAGA,wCACA,qCAGD,sCACC,UACA,YAGD,sCACC,YACA,QAGD,yBACC,iBAGD,uEAEC,UACA,SACA,gBAGD,wBACC,WACA,cACA,WACA,YACA,wBACA,kBACA,aACA,SAGD,4CACC,UACA,UAGD,4CACC,4BACA,YACA,SAGD,qHAGC,kBACA,eAGD,kCACC,6BACA,0CAGD,8CACC,gBAGD,wDAEC,6BACA,2CAMD,sBACC,gBAGD,0EAEC,iBAMD,2FAEC,iBACA,oBACA,cACA,eACA,kBACA,gBACA,gBAGD,sCACC,kBACA,QACA,UACA,iBACA,UAIA,+BACA,YAGD,0GAEC,UAGD,qFAEC,eACA,qBACA,WACA,YACA,gBACA,YACA,WACA,mBACA,+BACA,aAGD,kMAIC,WAGD,mGAEC,UAGD,uDACC,aAGD,sDACC,4BAGD,wDACC,4BAGD,sDACC,6BAMD,kCACC,kBAGD,wCACC,MACA,eACA,eACA,eAGD,mFAEC,cACA,eACA,iBACA,YACA,SACA,cACA,gBAGA,yBACA,sBACA,YAGD,8DACC,WACA,UAGD,0EACC,kBACA,yBACA,0BAGD,6EACC,YACA,sBACA,0BACA,4CAGD,+EACC,WACA,sBACA,0BAGD,uDACC,iBAIA,0BAGD,+FAEC,yBACA,aAGD,2GAEC,WACA,YACA,UACA,eACA,iBACA,eAGD,sCACC,gBAGD,8GAGC,iBACA,YACA,6BACA,yBAmBA,4GAcA,uHACC,CAGD,oHACC,CAMD,0BAGD,yDACC,gBACA,gCAIA,0BAGD,uEAEC,kBACA,qBACA,qBACA,cACA,0CACA,qBACA,iBACA,eACA,iBACA,yBACA,yBAsBA,oIAaA,mFACC,CAED,gFACC,CAKD,kBAGD,0BACC,kBACA,QACA,SACA,cACA,WACA,WACA,YACA,gBACA,4BAGD,qMAKC,aACA,qBACA,yBAsBA,iIAOA,WACA,qCAGD,gEAEC,gBACA,6BAGD,wFAEC,qBACA,yBAsBA,gIASD,yCACC,6BAGD,uJAGC,gBACA,6BAGD,0CACC,4BAGD,2EACC,yBAGD,6DACC,4BACA,YAGD,kBACC,kBACA,MACA,QACA,WACA,YACA,+BAGD,sCACC,WACA,OACA,6BAGD,sCACC,SACA,SACA,+BAGD,yDACC,6BAMD,kBACC,WACA,eACA,UACA,OACA,WACA,eACA,iBACA,kBACA,gBACA,0BACA,gCAIA,4BAGD,0BACC,qBAGD,wBACC,qBAGD,oBACC,SAGD,oBACC,WAGD,uBACC,MAMD,gBACC,mBAGD,+BACC,qBACA,cACA,kBACA,gBACA,iBACA,yBAIA,kBAMD,kBACC,eACA,MACA,QACA,OACA,gBACA,cACA,YACA,gCACA,kBACA,mBAIA,gBAKA,iDACC,CACD,8CACC,CAGF,yBACC,eACA,iBACA,cACA,yCACA,kBACA,SAID,4FAEC,kBACA,qBACA,gBACA,iBACA,cACA,iBAGD,yGAEC,gBACA,cACA,WACA,iBAIA,4BAGD,mDACC,iBAGD,mDACC,cACA,YACA,wBACA,sBACA,yBACA,iBACA,gBACA,iBACA,gBACA,eACA,YACA,WACA,yBAIA,4BAKA,4CACC,CACD,yCACC,CAIF,yDACC,aACA,sBAGD,0CACC,kBACA,UACA,QACA,YACA,mBACA,WACA,YACA,4BACA,WAGD,gGAEC,WAGD,iDACC,UAGD,sDACC,yBACA,UACA,mBACA,WACA,gBAOA,mFACC,CAED,gFACC,CAIF,8KAGC,oBAGD,4DACC,kBACA,QACA,SACA,WACA,cACA,UACA,WACA,6BAGD,kEACC,6BAGD,sEAIC,4BACA,iBAGD,4EACC,UACA,UACA,6BAGD,kFACC,6BAGD,qBACC,mBACA,+BACA,wGAGD,uBACC,sB;AC13BD,WACA,4BACE,kBACA,gBACA,mBACA,4CACA,yLAEA,iBAEF,4BACE,mBACA,kBACA,eACA,qBAEA,cACA,oBACA,sBACA,iBACA,mBACA,kBAEA,mCAEA,kCAEA,kCAEA,6BAEA,6BACA,WACE,8BACF,WACE,8BACF,WACE,6BACF,WACE,8BACF,WACE,8BACF,WACE,8BACF,WACE,8BACF,WACE,8BACF,WACE,8BACF,WACE,sCACF,WACE,8BACF,WACE,8BACF,WACE,4BACF,WACE,iCACF,WACE,uCACF,WACE,8BACF,WACE,8BACF,WACE,8BACF,WACE,8BACF,WACE,8BACF,WACE,4BACF,WACE,iCACF,WACE,6BACF,WACE,+BACF,WACE,sCACF,WACE,6BACF,WACE,qCACF,WACE,uCACF,WACE,4BACF,WACE,iCACF,WACE,6BACF,WACE,4BACF,WACE,uCACF,WACE,4CACF,WACE,4BACF,WACE,iCACF,WACE,6BACF,WACE,4BACF,WACE,4BACF,WACE,iCACF,WACE,6BACF,WACE,+BACF,WACE,sCACF,WACE,oCACF,WACE,4BACF,WACE,iCACF,WACE,6BACF,WACE,4BACF,WACE,iCACF,WACE,6BACF,WACE,4BACF,WACE,iCACF,WACE,6BACF,WACE,4BACF,WACE,iCACF,WACE,6BACF,WACE,4BACF,WACE,gCACF,WACE,qCACF,WACE,sCACF,WACE,oCACF,WACE,2CACF,WACE,sCACF,WACE,0CACF,WACE,mCACF,WACE,2CACF,WACE,wCACF,WACE,+CACF,WACE,oCACF,WACE,uCACF,WACE,qCACF,WACE,iCACF,WACE,4BACF,WACE,4BACF,WACE,oCACF,WACE,kCACF,WACE,kCACF,WACE,gCACF,WACE,qCACF,WACE,iCACF,WACE,iCACF,WACE,kCACF,WACE,mCACF,WACE,2CACF,WACE,oCACF,WACE,iCACF,WACE,sCACF,WACE,oCACF,WACE,iCACF,WACE,qCACF,WACE,yCACF,WACE,sCACF,WACE,4CACF,WACE,qCACF,WACE,iCACF,WACE,0CACF,WACE,iCACF,WACE,qCACF,WACE,2CACF,WACE,sCACF,WACE,qCACF,WACE,iCACF,WACE,oCACF,WACE,+BACF,WACE,6CACF,WACE,8BACF,WACE,kCACF,WACE,oCACF,WACE,4BACF,WACE,0CACF,WACE,iDACF,WACE,sDACF,WACE,mDACF,WACE,oDACF,WACE,qDACF,WACE,mDACF,WACE,oDACF,WACE,sCACF,WACE,iCACF,WACE,wCACF,WACE,4CACF,WACE,8CACF,WACE,yCACF,WACE,wCACF,WACE,gCACF,WACE,wCACF,WACE,8BACF,WACE,kCACF,WACE,kCACF,WACE,iCACF,WACE,8BACF,WACE,gDACF,WACE,8CACF,WACE,+CACF,WACE,8CACF,WACE,8CACF,WACE,2CACF,WACE,kCACF,WACE,sCACF,WACE,gCACF,WACE,kCACF,WACE,wCACF,WACE,oCACF,WACE,kCACF,WACE,+BACF,WACE,gCACF,WACE,kCACF,WACE,qCACF,WACE,4BACF,WACE,kCACF,WACE,4BACF,WACE,qCACF,WACE,yCACF,WACE,yCACF,WACE,qCACF,WACE,8BACF,WACE,iCACF,WACE,6BACF,WACE,oCACF,WACE,qCACF,WACE,gCACF,WACE,mCACF,WACE,mCACF,WACE,uCACF,WACE,2CACF,WACE,0CACF,WACE,0CACF,WACE,2CACF,WACE,wCACF,WACE,uCACF,WACE,wCACF,WACE,+CACF,WACE,sCACF,WACE,sCACF,WACE,0CACF,WACE,mCACF,WACE,oCACF,WACE,wCACF,WACE,qCACF,WACE,kCACF,WACE,gCACF,WACE,qCACF,WACE,mCACF,WACE,mCACF,WACE,uCACF,WACE,wCACF,WACE,0CACF,WACE,4CACF,WACE,6CACF,WACE,kCACF,WACE,4CACF,WACE,6CACF,WACE,wCACF,WACE,yCACF,WACE,4BACF,WACE,qCACF,WACE,oCACF,WACE,qCACF,WACE,mCACF,WACE,oCACF,WACE,oCACF,WACE,mCACF,WACE,mCACF,WACE,qCACF,WACE,4CACF,WACE,4CACF,WACE,oCACF,WACE,sCACF,WACE,wCACF,WACE,qCACF,WACE,mCACF,WACE,kCACF,WACE,qCACF,WACE,uCACF,WACE,kCACF,WACE,iCACF,WACE,8CACF,WACE,kCACF,WACE,iCACF,WACE,kCACF,WACE,+BACF,WACE,qCACF,WACE,8BACF,WACE,sCACF,WACE,gCACF,WACE,gCACF,WACE,+BACF,WACE,kCACF,WACE,yCACF,WACE,iCACF,WACE,gCACF,WACE,sCACF,WACE,sCACF,WACE,sCACF,WACE,sCACF,WACE,sCACF,WACE,sCACF,WACE,sCACF,WACE,sCACF,WACE,8CACF,WACE,qCACF,WACE,sCACF,WACE,oCACF,WACE,wCACF,WACE,qCACF,WACE,4BACF,WACE,qCACF,WACE,sCACF,WACE,uCACF,WACE,gCACF,WACE,oCACF,WACE,iCACF,WACE,8BACF,WACE,qCACF,WACE,gCACF,WACE,gCACF,WACE,+BACF,WACE,sCACF,WACE,8BACF,WACE,sCACF,WACE,kCACF,WACE,kCACF,WACE,wCACF,WACE,4CACF,WACE,2CACF,WACE,wCACF,WACE,4CACF,WACE,sCACF,WACE,oCACF,WACE,iCACF,WACE,gCACF,WACE,6BACF,WACE,6BACF,WACE,oCACF,WACE,iCACF,WACE,qCACF,WACE,uCACF,WACE,wCACF,WACE,yCACF,WACE,wCACF,WACE,kCACF,WACE,mCACF,WACE,sCACF,WACE,qCACF,WACE,qCACF,WACE,0CACF,WACE,qCACF,WACE,oCACF,WACE,qCACF,WACE,qCACF,WACE,qCACF,WACE,mCACF,WACE,wCACF,WACE,4BACF,WACE,2CACF,WACE,yCACF,WACE,qCACF,WACE,qCACF,WACE,qCACF,WACE,qCACF,WACE,qCACF,WACE,qCACF,WACE,qCACF,WACE,wCACF,WACE,wCACF,WACE,uCACF,WACE,0CACF,WACE,0CACF,WACE,8CACF,WACE,qCACF,WACE,uCACF,WACE,8CACF,WACE,wCACF,WACE,sCACF,WACE,8BACF,WACE,qCACF,WACE,mCACF,WACE,8BACF,WACE,qCACF,WACE,iCACF,WACE,mCACF,WACE,kCACF,WACE,iCACF,WACE,wCACF,WACE,8BACF,WACE,8BACF,WACE,+BACF,WACE,6BACF,WACE,kCACF,WACE,uCACF,WACE,uCACF,WACE,0CACF,WACE,4CACF,WACE,2CACF,WACE,6BACF,WACE,iCACF,WACE,kCACF,WACE,mCACF,WACE,oCACF,WACE,6CACF,WACE,sCACF,WACE,mCACF,WACE,uCACF,WACE,+BACF,WACE,mCACF,WACE,uCACF,WACE,qCACF,WACE,sCACF,WACE,uCACF,WACE,oCACF,WACE,oCACF,WACE,qCACF,WACE,iCACF,WACE,+BACF,WACE,4CACF,WACE,6CACF,WACE,0CACF,WACE,kCACF,WACE,mCACF,WACE,mCACF,WACE,sCACF,WACE,wCACF,WACE,oCACF,WACE,kCACF,WACE,8BACF,WACE,+BACF,WACE,6BACF,WACE,uCACF,WACE,2CACF,WACE,+BACF,WACE,yCACF,WACE,iCACF,WACE,oCACF,WACE,mCACF,WACE,kCACF,WACE,4CACF,WACE,0CACF,WACE,8BACF,WACE,kCACF,WACE,+BACF,WACE,sCACF,WACE,uCACF,WACE,yCACF,WACE,6BACF,WACE,oCACF,WACE,4CACF,WACE,8BACF,WACE,kCACF,WACE,gDACF,WACE,qCACF,WACE,6CACF,WACE,kCACF,WACE,sCACF,WACE,kCACF,WACE,qCACF,WACE,sCACF,WACE,mCACF,WACE,uCACF,WACE,2CACF,WACE,+BACF,WACE,+BACF,WACE,6CACF,WACE,8BACF,WACE,oCACF,WACE,0CACF,WACE,8BACF,WACE,kCACF,WACE,8BACF,WACE,yCACF,WACE,uCACF,WACE,gDACF,WACE,2CACF,WACE,8BACF,WACE,qCACF,WACE,mCACF,WACE,uCACF,WACE,kCACF,WACE,oCACF,WACE,mCACF,WACE,qCACF,WACE,uCACF,WACE,4BACF,WACE,mCACF,WACE,6BACF,WACE,iCACF,WACE,+BACF,WACE,qCACF,WACE,oCACF,WACE,6CACF,WACE,mCACF,WACE,iCACF,WACE,gCACF,WACE,qCACF,WACE,0CACF,WACE,+BACF,WACE,gCACF,WACE,gCACF,WACE,uCACF,WACE,4CACF,WACE,gCACF,WACE,iCACF,WACE,iCACF,WACE,yCACF,WACE,4CACF,WACE,gDACF,WACE,qCACF,WACE,4CACF,WACE,qCACF,WACE,qCACF,WACE,qCACF,WACE,sCACF,WACE,wCACF,WACE,oCACF,WACE,iCACF,WACE,qCACF,WACE,oCACF,WACE,sCACF,WACE,yCACF,WACE,0CACF,WACE,6CACF,WACE,iCACF,WACE,uCACF,WACE,sCACF,WACE,gDACF,WACE,+BACF,WACE,iCACF,WACE,kCACF,WACE,oCACF,WACE,uCACF,WACE,gCACF,WACE,oCACF,WACE,+BACF,WACE,0CACF,WACE,oCACF,WACE,wCACF,WACE,qCACF,WACE,6BACF,WACE,qCACF,WACE,6BACF,WACE,kCACF,WACE,iCACF,WACE,iCACF,WACE,iCACF,WACE,iCACF,WACE,kCACF,WACE,uCACF,WACE,sCACF,WACE,sCACF,WACE,oCACF,WACE,oCACF,WACE,qCACF,WACE,4BACF,WACE,yCACF,WACE,0CACF,WACE,uCACF,WACE,sCACF,WACE,uCACF,WACE,uCACF,WACE,uCACF,WACE,qCACF,WACE,sCACF,WACE,iCACF,WACE,wCACF,WACE,gCACF,WACE,kCACF,WACE,kCACF,WACE,kCACF,WACE,4CACF,WACE,mCACF,WACE,yCACF,WACE,oCACF,WACE,uCACF,WACE,sCACF,WACE,0CACF,WACE,mCACF,WACE,gCACF,WACE,uCACF,WACE,mCACF,WACE,+BACF,WACE,6BACF,WACE,+BACF,WACE,+BACF,WACE,uCACF,WACE,uCACF,WACE,qCACF,WACE,wCACF,WACE,sCACF,WACE,uCACF,WACE,sCACF,WACE,wCACF,WACE,oCACF,WACE,iCACF,WACE,wCACF,WACE,6BACF,WACE,gDACF,WACE,oCACF,WACE,wCACF,WACE,gCACF,WACE,wCACF,WACE,4CACF,WACE,uCACF,WACE,mCACF,WACE,0CACF,WACE,uCACF,WACE,gCACF,WACE,qCACF,WACE,sCACF,WACE,mCACF,WACE,gCACF,WACE,gCACF,WACE,mCACF,WACE,+BACF,WACE,sCACF,WACE,mCACF,WACE,wCACF,WACE,wCACF,WACE,+CACF,WACE,uCACF,WACE,8CACF,WACE,uCACF,WACE,8CACF,WACE,yCACF,WACE,uCACF,WACE,2CACF,WACE,kDACF,WACE,uCACF,WACE,0CACF,WACE,iDACF,WACE,yCACF,WACE,2CACF,WACE,kDACF,WACE,wCACF,WACE,mCACF,WACE,4CACF,WACE,yCACF,WACE,kCACF,WACE,gCACF,WACE,iCACF,WACE,yCACF,WACE,yCACF,WACE,4BACF,WACE,mCACF,WACE,uCACF,WACE,uCACF,WACE,sCACF,WACE,uCACF,WACE,2CACF,WACE,2CACF,WACE,0CACF,WACE,wDACF,WACE,oCACF,WACE,qCACF,WACE,6BACF,WACE,yCACF,WACE,+BACF,WACE,mCACF,WACE,wCACF,WACE,4CACF,WACE,6BACF,WACE,iCACF,WACE,qCACF,WACE,oCACF,WACE,oCACF,WACE,kCACF,WACE,mCACF,WACE,qCACF,WACE,iCACF,WACE,qCACF,WACE,wCACF,WACE,iCACF,WACE,sCACF,WACE,6CACF,WACE,oCACF,WACE,+BACF,WACE,oCACF,WACE,uCACF,WACE,6BACF,WACE,kCACF,WACE,wCACF,WACE,gDACF,WACE,4CACF,WACE,kDACF,WACE,4CACF,WACE,4BACF,WACE,qCACF,WACE,4BACF,WACE,4BACF,WACE,qCACF,WACE,qCACF,WACE,qCACF,WACE,gCACF,WACE,wCACF,WACE,6BACF,WACE,4BACF,WACE,wCACF,WACE,uCACF,WACE,6BACF,WACE,wCACF,WACE,sCACF,WACE,sCACF,WACE,0CACF,WACE,kCACF,WACE,2CACF,WACE,iCACF,WACE,kCACF,WACE,4BACF,WACE,gCACF,WACE,8BACF,WACE,gCACF,WACE,sCACF,WACE,sCACF,WACE,sCACF,WACE,qCACF,WACE,uCACF,WACE,uCACF,WACE,0CACF,WACE,yCACF,WACE,4CACF,WACE,iCACF,WACE,8BACF,WACE,kCACF,WACE,4CACF,WACE,wCACF,WACE,uCACF,WACE,qCACF,WACE,oCACF,WACE,4CACF,WACE,qCACF,WACE,sCACF,WACE,qCACF,WACE,sCACF,WACE,6CACF,WACE,4CACF,WACE,oCACF,WACE,gDACF,WACE,4CACF,WACE,kCACF,WACE,8BACF,WACE,sCACF,WACE,kCACF,WACE,0CACF,WACE,6BACF,WACE,oCACF,WACE,mCACF,WACE,8BACF,WACE,wCACF,WACE,mCACF,WACE,mCACF,WACE,qCACF,WACE,mCACF,WACE,oCACF,WACE,+BACF,WACE,2CACF,WACE,oCACF,WACE,oCACF,WACE,iCACF,WACE,gCACF,WACE,oCACF,WACE,iCACF,WACE,yCACF,WACE,yCACF,WACE,uCACF,WACE,uCACF,WACE,wCACF,WACE,wCACF,WACE,sCACF,WACE,kCACF,WACE,sCACF,WACE,6BACF,WACE,gDACF,WACE,4CACF,WACE,iCACF,WACE,mCACF,WACE,gCACF,WACE,wCACF,WACE,qCACF,WACE,oCACF,WACE,iCACF,WACE,iCACF,WACE,wCACF,WACE,yCACF,WACE,4BACF,WACE,2CACF,WACE,uCACF,WACE,6BACF,WACE,iCACF,WACE,+BACF,WACE,8BACF,WACE,iCACF,WACE,kCACF,WACE,4CACF,WACE,kCACF,WACE,kCACF,WACE,2CACF,WACE,kCACF,WACE,sCACF,WACE,2CACF,WACE,0CACF,WACE,kCACF,WACE,qCACF,WACE,oCACF,WACE,+BACF,WACE,iCACF,WACE,iCACF,WACE,iCACF,WACE,iCACF,WACE,iCACF,WACE,iCACF,WACE,iCACF,WACE,iCACF,WACE,iCACF,WACE,sCACF,WACE,mCACF,WACE,uCACF,WACE,uCACF,WACE,4CACF,WACE,qCACF,WACE,sCACF,WACE,mCACF,WACE,oCACF,WACE,wCACF,WACE,wCACF,WACE,oCACF,WACE,0CACF,WACE,uCACF,WACE,qCACF,WACE,qCACF,WACE,oCACF,WACE,0CACF,WACE,qCACF,WACE,yCACF,WACE,mCACF,WACE,kCACF,WACE,mCACF,WACE,mCACF,WACE,+BACF,WACE,uCACF,WACE,6BACF,WACE,oCACF,WACE,8BACF,WACE,8BACF,WACE,mCACF,WACE,kCACF,WACE,iCACF,WACE,uCACF,WACE,sCACF,WACE,iCACF,WACE,+BACF,WACE,qCACF,WACE,oCACF,WACE,uCACF,WACE,6BACF,WACE,4CACF,WACE,wCACF,WACE,qCACF,WACE,sCACF,WACE,8BACF,WACE,oCACF,WACE,qCACF,WACE,gCACF,WACE,iCACF,WACE,8BACF,WACE,+BACF,WACE,oCACF,WACE,sCACF,WACE,mCACF,WACE,oCACF,WACE,sCACF,WACE,uCACF,WACE,mCACF,WACE,yCACF,WACE,sCACF,WACE,0CACF,WACE,kCACF,WACE,+BACF,WACE,kCACF,WACE,mCACF,WACE,4CACF,WACE,6CACF,WACE,0CACF,WACE,2CACF,WACE,oCACF,WACE,qCACF,WACE,0CACF,WACE,2CACF,WACE,0CACF,WACE,+CACF,WACE,+CACF,WACE,sCACF,WACE,4CACF,WACE,6CACF,WACE,6CACF,WACE,iDACF,WACE,wCACF,WACE,qCACF,WACE,qCACF,WACE,sCACF,WACE,oCACF,WACE,6CACF,WACE,oDACF,WACE,oDACF,WACE,yCACF,WACE,0CACF,WACE,6BACF,WACE,8BACF,WACE,gCACF,WACE,mCACF,WACE,mCACF,WACE,kCACF,WACE,yCACF,WACE,mCACF,WACE,uCACF,WACE,0CACF,WACE,mCACF,WACE,mCACF,WACE,wCACF,WACE,kCACF,WACE,qCACF,WACE,oCACF,WACE,gCACF,WACE,8BACF,WACE,+BACF,WACE,kCACF,WACE,8BACF,WACE,0CACF,WACE,gCACF,WACE,gCACF,WACE,4BACF,WACE,gCACF,WACE,6BACF,WACE,6BACF,WACE,6BACF,WACE,oCACF,WACE,gCACF,WACE,iCACF,WACE,kCACF,WACE,kCACF,WACE,sCACF,WACE,gCACF,WACE,8BACF,WACE,iCACF,WACE,gCACF,WACE,8BACF,WACE,mCACF,WACE,8BACF,WACE,iCACF,WACE,iCACF,WACE,yCACF,WACE,iCACF,WACE,gCACF,WACE,kCACF,WACE,8BACF,WACE,kCACF,WACE,kCACF,WACE,qCACF,WACE,mCACF,WACE,+BACF,WACE,qCACF,WACE,0CACF,WACE,6BACF,WACE,kCACF,WACE,iCACF,WACE,iCACF,WACE,2BACF,WACE,iCACF,WACE,wCACF,WACE,4CACF,WACE,gCACF,WACE,uCACF,WACE,+BACF,WACE,sCACF,WACE,iCACF,WACE,mCACF,WACE,iCACF,WACE,mCACF,WACE,2CACF,WACE,gCACF,WACE,oCACF,WACE,oCACF,WACE,gCACF,WACE,0CACF,WACE,gCACF,WACE,yCACF,WACE,qCACF,WACE,kCACF,WACE,+BACF,WACE,6BACF,WACE,oCACF,WACE,qCACF,WACE,6BACF,WACE,gCACF,WACE,mCACF,WACE,oCACF,WACE,qCACF,WACE,kCACF,WACE,sCACF,WACE,sCACF,WACE,yCACF,WACE,+BACF,WACE,gCACF,WACE,oCACF,WACE,2CACF,WACE,6BACF,WACE,4BACF,WACE,gCACF,WACE,wCACF,WACE,6BACF,WACE,oCACF,WACE,iCACF,WACE,kCACF,WACE,4CACF,WACE,kCACF,WACE,8CACF,WACE,wCACF,WACE,yCACF,WACE,gCACF,WACE,8BACF,WACE,oCACF,WACE,yCACF,WACE,2CACF,WACE,wCACF,WACE,uCACF,WACE,sCACF,WACE,8BACF,WACE,qCACF,WACE,kCACF,WACE,mCACF,WACE,oCACF,WACE,6BACF,WACE,6BACF,WACE,8BACF,WACE,4BACF,WACE,6BACF,WACE,oCACF,WACE,iCACF,WACE,8BACF,WACE,2CACF,WACE,4CACF,WACE,qCACF,WACE,2CACF,WACE,wCACF,WACE,sCACF,WACE,0CACF,WACE,8BACF,WACE,0CACF,WACE,gDACF,WACE,6BACF,WACE,qCACF,WACE,8BACF,WACE,qCACF,WACE,8CACF,WACE,uCACF,WACE,0CACF,WACE,wCACF,WACE,0CACF,WACE,oCACF,WACE,0CACF,WACE,qCACF,WACE,iCACF,WACE,wCACF,WACE,uCACF,WACE,iDACF,WACE,kCACF,WACE,yCACF,WACE,kCACF,WACE,oCACF,WACE,sCACF,WACE,0CACF,WACE,yCACF,WACE,kCACF,WACE,6BACF,WACE,4BACF,WACE,mCACF,WACE,kCACF,WACE,mCACF,WACE,kCACF,WACE,mCACF,WACE,iCACF,WACE,qCACF,WACE,4BACF,WACE,gCACF,WACE,iCACF,WACE,qCACF,WACE,4CACF,WACE,4CACF,WACE,6CACF,WACE,0CACF,WACE,2CACF,WACE,0CACF,WACE,yCACF,WACE,6CACF,WACE,yCACF,WACE,6CACF,WACE,mDACF,WACE,mDACF,WACE,oDACF,WACE,iDACF,WACE,sCACF,WACE,wCACF,WACE,4CACF,WACE,wCACF,WACE,qCACF,WACE,uCACF,WACE,iCACF,WACE,gCACF,WACE,oCACF,WACE,8BACF,WACE,wCACF,WACE,gDACF,WACE,kCACF,WACE,sCACF,WACE,4BACF,WACE,kCACF,WACE,kCACF,WACE,iCACF,WACE,+BACF,WACE,0CACF,WACE,mCACF,WACE,uCACF,WACE,kCACF,WACE,+BACF,WACE,+BACF,WACE,qCACF,WACE,oCACF,WACE,iCACF,WACE,oCACF,WACE,2CACF,WACE,sCACF,WACE,6BACF,WACE,kCACF,WACE,oCACF,WACE,0CACF,WACE,sCACF,WACE,sCACF,WACE,8BACF,WACE,mCACF,WACE,kCACF,WACE,yCACF,WACE,0CACF,WACE,kCACF,WACE,mCACF,WACE,oCACF,WACE,qCACF,WACE,6BACF,WACE,iCACF,WACE,sCACF,WACE,+BACF,WACE,6BACF,WACE,iCACF,WACE,kCACF,WACE,gCACF,WACE,+BACF,WACE,uCACF,WACE,sCACF,WACE,kCACF,WACE,yCACF,WACE,kCACF,WACE,mCACF,WACE,uCACF,WACE,gDACF,WACE,qCACF,WACE,oCACF,WACE,8CACF,WACE,sCACF,WACE,0CACF,WACE,4CACF,WACE,uCACF,WACE,oCACF,WACE,8CACF,WACE,sCACF,WACE,mCACF,WACE,qCACF,WACE,oCACF,WACE,sCACF,WACE,uCACF,WACE,oCACF,WACE,oCACF,WACE,mCACF,WACE,qCACF,WACE,0CACF,WACE,yCACF,WACE,wCACF,WACE,yCACF,WACE,kCACF,WACE,uCACF,WACE,mCACF,WACE,sCACF,WACE,0CACF,WACE,yCACF,WACE,qCACF,WACE,oCACF,WACE,qCACF,WACE,2CACF,WACE,6BACF,WACE,mCACF,WACE,kCACF,WACE,qCACF,WACE,oCACF,WACE,mCACF,WACE,8BACF,WACE,iCACF,WACE,+BACF,WACE,8BACF,WACE,gCACF,WACE,gCACF,WACE,gCACF,WACE,gCACF,WACE,kCACF,WACE,kCACF,WACE,6BACF,WACE,8BACF,WACE,qCACF,WACE,gCACF,WACE,uCACF,WACE,4CACF,WACE,gCACF,WACE,qCACF,WACE,+BACF,WACE,6BACF,WACE,kCACF,WACE,qCACF,WACE,6BACF,WACE,4BACF,WACE,wCACF,WACE,uCACF,WACE,sCACF,WACE,4BACF,WACE,uCACF,WACE,iCACF,WACE,+BACF,WACE,uCACF,WACE,uCACF,WACE,yCACF,WACE,wCACF,WACE,0CACF,WACE,6CACF,WACE,mCACF,WACE,2CACF,WACE,8BACF,WACE,iCACF,WACE,4CACF,WACE,2CACF,WACE,kCACF,WACE,4CACF,WACE,yCACF,WACE,mCACF,WACE,0CACF,WACE,qCACF,WACE,+BACF,WACE,6BACF,WACE,kCACF,WACE,kCACF,WACE,8BACF,WACE,mCACF,WACE,gCACF,WACE,kCACF,WACE,0CACF,WACE,4BACF,WACE,yCACF,WACE,wCACF,WACE,iCACF,WACE,gCACF,WACE,kCACF,WACE,sCACF,WACE,iCACF,WACE,oCACF,WACE,+CACF,WACE,0CACF,WACE,4BACF,WACE,wCACF,WACE,mCACF,WACE,4CACF,WACE,uCACF,WACE,6BACF,WACE,qCACF,WACE,kCACF,WACE,0CACF,WACE,qCACF,WACE,mCACF,WACE,uCACF,WACE,qCACF,WACE,uCACF,WACE,wCACF,WACE,8BACF,WACE,kCACF,WACE,wCACF,WACE,gCACF,WACE,sCACF,WACE,uCACF,WACE,0CACF,WACE,6BACF,WACE,iCACF,WACE,8BACF,WACE,6BACF,WACE,mCACF,WACE,kCACF,WACE,kCACF,WACE,+BACF,WACE,2CACF,WACE,0CACF,WACE,yCACF,WACE,4CACF,WACE,6CACF,WACE,mCACF,WACE,8BACF,WACE,kCACF,WACE,sCACF,WACE,gCACF,WACE,8BACF,WACE,uCACF,WACE,qCACF,WACE,+BACF,WACE,2BACF,WACE,wCACF,WACE,sCACF,WACE,yCACF,WACE,+BACF,WACE,mCACF,WACE,kCACF,WACE,oCACF,WACE,uCACF,WACE,yCACF,WACE,yCACF,WACE,oCACF,WACE,4BACF,WACE,+BACF,WACE,sCACF,WACE,wCACF,WACE,sCACF,WACE,mCACF,WACE,gCACF,WACE,yCACF,WACE,qCACF,WACE,mCACF,WACE,6CACF,WACE,qCACF,WACE,sCACF,WACE,uCACF,WACE,qCACF,WACE,qCACF,WACE,2CACF,WACE,2CACF,WACE,2CACF,WACE,kCACF,WACE,qCACF,WACE,kCACF,WACE,kCACF,WACE,kCACF,WACE,4BACF,WACE,sCACF,WACE,kCACF,WACE,mCACF,WACE,yCACF,WACE,oCACF,WACE,oCACF,WACE,yCACF,WACE,oCACF,WACE,gCACF,WACE,iCACF,WACE,kCACF,WACE,sCACF,WACE,oDACF,WACE,iCACF,WACE,gCACF,WACE,mCACF,WACE,iCACF,WACE,wCACF,WACE,wCACF,WACE,uCACF,WACE,+BACF,WACE,oCACF,WACE,oCACF,WACE,oCACF,WACE,0CACF,WACE,uCACF,WACE,8BACF,WACE,mCACF,WACE,mCACF,WACE,uCACF,WACE,uCACF,WACE,4CACF,WACE,oCACF,WACE,6BACF,WACE,iCACF,WACE,iCACF,WACE,8BACF,WACE,yCACF,WACE,+CACF,WACE,sCACF,WACE,6CACF,WACE,2CACF,WACE,0CACF,WACE,yCACF,WACE,6CACF,WACE,sCACF,WACE,oCACF,WACE,gCACF,WACE,qCACF,WACE,oCACF,WACE,sCACF,WACE,mCACF,WACE,2CACF,WACE,uCACF,WACE,0CACF,WACE,gCACF,WACE,wCACF,WACE,qCACF,WACE,oCACF,WACE,wCACF,WACE,kCACF,WACE,qCACF,WACE,gCACF,WACE,iCACF,WACE,+BACF,WACE,sCACF,WACE,sCACF,WACE,+BACF,WACE,sCACF,WACE,+BACF,WACE,gCACF,WACE,8BACF,WACE,iCACF,WACE,6BACF,WACE,gCACF,WACE,iCACF,WACE,qCACF,WACE,iCACF,WACE,0CACF,WACE,yCACF,WACE,4CACF,WACE,mDACF,WACE,6CACF,WACE,oDACF,WACE,0CACF,WACE,iDACF,WACE,4CACF,WACE,mDACF,WACE,oCACF,WACE,6BACF,WACE,mCACF,WACE,iCACF,WACE,gCACF,WACE,8BACF,WACE,qCACF,WACE,4CACF,WACE,6CACF,WACE,2CACF,WACE,gCACF,WACE,iCACF,WACE,+BACF,WACE,mCACF,WACE,gCACF,WACE,wCACF,WACE,iCACF,WACE,+BACF,WACE,mCACF,WACE,uCACF,WACE,gCACF,WACE,wCACF,WACE,yCACF,WACE,8CACF,WACE,0CACF,WACE,yCACF,WACE,gDACF,WACE,sCACF,WACE,mCACF,WACE,uCACF,WACE,uCACF,WACE,+BACF,WACE,mCACF,WACE,uCACF,WACE,yCACF,WACE,4CACF,WACE,mCACF,WACE,uCACF,WACE,mCACF,WACE,0CACF,WACE,sCACF,WACE,4CACF,WACE,sCACF,WACE,wCACF,WACE,uCACF,WACE,qCACF,WACE,4CACF,WACE,6BACF,WACE,iCACF,WACE,8BACF,WACE,sCACF,WACE,gDACF,WACE,uCACF,WACE,uCACF,WACE,sCACF,WACE,wCACF,WACE,sCACF,WACE,qCACF,WACE,qCACF,WACE,qCACF,WACE,qCACF,WACE,kCACF,WACE,wCACF,WACE,uCACF,WACE,sCACF,WACE,uCACF,WACE,wCACF,WACE,8BACF,WACE,oCACF,WACE,qCACF,WACE,0CACF,WACE,2CACF,WACE,qCACF,WACE,sCACF,WACE,iDACF,WACE,gDACF,WACE,gDACF,WACE,4BACF,WACE,8BACF,WACE,kCACF,WACE,uCACF,WACE,2CACF,WACE,+CACF,WACE,kCACF,WACE,0CACF,WACE,2CACF,WACE,4BACF,WACE,iCACF,WACE,gCACF,WACE,mCACF,WACE,8BACF,WACE,0CACF,WACE,4BACF,WACE,8BACF,WACE,mCACF,WACE,mCACF,WACE,oCACF,WACE,yCACF,WACE,2CACF,WACE,4CACF,WACE,sCACF,WACE,sCACF,WACE,oCACF,WACE,qCACF,WACE,2CACF,WACE,kDACF,WACE,4CACF,WACE,sCACF,WACE,wCACF,WACE,iCACF,WACE,iCACF,WACE,iCACF,WACE,sCACF,WACE,+BACF,WACE,6BACF,WACE,iCACF,WACE,gCACF,WACE,6BACF,WACE,0CACF,WACE,iCACF,WACE,iCACF,WACE,8BACF,WACE,oCACF,WACE,kCACF,WACE,2CACF,WACE,gDACF,WACE,uCACF,WACE,uCACF,WACE,gCACF,WACE,qCACF,WACE,oCACF,WACE,8BACF,WACE,uCACF,WACE,sCACF,WACE,oCACF,WACE,6CACF,WACE,mDACF,WACE,gCACF,WACE,qCACF,WACE,mCACF,WACE,uCACF,WACE,+BACF,WACE,mCACF,WACE,gCACF,WACE,+CACF,WACE,oCACF,WACE,iCACF,WACE,gCACF,WACE,kCACF,WACE,wCACF,WACE,sCACF,WACE,oCACF,WACE,wCACF,WACE,sCACF,WACE,8BACF,WACE,oCACF,WACE,wCACF,WACE,8CACF,WACE,4CACF,WACE,mCACF,WACE,6BACF,WACE,8BACF,WACE,qCACF,WACE,8BACF,WACE,8BACF,WACE,6CACF,WACE,yCACF,WACE,wCACF,WACE,+CACF,WACE,sCACF,WACE,qCACF,WACE,kCACF,WACE,mCACF,WACE,oCACF,WACE,gCACF,WACE,+BACF,WACE,kCACF,WACE,0CACF,WACE,gCACF,WACE,qCACF,WACE,sCACF,WACE,kCACF,WACE,0CACF,WACE,kCACF,WACE,kCACF,WACE,+BACF,WACE,+BACF,WACE,6BACF,WACE,wCACF,WACE,gCACF,WACE,oCACF,WACE,+BACF,WACE,sCACF,WACE,8CACF,WACE,oCACF,WACE,0CACF,WACE,yCACF,WACE,uCACF,WACE,oCACF,WACE,6CACF,WACE,gCACF,WACE,oCACF,WACE,+BACF,WACE,kCACF,WACE,mCACF,WACE,sCACF,WACE,+BACF,WACE,kCACF,WACE,kCACF,WACE,iCACF,WACE,6CACF,WACE,8BACF,WACE,kCACF,WACE,+BACF,WACE,6CACF,WACE,mCACF,WACE,uCACF,WACE,qCACF,WACE,sCACF,WACE,iCACF,WACE,oCACF,WACE,mCACF,WACE,wCACF,WACE,gCACF,WACE,2CACF,WACE,qCACF,WACE,gCACF,WACE,kCACF,WACE,oCACF,WACE,+BACF,WACE,sCACF,WACE,sCACF,WACE,6CACF,WACE,uCACF,WACE,gCACF,WACE,6BACF,WACE,yCACF,WACE,qCACF,WACE,8CACF,WACE,6CACF,WACE,oCACF,WACE,qCACF,WACE,wCACF,WACE,yCACF,WACE,uCACF,WACE,8BACF,WACE,+BACF,WACE,+BACF,WACE,iCACF,WACE,6BACF,WACE,4BACF,WACE,6BACF,WACE,oCACF,WACE,mCACF,WACE,4CACF,WACE,kCACF,WACE,qCACF,WACE,uCACF,WACE,gCACF,WACE,kCACF,WACE,kCACF,WACE,sCACF,WACE,6BACF,WACE,iCACF,WACE,gCACF,WACE,qCACF,WACE,gCACF,WACE,8BACF,WACE,gCACF,WACE,qCACF,WACE,iCACF,WACE,sCACF,WACE,+BACF,WACE,+BACF,WACE,gCACF,WACE,8BACF,WACE,mCACF,WACE,8CACF,WACE,6CACF,WACE,6CACF,WACE,wCACF,WACE,4CACF,WACE,8CACF,WACE,qCACF,WACE,mCACF,WACE,2CACF,WACE,qCACF,WACE,2BACF,WACE,gCACF,WACE,sCACF,WACE,mCACF,WACE,+BACF,WACE,mCACF,WACE,iCACF,WACE,wCACF,WACE,6CACF,WACE,gDACF,WACE,gCACF,WACE,mCACF,WACE,yCACF,WACE,6BACF,WACE,6BACF,WACE,yCACF,WACE,4CACF,WACE,uCACF,WACE,oCACF,WACE,wCACF,WACE,sCACF,WACE,gCACF,WACE,oCACF,WACE,+CACF,WACE,0CACF,WACE,4CACF,WACE,gDACF,WACE,oDACF,WACE,iDACF,WACE,iCACF,WACE,iCACF,WACE,+CACF,WACE,8CACF,WACE,gDACF,WACE,2CACF,WACE,4CACF,WACE,sCACF,WACE,yCACF,WACE,0CACF,WACE,+CACF,WACE,iDACF,WACE,iDACF,WACE,4CACF,WACE,8CACF,WACE,0CACF,WACE,uCACF,WACE,uCACF,WACE,wCACF,WACE,yCACF,WACE,iDACF,WACE,uCACF,WACE,oCACF,WACE,8BACF,WACE,2CACF,WACE,uCACF,WACE,+BACF,WACE,oCACF,WACE,6BACF,WACE,+BACF,WACE,iCACF,WACE,gCACF,WACE,qCACF,WACE,wCACF,WACE,sCACF,WACE,+CACF,WACE,mCACF,WACE,iCACF,WACE,mCACF,WACE,+BACF,WACE,gCACF,WACE,mCACF,WACE,sCACF,WACE,6BACF,WACE,sCACF,WACE,8CACF,WACE,8CACF,WACE,4CACF,WACE,kDACF,WACE,kDACF,WACE,oEACF,WACE,oEACF,WACE,+CACF,WACE,+CACF,WACE,6CACF,WACE,4CACF,WACE,0CACF,WACE,0CACF,WACE,+CACF,WACE,wCACF,WACE,4DACF,WACE,wCACF,WACE,oDACF,WACE,sEACF,WACE,mDACF,WACE,iCACF,WACE,iCACF,WACE,uCACF,WACE,0CACF,WACE,mCACF,WACE,4BACF,WACE,sCACF,WACE,kCACF,WACE,sCACF,WACE,iCACF,WACE,kCACF,WACE,0CACF,WACE,qCACF,WACE,sCACF,WACE,qCACF,WACE,kCACF,WACE,mCACF,WACE,mCACF,WACE,sCACF,WACE,4BACF,WACE,mCACF,WACE,iCACF,WACE,uCACF,WACE,+BACF,WACE,qCACF,WACE,gCACF,WACE,mCACF,WACE,oCACF,WACE,6BACF,WACE,wCACF,WACE,oCACF,WACE,6BACF,WACE,sCACF,WACE,4BACF,WACE,qCACF,WACE,+BACF,WACE,8BACF,WACE,sCACF,WACE,mCACF,WACE,mCACF,WACE,4BACF,WACE,kCACF,WACE,wCACF,WACE,sCACF,WACE,0CACF,WACE,yCACF,WACE,gCACF,WACE,sCACF,WACE,sCACF,WACE,0CACF,WACE,sCACF,WACE,8BACF,WACE,mCACF,WACE,oCACF,WACE,8BACF,WACE,+BACF,WACE,mCACF,WACE,wCACF,WACE,0CACF,WACE,uCACF,WACE,uCACF,WACE,wCACF,WACE,oCACF,WACE,0CACF,WACE,wCACF,WACE,sCACF,WACE,uCACF,WACE,4CACF,WACE,mCACF,WACE,2CACF,WACE,qCACF,WACE,qCACF,WACE,sCACF,WACE,sCACF,WACE,0CACF,WACE,+BACF,WACE,oCACF,WACE,mCACF,WACE,0CACF,WACE,2CACF,WACE,gCACF,WACE,+BACF,WACE,6BACF,WACE,oCACF,WACE,8CACF,WACE,kCACF,WACE,qCACF,WACE,uCACF,WACE,kCACF,WACE,8BACF,WACE,8BACF,WACE,+CACF,WACE,8CACF,WACE,+CACF,WACE,8CACF,WACE,sCACF,WACE,6BACF,WACE,oCACF,WACE,0CACF,WACE,gCACF,WACE,8BACF,WACE,6CACF,WACE,mCACF,WACE,8BACF,WACE,iCACF,WACE,mCACF,WACE,+BACF,WACE,mCACF,WACE,wCACF,WACE,iCACF,WACE,8BACF,WACE,gDACF,WACE,iDACF,WACE,gCACF,WACE,kCACF,WACE,sCACF,WACE,kCACF,WACE,sCACF,WACE,+BACF,WACE,kCACF,WACE,8BACF,WACE,sCACF,WACE,oCACF,WACE,+CACF,WACE,2CACF,WACE,gCACF,WACE,sCACF,WACE,gCACF,WACE,uCACF,WACE,mCACF,WACE,mCACF,WACE,+CACF,WACE,kCACF,WACE,yCACF,WACE,6CACF,WACE,8BACF,WACE,mCACF,WACE,uCACF,WACE,mCACF,WACE,uCACF,WACE,oCACF,WACE,wCACF,WACE,iCACF,WACE,qCACF,WACE,uCACF,WACE,+CACF,WACE,mDACF,WACE,uCACF,WACE,sCACF,WACE,oCACF,WACE,qCACF,WACE,qCACF,WACE,kCACF,WACE,6BACF,WACE,iCACF,WACE,sCACF,WACE,kCACF,WACE,qCACF,WACE,+CACF,WACE,oDACF,WACE,uDACF,WACE,sCACF,WACE,0CACF,WACE,yCACF,WACE,4BACF,WACE,uCACF,WACE,kCACF,WACE,oCACF,WACE,yCACF,WACE,mCACF,WACE,mCACF,WACE,+BACF,WACE,uCACF,WACE,mCACF,WACE,4BACF,WACE,kCACF,WACE,uCACF,WACE,qCACF,WACE,8BACF,WACE,6BACF,WACE,iCACF,WACE,mCACF,WACE,iCACF,WACE,wCACF,WACE,qCACF,WACE,iCACF,WACE,gCACF,WACE,sCACF,WACE,oCACF,WACE,oCACF,WACE,sCACF,WACE,uCACF,WACE,6CACF,WACE,gDACF,WACE,8CACF,WACE,2CACF,WACE,2CACF,WACE,qCACF,WACE,gCACF,WACE,gCACF,WACE,uCACF,WACE,iCACF,WACE,mCACF,WACE,wCACF,WACE,mCACF,WACE,uCACF,WACE,2CACF,WACE,iCACF,WACE,qCACF,WACE,yCACF,WACE,uCACF,WACE,qCACF,WACE,+BACF,WACE,sCACF,WACE,kCACF,WACE,iCACF,WACE,8BACF,WACE,iCACF,WACE,wCACF,WACE,gCACF,WACE,uCACF,WACE,kCACF,WACE,yCACF,WACE,oCACF,WACE,8BACF,WACE,4BACF,WACE,8BACF,WACE,mCACF,WACE,kCACF,WACE,8BACF,WACE,6BACF,WACE,iCACF,WACE,8BACF,WACE,gCACF,WACE,kCACF,WACE,6BACF,WACE,6BACF,WACE,sCACF,WACE,gCACF,WACE,8BACF,WACE,6BACF,WACE,mCACF,WACE,kDACF,WACE,kCACF,WACE,oCACF,WACE,0CACF,WACE,kCACF,WACE,uCACF,WACE,sCACF,WACE,sCACF,WACE,yCACF,WACE,oCACF,WACE,oCACF,WACE,qCACF,WACE,4BACF,WACE,gCACF,WACE,4BACF,WACE,6BACF,WACE,iCACF,WACE,kCACF,WACE,mCACF,WACE,wCACF,WACE,yCACF,WACE,yCACF,WACE,0CACF,WACE,kCACF,WACE,sCACF,WACE,2BACF,WACE,+BACF,WACE,oCACF,WACE,sCACF,WACE,oCACF,WACE,qCACF,WACE,iCACF,WACE,kCACF,WACE,6BACF,WACE,oCACF,WACE,oCACF,WACE,oCACF,WACE,oCACF,WACE,iCACF,WACE,+BACF,WACE,wCACF,WACE,gCACF,WACE,+BACF,WACE,oCACF,WACE,4BACF,WACE,gCACF,WACE,iCACF,WACE,kCACF,WACE,qCACF,WACE,iCACF,WACE,sCACF,WACE,8CACF,WACE,8CACF,WACE,2CACF,WACE,4CACF,WACE,wCACF,WACE,+CACF,WACE,uCACF,WACE,kCACF,WACE,mCACF,WACE,0CACF,WACE,2CACF,WACE,yCACF,WACE,mCACF,WACE,oCACF,WACE,sCACF,WACE,uCACF,WACE,qCACF,WACE,iCACF,WACE,qCACF,WACE,wCACF,WACE,4CACF,WACE,oCACF,WACE,mCACF,WACE,sCACF,WACE,oCACF,WACE,yCACF,WACE,mCACF,WACE,uCACF,WACE,qCACF,WACE,yCACF,WACE,kCACF,WACE,iCACF,WACE,sCACF,WACE,mCACF,WACE,oCACF,WACE,kCACF,WACE,oCACF,WACE,mCACF,WACE,qCACF,WACE,oCACF,WACE,sCACF,WACE,kCACF,WACE,iCACF,WACE,8BACF,WACE,mCACF,WACE,uCACF,WACE,mCACF,WACE,uCACF,WACE,kCACF,WACE,gCACF,WACE,oCACF,WACE,wCACF,WACE,oCACF,WACE,mCACF,WACE,kCACF,WACE,2CACF,WACE,gCACF,WACE,oCACF,WACE,iCACF,WACE,+BACF,WACE,+BACF,WACE,wCACF,WACE,0CACF,WACE,sCACF,WACE,kCACF,WACE,kCACF,WACE,gCACF,WACE,sCACF,WACE,6BACF,WACE,8BACF,WACE,oCACF,WACE,kCACF,WACE,8BACF,WACE,qCACF,WACE,mCACF,WACE,wCACF,WACE,8BACF,WACE,oCACF,WACE,gCACF,WACE,kCACF,WACE,wCACF,WACE,sCACF,WACE,iCACF,WACE,iCACF,WACE,sCACF,WACE,oCACF,WACE,2BACF,WACE,4BACF,WACE,kCACF,WACE,sCACF,WACE,oCACF,WACE,gCACF,WACE,+BACF,WACE,gCACF,WACE,6BACF,WACE,iCACF,WACE,iCACF,WACE,0CACF,WACE,sCACF,WACE,gCACF,WACE,mCACF,WACE,qCACF,WACE,mCACF,WACE,6BACF,WACE,mCACF,WACE,mCACF,WACE,qCACF,WACE,uCACF,WACE,qCACF,WACE,kCACF,WACE,kCACF,WACE,iCACF,WACE,sCACF,WACE,6CACF,WACE,uCACF,WACE,6CACF,WACE,qDACF,WACE,2CACF,WACE,mCACF,WACE,+BACF,WACE,iCACF,WACE,8BACF,WACE,qCACF,WACE,kCACF,WACE,6BACF,WACE,qCACF,WACE,iCACF,WACE,qCACF,WACE,0CACF,WACE,mCACF,WACE,0CACF,WACE,2CACF,WACE,kCACF,WACE,uCACF,WACE,gCACF,WACE,6BACF,WACE,6CACF,WACE,gCACF,WACE,oCACF,WACE,iCACF,WACE,qCACF,G;ACh0IF;;CAAA,CAIA,WACE,iBACA,gBACA,kBACA,kCACA,mHAGF,WACE,iBACA,gBACA,kBACA,kCACA,mHAGF,WACE,iBACA,gBACA,kBACA,kCACA,mHAGF,WACE,iBACA,gBACA,kBACA,kCACA,mHAGF,WACE,iBACA,gBACA,kBACA,kCACA,mHAGF,WACE,iBACA,gBACA,kBACA,kCACA,qHAGF,WACE,iBACA,gBACA,kBACA,kCACA,qHAGF,WACE,iBACA,gBACA,kBACA,kCACA,qHAGF,WACE,0BACA,gBACA,kBACA,kCACA,qHAGF,WACE,0BACA,gBACA,kBACA,kCACA,qHAGF,WACE,iBACA,gBACA,kBACA,kCACA,qHAGF,WACE,iBACA,gBACA,kBACA,kCACA,qHAGF,WACE,iBACA,gBACA,kBACA,kCACA,qHAGF,WACE,iBACA,gBACA,kBACA,kCACA,qHAGF,WACE,iBACA,gBACA,kBACA,kCACA,qHAGF,WACE,iBACA,gBACA,kBACA,kCACA,qHAGF,WACE,iBACA,gBACA,kBACA,kCACA,I;ACxIF,qCACA,qCACA,qCACA,qCAGA,8CACA,0DAGA,oCACA,gE;ACZA,w1B;ACAA,iBCAA,UACE,sBACA,CDFF,YCAA,UACE,sBACA,cAGF,YACE,OAGF,cACE,WACA,SACA,UACA,UAGF,gCAGE,yBACA,YAGF,UAGE,GAGF,UACE,iBACA,WAEA,oBACE,iBAGF,oBAEE,eAIJ,QACE,UACA,SACA,4HAGF,qBAME,iBACA,eACA,WACA,eAGF,OACE,uBACE,CADF,oBACE,CADF,eACE,gBACA,+EACA,eAKF,oBACE,kBACA,eAGF,aACE,gBAIJ,oBACE,iBACA,WACA,OAGF,iBACE,WAGF,kBACE,gCAGF,cAEE,sBACA,WACA,iBACA,qBACA,sBACA,uFAGF,qBAIE,WACA,wBACA,cAGF,WACE,WAGF,UACE,WACA,UACA,sBACA,cACA,QAGF,SACE,SACA,WAEA,eACE,SACA,UACA,QAIJ,cACE,MACA,WACA,OACA,iBACA,sBACA,kBACA,YACA,4CACA,WACA,aAEA,aACE,0BACA,WACA,kBACA,yBACA,qBACA,mBACA,iCACA,wBACA,qCAEA,qBAEE,WACA,wBAIJ,UACE,QACA,SACA,kBACA,gCACA,wBACA,QACA,QACA,iBACA,sBAGF,cACE,WACA,WACA,gCAEA,eACE,kBACA,QACA,OAKN,gBACE,kBACA,WACA,iBACA,mBACA,OAGF,SACE,qBACA,WACA,qBACA,UAEA,cACE,eACA,aAEA,gBACE,SAIJ,iBACE,sBACA,WAGF,uBACE,kBAEA,cACE,eAKN,WACE,gBACA,mBACA,WACA,WAGF,UACE,qBACA,qBACA,qBAEA,mEACE,qBAGF,mEACE,kBAIJ,cACE,wBACA,aACA,SACA,OACA,WACA,WACA,UChQF,cACE,gBACA,QAGF,gBACE,kBACA,SACA,UACA,WACA,eACA,kBACA,WACA,UAEA,UACE,mBACA,eAIJ,mBACE,iBAGF,UACE,eACA,kBAGF,cACE,kBACA,UACA,SACA,2CAGF,oBAEE,aACA,iBACA,gCACA,kBACA,eACA,gBACA,uBACA,yCAGF,oBAEE,mBACA,WACA,oBAGF,eACE,wBAGF,iBACE,2BAGF,UAEE,kBACA,mBACA,eACA,sBAGF,iBACE,SACA,QAGF,qBACE,sBACA,oCACA,qBACA,UACA,oBACA,mBACA,gBACA,kBACA,gBACA,oBACA,aACA,oBAEA,UACE,oBACA,CADA,gBACA,YACA,gBAGF,UACE,QACA,SACA,gCACA,yBACA,kBACA,YACA,WACA,YACA,wBACA,eAGF,UACE,kBACA,WACA,WACA,SACA,OACA,sBACA,wBACA,cAGF,0BACE,qBAEA,WACE,sBAGF,YACE,mBAGF,UACE,qBAGF,QACE,WAIJ,mBACE,gBACA,gBACA,gBACA,eAGF,YACE,UAGF,aACE,qBACA,WACA,qBACA,wBACA,UAGF,UACE,eACA,gBACA,oBACA,2BAGF,wBACE,eAGF,iBACE,aACA,OACA,gBACA,WACA,WACA,mBACA,iBACA,wBACA,iBAEA,UACE,qBACA,cACA,aACA,uBAEA,UACE,kBAIJ,oBACE,gBACA,8BAGF,UACE,eACA,6BACA,uBACA,gBACA,mBACA,eACA,iBACA,2BAIJ,iBACE,UACA,UACA,WACA,cACA,eACA,8BAEA,0BACE,0BACA,gCACA,0BACA,WACA,eACA,eACA,gBACA,uBACA,mBACA,gCAEA,UACE,wBAMR,aACE,UAGF,mBACE,iBACA,YAEA,oBACE,mBACA,sBACA,UACA,iBACA,mBAIJ,gBACE,aAGF,eACE,kBACA,WACA,oBACA,qBAIA,UACE,qBACA,qDAEA,yBAEE,qBAIJ,oBACE,iBACA,mEAGF,YAEE,4BAGF,WACE,gBACA,yBACA,qBACA,iBACA,WACA,sBACA,gBAIJ,oBACE,iCAGF,cACE,eAGF,YAEE,UCnTF,SACE,kBACA,mBACA,gBAEA,iBACE,YAGF,iBACE,aAGF,eACE,oBAGF,YACE,qCAGF,mBAGE,YAIJ,qBACE,sBACA,YACA,SACA,UAGF,cACE,UACA,WACA,gBACA,kBAGF,iBACE,qBAEA,oBACE,gBACA,oBAGF,qBACE,uBACA,WACA,qBACA,mDAEA,qBAEE,kBAKN,cACE,kBAGF,WACE,SAGF,oBACE,eACA,cACA,iBAGF,iBACE,SAGF,iBACE,WACA,YAGF,qBACE,WACA,kBACA,oBAEA,iBACE,QACA,eAKF,kBACE,yDAGF,qBAEE,WACA,qBACA,cAGF,oBACE,uCAEA,yBAEE,UAKN,2CACE,UAGF,cACE,UACA,YACA,MACA,QACA,sBACA,4BACA,2BACA,WACA,gBACA,6BAEA,UACE,gBAIJ,cACE,UACA,YACA,MACA,QACA,sBACA,4BACA,2BACA,WACA,gBACA,mBAEA,aACE,0BACA,WACA,kBACA,yBACA,qBACA,gBACA,iCACA,wBACA,YC7JJ,mBACE,4CACA,mBACA,kBACA,iBAGF,4BACE,mBACA,kBACA,cACA,UACA,WACA,qBACA,cACA,oBACA,sBACA,iBACA,mBACA,cACA,mCAGA,kCAGA,kCAGA,6BAGA,wBAEA,sCACA,sCACA,sCACA,sDAEA,gCACE,6BAIJ,iBAEE,YACA,kDAGF,mBAEE,WACA,kBACA,mBACA,oBACA,oBACA,cACA,iBAGA,6BACA,mCAGA,kCACA,sBAGF,WACE,oBAGF,WACE,uBAGF,WACE,oBAGF,WACE,qBAGF,WACE,oBAGF,WACE,qBAGF,WACE,oBAGF,WACE,qBAGF,WACE,uBAGF,WACE,yBAGF,WACE,qBAGF,WACE,sBAGF,WACE,qBAGF,WACE,8BAGF,WACE,oBAGF,WACE,qBAGF,WACE,sBAGF,WACE,0BAGF,WACE,mBAGF,WACE,sBAGF,WACE,wBAGF,WACE,oBAGF,WACE,aAMF,+BACE,6BACA,4BACA,qBAIF,wDACE,uBAIF,wDACE,qBAIF,wDACE,sBAIF,wDACE,wBAOF,UACE,6BAGF,UACE,QC3MF,qBACE,cAEA,SACE,SACA,aAGF,qBACE,cACA,oCACA,WACA,kBACA,QACA,SACA,kBACA,cAGF,iBACE,QACA,SACA,kBACA,aCnBJ,yBACE,kBACA,MACA,UACA,WACA,YACA,WACA,SACA,2BACA,YACA,aACA,2BACA,kBAEA,qBACE,kBACA,MACA,OACA,WACA,uBACA,YACA,aACA,YACA,0BAIJ,aACE,6BAGF,qBAEE,WACA,gBACA,gBACA,YACA,aACA,kBACA,qBACA,iFAEA,qBAEE,WACA,sBAIJ,oBACE,kBACA,MACA,QACA,gBACA,iBAGF,qBACE,wBAEA,UACE,QACA,SACA,kBACA,gCACA,wBACA,QACA,QACA,iBACA,YAIJ,UACE,6BAGF,qBACE,WACA,kBACA,8BAGF,iBACE,kBACA,UACA,uBACA,oCACA,0FAGF,SAEE,mBACA,wBACA,mCACA,qCAGF,WACE,kBAGF,gBACE,eACA,gBAGF,cACE,WC7GF,eACE,UACA,gBACA,aAEA,oBACE,oBAGF,eACE,0BAEA,wBACE,sBACA,mBACA,2BAGF,wBACE,WACA,mBACA,4BAGF,wBACE,8BACA,UAKN,gBACE,cACA,WACA,YAGF,eACE,gBACA,WACA,cAEA,UACE,uCC/CJ,OACE,SACE,wBAGF,gBACE,wBAGF,aACE,uCAIJ,SACE,SACE,UAGF,WACE,uCAIJ,OACE,UACE,cACA,eAGF,YACE,wCAIJ,2CACE,YAGE,uCAIJ,OACE,UACE,cACA,aAGF,qBACE,eACA,MACA,WACA,WACA,WACA,sBAGF,eACE,WACA,gCAGF,YACE,OAGF,YACE,cACA,OACA,MACA,eAGF,eACE,aAGF,UACE,gBACA,cACA,cAGF,WACE,SACA,WACA,oBACA,cAGF,aACE,eACA,WACA,MACA,QACA,SACA,YACA,aACA,eACA,sBACA,gBACA,uCAGF,qBAEE,QAGF,YACE,WACA,YACA,gBACA,mBAGF,aACE,QAGF,eACE,iBACA,OAGF,iBACE,oBACA,gBACA,eACA,oBAGF,YACE,2BAGF,YACE,UAGF,UACE,aAGF,eACE,oBAGF,sBACE,eAGF,YACE,sCAGF,MAGE,WACA,iBACA,qDAGF,UAGE,oBAIJ,eACE,YACE,eC9KJ,KAGE,iBACE,sBACA,OAGF,UACE,KAGF,yBACE,sJAMF,uBAYE,SAGF,sBACE,wBAIF,2BACE,oBAIF,4BACE,0BAIF,mBACE,OAGF,UACE,SACA,UACA,UAGF,UACE,ICtDJ,qBACE,MAGF,sBACE,8BACA,CADA,0BACA,CADA,qBACA,MAGF,aACE,gBACA,SACA,sJAOF,YAUE,mBAGF,2BAIE,KAGF,oBACE,QAGF,wBACE,OAGF,gBACE,QAGF,aACE,kBACA,kBAGF,cAGE,YACA,QAGF,cACE,KAGF,UACE,KAGF,WACE,OAGF,wBACE,QAGF,QACE,8BAGF,mBAIE,eACA,SACA,oBAGF,4BACE,CADF,yBACE,CADF,oBACE,MAOF,oBACE,sBACA,QAGF,YACE,SAGF,aACE,WAGF,iBACE,aAGF,kBACE,oBAGF,QACE,mBACA,WACA,YACA,gBACA,UACA,kBACA,UACA,QAGF,cACE,MAGF,eACE,OAKF,UACE,MAGF,SACE,MAGF,SACE,MAGF,SACE,MAGF,SACE,MAGF,SACE,MAGF,SACE,MAGF,SACE,MAGF,SACE,MAGF,SACE,uFASF,aAYE,oBAKF,oBAGE,eAGF,OACE,uBACE,CADF,oBACE,CADF,eACE,gBACA,e","sources":["webpack://wallabag/./node_modules/annotator/css/annotator.css","webpack://wallabag/./node_modules/material-design-icons-iconfont/dist/material-design-icons.css","webpack://wallabag/./node_modules/lato-font/css/lato-font.css","webpack://wallabag/./app/Resources/static/themes/_global/global.scss","webpack://wallabag/./node_modules/highlight.js/styles/atom-one-light.css","webpack://wallabag/./app/Resources/static/themes/baggy/css/index.scss","webpack://wallabag/./app/Resources/static/themes/baggy/css/guide.scss","webpack://wallabag/./app/Resources/static/themes/baggy/css/layout.scss","webpack://wallabag/./app/Resources/static/themes/baggy/css/article.scss","webpack://wallabag/./app/Resources/static/themes/baggy/css/pictos.scss","webpack://wallabag/./app/Resources/static/themes/baggy/css/login.scss","webpack://wallabag/./app/Resources/static/themes/baggy/css/save.scss","webpack://wallabag/./app/Resources/static/themes/baggy/css/messages.scss","webpack://wallabag/./app/Resources/static/themes/baggy/css/media_queries.scss","webpack://wallabag/./app/Resources/static/themes/baggy/css/print.scss","webpack://wallabag/./app/Resources/static/themes/baggy/css/ratatouille.scss"],"sourcesContent":["/* Base Reset\n-------------------------------------------------------------------- */\n\n.annotator-notice,\n.annotator-filter *,\n.annotator-widget * {\n\tfont-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n\tfont-weight: normal;\n\ttext-align: left;\n\tmargin: 0;\n\tpadding: 0;\n\tbackground: none;\n\t-webkit-transition: none;\n\t-moz-transition: none;\n\t-o-transition: none;\n\ttransition: none;\n\t-moz-box-shadow: none;\n\t-webkit-box-shadow: none;\n\t-o-box-shadow: none;\n\tbox-shadow: none;\n\tcolor: rgb(144, 144, 144);\n}\n\n/* Images\n-------------------------------------------------------------------- */\n\n.annotator-adder {\n\tbackground-image: url(../img/annotator-icon-sprite.png?embed);\n\tbackground-repeat: no-repeat;\n}\n\n.annotator-resize,\n.annotator-widget:after,\n.annotator-editor a:after,\n.annotator-viewer .annotator-controls button,\n.annotator-viewer .annotator-controls a,\n.annotator-filter .annotator-filter-navigation button:after,\n.annotator-filter .annotator-filter-property .annotator-filter-clear {\n\tbackground-image: url(../img/annotator-glyph-sprite.png?embed);\n\tbackground-repeat: no-repeat;\n}\n\n/* Annotator Highlight\n-------------------------------------------------------------------- */\n\n.annotator-hl {\n\tbackground: #FFFF0A;\n\tbackground: rgba(255, 255, 10, 0.3);\n\t-ms-filter: \"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4DFFFF0A, endColorstr=#4DFFFF0A)\"; /* 0.3 == 4D in MS filters */\n}\n\n.annotator-hl-temporary {\n\tbackground: #007CFF;\n\tbackground: rgba(0, 124, 255, 0.3);\n\t-ms-filter: \"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4D007CFF, endColorstr=#4D007CFF)\"; /* 0.3 == 4D in MS filters */\n}\n\n/* Annotator Wrapper\n-------------------------------------------------------------------- */\n\n.annotator-wrapper {\n\tposition: relative;\n}\n\n/* NB: If you change the list of classes for which z-index is set,\n you should update setupDynamicStyle() in annotator.ui.main */\n.annotator-adder,\n.annotator-outer,\n.annotator-notice {\n\tz-index: 1020;\n}\n\n.annotator-filter {\n\tz-index: 1010;\n}\n\n.annotator-adder,\n.annotator-outer,\n.annotator-widget,\n.annotator-notice {\n\tposition: absolute;\n\tfont-size: 10px;\n\tline-height: 1;\n}\n\n.annotator-hide {\n\tdisplay: none;\n\tvisibility: hidden;\n}\n\n/* Annotator Adder\n-------------------------------------------------------------------- */\n\n.annotator-adder {\n\tmargin-top: -48px;\n\tmargin-left: -24px;\n\twidth: 48px;\n\theight: 48px;\n\tbackground-position: left top;\n}\n\n.annotator-adder:hover {\n\tbackground-position: center top;\n}\n\n.annotator-adder:active {\n\tbackground-position: center right;\n}\n\n.annotator-adder button {\n\tdisplay: block;\n\twidth: 36px;\n\theight: 41px;\n\tmargin: 0 auto;\n\tborder: none;\n\tbackground: none;\n\ttext-indent: -999em;\n\tcursor: pointer;\n}\n\n/* Annotator Widget\n \n This applies to both the Viewer and the Editor\n-------------------------------------------------------------------- */\n\n.annotator-outer {\n\twidth: 0;\n\theight: 0;\n}\n\n.annotator-widget {\n\tmargin: 0;\n\tpadding: 0;\n\tbottom: 15px;\n\tleft: -18px;\n\tmin-width: 265px;\n\tbackground-color: #FBFBFB;\n\tbackground-color: rgba(251, 251, 251, 0.98);\n\tborder: 1px solid #7A7A7A;\n\tborder: 1px solid rgba(122, 122, 122, 0.6);\n\t-webkit-border-radius: 5px;\n\t-moz-border-radius: 5px;\n\tborder-radius: 5px;\n\t-webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);\n\t-moz-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);\n\t-o-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);\n\tbox-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);\n}\n\n.annotator-invert-x .annotator-widget {\n\tleft: auto;\n\tright: -18px;\n}\n\n.annotator-invert-y .annotator-widget {\n\tbottom: auto;\n\ttop: 8px;\n}\n\n.annotator-widget strong {\n\tfont-weight: bold;\n}\n\n.annotator-widget .annotator-listing,\n.annotator-widget .annotator-item {\n\tpadding: 0;\n\tmargin: 0;\n\tlist-style: none;\n}\n\n.annotator-widget:after {\n\tcontent: \"\";\n\tdisplay: block;\n\twidth: 18px;\n\theight: 10px;\n\tbackground-position: 0 0;\n\tposition: absolute;\n\tbottom: -10px;\n\tleft: 8px;\n}\n\n.annotator-invert-x .annotator-widget:after {\n\tleft: auto;\n\tright: 8px;\n}\n\n.annotator-invert-y .annotator-widget:after {\n\tbackground-position: 0 -15px;\n\tbottom: auto;\n\ttop: -9px;\n}\n\n.annotator-widget .annotator-item,\n.annotator-editor .annotator-item input,\n.annotator-editor .annotator-item textarea {\n\tposition: relative;\n\tfont-size: 12px;\n}\n\n.annotator-viewer .annotator-item {\n\tborder-top: 2px solid #7A7A7A;\n\tborder-top: 2px solid rgba(122, 122, 122, 0.2);\n}\n\n.annotator-widget .annotator-item:first-child {\n\tborder-top: none;\n}\n\n.annotator-editor .annotator-item,\n.annotator-viewer div {\n\tborder-top: 1px solid #858585;\n\tborder-top: 1px solid rgba(133, 133, 133, 0.11);\n}\n\n/* Annotator Viewer\n-------------------------------------------------------------------- */\n\n.annotator-viewer div {\n\tpadding: 6px 6px;\n}\n\n.annotator-viewer .annotator-item ol,\n.annotator-viewer .annotator-item ul {\n\tpadding: 4px 16px;\n}\n\n.annotator-viewer .annotator-item li {\n}\n\n.annotator-viewer div:first-of-type,\n.annotator-editor .annotator-item:first-child textarea {\n\tpadding-top: 12px;\n\tpadding-bottom: 12px;\n\tcolor: rgb(60, 60, 60);\n\tfont-size: 13px;\n\tfont-style: italic;\n\tline-height: 1.3;\n\tborder-top: none;\n}\n\n.annotator-viewer .annotator-controls {\n\tposition: relative;\n\ttop: 5px;\n\tright: 5px;\n\tpadding-left: 5px;\n\topacity: 0;\n\t-webkit-transition: opacity 0.2s ease-in;\n\t-moz-transition: opacity 0.2s ease-in;\n\t-o-transition: opacity 0.2s ease-in;\n\ttransition: opacity 0.2s ease-in;\n\tfloat: right;\n}\n\n.annotator-viewer li:hover .annotator-controls,\n.annotator-viewer li .annotator-controls.annotator-visible {\n\topacity: 1;\n}\n\n.annotator-viewer .annotator-controls button,\n.annotator-viewer .annotator-controls a {\n\tcursor: pointer;\n\tdisplay: inline-block;\n\twidth: 13px;\n\theight: 13px;\n\tmargin-left: 2px;\n\tborder: none;\n\topacity: 0.2;\n\ttext-indent: -900em;\n\tbackground-color: transparent;\n\toutline: none;\n}\n\n.annotator-viewer .annotator-controls button:hover,\n.annotator-viewer .annotator-controls button:focus,\n.annotator-viewer .annotator-controls a:hover,\n.annotator-viewer .annotator-controls a:focus {\n\topacity: 0.9;\n}\n\n.annotator-viewer .annotator-controls button:active,\n.annotator-viewer .annotator-controls a:active {\n\topacity: 1;\n}\n\n.annotator-viewer .annotator-controls button[disabled] {\n\tdisplay: none;\n}\n\n.annotator-viewer .annotator-controls .annotator-edit {\n\tbackground-position: 0 -60px;\n}\n\n.annotator-viewer .annotator-controls .annotator-delete {\n\tbackground-position: 0 -75px;\n}\n\n.annotator-viewer .annotator-controls .annotator-link {\n\tbackground-position: 0 -270px;\n}\n\n/* Annotator Editor\n-------------------------------------------------------------------- */\n\n.annotator-editor .annotator-item {\n\tposition: relative;\n}\n\n.annotator-editor .annotator-item label {\n\ttop: 0;\n\tdisplay: inline;\n\tcursor: pointer;\n\tfont-size: 12px;\n}\n\n.annotator-editor .annotator-item input,\n.annotator-editor .annotator-item textarea {\n\tdisplay: block;\n\tmin-width: 100%;\n\tpadding: 10px 8px;\n\tborder: none;\n\tmargin: 0;\n\tcolor: rgb(60, 60, 60);\n\tbackground: none;\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\t-o-box-sizing: border-box;\n\tbox-sizing: border-box;\n\tresize: none;\n}\n\n.annotator-editor .annotator-item textarea::-webkit-scrollbar {\n\theight: 8px;\n\twidth: 8px;\n}\n\n.annotator-editor .annotator-item textarea::-webkit-scrollbar-track-piece {\n\tmargin: 13px 0 3px;\n\tbackground-color: #e5e5e5;\n\t-webkit-border-radius: 4px;\n}\n\n.annotator-editor .annotator-item textarea::-webkit-scrollbar-thumb:vertical {\n\theight: 25px;\n\tbackground-color: #ccc;\n\t-webkit-border-radius: 4px;\n\t-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n}\n\n.annotator-editor .annotator-item textarea::-webkit-scrollbar-thumb:horizontal {\n\twidth: 25px;\n\tbackground-color: #ccc;\n\t-webkit-border-radius: 4px;\n}\n\n.annotator-editor .annotator-item:first-child textarea {\n\tmin-height: 5.5em;\n\t-webkit-border-radius: 5px 5px 0 0;\n\t-moz-border-radius: 5px 5px 0 0;\n\t-o-border-radius: 5px 5px 0 0;\n\tborder-radius: 5px 5px 0 0;\n}\n\n.annotator-editor .annotator-item input:focus,\n.annotator-editor .annotator-item textarea:focus{\n\tbackground-color: rgb(243, 243, 243);\n\toutline: none;\n}\n\n.annotator-editor .annotator-item input[type=radio],\n.annotator-editor .annotator-item input[type=checkbox] {\n\twidth: auto;\n\tmin-width: 0;\n\tpadding: 0;\n\tdisplay: inline;\n\tmargin: 0 4px 0 0;\n\tcursor: pointer;\n}\n\n.annotator-editor .annotator-checkbox {\n\tpadding: 8px 6px;\n}\n\n.annotator-filter,\n.annotator-filter .annotator-filter-navigation button,\n.annotator-editor .annotator-controls {\n\ttext-align: right;\n\tpadding: 3px;\n\tborder-top: 1px solid rgb(212,212,212);\n\tbackground-color: rgb(212, 212, 212);\n\tbackground-image: -webkit-gradient(\n\t\tlinear, left top, left bottom,\n\t\tfrom(rgb(245, 245, 245)),\n\t\tcolor-stop(0.6, rgb(220, 220, 220)),\n\t\tto(rgb(210, 210, 210))\n\t);\n\tbackground-image: -moz-linear-gradient(\n\t to bottom,\n\t rgb(245, 245, 245),\n\t rgb(220, 220, 220) 60%,\n\t rgb(210, 210, 210)\n\t);\n\tbackground-image: -webkit-linear-gradient(\n\t to bottom,\n\t rgb(245, 245, 245),\n\t rgb(220, 220, 220) 60%,\n\t rgb(210, 210, 210)\n\t);\n\tbackground-image: linear-gradient(\n\t to bottom,\n\t rgb(245, 245, 245),\n\t rgb(220, 220, 220) 60%,\n\t rgb(210, 210, 210)\n\t);\n\t-webkit-box-shadow: \n\t\tinset 1px 0 0 rgba(255, 255, 255, 0.7),\n\t\tinset -1px 0 0 rgba(255, 255, 255, 0.7),\n\t\tinset 0 1px 0 rgba(255, 255, 255, 0.7);\n\t-moz-box-shadow: \n\t\tinset 1px 0 0 rgba(255, 255, 255, 0.7),\n\t\tinset -1px 0 0 rgba(255, 255, 255, 0.7),\n\t\tinset 0 1px 0 rgba(255, 255, 255, 0.7);\n\t-o-box-shadow: \n\t\tinset 1px 0 0 rgba(255, 255, 255, 0.7),\n\t\tinset -1px 0 0 rgba(255, 255, 255, 0.7),\n\t\tinset 0 1px 0 rgba(255, 255, 255, 0.7);\n\tbox-shadow: \n\t\tinset 1px 0 0 rgba(255, 255, 255, 0.7),\n\t\tinset -1px 0 0 rgba(255, 255, 255, 0.7),\n\t\tinset 0 1px 0 rgba(255, 255, 255, 0.7);\n\t-webkit-border-radius: 0 0 5px 5px;\n\t-moz-border-radius: 0 0 5px 5px;\n\t-o-border-radius: 0 0 5px 5px;\n\tborder-radius: 0 0 5px 5px;\n}\n\n.annotator-editor.annotator-invert-y .annotator-controls {\n\tborder-top: none;\n\tborder-bottom: 1px solid rgb(180, 180, 180);\n\t-webkit-border-radius: 5px 5px 0 0;\n\t-moz-border-radius: 5px 5px 0 0;\n\t-o-border-radius: 5px 5px 0 0;\n\tborder-radius: 5px 5px 0 0;\n}\n\n.annotator-editor a,\n.annotator-filter .annotator-filter-property label {\n\tposition: relative;\n\tdisplay: inline-block;\n\tpadding: 0 6px 0 22px;\n\tcolor: rgb(54, 54, 54);\n\ttext-shadow: 0 1px 0 rgba(255, 255, 255, 0.75);\n\ttext-decoration: none;\n\tline-height: 24px;\n\tfont-size: 12px;\n\tfont-weight: bold;\n\tborder: 1px solid rgb(162, 162, 162);\n\tbackground-color: rgb(212, 212, 212);\n\tbackground-image: -webkit-gradient(\n\t\tlinear, left top, left bottom,\n\t\tfrom(rgb(245, 245, 245)),\n\t\tcolor-stop(0.5, rgb(210, 210, 210)),\n\t\tcolor-stop(0.5, rgb(190, 190, 190)),\n\t\tto(rgb(210, 210, 210))\n\t);\n\tbackground-image: -moz-linear-gradient(\n\t to bottom,\n\t rgb(245, 245, 245),\n\t rgb(210, 210, 210) 50%,\n\t rgb(190, 190, 190) 50%,\n\t rgb(210, 210, 210)\n\t);\n\tbackground-image: -webkit-linear-gradient(\n\t to bottom,\n\t rgb(245, 245, 245),\n\t rgb(210, 210, 210) 50%,\n\t rgb(190, 190, 190) 50%,\n\t rgb(210, 210, 210)\n\t);\n\tbackground-image: linear-gradient(\n\t to bottom,\n\t rgb(245, 245, 245),\n\t rgb(210, 210, 210) 50%,\n\t rgb(190, 190, 190) 50%,\n\t rgb(210, 210, 210)\n\t);\n\t-webkit-box-shadow: \n\t\tinset 0 0 5px rgba(255, 255, 255, 0.2),\n\t\tinset 0 0 1px rgba(255, 255, 255, 0.8);\n\t-moz-box-shadow:\n\t\tinset 0 0 5px rgba(255, 255, 255, 0.2),\n\t\tinset 0 0 1px rgba(255, 255, 255, 0.8);\n\t-o-box-shadow:\n\t\tinset 0 0 5px rgba(255, 255, 255, 0.2),\n\t\tinset 0 0 1px rgba(255, 255, 255, 0.8);\n\tbox-shadow:\n\t\tinset 0 0 5px rgba(255, 255, 255, 0.2),\n\t\tinset 0 0 1px rgba(255, 255, 255, 0.8);\n\t-webkit-border-radius: 5px;\n\t-moz-border-radius: 5px;\n\t-o-border-radius: 5px;\n\tborder-radius: 5px;\n}\n\n.annotator-editor a:after {\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 5px;\n\tdisplay: block;\n\tcontent: \"\";\n\twidth: 15px;\n\theight: 15px;\n\tmargin-top: -7px;\n\tbackground-position: 0 -90px;\n}\n\n.annotator-editor a:hover,\n.annotator-editor a:focus,\n.annotator-editor a.annotator-focus,\n.annotator-filter .annotator-filter-active label,\n.annotator-filter .annotator-filter-navigation button:hover {\n\toutline: none;\n\tborder-color: rgb(67, 90, 160);\n\tbackground-color: rgb(56, 101, 249);\n\tbackground-image: -webkit-gradient(\n\t\tlinear, left top, left bottom,\n\t\tfrom(rgb(118, 145, 251)),\n\t\tcolor-stop(0.5, rgb(80, 117, 251)),\n\t\tcolor-stop(0.5, rgb(56, 101, 249)),\n\t\tto(rgb(54, 101, 250))\n\t);\n\tbackground-image: -moz-linear-gradient(\n\t to bottom,\n\t rgb(118, 145, 251),\n\t rgb(80, 117, 251) 50%,\n\t rgb(56, 101, 249) 50%,\n\t rgb(54, 101, 250)\n\t);\n\tbackground-image: -webkit-linear-gradient(\n\t to bottom,\n\t rgb(118, 145, 251),\n\t rgb(80, 117, 251) 50%,\n\t rgb(56, 101, 249) 50%,\n\t rgb(54, 101, 250)\n\t);\n\tbackground-image: linear-gradient(\n\t to bottom,\n\t rgb(118, 145, 251),\n\t rgb(80, 117, 251) 50%,\n\t rgb(56, 101, 249) 50%,\n\t rgb(54, 101, 250)\n\t);\n\tcolor: rgb(255, 255, 255);\n\ttext-shadow: 0 -1px 0 rgba(0, 0, 0, 0.42);\n}\n\n.annotator-editor a:hover:after,\n.annotator-editor a:focus:after {\n\tmargin-top: -8px;\n\tbackground-position: 0 -105px;\n}\n\n.annotator-editor a:active,\n.annotator-filter .annotator-filter-navigation button:active {\n\tborder-color: rgb(112, 12, 73);\n\tbackground-color: rgb(209, 46, 142);\n\tbackground-image: -webkit-gradient(\n\t\tlinear, left top, left bottom,\n\t\tfrom(rgb(252, 124, 202)),\n\t\tcolor-stop(0.5, rgb(232, 93, 178)),\n\t\tcolor-stop(0.5, rgb(209, 46, 142)),\n\t\tto(rgb(255, 0, 156))\n\t);\n\tbackground-image: -moz-linear-gradient(\n\t to bottom,\n\t rgb(252, 124, 202),\n\t rgb(232, 93, 178) 50%,\n\t rgb(209, 46, 142) 50%,\n\t rgb(255, 0, 156)\n\t);\n\tbackground-image: -webkit-linear-gradient(\n\t to bottom,\n\t rgb(252, 124, 202),\n\t rgb(232, 93, 178) 50%,\n\t rgb(209, 46, 142) 50%,\n\t rgb(255, 0, 156)\n\t);\n\tbackground-image: linear-gradient(\n\t to bottom,\n\t rgb(252, 124, 202),\n\t rgb(232, 93, 178) 50%,\n\t rgb(209, 46, 142) 50%,\n\t rgb(255, 0, 156)\n\t);\n}\n\n.annotator-editor a.annotator-save:after {\n\tbackground-position: 0 -120px;\n}\n\n.annotator-editor a.annotator-save:hover:after,\n.annotator-editor a.annotator-save:focus:after,\n.annotator-editor a.annotator-save.annotator-focus:after {\n\tmargin-top: -8px;\n\tbackground-position: 0 -135px;\n}\n\n.annotator-editor .annotator-widget:after {\n\tbackground-position: 0 -30px;\n}\n\n.annotator-editor.annotator-invert-y .annotator-widget .annotator-controls {\n\tbackground-color: #f2f2f2;\n}\n\n.annotator-editor.annotator-invert-y .annotator-widget:after {\n\tbackground-position: 0 -45px;\n\theight: 11px;\n}\n\n.annotator-resize {\n\tposition: absolute;\n\ttop: 0;\n\tright: 0;\n\twidth: 12px;\n\theight: 12px;\n\tbackground-position: 2px -150px;\n}\n\n.annotator-invert-x .annotator-resize {\n\tright: auto;\n\tleft: 0;\n\tbackground-position: 0 -195px;\n}\n\n.annotator-invert-y .annotator-resize {\n\ttop: auto;\n\tbottom: 0;\n\tbackground-position: 2px -165px;\n}\n\n.annotator-invert-y.annotator-invert-x .annotator-resize {\n\tbackground-position: 0 -180px;\n}\n\n/* Annotator Notification\n-------------------------------------------------------------------- */\n\n.annotator-notice {\n\tcolor: #fff;\n\tposition: fixed;\n\ttop: -54px;\n\tleft: 0;\n\twidth: 100%;\n\tfont-size: 14px;\n\tline-height: 50px;\n\ttext-align: center;\n\tbackground: black;\n\tbackground: rgba(0, 0, 0, 0.9);\n\tborder-bottom: 4px solid #d4d4d4;\n\t-webkit-transition: top 0.4s ease-out;\n\t-moz-transition: top 0.4s ease-out;\n\t-o-transition: top 0.4s ease-out;\n\ttransition: top 0.4s ease-out;\n}\n\n.annotator-notice-success {\n\tborder-color: #3665f9;\n}\n\n.annotator-notice-error {\n\tborder-color: #ff7e00;\n}\n\n.annotator-notice p {\n\tmargin: 0;\n}\n\n.annotator-notice a {\n\tcolor: #fff;\n}\n\n.annotator-notice-show {\n\ttop: 0;\n}\n\n/* Annotator Tags\n-------------------------------------------------------------------- */\n\n.annotator-tags {\n\tmargin-bottom: -2px;\n}\n\n.annotator-tags .annotator-tag {\n\tdisplay: inline-block;\n\tpadding: 0 8px;\n\tmargin-bottom: 2px;\n\tline-height: 1.6;\n\tfont-weight: bold;\n\tbackground-color: rgb(230, 230, 230);\n\t-webkit-border-radius: 8px;\n\t-moz-border-radius: 8px;\n\t-o-border-radius: 8px;\n\tborder-radius: 8px;\n}\n\n/* Annotator Filter\n-------------------------------------------------------------------- */\n\n.annotator-filter {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tleft: 0;\n\ttext-align: left;\n\tline-height: 0;\n\tborder: none;\n\tborder-bottom: 1px solid #878787;\n\tpadding-left: 10px;\n\tpadding-right: 10px;\n\t-webkit-border-radius: 0;\n\t-moz-border-radius: 0;\n\t-o-border-radius: 0;\n\tborder-radius: 0;\n\t-webkit-box-shadow: \n\t\tinset 0 -1px 0 rgba(255, 255, 255, 0.3);\n\t-moz-box-shadow: \n\t\tinset 0 -1px 0 rgba(255, 255, 255, 0.3);\n\t-o-box-shadow: \n\t\tinset 0 -1px 0 rgba(255, 255, 255, 0.3);\n\tbox-shadow: \n\t\tinset 0 -1px 0 rgba(255, 255, 255, 0.3);\n}\n\n.annotator-filter strong {\n\tfont-size: 12px;\n\tfont-weight: bold;\n\tcolor: #3c3c3c;\n\ttext-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);\n\tposition: relative;\n\ttop: -9px;\n}\n\n\n.annotator-filter .annotator-filter-property,\n.annotator-filter .annotator-filter-navigation {\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tline-height: 10px;\n\tpadding: 2px 0;\n\tmargin-right: 8px;\n}\n\n.annotator-filter .annotator-filter-property label,\n.annotator-filter .annotator-filter-navigation button {\n\ttext-align: left;\n\tdisplay: block;\n\tfloat: left;\n\tline-height: 20px;\n\t-webkit-border-radius: 10px 0 0 10px;\n\t-moz-border-radius: 10px 0 0 10px;\n\t-o-border-radius: 10px 0 0 10px;\n\tborder-radius: 10px 0 0 10px;\n}\n\n.annotator-filter .annotator-filter-property label {\n\tpadding-left: 8px;\n}\n\n.annotator-filter .annotator-filter-property input {\n\tdisplay: block;\n\tfloat: right;\n\t-webkit-appearance: none;\n\tbackground-color: #fff;\n\tborder: 1px solid #878787;\n\tborder-left: none;\n\tpadding: 2px 4px;\n\tline-height: 16px;\n\tmin-height: 16px;\n\tfont-size: 12px;\n\twidth: 150px;\n\tcolor: #333;\n\tbackground-color: #f8f8f8;\n\t-webkit-border-radius: 0 10px 10px 0;\n\t-moz-border-radius: 0 10px 10px 0;\n\t-o-border-radius: 0 10px 10px 0;\n\tborder-radius: 0 10px 10px 0;\n\t-webkit-box-shadow: \n\t\tinset 0 1px 1px rgba(0, 0, 0, 0.2);\n\t-moz-box-shadow: \n\t\tinset 0 1px 1px rgba(0, 0, 0, 0.2);\n\t-o-box-shadow: \n\t\tinset 0 1px 1px rgba(0, 0, 0, 0.2);\n\tbox-shadow: \n\t\tinset 0 1px 1px rgba(0, 0, 0, 0.2);\n\t\n}\n\n.annotator-filter .annotator-filter-property input:focus {\n\toutline: none;\n\tbackground-color: #fff;\n}\n\n.annotator-filter .annotator-filter-clear {\n\tposition: absolute;\n\tright: 3px;\n\ttop: 6px;\n\tborder: none;\n\ttext-indent: -900em;\n\twidth: 15px;\n\theight: 15px;\n\tbackground-position: 0 -90px;\n\topacity: 0.4;\n}\n\n.annotator-filter .annotator-filter-clear:hover,\n.annotator-filter .annotator-filter-clear:focus {\n\topacity: 0.8;\n}\n\n.annotator-filter .annotator-filter-clear:active {\n\topacity: 1;\n}\n\n.annotator-filter .annotator-filter-navigation button {\n\tborder: 1px solid rgb(162, 162, 162);\n\tpadding: 0;\n\ttext-indent: -900px;\n\twidth: 20px;\n\tmin-height: 22px;\n\t-webkit-box-shadow: \n\t\tinset 0 0 5px rgba(255, 255, 255, 0.2),\n\t\tinset 0 0 1px rgba(255, 255, 255, 0.8);\n\t-moz-box-shadow:\n\t\tinset 0 0 5px rgba(255, 255, 255, 0.2),\n\t\tinset 0 0 1px rgba(255, 255, 255, 0.8);\n\t-o-box-shadow:\n\t\tinset 0 0 5px rgba(255, 255, 255, 0.2),\n\t\tinset 0 0 1px rgba(255, 255, 255, 0.8);\n\tbox-shadow:\n\t\tinset 0 0 5px rgba(255, 255, 255, 0.2),\n\t\tinset 0 0 1px rgba(255, 255, 255, 0.8);\n}\n\n.annotator-filter .annotator-filter-navigation button,\n.annotator-filter .annotator-filter-navigation button:hover,\n.annotator-filter .annotator-filter-navigation button:focus {\n\tcolor: transparent;\n}\n\n.annotator-filter .annotator-filter-navigation button:after {\n\tposition: absolute;\n\ttop: 8px;\n\tleft: 8px;\n\tcontent: \"\";\n\tdisplay: block;\n\twidth: 9px;\n\theight: 9px;\n\tbackground-position: 0 -210px;\n}\n\n.annotator-filter .annotator-filter-navigation button:hover:after {\n\tbackground-position: 0 -225px;\n}\n\n.annotator-filter .annotator-filter-navigation .annotator-filter-next {\n\t-webkit-border-radius: 0 10px 10px 0;\n\t-moz-border-radius: 0 10px 10px 0;\n\t-o-border-radius: 0 10px 10px 0;\n\tborder-radius: 0 10px 10px 0;\n\tborder-left: none;\n}\n\n.annotator-filter .annotator-filter-navigation .annotator-filter-next:after {\n\tleft: auto;\n\tright: 7px;\n\tbackground-position: 0 -240px;\n}\n\n.annotator-filter .annotator-filter-navigation .annotator-filter-next:hover:after {\n\tbackground-position: 0 -255px;\n}\n\n.annotator-hl-active {\n\tbackground: #FFFF0A;\n\tbackground: rgba(255, 255, 10, 0.8);\n\t-ms-filter: \"progid:DXImageTransform.Microsoft.gradient(startColorstr=#CCFFFF0A, endColorstr=#CCFFFF0A)\"; /* 0.8 == CC in MS filters */\n}\n\n.annotator-hl-filtered {\n\tbackground-color: transparent;\n}\n","@charset \"UTF-8\";\n@font-face {\n font-family: 'Material Icons';\n font-style: normal;\n font-weight: 400;\n font-display: block;\n src: url(\"./fonts/MaterialIcons-Regular.eot\");\n /* For IE6-8 */\n src: local(\"☺\"), url(\"./fonts/MaterialIcons-Regular.woff2\") format(\"woff2\"), url(\"./fonts/MaterialIcons-Regular.woff\") format(\"woff\"), url(\"./fonts/MaterialIcons-Regular.ttf\") format(\"truetype\"); }\n\n.material-icons {\n font-family: 'Material Icons';\n font-weight: normal;\n font-style: normal;\n font-size: 24px;\n /* Preferred icon size */\n display: inline-block;\n line-height: 1;\n text-transform: none;\n letter-spacing: normal;\n word-wrap: normal;\n white-space: nowrap;\n /* Respect document layout direction */\n direction: inherit;\n /* Support for all WebKit browsers. */\n -webkit-font-smoothing: antialiased;\n /* Support for Safari and Chrome. */\n text-rendering: optimizeLegibility;\n /* Support for Firefox. */\n -moz-osx-font-smoothing: grayscale;\n /* Support for IE. */\n font-feature-settings: 'liga'; }\n .material-icons._10k:before {\n content: \"\\e951\"; }\n .material-icons._10mp:before {\n content: \"\\e952\"; }\n .material-icons._11mp:before {\n content: \"\\e953\"; }\n .material-icons._123:before {\n content: \"\\eb8d\"; }\n .material-icons._12mp:before {\n content: \"\\e954\"; }\n .material-icons._13mp:before {\n content: \"\\e955\"; }\n .material-icons._14mp:before {\n content: \"\\e956\"; }\n .material-icons._15mp:before {\n content: \"\\e957\"; }\n .material-icons._16mp:before {\n content: \"\\e958\"; }\n .material-icons._17mp:before {\n content: \"\\e959\"; }\n .material-icons._18_up_rating:before {\n content: \"\\f8fd\"; }\n .material-icons._18mp:before {\n content: \"\\e95a\"; }\n .material-icons._19mp:before {\n content: \"\\e95b\"; }\n .material-icons._1k:before {\n content: \"\\e95c\"; }\n .material-icons._1k_plus:before {\n content: \"\\e95d\"; }\n .material-icons._1x_mobiledata:before {\n content: \"\\efcd\"; }\n .material-icons._20mp:before {\n content: \"\\e95e\"; }\n .material-icons._21mp:before {\n content: \"\\e95f\"; }\n .material-icons._22mp:before {\n content: \"\\e960\"; }\n .material-icons._23mp:before {\n content: \"\\e961\"; }\n .material-icons._24mp:before {\n content: \"\\e962\"; }\n .material-icons._2k:before {\n content: \"\\e963\"; }\n .material-icons._2k_plus:before {\n content: \"\\e964\"; }\n .material-icons._2mp:before {\n content: \"\\e965\"; }\n .material-icons._30fps:before {\n content: \"\\efce\"; }\n .material-icons._30fps_select:before {\n content: \"\\efcf\"; }\n .material-icons._360:before {\n content: \"\\e577\"; }\n .material-icons._3d_rotation:before {\n content: \"\\e84d\"; }\n .material-icons._3g_mobiledata:before {\n content: \"\\efd0\"; }\n .material-icons._3k:before {\n content: \"\\e966\"; }\n .material-icons._3k_plus:before {\n content: \"\\e967\"; }\n .material-icons._3mp:before {\n content: \"\\e968\"; }\n .material-icons._3p:before {\n content: \"\\efd1\"; }\n .material-icons._4g_mobiledata:before {\n content: \"\\efd2\"; }\n .material-icons._4g_plus_mobiledata:before {\n content: \"\\efd3\"; }\n .material-icons._4k:before {\n content: \"\\e072\"; }\n .material-icons._4k_plus:before {\n content: \"\\e969\"; }\n .material-icons._4mp:before {\n content: \"\\e96a\"; }\n .material-icons._5g:before {\n content: \"\\ef38\"; }\n .material-icons._5k:before {\n content: \"\\e96b\"; }\n .material-icons._5k_plus:before {\n content: \"\\e96c\"; }\n .material-icons._5mp:before {\n content: \"\\e96d\"; }\n .material-icons._60fps:before {\n content: \"\\efd4\"; }\n .material-icons._60fps_select:before {\n content: \"\\efd5\"; }\n .material-icons._6_ft_apart:before {\n content: \"\\f21e\"; }\n .material-icons._6k:before {\n content: \"\\e96e\"; }\n .material-icons._6k_plus:before {\n content: \"\\e96f\"; }\n .material-icons._6mp:before {\n content: \"\\e970\"; }\n .material-icons._7k:before {\n content: \"\\e971\"; }\n .material-icons._7k_plus:before {\n content: \"\\e972\"; }\n .material-icons._7mp:before {\n content: \"\\e973\"; }\n .material-icons._8k:before {\n content: \"\\e974\"; }\n .material-icons._8k_plus:before {\n content: \"\\e975\"; }\n .material-icons._8mp:before {\n content: \"\\e976\"; }\n .material-icons._9k:before {\n content: \"\\e977\"; }\n .material-icons._9k_plus:before {\n content: \"\\e978\"; }\n .material-icons._9mp:before {\n content: \"\\e979\"; }\n .material-icons.abc:before {\n content: \"\\eb94\"; }\n .material-icons.ac_unit:before {\n content: \"\\eb3b\"; }\n .material-icons.access_alarm:before {\n content: \"\\e190\"; }\n .material-icons.access_alarms:before {\n content: \"\\e191\"; }\n .material-icons.access_time:before {\n content: \"\\e192\"; }\n .material-icons.access_time_filled:before {\n content: \"\\efd6\"; }\n .material-icons.accessibility:before {\n content: \"\\e84e\"; }\n .material-icons.accessibility_new:before {\n content: \"\\e92c\"; }\n .material-icons.accessible:before {\n content: \"\\e914\"; }\n .material-icons.accessible_forward:before {\n content: \"\\e934\"; }\n .material-icons.account_balance:before {\n content: \"\\e84f\"; }\n .material-icons.account_balance_wallet:before {\n content: \"\\e850\"; }\n .material-icons.account_box:before {\n content: \"\\e851\"; }\n .material-icons.account_circle:before {\n content: \"\\e853\"; }\n .material-icons.account_tree:before {\n content: \"\\e97a\"; }\n .material-icons.ad_units:before {\n content: \"\\ef39\"; }\n .material-icons.adb:before {\n content: \"\\e60e\"; }\n .material-icons.add:before {\n content: \"\\e145\"; }\n .material-icons.add_a_photo:before {\n content: \"\\e439\"; }\n .material-icons.add_alarm:before {\n content: \"\\e193\"; }\n .material-icons.add_alert:before {\n content: \"\\e003\"; }\n .material-icons.add_box:before {\n content: \"\\e146\"; }\n .material-icons.add_business:before {\n content: \"\\e729\"; }\n .material-icons.add_call:before {\n content: \"\\e0e8\"; }\n .material-icons.add_card:before {\n content: \"\\eb86\"; }\n .material-icons.add_chart:before {\n content: \"\\e97b\"; }\n .material-icons.add_circle:before {\n content: \"\\e147\"; }\n .material-icons.add_circle_outline:before {\n content: \"\\e148\"; }\n .material-icons.add_comment:before {\n content: \"\\e266\"; }\n .material-icons.add_home:before {\n content: \"\\f8eb\"; }\n .material-icons.add_home_work:before {\n content: \"\\f8ed\"; }\n .material-icons.add_ic_call:before {\n content: \"\\e97c\"; }\n .material-icons.add_link:before {\n content: \"\\e178\"; }\n .material-icons.add_location:before {\n content: \"\\e567\"; }\n .material-icons.add_location_alt:before {\n content: \"\\ef3a\"; }\n .material-icons.add_moderator:before {\n content: \"\\e97d\"; }\n .material-icons.add_photo_alternate:before {\n content: \"\\e43e\"; }\n .material-icons.add_reaction:before {\n content: \"\\e1d3\"; }\n .material-icons.add_road:before {\n content: \"\\ef3b\"; }\n .material-icons.add_shopping_cart:before {\n content: \"\\e854\"; }\n .material-icons.add_task:before {\n content: \"\\f23a\"; }\n .material-icons.add_to_drive:before {\n content: \"\\e65c\"; }\n .material-icons.add_to_home_screen:before {\n content: \"\\e1fe\"; }\n .material-icons.add_to_photos:before {\n content: \"\\e39d\"; }\n .material-icons.add_to_queue:before {\n content: \"\\e05c\"; }\n .material-icons.addchart:before {\n content: \"\\ef3c\"; }\n .material-icons.adf_scanner:before {\n content: \"\\eada\"; }\n .material-icons.adjust:before {\n content: \"\\e39e\"; }\n .material-icons.admin_panel_settings:before {\n content: \"\\ef3d\"; }\n .material-icons.adobe:before {\n content: \"\\ea96\"; }\n .material-icons.ads_click:before {\n content: \"\\e762\"; }\n .material-icons.agriculture:before {\n content: \"\\ea79\"; }\n .material-icons.air:before {\n content: \"\\efd8\"; }\n .material-icons.airline_seat_flat:before {\n content: \"\\e630\"; }\n .material-icons.airline_seat_flat_angled:before {\n content: \"\\e631\"; }\n .material-icons.airline_seat_individual_suite:before {\n content: \"\\e632\"; }\n .material-icons.airline_seat_legroom_extra:before {\n content: \"\\e633\"; }\n .material-icons.airline_seat_legroom_normal:before {\n content: \"\\e634\"; }\n .material-icons.airline_seat_legroom_reduced:before {\n content: \"\\e635\"; }\n .material-icons.airline_seat_recline_extra:before {\n content: \"\\e636\"; }\n .material-icons.airline_seat_recline_normal:before {\n content: \"\\e637\"; }\n .material-icons.airline_stops:before {\n content: \"\\e7d0\"; }\n .material-icons.airlines:before {\n content: \"\\e7ca\"; }\n .material-icons.airplane_ticket:before {\n content: \"\\efd9\"; }\n .material-icons.airplanemode_active:before {\n content: \"\\e195\"; }\n .material-icons.airplanemode_inactive:before {\n content: \"\\e194\"; }\n .material-icons.airplanemode_off:before {\n content: \"\\e194\"; }\n .material-icons.airplanemode_on:before {\n content: \"\\e195\"; }\n .material-icons.airplay:before {\n content: \"\\e055\"; }\n .material-icons.airport_shuttle:before {\n content: \"\\eb3c\"; }\n .material-icons.alarm:before {\n content: \"\\e855\"; }\n .material-icons.alarm_add:before {\n content: \"\\e856\"; }\n .material-icons.alarm_off:before {\n content: \"\\e857\"; }\n .material-icons.alarm_on:before {\n content: \"\\e858\"; }\n .material-icons.album:before {\n content: \"\\e019\"; }\n .material-icons.align_horizontal_center:before {\n content: \"\\e00f\"; }\n .material-icons.align_horizontal_left:before {\n content: \"\\e00d\"; }\n .material-icons.align_horizontal_right:before {\n content: \"\\e010\"; }\n .material-icons.align_vertical_bottom:before {\n content: \"\\e015\"; }\n .material-icons.align_vertical_center:before {\n content: \"\\e011\"; }\n .material-icons.align_vertical_top:before {\n content: \"\\e00c\"; }\n .material-icons.all_inbox:before {\n content: \"\\e97f\"; }\n .material-icons.all_inclusive:before {\n content: \"\\eb3d\"; }\n .material-icons.all_out:before {\n content: \"\\e90b\"; }\n .material-icons.alt_route:before {\n content: \"\\f184\"; }\n .material-icons.alternate_email:before {\n content: \"\\e0e6\"; }\n .material-icons.amp_stories:before {\n content: \"\\ea13\"; }\n .material-icons.analytics:before {\n content: \"\\ef3e\"; }\n .material-icons.anchor:before {\n content: \"\\f1cd\"; }\n .material-icons.android:before {\n content: \"\\e859\"; }\n .material-icons.animation:before {\n content: \"\\e71c\"; }\n .material-icons.announcement:before {\n content: \"\\e85a\"; }\n .material-icons.aod:before {\n content: \"\\efda\"; }\n .material-icons.apartment:before {\n content: \"\\ea40\"; }\n .material-icons.api:before {\n content: \"\\f1b7\"; }\n .material-icons.app_blocking:before {\n content: \"\\ef3f\"; }\n .material-icons.app_registration:before {\n content: \"\\ef40\"; }\n .material-icons.app_settings_alt:before {\n content: \"\\ef41\"; }\n .material-icons.app_shortcut:before {\n content: \"\\eae4\"; }\n .material-icons.apple:before {\n content: \"\\ea80\"; }\n .material-icons.approval:before {\n content: \"\\e982\"; }\n .material-icons.apps:before {\n content: \"\\e5c3\"; }\n .material-icons.apps_outage:before {\n content: \"\\e7cc\"; }\n .material-icons.architecture:before {\n content: \"\\ea3b\"; }\n .material-icons.archive:before {\n content: \"\\e149\"; }\n .material-icons.area_chart:before {\n content: \"\\e770\"; }\n .material-icons.arrow_back:before {\n content: \"\\e5c4\"; }\n .material-icons.arrow_back_ios:before {\n content: \"\\e5e0\"; }\n .material-icons.arrow_back_ios_new:before {\n content: \"\\e2ea\"; }\n .material-icons.arrow_circle_down:before {\n content: \"\\f181\"; }\n .material-icons.arrow_circle_left:before {\n content: \"\\eaa7\"; }\n .material-icons.arrow_circle_right:before {\n content: \"\\eaaa\"; }\n .material-icons.arrow_circle_up:before {\n content: \"\\f182\"; }\n .material-icons.arrow_downward:before {\n content: \"\\e5db\"; }\n .material-icons.arrow_drop_down:before {\n content: \"\\e5c5\"; }\n .material-icons.arrow_drop_down_circle:before {\n content: \"\\e5c6\"; }\n .material-icons.arrow_drop_up:before {\n content: \"\\e5c7\"; }\n .material-icons.arrow_forward:before {\n content: \"\\e5c8\"; }\n .material-icons.arrow_forward_ios:before {\n content: \"\\e5e1\"; }\n .material-icons.arrow_left:before {\n content: \"\\e5de\"; }\n .material-icons.arrow_right:before {\n content: \"\\e5df\"; }\n .material-icons.arrow_right_alt:before {\n content: \"\\e941\"; }\n .material-icons.arrow_upward:before {\n content: \"\\e5d8\"; }\n .material-icons.art_track:before {\n content: \"\\e060\"; }\n .material-icons.article:before {\n content: \"\\ef42\"; }\n .material-icons.aspect_ratio:before {\n content: \"\\e85b\"; }\n .material-icons.assessment:before {\n content: \"\\e85c\"; }\n .material-icons.assignment:before {\n content: \"\\e85d\"; }\n .material-icons.assignment_ind:before {\n content: \"\\e85e\"; }\n .material-icons.assignment_late:before {\n content: \"\\e85f\"; }\n .material-icons.assignment_return:before {\n content: \"\\e860\"; }\n .material-icons.assignment_returned:before {\n content: \"\\e861\"; }\n .material-icons.assignment_turned_in:before {\n content: \"\\e862\"; }\n .material-icons.assistant:before {\n content: \"\\e39f\"; }\n .material-icons.assistant_direction:before {\n content: \"\\e988\"; }\n .material-icons.assistant_navigation:before {\n content: \"\\e989\"; }\n .material-icons.assistant_photo:before {\n content: \"\\e3a0\"; }\n .material-icons.assured_workload:before {\n content: \"\\eb6f\"; }\n .material-icons.atm:before {\n content: \"\\e573\"; }\n .material-icons.attach_email:before {\n content: \"\\ea5e\"; }\n .material-icons.attach_file:before {\n content: \"\\e226\"; }\n .material-icons.attach_money:before {\n content: \"\\e227\"; }\n .material-icons.attachment:before {\n content: \"\\e2bc\"; }\n .material-icons.attractions:before {\n content: \"\\ea52\"; }\n .material-icons.attribution:before {\n content: \"\\efdb\"; }\n .material-icons.audio_file:before {\n content: \"\\eb82\"; }\n .material-icons.audiotrack:before {\n content: \"\\e3a1\"; }\n .material-icons.auto_awesome:before {\n content: \"\\e65f\"; }\n .material-icons.auto_awesome_mosaic:before {\n content: \"\\e660\"; }\n .material-icons.auto_awesome_motion:before {\n content: \"\\e661\"; }\n .material-icons.auto_delete:before {\n content: \"\\ea4c\"; }\n .material-icons.auto_fix_high:before {\n content: \"\\e663\"; }\n .material-icons.auto_fix_normal:before {\n content: \"\\e664\"; }\n .material-icons.auto_fix_off:before {\n content: \"\\e665\"; }\n .material-icons.auto_graph:before {\n content: \"\\e4fb\"; }\n .material-icons.auto_mode:before {\n content: \"\\ec20\"; }\n .material-icons.auto_stories:before {\n content: \"\\e666\"; }\n .material-icons.autofps_select:before {\n content: \"\\efdc\"; }\n .material-icons.autorenew:before {\n content: \"\\e863\"; }\n .material-icons.av_timer:before {\n content: \"\\e01b\"; }\n .material-icons.baby_changing_station:before {\n content: \"\\f19b\"; }\n .material-icons.back_hand:before {\n content: \"\\e764\"; }\n .material-icons.backpack:before {\n content: \"\\f19c\"; }\n .material-icons.backspace:before {\n content: \"\\e14a\"; }\n .material-icons.backup:before {\n content: \"\\e864\"; }\n .material-icons.backup_table:before {\n content: \"\\ef43\"; }\n .material-icons.badge:before {\n content: \"\\ea67\"; }\n .material-icons.bakery_dining:before {\n content: \"\\ea53\"; }\n .material-icons.balance:before {\n content: \"\\eaf6\"; }\n .material-icons.balcony:before {\n content: \"\\e58f\"; }\n .material-icons.ballot:before {\n content: \"\\e172\"; }\n .material-icons.bar_chart:before {\n content: \"\\e26b\"; }\n .material-icons.batch_prediction:before {\n content: \"\\f0f5\"; }\n .material-icons.bathroom:before {\n content: \"\\efdd\"; }\n .material-icons.bathtub:before {\n content: \"\\ea41\"; }\n .material-icons.battery_0_bar:before {\n content: \"\\ebdc\"; }\n .material-icons.battery_1_bar:before {\n content: \"\\ebd9\"; }\n .material-icons.battery_2_bar:before {\n content: \"\\ebe0\"; }\n .material-icons.battery_3_bar:before {\n content: \"\\ebdd\"; }\n .material-icons.battery_4_bar:before {\n content: \"\\ebe2\"; }\n .material-icons.battery_5_bar:before {\n content: \"\\ebd4\"; }\n .material-icons.battery_6_bar:before {\n content: \"\\ebd2\"; }\n .material-icons.battery_alert:before {\n content: \"\\e19c\"; }\n .material-icons.battery_charging_full:before {\n content: \"\\e1a3\"; }\n .material-icons.battery_full:before {\n content: \"\\e1a4\"; }\n .material-icons.battery_saver:before {\n content: \"\\efde\"; }\n .material-icons.battery_std:before {\n content: \"\\e1a5\"; }\n .material-icons.battery_unknown:before {\n content: \"\\e1a6\"; }\n .material-icons.beach_access:before {\n content: \"\\eb3e\"; }\n .material-icons.bed:before {\n content: \"\\efdf\"; }\n .material-icons.bedroom_baby:before {\n content: \"\\efe0\"; }\n .material-icons.bedroom_child:before {\n content: \"\\efe1\"; }\n .material-icons.bedroom_parent:before {\n content: \"\\efe2\"; }\n .material-icons.bedtime:before {\n content: \"\\ef44\"; }\n .material-icons.bedtime_off:before {\n content: \"\\eb76\"; }\n .material-icons.beenhere:before {\n content: \"\\e52d\"; }\n .material-icons.bento:before {\n content: \"\\f1f4\"; }\n .material-icons.bike_scooter:before {\n content: \"\\ef45\"; }\n .material-icons.biotech:before {\n content: \"\\ea3a\"; }\n .material-icons.blender:before {\n content: \"\\efe3\"; }\n .material-icons.blinds:before {\n content: \"\\e286\"; }\n .material-icons.blinds_closed:before {\n content: \"\\ec1f\"; }\n .material-icons.block:before {\n content: \"\\e14b\"; }\n .material-icons.block_flipped:before {\n content: \"\\ef46\"; }\n .material-icons.bloodtype:before {\n content: \"\\efe4\"; }\n .material-icons.bluetooth:before {\n content: \"\\e1a7\"; }\n .material-icons.bluetooth_audio:before {\n content: \"\\e60f\"; }\n .material-icons.bluetooth_connected:before {\n content: \"\\e1a8\"; }\n .material-icons.bluetooth_disabled:before {\n content: \"\\e1a9\"; }\n .material-icons.bluetooth_drive:before {\n content: \"\\efe5\"; }\n .material-icons.bluetooth_searching:before {\n content: \"\\e1aa\"; }\n .material-icons.blur_circular:before {\n content: \"\\e3a2\"; }\n .material-icons.blur_linear:before {\n content: \"\\e3a3\"; }\n .material-icons.blur_off:before {\n content: \"\\e3a4\"; }\n .material-icons.blur_on:before {\n content: \"\\e3a5\"; }\n .material-icons.bolt:before {\n content: \"\\ea0b\"; }\n .material-icons.book:before {\n content: \"\\e865\"; }\n .material-icons.book_online:before {\n content: \"\\f217\"; }\n .material-icons.bookmark:before {\n content: \"\\e866\"; }\n .material-icons.bookmark_add:before {\n content: \"\\e598\"; }\n .material-icons.bookmark_added:before {\n content: \"\\e599\"; }\n .material-icons.bookmark_border:before {\n content: \"\\e867\"; }\n .material-icons.bookmark_outline:before {\n content: \"\\e867\"; }\n .material-icons.bookmark_remove:before {\n content: \"\\e59a\"; }\n .material-icons.bookmarks:before {\n content: \"\\e98b\"; }\n .material-icons.border_all:before {\n content: \"\\e228\"; }\n .material-icons.border_bottom:before {\n content: \"\\e229\"; }\n .material-icons.border_clear:before {\n content: \"\\e22a\"; }\n .material-icons.border_color:before {\n content: \"\\e22b\"; }\n .material-icons.border_horizontal:before {\n content: \"\\e22c\"; }\n .material-icons.border_inner:before {\n content: \"\\e22d\"; }\n .material-icons.border_left:before {\n content: \"\\e22e\"; }\n .material-icons.border_outer:before {\n content: \"\\e22f\"; }\n .material-icons.border_right:before {\n content: \"\\e230\"; }\n .material-icons.border_style:before {\n content: \"\\e231\"; }\n .material-icons.border_top:before {\n content: \"\\e232\"; }\n .material-icons.border_vertical:before {\n content: \"\\e233\"; }\n .material-icons.boy:before {\n content: \"\\eb67\"; }\n .material-icons.branding_watermark:before {\n content: \"\\e06b\"; }\n .material-icons.breakfast_dining:before {\n content: \"\\ea54\"; }\n .material-icons.brightness_1:before {\n content: \"\\e3a6\"; }\n .material-icons.brightness_2:before {\n content: \"\\e3a7\"; }\n .material-icons.brightness_3:before {\n content: \"\\e3a8\"; }\n .material-icons.brightness_4:before {\n content: \"\\e3a9\"; }\n .material-icons.brightness_5:before {\n content: \"\\e3aa\"; }\n .material-icons.brightness_6:before {\n content: \"\\e3ab\"; }\n .material-icons.brightness_7:before {\n content: \"\\e3ac\"; }\n .material-icons.brightness_auto:before {\n content: \"\\e1ab\"; }\n .material-icons.brightness_high:before {\n content: \"\\e1ac\"; }\n .material-icons.brightness_low:before {\n content: \"\\e1ad\"; }\n .material-icons.brightness_medium:before {\n content: \"\\e1ae\"; }\n .material-icons.broadcast_on_home:before {\n content: \"\\f8f8\"; }\n .material-icons.broadcast_on_personal:before {\n content: \"\\f8f9\"; }\n .material-icons.broken_image:before {\n content: \"\\e3ad\"; }\n .material-icons.browse_gallery:before {\n content: \"\\ebd1\"; }\n .material-icons.browser_not_supported:before {\n content: \"\\ef47\"; }\n .material-icons.browser_updated:before {\n content: \"\\e7cf\"; }\n .material-icons.brunch_dining:before {\n content: \"\\ea73\"; }\n .material-icons.brush:before {\n content: \"\\e3ae\"; }\n .material-icons.bubble_chart:before {\n content: \"\\e6dd\"; }\n .material-icons.bug_report:before {\n content: \"\\e868\"; }\n .material-icons.build:before {\n content: \"\\e869\"; }\n .material-icons.build_circle:before {\n content: \"\\ef48\"; }\n .material-icons.bungalow:before {\n content: \"\\e591\"; }\n .material-icons.burst_mode:before {\n content: \"\\e43c\"; }\n .material-icons.bus_alert:before {\n content: \"\\e98f\"; }\n .material-icons.business:before {\n content: \"\\e0af\"; }\n .material-icons.business_center:before {\n content: \"\\eb3f\"; }\n .material-icons.cabin:before {\n content: \"\\e589\"; }\n .material-icons.cable:before {\n content: \"\\efe6\"; }\n .material-icons.cached:before {\n content: \"\\e86a\"; }\n .material-icons.cake:before {\n content: \"\\e7e9\"; }\n .material-icons.calculate:before {\n content: \"\\ea5f\"; }\n .material-icons.calendar_month:before {\n content: \"\\ebcc\"; }\n .material-icons.calendar_today:before {\n content: \"\\e935\"; }\n .material-icons.calendar_view_day:before {\n content: \"\\e936\"; }\n .material-icons.calendar_view_month:before {\n content: \"\\efe7\"; }\n .material-icons.calendar_view_week:before {\n content: \"\\efe8\"; }\n .material-icons.call:before {\n content: \"\\e0b0\"; }\n .material-icons.call_end:before {\n content: \"\\e0b1\"; }\n .material-icons.call_made:before {\n content: \"\\e0b2\"; }\n .material-icons.call_merge:before {\n content: \"\\e0b3\"; }\n .material-icons.call_missed:before {\n content: \"\\e0b4\"; }\n .material-icons.call_missed_outgoing:before {\n content: \"\\e0e4\"; }\n .material-icons.call_received:before {\n content: \"\\e0b5\"; }\n .material-icons.call_split:before {\n content: \"\\e0b6\"; }\n .material-icons.call_to_action:before {\n content: \"\\e06c\"; }\n .material-icons.camera:before {\n content: \"\\e3af\"; }\n .material-icons.camera_alt:before {\n content: \"\\e3b0\"; }\n .material-icons.camera_enhance:before {\n content: \"\\e8fc\"; }\n .material-icons.camera_front:before {\n content: \"\\e3b1\"; }\n .material-icons.camera_indoor:before {\n content: \"\\efe9\"; }\n .material-icons.camera_outdoor:before {\n content: \"\\efea\"; }\n .material-icons.camera_rear:before {\n content: \"\\e3b2\"; }\n .material-icons.camera_roll:before {\n content: \"\\e3b3\"; }\n .material-icons.cameraswitch:before {\n content: \"\\efeb\"; }\n .material-icons.campaign:before {\n content: \"\\ef49\"; }\n .material-icons.cancel:before {\n content: \"\\e5c9\"; }\n .material-icons.cancel_presentation:before {\n content: \"\\e0e9\"; }\n .material-icons.cancel_schedule_send:before {\n content: \"\\ea39\"; }\n .material-icons.candlestick_chart:before {\n content: \"\\ead4\"; }\n .material-icons.car_crash:before {\n content: \"\\ebf2\"; }\n .material-icons.car_rental:before {\n content: \"\\ea55\"; }\n .material-icons.car_repair:before {\n content: \"\\ea56\"; }\n .material-icons.card_giftcard:before {\n content: \"\\e8f6\"; }\n .material-icons.card_membership:before {\n content: \"\\e8f7\"; }\n .material-icons.card_travel:before {\n content: \"\\e8f8\"; }\n .material-icons.carpenter:before {\n content: \"\\f1f8\"; }\n .material-icons.cases:before {\n content: \"\\e992\"; }\n .material-icons.casino:before {\n content: \"\\eb40\"; }\n .material-icons.cast:before {\n content: \"\\e307\"; }\n .material-icons.cast_connected:before {\n content: \"\\e308\"; }\n .material-icons.cast_for_education:before {\n content: \"\\efec\"; }\n .material-icons.castle:before {\n content: \"\\eab1\"; }\n .material-icons.catching_pokemon:before {\n content: \"\\e508\"; }\n .material-icons.category:before {\n content: \"\\e574\"; }\n .material-icons.celebration:before {\n content: \"\\ea65\"; }\n .material-icons.cell_tower:before {\n content: \"\\ebba\"; }\n .material-icons.cell_wifi:before {\n content: \"\\e0ec\"; }\n .material-icons.center_focus_strong:before {\n content: \"\\e3b4\"; }\n .material-icons.center_focus_weak:before {\n content: \"\\e3b5\"; }\n .material-icons.chair:before {\n content: \"\\efed\"; }\n .material-icons.chair_alt:before {\n content: \"\\efee\"; }\n .material-icons.chalet:before {\n content: \"\\e585\"; }\n .material-icons.change_circle:before {\n content: \"\\e2e7\"; }\n .material-icons.change_history:before {\n content: \"\\e86b\"; }\n .material-icons.charging_station:before {\n content: \"\\f19d\"; }\n .material-icons.chat:before {\n content: \"\\e0b7\"; }\n .material-icons.chat_bubble:before {\n content: \"\\e0ca\"; }\n .material-icons.chat_bubble_outline:before {\n content: \"\\e0cb\"; }\n .material-icons.check:before {\n content: \"\\e5ca\"; }\n .material-icons.check_box:before {\n content: \"\\e834\"; }\n .material-icons.check_box_outline_blank:before {\n content: \"\\e835\"; }\n .material-icons.check_circle:before {\n content: \"\\e86c\"; }\n .material-icons.check_circle_outline:before {\n content: \"\\e92d\"; }\n .material-icons.checklist:before {\n content: \"\\e6b1\"; }\n .material-icons.checklist_rtl:before {\n content: \"\\e6b3\"; }\n .material-icons.checkroom:before {\n content: \"\\f19e\"; }\n .material-icons.chevron_left:before {\n content: \"\\e5cb\"; }\n .material-icons.chevron_right:before {\n content: \"\\e5cc\"; }\n .material-icons.child_care:before {\n content: \"\\eb41\"; }\n .material-icons.child_friendly:before {\n content: \"\\eb42\"; }\n .material-icons.chrome_reader_mode:before {\n content: \"\\e86d\"; }\n .material-icons.church:before {\n content: \"\\eaae\"; }\n .material-icons.circle:before {\n content: \"\\ef4a\"; }\n .material-icons.circle_notifications:before {\n content: \"\\e994\"; }\n .material-icons.class:before {\n content: \"\\e86e\"; }\n .material-icons.clean_hands:before {\n content: \"\\f21f\"; }\n .material-icons.cleaning_services:before {\n content: \"\\f0ff\"; }\n .material-icons.clear:before {\n content: \"\\e14c\"; }\n .material-icons.clear_all:before {\n content: \"\\e0b8\"; }\n .material-icons.close:before {\n content: \"\\e5cd\"; }\n .material-icons.close_fullscreen:before {\n content: \"\\f1cf\"; }\n .material-icons.closed_caption:before {\n content: \"\\e01c\"; }\n .material-icons.closed_caption_disabled:before {\n content: \"\\f1dc\"; }\n .material-icons.closed_caption_off:before {\n content: \"\\e996\"; }\n .material-icons.cloud:before {\n content: \"\\e2bd\"; }\n .material-icons.cloud_circle:before {\n content: \"\\e2be\"; }\n .material-icons.cloud_done:before {\n content: \"\\e2bf\"; }\n .material-icons.cloud_download:before {\n content: \"\\e2c0\"; }\n .material-icons.cloud_off:before {\n content: \"\\e2c1\"; }\n .material-icons.cloud_queue:before {\n content: \"\\e2c2\"; }\n .material-icons.cloud_sync:before {\n content: \"\\eb5a\"; }\n .material-icons.cloud_upload:before {\n content: \"\\e2c3\"; }\n .material-icons.cloudy_snowing:before {\n content: \"\\e810\"; }\n .material-icons.co2:before {\n content: \"\\e7b0\"; }\n .material-icons.co_present:before {\n content: \"\\eaf0\"; }\n .material-icons.code:before {\n content: \"\\e86f\"; }\n .material-icons.code_off:before {\n content: \"\\e4f3\"; }\n .material-icons.coffee:before {\n content: \"\\efef\"; }\n .material-icons.coffee_maker:before {\n content: \"\\eff0\"; }\n .material-icons.collections:before {\n content: \"\\e3b6\"; }\n .material-icons.collections_bookmark:before {\n content: \"\\e431\"; }\n .material-icons.color_lens:before {\n content: \"\\e3b7\"; }\n .material-icons.colorize:before {\n content: \"\\e3b8\"; }\n .material-icons.comment:before {\n content: \"\\e0b9\"; }\n .material-icons.comment_bank:before {\n content: \"\\ea4e\"; }\n .material-icons.comments_disabled:before {\n content: \"\\e7a2\"; }\n .material-icons.commit:before {\n content: \"\\eaf5\"; }\n .material-icons.commute:before {\n content: \"\\e940\"; }\n .material-icons.compare:before {\n content: \"\\e3b9\"; }\n .material-icons.compare_arrows:before {\n content: \"\\e915\"; }\n .material-icons.compass_calibration:before {\n content: \"\\e57c\"; }\n .material-icons.compost:before {\n content: \"\\e761\"; }\n .material-icons.compress:before {\n content: \"\\e94d\"; }\n .material-icons.computer:before {\n content: \"\\e30a\"; }\n .material-icons.confirmation_num:before {\n content: \"\\e638\"; }\n .material-icons.confirmation_number:before {\n content: \"\\e638\"; }\n .material-icons.connect_without_contact:before {\n content: \"\\f223\"; }\n .material-icons.connected_tv:before {\n content: \"\\e998\"; }\n .material-icons.connecting_airports:before {\n content: \"\\e7c9\"; }\n .material-icons.construction:before {\n content: \"\\ea3c\"; }\n .material-icons.contact_mail:before {\n content: \"\\e0d0\"; }\n .material-icons.contact_page:before {\n content: \"\\f22e\"; }\n .material-icons.contact_phone:before {\n content: \"\\e0cf\"; }\n .material-icons.contact_support:before {\n content: \"\\e94c\"; }\n .material-icons.contactless:before {\n content: \"\\ea71\"; }\n .material-icons.contacts:before {\n content: \"\\e0ba\"; }\n .material-icons.content_copy:before {\n content: \"\\e14d\"; }\n .material-icons.content_cut:before {\n content: \"\\e14e\"; }\n .material-icons.content_paste:before {\n content: \"\\e14f\"; }\n .material-icons.content_paste_go:before {\n content: \"\\ea8e\"; }\n .material-icons.content_paste_off:before {\n content: \"\\e4f8\"; }\n .material-icons.content_paste_search:before {\n content: \"\\ea9b\"; }\n .material-icons.contrast:before {\n content: \"\\eb37\"; }\n .material-icons.control_camera:before {\n content: \"\\e074\"; }\n .material-icons.control_point:before {\n content: \"\\e3ba\"; }\n .material-icons.control_point_duplicate:before {\n content: \"\\e3bb\"; }\n .material-icons.cookie:before {\n content: \"\\eaac\"; }\n .material-icons.copy_all:before {\n content: \"\\e2ec\"; }\n .material-icons.copyright:before {\n content: \"\\e90c\"; }\n .material-icons.coronavirus:before {\n content: \"\\f221\"; }\n .material-icons.corporate_fare:before {\n content: \"\\f1d0\"; }\n .material-icons.cottage:before {\n content: \"\\e587\"; }\n .material-icons.countertops:before {\n content: \"\\f1f7\"; }\n .material-icons.create:before {\n content: \"\\e150\"; }\n .material-icons.create_new_folder:before {\n content: \"\\e2cc\"; }\n .material-icons.credit_card:before {\n content: \"\\e870\"; }\n .material-icons.credit_card_off:before {\n content: \"\\e4f4\"; }\n .material-icons.credit_score:before {\n content: \"\\eff1\"; }\n .material-icons.crib:before {\n content: \"\\e588\"; }\n .material-icons.crisis_alert:before {\n content: \"\\ebe9\"; }\n .material-icons.crop:before {\n content: \"\\e3be\"; }\n .material-icons.crop_16_9:before {\n content: \"\\e3bc\"; }\n .material-icons.crop_3_2:before {\n content: \"\\e3bd\"; }\n .material-icons.crop_5_4:before {\n content: \"\\e3bf\"; }\n .material-icons.crop_7_5:before {\n content: \"\\e3c0\"; }\n .material-icons.crop_din:before {\n content: \"\\e3c1\"; }\n .material-icons.crop_free:before {\n content: \"\\e3c2\"; }\n .material-icons.crop_landscape:before {\n content: \"\\e3c3\"; }\n .material-icons.crop_original:before {\n content: \"\\e3c4\"; }\n .material-icons.crop_portrait:before {\n content: \"\\e3c5\"; }\n .material-icons.crop_rotate:before {\n content: \"\\e437\"; }\n .material-icons.crop_square:before {\n content: \"\\e3c6\"; }\n .material-icons.cruelty_free:before {\n content: \"\\e799\"; }\n .material-icons.css:before {\n content: \"\\eb93\"; }\n .material-icons.currency_bitcoin:before {\n content: \"\\ebc5\"; }\n .material-icons.currency_exchange:before {\n content: \"\\eb70\"; }\n .material-icons.currency_franc:before {\n content: \"\\eafa\"; }\n .material-icons.currency_lira:before {\n content: \"\\eaef\"; }\n .material-icons.currency_pound:before {\n content: \"\\eaf1\"; }\n .material-icons.currency_ruble:before {\n content: \"\\eaec\"; }\n .material-icons.currency_rupee:before {\n content: \"\\eaf7\"; }\n .material-icons.currency_yen:before {\n content: \"\\eafb\"; }\n .material-icons.currency_yuan:before {\n content: \"\\eaf9\"; }\n .material-icons.curtains:before {\n content: \"\\ec1e\"; }\n .material-icons.curtains_closed:before {\n content: \"\\ec1d\"; }\n .material-icons.cyclone:before {\n content: \"\\ebd5\"; }\n .material-icons.dangerous:before {\n content: \"\\e99a\"; }\n .material-icons.dark_mode:before {\n content: \"\\e51c\"; }\n .material-icons.dashboard:before {\n content: \"\\e871\"; }\n .material-icons.dashboard_customize:before {\n content: \"\\e99b\"; }\n .material-icons.data_array:before {\n content: \"\\ead1\"; }\n .material-icons.data_exploration:before {\n content: \"\\e76f\"; }\n .material-icons.data_object:before {\n content: \"\\ead3\"; }\n .material-icons.data_saver_off:before {\n content: \"\\eff2\"; }\n .material-icons.data_saver_on:before {\n content: \"\\eff3\"; }\n .material-icons.data_thresholding:before {\n content: \"\\eb9f\"; }\n .material-icons.data_usage:before {\n content: \"\\e1af\"; }\n .material-icons.dataset:before {\n content: \"\\f8ee\"; }\n .material-icons.dataset_linked:before {\n content: \"\\f8ef\"; }\n .material-icons.date_range:before {\n content: \"\\e916\"; }\n .material-icons.deblur:before {\n content: \"\\eb77\"; }\n .material-icons.deck:before {\n content: \"\\ea42\"; }\n .material-icons.dehaze:before {\n content: \"\\e3c7\"; }\n .material-icons.delete:before {\n content: \"\\e872\"; }\n .material-icons.delete_forever:before {\n content: \"\\e92b\"; }\n .material-icons.delete_outline:before {\n content: \"\\e92e\"; }\n .material-icons.delete_sweep:before {\n content: \"\\e16c\"; }\n .material-icons.delivery_dining:before {\n content: \"\\ea72\"; }\n .material-icons.density_large:before {\n content: \"\\eba9\"; }\n .material-icons.density_medium:before {\n content: \"\\eb9e\"; }\n .material-icons.density_small:before {\n content: \"\\eba8\"; }\n .material-icons.departure_board:before {\n content: \"\\e576\"; }\n .material-icons.description:before {\n content: \"\\e873\"; }\n .material-icons.deselect:before {\n content: \"\\ebb6\"; }\n .material-icons.design_services:before {\n content: \"\\f10a\"; }\n .material-icons.desk:before {\n content: \"\\f8f4\"; }\n .material-icons.desktop_access_disabled:before {\n content: \"\\e99d\"; }\n .material-icons.desktop_mac:before {\n content: \"\\e30b\"; }\n .material-icons.desktop_windows:before {\n content: \"\\e30c\"; }\n .material-icons.details:before {\n content: \"\\e3c8\"; }\n .material-icons.developer_board:before {\n content: \"\\e30d\"; }\n .material-icons.developer_board_off:before {\n content: \"\\e4ff\"; }\n .material-icons.developer_mode:before {\n content: \"\\e1b0\"; }\n .material-icons.device_hub:before {\n content: \"\\e335\"; }\n .material-icons.device_thermostat:before {\n content: \"\\e1ff\"; }\n .material-icons.device_unknown:before {\n content: \"\\e339\"; }\n .material-icons.devices:before {\n content: \"\\e1b1\"; }\n .material-icons.devices_fold:before {\n content: \"\\ebde\"; }\n .material-icons.devices_other:before {\n content: \"\\e337\"; }\n .material-icons.dialer_sip:before {\n content: \"\\e0bb\"; }\n .material-icons.dialpad:before {\n content: \"\\e0bc\"; }\n .material-icons.diamond:before {\n content: \"\\ead5\"; }\n .material-icons.difference:before {\n content: \"\\eb7d\"; }\n .material-icons.dining:before {\n content: \"\\eff4\"; }\n .material-icons.dinner_dining:before {\n content: \"\\ea57\"; }\n .material-icons.directions:before {\n content: \"\\e52e\"; }\n .material-icons.directions_bike:before {\n content: \"\\e52f\"; }\n .material-icons.directions_boat:before {\n content: \"\\e532\"; }\n .material-icons.directions_boat_filled:before {\n content: \"\\eff5\"; }\n .material-icons.directions_bus:before {\n content: \"\\e530\"; }\n .material-icons.directions_bus_filled:before {\n content: \"\\eff6\"; }\n .material-icons.directions_car:before {\n content: \"\\e531\"; }\n .material-icons.directions_car_filled:before {\n content: \"\\eff7\"; }\n .material-icons.directions_ferry:before {\n content: \"\\e532\"; }\n .material-icons.directions_off:before {\n content: \"\\f10f\"; }\n .material-icons.directions_railway:before {\n content: \"\\e534\"; }\n .material-icons.directions_railway_filled:before {\n content: \"\\eff8\"; }\n .material-icons.directions_run:before {\n content: \"\\e566\"; }\n .material-icons.directions_subway:before {\n content: \"\\e533\"; }\n .material-icons.directions_subway_filled:before {\n content: \"\\eff9\"; }\n .material-icons.directions_train:before {\n content: \"\\e534\"; }\n .material-icons.directions_transit:before {\n content: \"\\e535\"; }\n .material-icons.directions_transit_filled:before {\n content: \"\\effa\"; }\n .material-icons.directions_walk:before {\n content: \"\\e536\"; }\n .material-icons.dirty_lens:before {\n content: \"\\ef4b\"; }\n .material-icons.disabled_by_default:before {\n content: \"\\f230\"; }\n .material-icons.disabled_visible:before {\n content: \"\\e76e\"; }\n .material-icons.disc_full:before {\n content: \"\\e610\"; }\n .material-icons.discord:before {\n content: \"\\ea6c\"; }\n .material-icons.discount:before {\n content: \"\\ebc9\"; }\n .material-icons.display_settings:before {\n content: \"\\eb97\"; }\n .material-icons.dnd_forwardslash:before {\n content: \"\\e611\"; }\n .material-icons.dns:before {\n content: \"\\e875\"; }\n .material-icons.do_disturb:before {\n content: \"\\f08c\"; }\n .material-icons.do_disturb_alt:before {\n content: \"\\f08d\"; }\n .material-icons.do_disturb_off:before {\n content: \"\\f08e\"; }\n .material-icons.do_disturb_on:before {\n content: \"\\f08f\"; }\n .material-icons.do_not_disturb:before {\n content: \"\\e612\"; }\n .material-icons.do_not_disturb_alt:before {\n content: \"\\e611\"; }\n .material-icons.do_not_disturb_off:before {\n content: \"\\e643\"; }\n .material-icons.do_not_disturb_on:before {\n content: \"\\e644\"; }\n .material-icons.do_not_disturb_on_total_silence:before {\n content: \"\\effb\"; }\n .material-icons.do_not_step:before {\n content: \"\\f19f\"; }\n .material-icons.do_not_touch:before {\n content: \"\\f1b0\"; }\n .material-icons.dock:before {\n content: \"\\e30e\"; }\n .material-icons.document_scanner:before {\n content: \"\\e5fa\"; }\n .material-icons.domain:before {\n content: \"\\e7ee\"; }\n .material-icons.domain_add:before {\n content: \"\\eb62\"; }\n .material-icons.domain_disabled:before {\n content: \"\\e0ef\"; }\n .material-icons.domain_verification:before {\n content: \"\\ef4c\"; }\n .material-icons.done:before {\n content: \"\\e876\"; }\n .material-icons.done_all:before {\n content: \"\\e877\"; }\n .material-icons.done_outline:before {\n content: \"\\e92f\"; }\n .material-icons.donut_large:before {\n content: \"\\e917\"; }\n .material-icons.donut_small:before {\n content: \"\\e918\"; }\n .material-icons.door_back:before {\n content: \"\\effc\"; }\n .material-icons.door_front:before {\n content: \"\\effd\"; }\n .material-icons.door_sliding:before {\n content: \"\\effe\"; }\n .material-icons.doorbell:before {\n content: \"\\efff\"; }\n .material-icons.double_arrow:before {\n content: \"\\ea50\"; }\n .material-icons.downhill_skiing:before {\n content: \"\\e509\"; }\n .material-icons.download:before {\n content: \"\\f090\"; }\n .material-icons.download_done:before {\n content: \"\\f091\"; }\n .material-icons.download_for_offline:before {\n content: \"\\f000\"; }\n .material-icons.downloading:before {\n content: \"\\f001\"; }\n .material-icons.drafts:before {\n content: \"\\e151\"; }\n .material-icons.drag_handle:before {\n content: \"\\e25d\"; }\n .material-icons.drag_indicator:before {\n content: \"\\e945\"; }\n .material-icons.draw:before {\n content: \"\\e746\"; }\n .material-icons.drive_eta:before {\n content: \"\\e613\"; }\n .material-icons.drive_file_move:before {\n content: \"\\e675\"; }\n .material-icons.drive_file_move_outline:before {\n content: \"\\e9a1\"; }\n .material-icons.drive_file_move_rtl:before {\n content: \"\\e76d\"; }\n .material-icons.drive_file_rename_outline:before {\n content: \"\\e9a2\"; }\n .material-icons.drive_folder_upload:before {\n content: \"\\e9a3\"; }\n .material-icons.dry:before {\n content: \"\\f1b3\"; }\n .material-icons.dry_cleaning:before {\n content: \"\\ea58\"; }\n .material-icons.duo:before {\n content: \"\\e9a5\"; }\n .material-icons.dvr:before {\n content: \"\\e1b2\"; }\n .material-icons.dynamic_feed:before {\n content: \"\\ea14\"; }\n .material-icons.dynamic_form:before {\n content: \"\\f1bf\"; }\n .material-icons.e_mobiledata:before {\n content: \"\\f002\"; }\n .material-icons.earbuds:before {\n content: \"\\f003\"; }\n .material-icons.earbuds_battery:before {\n content: \"\\f004\"; }\n .material-icons.east:before {\n content: \"\\f1df\"; }\n .material-icons.eco:before {\n content: \"\\ea35\"; }\n .material-icons.edgesensor_high:before {\n content: \"\\f005\"; }\n .material-icons.edgesensor_low:before {\n content: \"\\f006\"; }\n .material-icons.edit:before {\n content: \"\\e3c9\"; }\n .material-icons.edit_attributes:before {\n content: \"\\e578\"; }\n .material-icons.edit_calendar:before {\n content: \"\\e742\"; }\n .material-icons.edit_location:before {\n content: \"\\e568\"; }\n .material-icons.edit_location_alt:before {\n content: \"\\e1c5\"; }\n .material-icons.edit_note:before {\n content: \"\\e745\"; }\n .material-icons.edit_notifications:before {\n content: \"\\e525\"; }\n .material-icons.edit_off:before {\n content: \"\\e950\"; }\n .material-icons.edit_road:before {\n content: \"\\ef4d\"; }\n .material-icons.egg:before {\n content: \"\\eacc\"; }\n .material-icons.egg_alt:before {\n content: \"\\eac8\"; }\n .material-icons.eject:before {\n content: \"\\e8fb\"; }\n .material-icons.elderly:before {\n content: \"\\f21a\"; }\n .material-icons.elderly_woman:before {\n content: \"\\eb69\"; }\n .material-icons.electric_bike:before {\n content: \"\\eb1b\"; }\n .material-icons.electric_bolt:before {\n content: \"\\ec1c\"; }\n .material-icons.electric_car:before {\n content: \"\\eb1c\"; }\n .material-icons.electric_meter:before {\n content: \"\\ec1b\"; }\n .material-icons.electric_moped:before {\n content: \"\\eb1d\"; }\n .material-icons.electric_rickshaw:before {\n content: \"\\eb1e\"; }\n .material-icons.electric_scooter:before {\n content: \"\\eb1f\"; }\n .material-icons.electrical_services:before {\n content: \"\\f102\"; }\n .material-icons.elevator:before {\n content: \"\\f1a0\"; }\n .material-icons.email:before {\n content: \"\\e0be\"; }\n .material-icons.emergency:before {\n content: \"\\e1eb\"; }\n .material-icons.emergency_recording:before {\n content: \"\\ebf4\"; }\n .material-icons.emergency_share:before {\n content: \"\\ebf6\"; }\n .material-icons.emoji_emotions:before {\n content: \"\\ea22\"; }\n .material-icons.emoji_events:before {\n content: \"\\ea23\"; }\n .material-icons.emoji_flags:before {\n content: \"\\ea1a\"; }\n .material-icons.emoji_food_beverage:before {\n content: \"\\ea1b\"; }\n .material-icons.emoji_nature:before {\n content: \"\\ea1c\"; }\n .material-icons.emoji_objects:before {\n content: \"\\ea24\"; }\n .material-icons.emoji_people:before {\n content: \"\\ea1d\"; }\n .material-icons.emoji_symbols:before {\n content: \"\\ea1e\"; }\n .material-icons.emoji_transportation:before {\n content: \"\\ea1f\"; }\n .material-icons.energy_savings_leaf:before {\n content: \"\\ec1a\"; }\n .material-icons.engineering:before {\n content: \"\\ea3d\"; }\n .material-icons.enhance_photo_translate:before {\n content: \"\\e8fc\"; }\n .material-icons.enhanced_encryption:before {\n content: \"\\e63f\"; }\n .material-icons.equalizer:before {\n content: \"\\e01d\"; }\n .material-icons.error:before {\n content: \"\\e000\"; }\n .material-icons.error_outline:before {\n content: \"\\e001\"; }\n .material-icons.escalator:before {\n content: \"\\f1a1\"; }\n .material-icons.escalator_warning:before {\n content: \"\\f1ac\"; }\n .material-icons.euro:before {\n content: \"\\ea15\"; }\n .material-icons.euro_symbol:before {\n content: \"\\e926\"; }\n .material-icons.ev_station:before {\n content: \"\\e56d\"; }\n .material-icons.event:before {\n content: \"\\e878\"; }\n .material-icons.event_available:before {\n content: \"\\e614\"; }\n .material-icons.event_busy:before {\n content: \"\\e615\"; }\n .material-icons.event_note:before {\n content: \"\\e616\"; }\n .material-icons.event_repeat:before {\n content: \"\\eb7b\"; }\n .material-icons.event_seat:before {\n content: \"\\e903\"; }\n .material-icons.exit_to_app:before {\n content: \"\\e879\"; }\n .material-icons.expand:before {\n content: \"\\e94f\"; }\n .material-icons.expand_circle_down:before {\n content: \"\\e7cd\"; }\n .material-icons.expand_less:before {\n content: \"\\e5ce\"; }\n .material-icons.expand_more:before {\n content: \"\\e5cf\"; }\n .material-icons.explicit:before {\n content: \"\\e01e\"; }\n .material-icons.explore:before {\n content: \"\\e87a\"; }\n .material-icons.explore_off:before {\n content: \"\\e9a8\"; }\n .material-icons.exposure:before {\n content: \"\\e3ca\"; }\n .material-icons.exposure_minus_1:before {\n content: \"\\e3cb\"; }\n .material-icons.exposure_minus_2:before {\n content: \"\\e3cc\"; }\n .material-icons.exposure_neg_1:before {\n content: \"\\e3cb\"; }\n .material-icons.exposure_neg_2:before {\n content: \"\\e3cc\"; }\n .material-icons.exposure_plus_1:before {\n content: \"\\e3cd\"; }\n .material-icons.exposure_plus_2:before {\n content: \"\\e3ce\"; }\n .material-icons.exposure_zero:before {\n content: \"\\e3cf\"; }\n .material-icons.extension:before {\n content: \"\\e87b\"; }\n .material-icons.extension_off:before {\n content: \"\\e4f5\"; }\n .material-icons.face:before {\n content: \"\\e87c\"; }\n .material-icons.face_retouching_natural:before {\n content: \"\\ef4e\"; }\n .material-icons.face_retouching_off:before {\n content: \"\\f007\"; }\n .material-icons.facebook:before {\n content: \"\\f234\"; }\n .material-icons.fact_check:before {\n content: \"\\f0c5\"; }\n .material-icons.factory:before {\n content: \"\\ebbc\"; }\n .material-icons.family_restroom:before {\n content: \"\\f1a2\"; }\n .material-icons.fast_forward:before {\n content: \"\\e01f\"; }\n .material-icons.fast_rewind:before {\n content: \"\\e020\"; }\n .material-icons.fastfood:before {\n content: \"\\e57a\"; }\n .material-icons.favorite:before {\n content: \"\\e87d\"; }\n .material-icons.favorite_border:before {\n content: \"\\e87e\"; }\n .material-icons.favorite_outline:before {\n content: \"\\e87e\"; }\n .material-icons.fax:before {\n content: \"\\ead8\"; }\n .material-icons.featured_play_list:before {\n content: \"\\e06d\"; }\n .material-icons.featured_video:before {\n content: \"\\e06e\"; }\n .material-icons.feed:before {\n content: \"\\f009\"; }\n .material-icons.feedback:before {\n content: \"\\e87f\"; }\n .material-icons.female:before {\n content: \"\\e590\"; }\n .material-icons.fence:before {\n content: \"\\f1f6\"; }\n .material-icons.festival:before {\n content: \"\\ea68\"; }\n .material-icons.fiber_dvr:before {\n content: \"\\e05d\"; }\n .material-icons.fiber_manual_record:before {\n content: \"\\e061\"; }\n .material-icons.fiber_new:before {\n content: \"\\e05e\"; }\n .material-icons.fiber_pin:before {\n content: \"\\e06a\"; }\n .material-icons.fiber_smart_record:before {\n content: \"\\e062\"; }\n .material-icons.file_copy:before {\n content: \"\\e173\"; }\n .material-icons.file_download:before {\n content: \"\\e2c4\"; }\n .material-icons.file_download_done:before {\n content: \"\\e9aa\"; }\n .material-icons.file_download_off:before {\n content: \"\\e4fe\"; }\n .material-icons.file_open:before {\n content: \"\\eaf3\"; }\n .material-icons.file_present:before {\n content: \"\\ea0e\"; }\n .material-icons.file_upload:before {\n content: \"\\e2c6\"; }\n .material-icons.filter:before {\n content: \"\\e3d3\"; }\n .material-icons.filter_1:before {\n content: \"\\e3d0\"; }\n .material-icons.filter_2:before {\n content: \"\\e3d1\"; }\n .material-icons.filter_3:before {\n content: \"\\e3d2\"; }\n .material-icons.filter_4:before {\n content: \"\\e3d4\"; }\n .material-icons.filter_5:before {\n content: \"\\e3d5\"; }\n .material-icons.filter_6:before {\n content: \"\\e3d6\"; }\n .material-icons.filter_7:before {\n content: \"\\e3d7\"; }\n .material-icons.filter_8:before {\n content: \"\\e3d8\"; }\n .material-icons.filter_9:before {\n content: \"\\e3d9\"; }\n .material-icons.filter_9_plus:before {\n content: \"\\e3da\"; }\n .material-icons.filter_alt:before {\n content: \"\\ef4f\"; }\n .material-icons.filter_alt_off:before {\n content: \"\\eb32\"; }\n .material-icons.filter_b_and_w:before {\n content: \"\\e3db\"; }\n .material-icons.filter_center_focus:before {\n content: \"\\e3dc\"; }\n .material-icons.filter_drama:before {\n content: \"\\e3dd\"; }\n .material-icons.filter_frames:before {\n content: \"\\e3de\"; }\n .material-icons.filter_hdr:before {\n content: \"\\e3df\"; }\n .material-icons.filter_list:before {\n content: \"\\e152\"; }\n .material-icons.filter_list_alt:before {\n content: \"\\e94e\"; }\n .material-icons.filter_list_off:before {\n content: \"\\eb57\"; }\n .material-icons.filter_none:before {\n content: \"\\e3e0\"; }\n .material-icons.filter_tilt_shift:before {\n content: \"\\e3e2\"; }\n .material-icons.filter_vintage:before {\n content: \"\\e3e3\"; }\n .material-icons.find_in_page:before {\n content: \"\\e880\"; }\n .material-icons.find_replace:before {\n content: \"\\e881\"; }\n .material-icons.fingerprint:before {\n content: \"\\e90d\"; }\n .material-icons.fire_extinguisher:before {\n content: \"\\f1d8\"; }\n .material-icons.fire_hydrant:before {\n content: \"\\f1a3\"; }\n .material-icons.fire_hydrant_alt:before {\n content: \"\\f8f1\"; }\n .material-icons.fire_truck:before {\n content: \"\\f8f2\"; }\n .material-icons.fireplace:before {\n content: \"\\ea43\"; }\n .material-icons.first_page:before {\n content: \"\\e5dc\"; }\n .material-icons.fit_screen:before {\n content: \"\\ea10\"; }\n .material-icons.fitbit:before {\n content: \"\\e82b\"; }\n .material-icons.fitness_center:before {\n content: \"\\eb43\"; }\n .material-icons.flag:before {\n content: \"\\e153\"; }\n .material-icons.flag_circle:before {\n content: \"\\eaf8\"; }\n .material-icons.flaky:before {\n content: \"\\ef50\"; }\n .material-icons.flare:before {\n content: \"\\e3e4\"; }\n .material-icons.flash_auto:before {\n content: \"\\e3e5\"; }\n .material-icons.flash_off:before {\n content: \"\\e3e6\"; }\n .material-icons.flash_on:before {\n content: \"\\e3e7\"; }\n .material-icons.flashlight_off:before {\n content: \"\\f00a\"; }\n .material-icons.flashlight_on:before {\n content: \"\\f00b\"; }\n .material-icons.flatware:before {\n content: \"\\f00c\"; }\n .material-icons.flight:before {\n content: \"\\e539\"; }\n .material-icons.flight_class:before {\n content: \"\\e7cb\"; }\n .material-icons.flight_land:before {\n content: \"\\e904\"; }\n .material-icons.flight_takeoff:before {\n content: \"\\e905\"; }\n .material-icons.flip:before {\n content: \"\\e3e8\"; }\n .material-icons.flip_camera_android:before {\n content: \"\\ea37\"; }\n .material-icons.flip_camera_ios:before {\n content: \"\\ea38\"; }\n .material-icons.flip_to_back:before {\n content: \"\\e882\"; }\n .material-icons.flip_to_front:before {\n content: \"\\e883\"; }\n .material-icons.flood:before {\n content: \"\\ebe6\"; }\n .material-icons.flourescent:before {\n content: \"\\f00d\"; }\n .material-icons.flutter_dash:before {\n content: \"\\e00b\"; }\n .material-icons.fmd_bad:before {\n content: \"\\f00e\"; }\n .material-icons.fmd_good:before {\n content: \"\\f00f\"; }\n .material-icons.foggy:before {\n content: \"\\e818\"; }\n .material-icons.folder:before {\n content: \"\\e2c7\"; }\n .material-icons.folder_copy:before {\n content: \"\\ebbd\"; }\n .material-icons.folder_delete:before {\n content: \"\\eb34\"; }\n .material-icons.folder_off:before {\n content: \"\\eb83\"; }\n .material-icons.folder_open:before {\n content: \"\\e2c8\"; }\n .material-icons.folder_shared:before {\n content: \"\\e2c9\"; }\n .material-icons.folder_special:before {\n content: \"\\e617\"; }\n .material-icons.folder_zip:before {\n content: \"\\eb2c\"; }\n .material-icons.follow_the_signs:before {\n content: \"\\f222\"; }\n .material-icons.font_download:before {\n content: \"\\e167\"; }\n .material-icons.font_download_off:before {\n content: \"\\e4f9\"; }\n .material-icons.food_bank:before {\n content: \"\\f1f2\"; }\n .material-icons.forest:before {\n content: \"\\ea99\"; }\n .material-icons.fork_left:before {\n content: \"\\eba0\"; }\n .material-icons.fork_right:before {\n content: \"\\ebac\"; }\n .material-icons.format_align_center:before {\n content: \"\\e234\"; }\n .material-icons.format_align_justify:before {\n content: \"\\e235\"; }\n .material-icons.format_align_left:before {\n content: \"\\e236\"; }\n .material-icons.format_align_right:before {\n content: \"\\e237\"; }\n .material-icons.format_bold:before {\n content: \"\\e238\"; }\n .material-icons.format_clear:before {\n content: \"\\e239\"; }\n .material-icons.format_color_fill:before {\n content: \"\\e23a\"; }\n .material-icons.format_color_reset:before {\n content: \"\\e23b\"; }\n .material-icons.format_color_text:before {\n content: \"\\e23c\"; }\n .material-icons.format_indent_decrease:before {\n content: \"\\e23d\"; }\n .material-icons.format_indent_increase:before {\n content: \"\\e23e\"; }\n .material-icons.format_italic:before {\n content: \"\\e23f\"; }\n .material-icons.format_line_spacing:before {\n content: \"\\e240\"; }\n .material-icons.format_list_bulleted:before {\n content: \"\\e241\"; }\n .material-icons.format_list_numbered:before {\n content: \"\\e242\"; }\n .material-icons.format_list_numbered_rtl:before {\n content: \"\\e267\"; }\n .material-icons.format_overline:before {\n content: \"\\eb65\"; }\n .material-icons.format_paint:before {\n content: \"\\e243\"; }\n .material-icons.format_quote:before {\n content: \"\\e244\"; }\n .material-icons.format_shapes:before {\n content: \"\\e25e\"; }\n .material-icons.format_size:before {\n content: \"\\e245\"; }\n .material-icons.format_strikethrough:before {\n content: \"\\e246\"; }\n .material-icons.format_textdirection_l_to_r:before {\n content: \"\\e247\"; }\n .material-icons.format_textdirection_r_to_l:before {\n content: \"\\e248\"; }\n .material-icons.format_underline:before {\n content: \"\\e249\"; }\n .material-icons.format_underlined:before {\n content: \"\\e249\"; }\n .material-icons.fort:before {\n content: \"\\eaad\"; }\n .material-icons.forum:before {\n content: \"\\e0bf\"; }\n .material-icons.forward:before {\n content: \"\\e154\"; }\n .material-icons.forward_10:before {\n content: \"\\e056\"; }\n .material-icons.forward_30:before {\n content: \"\\e057\"; }\n .material-icons.forward_5:before {\n content: \"\\e058\"; }\n .material-icons.forward_to_inbox:before {\n content: \"\\f187\"; }\n .material-icons.foundation:before {\n content: \"\\f200\"; }\n .material-icons.free_breakfast:before {\n content: \"\\eb44\"; }\n .material-icons.free_cancellation:before {\n content: \"\\e748\"; }\n .material-icons.front_hand:before {\n content: \"\\e769\"; }\n .material-icons.fullscreen:before {\n content: \"\\e5d0\"; }\n .material-icons.fullscreen_exit:before {\n content: \"\\e5d1\"; }\n .material-icons.functions:before {\n content: \"\\e24a\"; }\n .material-icons.g_mobiledata:before {\n content: \"\\f010\"; }\n .material-icons.g_translate:before {\n content: \"\\e927\"; }\n .material-icons.gamepad:before {\n content: \"\\e30f\"; }\n .material-icons.games:before {\n content: \"\\e021\"; }\n .material-icons.garage:before {\n content: \"\\f011\"; }\n .material-icons.gas_meter:before {\n content: \"\\ec19\"; }\n .material-icons.gavel:before {\n content: \"\\e90e\"; }\n .material-icons.generating_tokens:before {\n content: \"\\e749\"; }\n .material-icons.gesture:before {\n content: \"\\e155\"; }\n .material-icons.get_app:before {\n content: \"\\e884\"; }\n .material-icons.gif:before {\n content: \"\\e908\"; }\n .material-icons.gif_box:before {\n content: \"\\e7a3\"; }\n .material-icons.girl:before {\n content: \"\\eb68\"; }\n .material-icons.gite:before {\n content: \"\\e58b\"; }\n .material-icons.goat:before {\n content: \"\\ebff\"; }\n .material-icons.golf_course:before {\n content: \"\\eb45\"; }\n .material-icons.gpp_bad:before {\n content: \"\\f012\"; }\n .material-icons.gpp_good:before {\n content: \"\\f013\"; }\n .material-icons.gpp_maybe:before {\n content: \"\\f014\"; }\n .material-icons.gps_fixed:before {\n content: \"\\e1b3\"; }\n .material-icons.gps_not_fixed:before {\n content: \"\\e1b4\"; }\n .material-icons.gps_off:before {\n content: \"\\e1b5\"; }\n .material-icons.grade:before {\n content: \"\\e885\"; }\n .material-icons.gradient:before {\n content: \"\\e3e9\"; }\n .material-icons.grading:before {\n content: \"\\ea4f\"; }\n .material-icons.grain:before {\n content: \"\\e3ea\"; }\n .material-icons.graphic_eq:before {\n content: \"\\e1b8\"; }\n .material-icons.grass:before {\n content: \"\\f205\"; }\n .material-icons.grid_3x3:before {\n content: \"\\f015\"; }\n .material-icons.grid_4x4:before {\n content: \"\\f016\"; }\n .material-icons.grid_goldenratio:before {\n content: \"\\f017\"; }\n .material-icons.grid_off:before {\n content: \"\\e3eb\"; }\n .material-icons.grid_on:before {\n content: \"\\e3ec\"; }\n .material-icons.grid_view:before {\n content: \"\\e9b0\"; }\n .material-icons.group:before {\n content: \"\\e7ef\"; }\n .material-icons.group_add:before {\n content: \"\\e7f0\"; }\n .material-icons.group_off:before {\n content: \"\\e747\"; }\n .material-icons.group_remove:before {\n content: \"\\e7ad\"; }\n .material-icons.group_work:before {\n content: \"\\e886\"; }\n .material-icons.groups:before {\n content: \"\\f233\"; }\n .material-icons.h_mobiledata:before {\n content: \"\\f018\"; }\n .material-icons.h_plus_mobiledata:before {\n content: \"\\f019\"; }\n .material-icons.hail:before {\n content: \"\\e9b1\"; }\n .material-icons.handshake:before {\n content: \"\\ebcb\"; }\n .material-icons.handyman:before {\n content: \"\\f10b\"; }\n .material-icons.hardware:before {\n content: \"\\ea59\"; }\n .material-icons.hd:before {\n content: \"\\e052\"; }\n .material-icons.hdr_auto:before {\n content: \"\\f01a\"; }\n .material-icons.hdr_auto_select:before {\n content: \"\\f01b\"; }\n .material-icons.hdr_enhanced_select:before {\n content: \"\\ef51\"; }\n .material-icons.hdr_off:before {\n content: \"\\e3ed\"; }\n .material-icons.hdr_off_select:before {\n content: \"\\f01c\"; }\n .material-icons.hdr_on:before {\n content: \"\\e3ee\"; }\n .material-icons.hdr_on_select:before {\n content: \"\\f01d\"; }\n .material-icons.hdr_plus:before {\n content: \"\\f01e\"; }\n .material-icons.hdr_strong:before {\n content: \"\\e3f1\"; }\n .material-icons.hdr_weak:before {\n content: \"\\e3f2\"; }\n .material-icons.headphones:before {\n content: \"\\f01f\"; }\n .material-icons.headphones_battery:before {\n content: \"\\f020\"; }\n .material-icons.headset:before {\n content: \"\\e310\"; }\n .material-icons.headset_mic:before {\n content: \"\\e311\"; }\n .material-icons.headset_off:before {\n content: \"\\e33a\"; }\n .material-icons.healing:before {\n content: \"\\e3f3\"; }\n .material-icons.health_and_safety:before {\n content: \"\\e1d5\"; }\n .material-icons.hearing:before {\n content: \"\\e023\"; }\n .material-icons.hearing_disabled:before {\n content: \"\\f104\"; }\n .material-icons.heart_broken:before {\n content: \"\\eac2\"; }\n .material-icons.heat_pump:before {\n content: \"\\ec18\"; }\n .material-icons.height:before {\n content: \"\\ea16\"; }\n .material-icons.help:before {\n content: \"\\e887\"; }\n .material-icons.help_center:before {\n content: \"\\f1c0\"; }\n .material-icons.help_outline:before {\n content: \"\\e8fd\"; }\n .material-icons.hevc:before {\n content: \"\\f021\"; }\n .material-icons.hexagon:before {\n content: \"\\eb39\"; }\n .material-icons.hide_image:before {\n content: \"\\f022\"; }\n .material-icons.hide_source:before {\n content: \"\\f023\"; }\n .material-icons.high_quality:before {\n content: \"\\e024\"; }\n .material-icons.highlight:before {\n content: \"\\e25f\"; }\n .material-icons.highlight_alt:before {\n content: \"\\ef52\"; }\n .material-icons.highlight_off:before {\n content: \"\\e888\"; }\n .material-icons.highlight_remove:before {\n content: \"\\e888\"; }\n .material-icons.hiking:before {\n content: \"\\e50a\"; }\n .material-icons.history:before {\n content: \"\\e889\"; }\n .material-icons.history_edu:before {\n content: \"\\ea3e\"; }\n .material-icons.history_toggle_off:before {\n content: \"\\f17d\"; }\n .material-icons.hive:before {\n content: \"\\eaa6\"; }\n .material-icons.hls:before {\n content: \"\\eb8a\"; }\n .material-icons.hls_off:before {\n content: \"\\eb8c\"; }\n .material-icons.holiday_village:before {\n content: \"\\e58a\"; }\n .material-icons.home:before {\n content: \"\\e88a\"; }\n .material-icons.home_filled:before {\n content: \"\\e9b2\"; }\n .material-icons.home_max:before {\n content: \"\\f024\"; }\n .material-icons.home_mini:before {\n content: \"\\f025\"; }\n .material-icons.home_repair_service:before {\n content: \"\\f100\"; }\n .material-icons.home_work:before {\n content: \"\\ea09\"; }\n .material-icons.horizontal_distribute:before {\n content: \"\\e014\"; }\n .material-icons.horizontal_rule:before {\n content: \"\\f108\"; }\n .material-icons.horizontal_split:before {\n content: \"\\e947\"; }\n .material-icons.hot_tub:before {\n content: \"\\eb46\"; }\n .material-icons.hotel:before {\n content: \"\\e53a\"; }\n .material-icons.hotel_class:before {\n content: \"\\e743\"; }\n .material-icons.hourglass_bottom:before {\n content: \"\\ea5c\"; }\n .material-icons.hourglass_disabled:before {\n content: \"\\ef53\"; }\n .material-icons.hourglass_empty:before {\n content: \"\\e88b\"; }\n .material-icons.hourglass_full:before {\n content: \"\\e88c\"; }\n .material-icons.hourglass_top:before {\n content: \"\\ea5b\"; }\n .material-icons.house:before {\n content: \"\\ea44\"; }\n .material-icons.house_siding:before {\n content: \"\\f202\"; }\n .material-icons.houseboat:before {\n content: \"\\e584\"; }\n .material-icons.how_to_reg:before {\n content: \"\\e174\"; }\n .material-icons.how_to_vote:before {\n content: \"\\e175\"; }\n .material-icons.html:before {\n content: \"\\eb7e\"; }\n .material-icons.http:before {\n content: \"\\e902\"; }\n .material-icons.https:before {\n content: \"\\e88d\"; }\n .material-icons.hub:before {\n content: \"\\e9f4\"; }\n .material-icons.hvac:before {\n content: \"\\f10e\"; }\n .material-icons.ice_skating:before {\n content: \"\\e50b\"; }\n .material-icons.icecream:before {\n content: \"\\ea69\"; }\n .material-icons.image:before {\n content: \"\\e3f4\"; }\n .material-icons.image_aspect_ratio:before {\n content: \"\\e3f5\"; }\n .material-icons.image_not_supported:before {\n content: \"\\f116\"; }\n .material-icons.image_search:before {\n content: \"\\e43f\"; }\n .material-icons.imagesearch_roller:before {\n content: \"\\e9b4\"; }\n .material-icons.import_contacts:before {\n content: \"\\e0e0\"; }\n .material-icons.import_export:before {\n content: \"\\e0c3\"; }\n .material-icons.important_devices:before {\n content: \"\\e912\"; }\n .material-icons.inbox:before {\n content: \"\\e156\"; }\n .material-icons.incomplete_circle:before {\n content: \"\\e79b\"; }\n .material-icons.indeterminate_check_box:before {\n content: \"\\e909\"; }\n .material-icons.info:before {\n content: \"\\e88e\"; }\n .material-icons.info_outline:before {\n content: \"\\e88f\"; }\n .material-icons.input:before {\n content: \"\\e890\"; }\n .material-icons.insert_chart:before {\n content: \"\\e24b\"; }\n .material-icons.insert_chart_outlined:before {\n content: \"\\e26a\"; }\n .material-icons.insert_comment:before {\n content: \"\\e24c\"; }\n .material-icons.insert_drive_file:before {\n content: \"\\e24d\"; }\n .material-icons.insert_emoticon:before {\n content: \"\\e24e\"; }\n .material-icons.insert_invitation:before {\n content: \"\\e24f\"; }\n .material-icons.insert_link:before {\n content: \"\\e250\"; }\n .material-icons.insert_page_break:before {\n content: \"\\eaca\"; }\n .material-icons.insert_photo:before {\n content: \"\\e251\"; }\n .material-icons.insights:before {\n content: \"\\f092\"; }\n .material-icons.install_desktop:before {\n content: \"\\eb71\"; }\n .material-icons.install_mobile:before {\n content: \"\\eb72\"; }\n .material-icons.integration_instructions:before {\n content: \"\\ef54\"; }\n .material-icons.interests:before {\n content: \"\\e7c8\"; }\n .material-icons.interpreter_mode:before {\n content: \"\\e83b\"; }\n .material-icons.inventory:before {\n content: \"\\e179\"; }\n .material-icons.inventory_2:before {\n content: \"\\e1a1\"; }\n .material-icons.invert_colors:before {\n content: \"\\e891\"; }\n .material-icons.invert_colors_off:before {\n content: \"\\e0c4\"; }\n .material-icons.invert_colors_on:before {\n content: \"\\e891\"; }\n .material-icons.ios_share:before {\n content: \"\\e6b8\"; }\n .material-icons.iron:before {\n content: \"\\e583\"; }\n .material-icons.iso:before {\n content: \"\\e3f6\"; }\n .material-icons.javascript:before {\n content: \"\\eb7c\"; }\n .material-icons.join_full:before {\n content: \"\\eaeb\"; }\n .material-icons.join_inner:before {\n content: \"\\eaf4\"; }\n .material-icons.join_left:before {\n content: \"\\eaf2\"; }\n .material-icons.join_right:before {\n content: \"\\eaea\"; }\n .material-icons.kayaking:before {\n content: \"\\e50c\"; }\n .material-icons.kebab_dining:before {\n content: \"\\e842\"; }\n .material-icons.key:before {\n content: \"\\e73c\"; }\n .material-icons.key_off:before {\n content: \"\\eb84\"; }\n .material-icons.keyboard:before {\n content: \"\\e312\"; }\n .material-icons.keyboard_alt:before {\n content: \"\\f028\"; }\n .material-icons.keyboard_arrow_down:before {\n content: \"\\e313\"; }\n .material-icons.keyboard_arrow_left:before {\n content: \"\\e314\"; }\n .material-icons.keyboard_arrow_right:before {\n content: \"\\e315\"; }\n .material-icons.keyboard_arrow_up:before {\n content: \"\\e316\"; }\n .material-icons.keyboard_backspace:before {\n content: \"\\e317\"; }\n .material-icons.keyboard_capslock:before {\n content: \"\\e318\"; }\n .material-icons.keyboard_command:before {\n content: \"\\eae0\"; }\n .material-icons.keyboard_command_key:before {\n content: \"\\eae7\"; }\n .material-icons.keyboard_control:before {\n content: \"\\e5d3\"; }\n .material-icons.keyboard_control_key:before {\n content: \"\\eae6\"; }\n .material-icons.keyboard_double_arrow_down:before {\n content: \"\\ead0\"; }\n .material-icons.keyboard_double_arrow_left:before {\n content: \"\\eac3\"; }\n .material-icons.keyboard_double_arrow_right:before {\n content: \"\\eac9\"; }\n .material-icons.keyboard_double_arrow_up:before {\n content: \"\\eacf\"; }\n .material-icons.keyboard_hide:before {\n content: \"\\e31a\"; }\n .material-icons.keyboard_option:before {\n content: \"\\eadf\"; }\n .material-icons.keyboard_option_key:before {\n content: \"\\eae8\"; }\n .material-icons.keyboard_return:before {\n content: \"\\e31b\"; }\n .material-icons.keyboard_tab:before {\n content: \"\\e31c\"; }\n .material-icons.keyboard_voice:before {\n content: \"\\e31d\"; }\n .material-icons.king_bed:before {\n content: \"\\ea45\"; }\n .material-icons.kitchen:before {\n content: \"\\eb47\"; }\n .material-icons.kitesurfing:before {\n content: \"\\e50d\"; }\n .material-icons.label:before {\n content: \"\\e892\"; }\n .material-icons.label_important:before {\n content: \"\\e937\"; }\n .material-icons.label_important_outline:before {\n content: \"\\e948\"; }\n .material-icons.label_off:before {\n content: \"\\e9b6\"; }\n .material-icons.label_outline:before {\n content: \"\\e893\"; }\n .material-icons.lan:before {\n content: \"\\eb2f\"; }\n .material-icons.landscape:before {\n content: \"\\e3f7\"; }\n .material-icons.landslide:before {\n content: \"\\ebd7\"; }\n .material-icons.language:before {\n content: \"\\e894\"; }\n .material-icons.laptop:before {\n content: \"\\e31e\"; }\n .material-icons.laptop_chromebook:before {\n content: \"\\e31f\"; }\n .material-icons.laptop_mac:before {\n content: \"\\e320\"; }\n .material-icons.laptop_windows:before {\n content: \"\\e321\"; }\n .material-icons.last_page:before {\n content: \"\\e5dd\"; }\n .material-icons.launch:before {\n content: \"\\e895\"; }\n .material-icons.layers:before {\n content: \"\\e53b\"; }\n .material-icons.layers_clear:before {\n content: \"\\e53c\"; }\n .material-icons.leaderboard:before {\n content: \"\\f20c\"; }\n .material-icons.leak_add:before {\n content: \"\\e3f8\"; }\n .material-icons.leak_remove:before {\n content: \"\\e3f9\"; }\n .material-icons.leave_bags_at_home:before {\n content: \"\\f21b\"; }\n .material-icons.legend_toggle:before {\n content: \"\\f11b\"; }\n .material-icons.lens:before {\n content: \"\\e3fa\"; }\n .material-icons.lens_blur:before {\n content: \"\\f029\"; }\n .material-icons.library_add:before {\n content: \"\\e02e\"; }\n .material-icons.library_add_check:before {\n content: \"\\e9b7\"; }\n .material-icons.library_books:before {\n content: \"\\e02f\"; }\n .material-icons.library_music:before {\n content: \"\\e030\"; }\n .material-icons.light:before {\n content: \"\\f02a\"; }\n .material-icons.light_mode:before {\n content: \"\\e518\"; }\n .material-icons.lightbulb:before {\n content: \"\\e0f0\"; }\n .material-icons.lightbulb_circle:before {\n content: \"\\ebfe\"; }\n .material-icons.lightbulb_outline:before {\n content: \"\\e90f\"; }\n .material-icons.line_axis:before {\n content: \"\\ea9a\"; }\n .material-icons.line_style:before {\n content: \"\\e919\"; }\n .material-icons.line_weight:before {\n content: \"\\e91a\"; }\n .material-icons.linear_scale:before {\n content: \"\\e260\"; }\n .material-icons.link:before {\n content: \"\\e157\"; }\n .material-icons.link_off:before {\n content: \"\\e16f\"; }\n .material-icons.linked_camera:before {\n content: \"\\e438\"; }\n .material-icons.liquor:before {\n content: \"\\ea60\"; }\n .material-icons.list:before {\n content: \"\\e896\"; }\n .material-icons.list_alt:before {\n content: \"\\e0ee\"; }\n .material-icons.live_help:before {\n content: \"\\e0c6\"; }\n .material-icons.live_tv:before {\n content: \"\\e639\"; }\n .material-icons.living:before {\n content: \"\\f02b\"; }\n .material-icons.local_activity:before {\n content: \"\\e53f\"; }\n .material-icons.local_airport:before {\n content: \"\\e53d\"; }\n .material-icons.local_atm:before {\n content: \"\\e53e\"; }\n .material-icons.local_attraction:before {\n content: \"\\e53f\"; }\n .material-icons.local_bar:before {\n content: \"\\e540\"; }\n .material-icons.local_cafe:before {\n content: \"\\e541\"; }\n .material-icons.local_car_wash:before {\n content: \"\\e542\"; }\n .material-icons.local_convenience_store:before {\n content: \"\\e543\"; }\n .material-icons.local_dining:before {\n content: \"\\e556\"; }\n .material-icons.local_drink:before {\n content: \"\\e544\"; }\n .material-icons.local_fire_department:before {\n content: \"\\ef55\"; }\n .material-icons.local_florist:before {\n content: \"\\e545\"; }\n .material-icons.local_gas_station:before {\n content: \"\\e546\"; }\n .material-icons.local_grocery_store:before {\n content: \"\\e547\"; }\n .material-icons.local_hospital:before {\n content: \"\\e548\"; }\n .material-icons.local_hotel:before {\n content: \"\\e549\"; }\n .material-icons.local_laundry_service:before {\n content: \"\\e54a\"; }\n .material-icons.local_library:before {\n content: \"\\e54b\"; }\n .material-icons.local_mall:before {\n content: \"\\e54c\"; }\n .material-icons.local_movies:before {\n content: \"\\e54d\"; }\n .material-icons.local_offer:before {\n content: \"\\e54e\"; }\n .material-icons.local_parking:before {\n content: \"\\e54f\"; }\n .material-icons.local_pharmacy:before {\n content: \"\\e550\"; }\n .material-icons.local_phone:before {\n content: \"\\e551\"; }\n .material-icons.local_pizza:before {\n content: \"\\e552\"; }\n .material-icons.local_play:before {\n content: \"\\e553\"; }\n .material-icons.local_police:before {\n content: \"\\ef56\"; }\n .material-icons.local_post_office:before {\n content: \"\\e554\"; }\n .material-icons.local_print_shop:before {\n content: \"\\e555\"; }\n .material-icons.local_printshop:before {\n content: \"\\e555\"; }\n .material-icons.local_restaurant:before {\n content: \"\\e556\"; }\n .material-icons.local_see:before {\n content: \"\\e557\"; }\n .material-icons.local_shipping:before {\n content: \"\\e558\"; }\n .material-icons.local_taxi:before {\n content: \"\\e559\"; }\n .material-icons.location_city:before {\n content: \"\\e7f1\"; }\n .material-icons.location_disabled:before {\n content: \"\\e1b6\"; }\n .material-icons.location_history:before {\n content: \"\\e55a\"; }\n .material-icons.location_off:before {\n content: \"\\e0c7\"; }\n .material-icons.location_on:before {\n content: \"\\e0c8\"; }\n .material-icons.location_pin:before {\n content: \"\\f1db\"; }\n .material-icons.location_searching:before {\n content: \"\\e1b7\"; }\n .material-icons.lock:before {\n content: \"\\e897\"; }\n .material-icons.lock_clock:before {\n content: \"\\ef57\"; }\n .material-icons.lock_open:before {\n content: \"\\e898\"; }\n .material-icons.lock_outline:before {\n content: \"\\e899\"; }\n .material-icons.lock_person:before {\n content: \"\\f8f3\"; }\n .material-icons.lock_reset:before {\n content: \"\\eade\"; }\n .material-icons.login:before {\n content: \"\\ea77\"; }\n .material-icons.logo_dev:before {\n content: \"\\ead6\"; }\n .material-icons.logout:before {\n content: \"\\e9ba\"; }\n .material-icons.looks:before {\n content: \"\\e3fc\"; }\n .material-icons.looks_3:before {\n content: \"\\e3fb\"; }\n .material-icons.looks_4:before {\n content: \"\\e3fd\"; }\n .material-icons.looks_5:before {\n content: \"\\e3fe\"; }\n .material-icons.looks_6:before {\n content: \"\\e3ff\"; }\n .material-icons.looks_one:before {\n content: \"\\e400\"; }\n .material-icons.looks_two:before {\n content: \"\\e401\"; }\n .material-icons.loop:before {\n content: \"\\e028\"; }\n .material-icons.loupe:before {\n content: \"\\e402\"; }\n .material-icons.low_priority:before {\n content: \"\\e16d\"; }\n .material-icons.loyalty:before {\n content: \"\\e89a\"; }\n .material-icons.lte_mobiledata:before {\n content: \"\\f02c\"; }\n .material-icons.lte_plus_mobiledata:before {\n content: \"\\f02d\"; }\n .material-icons.luggage:before {\n content: \"\\f235\"; }\n .material-icons.lunch_dining:before {\n content: \"\\ea61\"; }\n .material-icons.lyrics:before {\n content: \"\\ec0b\"; }\n .material-icons.mail:before {\n content: \"\\e158\"; }\n .material-icons.mail_lock:before {\n content: \"\\ec0a\"; }\n .material-icons.mail_outline:before {\n content: \"\\e0e1\"; }\n .material-icons.male:before {\n content: \"\\e58e\"; }\n .material-icons.man:before {\n content: \"\\e4eb\"; }\n .material-icons.manage_accounts:before {\n content: \"\\f02e\"; }\n .material-icons.manage_history:before {\n content: \"\\ebe7\"; }\n .material-icons.manage_search:before {\n content: \"\\f02f\"; }\n .material-icons.map:before {\n content: \"\\e55b\"; }\n .material-icons.maps_home_work:before {\n content: \"\\f030\"; }\n .material-icons.maps_ugc:before {\n content: \"\\ef58\"; }\n .material-icons.margin:before {\n content: \"\\e9bb\"; }\n .material-icons.mark_as_unread:before {\n content: \"\\e9bc\"; }\n .material-icons.mark_chat_read:before {\n content: \"\\f18b\"; }\n .material-icons.mark_chat_unread:before {\n content: \"\\f189\"; }\n .material-icons.mark_email_read:before {\n content: \"\\f18c\"; }\n .material-icons.mark_email_unread:before {\n content: \"\\f18a\"; }\n .material-icons.mark_unread_chat_alt:before {\n content: \"\\eb9d\"; }\n .material-icons.markunread:before {\n content: \"\\e159\"; }\n .material-icons.markunread_mailbox:before {\n content: \"\\e89b\"; }\n .material-icons.masks:before {\n content: \"\\f218\"; }\n .material-icons.maximize:before {\n content: \"\\e930\"; }\n .material-icons.media_bluetooth_off:before {\n content: \"\\f031\"; }\n .material-icons.media_bluetooth_on:before {\n content: \"\\f032\"; }\n .material-icons.mediation:before {\n content: \"\\efa7\"; }\n .material-icons.medical_information:before {\n content: \"\\ebed\"; }\n .material-icons.medical_services:before {\n content: \"\\f109\"; }\n .material-icons.medication:before {\n content: \"\\f033\"; }\n .material-icons.medication_liquid:before {\n content: \"\\ea87\"; }\n .material-icons.meeting_room:before {\n content: \"\\eb4f\"; }\n .material-icons.memory:before {\n content: \"\\e322\"; }\n .material-icons.menu:before {\n content: \"\\e5d2\"; }\n .material-icons.menu_book:before {\n content: \"\\ea19\"; }\n .material-icons.menu_open:before {\n content: \"\\e9bd\"; }\n .material-icons.merge:before {\n content: \"\\eb98\"; }\n .material-icons.merge_type:before {\n content: \"\\e252\"; }\n .material-icons.message:before {\n content: \"\\e0c9\"; }\n .material-icons.messenger:before {\n content: \"\\e0ca\"; }\n .material-icons.messenger_outline:before {\n content: \"\\e0cb\"; }\n .material-icons.mic:before {\n content: \"\\e029\"; }\n .material-icons.mic_external_off:before {\n content: \"\\ef59\"; }\n .material-icons.mic_external_on:before {\n content: \"\\ef5a\"; }\n .material-icons.mic_none:before {\n content: \"\\e02a\"; }\n .material-icons.mic_off:before {\n content: \"\\e02b\"; }\n .material-icons.microwave:before {\n content: \"\\f204\"; }\n .material-icons.military_tech:before {\n content: \"\\ea3f\"; }\n .material-icons.minimize:before {\n content: \"\\e931\"; }\n .material-icons.minor_crash:before {\n content: \"\\ebf1\"; }\n .material-icons.miscellaneous_services:before {\n content: \"\\f10c\"; }\n .material-icons.missed_video_call:before {\n content: \"\\e073\"; }\n .material-icons.mms:before {\n content: \"\\e618\"; }\n .material-icons.mobile_friendly:before {\n content: \"\\e200\"; }\n .material-icons.mobile_off:before {\n content: \"\\e201\"; }\n .material-icons.mobile_screen_share:before {\n content: \"\\e0e7\"; }\n .material-icons.mobiledata_off:before {\n content: \"\\f034\"; }\n .material-icons.mode:before {\n content: \"\\f097\"; }\n .material-icons.mode_comment:before {\n content: \"\\e253\"; }\n .material-icons.mode_edit:before {\n content: \"\\e254\"; }\n .material-icons.mode_edit_outline:before {\n content: \"\\f035\"; }\n .material-icons.mode_fan_off:before {\n content: \"\\ec17\"; }\n .material-icons.mode_night:before {\n content: \"\\f036\"; }\n .material-icons.mode_of_travel:before {\n content: \"\\e7ce\"; }\n .material-icons.mode_standby:before {\n content: \"\\f037\"; }\n .material-icons.model_training:before {\n content: \"\\f0cf\"; }\n .material-icons.monetization_on:before {\n content: \"\\e263\"; }\n .material-icons.money:before {\n content: \"\\e57d\"; }\n .material-icons.money_off:before {\n content: \"\\e25c\"; }\n .material-icons.money_off_csred:before {\n content: \"\\f038\"; }\n .material-icons.monitor:before {\n content: \"\\ef5b\"; }\n .material-icons.monitor_heart:before {\n content: \"\\eaa2\"; }\n .material-icons.monitor_weight:before {\n content: \"\\f039\"; }\n .material-icons.monochrome_photos:before {\n content: \"\\e403\"; }\n .material-icons.mood:before {\n content: \"\\e7f2\"; }\n .material-icons.mood_bad:before {\n content: \"\\e7f3\"; }\n .material-icons.moped:before {\n content: \"\\eb28\"; }\n .material-icons.more:before {\n content: \"\\e619\"; }\n .material-icons.more_horiz:before {\n content: \"\\e5d3\"; }\n .material-icons.more_time:before {\n content: \"\\ea5d\"; }\n .material-icons.more_vert:before {\n content: \"\\e5d4\"; }\n .material-icons.mosque:before {\n content: \"\\eab2\"; }\n .material-icons.motion_photos_auto:before {\n content: \"\\f03a\"; }\n .material-icons.motion_photos_off:before {\n content: \"\\e9c0\"; }\n .material-icons.motion_photos_on:before {\n content: \"\\e9c1\"; }\n .material-icons.motion_photos_pause:before {\n content: \"\\f227\"; }\n .material-icons.motion_photos_paused:before {\n content: \"\\e9c2\"; }\n .material-icons.motorcycle:before {\n content: \"\\e91b\"; }\n .material-icons.mouse:before {\n content: \"\\e323\"; }\n .material-icons.move_down:before {\n content: \"\\eb61\"; }\n .material-icons.move_to_inbox:before {\n content: \"\\e168\"; }\n .material-icons.move_up:before {\n content: \"\\eb64\"; }\n .material-icons.movie:before {\n content: \"\\e02c\"; }\n .material-icons.movie_creation:before {\n content: \"\\e404\"; }\n .material-icons.movie_filter:before {\n content: \"\\e43a\"; }\n .material-icons.moving:before {\n content: \"\\e501\"; }\n .material-icons.mp:before {\n content: \"\\e9c3\"; }\n .material-icons.multiline_chart:before {\n content: \"\\e6df\"; }\n .material-icons.multiple_stop:before {\n content: \"\\f1b9\"; }\n .material-icons.multitrack_audio:before {\n content: \"\\e1b8\"; }\n .material-icons.museum:before {\n content: \"\\ea36\"; }\n .material-icons.music_note:before {\n content: \"\\e405\"; }\n .material-icons.music_off:before {\n content: \"\\e440\"; }\n .material-icons.music_video:before {\n content: \"\\e063\"; }\n .material-icons.my_library_add:before {\n content: \"\\e02e\"; }\n .material-icons.my_library_books:before {\n content: \"\\e02f\"; }\n .material-icons.my_library_music:before {\n content: \"\\e030\"; }\n .material-icons.my_location:before {\n content: \"\\e55c\"; }\n .material-icons.nat:before {\n content: \"\\ef5c\"; }\n .material-icons.nature:before {\n content: \"\\e406\"; }\n .material-icons.nature_people:before {\n content: \"\\e407\"; }\n .material-icons.navigate_before:before {\n content: \"\\e408\"; }\n .material-icons.navigate_next:before {\n content: \"\\e409\"; }\n .material-icons.navigation:before {\n content: \"\\e55d\"; }\n .material-icons.near_me:before {\n content: \"\\e569\"; }\n .material-icons.near_me_disabled:before {\n content: \"\\f1ef\"; }\n .material-icons.nearby_error:before {\n content: \"\\f03b\"; }\n .material-icons.nearby_off:before {\n content: \"\\f03c\"; }\n .material-icons.nest_cam_wired_stand:before {\n content: \"\\ec16\"; }\n .material-icons.network_cell:before {\n content: \"\\e1b9\"; }\n .material-icons.network_check:before {\n content: \"\\e640\"; }\n .material-icons.network_locked:before {\n content: \"\\e61a\"; }\n .material-icons.network_ping:before {\n content: \"\\ebca\"; }\n .material-icons.network_wifi:before {\n content: \"\\e1ba\"; }\n .material-icons.network_wifi_1_bar:before {\n content: \"\\ebe4\"; }\n .material-icons.network_wifi_2_bar:before {\n content: \"\\ebd6\"; }\n .material-icons.network_wifi_3_bar:before {\n content: \"\\ebe1\"; }\n .material-icons.new_label:before {\n content: \"\\e609\"; }\n .material-icons.new_releases:before {\n content: \"\\e031\"; }\n .material-icons.newspaper:before {\n content: \"\\eb81\"; }\n .material-icons.next_plan:before {\n content: \"\\ef5d\"; }\n .material-icons.next_week:before {\n content: \"\\e16a\"; }\n .material-icons.nfc:before {\n content: \"\\e1bb\"; }\n .material-icons.night_shelter:before {\n content: \"\\f1f1\"; }\n .material-icons.nightlife:before {\n content: \"\\ea62\"; }\n .material-icons.nightlight:before {\n content: \"\\f03d\"; }\n .material-icons.nightlight_round:before {\n content: \"\\ef5e\"; }\n .material-icons.nights_stay:before {\n content: \"\\ea46\"; }\n .material-icons.no_accounts:before {\n content: \"\\f03e\"; }\n .material-icons.no_adult_content:before {\n content: \"\\f8fe\"; }\n .material-icons.no_backpack:before {\n content: \"\\f237\"; }\n .material-icons.no_cell:before {\n content: \"\\f1a4\"; }\n .material-icons.no_crash:before {\n content: \"\\ebf0\"; }\n .material-icons.no_drinks:before {\n content: \"\\f1a5\"; }\n .material-icons.no_encryption:before {\n content: \"\\e641\"; }\n .material-icons.no_encryption_gmailerrorred:before {\n content: \"\\f03f\"; }\n .material-icons.no_flash:before {\n content: \"\\f1a6\"; }\n .material-icons.no_food:before {\n content: \"\\f1a7\"; }\n .material-icons.no_luggage:before {\n content: \"\\f23b\"; }\n .material-icons.no_meals:before {\n content: \"\\f1d6\"; }\n .material-icons.no_meals_ouline:before {\n content: \"\\f229\"; }\n .material-icons.no_meeting_room:before {\n content: \"\\eb4e\"; }\n .material-icons.no_photography:before {\n content: \"\\f1a8\"; }\n .material-icons.no_sim:before {\n content: \"\\e0cc\"; }\n .material-icons.no_stroller:before {\n content: \"\\f1af\"; }\n .material-icons.no_transfer:before {\n content: \"\\f1d5\"; }\n .material-icons.noise_aware:before {\n content: \"\\ebec\"; }\n .material-icons.noise_control_off:before {\n content: \"\\ebf3\"; }\n .material-icons.nordic_walking:before {\n content: \"\\e50e\"; }\n .material-icons.north:before {\n content: \"\\f1e0\"; }\n .material-icons.north_east:before {\n content: \"\\f1e1\"; }\n .material-icons.north_west:before {\n content: \"\\f1e2\"; }\n .material-icons.not_accessible:before {\n content: \"\\f0fe\"; }\n .material-icons.not_interested:before {\n content: \"\\e033\"; }\n .material-icons.not_listed_location:before {\n content: \"\\e575\"; }\n .material-icons.not_started:before {\n content: \"\\f0d1\"; }\n .material-icons.note:before {\n content: \"\\e06f\"; }\n .material-icons.note_add:before {\n content: \"\\e89c\"; }\n .material-icons.note_alt:before {\n content: \"\\f040\"; }\n .material-icons.notes:before {\n content: \"\\e26c\"; }\n .material-icons.notification_add:before {\n content: \"\\e399\"; }\n .material-icons.notification_important:before {\n content: \"\\e004\"; }\n .material-icons.notifications:before {\n content: \"\\e7f4\"; }\n .material-icons.notifications_active:before {\n content: \"\\e7f7\"; }\n .material-icons.notifications_none:before {\n content: \"\\e7f5\"; }\n .material-icons.notifications_off:before {\n content: \"\\e7f6\"; }\n .material-icons.notifications_on:before {\n content: \"\\e7f7\"; }\n .material-icons.notifications_paused:before {\n content: \"\\e7f8\"; }\n .material-icons.now_wallpaper:before {\n content: \"\\e1bc\"; }\n .material-icons.now_widgets:before {\n content: \"\\e1bd\"; }\n .material-icons.numbers:before {\n content: \"\\eac7\"; }\n .material-icons.offline_bolt:before {\n content: \"\\e932\"; }\n .material-icons.offline_pin:before {\n content: \"\\e90a\"; }\n .material-icons.offline_share:before {\n content: \"\\e9c5\"; }\n .material-icons.oil_barrel:before {\n content: \"\\ec15\"; }\n .material-icons.on_device_training:before {\n content: \"\\ebfd\"; }\n .material-icons.ondemand_video:before {\n content: \"\\e63a\"; }\n .material-icons.online_prediction:before {\n content: \"\\f0eb\"; }\n .material-icons.opacity:before {\n content: \"\\e91c\"; }\n .material-icons.open_in_browser:before {\n content: \"\\e89d\"; }\n .material-icons.open_in_full:before {\n content: \"\\f1ce\"; }\n .material-icons.open_in_new:before {\n content: \"\\e89e\"; }\n .material-icons.open_in_new_off:before {\n content: \"\\e4f6\"; }\n .material-icons.open_with:before {\n content: \"\\e89f\"; }\n .material-icons.other_houses:before {\n content: \"\\e58c\"; }\n .material-icons.outbond:before {\n content: \"\\f228\"; }\n .material-icons.outbound:before {\n content: \"\\e1ca\"; }\n .material-icons.outbox:before {\n content: \"\\ef5f\"; }\n .material-icons.outdoor_grill:before {\n content: \"\\ea47\"; }\n .material-icons.outgoing_mail:before {\n content: \"\\f0d2\"; }\n .material-icons.outlet:before {\n content: \"\\f1d4\"; }\n .material-icons.outlined_flag:before {\n content: \"\\e16e\"; }\n .material-icons.output:before {\n content: \"\\ebbe\"; }\n .material-icons.padding:before {\n content: \"\\e9c8\"; }\n .material-icons.pages:before {\n content: \"\\e7f9\"; }\n .material-icons.pageview:before {\n content: \"\\e8a0\"; }\n .material-icons.paid:before {\n content: \"\\f041\"; }\n .material-icons.palette:before {\n content: \"\\e40a\"; }\n .material-icons.pan_tool:before {\n content: \"\\e925\"; }\n .material-icons.pan_tool_alt:before {\n content: \"\\ebb9\"; }\n .material-icons.panorama:before {\n content: \"\\e40b\"; }\n .material-icons.panorama_fish_eye:before {\n content: \"\\e40c\"; }\n .material-icons.panorama_fisheye:before {\n content: \"\\e40c\"; }\n .material-icons.panorama_horizontal:before {\n content: \"\\e40d\"; }\n .material-icons.panorama_horizontal_select:before {\n content: \"\\ef60\"; }\n .material-icons.panorama_photosphere:before {\n content: \"\\e9c9\"; }\n .material-icons.panorama_photosphere_select:before {\n content: \"\\e9ca\"; }\n .material-icons.panorama_vertical:before {\n content: \"\\e40e\"; }\n .material-icons.panorama_vertical_select:before {\n content: \"\\ef61\"; }\n .material-icons.panorama_wide_angle:before {\n content: \"\\e40f\"; }\n .material-icons.panorama_wide_angle_select:before {\n content: \"\\ef62\"; }\n .material-icons.paragliding:before {\n content: \"\\e50f\"; }\n .material-icons.park:before {\n content: \"\\ea63\"; }\n .material-icons.party_mode:before {\n content: \"\\e7fa\"; }\n .material-icons.password:before {\n content: \"\\f042\"; }\n .material-icons.pattern:before {\n content: \"\\f043\"; }\n .material-icons.pause:before {\n content: \"\\e034\"; }\n .material-icons.pause_circle:before {\n content: \"\\e1a2\"; }\n .material-icons.pause_circle_filled:before {\n content: \"\\e035\"; }\n .material-icons.pause_circle_outline:before {\n content: \"\\e036\"; }\n .material-icons.pause_presentation:before {\n content: \"\\e0ea\"; }\n .material-icons.payment:before {\n content: \"\\e8a1\"; }\n .material-icons.payments:before {\n content: \"\\ef63\"; }\n .material-icons.paypal:before {\n content: \"\\ea8d\"; }\n .material-icons.pedal_bike:before {\n content: \"\\eb29\"; }\n .material-icons.pending:before {\n content: \"\\ef64\"; }\n .material-icons.pending_actions:before {\n content: \"\\f1bb\"; }\n .material-icons.pentagon:before {\n content: \"\\eb50\"; }\n .material-icons.people:before {\n content: \"\\e7fb\"; }\n .material-icons.people_alt:before {\n content: \"\\ea21\"; }\n .material-icons.people_outline:before {\n content: \"\\e7fc\"; }\n .material-icons.percent:before {\n content: \"\\eb58\"; }\n .material-icons.perm_camera_mic:before {\n content: \"\\e8a2\"; }\n .material-icons.perm_contact_cal:before {\n content: \"\\e8a3\"; }\n .material-icons.perm_contact_calendar:before {\n content: \"\\e8a3\"; }\n .material-icons.perm_data_setting:before {\n content: \"\\e8a4\"; }\n .material-icons.perm_device_info:before {\n content: \"\\e8a5\"; }\n .material-icons.perm_device_information:before {\n content: \"\\e8a5\"; }\n .material-icons.perm_identity:before {\n content: \"\\e8a6\"; }\n .material-icons.perm_media:before {\n content: \"\\e8a7\"; }\n .material-icons.perm_phone_msg:before {\n content: \"\\e8a8\"; }\n .material-icons.perm_scan_wifi:before {\n content: \"\\e8a9\"; }\n .material-icons.person:before {\n content: \"\\e7fd\"; }\n .material-icons.person_add:before {\n content: \"\\e7fe\"; }\n .material-icons.person_add_alt:before {\n content: \"\\ea4d\"; }\n .material-icons.person_add_alt_1:before {\n content: \"\\ef65\"; }\n .material-icons.person_add_disabled:before {\n content: \"\\e9cb\"; }\n .material-icons.person_off:before {\n content: \"\\e510\"; }\n .material-icons.person_outline:before {\n content: \"\\e7ff\"; }\n .material-icons.person_pin:before {\n content: \"\\e55a\"; }\n .material-icons.person_pin_circle:before {\n content: \"\\e56a\"; }\n .material-icons.person_remove:before {\n content: \"\\ef66\"; }\n .material-icons.person_remove_alt_1:before {\n content: \"\\ef67\"; }\n .material-icons.person_search:before {\n content: \"\\f106\"; }\n .material-icons.personal_injury:before {\n content: \"\\e6da\"; }\n .material-icons.personal_video:before {\n content: \"\\e63b\"; }\n .material-icons.pest_control:before {\n content: \"\\f0fa\"; }\n .material-icons.pest_control_rodent:before {\n content: \"\\f0fd\"; }\n .material-icons.pets:before {\n content: \"\\e91d\"; }\n .material-icons.phishing:before {\n content: \"\\ead7\"; }\n .material-icons.phone:before {\n content: \"\\e0cd\"; }\n .material-icons.phone_android:before {\n content: \"\\e324\"; }\n .material-icons.phone_bluetooth_speaker:before {\n content: \"\\e61b\"; }\n .material-icons.phone_callback:before {\n content: \"\\e649\"; }\n .material-icons.phone_disabled:before {\n content: \"\\e9cc\"; }\n .material-icons.phone_enabled:before {\n content: \"\\e9cd\"; }\n .material-icons.phone_forwarded:before {\n content: \"\\e61c\"; }\n .material-icons.phone_in_talk:before {\n content: \"\\e61d\"; }\n .material-icons.phone_iphone:before {\n content: \"\\e325\"; }\n .material-icons.phone_locked:before {\n content: \"\\e61e\"; }\n .material-icons.phone_missed:before {\n content: \"\\e61f\"; }\n .material-icons.phone_paused:before {\n content: \"\\e620\"; }\n .material-icons.phonelink:before {\n content: \"\\e326\"; }\n .material-icons.phonelink_erase:before {\n content: \"\\e0db\"; }\n .material-icons.phonelink_lock:before {\n content: \"\\e0dc\"; }\n .material-icons.phonelink_off:before {\n content: \"\\e327\"; }\n .material-icons.phonelink_ring:before {\n content: \"\\e0dd\"; }\n .material-icons.phonelink_setup:before {\n content: \"\\e0de\"; }\n .material-icons.photo:before {\n content: \"\\e410\"; }\n .material-icons.photo_album:before {\n content: \"\\e411\"; }\n .material-icons.photo_camera:before {\n content: \"\\e412\"; }\n .material-icons.photo_camera_back:before {\n content: \"\\ef68\"; }\n .material-icons.photo_camera_front:before {\n content: \"\\ef69\"; }\n .material-icons.photo_filter:before {\n content: \"\\e43b\"; }\n .material-icons.photo_library:before {\n content: \"\\e413\"; }\n .material-icons.photo_size_select_actual:before {\n content: \"\\e432\"; }\n .material-icons.photo_size_select_large:before {\n content: \"\\e433\"; }\n .material-icons.photo_size_select_small:before {\n content: \"\\e434\"; }\n .material-icons.php:before {\n content: \"\\eb8f\"; }\n .material-icons.piano:before {\n content: \"\\e521\"; }\n .material-icons.piano_off:before {\n content: \"\\e520\"; }\n .material-icons.picture_as_pdf:before {\n content: \"\\e415\"; }\n .material-icons.picture_in_picture:before {\n content: \"\\e8aa\"; }\n .material-icons.picture_in_picture_alt:before {\n content: \"\\e911\"; }\n .material-icons.pie_chart:before {\n content: \"\\e6c4\"; }\n .material-icons.pie_chart_outline:before {\n content: \"\\f044\"; }\n .material-icons.pie_chart_outlined:before {\n content: \"\\e6c5\"; }\n .material-icons.pin:before {\n content: \"\\f045\"; }\n .material-icons.pin_drop:before {\n content: \"\\e55e\"; }\n .material-icons.pin_end:before {\n content: \"\\e767\"; }\n .material-icons.pin_invoke:before {\n content: \"\\e763\"; }\n .material-icons.pinch:before {\n content: \"\\eb38\"; }\n .material-icons.pivot_table_chart:before {\n content: \"\\e9ce\"; }\n .material-icons.pix:before {\n content: \"\\eaa3\"; }\n .material-icons.place:before {\n content: \"\\e55f\"; }\n .material-icons.plagiarism:before {\n content: \"\\ea5a\"; }\n .material-icons.play_arrow:before {\n content: \"\\e037\"; }\n .material-icons.play_circle:before {\n content: \"\\e1c4\"; }\n .material-icons.play_circle_fill:before {\n content: \"\\e038\"; }\n .material-icons.play_circle_filled:before {\n content: \"\\e038\"; }\n .material-icons.play_circle_outline:before {\n content: \"\\e039\"; }\n .material-icons.play_disabled:before {\n content: \"\\ef6a\"; }\n .material-icons.play_for_work:before {\n content: \"\\e906\"; }\n .material-icons.play_lesson:before {\n content: \"\\f047\"; }\n .material-icons.playlist_add:before {\n content: \"\\e03b\"; }\n .material-icons.playlist_add_check:before {\n content: \"\\e065\"; }\n .material-icons.playlist_add_check_circle:before {\n content: \"\\e7e6\"; }\n .material-icons.playlist_add_circle:before {\n content: \"\\e7e5\"; }\n .material-icons.playlist_play:before {\n content: \"\\e05f\"; }\n .material-icons.playlist_remove:before {\n content: \"\\eb80\"; }\n .material-icons.plumbing:before {\n content: \"\\f107\"; }\n .material-icons.plus_one:before {\n content: \"\\e800\"; }\n .material-icons.podcasts:before {\n content: \"\\f048\"; }\n .material-icons.point_of_sale:before {\n content: \"\\f17e\"; }\n .material-icons.policy:before {\n content: \"\\ea17\"; }\n .material-icons.poll:before {\n content: \"\\e801\"; }\n .material-icons.polyline:before {\n content: \"\\ebbb\"; }\n .material-icons.polymer:before {\n content: \"\\e8ab\"; }\n .material-icons.pool:before {\n content: \"\\eb48\"; }\n .material-icons.portable_wifi_off:before {\n content: \"\\e0ce\"; }\n .material-icons.portrait:before {\n content: \"\\e416\"; }\n .material-icons.post_add:before {\n content: \"\\ea20\"; }\n .material-icons.power:before {\n content: \"\\e63c\"; }\n .material-icons.power_input:before {\n content: \"\\e336\"; }\n .material-icons.power_off:before {\n content: \"\\e646\"; }\n .material-icons.power_settings_new:before {\n content: \"\\e8ac\"; }\n .material-icons.precision_manufacturing:before {\n content: \"\\f049\"; }\n .material-icons.pregnant_woman:before {\n content: \"\\e91e\"; }\n .material-icons.present_to_all:before {\n content: \"\\e0df\"; }\n .material-icons.preview:before {\n content: \"\\f1c5\"; }\n .material-icons.price_change:before {\n content: \"\\f04a\"; }\n .material-icons.price_check:before {\n content: \"\\f04b\"; }\n .material-icons.print:before {\n content: \"\\e8ad\"; }\n .material-icons.print_disabled:before {\n content: \"\\e9cf\"; }\n .material-icons.priority_high:before {\n content: \"\\e645\"; }\n .material-icons.privacy_tip:before {\n content: \"\\f0dc\"; }\n .material-icons.private_connectivity:before {\n content: \"\\e744\"; }\n .material-icons.production_quantity_limits:before {\n content: \"\\e1d1\"; }\n .material-icons.propane:before {\n content: \"\\ec14\"; }\n .material-icons.propane_tank:before {\n content: \"\\ec13\"; }\n .material-icons.psychology:before {\n content: \"\\ea4a\"; }\n .material-icons.psychology_alt:before {\n content: \"\\f8ea\"; }\n .material-icons.public:before {\n content: \"\\e80b\"; }\n .material-icons.public_off:before {\n content: \"\\f1ca\"; }\n .material-icons.publish:before {\n content: \"\\e255\"; }\n .material-icons.published_with_changes:before {\n content: \"\\f232\"; }\n .material-icons.punch_clock:before {\n content: \"\\eaa8\"; }\n .material-icons.push_pin:before {\n content: \"\\f10d\"; }\n .material-icons.qr_code:before {\n content: \"\\ef6b\"; }\n .material-icons.qr_code_2:before {\n content: \"\\e00a\"; }\n .material-icons.qr_code_scanner:before {\n content: \"\\f206\"; }\n .material-icons.query_builder:before {\n content: \"\\e8ae\"; }\n .material-icons.query_stats:before {\n content: \"\\e4fc\"; }\n .material-icons.question_answer:before {\n content: \"\\e8af\"; }\n .material-icons.question_mark:before {\n content: \"\\eb8b\"; }\n .material-icons.queue:before {\n content: \"\\e03c\"; }\n .material-icons.queue_music:before {\n content: \"\\e03d\"; }\n .material-icons.queue_play_next:before {\n content: \"\\e066\"; }\n .material-icons.quick_contacts_dialer:before {\n content: \"\\e0cf\"; }\n .material-icons.quick_contacts_mail:before {\n content: \"\\e0d0\"; }\n .material-icons.quickreply:before {\n content: \"\\ef6c\"; }\n .material-icons.quiz:before {\n content: \"\\f04c\"; }\n .material-icons.quora:before {\n content: \"\\ea98\"; }\n .material-icons.r_mobiledata:before {\n content: \"\\f04d\"; }\n .material-icons.radar:before {\n content: \"\\f04e\"; }\n .material-icons.radio:before {\n content: \"\\e03e\"; }\n .material-icons.radio_button_checked:before {\n content: \"\\e837\"; }\n .material-icons.radio_button_off:before {\n content: \"\\e836\"; }\n .material-icons.radio_button_on:before {\n content: \"\\e837\"; }\n .material-icons.radio_button_unchecked:before {\n content: \"\\e836\"; }\n .material-icons.railway_alert:before {\n content: \"\\e9d1\"; }\n .material-icons.ramen_dining:before {\n content: \"\\ea64\"; }\n .material-icons.ramp_left:before {\n content: \"\\eb9c\"; }\n .material-icons.ramp_right:before {\n content: \"\\eb96\"; }\n .material-icons.rate_review:before {\n content: \"\\e560\"; }\n .material-icons.raw_off:before {\n content: \"\\f04f\"; }\n .material-icons.raw_on:before {\n content: \"\\f050\"; }\n .material-icons.read_more:before {\n content: \"\\ef6d\"; }\n .material-icons.real_estate_agent:before {\n content: \"\\e73a\"; }\n .material-icons.receipt:before {\n content: \"\\e8b0\"; }\n .material-icons.receipt_long:before {\n content: \"\\ef6e\"; }\n .material-icons.recent_actors:before {\n content: \"\\e03f\"; }\n .material-icons.recommend:before {\n content: \"\\e9d2\"; }\n .material-icons.record_voice_over:before {\n content: \"\\e91f\"; }\n .material-icons.rectangle:before {\n content: \"\\eb54\"; }\n .material-icons.recycling:before {\n content: \"\\e760\"; }\n .material-icons.reddit:before {\n content: \"\\eaa0\"; }\n .material-icons.redeem:before {\n content: \"\\e8b1\"; }\n .material-icons.redo:before {\n content: \"\\e15a\"; }\n .material-icons.reduce_capacity:before {\n content: \"\\f21c\"; }\n .material-icons.refresh:before {\n content: \"\\e5d5\"; }\n .material-icons.remember_me:before {\n content: \"\\f051\"; }\n .material-icons.remove:before {\n content: \"\\e15b\"; }\n .material-icons.remove_circle:before {\n content: \"\\e15c\"; }\n .material-icons.remove_circle_outline:before {\n content: \"\\e15d\"; }\n .material-icons.remove_done:before {\n content: \"\\e9d3\"; }\n .material-icons.remove_from_queue:before {\n content: \"\\e067\"; }\n .material-icons.remove_moderator:before {\n content: \"\\e9d4\"; }\n .material-icons.remove_red_eye:before {\n content: \"\\e417\"; }\n .material-icons.remove_road:before {\n content: \"\\ebfc\"; }\n .material-icons.remove_shopping_cart:before {\n content: \"\\e928\"; }\n .material-icons.reorder:before {\n content: \"\\e8fe\"; }\n .material-icons.repartition:before {\n content: \"\\f8e8\"; }\n .material-icons.repeat:before {\n content: \"\\e040\"; }\n .material-icons.repeat_on:before {\n content: \"\\e9d6\"; }\n .material-icons.repeat_one:before {\n content: \"\\e041\"; }\n .material-icons.repeat_one_on:before {\n content: \"\\e9d7\"; }\n .material-icons.replay:before {\n content: \"\\e042\"; }\n .material-icons.replay_10:before {\n content: \"\\e059\"; }\n .material-icons.replay_30:before {\n content: \"\\e05a\"; }\n .material-icons.replay_5:before {\n content: \"\\e05b\"; }\n .material-icons.replay_circle_filled:before {\n content: \"\\e9d8\"; }\n .material-icons.reply:before {\n content: \"\\e15e\"; }\n .material-icons.reply_all:before {\n content: \"\\e15f\"; }\n .material-icons.report:before {\n content: \"\\e160\"; }\n .material-icons.report_gmailerrorred:before {\n content: \"\\f052\"; }\n .material-icons.report_off:before {\n content: \"\\e170\"; }\n .material-icons.report_problem:before {\n content: \"\\e8b2\"; }\n .material-icons.request_page:before {\n content: \"\\f22c\"; }\n .material-icons.request_quote:before {\n content: \"\\f1b6\"; }\n .material-icons.reset_tv:before {\n content: \"\\e9d9\"; }\n .material-icons.restart_alt:before {\n content: \"\\f053\"; }\n .material-icons.restaurant:before {\n content: \"\\e56c\"; }\n .material-icons.restaurant_menu:before {\n content: \"\\e561\"; }\n .material-icons.restore:before {\n content: \"\\e8b3\"; }\n .material-icons.restore_from_trash:before {\n content: \"\\e938\"; }\n .material-icons.restore_page:before {\n content: \"\\e929\"; }\n .material-icons.reviews:before {\n content: \"\\f054\"; }\n .material-icons.rice_bowl:before {\n content: \"\\f1f5\"; }\n .material-icons.ring_volume:before {\n content: \"\\e0d1\"; }\n .material-icons.rocket:before {\n content: \"\\eba5\"; }\n .material-icons.rocket_launch:before {\n content: \"\\eb9b\"; }\n .material-icons.roller_shades:before {\n content: \"\\ec12\"; }\n .material-icons.roller_shades_closed:before {\n content: \"\\ec11\"; }\n .material-icons.roller_skating:before {\n content: \"\\ebcd\"; }\n .material-icons.roofing:before {\n content: \"\\f201\"; }\n .material-icons.room:before {\n content: \"\\e8b4\"; }\n .material-icons.room_preferences:before {\n content: \"\\f1b8\"; }\n .material-icons.room_service:before {\n content: \"\\eb49\"; }\n .material-icons.rotate_90_degrees_ccw:before {\n content: \"\\e418\"; }\n .material-icons.rotate_90_degrees_cw:before {\n content: \"\\eaab\"; }\n .material-icons.rotate_left:before {\n content: \"\\e419\"; }\n .material-icons.rotate_right:before {\n content: \"\\e41a\"; }\n .material-icons.roundabout_left:before {\n content: \"\\eb99\"; }\n .material-icons.roundabout_right:before {\n content: \"\\eba3\"; }\n .material-icons.rounded_corner:before {\n content: \"\\e920\"; }\n .material-icons.route:before {\n content: \"\\eacd\"; }\n .material-icons.router:before {\n content: \"\\e328\"; }\n .material-icons.rowing:before {\n content: \"\\e921\"; }\n .material-icons.rss_feed:before {\n content: \"\\e0e5\"; }\n .material-icons.rsvp:before {\n content: \"\\f055\"; }\n .material-icons.rtt:before {\n content: \"\\e9ad\"; }\n .material-icons.rule:before {\n content: \"\\f1c2\"; }\n .material-icons.rule_folder:before {\n content: \"\\f1c9\"; }\n .material-icons.run_circle:before {\n content: \"\\ef6f\"; }\n .material-icons.running_with_errors:before {\n content: \"\\e51d\"; }\n .material-icons.rv_hookup:before {\n content: \"\\e642\"; }\n .material-icons.safety_check:before {\n content: \"\\ebef\"; }\n .material-icons.safety_divider:before {\n content: \"\\e1cc\"; }\n .material-icons.sailing:before {\n content: \"\\e502\"; }\n .material-icons.sanitizer:before {\n content: \"\\f21d\"; }\n .material-icons.satellite:before {\n content: \"\\e562\"; }\n .material-icons.satellite_alt:before {\n content: \"\\eb3a\"; }\n .material-icons.save:before {\n content: \"\\e161\"; }\n .material-icons.save_alt:before {\n content: \"\\e171\"; }\n .material-icons.save_as:before {\n content: \"\\eb60\"; }\n .material-icons.saved_search:before {\n content: \"\\ea11\"; }\n .material-icons.savings:before {\n content: \"\\e2eb\"; }\n .material-icons.scale:before {\n content: \"\\eb5f\"; }\n .material-icons.scanner:before {\n content: \"\\e329\"; }\n .material-icons.scatter_plot:before {\n content: \"\\e268\"; }\n .material-icons.schedule:before {\n content: \"\\e8b5\"; }\n .material-icons.schedule_send:before {\n content: \"\\ea0a\"; }\n .material-icons.schema:before {\n content: \"\\e4fd\"; }\n .material-icons.school:before {\n content: \"\\e80c\"; }\n .material-icons.science:before {\n content: \"\\ea4b\"; }\n .material-icons.score:before {\n content: \"\\e269\"; }\n .material-icons.scoreboard:before {\n content: \"\\ebd0\"; }\n .material-icons.screen_lock_landscape:before {\n content: \"\\e1be\"; }\n .material-icons.screen_lock_portrait:before {\n content: \"\\e1bf\"; }\n .material-icons.screen_lock_rotation:before {\n content: \"\\e1c0\"; }\n .material-icons.screen_rotation:before {\n content: \"\\e1c1\"; }\n .material-icons.screen_rotation_alt:before {\n content: \"\\ebee\"; }\n .material-icons.screen_search_desktop:before {\n content: \"\\ef70\"; }\n .material-icons.screen_share:before {\n content: \"\\e0e2\"; }\n .material-icons.screenshot:before {\n content: \"\\f056\"; }\n .material-icons.screenshot_monitor:before {\n content: \"\\ec08\"; }\n .material-icons.scuba_diving:before {\n content: \"\\ebce\"; }\n .material-icons.sd:before {\n content: \"\\e9dd\"; }\n .material-icons.sd_card:before {\n content: \"\\e623\"; }\n .material-icons.sd_card_alert:before {\n content: \"\\f057\"; }\n .material-icons.sd_storage:before {\n content: \"\\e1c2\"; }\n .material-icons.search:before {\n content: \"\\e8b6\"; }\n .material-icons.search_off:before {\n content: \"\\ea76\"; }\n .material-icons.security:before {\n content: \"\\e32a\"; }\n .material-icons.security_update:before {\n content: \"\\f058\"; }\n .material-icons.security_update_good:before {\n content: \"\\f059\"; }\n .material-icons.security_update_warning:before {\n content: \"\\f05a\"; }\n .material-icons.segment:before {\n content: \"\\e94b\"; }\n .material-icons.select_all:before {\n content: \"\\e162\"; }\n .material-icons.self_improvement:before {\n content: \"\\ea78\"; }\n .material-icons.sell:before {\n content: \"\\f05b\"; }\n .material-icons.send:before {\n content: \"\\e163\"; }\n .material-icons.send_and_archive:before {\n content: \"\\ea0c\"; }\n .material-icons.send_time_extension:before {\n content: \"\\eadb\"; }\n .material-icons.send_to_mobile:before {\n content: \"\\f05c\"; }\n .material-icons.sensor_door:before {\n content: \"\\f1b5\"; }\n .material-icons.sensor_occupied:before {\n content: \"\\ec10\"; }\n .material-icons.sensor_window:before {\n content: \"\\f1b4\"; }\n .material-icons.sensors:before {\n content: \"\\e51e\"; }\n .material-icons.sensors_off:before {\n content: \"\\e51f\"; }\n .material-icons.sentiment_dissatisfied:before {\n content: \"\\e811\"; }\n .material-icons.sentiment_neutral:before {\n content: \"\\e812\"; }\n .material-icons.sentiment_satisfied:before {\n content: \"\\e813\"; }\n .material-icons.sentiment_satisfied_alt:before {\n content: \"\\e0ed\"; }\n .material-icons.sentiment_very_dissatisfied:before {\n content: \"\\e814\"; }\n .material-icons.sentiment_very_satisfied:before {\n content: \"\\e815\"; }\n .material-icons.set_meal:before {\n content: \"\\f1ea\"; }\n .material-icons.settings:before {\n content: \"\\e8b8\"; }\n .material-icons.settings_accessibility:before {\n content: \"\\f05d\"; }\n .material-icons.settings_applications:before {\n content: \"\\e8b9\"; }\n .material-icons.settings_backup_restore:before {\n content: \"\\e8ba\"; }\n .material-icons.settings_bluetooth:before {\n content: \"\\e8bb\"; }\n .material-icons.settings_brightness:before {\n content: \"\\e8bd\"; }\n .material-icons.settings_cell:before {\n content: \"\\e8bc\"; }\n .material-icons.settings_display:before {\n content: \"\\e8bd\"; }\n .material-icons.settings_ethernet:before {\n content: \"\\e8be\"; }\n .material-icons.settings_input_antenna:before {\n content: \"\\e8bf\"; }\n .material-icons.settings_input_component:before {\n content: \"\\e8c0\"; }\n .material-icons.settings_input_composite:before {\n content: \"\\e8c1\"; }\n .material-icons.settings_input_hdmi:before {\n content: \"\\e8c2\"; }\n .material-icons.settings_input_svideo:before {\n content: \"\\e8c3\"; }\n .material-icons.settings_overscan:before {\n content: \"\\e8c4\"; }\n .material-icons.settings_phone:before {\n content: \"\\e8c5\"; }\n .material-icons.settings_power:before {\n content: \"\\e8c6\"; }\n .material-icons.settings_remote:before {\n content: \"\\e8c7\"; }\n .material-icons.settings_suggest:before {\n content: \"\\f05e\"; }\n .material-icons.settings_system_daydream:before {\n content: \"\\e1c3\"; }\n .material-icons.settings_voice:before {\n content: \"\\e8c8\"; }\n .material-icons.severe_cold:before {\n content: \"\\ebd3\"; }\n .material-icons.share:before {\n content: \"\\e80d\"; }\n .material-icons.share_arrival_time:before {\n content: \"\\e524\"; }\n .material-icons.share_location:before {\n content: \"\\f05f\"; }\n .material-icons.shield:before {\n content: \"\\e9e0\"; }\n .material-icons.shield_moon:before {\n content: \"\\eaa9\"; }\n .material-icons.shop:before {\n content: \"\\e8c9\"; }\n .material-icons.shop_2:before {\n content: \"\\e19e\"; }\n .material-icons.shop_two:before {\n content: \"\\e8ca\"; }\n .material-icons.shopify:before {\n content: \"\\ea9d\"; }\n .material-icons.shopping_bag:before {\n content: \"\\f1cc\"; }\n .material-icons.shopping_basket:before {\n content: \"\\e8cb\"; }\n .material-icons.shopping_cart:before {\n content: \"\\e8cc\"; }\n .material-icons.shopping_cart_checkout:before {\n content: \"\\eb88\"; }\n .material-icons.short_text:before {\n content: \"\\e261\"; }\n .material-icons.shortcut:before {\n content: \"\\f060\"; }\n .material-icons.show_chart:before {\n content: \"\\e6e1\"; }\n .material-icons.shower:before {\n content: \"\\f061\"; }\n .material-icons.shuffle:before {\n content: \"\\e043\"; }\n .material-icons.shuffle_on:before {\n content: \"\\e9e1\"; }\n .material-icons.shutter_speed:before {\n content: \"\\e43d\"; }\n .material-icons.sick:before {\n content: \"\\f220\"; }\n .material-icons.sign_language:before {\n content: \"\\ebe5\"; }\n .material-icons.signal_cellular_0_bar:before {\n content: \"\\f0a8\"; }\n .material-icons.signal_cellular_4_bar:before {\n content: \"\\e1c8\"; }\n .material-icons.signal_cellular_alt:before {\n content: \"\\e202\"; }\n .material-icons.signal_cellular_alt_1_bar:before {\n content: \"\\ebdf\"; }\n .material-icons.signal_cellular_alt_2_bar:before {\n content: \"\\ebe3\"; }\n .material-icons.signal_cellular_connected_no_internet_0_bar:before {\n content: \"\\f0ac\"; }\n .material-icons.signal_cellular_connected_no_internet_4_bar:before {\n content: \"\\e1cd\"; }\n .material-icons.signal_cellular_no_sim:before {\n content: \"\\e1ce\"; }\n .material-icons.signal_cellular_nodata:before {\n content: \"\\f062\"; }\n .material-icons.signal_cellular_null:before {\n content: \"\\e1cf\"; }\n .material-icons.signal_cellular_off:before {\n content: \"\\e1d0\"; }\n .material-icons.signal_wifi_0_bar:before {\n content: \"\\f0b0\"; }\n .material-icons.signal_wifi_4_bar:before {\n content: \"\\e1d8\"; }\n .material-icons.signal_wifi_4_bar_lock:before {\n content: \"\\e1d9\"; }\n .material-icons.signal_wifi_bad:before {\n content: \"\\f063\"; }\n .material-icons.signal_wifi_connected_no_internet_4:before {\n content: \"\\f064\"; }\n .material-icons.signal_wifi_off:before {\n content: \"\\e1da\"; }\n .material-icons.signal_wifi_statusbar_4_bar:before {\n content: \"\\f065\"; }\n .material-icons.signal_wifi_statusbar_connected_no_internet_4:before {\n content: \"\\f066\"; }\n .material-icons.signal_wifi_statusbar_null:before {\n content: \"\\f067\"; }\n .material-icons.signpost:before {\n content: \"\\eb91\"; }\n .material-icons.sim_card:before {\n content: \"\\e32b\"; }\n .material-icons.sim_card_alert:before {\n content: \"\\e624\"; }\n .material-icons.sim_card_download:before {\n content: \"\\f068\"; }\n .material-icons.single_bed:before {\n content: \"\\ea48\"; }\n .material-icons.sip:before {\n content: \"\\f069\"; }\n .material-icons.skateboarding:before {\n content: \"\\e511\"; }\n .material-icons.skip_next:before {\n content: \"\\e044\"; }\n .material-icons.skip_previous:before {\n content: \"\\e045\"; }\n .material-icons.sledding:before {\n content: \"\\e512\"; }\n .material-icons.slideshow:before {\n content: \"\\e41b\"; }\n .material-icons.slow_motion_video:before {\n content: \"\\e068\"; }\n .material-icons.smart_button:before {\n content: \"\\f1c1\"; }\n .material-icons.smart_display:before {\n content: \"\\f06a\"; }\n .material-icons.smart_screen:before {\n content: \"\\f06b\"; }\n .material-icons.smart_toy:before {\n content: \"\\f06c\"; }\n .material-icons.smartphone:before {\n content: \"\\e32c\"; }\n .material-icons.smoke_free:before {\n content: \"\\eb4a\"; }\n .material-icons.smoking_rooms:before {\n content: \"\\eb4b\"; }\n .material-icons.sms:before {\n content: \"\\e625\"; }\n .material-icons.sms_failed:before {\n content: \"\\e626\"; }\n .material-icons.snapchat:before {\n content: \"\\ea6e\"; }\n .material-icons.snippet_folder:before {\n content: \"\\f1c7\"; }\n .material-icons.snooze:before {\n content: \"\\e046\"; }\n .material-icons.snowboarding:before {\n content: \"\\e513\"; }\n .material-icons.snowing:before {\n content: \"\\e80f\"; }\n .material-icons.snowmobile:before {\n content: \"\\e503\"; }\n .material-icons.snowshoeing:before {\n content: \"\\e514\"; }\n .material-icons.soap:before {\n content: \"\\f1b2\"; }\n .material-icons.social_distance:before {\n content: \"\\e1cb\"; }\n .material-icons.solar_power:before {\n content: \"\\ec0f\"; }\n .material-icons.sort:before {\n content: \"\\e164\"; }\n .material-icons.sort_by_alpha:before {\n content: \"\\e053\"; }\n .material-icons.sos:before {\n content: \"\\ebf7\"; }\n .material-icons.soup_kitchen:before {\n content: \"\\e7d3\"; }\n .material-icons.source:before {\n content: \"\\f1c4\"; }\n .material-icons.south:before {\n content: \"\\f1e3\"; }\n .material-icons.south_america:before {\n content: \"\\e7e4\"; }\n .material-icons.south_east:before {\n content: \"\\f1e4\"; }\n .material-icons.south_west:before {\n content: \"\\f1e5\"; }\n .material-icons.spa:before {\n content: \"\\eb4c\"; }\n .material-icons.space_bar:before {\n content: \"\\e256\"; }\n .material-icons.space_dashboard:before {\n content: \"\\e66b\"; }\n .material-icons.spatial_audio:before {\n content: \"\\ebeb\"; }\n .material-icons.spatial_audio_off:before {\n content: \"\\ebe8\"; }\n .material-icons.spatial_tracking:before {\n content: \"\\ebea\"; }\n .material-icons.speaker:before {\n content: \"\\e32d\"; }\n .material-icons.speaker_group:before {\n content: \"\\e32e\"; }\n .material-icons.speaker_notes:before {\n content: \"\\e8cd\"; }\n .material-icons.speaker_notes_off:before {\n content: \"\\e92a\"; }\n .material-icons.speaker_phone:before {\n content: \"\\e0d2\"; }\n .material-icons.speed:before {\n content: \"\\e9e4\"; }\n .material-icons.spellcheck:before {\n content: \"\\e8ce\"; }\n .material-icons.splitscreen:before {\n content: \"\\f06d\"; }\n .material-icons.spoke:before {\n content: \"\\e9a7\"; }\n .material-icons.sports:before {\n content: \"\\ea30\"; }\n .material-icons.sports_bar:before {\n content: \"\\f1f3\"; }\n .material-icons.sports_baseball:before {\n content: \"\\ea51\"; }\n .material-icons.sports_basketball:before {\n content: \"\\ea26\"; }\n .material-icons.sports_cricket:before {\n content: \"\\ea27\"; }\n .material-icons.sports_esports:before {\n content: \"\\ea28\"; }\n .material-icons.sports_football:before {\n content: \"\\ea29\"; }\n .material-icons.sports_golf:before {\n content: \"\\ea2a\"; }\n .material-icons.sports_gymnastics:before {\n content: \"\\ebc4\"; }\n .material-icons.sports_handball:before {\n content: \"\\ea33\"; }\n .material-icons.sports_hockey:before {\n content: \"\\ea2b\"; }\n .material-icons.sports_kabaddi:before {\n content: \"\\ea34\"; }\n .material-icons.sports_martial_arts:before {\n content: \"\\eae9\"; }\n .material-icons.sports_mma:before {\n content: \"\\ea2c\"; }\n .material-icons.sports_motorsports:before {\n content: \"\\ea2d\"; }\n .material-icons.sports_rugby:before {\n content: \"\\ea2e\"; }\n .material-icons.sports_score:before {\n content: \"\\f06e\"; }\n .material-icons.sports_soccer:before {\n content: \"\\ea2f\"; }\n .material-icons.sports_tennis:before {\n content: \"\\ea32\"; }\n .material-icons.sports_volleyball:before {\n content: \"\\ea31\"; }\n .material-icons.square:before {\n content: \"\\eb36\"; }\n .material-icons.square_foot:before {\n content: \"\\ea49\"; }\n .material-icons.ssid_chart:before {\n content: \"\\eb66\"; }\n .material-icons.stacked_bar_chart:before {\n content: \"\\e9e6\"; }\n .material-icons.stacked_line_chart:before {\n content: \"\\f22b\"; }\n .material-icons.stadium:before {\n content: \"\\eb90\"; }\n .material-icons.stairs:before {\n content: \"\\f1a9\"; }\n .material-icons.star:before {\n content: \"\\e838\"; }\n .material-icons.star_border:before {\n content: \"\\e83a\"; }\n .material-icons.star_border_purple500:before {\n content: \"\\f099\"; }\n .material-icons.star_half:before {\n content: \"\\e839\"; }\n .material-icons.star_outline:before {\n content: \"\\f06f\"; }\n .material-icons.star_purple500:before {\n content: \"\\f09a\"; }\n .material-icons.star_rate:before {\n content: \"\\f0ec\"; }\n .material-icons.stars:before {\n content: \"\\e8d0\"; }\n .material-icons.start:before {\n content: \"\\e089\"; }\n .material-icons.stay_current_landscape:before {\n content: \"\\e0d3\"; }\n .material-icons.stay_current_portrait:before {\n content: \"\\e0d4\"; }\n .material-icons.stay_primary_landscape:before {\n content: \"\\e0d5\"; }\n .material-icons.stay_primary_portrait:before {\n content: \"\\e0d6\"; }\n .material-icons.sticky_note_2:before {\n content: \"\\f1fc\"; }\n .material-icons.stop:before {\n content: \"\\e047\"; }\n .material-icons.stop_circle:before {\n content: \"\\ef71\"; }\n .material-icons.stop_screen_share:before {\n content: \"\\e0e3\"; }\n .material-icons.storage:before {\n content: \"\\e1db\"; }\n .material-icons.store:before {\n content: \"\\e8d1\"; }\n .material-icons.store_mall_directory:before {\n content: \"\\e563\"; }\n .material-icons.storefront:before {\n content: \"\\ea12\"; }\n .material-icons.storm:before {\n content: \"\\f070\"; }\n .material-icons.straight:before {\n content: \"\\eb95\"; }\n .material-icons.straighten:before {\n content: \"\\e41c\"; }\n .material-icons.stream:before {\n content: \"\\e9e9\"; }\n .material-icons.streetview:before {\n content: \"\\e56e\"; }\n .material-icons.strikethrough_s:before {\n content: \"\\e257\"; }\n .material-icons.stroller:before {\n content: \"\\f1ae\"; }\n .material-icons.style:before {\n content: \"\\e41d\"; }\n .material-icons.subdirectory_arrow_left:before {\n content: \"\\e5d9\"; }\n .material-icons.subdirectory_arrow_right:before {\n content: \"\\e5da\"; }\n .material-icons.subject:before {\n content: \"\\e8d2\"; }\n .material-icons.subscript:before {\n content: \"\\f111\"; }\n .material-icons.subscriptions:before {\n content: \"\\e064\"; }\n .material-icons.subtitles:before {\n content: \"\\e048\"; }\n .material-icons.subtitles_off:before {\n content: \"\\ef72\"; }\n .material-icons.subway:before {\n content: \"\\e56f\"; }\n .material-icons.summarize:before {\n content: \"\\f071\"; }\n .material-icons.sunny:before {\n content: \"\\e81a\"; }\n .material-icons.sunny_snowing:before {\n content: \"\\e819\"; }\n .material-icons.superscript:before {\n content: \"\\f112\"; }\n .material-icons.supervised_user_circle:before {\n content: \"\\e939\"; }\n .material-icons.supervisor_account:before {\n content: \"\\e8d3\"; }\n .material-icons.support:before {\n content: \"\\ef73\"; }\n .material-icons.support_agent:before {\n content: \"\\f0e2\"; }\n .material-icons.surfing:before {\n content: \"\\e515\"; }\n .material-icons.surround_sound:before {\n content: \"\\e049\"; }\n .material-icons.swap_calls:before {\n content: \"\\e0d7\"; }\n .material-icons.swap_horiz:before {\n content: \"\\e8d4\"; }\n .material-icons.swap_horizontal_circle:before {\n content: \"\\e933\"; }\n .material-icons.swap_vert:before {\n content: \"\\e8d5\"; }\n .material-icons.swap_vert_circle:before {\n content: \"\\e8d6\"; }\n .material-icons.swap_vertical_circle:before {\n content: \"\\e8d6\"; }\n .material-icons.swipe:before {\n content: \"\\e9ec\"; }\n .material-icons.swipe_down:before {\n content: \"\\eb53\"; }\n .material-icons.swipe_down_alt:before {\n content: \"\\eb30\"; }\n .material-icons.swipe_left:before {\n content: \"\\eb59\"; }\n .material-icons.swipe_left_alt:before {\n content: \"\\eb33\"; }\n .material-icons.swipe_right:before {\n content: \"\\eb52\"; }\n .material-icons.swipe_right_alt:before {\n content: \"\\eb56\"; }\n .material-icons.swipe_up:before {\n content: \"\\eb2e\"; }\n .material-icons.swipe_up_alt:before {\n content: \"\\eb35\"; }\n .material-icons.swipe_vertical:before {\n content: \"\\eb51\"; }\n .material-icons.switch_access_shortcut:before {\n content: \"\\e7e1\"; }\n .material-icons.switch_access_shortcut_add:before {\n content: \"\\e7e2\"; }\n .material-icons.switch_account:before {\n content: \"\\e9ed\"; }\n .material-icons.switch_camera:before {\n content: \"\\e41e\"; }\n .material-icons.switch_left:before {\n content: \"\\f1d1\"; }\n .material-icons.switch_right:before {\n content: \"\\f1d2\"; }\n .material-icons.switch_video:before {\n content: \"\\e41f\"; }\n .material-icons.synagogue:before {\n content: \"\\eab0\"; }\n .material-icons.sync:before {\n content: \"\\e627\"; }\n .material-icons.sync_alt:before {\n content: \"\\ea18\"; }\n .material-icons.sync_disabled:before {\n content: \"\\e628\"; }\n .material-icons.sync_lock:before {\n content: \"\\eaee\"; }\n .material-icons.sync_problem:before {\n content: \"\\e629\"; }\n .material-icons.system_security_update:before {\n content: \"\\f072\"; }\n .material-icons.system_security_update_good:before {\n content: \"\\f073\"; }\n .material-icons.system_security_update_warning:before {\n content: \"\\f074\"; }\n .material-icons.system_update:before {\n content: \"\\e62a\"; }\n .material-icons.system_update_alt:before {\n content: \"\\e8d7\"; }\n .material-icons.system_update_tv:before {\n content: \"\\e8d7\"; }\n .material-icons.tab:before {\n content: \"\\e8d8\"; }\n .material-icons.tab_unselected:before {\n content: \"\\e8d9\"; }\n .material-icons.table_bar:before {\n content: \"\\ead2\"; }\n .material-icons.table_chart:before {\n content: \"\\e265\"; }\n .material-icons.table_restaurant:before {\n content: \"\\eac6\"; }\n .material-icons.table_rows:before {\n content: \"\\f101\"; }\n .material-icons.table_view:before {\n content: \"\\f1be\"; }\n .material-icons.tablet:before {\n content: \"\\e32f\"; }\n .material-icons.tablet_android:before {\n content: \"\\e330\"; }\n .material-icons.tablet_mac:before {\n content: \"\\e331\"; }\n .material-icons.tag:before {\n content: \"\\e9ef\"; }\n .material-icons.tag_faces:before {\n content: \"\\e420\"; }\n .material-icons.takeout_dining:before {\n content: \"\\ea74\"; }\n .material-icons.tap_and_play:before {\n content: \"\\e62b\"; }\n .material-icons.tapas:before {\n content: \"\\f1e9\"; }\n .material-icons.task:before {\n content: \"\\f075\"; }\n .material-icons.task_alt:before {\n content: \"\\e2e6\"; }\n .material-icons.taxi_alert:before {\n content: \"\\ef74\"; }\n .material-icons.telegram:before {\n content: \"\\ea6b\"; }\n .material-icons.temple_buddhist:before {\n content: \"\\eab3\"; }\n .material-icons.temple_hindu:before {\n content: \"\\eaaf\"; }\n .material-icons.terminal:before {\n content: \"\\eb8e\"; }\n .material-icons.terrain:before {\n content: \"\\e564\"; }\n .material-icons.text_decrease:before {\n content: \"\\eadd\"; }\n .material-icons.text_fields:before {\n content: \"\\e262\"; }\n .material-icons.text_format:before {\n content: \"\\e165\"; }\n .material-icons.text_increase:before {\n content: \"\\eae2\"; }\n .material-icons.text_rotate_up:before {\n content: \"\\e93a\"; }\n .material-icons.text_rotate_vertical:before {\n content: \"\\e93b\"; }\n .material-icons.text_rotation_angledown:before {\n content: \"\\e93c\"; }\n .material-icons.text_rotation_angleup:before {\n content: \"\\e93d\"; }\n .material-icons.text_rotation_down:before {\n content: \"\\e93e\"; }\n .material-icons.text_rotation_none:before {\n content: \"\\e93f\"; }\n .material-icons.text_snippet:before {\n content: \"\\f1c6\"; }\n .material-icons.textsms:before {\n content: \"\\e0d8\"; }\n .material-icons.texture:before {\n content: \"\\e421\"; }\n .material-icons.theater_comedy:before {\n content: \"\\ea66\"; }\n .material-icons.theaters:before {\n content: \"\\e8da\"; }\n .material-icons.thermostat:before {\n content: \"\\f076\"; }\n .material-icons.thermostat_auto:before {\n content: \"\\f077\"; }\n .material-icons.thumb_down:before {\n content: \"\\e8db\"; }\n .material-icons.thumb_down_alt:before {\n content: \"\\e816\"; }\n .material-icons.thumb_down_off_alt:before {\n content: \"\\e9f2\"; }\n .material-icons.thumb_up:before {\n content: \"\\e8dc\"; }\n .material-icons.thumb_up_alt:before {\n content: \"\\e817\"; }\n .material-icons.thumb_up_off_alt:before {\n content: \"\\e9f3\"; }\n .material-icons.thumbs_up_down:before {\n content: \"\\e8dd\"; }\n .material-icons.thunderstorm:before {\n content: \"\\ebdb\"; }\n .material-icons.tiktok:before {\n content: \"\\ea7e\"; }\n .material-icons.time_to_leave:before {\n content: \"\\e62c\"; }\n .material-icons.timelapse:before {\n content: \"\\e422\"; }\n .material-icons.timeline:before {\n content: \"\\e922\"; }\n .material-icons.timer:before {\n content: \"\\e425\"; }\n .material-icons.timer_10:before {\n content: \"\\e423\"; }\n .material-icons.timer_10_select:before {\n content: \"\\f07a\"; }\n .material-icons.timer_3:before {\n content: \"\\e424\"; }\n .material-icons.timer_3_select:before {\n content: \"\\f07b\"; }\n .material-icons.timer_off:before {\n content: \"\\e426\"; }\n .material-icons.tips_and_updates:before {\n content: \"\\e79a\"; }\n .material-icons.tire_repair:before {\n content: \"\\ebc8\"; }\n .material-icons.title:before {\n content: \"\\e264\"; }\n .material-icons.toc:before {\n content: \"\\e8de\"; }\n .material-icons.today:before {\n content: \"\\e8df\"; }\n .material-icons.toggle_off:before {\n content: \"\\e9f5\"; }\n .material-icons.toggle_on:before {\n content: \"\\e9f6\"; }\n .material-icons.token:before {\n content: \"\\ea25\"; }\n .material-icons.toll:before {\n content: \"\\e8e0\"; }\n .material-icons.tonality:before {\n content: \"\\e427\"; }\n .material-icons.topic:before {\n content: \"\\f1c8\"; }\n .material-icons.tornado:before {\n content: \"\\e199\"; }\n .material-icons.touch_app:before {\n content: \"\\e913\"; }\n .material-icons.tour:before {\n content: \"\\ef75\"; }\n .material-icons.toys:before {\n content: \"\\e332\"; }\n .material-icons.track_changes:before {\n content: \"\\e8e1\"; }\n .material-icons.traffic:before {\n content: \"\\e565\"; }\n .material-icons.train:before {\n content: \"\\e570\"; }\n .material-icons.tram:before {\n content: \"\\e571\"; }\n .material-icons.transcribe:before {\n content: \"\\f8ec\"; }\n .material-icons.transfer_within_a_station:before {\n content: \"\\e572\"; }\n .material-icons.transform:before {\n content: \"\\e428\"; }\n .material-icons.transgender:before {\n content: \"\\e58d\"; }\n .material-icons.transit_enterexit:before {\n content: \"\\e579\"; }\n .material-icons.translate:before {\n content: \"\\e8e2\"; }\n .material-icons.travel_explore:before {\n content: \"\\e2db\"; }\n .material-icons.trending_down:before {\n content: \"\\e8e3\"; }\n .material-icons.trending_flat:before {\n content: \"\\e8e4\"; }\n .material-icons.trending_neutral:before {\n content: \"\\e8e4\"; }\n .material-icons.trending_up:before {\n content: \"\\e8e5\"; }\n .material-icons.trip_origin:before {\n content: \"\\e57b\"; }\n .material-icons.troubleshoot:before {\n content: \"\\e1d2\"; }\n .material-icons.try:before {\n content: \"\\f07c\"; }\n .material-icons.tsunami:before {\n content: \"\\ebd8\"; }\n .material-icons.tty:before {\n content: \"\\f1aa\"; }\n .material-icons.tune:before {\n content: \"\\e429\"; }\n .material-icons.tungsten:before {\n content: \"\\f07d\"; }\n .material-icons.turn_left:before {\n content: \"\\eba6\"; }\n .material-icons.turn_right:before {\n content: \"\\ebab\"; }\n .material-icons.turn_sharp_left:before {\n content: \"\\eba7\"; }\n .material-icons.turn_sharp_right:before {\n content: \"\\ebaa\"; }\n .material-icons.turn_slight_left:before {\n content: \"\\eba4\"; }\n .material-icons.turn_slight_right:before {\n content: \"\\eb9a\"; }\n .material-icons.turned_in:before {\n content: \"\\e8e6\"; }\n .material-icons.turned_in_not:before {\n content: \"\\e8e7\"; }\n .material-icons.tv:before {\n content: \"\\e333\"; }\n .material-icons.tv_off:before {\n content: \"\\e647\"; }\n .material-icons.two_wheeler:before {\n content: \"\\e9f9\"; }\n .material-icons.type_specimen:before {\n content: \"\\f8f0\"; }\n .material-icons.u_turn_left:before {\n content: \"\\eba1\"; }\n .material-icons.u_turn_right:before {\n content: \"\\eba2\"; }\n .material-icons.umbrella:before {\n content: \"\\f1ad\"; }\n .material-icons.unarchive:before {\n content: \"\\e169\"; }\n .material-icons.undo:before {\n content: \"\\e166\"; }\n .material-icons.unfold_less:before {\n content: \"\\e5d6\"; }\n .material-icons.unfold_more:before {\n content: \"\\e5d7\"; }\n .material-icons.unpublished:before {\n content: \"\\f236\"; }\n .material-icons.unsubscribe:before {\n content: \"\\e0eb\"; }\n .material-icons.upcoming:before {\n content: \"\\f07e\"; }\n .material-icons.update:before {\n content: \"\\e923\"; }\n .material-icons.update_disabled:before {\n content: \"\\e075\"; }\n .material-icons.upgrade:before {\n content: \"\\f0fb\"; }\n .material-icons.upload:before {\n content: \"\\f09b\"; }\n .material-icons.upload_file:before {\n content: \"\\e9fc\"; }\n .material-icons.usb:before {\n content: \"\\e1e0\"; }\n .material-icons.usb_off:before {\n content: \"\\e4fa\"; }\n .material-icons.vaccines:before {\n content: \"\\e138\"; }\n .material-icons.vape_free:before {\n content: \"\\ebc6\"; }\n .material-icons.vaping_rooms:before {\n content: \"\\ebcf\"; }\n .material-icons.verified:before {\n content: \"\\ef76\"; }\n .material-icons.verified_user:before {\n content: \"\\e8e8\"; }\n .material-icons.vertical_align_bottom:before {\n content: \"\\e258\"; }\n .material-icons.vertical_align_center:before {\n content: \"\\e259\"; }\n .material-icons.vertical_align_top:before {\n content: \"\\e25a\"; }\n .material-icons.vertical_distribute:before {\n content: \"\\e076\"; }\n .material-icons.vertical_shades:before {\n content: \"\\ec0e\"; }\n .material-icons.vertical_shades_closed:before {\n content: \"\\ec0d\"; }\n .material-icons.vertical_split:before {\n content: \"\\e949\"; }\n .material-icons.vibration:before {\n content: \"\\e62d\"; }\n .material-icons.video_call:before {\n content: \"\\e070\"; }\n .material-icons.video_camera_back:before {\n content: \"\\f07f\"; }\n .material-icons.video_camera_front:before {\n content: \"\\f080\"; }\n .material-icons.video_collection:before {\n content: \"\\e04a\"; }\n .material-icons.video_file:before {\n content: \"\\eb87\"; }\n .material-icons.video_label:before {\n content: \"\\e071\"; }\n .material-icons.video_library:before {\n content: \"\\e04a\"; }\n .material-icons.video_settings:before {\n content: \"\\ea75\"; }\n .material-icons.video_stable:before {\n content: \"\\f081\"; }\n .material-icons.videocam:before {\n content: \"\\e04b\"; }\n .material-icons.videocam_off:before {\n content: \"\\e04c\"; }\n .material-icons.videogame_asset:before {\n content: \"\\e338\"; }\n .material-icons.videogame_asset_off:before {\n content: \"\\e500\"; }\n .material-icons.view_agenda:before {\n content: \"\\e8e9\"; }\n .material-icons.view_array:before {\n content: \"\\e8ea\"; }\n .material-icons.view_carousel:before {\n content: \"\\e8eb\"; }\n .material-icons.view_column:before {\n content: \"\\e8ec\"; }\n .material-icons.view_comfortable:before {\n content: \"\\e42a\"; }\n .material-icons.view_comfy:before {\n content: \"\\e42a\"; }\n .material-icons.view_comfy_alt:before {\n content: \"\\eb73\"; }\n .material-icons.view_compact:before {\n content: \"\\e42b\"; }\n .material-icons.view_compact_alt:before {\n content: \"\\eb74\"; }\n .material-icons.view_cozy:before {\n content: \"\\eb75\"; }\n .material-icons.view_day:before {\n content: \"\\e8ed\"; }\n .material-icons.view_headline:before {\n content: \"\\e8ee\"; }\n .material-icons.view_in_ar:before {\n content: \"\\e9fe\"; }\n .material-icons.view_kanban:before {\n content: \"\\eb7f\"; }\n .material-icons.view_list:before {\n content: \"\\e8ef\"; }\n .material-icons.view_module:before {\n content: \"\\e8f0\"; }\n .material-icons.view_quilt:before {\n content: \"\\e8f1\"; }\n .material-icons.view_sidebar:before {\n content: \"\\f114\"; }\n .material-icons.view_stream:before {\n content: \"\\e8f2\"; }\n .material-icons.view_timeline:before {\n content: \"\\eb85\"; }\n .material-icons.view_week:before {\n content: \"\\e8f3\"; }\n .material-icons.vignette:before {\n content: \"\\e435\"; }\n .material-icons.villa:before {\n content: \"\\e586\"; }\n .material-icons.visibility:before {\n content: \"\\e8f4\"; }\n .material-icons.visibility_off:before {\n content: \"\\e8f5\"; }\n .material-icons.voice_chat:before {\n content: \"\\e62e\"; }\n .material-icons.voice_over_off:before {\n content: \"\\e94a\"; }\n .material-icons.voicemail:before {\n content: \"\\e0d9\"; }\n .material-icons.volcano:before {\n content: \"\\ebda\"; }\n .material-icons.volume_down:before {\n content: \"\\e04d\"; }\n .material-icons.volume_down_alt:before {\n content: \"\\e79c\"; }\n .material-icons.volume_mute:before {\n content: \"\\e04e\"; }\n .material-icons.volume_off:before {\n content: \"\\e04f\"; }\n .material-icons.volume_up:before {\n content: \"\\e050\"; }\n .material-icons.volunteer_activism:before {\n content: \"\\ea70\"; }\n .material-icons.vpn_key:before {\n content: \"\\e0da\"; }\n .material-icons.vpn_key_off:before {\n content: \"\\eb7a\"; }\n .material-icons.vpn_lock:before {\n content: \"\\e62f\"; }\n .material-icons.vrpano:before {\n content: \"\\f082\"; }\n .material-icons.wallet:before {\n content: \"\\f8ff\"; }\n .material-icons.wallet_giftcard:before {\n content: \"\\e8f6\"; }\n .material-icons.wallet_membership:before {\n content: \"\\e8f7\"; }\n .material-icons.wallet_travel:before {\n content: \"\\e8f8\"; }\n .material-icons.wallpaper:before {\n content: \"\\e1bc\"; }\n .material-icons.warehouse:before {\n content: \"\\ebb8\"; }\n .material-icons.warning:before {\n content: \"\\e002\"; }\n .material-icons.warning_amber:before {\n content: \"\\f083\"; }\n .material-icons.wash:before {\n content: \"\\f1b1\"; }\n .material-icons.watch:before {\n content: \"\\e334\"; }\n .material-icons.watch_later:before {\n content: \"\\e924\"; }\n .material-icons.watch_off:before {\n content: \"\\eae3\"; }\n .material-icons.water:before {\n content: \"\\f084\"; }\n .material-icons.water_damage:before {\n content: \"\\f203\"; }\n .material-icons.water_drop:before {\n content: \"\\e798\"; }\n .material-icons.waterfall_chart:before {\n content: \"\\ea00\"; }\n .material-icons.waves:before {\n content: \"\\e176\"; }\n .material-icons.waving_hand:before {\n content: \"\\e766\"; }\n .material-icons.wb_auto:before {\n content: \"\\e42c\"; }\n .material-icons.wb_cloudy:before {\n content: \"\\e42d\"; }\n .material-icons.wb_incandescent:before {\n content: \"\\e42e\"; }\n .material-icons.wb_iridescent:before {\n content: \"\\e436\"; }\n .material-icons.wb_shade:before {\n content: \"\\ea01\"; }\n .material-icons.wb_sunny:before {\n content: \"\\e430\"; }\n .material-icons.wb_twighlight:before {\n content: \"\\ea02\"; }\n .material-icons.wb_twilight:before {\n content: \"\\e1c6\"; }\n .material-icons.wc:before {\n content: \"\\e63d\"; }\n .material-icons.web:before {\n content: \"\\e051\"; }\n .material-icons.web_asset:before {\n content: \"\\e069\"; }\n .material-icons.web_asset_off:before {\n content: \"\\e4f7\"; }\n .material-icons.web_stories:before {\n content: \"\\e595\"; }\n .material-icons.webhook:before {\n content: \"\\eb92\"; }\n .material-icons.wechat:before {\n content: \"\\ea81\"; }\n .material-icons.weekend:before {\n content: \"\\e16b\"; }\n .material-icons.west:before {\n content: \"\\f1e6\"; }\n .material-icons.whatsapp:before {\n content: \"\\ea9c\"; }\n .material-icons.whatshot:before {\n content: \"\\e80e\"; }\n .material-icons.wheelchair_pickup:before {\n content: \"\\f1ab\"; }\n .material-icons.where_to_vote:before {\n content: \"\\e177\"; }\n .material-icons.widgets:before {\n content: \"\\e1bd\"; }\n .material-icons.width_full:before {\n content: \"\\f8f5\"; }\n .material-icons.width_normal:before {\n content: \"\\f8f6\"; }\n .material-icons.width_wide:before {\n content: \"\\f8f7\"; }\n .material-icons.wifi:before {\n content: \"\\e63e\"; }\n .material-icons.wifi_1_bar:before {\n content: \"\\e4ca\"; }\n .material-icons.wifi_2_bar:before {\n content: \"\\e4d9\"; }\n .material-icons.wifi_calling:before {\n content: \"\\ef77\"; }\n .material-icons.wifi_calling_3:before {\n content: \"\\f085\"; }\n .material-icons.wifi_channel:before {\n content: \"\\eb6a\"; }\n .material-icons.wifi_find:before {\n content: \"\\eb31\"; }\n .material-icons.wifi_lock:before {\n content: \"\\e1e1\"; }\n .material-icons.wifi_off:before {\n content: \"\\e648\"; }\n .material-icons.wifi_password:before {\n content: \"\\eb6b\"; }\n .material-icons.wifi_protected_setup:before {\n content: \"\\f0fc\"; }\n .material-icons.wifi_tethering:before {\n content: \"\\e1e2\"; }\n .material-icons.wifi_tethering_error:before {\n content: \"\\ead9\"; }\n .material-icons.wifi_tethering_error_rounded:before {\n content: \"\\f086\"; }\n .material-icons.wifi_tethering_off:before {\n content: \"\\f087\"; }\n .material-icons.wind_power:before {\n content: \"\\ec0c\"; }\n .material-icons.window:before {\n content: \"\\f088\"; }\n .material-icons.wine_bar:before {\n content: \"\\f1e8\"; }\n .material-icons.woman:before {\n content: \"\\e13e\"; }\n .material-icons.woo_commerce:before {\n content: \"\\ea6d\"; }\n .material-icons.wordpress:before {\n content: \"\\ea9f\"; }\n .material-icons.work:before {\n content: \"\\e8f9\"; }\n .material-icons.work_history:before {\n content: \"\\ec09\"; }\n .material-icons.work_off:before {\n content: \"\\e942\"; }\n .material-icons.work_outline:before {\n content: \"\\e943\"; }\n .material-icons.workspace_premium:before {\n content: \"\\e7af\"; }\n .material-icons.workspaces:before {\n content: \"\\e1a0\"; }\n .material-icons.workspaces_filled:before {\n content: \"\\ea0d\"; }\n .material-icons.workspaces_outline:before {\n content: \"\\ea0f\"; }\n .material-icons.wrap_text:before {\n content: \"\\e25b\"; }\n .material-icons.wrong_location:before {\n content: \"\\ef78\"; }\n .material-icons.wysiwyg:before {\n content: \"\\f1c3\"; }\n .material-icons.yard:before {\n content: \"\\f089\"; }\n .material-icons.youtube_searched_for:before {\n content: \"\\e8fa\"; }\n .material-icons.zoom_in:before {\n content: \"\\e8ff\"; }\n .material-icons.zoom_in_map:before {\n content: \"\\eb2d\"; }\n .material-icons.zoom_out:before {\n content: \"\\e900\"; }\n .material-icons.zoom_out_map:before {\n content: \"\\e56b\"; }\n\n/*# sourceMappingURL=material-design-icons.css.map */","/*!\n\tLato font.\n*/\n/* Lato (hairline, regular) */\n@font-face {\n font-family: Lato;\n font-weight: 100;\n font-style: normal;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-hairline/lato-hairline.woff2\") format(\"woff2\"), url(\"../fonts/lato-hairline/lato-hairline.woff\") format(\"woff\");\n}\n/* Lato (hairline, italic) */\n@font-face {\n font-family: Lato;\n font-weight: 100;\n font-style: italic;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-hairline-italic/lato-hairline-italic.woff2\") format(\"woff2\"), url(\"../fonts/lato-hairline-italic/lato-hairline-italic.woff\") format(\"woff\");\n}\n/* Lato (thin, regular) */\n@font-face {\n font-family: Lato;\n font-weight: 200;\n font-style: normal;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-thin/lato-thin.woff2\") format(\"woff2\"), url(\"../fonts/lato-thin/lato-thin.woff\") format(\"woff\");\n}\n/* Lato (thin, italic) */\n@font-face {\n font-family: Lato;\n font-weight: 200;\n font-style: italic;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-thin-italic/lato-thin-italic.woff2\") format(\"woff2\"), url(\"../fonts/lato-thin-italic/lato-thin-italic.woff\") format(\"woff\");\n}\n/* Lato (light, regular) */\n@font-face {\n font-family: Lato;\n font-weight: 300;\n font-style: normal;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-light/lato-light.woff2\") format(\"woff2\"), url(\"../fonts/lato-light/lato-light.woff\") format(\"woff\");\n}\n/* Lato (light, italic) */\n@font-face {\n font-family: Lato;\n font-weight: 300;\n font-style: italic;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-light-italic/lato-light-italic.woff2\") format(\"woff2\"), url(\"../fonts/lato-light-italic/lato-light-italic.woff\") format(\"woff\");\n}\n/* Lato (normal, regular) */\n@font-face {\n font-family: Lato;\n font-weight: 400;\n font-style: normal;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-normal/lato-normal.woff2\") format(\"woff2\"), url(\"../fonts/lato-normal/lato-normal.woff\") format(\"woff\");\n}\n/* Lato (normal, italic) */\n@font-face {\n font-family: Lato;\n font-weight: 400;\n font-style: italic;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-normal-italic/lato-normal-italic.woff2\") format(\"woff2\"), url(\"../fonts/lato-normal-italic/lato-normal-italic.woff\") format(\"woff\");\n}\n/* Lato (medium, regular) */\n@font-face {\n font-family: \"Lato Medium\";\n font-weight: 400;\n font-style: normal;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-medium/lato-medium.woff2\") format(\"woff2\"), url(\"../fonts/lato-medium/lato-medium.woff\") format(\"woff\");\n}\n/* Lato (medium, italic) */\n@font-face {\n font-family: \"Lato Medium\";\n font-weight: 400;\n font-style: italic;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-medium-italic/lato-medium-italic.woff2\") format(\"woff2\"), url(\"../fonts/lato-medium-italic/lato-medium-italic.woff\") format(\"woff\");\n}\n/* Lato (semibold, regular) */\n@font-face {\n font-family: Lato;\n font-weight: 500;\n font-style: normal;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-semibold/lato-semibold.woff2\") format(\"woff2\"), url(\"../fonts/lato-semibold/lato-semibold.woff\") format(\"woff\");\n}\n/* Lato (semibold, italic) */\n@font-face {\n font-family: Lato;\n font-weight: 500;\n font-style: italic;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-semibold-italic/lato-semibold-italic.woff2\") format(\"woff2\"), url(\"../fonts/lato-semibold-italic/lato-semibold-italic.woff\") format(\"woff\");\n}\n/* Lato (bold, regular) */\n@font-face {\n font-family: Lato;\n font-weight: 600;\n font-style: normal;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-bold/lato-bold.woff2\") format(\"woff2\"), url(\"../fonts/lato-bold/lato-bold.woff\") format(\"woff\");\n}\n/* Lato (bold, italic) */\n@font-face {\n font-family: Lato;\n font-weight: 600;\n font-style: italic;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-bold-italic/lato-bold-italic.woff2\") format(\"woff2\"), url(\"../fonts/lato-bold-italic/lato-bold-italic.woff\") format(\"woff\");\n}\n/* Lato (heavy, regular) */\n@font-face {\n font-family: Lato;\n font-weight: 800;\n font-style: normal;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-heavy/lato-heavy.woff2\") format(\"woff2\"), url(\"../fonts/lato-heavy/lato-heavy.woff\") format(\"woff\");\n}\n/* Lato (heavy, italic) */\n@font-face {\n font-family: Lato;\n font-weight: 800;\n font-style: italic;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-heavy-italic/lato-heavy-italic.woff2\") format(\"woff2\"), url(\"../fonts/lato-heavy-italic/lato-heavy-italic.woff\") format(\"woff\");\n}\n/* Lato (black, regular) */\n@font-face {\n font-family: Lato;\n font-weight: 900;\n font-style: normal;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-black/lato-black.woff2\") format(\"woff2\"), url(\"../fonts/lato-black/lato-black.woff\") format(\"woff\");\n}\n/* Lato (black, italic) */\n@font-face {\n font-family: Lato;\n font-weight: 900;\n font-style: italic;\n text-rendering: optimizeLegibility;\n src: url(\"../fonts/lato-black-italic/lato-black-italic.woff2\") format(\"woff2\"), url(\"../fonts/lato-black-italic/lato-black-italic.woff\") format(\"woff\");\n}\n","/* Rules for sizing the icon. */\n.material-icons.md-18 { font-size: 18px; }\n.material-icons.md-24 { font-size: 24px; }\n.material-icons.md-36 { font-size: 36px; }\n.material-icons.md-48 { font-size: 48px; }\n\n/* Rules for using icons as black on a light background. */\n.material-icons.md-dark { color: rgb(0 0 0 / 54%); }\n.material-icons.md-dark.md-inactive { color: rgb(0 0 0 / 26%); }\n\n/* Rules for using icons as white on a dark background. */\n.material-icons.md-light { color: rgb(255 255 255 / 100%); }\n.material-icons.md-light.md-inactive { color: rgb(255 255 255 / 30%); }\n","pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#383a42;background:#fafafa}.hljs-comment,.hljs-quote{color:#a0a1a7;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#a626a4}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e45649}.hljs-literal{color:#0184bb}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#50a14f}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#986801}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#4078f2}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#c18401}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}","::selection{color:#fff;background-color:#000}.desktopHide{display:none}.logo{position:fixed;z-index:20;top:.4em;left:.6em}h2,h3,h4{font-family:\"PT Sans\",sans-serif;text-transform:uppercase}p,li,label{color:#666}a{color:#000;font-weight:bold}a.nostyle{text-decoration:none}a:hover,a:focus{text-decoration:none}form fieldset{border:0;padding:0;margin:0}form input[type=text],form input[type=number],select,form input[type=password],form input[type=url],form input[type=email]{border:1px solid #999;padding:.5em 1em;min-width:12em;color:#666}@media screen{select{appearance:none;border-radius:0;background:#fff url(\"../../_global/img/bg-select.png\") no-repeat right center}}.inline .row{display:inline-block;margin-right:.5em}.inline label{min-width:6em}fieldset label{display:inline-block;min-width:12.5em;color:#666}label{margin-right:.5em}form .row{margin-bottom:.5em}form button,input[type=submit]{cursor:pointer;background-color:#000;color:#fff;padding:.5em 1em;display:inline-block;border:1px solid #000}form button:hover,form button:focus,input[type=submit]:hover,input[type=submit]:focus{background-color:#fff;color:#000;transition:all .5s ease}#bookmarklet{cursor:move}h2::after{content:\"\";height:4px;width:20%;background-color:#000;display:block}.links{padding:0;margin:0}.links li{list-style:none;margin:0;padding:0}#links{position:fixed;top:0;width:10em;left:0;text-align:right;background-color:#333;padding-top:9.5em;height:100%;box-shadow:inset -4px 0 20px rgba(0,0,0,.6);z-index:15}#links>li>a{display:block;padding:.5em 2em .5em 1em;color:#fff;position:relative;text-transform:uppercase;text-decoration:none;font-weight:normal;font-family:\"PT Sans\",sans-serif;transition:all .5s ease}#links>li>a:hover,#links>li>a:focus{background-color:#999;color:#000}#links .current::after{content:\"\";width:0;height:0;position:absolute;border:10px solid rgba(0,0,0,0);border-right-color:#eee;right:0;top:50%;margin-top:-10px}#links li:last-child{position:fixed;bottom:1em;width:10em}#links li:last-child a::before{font-size:1.2em;position:relative;top:2px}#main{margin-left:12em;position:relative;z-index:10;padding-right:5%;padding-bottom:1em}#sort{padding:0;list-style-type:none;opacity:.5;display:inline-block}#sort li{display:inline;font-size:.9em}#sort li+li{margin-left:10px}#sort a{padding:2px 2px 0;vertical-align:middle}#sort img{vertical-align:baseline}#sort img :hover{cursor:pointer}#display-mode{float:right;margin-top:10px;margin-bottom:10px;opacity:.5}#listmode{width:16px;display:inline-block;text-decoration:none}#listmode.tablemode{background:url(\"../../_global/img/table.png\") no-repeat bottom}#listmode .listmode{background:url(\"../../_global/img/list.png\") no-repeat bottom}#warning_message{position:fixed;background-color:tomato;z-index:1000;bottom:0;left:0;width:100%;color:#000}#content{margin-top:2em;min-height:30em}footer{text-align:right;position:relative;bottom:0;right:5em;color:#999;font-size:.8em;font-style:italic;z-index:20}footer a{color:#999;font-weight:normal}.list-entries{letter-spacing:-5px}.listmode.entry{width:100%;height:inherit}.card-entry-tags{max-height:2em;overflow-y:hidden;padding:0;margin:0}.card-entry-tags li,.card-entry-tags span{display:inline-block;margin:0 5px;padding:5px 12px;background-color:rgba(0,0,0,.6);border-radius:3px;max-height:2em;overflow:hidden;text-overflow:ellipsis}.card-entry-tags a,.card-entry-labels a{text-decoration:none;font-weight:normal;color:#fff}.nav-panel-add-tag{margin-top:10px}.list-entries+.results{margin-bottom:2em}.reading-time,.created-at{color:#999;font-style:italic;font-weight:normal;font-size:.9em}.estimatedTime small{position:relative;top:-1px}.entry{background-color:#fff;letter-spacing:normal;box-shadow:0 3px 7px rgba(0,0,0,.3);display:inline-block;width:32%;margin-bottom:1.5em;vertical-align:top;margin-right:1%;position:relative;overflow:hidden;padding:1.5em 0 3em;height:440px}.entry img.preview{width:100%;object-fit:cover;height:100%}.entry::before{content:\"\";width:0;height:0;border:10px solid rgba(0,0,0,0);border-bottom-color:#000;position:absolute;bottom:.7em;z-index:10;right:1.5em;transition:all .5s ease}.entry::after{content:\"\";position:absolute;height:7px;width:100%;bottom:0;left:0;background-color:#000;transition:all .5s ease}.entry:hover{box-shadow:0 3px 10px #000}.entry:hover::after{height:40px}.entry:hover::before{bottom:2.3em}.entry:hover h2 a{color:#666}.entry:hover .tools{bottom:0}.entry h2{text-transform:none;margin-bottom:0;line-height:1.2;margin-left:5px}.entry::after{content:none}.entry a{display:block;text-decoration:none;color:#000;word-wrap:break-word;transition:all .5s ease}.entry p{color:#666;font-size:.9em;line-height:1.7;margin:5px 5px auto}.entry h2 a::first-letter{text-transform:uppercase}.entry .tools{position:absolute;bottom:-40px;left:0;background:#000;width:100%;z-index:10;padding-right:.5em;text-align:right;transition:all .5s ease}.entry .tools a{color:#666;text-decoration:none;display:block;padding:.4em}.entry .tools a:hover{color:#fff}.entry .tools li{display:inline-block;margin-top:10px}.entry .tools li:first-child{float:left;font-size:.9em;max-width:calc(100% - 160px);text-overflow:ellipsis;overflow:hidden;white-space:nowrap;max-height:2em;margin-left:10px}.entry .card-entry-labels{position:absolute;top:100px;left:-1em;z-index:90;max-width:50%;padding-left:0}.entry .card-entry-labels li{margin:10px 10px 10px auto;padding:5px 12px 5px 25px;background-color:rgba(0,0,0,.6);border-radius:0 3px 3px 0;color:#fff;cursor:default;max-height:2em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.entry .card-entry-labels li a{color:#fff}.entry:nth-child(3n+1){margin-left:0}.results{letter-spacing:-5px;padding:0 0 .5em}.results>*{display:inline-block;vertical-align:top;letter-spacing:normal;width:50%;text-align:right}div.pagination ul{text-align:right}.nb-results{text-align:left;font-style:italic;color:#999;display:inline-flex}div.pagination ul a{color:#999;text-decoration:none}div.pagination ul a:hover,div.pagination ul a:focus{text-decoration:underline}div.pagination ul>*{display:inline-block;margin-left:.5em}div.pagination ul .prev.disabled,div.pagination ul .next.disabled{display:none}div.pagination ul .current{height:25px;padding:4px 8px;border:1px solid #d5d5d5;text-decoration:none;font-weight:bold;color:#000;background-color:#ccc}.card-tag-form{display:inline-block}.card-tag-form input[type=text]{min-width:20em}.hide,.hidden{display:none}#article{width:70%;margin-bottom:3em;text-align:justify}#article .tags{margin-bottom:1em}#article i{font-style:normal}#article h1{text-align:left}#article h2::after{content:none}#article h2,#article h3,#article h4{text-transform:none}blockquote{border:1px solid #999;background-color:#fff;padding:1em;margin:0}.topPosF{position:fixed;right:20%;bottom:2em;font-size:1.5em}#article_toolbar{margin-bottom:1em}#article_toolbar li{display:inline-block;margin:3px auto}#article_toolbar a{background-color:#000;padding:.3em .5em .2em;color:#fff;text-decoration:none}#article_toolbar a:hover,#article_toolbar a:focus{background-color:#999}#nav-btn-add-tag{cursor:pointer}.shaarli::before{content:\"*\"}.return{text-decoration:none;margin-top:1em;display:block}.return::before{margin-right:.5em}.notags{font-style:italic;color:#999}.icon-feed{background-color:#000;color:#fff;padding:.2em .5em}.icon-feed::before{position:relative;top:2px}.list-tags li{margin-bottom:.5em}.list-tags .icon-feed:hover,.list-tags .icon-feed:focus{background-color:#fff;color:#000;text-decoration:none}.list-tags a{text-decoration:none}.list-tags a:hover,.list-tags a:focus{text-decoration:underline}pre code{font-family:\"Courier New\",Courier,monospace}#filters{position:fixed;width:20%;height:100%;top:0;right:0;background-color:#fff;padding:30px 30px 15px 15px;border-left:1px #333 solid;z-index:12;min-width:300px}#filters form .filter-group{margin:5px}#download-form{position:fixed;width:10%;height:100%;top:0;right:0;background-color:#fff;padding:30px 30px 15px 15px;border-left:1px #333 solid;z-index:12;min-width:200px}#download-form li{display:block;padding:.5em 2em .5em 1em;color:#fff;position:relative;text-transform:uppercase;text-decoration:none;font-weight:400;font-family:\"PT Sans\",sans-serif;transition:all .5s ease}@font-face{font-family:icomoon;src:url(\"~icomoon-free-npm/Font/IcoMoon-Free.ttf\");font-weight:normal;font-style:normal}.material-icons{font-family:\"Material Icons\";font-weight:normal;font-style:normal;font-size:1em;width:1em;height:1em;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:\"liga\"}.material-icons .md-18{font-size:18px}.material-icons .md-24{font-size:24px}.material-icons .md-36{font-size:36px}.material-icons .md-48{font-size:48px}.material-icons .vertical-align-middle{vertical-align:middle !important}.icon span,.icon-image span{position:absolute;top:-9999px}[class^=icon-]::before,[class*=\" icon-\"]::before{font-family:icomoon;speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;letter-spacing:0;font-feature-settings:\"liga\";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-flattr::before{content:\"\"}.icon-mail::before{content:\"\"}.icon-up-open::before{content:\"\"}.icon-star::before{content:\"\"}.icon-check::before{content:\"\"}.icon-link::before{content:\"\"}.icon-reply::before{content:\"\"}.icon-menu::before{content:\"\"}.icon-clock::before{content:\"\"}.icon-twitter::before{content:\"\"}.icon-down-open::before{content:\"\"}.icon-trash::before{content:\"\"}.icon-delete::before{content:\"\"}.icon-power::before{content:\"\"}.icon-arrow-up-thick::before{content:\"\"}.icon-feed::before{content:\"\"}.icon-print::before{content:\"\"}.icon-reload::before{content:\"\"}.icon-price-tags::before{content:\"\"}.icon-eye::before{content:\"\"}.icon-no-eye::before{content:\"\"}.icon-calendar::before{content:\"\"}.icon-time::before{content:\"\"}.icon-image{background:no-repeat center/80%;padding-right:1em !important;padding-left:1em !important}.icon-image--carrot{background-image:url(\"../../_global/img/icons/carrot-icon--white.png\")}.icon-image--diaspora{background-image:url(\"../../_global/img/icons/Diaspora-asterisk.svg\")}.icon-image--unmark{background-image:url(\"../../_global/img/icons/unmark-icon--black.png\")}.icon-image--shaarli{background-image:url(\"../../_global/img/icons/shaarli.png\")}.icon-star.fav::before{color:#fff}.icon-check.archive::before{color:#fff}.login{background-color:#333}.login #main{padding:0;margin:0}.login form{background-color:#fff;padding:1.5em;box-shadow:0 1px 8px rgba(0,0,0,.9);width:20em;position:absolute;top:8em;left:50%;margin-left:-10em}.login .logo{position:absolute;top:2em;left:50%;margin-left:-55px}.popup-form{background:rgba(0,0,0,.5);position:absolute;top:0;left:10em;z-index:20;height:100%;width:100%;margin:0;margin-top:-30% !important;padding:2em;display:none;border-left:1px #eee solid}.popup-form form{background-color:#fff;position:absolute;top:0;left:0;z-index:20;border:10px solid #000;width:400px;height:200px;padding:2em}#bagit-form-form .addurl{margin-left:0}.closeMessage,.close-button{background-color:#000;color:#fff;font-size:1.2em;line-height:1.6;width:1.6em;height:1.6em;text-align:center;text-decoration:none}.closeMessage:hover,.closeMessage:focus,.close-button:hover,.close-button:focus{background-color:#999;color:#000}.close-button--popup{display:inline-block;position:absolute;top:0;right:0;font-size:1.4em}.active-current{background-color:#999}.active-current::after{content:\"\";width:0;height:0;position:absolute;border:10px solid rgba(0,0,0,0);border-right-color:#eee;right:0;top:50%;margin-top:-10px}.opacity03{opacity:.3}.add-to-wallabag-link-after{background-color:#000;color:#fff;padding:0 3px 2px}a.add-to-wallabag-link-after{visibility:hidden;position:absolute;opacity:0;transition-duration:2s;transition-timing-function:ease-out}#article article a:hover+a.add-to-wallabag-link-after,a.add-to-wallabag-link-after:hover{opacity:1;visibility:visible;transition-duration:.3s;transition-timing-function:ease-in}a.add-to-wallabag-link-after::after{content:\"w\"}#add-link-result{font-weight:bold;font-size:.9em}.btn-clickable{cursor:pointer}.messages{text-align:left;width:60%;margin:auto 17%}.messages>*{display:inline-block}.messages .install{text-align:left}.messages .install.error{border:1px solid #c42608;color:#c00 !important;background:#fff0ef}.messages .install.notice{border:1px solid #ebcd41;color:#000;background:#fffcd3}.messages .install.success{border:1px solid #6dc70c;background:#e0fbcc !important}.warning{font-weight:bold;display:block;width:100%}.more-info{font-size:.85em;line-height:1.5;color:#aaa}.more-info a{color:#aaa}@media screen and (max-width: 1050px){.entry{width:49%}.entry:nth-child(3n+1){margin-left:1.5%}.entry:nth-child(2n+1){margin-left:0}}@media screen and (max-width: 900px){#article{width:80%}.topPosF{right:2.5em}}@media screen and (max-width: 700px){.entry{width:100%;margin-left:0}#display-mode{display:none}}@media screen and (max-height: 770px){.menu.users,.menu.internal,.menu.developer{display:none}}@media screen and (max-width: 500px){.entry{width:100%;margin-left:0}body>header{background-color:#333;position:fixed;top:0;width:100%;height:3em;z-index:11}#links li:last-child{position:static;width:auto}#links li:last-child a::before{content:none}.logo{width:1.25em;height:1.25em;left:0;top:0}.login>header{position:static}.login form{width:100%;position:static;margin-left:0}.login .logo{height:auto;top:.5em;width:75px;margin-left:-37.5px}.desktopHide{display:block;position:fixed;z-index:20;top:0;right:0;border:0;width:2.5em;height:2.5em;cursor:pointer;background-color:#999;font-size:1.2em}.desktopHide:hover,.desktopHide:focus{background-color:#fff}#links{display:none;width:100%;height:auto;padding-top:3em}#links.menu--open{display:block}footer{position:static;margin-right:3em}#main{margin-left:1.5em;padding-right:1.5em;position:static;margin-top:3em}.card-entry-labels{display:none}#article_toolbar .topPosF{display:none}#article{width:100%}#article h1{font-size:1.5em}#article_toolbar a{padding:.3em .4em .2em}#display-mode{display:none}.popup-form,#bagit-form,#search-form{left:0;width:100%;border-left:none}.popup-form form,#bagit-form form,#search-form form{width:100%}}@media only print{header h1.logo{display:none}}@media print{body{font-family:serif;background-color:#fff}@page{margin:1cm}img{max-width:100% !important}body>.logo,#article_toolbar,#links,#sort,body>footer,.top_link,div.tools,header div,.messages,.entrie+.results,#article .mbm a,#article-informations{display:none !important}article{border:none !important}.vieworiginal a::after{content:\" (\" attr(href) \")\"}abbr[title]::after{content:\" (\" attr(title) \")\"}.pagination span.current{border-style:dashed}#main{width:100%;margin:0;padding:0}#article{width:100%}}*{box-sizing:border-box}html{font-family:sans-serif;text-size-adjust:100%}body{font-size:1em;line-height:1.5;margin:0}h1:first-child,h2:first-child,h3:first-child,h4:first-child,h5:first-child,h6:first-child,p:first-child,ul:first-child,ol:first-child,dl:first-child{margin-top:0}code,kbd,pre,samp{font-family:monospace,serif}pre{white-space:pre-wrap}.upper{text-transform:uppercase}.bold{font-weight:bold}.inner{margin:0 auto;max-width:61.25em}table,img,figure{max-width:100%;height:auto}iframe{max-width:100%}.fl{float:left}.fr{float:right}table{border-collapse:collapse}figure{margin:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}input[type=search]{appearance:textfield}.dib{display:inline-block;vertical-align:middle}.dnone{display:none}.dtable{display:table}.dtable>*{display:table-row}.dtable>*>*{display:table-cell}.element-invisible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.small{font-size:.8em}.big{font-size:1.2em}.w100{width:100%}.w90{width:90%}.w80{width:80%}.w70{width:70%}.w60{width:60%}.w50{width:50%}.w40{width:40%}.w30{width:30%}.w20{width:20%}.w10{width:10%}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}@media screen{select{appearance:none;border-radius:0}}","::selection {\n color: #fff;\n background-color: #000;\n}\n\n.desktopHide {\n display: none;\n}\n\n.logo {\n position: fixed;\n z-index: 20;\n top: 0.4em;\n left: 0.6em;\n}\n\nh2,\nh3,\nh4 {\n font-family: \"PT Sans\", sans-serif;\n text-transform: uppercase;\n}\n\np,\nli,\nlabel {\n color: #666;\n}\n\na {\n color: #000;\n font-weight: bold;\n\n &.nostyle {\n text-decoration: none;\n }\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n}\n\nform fieldset {\n border: 0;\n padding: 0;\n margin: 0;\n}\n\nform input[type=\"text\"],\nform input[type=\"number\"],\nselect,\nform input[type=\"password\"],\nform input[type=\"url\"],\nform input[type=\"email\"] {\n border: 1px solid #999;\n padding: 0.5em 1em;\n min-width: 12em;\n color: #666;\n}\n\n@media screen {\n select {\n appearance: none;\n border-radius: 0;\n background: #fff url(\"../../_global/img/bg-select.png\") no-repeat right center;\n }\n}\n\n.inline {\n .row {\n display: inline-block;\n margin-right: 0.5em;\n }\n\n label {\n min-width: 6em;\n }\n}\n\nfieldset label {\n display: inline-block;\n min-width: 12.5em;\n color: #666;\n}\n\nlabel {\n margin-right: 0.5em;\n}\n\nform .row {\n margin-bottom: 0.5em;\n}\n\nform button,\ninput[type=\"submit\"] {\n cursor: pointer;\n background-color: #000;\n color: #fff;\n padding: 0.5em 1em;\n display: inline-block;\n border: 1px solid #000;\n}\n\nform button:hover,\nform button:focus,\ninput[type=\"submit\"]:hover,\ninput[type=\"submit\"]:focus {\n background-color: #fff;\n color: #000;\n transition: all 0.5s ease;\n}\n\n#bookmarklet {\n cursor: move;\n}\n\nh2::after {\n content: \"\";\n height: 4px;\n width: 20%;\n background-color: #000;\n display: block;\n}\n\n.links {\n padding: 0;\n margin: 0;\n\n li {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n}\n\n#links {\n position: fixed;\n top: 0;\n width: 10em;\n left: 0;\n text-align: right;\n background-color: #333;\n padding-top: 9.5em;\n height: 100%;\n box-shadow: inset -4px 0 20px rgb(0 0 0 / 60%);\n z-index: 15;\n\n > li > a {\n display: block;\n padding: 0.5em 2em 0.5em 1em;\n color: #fff;\n position: relative;\n text-transform: uppercase;\n text-decoration: none;\n font-weight: normal;\n font-family: \"PT Sans\", sans-serif;\n transition: all 0.5s ease;\n\n &:hover,\n &:focus {\n background-color: #999;\n color: #000;\n }\n }\n\n .current::after {\n content: \"\";\n width: 0;\n height: 0;\n position: absolute;\n border: 10px solid transparent;\n border-right-color: #eee;\n right: 0;\n top: 50%;\n margin-top: -10px;\n }\n\n li:last-child {\n position: fixed;\n bottom: 1em;\n width: 10em;\n\n a::before {\n font-size: 1.2em;\n position: relative;\n top: 2px;\n }\n }\n}\n\n#main {\n margin-left: 12em;\n position: relative;\n z-index: 10;\n padding-right: 5%;\n padding-bottom: 1em;\n}\n\n#sort {\n padding: 0;\n list-style-type: none;\n opacity: 0.5;\n display: inline-block;\n\n li {\n display: inline;\n font-size: 0.9em;\n\n & + li {\n margin-left: 10px;\n }\n }\n\n a {\n padding: 2px 2px 0;\n vertical-align: middle;\n }\n\n img {\n vertical-align: baseline;\n\n :hover {\n cursor: pointer;\n }\n }\n}\n\n#display-mode {\n float: right;\n margin-top: 10px;\n margin-bottom: 10px;\n opacity: 0.5;\n}\n\n#listmode {\n width: 16px;\n display: inline-block;\n text-decoration: none;\n\n &.tablemode {\n background: url(\"../../_global/img/table.png\") no-repeat bottom;\n }\n\n .listmode {\n background: url(\"../../_global/img/list.png\") no-repeat bottom;\n }\n}\n\n#warning_message {\n position: fixed;\n background-color: #ff6347;\n z-index: 1000;\n bottom: 0;\n left: 0;\n width: 100%;\n color: #000;\n}\n","#content {\n margin-top: 2em;\n min-height: 30em;\n}\n\nfooter {\n text-align: right;\n position: relative;\n bottom: 0;\n right: 5em;\n color: #999;\n font-size: 0.8em;\n font-style: italic;\n z-index: 20;\n\n a {\n color: #999;\n font-weight: normal;\n }\n}\n\n.list-entries {\n letter-spacing: -5px;\n}\n\n.listmode.entry {\n width: 100%;\n height: inherit;\n}\n\n.card-entry-tags {\n max-height: 2em;\n overflow-y: hidden;\n padding: 0;\n margin: 0;\n}\n\n.card-entry-tags li,\n.card-entry-tags span {\n display: inline-block;\n margin: 0 5px;\n padding: 5px 12px;\n background-color: rgb(0 0 0 / 60%);\n border-radius: 3px;\n max-height: 2em;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.card-entry-tags a,\n.card-entry-labels a {\n text-decoration: none;\n font-weight: normal;\n color: #fff;\n}\n\n.nav-panel-add-tag {\n margin-top: 10px;\n}\n\n.list-entries + .results {\n margin-bottom: 2em;\n}\n\n.reading-time,\n.created-at {\n color: #999;\n font-style: italic;\n font-weight: normal;\n font-size: 0.9em;\n}\n\n.estimatedTime small {\n position: relative;\n top: -1px;\n}\n\n.entry {\n background-color: #fff;\n letter-spacing: normal;\n box-shadow: 0 3px 7px rgb(0 0 0 / 30%);\n display: inline-block;\n width: 32%;\n margin-bottom: 1.5em;\n vertical-align: top;\n margin-right: 1%;\n position: relative;\n overflow: hidden;\n padding: 1.5em 0 3em;\n height: 440px;\n\n img.preview {\n width: 100%;\n object-fit: cover;\n height: 100%;\n }\n\n &::before {\n content: \"\";\n width: 0;\n height: 0;\n border: 10px solid transparent;\n border-bottom-color: #000;\n position: absolute;\n bottom: 0.7em;\n z-index: 10;\n right: 1.5em;\n transition: all 0.5s ease;\n }\n\n &::after {\n content: \"\";\n position: absolute;\n height: 7px;\n width: 100%;\n bottom: 0;\n left: 0;\n background-color: #000;\n transition: all 0.5s ease;\n }\n\n &:hover {\n box-shadow: 0 3px 10px rgb(0 0 0 / 100%);\n\n &::after {\n height: 40px;\n }\n\n &::before {\n bottom: 2.3em;\n }\n\n h2 a {\n color: #666;\n }\n\n .tools {\n bottom: 0;\n }\n }\n\n h2 {\n text-transform: none;\n margin-bottom: 0;\n line-height: 1.2;\n margin-left: 5px;\n }\n\n &::after {\n content: none;\n }\n\n a {\n display: block;\n text-decoration: none;\n color: #000;\n word-wrap: break-word;\n transition: all 0.5s ease;\n }\n\n p {\n color: #666;\n font-size: 0.9em;\n line-height: 1.7;\n margin: 5px 5px auto;\n }\n\n h2 a::first-letter {\n text-transform: uppercase;\n }\n\n .tools {\n position: absolute;\n bottom: -40px;\n left: 0;\n background: #000;\n width: 100%;\n z-index: 10;\n padding-right: 0.5em;\n text-align: right;\n transition: all 0.5s ease;\n\n a {\n color: #666;\n text-decoration: none;\n display: block;\n padding: 0.4em;\n\n &:hover {\n color: #fff;\n }\n }\n\n li {\n display: inline-block;\n margin-top: 10px;\n }\n\n li:first-child {\n float: left;\n font-size: 0.9em;\n max-width: calc(100% - 40px * 4);\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n max-height: 2em;\n margin-left: 10px;\n }\n }\n\n .card-entry-labels {\n position: absolute;\n top: 100px;\n left: -1em;\n z-index: 90;\n max-width: 50%;\n padding-left: 0;\n\n li {\n margin: 10px 10px 10px auto;\n padding: 5px 12px 5px 25px;\n background-color: rgb(0 0 0 / 60%);\n border-radius: 0 3px 3px 0;\n color: #fff;\n cursor: default;\n max-height: 2em;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n a {\n color: #fff;\n }\n }\n }\n}\n\n.entry:nth-child(3n+1) {\n margin-left: 0;\n}\n\n.results {\n letter-spacing: -5px;\n padding: 0 0 0.5em;\n\n > * {\n display: inline-block;\n vertical-align: top;\n letter-spacing: normal;\n width: 50%;\n text-align: right;\n }\n}\n\ndiv.pagination ul {\n text-align: right;\n}\n\n.nb-results {\n text-align: left;\n font-style: italic;\n color: #999;\n display: inline-flex;\n}\n\ndiv.pagination ul {\n a {\n color: #999;\n text-decoration: none;\n\n &:hover,\n &:focus {\n text-decoration: underline;\n }\n }\n\n > * {\n display: inline-block;\n margin-left: 0.5em;\n }\n\n .prev.disabled,\n .next.disabled {\n display: none;\n }\n\n .current {\n height: 25px;\n padding: 4px 8px;\n border: 1px solid #d5d5d5;\n text-decoration: none;\n font-weight: bold;\n color: #000;\n background-color: #ccc;\n }\n}\n\n.card-tag-form {\n display: inline-block;\n}\n\n.card-tag-form input[type=\"text\"] {\n min-width: 20em;\n}\n\n.hide,\n.hidden {\n display: none;\n}\n","#article {\n width: 70%;\n margin-bottom: 3em;\n text-align: justify;\n\n .tags {\n margin-bottom: 1em;\n }\n\n i {\n font-style: normal;\n }\n\n h1 {\n text-align: left;\n }\n\n h2::after {\n content: none;\n }\n\n h2,\n h3,\n h4 {\n text-transform: none;\n }\n}\n\nblockquote {\n border: 1px solid #999;\n background-color: #fff;\n padding: 1em;\n margin: 0;\n}\n\n.topPosF {\n position: fixed;\n right: 20%;\n bottom: 2em;\n font-size: 1.5em;\n}\n\n#article_toolbar {\n margin-bottom: 1em;\n\n li {\n display: inline-block;\n margin: 3px auto;\n }\n\n a {\n background-color: #000;\n padding: 0.3em 0.5em 0.2em;\n color: #fff;\n text-decoration: none;\n\n &:hover,\n &:focus {\n background-color: #999;\n }\n }\n}\n\n#nav-btn-add-tag {\n cursor: pointer;\n}\n\n.shaarli::before {\n content: \"*\";\n}\n\n.return {\n text-decoration: none;\n margin-top: 1em;\n display: block;\n}\n\n.return::before {\n margin-right: 0.5em;\n}\n\n.notags {\n font-style: italic;\n color: #999;\n}\n\n.icon-feed {\n background-color: #000;\n color: #fff;\n padding: 0.2em 0.5em;\n\n &::before {\n position: relative;\n top: 2px;\n }\n}\n\n.list-tags {\n li {\n margin-bottom: 0.5em;\n }\n\n .icon-feed:hover,\n .icon-feed:focus {\n background-color: #fff;\n color: #000;\n text-decoration: none;\n }\n\n a {\n text-decoration: none;\n\n &:hover,\n &:focus {\n text-decoration: underline;\n }\n }\n}\n\npre code {\n font-family: \"Courier New\", Courier, monospace;\n}\n\n#filters {\n position: fixed;\n width: 20%;\n height: 100%;\n top: 0;\n right: 0;\n background-color: #fff;\n padding: 30px 30px 15px 15px;\n border-left: 1px #333 solid;\n z-index: 12;\n min-width: 300px;\n\n form .filter-group {\n margin: 5px;\n }\n}\n\n#download-form {\n position: fixed;\n width: 10%;\n height: 100%;\n top: 0;\n right: 0;\n background-color: #fff;\n padding: 30px 30px 15px 15px;\n border-left: 1px #333 solid;\n z-index: 12;\n min-width: 200px;\n\n li {\n display: block;\n padding: 0.5em 2em 0.5em 1em;\n color: #fff;\n position: relative;\n text-transform: uppercase;\n text-decoration: none;\n font-weight: 400;\n font-family: \"PT Sans\", sans-serif;\n transition: all 0.5s ease;\n }\n}\n","/* ==========================================================================\n Pictos\n ========================================================================== */\n\n@font-face {\n font-family: icomoon;\n src: url(\"~icomoon-free-npm/Font/IcoMoon-Free.ttf\");\n font-weight: normal;\n font-style: normal;\n}\n\n.material-icons {\n font-family: \"Material Icons\";\n font-weight: normal;\n font-style: normal;\n font-size: 1em; /* Preferred icon size */\n width: 1em;\n height: 1em;\n display: inline-block;\n line-height: 1;\n text-transform: none;\n letter-spacing: normal;\n word-wrap: normal;\n white-space: nowrap;\n direction: ltr;\n\n /* Support for all WebKit browsers. */\n -webkit-font-smoothing: antialiased;\n\n /* Support for Safari and Chrome. */\n text-rendering: optimizeLegibility;\n\n /* Support for Firefox. */\n -moz-osx-font-smoothing: grayscale;\n\n /* Support for IE. */\n font-feature-settings: \"liga\";\n\n .md-18 { font-size: 18px; }\n .md-24 { font-size: 24px; }\n .md-36 { font-size: 36px; }\n .md-48 { font-size: 48px; }\n\n .vertical-align-middle {\n vertical-align: middle !important;\n }\n}\n\n.icon span,\n.icon-image span {\n position: absolute;\n top: -9999px;\n}\n\n[class^=\"icon-\"]::before,\n[class*=\" icon-\"]::before {\n font-family: icomoon;\n speak: none;\n font-style: normal;\n font-weight: normal;\n font-variant: normal;\n text-transform: none;\n line-height: 1;\n\n /* Enable Ligatures ================ */\n letter-spacing: 0;\n font-feature-settings: \"liga\";\n\n /* Better Font Rendering =========== */\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n.icon-flattr::before {\n content: \"\\ead4\";\n}\n\n.icon-mail::before {\n content: \"\\ea86\";\n}\n\n.icon-up-open::before {\n content: \"\\e80b\";\n}\n\n.icon-star::before {\n content: \"\\e9d9\";\n}\n\n.icon-check::before {\n content: \"\\ea10\";\n}\n\n.icon-link::before {\n content: \"\\e9cb\";\n}\n\n.icon-reply::before {\n content: \"\\e806\";\n}\n\n.icon-menu::before {\n content: \"\\e9bd\";\n}\n\n.icon-clock::before {\n content: \"\\e803\";\n}\n\n.icon-twitter::before {\n content: \"\\ea96\";\n}\n\n.icon-down-open::before {\n content: \"\\e809\";\n}\n\n.icon-trash::before {\n content: \"\\e9ac\";\n}\n\n.icon-delete::before {\n content: \"\\ea0d\";\n}\n\n.icon-power::before {\n content: \"\\ea14\";\n}\n\n.icon-arrow-up-thick::before {\n content: \"\\ea3a\";\n}\n\n.icon-feed::before {\n content: \"\\e808\";\n}\n\n.icon-print::before {\n content: \"\\e954\";\n}\n\n.icon-reload::before {\n content: \"\\ea2e\";\n}\n\n.icon-price-tags::before {\n content: \"\\e936\";\n}\n\n.icon-eye::before {\n content: \"\\e9ce\";\n}\n\n.icon-no-eye::before {\n content: \"\\e9d1\";\n}\n\n.icon-calendar::before {\n content: \"\\e953\";\n}\n\n.icon-time::before {\n content: \"\\e952\";\n}\n\n/* .icon-image class, for image-based icons\n ========================================================================== */\n\n.icon-image {\n background: no-repeat center/80%;\n padding-right: 1em !important;\n padding-left: 1em !important;\n}\n\n/* Carrot (http://carrot.org) */\n.icon-image--carrot {\n background-image: url(\"../../_global/img/icons/carrot-icon--white.png\");\n}\n\n/* Diaspora */\n.icon-image--diaspora {\n background-image: url(\"../../_global/img/icons/Diaspora-asterisk.svg\");\n}\n\n/* Unmark.it */\n.icon-image--unmark {\n background-image: url(\"../../_global/img/icons/unmark-icon--black.png\");\n}\n\n/* shaarli */\n.icon-image--shaarli {\n background-image: url(\"../../_global/img/icons/shaarli.png\");\n}\n\n/* ==========================================================================\n Icon selected\n ========================================================================== */\n\n.icon-star.fav::before {\n color: #fff;\n}\n\n.icon-check.archive::before {\n color: #fff;\n}\n",".login {\n background-color: #333;\n\n #main {\n padding: 0;\n margin: 0;\n }\n\n form {\n background-color: #fff;\n padding: 1.5em;\n box-shadow: 0 1px 8px rgb(0 0 0 / 90%);\n width: 20em;\n position: absolute;\n top: 8em;\n left: 50%;\n margin-left: -10em;\n }\n\n .logo {\n position: absolute;\n top: 2em;\n left: 50%;\n margin-left: -55px;\n }\n}\n","/* ==========================================================================\n \"save a link\" related styles\n ========================================================================== */\n\n.popup-form {\n background: rgb(0 0 0 / 50%);\n position: absolute;\n top: 0;\n left: 10em;\n z-index: 20;\n height: 100%;\n width: 100%;\n margin: 0;\n margin-top: -30% !important;\n padding: 2em;\n display: none;\n border-left: 1px #eee solid;\n\n form {\n background-color: #fff;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 20;\n border: 10px solid #000;\n width: 400px;\n height: 200px;\n padding: 2em;\n }\n}\n\n#bagit-form-form .addurl {\n margin-left: 0;\n}\n\n.closeMessage,\n.close-button {\n background-color: #000;\n color: #fff;\n font-size: 1.2em;\n line-height: 1.6;\n width: 1.6em;\n height: 1.6em;\n text-align: center;\n text-decoration: none;\n\n &:hover,\n &:focus {\n background-color: #999;\n color: #000;\n }\n}\n\n.close-button--popup {\n display: inline-block;\n position: absolute;\n top: 0;\n right: 0;\n font-size: 1.4em;\n}\n\n.active-current {\n background-color: #999;\n\n &::after {\n content: \"\";\n width: 0;\n height: 0;\n position: absolute;\n border: 10px solid transparent;\n border-right-color: #eee;\n right: 0;\n top: 50%;\n margin-top: -10px;\n }\n}\n\n.opacity03 {\n opacity: 0.3;\n}\n\n.add-to-wallabag-link-after {\n background-color: #000;\n color: #fff;\n padding: 0 3px 2px;\n}\n\na.add-to-wallabag-link-after {\n visibility: hidden;\n position: absolute;\n opacity: 0;\n transition-duration: 2s;\n transition-timing-function: ease-out;\n}\n\n#article article a:hover + a.add-to-wallabag-link-after,\na.add-to-wallabag-link-after:hover {\n opacity: 1;\n visibility: visible;\n transition-duration: 0.3s;\n transition-timing-function: ease-in;\n}\n\na.add-to-wallabag-link-after::after {\n content: \"w\";\n}\n\n#add-link-result {\n font-weight: bold;\n font-size: 0.9em;\n}\n\n.btn-clickable {\n cursor: pointer;\n}\n","/* ==========================================================================\n Messages\n ========================================================================== */\n\n.messages {\n text-align: left;\n width: 60%;\n margin: auto 17%;\n\n > * {\n display: inline-block;\n }\n\n .install {\n text-align: left;\n\n &.error {\n border: 1px solid #c42608;\n color: #c00 !important;\n background: #fff0ef;\n }\n\n &.notice {\n border: 1px solid #ebcd41;\n color: #000;\n background: #fffcd3;\n }\n\n &.success {\n border: 1px solid #6dc70c;\n background: #e0fbcc !important;\n }\n }\n}\n\n.warning {\n font-weight: bold;\n display: block;\n width: 100%;\n}\n\n.more-info {\n font-size: 0.85em;\n line-height: 1.5;\n color: #aaa;\n\n a {\n color: #aaa;\n }\n}\n","@media screen and (max-width: 1050px) {\n .entry {\n width: 49%;\n }\n\n .entry:nth-child(3n+1) {\n margin-left: 1.5%;\n }\n\n .entry:nth-child(2n+1) {\n margin-left: 0;\n }\n}\n\n@media screen and (max-width: 900px) {\n #article {\n width: 80%;\n }\n\n .topPosF {\n right: 2.5em;\n }\n}\n\n@media screen and (max-width: 700px) {\n .entry {\n width: 100%;\n margin-left: 0;\n }\n\n #display-mode {\n display: none;\n }\n}\n\n@media screen and (max-height: 770px) {\n .menu.users,\n .menu.internal,\n .menu.developer {\n display: none;\n }\n}\n\n@media screen and (max-width: 500px) {\n .entry {\n width: 100%;\n margin-left: 0;\n }\n\n body > header {\n background-color: #333;\n position: fixed;\n top: 0;\n width: 100%;\n height: 3em;\n z-index: 11;\n }\n\n #links li:last-child {\n position: static;\n width: auto;\n }\n\n #links li:last-child a::before {\n content: none;\n }\n\n .logo {\n width: 1.25em;\n height: 1.25em;\n left: 0;\n top: 0;\n }\n\n .login > header {\n position: static;\n }\n\n .login form {\n width: 100%;\n position: static;\n margin-left: 0;\n }\n\n .login .logo {\n height: auto;\n top: 0.5em;\n width: 75px;\n margin-left: -37.5px;\n }\n\n .desktopHide {\n display: block;\n position: fixed;\n z-index: 20;\n top: 0;\n right: 0;\n border: 0;\n width: 2.5em;\n height: 2.5em;\n cursor: pointer;\n background-color: #999;\n font-size: 1.2em;\n }\n\n .desktopHide:hover,\n .desktopHide:focus {\n background-color: #fff;\n }\n\n #links {\n display: none;\n width: 100%;\n height: auto;\n padding-top: 3em;\n }\n\n #links.menu--open {\n display: block;\n }\n\n footer {\n position: static;\n margin-right: 3em;\n }\n\n #main {\n margin-left: 1.5em;\n padding-right: 1.5em;\n position: static;\n margin-top: 3em;\n }\n\n .card-entry-labels {\n display: none;\n }\n\n #article_toolbar .topPosF {\n display: none;\n }\n\n #article {\n width: 100%;\n }\n\n #article h1 {\n font-size: 1.5em;\n }\n\n #article_toolbar a {\n padding: 0.3em 0.4em 0.2em;\n }\n\n #display-mode {\n display: none;\n }\n\n .popup-form,\n #bagit-form,\n #search-form {\n left: 0;\n width: 100%;\n border-left: none;\n }\n\n .popup-form form,\n #bagit-form form,\n #search-form form {\n width: 100%;\n }\n}\n\n@media only print {\n header h1.logo {\n display: none;\n }\n}\n","@media print {\n /* ### Layout ### */\n\n body {\n font-family: serif;\n background-color: #fff;\n }\n\n @page {\n margin: 1cm;\n }\n\n img {\n max-width: 100% !important;\n }\n\n /* ### Content ### */\n\n /* Hide useless blocks */\n body > .logo,\n #article_toolbar,\n #links,\n #sort,\n body > footer,\n .top_link,\n div.tools,\n header div,\n .messages,\n .entrie + .results,\n #article .mbm a,\n #article-informations {\n display: none !important;\n }\n\n article {\n border: none !important;\n }\n\n /* Add URL after links */\n .vieworiginal a::after {\n content: \" (\" attr(href) \")\";\n }\n\n /* Add explanation after abbr */\n abbr[title]::after {\n content: \" (\" attr(title) \")\";\n }\n\n /* Change border on current pager item */\n .pagination span.current {\n border-style: dashed;\n }\n\n #main {\n width: 100%;\n margin: 0;\n padding: 0;\n }\n\n #article {\n width: 100%;\n }\n}\n","/*\n Ratatouille mini Framework css by Thomas LEBEAU\n Base on KNACSS => www.KNACSS.com (2013-10) @author: Raphael Goetter, Alsacreations\n and normalize.css\n*/\n\n* {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif; /* 1 */\n text-size-adjust: 100%; /* 2 */\n}\n\nbody {\n font-size: 1em;\n line-height: 1.5;\n margin: 0;\n}\n\n/* ==========================================================================\n Mise en forme\n ========================================================================== */\n\nh1:first-child,\nh2:first-child,\nh3:first-child,\nh4:first-child,\nh5:first-child,\nh6:first-child,\np:first-child,\nul:first-child,\nol:first-child,\ndl:first-child {\n margin-top: 0;\n}\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, serif;\n}\n\npre {\n white-space: pre-wrap;\n}\n\n.upper {\n text-transform: uppercase;\n}\n\n.bold {\n font-weight: bold;\n}\n\n.inner {\n margin: 0 auto;\n max-width: 61.25em; /* 980px */\n}\n\ntable,\nimg,\nfigure {\n max-width: 100%;\n height: auto;\n}\n\niframe {\n max-width: 100%;\n}\n\n.fl {\n float: left;\n}\n\n.fr {\n float: right;\n}\n\ntable {\n border-collapse: collapse;\n}\n\nfigure {\n margin: 0;\n}\n\nbutton,\ninput,\nselect,\ntextarea {\n font-family: inherit;\n font-size: 100%;\n margin: 0;\n}\n\ninput[type=\"search\"] {\n appearance: textfield;\n}\n\n/* ==========================================================================\n Mise en page\n ========================================================================== */\n\n.dib {\n display: inline-block;\n vertical-align: middle;\n}\n\n.dnone {\n display: none;\n}\n\n.dtable {\n display: table;\n}\n\n.dtable > * {\n display: table-row;\n}\n\n.dtable > * > * {\n display: table-cell;\n}\n\n.element-invisible {\n border: 0;\n clip: rect(0 0 0 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px;\n}\n\n.small {\n font-size: 0.8em;\n}\n\n.big {\n font-size: 1.2em;\n}\n\n/* Width */\n\n.w100 {\n width: 100%;\n}\n\n.w90 {\n width: 90%;\n}\n\n.w80 {\n width: 80%;\n}\n\n.w70 {\n width: 70%;\n}\n\n.w60 {\n width: 60%;\n}\n\n.w50 {\n width: 50%;\n}\n\n.w40 {\n width: 40%;\n}\n\n.w30 {\n width: 30%;\n}\n\n.w20 {\n width: 20%;\n}\n\n.w10 {\n width: 10%;\n}\n\n/* ==========================================================================\n Internet Explorer\n ========================================================================== */\n\n/* IE8 and IE9 */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n/* IE8 and IE9 */\n\naudio,\ncanvas,\nvideo {\n display: inline-block;\n}\n\n@media screen {\n select {\n appearance: none;\n border-radius: 0;\n }\n}\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/web/wallassets/baggy.js b/web/wallassets/baggy.js deleted file mode 100644 index 26cf791be..000000000 --- a/web/wallassets/baggy.js +++ /dev/null @@ -1,2 +0,0 @@ -(()=>{var __webpack_modules__={5641:(e,t,n)=>{"use strict";n(8186)(n(262));var r=n(9731),i=n(9999);t.gV=r.App,n(1849),n(5587),t.notification=n(3612),t.storage=n(4623),t.ui=n(5443);var o=n.g.wgxpath;null!=o&&"function"==typeof o.install&&o.install();var a=n.g.annotator},9731:(e,t,n)=>{"use strict";var r=n(280),i=n(2702).Promise,o=n(1849),a=n(5587),s=n(3612),l=n(1258),c=n(4623);function T(){this.modules=[],this.registry=new l.Registry,this._started=!1,this.registry.registerUtility(s.defaultNotifier,"notifier"),this.include(o.acl),this.include(a.simple),this.include(c.noop)}T.prototype.include=function(e,t){var n=e(t);return"function"==typeof n.configure&&n.configure(this.registry),this.modules.push(n),this},T.prototype.start=function(){if(!this._started){this._started=!0;var e=this,t=this.registry;return this.authz=t.getUtility("authorizationPolicy"),this.ident=t.getUtility("identityPolicy"),this.notify=t.getUtility("notifier"),this.annotations=new c.StorageAdapter(t.getUtility("storage"),(function(){return e.runHook.apply(e,arguments)})),this.runHook("start",[this])}},T.prototype.destroy=function(){return this.runHook("destroy")},T.prototype.runHook=function(e,t){for(var n=[],r=0,o=this.modules.length;r{"use strict";var n;t.acl=function(){var e=new n;return{configure:function(t){t.registerUtility(e,"authorizationPolicy")}}},(n=t.AclAuthzPolicy=function(){}).prototype.permits=function(e,t,n){var r=this.authorizedUserId(n),i=t.permissions;if(i){var o=i[e];if(null==o)return!0;for(var a=0,s=o.length;a{"use strict";var n;t.simple=function(){var e=new n;return{configure:function(t){t.registerUtility(e,"identityPolicy")},beforeAnnotationCreated:function(t){t.user=e.who()}}},n=function(){this.identity=null},t.SimpleIdentityPolicy=n,n.prototype.who=function(){return this.identity}},3612:(e,t,n)=>{"use strict";var r=n(9999),i=r.$,o="info",a={show:"annotator-notice-show",info:"annotator-notice-info",success:"annotator-notice-success",error:"annotator-notice-error"};function s(e,t){null==t&&(t=o);var s=i("
    ")[0],l=!1,c=function(){l||(l=!0,i(s).removeClass(a.show).removeClass(a[t]),setTimeout((function(){i(s).remove()}),500))};return i(s).addClass(a.show).addClass(a[t]).html(r.escapeHtml(e||"")).appendTo(n.g.document.body),i(s).on("click",c),setTimeout(c,5e3),{close:c}}t.banner=s,t.defaultNotifier=s,t.INFO=o,t.SUCCESS="success",t.ERROR="error"},1258:(e,t)=>{"use strict";function n(){this.utilities={}}function r(e){this.name="LookupError",this.message='No utility registered for interface "'+e+'".'}n.prototype.registerUtility=function(e,t){this.utilities[t]=e},n.prototype.getUtility=function(e){var t=this.queryUtility(e);if(null===t)throw new r(e);return t},n.prototype.queryUtility=function(e){var t=this.utilities[e];return null==t?null:t},r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,t.LookupError=r,t.Registry=n},4623:(e,t,n)=>{"use strict";var r,i,o=n(9999),a=o.$,s=o.gettext,l=o.Promise,c=(r=-1,function(){return r+=1});function T(e,t){this.store=e,this.runHook=t}t.debug=function(){function e(e,t){var n=JSON.parse(JSON.stringify(t));console.debug("annotator.storage.debug: "+e,n)}return{create:function(t){return t.id=c(),e("create",t),t},update:function(t){return e("update",t),t},delete:function(t){return e("destroy",t),t},query:function(t){return e("query",t),{results:[],meta:{total:0}}},configure:function(e){e.registerUtility(this,"storage")}}},t.noop=function(){return{create:function(e){return void 0!==e.id&&null!==e.id||(e.id=c()),e},update:function(e){return e},delete:function(e){return e},query:function(){return{results:[]}},configure:function(e){e.registerUtility(this,"storage")}}},t.http=function(e){var t=function(){};null==e&&(e={}),e.onError=e.onError||function(e,n){console.error(e,n),t(e,"error")};var n=new i(e);return{configure:function(e){e.registerUtility(n,"storage")},start:function(e){t=e.notify}}},(i=t.HttpStorage=function e(t){this.options=a.extend(!0,{},e.options,t),this.onError=this.options.onError}).prototype.create=function(e){return this._apiRequest("create",e)},i.prototype.update=function(e){return this._apiRequest("update",e)},i.prototype.delete=function(e){return this._apiRequest("destroy",e)},i.prototype.query=function(e){return this._apiRequest("search",e).then((function(e){var t=e.rows;return delete e.rows,{results:t,meta:e}}))},i.prototype.setHeader=function(e,t){this.options.headers[e]=t},i.prototype._apiRequest=function(e,t){var n=t&&t.id,r=this._urlFor(e,n),i=this._apiRequestOptions(e,t),o=a.ajax(r,i);return o._id=n,o._action=e,o},i.prototype._apiRequestOptions=function(e,t){var n=this._methodFor(e),r=this,i={type:n,dataType:"json",error:function(){r._onError.apply(r,arguments)},headers:this.options.headers};if(!this.options.emulateHTTP||"PUT"!==n&&"DELETE"!==n||(i.headers=a.extend(i.headers,{"X-HTTP-Method-Override":n}),i.type="POST"),"search"===e)return i=a.extend(i,{data:t});var o=t&&JSON.stringify(t);return this.options.emulateJSON?(i.data={json:o},this.options.emulateHTTP&&(i.data._method=n),i):i=a.extend(i,{data:o,contentType:"application/json; charset=utf-8"})},i.prototype._urlFor=function(e,t){null==t&&(t="");var n="";return void 0!==this.options.prefix&&null!==this.options.prefix&&(n=this.options.prefix),n=(n+=this.options.urls[e]).replace(/idAnnotation/,t)},i.prototype._methodFor=function(e){return{create:"POST",update:"PUT",destroy:"DELETE",search:"GET"}[e]},i.prototype._onError=function(e){var t;"function"==typeof this.onError&&(t=400===e.status?s("The annotation store did not understand the request! (Error 400)"):401===e.status?s("You must be logged in to perform this operation! (Error 401)"):403===e.status?s("You don't have permission to perform this operation! (Error 403)"):404===e.status?s("Could not connect to the annotation store! (Error 404)"):500===e.status?s("Internal error in annotation store! (Error 500)"):s("Unknown error while speaking to annotation store!"),this.onError(t,e))},i.options={emulateHTTP:!1,emulateJSON:!1,headers:{},onError:function(e){console.error("API request failed: "+e)},prefix:"/store",urls:{create:"/annotations",update:"/annotations/idAnnotation",destroy:"/annotations/idAnnotation",search:"/search"}},T.prototype.create=function(e){return null==e&&(e={}),this._cycle(e,"create","beforeAnnotationCreated","annotationCreated")},T.prototype.update=function(e){if(void 0===e.id||null===e.id)throw new TypeError("annotation must have an id for update()");return this._cycle(e,"update","beforeAnnotationUpdated","annotationUpdated")},T.prototype.delete=function(e){if(void 0===e.id||null===e.id)throw new TypeError("annotation must have an id for delete()");return this._cycle(e,"delete","beforeAnnotationDeleted","annotationDeleted")},T.prototype.query=function(e){return l.resolve(this.store.query(e))},T.prototype.load=function(e){var t=this;return this.query(e).then((function(e){t.runHook("annotationsLoaded",[e.results])}))},T.prototype._cycle=function(e,t,n,r){var i=this;return this.runHook(n,[e]).then((function(){var n=a.extend(!0,{},e);delete n._local;var r=i.store[t](n);return l.resolve(r)})).then((function(t){for(var n in e)e.hasOwnProperty(n)&&"_local"!==n&&delete e[n];return a.extend(e,t),i.runHook(r,[e]),e}))},t.StorageAdapter=T},5443:(e,t,n)=>{t.main=n(3735).main,n(5107),n(8486),n(3826),n(7930),n(863),n(6996),n(7224),n(4233),n(3553)},5107:(e,t,n)=>{"use strict";var r=n(3553).$,i=n(9999),o=i.$,a=i.gettext,s="annotator-adder",l=r.extend({constructor:function(e){r.call(this,e),this.ignoreMouseup=!1,this.annotation=null,this.onCreate=this.options.onCreate;var t=this;this.element.on("click."+s,"button",(function(e){t._onClick(e)})).on("mousedown."+s,"button",(function(e){t._onMousedown(e)})),this.document=this.element[0].ownerDocument,o(this.document.body).on("mouseup."+s,(function(e){t._onMouseup(e)}))},destroy:function(){this.element.off("."+s),o(this.document.body).off("."+s),r.prototype.destroy.call(this)},load:function(e,t){this.annotation=e,this.show(t)},show:function(e){null!=e&&this.element.css({top:e.top,left:e.left}),r.prototype.show.call(this)},_onMousedown:function(e){e.which>1||(e.preventDefault(),this.ignoreMouseup=!0)},_onMouseup:function(e){e.which>1||this.ignoreMouseup&&e.stopImmediatePropagation()},_onClick:function(e){e.which>1||(e.preventDefault(),this.hide(),this.ignoreMouseup=!1,null!==this.annotation&&"function"==typeof this.onCreate&&this.onCreate(this.annotation,e))}});l.template=['
    ',' ","
    "].join("\n"),l.options={onCreate:null},t.Adder=l},8486:(e,t,n)=>{"use strict";var r,i=n(3553).$,o=n(9999),a=o.$,s=o.gettext,l=o.Promise,c="annotator-editor",T=(r=-1,function(){return r+=1});function u(e){null!=e&&"function"==typeof e.preventDefault&&e.preventDefault()}var Q=t.dragTracker=function(e,t){var n=null,r=!1;function i(e){if(!r&&null!==n){var i={y:e.pageY-n.top,x:e.pageX-n.left},o=!0;"function"==typeof t&&(o=t(i)),!1!==o&&(n={top:e.pageY,left:e.pageX}),r=!0,setTimeout((function(){r=!1}),1e3/60)}}function o(){n=null,a(e.ownerDocument).off("mouseup",o).off("mousemove",i)}function s(t){t.target===e&&(n={top:t.pageY,left:t.pageX},a(e.ownerDocument).on("mouseup",o).on("mousemove",i),t.preventDefault())}return a(e).on("mousedown",s),{destroy:function(){a(e).off("mousedown",s)}}},d=t.resizer=function(e,t,n){var r=a(e);return null==n&&(n={}),Q(t,(function(e){var t=r.height(),i=r.width(),o=function(e){var t=1,r=-1;return"function"==typeof n.invertedX&&n.invertedX()&&(t=-1),"function"==typeof n.invertedY&&n.invertedY()&&(r=1),{x:e.x*t,y:e.y*r}}(e);return Math.abs(o.x)>0&&r.width(i+o.x),Math.abs(o.y)>0&&r.height(t+o.y),r.height()!==t||r.width()!==i}))},p=t.mover=function(e,t){return Q(t,(function(t){a(e).css({top:parseInt(a(e).css("top"),10)+t.y,left:parseInt(a(e).css("left"),10)+t.x})}))},_=t.Editor=i.extend({constructor:function(e){i.call(this,e),this.fields=[],this.annotation={},this.options.defaultFields&&this.addField({type:"textarea",label:s("Comments")+"…",load:function(e,t){a(e).find("textarea").val(t.text||"")},submit:function(e,t){t.text=a(e).find("textarea").val()}});var t=this;this.element.on("submit."+c,"form",(function(e){t._onFormSubmit(e)})).on("click."+c,".annotator-save",(function(e){t._onSaveClick(e)})).on("click."+c,".annotator-cancel",(function(e){t._onCancelClick(e)})).on("mouseover."+c,".annotator-cancel",(function(e){t._onCancelMouseover(e)})).on("keydown."+c,"textarea",(function(e){t._onTextareaKeydown(e)}))},destroy:function(){this.element.off("."+c),i.prototype.destroy.call(this)},show:function(e){null!=e&&this.element.css({top:e.top,left:e.left}),this.element.find(".annotator-save").addClass(this.classes.focus),i.prototype.show.call(this),this.element.find(":input:first").focus(),this._setupDraggables()},load:function(e,t){this.annotation=e;for(var n=0,r=this.fields.length;n');return t.element=r[0],"textarea"===t.type?n=a("",h.noCloneChecked=!!pe.cloneNode(!0).lastChild.defaultValue,pe.innerHTML="",h.option=!!pe.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function be(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&M(e,t)?L.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var ye=/<|&#?\w+;/;function Se(e,t,n,r,i){for(var o,a,s,l,c,T,u=t.createDocumentFragment(),Q=[],d=0,p=e.length;d-1)i&&i.push(o);else if(c=se(o),a=be(u.appendChild(o),"script"),c&&Ee(a),n)for(T=0;o=a[T++];)me.test(o.type||"")&&n.push(o);return u}var Le=/^([^.]*)(?:\.(.+)|)/;function ve(){return!0}function Oe(){return!1}function Ce(e,t){return e===function(){try{return g.activeElement}catch(e){}}()==("focus"===t)}function Ne(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ne(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Oe;else if(!i)return e;return 1===o&&(a=i,i=function(e){return L().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=L.guid++)),e.each((function(){L.event.add(this,t,i,r,n)}))}function Ae(e,t,n){n?(X.set(e,t,!1),L.event.add(e,t,{namespace:!1,handler:function(e){var r,i,o=X.get(this,t);if(1&e.isTrigger&&this[t]){if(o.length)(L.event.special[t]||{}).delegateType&&e.stopPropagation();else if(o=s.call(arguments),X.set(this,t,o),r=n(this,t),this[t](),o!==(i=X.get(this,t))||r?X.set(this,t,!1):i={},o!==i)return e.stopImmediatePropagation(),e.preventDefault(),i&&i.value}else o.length&&(X.set(this,t,{value:L.event.trigger(L.extend(o[0],L.Event.prototype),o.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===X.get(e,t)&&L.event.add(e,t,ve)}L.event={global:{},add:function(e,t,n,r,i){var o,a,s,l,c,T,u,Q,d,p,_,h=X.get(e);if($(e))for(n.handler&&(n=(o=n).handler,i=o.selector),i&&L.find.matchesSelector(ae,i),n.guid||(n.guid=L.guid++),(l=h.events)||(l=h.events=Object.create(null)),(a=h.handle)||(a=h.handle=function(t){return void 0!==L&&L.event.triggered!==t.type?L.event.dispatch.apply(e,arguments):void 0}),c=(t=(t||"").match(k)||[""]).length;c--;)d=_=(s=Le.exec(t[c])||[])[1],p=(s[2]||"").split(".").sort(),d&&(u=L.event.special[d]||{},d=(i?u.delegateType:u.bindType)||d,u=L.event.special[d]||{},T=L.extend({type:d,origType:_,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&L.expr.match.needsContext.test(i),namespace:p.join(".")},o),(Q=l[d])||((Q=l[d]=[]).delegateCount=0,u.setup&&!1!==u.setup.call(e,r,p,a)||e.addEventListener&&e.addEventListener(d,a)),u.add&&(u.add.call(e,T),T.handler.guid||(T.handler.guid=n.guid)),i?Q.splice(Q.delegateCount++,0,T):Q.push(T),L.event.global[d]=!0)},remove:function(e,t,n,r,i){var o,a,s,l,c,T,u,Q,d,p,_,h=X.hasData(e)&&X.get(e);if(h&&(l=h.events)){for(c=(t=(t||"").match(k)||[""]).length;c--;)if(d=_=(s=Le.exec(t[c])||[])[1],p=(s[2]||"").split(".").sort(),d){for(u=L.event.special[d]||{},Q=l[d=(r?u.delegateType:u.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=Q.length;o--;)T=Q[o],!i&&_!==T.origType||n&&n.guid!==T.guid||s&&!s.test(T.namespace)||r&&r!==T.selector&&("**"!==r||!T.selector)||(Q.splice(o,1),T.selector&&Q.delegateCount--,u.remove&&u.remove.call(e,T));a&&!Q.length&&(u.teardown&&!1!==u.teardown.call(e,p,h.handle)||L.removeEvent(e,d,h.handle),delete l[d])}else for(d in l)L.event.remove(e,d+t[c],n,r,!0);L.isEmptyObject(l)&&X.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),l=L.event.fix(e),c=(X.get(this,"events")||Object.create(null))[l.type]||[],T=L.event.special[l.type]||{};for(s[0]=l,t=1;t=1))for(;c!==this;c=c.parentNode||this)if(1===c.nodeType&&("click"!==e.type||!0!==c.disabled)){for(o=[],a={},n=0;n-1:L.find(i,this,null,[c]).length),a[i]&&o.push(r);o.length&&s.push({elem:c,handlers:o})}return c=this,l\s*$/g;function He(e,t){return M(e,"table")&&M(11!==t.nodeType?t:t.firstChild,"tr")&&L(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function we(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function De(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(X.hasData(e)&&(s=X.get(e).events))for(i in X.remove(t,"handle events"),s)for(n=0,r=s[i].length;n1&&"string"==typeof p&&!h.checkClone&&Re.test(p))return e.each((function(i){var o=e.eq(i);_&&(t[0]=p.call(this,i,o.html())),ke(o,t,n,r)}));if(Q&&(o=(i=Se(t,e[0].ownerDocument,!1,e,r)).firstChild,1===i.childNodes.length&&(i=o),o||r)){for(s=(a=L.map(be(i,"script"),Ie)).length;u0&&Ee(a,!l&&be(e,"script")),s},cleanData:function(e){for(var t,n,r,i=L.event.special,o=0;void 0!==(n=e[o]);o++)if($(n)){if(t=n[X.expando]){if(t.events)for(r in t.events)i[r]?L.event.remove(n,r):L.removeEvent(n,r,t.handle);n[X.expando]=void 0}n[J.expando]&&(n[J.expando]=void 0)}}}),L.fn.extend({detach:function(e){return Ve(this,e,!0)},remove:function(e){return Ve(this,e)},text:function(e){return q(this,(function(e){return void 0===e?L.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return ke(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||He(this,e).appendChild(e)}))},prepend:function(){return ke(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=He(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return ke(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return ke(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(L.cleanData(be(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return L.clone(this,e,t)}))},html:function(e){return q(this,(function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Me.test(e)&&!ge[(fe.exec(e)||["",""])[1].toLowerCase()]){e=L.htmlPrefilter(e);try{for(;n=0&&(l+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-l-s-.5))||0),l}function rt(e,t,n){var r=Ue(e),i=(!h.boxSizingReliable()||n)&&"border-box"===L.css(e,"boxSizing",!1,r),o=i,a=Ye(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Fe.test(a)){if(!n)return a;a="auto"}return(!h.boxSizingReliable()&&i||!h.reliableTrDimensions()&&M(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===L.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===L.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+nt(e,t,n||(i?"border":"content"),o,r,a)+"px"}function it(e,t,n,r,i){return new it.prototype.init(e,t,n,r,i)}L.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Ye(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=Z(t),l=Be.test(t),c=e.style;if(l||(t=Ke(s)),a=L.cssHooks[t]||L.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:c[t];"string"===(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=Te(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||l||(n+=i&&i[3]||(L.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(c[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(l?c.setProperty(t,n):c[t]=n))}},css:function(e,t,n,r){var i,o,a,s=Z(t);return Be.test(t)||(t=Ke(s)),(a=L.cssHooks[t]||L.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Ye(e,t,r)),"normal"===i&&t in et&&(i=et[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),L.each(["height","width"],(function(e,t){L.cssHooks[t]={get:function(e,n,r){if(n)return!Xe.test(L.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?rt(e,t,r):Ge(e,Je,(function(){return rt(e,t,r)}))},set:function(e,n,r){var i,o=Ue(e),a=!h.scrollboxSize()&&"absolute"===o.position,s=(a||r)&&"border-box"===L.css(e,"boxSizing",!1,o),l=r?nt(e,t,r,s,o):0;return s&&a&&(l-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-nt(e,t,"border",!1,o)-.5)),l&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=L.css(e,t)),tt(0,n,l)}}})),L.cssHooks.marginLeft=We(h.reliableMarginLeft,(function(e,t){if(t)return(parseFloat(Ye(e,"marginLeft"))||e.getBoundingClientRect().left-Ge(e,{marginLeft:0},(function(){return e.getBoundingClientRect().left})))+"px"})),L.each({margin:"",padding:"",border:"Width"},(function(e,t){L.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(L.cssHooks[e+t].set=tt)})),L.fn.extend({css:function(e,t){return q(this,(function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Ue(e),i=t.length;a1)}}),L.Tween=it,it.prototype={constructor:it,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||L.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(L.cssNumber[n]?"":"px")},cur:function(){var e=it.propHooks[this.prop];return e&&e.get?e.get(this):it.propHooks._default.get(this)},run:function(e){var t,n=it.propHooks[this.prop];return this.options.duration?this.pos=t=L.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):it.propHooks._default.set(this),this}},it.prototype.init.prototype=it.prototype,it.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=L.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){L.fx.step[e.prop]?L.fx.step[e.prop](e):1!==e.elem.nodeType||!L.cssHooks[e.prop]&&null==e.elem.style[Ke(e.prop)]?e.elem[e.prop]=e.now:L.style(e.elem,e.prop,e.now+e.unit)}}},it.propHooks.scrollTop=it.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},L.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},L.fx=it.prototype.init,L.fx.step={};var ot,at,st=/^(?:toggle|show|hide)$/,lt=/queueHooks$/;function ct(){at&&(!1===g.hidden&&r.requestAnimationFrame?r.requestAnimationFrame(ct):r.setTimeout(ct,L.fx.interval),L.fx.tick())}function Tt(){return r.setTimeout((function(){ot=void 0})),ot=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function Qt(e,t,n){for(var r,i=(dt.tweeners[t]||[]).concat(dt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each((function(){L.removeAttr(this,e)}))}}),L.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?L.prop(e,t,n):(1===o&&L.isXMLDoc(e)||(i=L.attrHooks[t.toLowerCase()]||(L.expr.match.bool.test(t)?pt:void 0)),void 0!==n?null===n?void L.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=L.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&M(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(k);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),pt={set:function(e,t,n){return!1===t?L.removeAttr(e,n):e.setAttribute(n,n),n}},L.each(L.expr.match.bool.source.match(/\w+/g),(function(e,t){var n=_t[t]||L.find.attr;_t[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=_t[a],_t[a]=i,i=null!=n(e,t,r)?a:null,_t[a]=o),i}}));var ht=/^(?:input|select|textarea|button)$/i,ft=/^(?:a|area)$/i;function mt(e){return(e.match(k)||[]).join(" ")}function gt(e){return e.getAttribute&&e.getAttribute("class")||""}function bt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(k)||[]}L.fn.extend({prop:function(e,t){return q(this,L.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each((function(){delete this[L.propFix[e]||e]}))}}),L.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&L.isXMLDoc(e)||(t=L.propFix[t]||t,i=L.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=L.find.attr(e,"tabindex");return t?parseInt(t,10):ht.test(e.nodeName)||ft.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),h.optSelected||(L.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),L.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){L.propFix[this.toLowerCase()]=this})),L.fn.extend({addClass:function(e){var t,n,r,i,o,a;return f(e)?this.each((function(t){L(this).addClass(e.call(this,t,gt(this)))})):(t=bt(e)).length?this.each((function(){if(r=gt(this),n=1===this.nodeType&&" "+mt(r)+" "){for(o=0;o-1;)n=n.replace(" "+i+" "," ");a=mt(n),r!==a&&this.setAttribute("class",a)}})):this:this.attr("class","")},toggleClass:function(e,t){var n,r,i,o,a=typeof e,s="string"===a||Array.isArray(e);return f(e)?this.each((function(n){L(this).toggleClass(e.call(this,n,gt(this),t),t)})):"boolean"==typeof t&&s?t?this.addClass(e):this.removeClass(e):(n=bt(e),this.each((function(){if(s)for(o=L(this),i=0;i-1)return!0;return!1}});var Et=/\r/g;L.fn.extend({val:function(e){var t,n,r,i=this[0];return arguments.length?(r=f(e),this.each((function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,L(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=L.map(i,(function(e){return null==e?"":e+""}))),(t=L.valHooks[this.type]||L.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))}))):i?(t=L.valHooks[i.type]||L.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(Et,""):null==n?"":n:void 0}}),L.extend({valHooks:{option:{get:function(e){var t=L.find.attr(e,"value");return null!=t?t:mt(L.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],l=a?o+1:i.length;for(r=o<0?l:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),L.each(["radio","checkbox"],(function(){L.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=L.inArray(L(e).val(),t)>-1}},h.checkOn||(L.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})})),h.focusin="onfocusin"in r;var yt=/^(?:focusinfocus|focusoutblur)$/,St=function(e){e.stopPropagation()};L.extend(L.event,{trigger:function(e,t,n,i){var o,a,s,l,c,T,u,Q,p=[n||g],_=d.call(e,"type")?e.type:e,h=d.call(e,"namespace")?e.namespace.split("."):[];if(a=Q=s=n=n||g,3!==n.nodeType&&8!==n.nodeType&&!yt.test(_+L.event.triggered)&&(_.indexOf(".")>-1&&(h=_.split("."),_=h.shift(),h.sort()),c=_.indexOf(":")<0&&"on"+_,(e=e[L.expando]?e:new L.Event(_,"object"==typeof e&&e)).isTrigger=i?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:L.makeArray(t,[e]),u=L.event.special[_]||{},i||!u.trigger||!1!==u.trigger.apply(n,t))){if(!i&&!u.noBubble&&!m(n)){for(l=u.delegateType||_,yt.test(l+_)||(a=a.parentNode);a;a=a.parentNode)p.push(a),s=a;s===(n.ownerDocument||g)&&p.push(s.defaultView||s.parentWindow||r)}for(o=0;(a=p[o++])&&!e.isPropagationStopped();)Q=a,e.type=o>1?l:u.bindType||_,(T=(X.get(a,"events")||Object.create(null))[e.type]&&X.get(a,"handle"))&&T.apply(a,t),(T=c&&a[c])&&T.apply&&$(a)&&(e.result=T.apply(a,t),!1===e.result&&e.preventDefault());return e.type=_,i||e.isDefaultPrevented()||u._default&&!1!==u._default.apply(p.pop(),t)||!$(n)||c&&f(n[_])&&!m(n)&&((s=n[c])&&(n[c]=null),L.event.triggered=_,e.isPropagationStopped()&&Q.addEventListener(_,St),n[_](),e.isPropagationStopped()&&Q.removeEventListener(_,St),L.event.triggered=void 0,s&&(n[c]=s)),e.result}},simulate:function(e,t,n){var r=L.extend(new L.Event,n,{type:e,isSimulated:!0});L.event.trigger(r,null,t)}}),L.fn.extend({trigger:function(e,t){return this.each((function(){L.event.trigger(e,t,this)}))},triggerHandler:function(e,t){var n=this[0];if(n)return L.event.trigger(e,t,n,!0)}}),h.focusin||L.each({focus:"focusin",blur:"focusout"},(function(e,t){var n=function(e){L.event.simulate(t,e.target,L.event.fix(e))};L.event.special[t]={setup:function(){var r=this.ownerDocument||this.document||this,i=X.access(r,t);i||r.addEventListener(e,n,!0),X.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this.document||this,i=X.access(r,t)-1;i?X.access(r,t,i):(r.removeEventListener(e,n,!0),X.remove(r,t))}}}));var Lt=r.location,vt={guid:Date.now()},Ot=/\?/;L.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new r.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||L.error("Invalid XML: "+(n?L.map(n.childNodes,(function(e){return e.textContent})).join("\n"):e)),t};var Ct=/\[\]$/,Nt=/\r?\n/g,At=/^(?:submit|button|image|reset|file)$/i,Mt=/^(?:input|select|textarea|keygen)/i;function Rt(e,t,n,r){var i;if(Array.isArray(t))L.each(t,(function(t,i){n||Ct.test(e)?r(e,i):Rt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)}));else if(n||"object"!==y(t))r(e,t);else for(i in t)Rt(e+"["+i+"]",t[i],n,r)}L.param=function(e,t){var n,r=[],i=function(e,t){var n=f(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!L.isPlainObject(e))L.each(e,(function(){i(this.name,this.value)}));else for(n in e)Rt(n,e[n],t,i);return r.join("&")},L.fn.extend({serialize:function(){return L.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var e=L.prop(this,"elements");return e?L.makeArray(e):this})).filter((function(){var e=this.type;return this.name&&!L(this).is(":disabled")&&Mt.test(this.nodeName)&&!At.test(e)&&(this.checked||!he.test(e))})).map((function(e,t){var n=L(this).val();return null==n?null:Array.isArray(n)?L.map(n,(function(e){return{name:t.name,value:e.replace(Nt,"\r\n")}})):{name:t.name,value:n.replace(Nt,"\r\n")}})).get()}});var xt=/%20/g,Ht=/#.*$/,It=/([?&])_=[^&]*/,wt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Dt=/^(?:GET|HEAD)$/,Pt=/^\/\//,kt={},Vt={},Ft="*/".concat("*"),Bt=g.createElement("a");function Ut(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(k)||[];if(f(n))for(;r=o[i++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function Gt(e,t,n,r){var i={},o=e===Vt;function a(s){var l;return i[s]=!0,L.each(e[s]||[],(function(e,s){var c=s(t,n,r);return"string"!=typeof c||o||i[c]?o?!(l=c):void 0:(t.dataTypes.unshift(c),a(c),!1)})),l}return a(t.dataTypes[0])||!i["*"]&&a("*")}function jt(e,t){var n,r,i=L.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&L.extend(!0,e,r),e}Bt.href=Lt.href,L.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Lt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Lt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Ft,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":L.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?jt(jt(e,L.ajaxSettings),t):jt(L.ajaxSettings,e)},ajaxPrefilter:Ut(kt),ajaxTransport:Ut(Vt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var n,i,o,a,s,l,c,T,u,Q,d=L.ajaxSetup({},t),p=d.context||d,_=d.context&&(p.nodeType||p.jquery)?L(p):L.event,h=L.Deferred(),f=L.Callbacks("once memory"),m=d.statusCode||{},b={},E={},y="canceled",S={readyState:0,getResponseHeader:function(e){var t;if(c){if(!a)for(a={};t=wt.exec(o);)a[t[1].toLowerCase()+" "]=(a[t[1].toLowerCase()+" "]||[]).concat(t[2]);t=a[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return c?o:null},setRequestHeader:function(e,t){return null==c&&(e=E[e.toLowerCase()]=E[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)S.always(e[S.status]);else for(t in e)m[t]=[m[t],e[t]];return this},abort:function(e){var t=e||y;return n&&n.abort(t),v(0,t),this}};if(h.promise(S),d.url=((e||d.url||Lt.href)+"").replace(Pt,Lt.protocol+"//"),d.type=t.method||t.type||d.method||d.type,d.dataTypes=(d.dataType||"*").toLowerCase().match(k)||[""],null==d.crossDomain){l=g.createElement("a");try{l.href=d.url,l.href=l.href,d.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){d.crossDomain=!0}}if(d.data&&d.processData&&"string"!=typeof d.data&&(d.data=L.param(d.data,d.traditional)),Gt(kt,d,t,S),c)return S;for(u in(T=L.event&&d.global)&&0==L.active++&&L.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!Dt.test(d.type),i=d.url.replace(Ht,""),d.hasContent?d.data&&d.processData&&0===(d.contentType||"").indexOf("application/x-www-form-urlencoded")&&(d.data=d.data.replace(xt,"+")):(Q=d.url.slice(i.length),d.data&&(d.processData||"string"==typeof d.data)&&(i+=(Ot.test(i)?"&":"?")+d.data,delete d.data),!1===d.cache&&(i=i.replace(It,"$1"),Q=(Ot.test(i)?"&":"?")+"_="+vt.guid+++Q),d.url=i+Q),d.ifModified&&(L.lastModified[i]&&S.setRequestHeader("If-Modified-Since",L.lastModified[i]),L.etag[i]&&S.setRequestHeader("If-None-Match",L.etag[i])),(d.data&&d.hasContent&&!1!==d.contentType||t.contentType)&&S.setRequestHeader("Content-Type",d.contentType),S.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+Ft+"; q=0.01":""):d.accepts["*"]),d.headers)S.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(!1===d.beforeSend.call(p,S,d)||c))return S.abort();if(y="abort",f.add(d.complete),S.done(d.success),S.fail(d.error),n=Gt(Vt,d,t,S)){if(S.readyState=1,T&&_.trigger("ajaxSend",[S,d]),c)return S;d.async&&d.timeout>0&&(s=r.setTimeout((function(){S.abort("timeout")}),d.timeout));try{c=!1,n.send(b,v)}catch(e){if(c)throw e;v(-1,e)}}else v(-1,"No Transport");function v(e,t,a,l){var u,Q,g,b,E,y=t;c||(c=!0,s&&r.clearTimeout(s),n=void 0,o=l||"",S.readyState=e>0?4:0,u=e>=200&&e<300||304===e,a&&(b=function(e,t,n){for(var r,i,o,a,s=e.contents,l=e.dataTypes;"*"===l[0];)l.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){l.unshift(i);break}if(l[0]in n)o=l[0];else{for(i in n){if(!l[0]||e.converters[i+" "+l[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==l[0]&&l.unshift(o),n[o]}(d,S,a)),!u&&L.inArray("script",d.dataTypes)>-1&&L.inArray("json",d.dataTypes)<0&&(d.converters["text script"]=function(){}),b=function(e,t,n,r){var i,o,a,s,l,c={},T=e.dataTypes.slice();if(T[1])for(a in e.converters)c[a.toLowerCase()]=e.converters[a];for(o=T.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=T.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(!(a=c[l+" "+o]||c["* "+o]))for(i in c)if((s=i.split(" "))[1]===o&&(a=c[l+" "+s[0]]||c["* "+s[0]])){!0===a?a=c[i]:!0!==c[i]&&(o=s[0],T.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}(d,b,S,u),u?(d.ifModified&&((E=S.getResponseHeader("Last-Modified"))&&(L.lastModified[i]=E),(E=S.getResponseHeader("etag"))&&(L.etag[i]=E)),204===e||"HEAD"===d.type?y="nocontent":304===e?y="notmodified":(y=b.state,Q=b.data,u=!(g=b.error))):(g=y,!e&&y||(y="error",e<0&&(e=0))),S.status=e,S.statusText=(t||y)+"",u?h.resolveWith(p,[Q,y,S]):h.rejectWith(p,[S,y,g]),S.statusCode(m),m=void 0,T&&_.trigger(u?"ajaxSuccess":"ajaxError",[S,d,u?Q:g]),f.fireWith(p,[S,y]),T&&(_.trigger("ajaxComplete",[S,d]),--L.active||L.event.trigger("ajaxStop")))}return S},getJSON:function(e,t,n){return L.get(e,t,n,"json")},getScript:function(e,t){return L.get(e,void 0,t,"script")}}),L.each(["get","post"],(function(e,t){L[t]=function(e,n,r,i){return f(n)&&(i=i||r,r=n,n=void 0),L.ajax(L.extend({url:e,type:t,dataType:i,data:n,success:r},L.isPlainObject(e)&&e))}})),L.ajaxPrefilter((function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")})),L._evalUrl=function(e,t,n){return L.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){L.globalEval(e,t,n)}})},L.fn.extend({wrapAll:function(e){var t;return this[0]&&(f(e)&&(e=e.call(this[0])),t=L(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map((function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e})).append(this)),this},wrapInner:function(e){return f(e)?this.each((function(t){L(this).wrapInner(e.call(this,t))})):this.each((function(){var t=L(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)}))},wrap:function(e){var t=f(e);return this.each((function(n){L(this).wrapAll(t?e.call(this,n):e)}))},unwrap:function(e){return this.parent(e).not("body").each((function(){L(this).replaceWith(this.childNodes)})),this}}),L.expr.pseudos.hidden=function(e){return!L.expr.pseudos.visible(e)},L.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},L.ajaxSettings.xhr=function(){try{return new r.XMLHttpRequest}catch(e){}};var qt={0:200,1223:204},Yt=L.ajaxSettings.xhr();h.cors=!!Yt&&"withCredentials"in Yt,h.ajax=Yt=!!Yt,L.ajaxTransport((function(e){var t,n;if(h.cors||Yt&&!e.crossDomain)return{send:function(i,o){var a,s=e.xhr();if(s.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(a in e.xhrFields)s[a]=e.xhrFields[a];for(a in e.mimeType&&s.overrideMimeType&&s.overrideMimeType(e.mimeType),e.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest"),i)s.setRequestHeader(a,i[a]);t=function(e){return function(){t&&(t=n=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(qt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=t(),n=s.onerror=s.ontimeout=t("error"),void 0!==s.onabort?s.onabort=n:s.onreadystatechange=function(){4===s.readyState&&r.setTimeout((function(){t&&n()}))},t=t("abort");try{s.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}})),L.ajaxPrefilter((function(e){e.crossDomain&&(e.contents.script=!1)})),L.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return L.globalEval(e),e}}}),L.ajaxPrefilter("script",(function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")})),L.ajaxTransport("script",(function(e){var t,n;if(e.crossDomain||e.scriptAttrs)return{send:function(r,i){t=L("