From 116b4de204381de8410c9358f6667447586fb486 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Thu, 5 Apr 2018 21:20:43 -0400 Subject: [PATCH 01/17] Update wiki and CI links due to move from Gitlab --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index e6d9501a..0ff19caa 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,6 @@ Update your anime/manga list on Kitsu.io and MyAnimeList.net [![Build Status](https://travis-ci.org/timw4mail/HummingBirdAnimeClient.svg?branch=master)](https://travis-ci.org/timw4mail/HummingBirdAnimeClient) -[![build status](https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient/badges/develop/build.svg)](https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient/commits/develop) -[![coverage report](https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient/badges/develop/coverage.svg)](https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient/commits/develop) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/timw4mail/HummingBirdAnimeClient/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/timw4mail/HummingBirdAnimeClient/?branch=master) [[Hosted Example](https://list.timshomepage.net)] @@ -58,6 +56,6 @@ Update your anime/manga list on Kitsu.io and MyAnimeList.net ### Server Setup -See the [wiki](https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient/wikis/home) +See the [wiki](https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient/wiki) for more in-depth information From 204313abbfd1bb6c85287ce10ee8e33344ef1ec1 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Wed, 11 Apr 2018 09:26:14 -0400 Subject: [PATCH 02/17] Use more efficient method of combining large sets of data from Kitsu --- src/API/Kitsu/Model.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/API/Kitsu/Model.php b/src/API/Kitsu/Model.php index 3df6f9c4..6d2077f1 100644 --- a/src/API/Kitsu/Model.php +++ b/src/API/Kitsu/Model.php @@ -26,7 +26,6 @@ use Aviat\AnimeClient\API\{ ParallelAPIRequest }; use Aviat\AnimeClient\API\Enum\{ - AnimeWatchingStatus\Title, AnimeWatchingStatus\Kitsu as KitsuWatchingStatus, MangaReadingStatus\Kitsu as KitsuReadingStatus }; @@ -47,7 +46,7 @@ class Model { use ContainerAware; use KitsuTrait; - const LIST_PAGE_SIZE = 100; + protected const LIST_PAGE_SIZE = 100; /** * Class to map anime list items @@ -417,7 +416,7 @@ class Model { * @param array $options * @return array */ - public function getFullAnimeList(array $options = [ + public function getFullRawAnimeList(array $options = [ 'include' => 'anime.mappings' ]): array { @@ -441,10 +440,10 @@ class Model { foreach($responses as $response) { $data = Json::decode($response); - $output = array_merge_recursive($output, $data); + $output[] = $data; } - return $output; + return array_merge_recursive(...$output); } /** @@ -547,7 +546,7 @@ class Model { 'sort' => '-updated_at' ]; - return $this->getFullAnimeList($options); + return $this->getFullRawAnimeList($options); } // ------------------------------------------------------------------------- @@ -680,7 +679,7 @@ class Model { * @param array $options * @return array */ - public function getFullMangaList(array $options = [ + public function getFullRawMangaList(array $options = [ 'include' => 'manga.mappings' ]): array { @@ -704,10 +703,10 @@ class Model { foreach($responses as $response) { $data = Json::decode($response); - $output = array_merge_recursive($output, $data); + $output[] = $data; } - return $output; + return array_merge_recursive(...$output); } /** From f04cc7d1d529f960ccf5126955d5d21755e8246c Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Wed, 8 Aug 2018 10:12:45 -0400 Subject: [PATCH 03/17] Some minor code cleanliness refactoring --- app/views/anime/cover.php | 4 +- app/views/anime/details.php | 2 +- app/views/anime/edit.php | 2 +- app/views/anime/list.php | 14 +- composer.json | 1 + src/API/Enum/AnimeWatchingStatus/Kitsu.php | 2 +- src/API/Enum/AnimeWatchingStatus/MAL.php | 2 +- src/API/Enum/AnimeWatchingStatus/Route.php | 2 +- src/API/Enum/AnimeWatchingStatus/Title.php | 2 +- src/API/Enum/MangaReadingStatus/Kitsu.php | 2 +- src/API/Enum/MangaReadingStatus/MAL.php | 2 +- src/API/Enum/MangaReadingStatus/Route.php | 4 +- src/API/Enum/MangaReadingStatus/Title.php | 4 +- src/API/JsonAPI.php | 2 +- src/API/Kitsu.php | 2 +- src/API/Kitsu/Auth.php | 6 +- src/API/Kitsu/Enum/AnimeAiringStatus.php | 2 +- src/API/Kitsu/KitsuRequestBuilder.php | 2 +- src/API/Kitsu/ListItem.php | 49 ++++--- src/API/Kitsu/Model.php | 37 +++--- .../Transformer/AnimeListTransformer.php | 43 ++++--- .../Kitsu/Transformer/AnimeTransformer.php | 15 ++- .../Transformer/MangaListTransformer.php | 2 +- .../Kitsu/Transformer/MangaTransformer.php | 2 +- src/API/ListItemInterface.php | 5 +- src/API/MAL.php | 2 +- src/API/MAL/ListItem.php | 7 +- src/API/MAL/MALRequestBuilder.php | 2 +- src/API/MAL/Model.php | 7 +- .../MAL/Transformer/AnimeListTransformer.php | 17 ++- .../MAL/Transformer/MangaListTransformer.php | 2 +- src/API/Mapping/AnimeWatchingStatus.php | 2 +- src/API/Mapping/MangaReadingStatus.php | 2 +- src/API/ParallelAPIRequest.php | 8 +- src/API/XML.php | 2 +- src/Command/CacheClear.php | 2 +- src/Command/CachePrime.php | 2 +- src/Command/SyncLists.php | 2 +- src/Controller/Anime.php | 6 +- src/Controller/AnimeCollection.php | 2 +- src/Controller/Character.php | 2 +- src/Controller/Index.php | 2 +- src/Controller/Manga.php | 2 +- src/Controller/MangaCollection.php | 2 +- src/Dispatcher.php | 2 +- src/Helper/Menu.php | 5 +- src/MenuGenerator.php | 2 +- src/Model/API.php | 2 +- src/Model/Anime.php | 19 ++- src/Model/AnimeCollection.php | 2 +- src/Model/Manga.php | 2 +- src/Model/MangaCollection.php | 2 +- src/Types/AbstractType.php | 121 ++++++++++++++++++ src/Types/Anime.php | 40 ++++++ src/Types/AnimeFormItem.php | 26 ++++ src/Types/AnimeFormItemData.php | 30 +++++ src/Types/AnimeListItem.php | 42 ++++++ 57 files changed, 429 insertions(+), 149 deletions(-) create mode 100644 src/Types/AbstractType.php create mode 100644 src/Types/Anime.php create mode 100644 src/Types/AnimeFormItem.php create mode 100644 src/Types/AnimeFormItemData.php create mode 100644 src/Types/AnimeListItem.php diff --git a/app/views/anime/cover.php b/app/views/anime/cover.php index b43dc9d3..b4d52de8 100644 --- a/app/views/anime/cover.php +++ b/app/views/anime/cover.php @@ -24,7 +24,7 @@ " alt="" />
-
html($item['anime']['type']) ?>
+
html($item['anime']['show_type']) ?>
html($item['airing']['status']) ?>
html($item['anime']['age_rating']) ?>
diff --git a/app/views/anime/details.php b/app/views/anime/details.php index eb6e333b..7e6d4fc6 100644 --- a/app/views/anime/details.php +++ b/app/views/anime/details.php @@ -38,7 +38,7 @@
-

+

diff --git a/app/views/anime/edit.php b/app/views/anime/edit.php index 08707720..a9ed6a6b 100644 --- a/app/views/anime/edit.php +++ b/app/views/anime/edit.php @@ -6,7 +6,7 @@ -

html(array_shift($item['anime']['titles'])) ?>

+

html($item['anime']['title']) ?>

html($title) ?>

diff --git a/app/views/anime/list.php b/app/views/anime/list.php index 2f67c626..08172ebd 100644 --- a/app/views/anime/list.php +++ b/app/views/anime/list.php @@ -42,15 +42,15 @@ - + - -
- + +
+ / 10 - + Episodes:
 /  @@ -83,8 +83,8 @@

html($item['notes']) ?>

- - + genres) ?> + genres) ?> diff --git a/composer.json b/composer.json index 82279651..48f5b5ec 100644 --- a/composer.json +++ b/composer.json @@ -39,6 +39,7 @@ "phpmd/phpmd": "^2.4", "phpstan/phpstan": "^0.9.1", "phpunit/phpunit": "^6.0", + "roave/security-advisories": "dev-master", "robmorgan/phinx": "^0.9.1", "sebastian/phpcpd": "^3.0", "spatie/phpunit-snapshot-assertions": "^1.2.0", diff --git a/src/API/Enum/AnimeWatchingStatus/Kitsu.php b/src/API/Enum/AnimeWatchingStatus/Kitsu.php index db3afcca..8bff6591 100644 --- a/src/API/Enum/AnimeWatchingStatus/Kitsu.php +++ b/src/API/Enum/AnimeWatchingStatus/Kitsu.php @@ -21,7 +21,7 @@ use Aviat\Ion\Enum; /** * Possible values for watching status for the current anime */ -class Kitsu extends Enum { +final class Kitsu extends Enum { const WATCHING = 'current'; const PLAN_TO_WATCH = 'planned'; const ON_HOLD = 'on_hold'; diff --git a/src/API/Enum/AnimeWatchingStatus/MAL.php b/src/API/Enum/AnimeWatchingStatus/MAL.php index b9d17c53..8d26bb72 100644 --- a/src/API/Enum/AnimeWatchingStatus/MAL.php +++ b/src/API/Enum/AnimeWatchingStatus/MAL.php @@ -21,7 +21,7 @@ use Aviat\Ion\Enum; /** * Possible values for watching status for the current anime */ -class MAL extends Enum { +final class MAL extends Enum { const WATCHING = 1; const COMPLETED = 2; const ON_HOLD = 3; diff --git a/src/API/Enum/AnimeWatchingStatus/Route.php b/src/API/Enum/AnimeWatchingStatus/Route.php index 4f834c55..05998b54 100644 --- a/src/API/Enum/AnimeWatchingStatus/Route.php +++ b/src/API/Enum/AnimeWatchingStatus/Route.php @@ -21,7 +21,7 @@ use Aviat\Ion\Enum as Enum; /** * Possible values for current watching status of anime */ -class Route extends Enum { +final class Route extends Enum { const ALL = 'all'; const WATCHING = 'watching'; const PLAN_TO_WATCH = 'plan_to_watch'; diff --git a/src/API/Enum/AnimeWatchingStatus/Title.php b/src/API/Enum/AnimeWatchingStatus/Title.php index ef3241cb..5a93d437 100644 --- a/src/API/Enum/AnimeWatchingStatus/Title.php +++ b/src/API/Enum/AnimeWatchingStatus/Title.php @@ -21,7 +21,7 @@ use Aviat\Ion\Enum as Enum; /** * Possible values for current watching status of anime */ -class Title extends Enum { +final class Title extends Enum { const ALL = 'All'; const WATCHING = 'Currently Watching'; const PLAN_TO_WATCH = 'Plan to Watch'; diff --git a/src/API/Enum/MangaReadingStatus/Kitsu.php b/src/API/Enum/MangaReadingStatus/Kitsu.php index 2c5f3d74..f7c157dc 100644 --- a/src/API/Enum/MangaReadingStatus/Kitsu.php +++ b/src/API/Enum/MangaReadingStatus/Kitsu.php @@ -21,7 +21,7 @@ use Aviat\Ion\Enum; /** * Possible values for current reading status of manga */ -class Kitsu extends Enum { +final class Kitsu extends Enum { const READING = 'current'; const PLAN_TO_READ = 'planned'; const DROPPED = 'dropped'; diff --git a/src/API/Enum/MangaReadingStatus/MAL.php b/src/API/Enum/MangaReadingStatus/MAL.php index 9fe1f767..469de135 100644 --- a/src/API/Enum/MangaReadingStatus/MAL.php +++ b/src/API/Enum/MangaReadingStatus/MAL.php @@ -21,7 +21,7 @@ use Aviat\Ion\Enum; /** * Possible values for watching status for the current anime */ -class MAL extends Enum { +final class MAL extends Enum { const READING = 'reading'; const COMPLETED = 'completed'; const ON_HOLD = 'onhold'; diff --git a/src/API/Enum/MangaReadingStatus/Route.php b/src/API/Enum/MangaReadingStatus/Route.php index f33f7ad1..ecd54366 100644 --- a/src/API/Enum/MangaReadingStatus/Route.php +++ b/src/API/Enum/MangaReadingStatus/Route.php @@ -16,12 +16,12 @@ namespace Aviat\AnimeClient\API\Enum\MangaReadingStatus; -use Aviat\Ion\Enum as Enum; +use Aviat\Ion\Enum; /** * Possible values for current reading status of manga */ -class Route extends Enum { +final class Route extends Enum { const ALL = 'all'; const READING = 'reading'; const PLAN_TO_READ = 'plan_to_read'; diff --git a/src/API/Enum/MangaReadingStatus/Title.php b/src/API/Enum/MangaReadingStatus/Title.php index 292da0da..8188658f 100644 --- a/src/API/Enum/MangaReadingStatus/Title.php +++ b/src/API/Enum/MangaReadingStatus/Title.php @@ -16,12 +16,12 @@ namespace Aviat\AnimeClient\API\Enum\MangaReadingStatus; -use Aviat\Ion\Enum as Enum; +use Aviat\Ion\Enum; /** * Possible values for current reading status of manga */ -class Title extends Enum { +final class Title extends Enum { const ALL = 'All'; const READING = 'Currently Reading'; const PLAN_TO_READ = 'Plan to Read'; diff --git a/src/API/JsonAPI.php b/src/API/JsonAPI.php index c90c4b85..f9ef15b3 100644 --- a/src/API/JsonAPI.php +++ b/src/API/JsonAPI.php @@ -19,7 +19,7 @@ namespace Aviat\AnimeClient\API; /** * Class encapsulating Json API data structure for a request or response */ -class JsonAPI { +final class JsonAPI { /** * The full data array diff --git a/src/API/Kitsu.php b/src/API/Kitsu.php index 3b485064..6f372bde 100644 --- a/src/API/Kitsu.php +++ b/src/API/Kitsu.php @@ -22,7 +22,7 @@ use DateTimeImmutable; /** * Data massaging helpers for the Kitsu API */ -class Kitsu { +final class Kitsu { const AUTH_URL = 'https://kitsu.io/api/oauth/token'; const AUTH_USER_ID_KEY = 'kitsu-auth-userid'; const AUTH_TOKEN_CACHE_KEY = 'kitsu-auth-token'; diff --git a/src/API/Kitsu/Auth.php b/src/API/Kitsu/Auth.php index 39a52362..e6386ff4 100644 --- a/src/API/Kitsu/Auth.php +++ b/src/API/Kitsu/Auth.php @@ -28,7 +28,7 @@ use Exception; /** * Kitsu API Authentication */ -class Auth { +final class Auth { use CacheTrait; use ContainerAware; @@ -37,14 +37,14 @@ class Auth { * * @var Model */ - protected $model; + private $model; /** * Session object * * @var \Aura\Session\Segment */ - protected $segment; + private $segment; /** * Constructor diff --git a/src/API/Kitsu/Enum/AnimeAiringStatus.php b/src/API/Kitsu/Enum/AnimeAiringStatus.php index 93577a5d..02a0bbdf 100644 --- a/src/API/Kitsu/Enum/AnimeAiringStatus.php +++ b/src/API/Kitsu/Enum/AnimeAiringStatus.php @@ -21,7 +21,7 @@ use Aviat\Ion\Enum as BaseEnum; /** * Status of when anime is being/was/will be aired */ -class AnimeAiringStatus extends BaseEnum { +final class AnimeAiringStatus extends BaseEnum { const NOT_YET_AIRED = 'Not Yet Aired'; const AIRING = 'Currently Airing'; const FINISHED_AIRING = 'Finished Airing'; diff --git a/src/API/Kitsu/KitsuRequestBuilder.php b/src/API/Kitsu/KitsuRequestBuilder.php index e36ee6f3..9fe30b91 100644 --- a/src/API/Kitsu/KitsuRequestBuilder.php +++ b/src/API/Kitsu/KitsuRequestBuilder.php @@ -18,7 +18,7 @@ namespace Aviat\AnimeClient\API\Kitsu; use Aviat\AnimeClient\API\APIRequestBuilder; -class KitsuRequestBuilder extends APIRequestBuilder { +final class KitsuRequestBuilder extends APIRequestBuilder { /** * The base url for api requests diff --git a/src/API/Kitsu/ListItem.php b/src/API/Kitsu/ListItem.php index aaa77c85..bb7be57b 100644 --- a/src/API/Kitsu/ListItem.php +++ b/src/API/Kitsu/ListItem.php @@ -25,39 +25,17 @@ use Aviat\AnimeClient\API\{ HummingbirdClient, ListItemInterface }; +use Aviat\AnimeClient\Types\AbstractType; use Aviat\Ion\Di\ContainerAware; use Aviat\Ion\Json; /** * CRUD operations for Kitsu list items */ -class ListItem implements ListItemInterface { +final class ListItem implements ListItemInterface { use ContainerAware; use KitsuTrait; - private function getAuthHeader() - { - $cache = $this->getContainer()->get('cache'); - $cacheItem = $cache->getItem('kitsu-auth-token'); - $sessionSegment = $this->getContainer() - ->get('session') - ->getSegment(SESSION_SEGMENT); - - if ($sessionSegment->get('auth_token') !== NULL) - { - $token = $sessionSegment->get('auth_token'); - return "bearer {$token}"; - } - - if ($cacheItem->isHit()) - { - $token = $cacheItem->get(); - return "bearer {$token}"; - } - - return FALSE; - } - public function create(array $data): Request { $body = [ @@ -134,7 +112,7 @@ class ListItem implements ListItemInterface { return Json::decode(wait($response->getBody())); } - public function update(string $id, array $data): Request + public function update(string $id, AbstractType $data): Request { $authHeader = $this->getAuthHeader(); $requestData = [ @@ -155,4 +133,25 @@ class ListItem implements ListItemInterface { return $request->getFullRequest(); } + + private function getAuthHeader() + { + $cache = $this->getContainer()->get('cache'); + $cacheItem = $cache->getItem('kitsu-auth-token'); + $sessionSegment = $this->getContainer() + ->get('session') + ->getSegment(SESSION_SEGMENT); + + if ($sessionSegment->get('auth_token') !== NULL) { + $token = $sessionSegment->get('auth_token'); + return "bearer {$token}"; + } + + if ($cacheItem->isHit()) { + $token = $cacheItem->get(); + return "bearer {$token}"; + } + + return FALSE; + } } \ No newline at end of file diff --git a/src/API/Kitsu/Model.php b/src/API/Kitsu/Model.php index 6d2077f1..63e2e021 100644 --- a/src/API/Kitsu/Model.php +++ b/src/API/Kitsu/Model.php @@ -36,17 +36,22 @@ use Aviat\AnimeClient\API\Kitsu\Transformer\{ MangaTransformer, MangaListTransformer }; +use Aviat\AnimeClient\Types\{ + Anime, + AnimeFormItem, + AnimeListItem +}; use Aviat\Ion\{Di\ContainerAware, Json}; /** * Kitsu API Model */ -class Model { +final class Model { use CacheTrait; use ContainerAware; use KitsuTrait; - protected const LIST_PAGE_SIZE = 100; + private const LIST_PAGE_SIZE = 100; /** * Class to map anime list items @@ -55,27 +60,27 @@ class Model { * * @var AnimeListTransformer */ - protected $animeListTransformer; + private $animeListTransformer; /** * @var AnimeTransformer */ - protected $animeTransformer; + private $animeTransformer; /** * @var ListItem */ - protected $listItem; + private $listItem; /** * @var MangaTransformer */ - protected $mangaTransformer; + private $mangaTransformer; /** * @var MangaListTransformer */ - protected $mangaListTransformer; + private $mangaListTransformer; /** * Constructor @@ -313,15 +318,15 @@ class Model { * Get information about a particular anime * * @param string $slug - * @return array + * @return Anime */ - public function getAnime(string $slug): array + public function getAnime(string $slug): Anime { $baseData = $this->getRawMediaData('anime', $slug); if (empty($baseData)) { - return []; + return new Anime(); } $transformed = $this->animeTransformer->transform($baseData); @@ -803,9 +808,9 @@ class Model { * Get the data for a specific list item, generally for editing * * @param string $listId - The unique identifier of that list item - * @return array + * @return mixed */ - public function getListItem(string $listId): array + public function getListItem(string $listId) { $baseData = $this->listItem->get($listId); $included = JsonAPI::organizeIncludes($baseData['included']); @@ -813,12 +818,12 @@ class Model { switch (TRUE) { - case in_array('anime', array_keys($included)): + case array_key_exists('anime', $included): // in_array('anime', array_keys($included)): $included = JsonAPI::inlineIncludedRelationships($included, 'anime'); $baseData['data']['included'] = $included; return $this->animeListTransformer->transform($baseData['data']); - case in_array('manga', array_keys($included)): + case array_key_exists('manga', $included): // in_array('manga', array_keys($included)): $included = JsonAPI::inlineIncludedRelationships($included, 'manga'); $baseData['data']['included'] = $included; $baseData['data']['manga'] = $baseData['included'][0]; @@ -832,10 +837,10 @@ class Model { /** * Modify a list item * - * @param array $data + * @param AnimeFormItem $data * @return Request */ - public function updateListItem(array $data): Request + public function updateListItem(AnimeFormItem $data): Request { return $this->listItem->update($data['id'], $data['data']); } diff --git a/src/API/Kitsu/Transformer/AnimeListTransformer.php b/src/API/Kitsu/Transformer/AnimeListTransformer.php index cd692caf..19b01952 100644 --- a/src/API/Kitsu/Transformer/AnimeListTransformer.php +++ b/src/API/Kitsu/Transformer/AnimeListTransformer.php @@ -17,21 +17,27 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer; use Aviat\AnimeClient\API\Kitsu; +use Aviat\AnimeClient\Types\{ + Anime, + AnimeFormItem, + AnimeFormItemData, + AnimeListItem +}; use Aviat\Ion\Transformer\AbstractTransformer; /** * Transformer for anime list */ -class AnimeListTransformer extends AbstractTransformer { +final class AnimeListTransformer extends AbstractTransformer { /** * Convert raw api response to a more * logical and workable structure * * @param array $item API library item - * @return array + * @return AnimeListItem */ - public function transform($item): array + public function transform($item): AnimeListItem { $included = $item['included']; $animeId = $item['relationships']['media']['data']['id']; @@ -66,7 +72,10 @@ class AnimeListTransformer extends AbstractTransformer { ? Kitsu::parseListItemStreamingLinks($included, $animeId) : []; - return [ + $titles = Kitsu::filterTitles($anime); + $title = array_shift($titles); + + return new AnimeListItem([ 'id' => $item['id'], 'mal_id' => $MALid, 'episodes' => [ @@ -81,24 +90,24 @@ class AnimeListTransformer extends AbstractTransformer { 'started' => $anime['startDate'], 'ended' => $anime['endDate'] ], - 'anime' => [ + 'anime' => new Anime([ 'id' => $animeId, 'age_rating' => $anime['ageRating'], - 'title' => $anime['canonicalTitle'], - 'titles' => Kitsu::filterTitles($anime), + 'title' => $title, + 'titles' => $titles, 'slug' => $anime['slug'], - 'type' => $this->string($anime['showType'])->upperCaseFirst()->__toString(), - 'image' => $anime['posterImage']['small'], + 'show_type' => $this->string($anime['showType'])->upperCaseFirst()->__toString(), + 'cover_image' => $anime['posterImage']['small'], 'genres' => $genres, 'streaming_links' => $streamingLinks, - ], + ]), 'watching_status' => $item['attributes']['status'], 'notes' => $item['attributes']['notes'], 'rewatching' => (bool) $item['attributes']['reconsuming'], 'rewatched' => (int) $item['attributes']['reconsumeCount'], 'user_rating' => $rating, 'private' => $item['attributes']['private'] ?? FALSE, - ]; + ]); } /** @@ -106,24 +115,24 @@ class AnimeListTransformer extends AbstractTransformer { * api response format * * @param array $item Transformed library item - * @return array API library item + * @return AnimeFormItem API library item */ - public function untransform($item): array + public function untransform($item): AnimeFormItem { $privacy = (array_key_exists('private', $item) && $item['private']); $rewatching = (array_key_exists('rewatching', $item) && $item['rewatching']); - $untransformed = [ + $untransformed = new AnimeFormItem([ 'id' => $item['id'], 'mal_id' => $item['mal_id'] ?? NULL, - 'data' => [ + 'data' => new AnimeFormItemData([ 'status' => $item['watching_status'], 'reconsuming' => $rewatching, 'reconsumeCount' => $item['rewatched'], 'notes' => $item['notes'], 'private' => $privacy - ] - ]; + ]) + ]); if (is_numeric($item['episodes_watched']) && $item['episodes_watched'] > 0) { diff --git a/src/API/Kitsu/Transformer/AnimeTransformer.php b/src/API/Kitsu/Transformer/AnimeTransformer.php index 1d8a35bd..bb5059c6 100644 --- a/src/API/Kitsu/Transformer/AnimeTransformer.php +++ b/src/API/Kitsu/Transformer/AnimeTransformer.php @@ -17,31 +17,32 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer; use Aviat\AnimeClient\API\{JsonAPI, Kitsu}; +use Aviat\AnimeClient\Types\Anime; use Aviat\Ion\Transformer\AbstractTransformer; /** * Transformer for anime description page */ -class AnimeTransformer extends AbstractTransformer { +final class AnimeTransformer extends AbstractTransformer { /** * Convert raw api response to a more * logical and workable structure * * @param array $item API library item - * @return array + * @return Anime */ - public function transform($item): array + public function transform($item): Anime { - $item['included'] = JsonAPI::organizeIncludes($item['included']); $genres = $item['included']['categories'] ?? []; $item['genres'] = array_column($genres, 'title') ?? []; sort($item['genres']); $titles = Kitsu::filterTitles($item); + $title = array_shift($titles); - return [ + return new Anime([ 'age_rating' => $item['ageRating'], 'age_rating_guide' => $item['ageRatingGuide'], 'cover_image' => $item['posterImage']['small'], @@ -54,10 +55,10 @@ class AnimeTransformer extends AbstractTransformer { 'status' => Kitsu::getAiringStatus($item['startDate'], $item['endDate']), 'streaming_links' => Kitsu::parseStreamingLinks($item['included']), 'synopsis' => $item['synopsis'], - 'title' => $titles[0], + 'title' => $title, 'titles' => $titles, 'trailer_id' => $item['youtubeVideoId'], 'url' => "https://kitsu.io/anime/{$item['slug']}", - ]; + ]); } } \ No newline at end of file diff --git a/src/API/Kitsu/Transformer/MangaListTransformer.php b/src/API/Kitsu/Transformer/MangaListTransformer.php index b243bcac..60ce4d19 100644 --- a/src/API/Kitsu/Transformer/MangaListTransformer.php +++ b/src/API/Kitsu/Transformer/MangaListTransformer.php @@ -23,7 +23,7 @@ use Aviat\Ion\Transformer\AbstractTransformer; /** * Data transformation class for zippered Hummingbird manga */ -class MangaListTransformer extends AbstractTransformer { +final class MangaListTransformer extends AbstractTransformer { use StringWrapper; diff --git a/src/API/Kitsu/Transformer/MangaTransformer.php b/src/API/Kitsu/Transformer/MangaTransformer.php index 53465603..532b37a1 100644 --- a/src/API/Kitsu/Transformer/MangaTransformer.php +++ b/src/API/Kitsu/Transformer/MangaTransformer.php @@ -21,7 +21,7 @@ use Aviat\Ion\Transformer\AbstractTransformer; /** * Transformer for anime description page */ -class MangaTransformer extends AbstractTransformer { +final class MangaTransformer extends AbstractTransformer { /** * Convert raw api response to a more diff --git a/src/API/ListItemInterface.php b/src/API/ListItemInterface.php index bd252417..9fbcde48 100644 --- a/src/API/ListItemInterface.php +++ b/src/API/ListItemInterface.php @@ -17,6 +17,7 @@ namespace Aviat\AnimeClient\API; use Amp\Artax\Request; +use Aviat\AnimeClient\Types\AbstractType; /** * Common interface for anime and manga list item CRUD @@ -43,10 +44,10 @@ interface ListItemInterface { * Update a list item * * @param string $id - The id of the list item to update - * @param array $data - The data with which to update the list item + * @param AbstractType $data - The data with which to update the list item * @return Request */ - public function update(string $id, array $data): Request; + public function update(string $id, AbstractType $data): Request; /** * Delete a list item diff --git a/src/API/MAL.php b/src/API/MAL.php index 12343a28..332a721f 100644 --- a/src/API/MAL.php +++ b/src/API/MAL.php @@ -28,7 +28,7 @@ use Aviat\AnimeClient\API\Enum\{ /** * Constants and mappings for the My Anime List API */ -class MAL { +final class MAL { const AUTH_URL = 'https://myanimelist.net/api/account/verify_credentials.xml'; const BASE_URL = 'https://myanimelist.net/api/'; diff --git a/src/API/MAL/ListItem.php b/src/API/MAL/ListItem.php index 7df6fad0..09405394 100644 --- a/src/API/MAL/ListItem.php +++ b/src/API/MAL/ListItem.php @@ -20,12 +20,13 @@ use Amp\Artax\{FormBody, Request}; use Aviat\AnimeClient\API\{ XML }; +use Aviat\AnimeClient\Types\AbstractType; use Aviat\Ion\Di\ContainerAware; /** * CRUD operations for MAL list items */ -class ListItem { +final class ListItem { use ContainerAware; use MALTrait; @@ -84,11 +85,11 @@ class ListItem { * Update a list item * * @param string $id - * @param array $data + * @param AbstractType $data * @param string $type * @return Request */ - public function update(string $id, array $data, string $type = 'anime'): Request + public function update(string $id, AbstractType $data, string $type = 'anime'): Request { $config = $this->container->get('config'); diff --git a/src/API/MAL/MALRequestBuilder.php b/src/API/MAL/MALRequestBuilder.php index c7539729..40171c4a 100644 --- a/src/API/MAL/MALRequestBuilder.php +++ b/src/API/MAL/MALRequestBuilder.php @@ -21,7 +21,7 @@ use Aviat\AnimeClient\API\{ MAL as M }; -class MALRequestBuilder extends APIRequestBuilder { +final class MALRequestBuilder extends APIRequestBuilder { /** * The base url for api requests diff --git a/src/API/MAL/Model.php b/src/API/MAL/Model.php index 7c807f31..b8160e00 100644 --- a/src/API/MAL/Model.php +++ b/src/API/MAL/Model.php @@ -24,12 +24,13 @@ use Aviat\AnimeClient\API\MAL\{ }; use Aviat\AnimeClient\API\XML; use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus}; +use Aviat\AnimeClient\Types\{Anime, AnimeFormItem}; use Aviat\Ion\Di\ContainerAware; /** * MyAnimeList API Model */ -class Model { +final class Model { use ContainerAware; use MALTrait; @@ -147,11 +148,11 @@ class Model { /** * Update a list item * - * @param array $data + * @param AnimeFormItem $data * @param string $type "anime" or "manga" * @return Request */ - public function updateListItem(array $data, string $type = 'anime'): Request + public function updateListItem(AnimeFormItem $data, string $type = 'anime'): Request { $updateData = []; diff --git a/src/API/MAL/Transformer/AnimeListTransformer.php b/src/API/MAL/Transformer/AnimeListTransformer.php index 25d18c2c..af38f8e7 100644 --- a/src/API/MAL/Transformer/AnimeListTransformer.php +++ b/src/API/MAL/Transformer/AnimeListTransformer.php @@ -17,12 +17,13 @@ namespace Aviat\AnimeClient\API\MAL\Transformer; use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus; +use Aviat\AnimeClient\Types\{AnimeFormItem, AnimeFormItemData}; use Aviat\Ion\Transformer\AbstractTransformer; /** * Transformer for updating MAL List */ -class AnimeListTransformer extends AbstractTransformer { +final class AnimeListTransformer extends AbstractTransformer { /** * Identity transformation * @@ -38,16 +39,14 @@ class AnimeListTransformer extends AbstractTransformer { * Transform Kitsu episode data to MAL episode data * * @param array $item - * @return array + * @return AnimeFormItem */ - public function untransform(array $item): array + public function untransform(array $item): AnimeFormItem { - $map = [ + $map = new AnimeFormItem([ 'id' => $item['mal_id'], - 'data' => [] - ]; - - $data =& $item['data']; + 'data' => new AnimeFormItemData([]), + ]); foreach($item['data'] as $key => $value) { @@ -56,7 +55,7 @@ class AnimeListTransformer extends AbstractTransformer { case 'progress': $map['data']['episode'] = $value; break; - + case 'notes': $map['data']['comments'] = $value; break; diff --git a/src/API/MAL/Transformer/MangaListTransformer.php b/src/API/MAL/Transformer/MangaListTransformer.php index 2c04db77..b55f91fc 100644 --- a/src/API/MAL/Transformer/MangaListTransformer.php +++ b/src/API/MAL/Transformer/MangaListTransformer.php @@ -22,7 +22,7 @@ use Aviat\Ion\Transformer\AbstractTransformer; /** * Transformer for updating MAL List */ -class MangaListTransformer extends AbstractTransformer { +final class MangaListTransformer extends AbstractTransformer { /** * Identity transformation * diff --git a/src/API/Mapping/AnimeWatchingStatus.php b/src/API/Mapping/AnimeWatchingStatus.php index 8bc37712..8771881b 100644 --- a/src/API/Mapping/AnimeWatchingStatus.php +++ b/src/API/Mapping/AnimeWatchingStatus.php @@ -23,7 +23,7 @@ use Aviat\Ion\Enum; * Anime watching status mappings, among Kitsu, MAL, Page titles * and url route segments */ -class AnimeWatchingStatus extends Enum { +final class AnimeWatchingStatus extends Enum { const KITSU_TO_MAL = [ Kitsu::WATCHING => MAL::WATCHING, Kitsu::PLAN_TO_WATCH => MAL::PLAN_TO_WATCH, diff --git a/src/API/Mapping/MangaReadingStatus.php b/src/API/Mapping/MangaReadingStatus.php index 77d76609..4d9080d4 100644 --- a/src/API/Mapping/MangaReadingStatus.php +++ b/src/API/Mapping/MangaReadingStatus.php @@ -23,7 +23,7 @@ use Aviat\Ion\Enum; * Manga reading status mappings, among Kitsu, MAL, Page titles * and url route segments */ -class MangaReadingStatus extends Enum { +final class MangaReadingStatus extends Enum { const KITSU_TO_MAL = [ Kitsu::READING => MAL::READING, Kitsu::PLAN_TO_READ => MAL::PLAN_TO_READ, diff --git a/src/API/ParallelAPIRequest.php b/src/API/ParallelAPIRequest.php index f89b11d7..877cf94a 100644 --- a/src/API/ParallelAPIRequest.php +++ b/src/API/ParallelAPIRequest.php @@ -22,14 +22,14 @@ use function Amp\Promise\{all, wait}; /** * Class to simplify making and validating simultaneous requests */ -class ParallelAPIRequest { +final class ParallelAPIRequest { /** * Set of requests to make in parallel * * @var array */ - protected $requests = []; + private $requests = []; /** * Add a request @@ -76,9 +76,7 @@ class ParallelAPIRequest { { $promises[$key] = call(function () use ($client, $url) { $response = yield $client->request($url); - $body = yield $response->getBody(); - - return $body; + return yield $response->getBody(); }); } diff --git a/src/API/XML.php b/src/API/XML.php index 8908bbb0..eeedf0c9 100644 --- a/src/API/XML.php +++ b/src/API/XML.php @@ -21,7 +21,7 @@ use DOMDocument, DOMNode, DOMNodeList, InvalidArgumentException; /** * XML <=> PHP Array codec */ -class XML { +final class XML { /** * XML representation of the data diff --git a/src/Command/CacheClear.php b/src/Command/CacheClear.php index 81ff5d59..61f98ba0 100644 --- a/src/Command/CacheClear.php +++ b/src/Command/CacheClear.php @@ -19,7 +19,7 @@ namespace Aviat\AnimeClient\Command; /** * Clears the API Cache */ -class CacheClear extends BaseCommand { +final class CacheClear extends BaseCommand { /** * Clear the API cache * diff --git a/src/Command/CachePrime.php b/src/Command/CachePrime.php index ae6cf5d3..871f8f70 100644 --- a/src/Command/CachePrime.php +++ b/src/Command/CachePrime.php @@ -19,7 +19,7 @@ namespace Aviat\AnimeClient\Command; /** * Clears the API Cache */ -class CachePrime extends BaseCommand { +final class CachePrime extends BaseCommand { /** * Clear, then prime the API cache * diff --git a/src/Command/SyncLists.php b/src/Command/SyncLists.php index c64d4194..4567a742 100644 --- a/src/Command/SyncLists.php +++ b/src/Command/SyncLists.php @@ -32,7 +32,7 @@ use DateTime; /** * Clears the API Cache */ -class SyncLists extends BaseCommand { +final class SyncLists extends BaseCommand { /** * Model for making requests to Kitsu API diff --git a/src/Controller/Anime.php b/src/Controller/Anime.php index 013c4a25..d1ccb05e 100644 --- a/src/Controller/Anime.php +++ b/src/Controller/Anime.php @@ -27,7 +27,7 @@ use Aviat\Ion\StringWrapper; /** * Controller for Anime-related pages */ -class Anime extends BaseController { +final class Anime extends BaseController { use StringWrapper; @@ -277,7 +277,7 @@ class Anime extends BaseController { $show_data = $this->model->getAnime($animeId); $characters = []; - if (empty($show_data)) + if ($show_data->title === '') { $this->notFound( $this->config->get('whose_list') . @@ -301,7 +301,7 @@ class Anime extends BaseController { 'title' => $this->formatTitle( $this->config->get('whose_list') . "'s Anime List", 'Anime', - $show_data['titles'][0] + $show_data->title ), 'characters' => $characters, 'show_data' => $show_data, diff --git a/src/Controller/AnimeCollection.php b/src/Controller/AnimeCollection.php index 520408f0..094f2120 100644 --- a/src/Controller/AnimeCollection.php +++ b/src/Controller/AnimeCollection.php @@ -26,7 +26,7 @@ use Aviat\Ion\Di\ContainerInterface; /** * Controller for Anime collection pages */ -class AnimeCollection extends BaseController { +final class AnimeCollection extends BaseController { /** * The anime collection model diff --git a/src/Controller/Character.php b/src/Controller/Character.php index 2619833a..d14b099a 100644 --- a/src/Controller/Character.php +++ b/src/Controller/Character.php @@ -23,7 +23,7 @@ use Aviat\Ion\ArrayWrapper; /** * Controller for character description pages */ -class Character extends BaseController { +final class Character extends BaseController { use ArrayWrapper; diff --git a/src/Controller/Index.php b/src/Controller/Index.php index 985dc92f..a797cf2c 100644 --- a/src/Controller/Index.php +++ b/src/Controller/Index.php @@ -25,7 +25,7 @@ use Aviat\Ion\View\HtmlView; /** * Controller for handling routes that don't fit elsewhere */ -class Index extends BaseController { +final class Index extends BaseController { /** * Purges the API cache diff --git a/src/Controller/Manga.php b/src/Controller/Manga.php index c6ed6de1..0c1ad65d 100644 --- a/src/Controller/Manga.php +++ b/src/Controller/Manga.php @@ -26,7 +26,7 @@ use Aviat\Ion\{Json, StringWrapper}; /** * Controller for manga list */ -class Manga extends Controller { +final class Manga extends Controller { use StringWrapper; diff --git a/src/Controller/MangaCollection.php b/src/Controller/MangaCollection.php index cbceefcc..a904d50e 100644 --- a/src/Controller/MangaCollection.php +++ b/src/Controller/MangaCollection.php @@ -26,7 +26,7 @@ use Aviat\Ion\Di\ContainerInterface; /** * Controller for manga collection pages */ -class MangaCollection extends BaseController { +final class MangaCollection extends BaseController { /** * The manga collection model diff --git a/src/Dispatcher.php b/src/Dispatcher.php index 19e17b35..d40e89a0 100644 --- a/src/Dispatcher.php +++ b/src/Dispatcher.php @@ -28,7 +28,7 @@ use Aviat\Ion\StringWrapper; /** * Basic routing/ dispatch */ -class Dispatcher extends RoutingBase { +final class Dispatcher extends RoutingBase { use StringWrapper; diff --git a/src/Helper/Menu.php b/src/Helper/Menu.php index 17a5e380..cdbc37c4 100644 --- a/src/Helper/Menu.php +++ b/src/Helper/Menu.php @@ -17,13 +17,14 @@ namespace Aviat\AnimeClient\Helper; use Aviat\AnimeClient\MenuGenerator; +use Aviat\Ion\Di\ContainerAware; /** * MenuGenerator helper wrapper */ -class Menu { +final class Menu { - use \Aviat\Ion\Di\ContainerAware; + use ContainerAware; /** * Create the html for the selected menu diff --git a/src/MenuGenerator.php b/src/MenuGenerator.php index b7c92da5..eaf51066 100644 --- a/src/MenuGenerator.php +++ b/src/MenuGenerator.php @@ -25,7 +25,7 @@ use Aviat\Ion\Exception\ConfigException; /** * Helper object to manage menu creation and selection */ -class MenuGenerator extends UrlGenerator { +final class MenuGenerator extends UrlGenerator { use ArrayWrapper; use StringWrapper; diff --git a/src/Model/API.php b/src/Model/API.php index e4501c90..a71273bb 100644 --- a/src/Model/API.php +++ b/src/Model/API.php @@ -44,7 +44,7 @@ class API { foreach ($array as $key => $item) { - $sort[$key] = $item[$sortKey]['titles'][0]; + $sort[$key] = $item[$sortKey]['title']; } array_multisort($sort, SORT_ASC, $array); diff --git a/src/Model/Anime.php b/src/Model/Anime.php index 3669002b..0b37bba4 100644 --- a/src/Model/Anime.php +++ b/src/Model/Anime.php @@ -18,13 +18,18 @@ namespace Aviat\AnimeClient\Model; use Aviat\AnimeClient\API\ParallelAPIRequest; use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus; +use Aviat\AnimeClient\Types\{ + Anime as AnimeType, + AnimeFormItem, + AnimeListItem, +}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Json; /** * Model for handling requests dealing with the anime list */ -class Anime extends API { +final class Anime extends API { /** * Model for making requests to Kitsu API * @@ -93,9 +98,9 @@ class Anime extends API { * Get information about an anime from its slug * * @param string $slug - * @return array + * @return AnimeType */ - public function getAnime(string $slug): array + public function getAnime(string $slug): AnimeType { return $this->kitsuModel->getAnime($slug); } @@ -127,9 +132,9 @@ class Anime extends API { * for editing/updating that item * * @param string $itemId - * @return array + * @return AnimeListItem */ - public function getLibraryItem(string $itemId): array + public function getLibraryItem(string $itemId): AnimeListItem { return $this->kitsuModel->getListItem($itemId); } @@ -166,10 +171,10 @@ class Anime extends API { /** * Update a list entry * - * @param array $data + * @param AnimeFormItem $data * @return array */ - public function updateLibraryItem(array $data): array + public function updateLibraryItem(AnimeFormItem $data): array { $requester = new ParallelAPIRequest(); diff --git a/src/Model/AnimeCollection.php b/src/Model/AnimeCollection.php index 2af9de2c..ba578f0d 100644 --- a/src/Model/AnimeCollection.php +++ b/src/Model/AnimeCollection.php @@ -22,7 +22,7 @@ use PDO; /** * Model for getting anime collection data */ -class AnimeCollection extends Collection { +final class AnimeCollection extends Collection { /** * Anime API Model diff --git a/src/Model/Manga.php b/src/Model/Manga.php index b3ddcf41..85c050c7 100644 --- a/src/Model/Manga.php +++ b/src/Model/Manga.php @@ -27,7 +27,7 @@ use Aviat\Ion\Json; /** * Model for handling requests dealing with the manga list */ -class Manga extends API +final class Manga extends API { /** * Model for making requests to Kitsu API diff --git a/src/Model/MangaCollection.php b/src/Model/MangaCollection.php index a41b6618..f3d41968 100644 --- a/src/Model/MangaCollection.php +++ b/src/Model/MangaCollection.php @@ -22,7 +22,7 @@ use PDO; /** * Model for getting anime collection data */ -class MangaCollection extends Collection { +final class MangaCollection extends Collection { /** * Manga API Model diff --git a/src/Types/AbstractType.php b/src/Types/AbstractType.php new file mode 100644 index 00000000..bbb3ed41 --- /dev/null +++ b/src/Types/AbstractType.php @@ -0,0 +1,121 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +use ArrayAccess; +use LogicException; + +abstract class AbstractType implements ArrayAccess { + /** + * Sets the properties by using the constructor + * + * @param array $data + */ + public function __construct(array $data = []) + { + foreach ($data as $key => $value) { + $this->$key = $value; + } + } + + /** + * See if a property is set + * + * @param $name + * @return bool + */ + public function __isset($name): bool + { + return property_exists($this, $name); + } + + /** + * Set a property on the type object + * + * @param string $name + * @param mixed $value + * @return void + */ + public function __set($name, $value): void + { + if (!property_exists($this, $name)) { + $existing = json_encode($this); + + throw new LogicException("Trying to set non-existent property: '$name'. Existing properties: $existing"); + } + + $this->$name = $value; + } + + /** + * Get a property from the type object + * + * @param string $name + * @return mixed + */ + public function __get($name) + { + if (property_exists($this, $name)) { + return $this->$name; + } + + throw new LogicException("Trying to get non-existent property: '$name'"); + } + + /** + * Implementing ArrayAccess + * + * @param $offset + * @return bool + */ + public function offsetExists($offset): bool + { + return $this->__isset($offset); + } + + /** + * Implementing ArrayAccess + * + * @param $offset + * @return mixed + */ + public function offsetGet($offset) + { + return $this->__get($offset); + } + + /** + * Implementing ArrayAccess + * + * @param $offset + * @param $value + */ + public function offsetSet($offset, $value): void + { + $this->__set($offset, $value); + } + + /** + * Implementing ArrayAccess + * + * @param $offset + */ + public function offsetUnset($offset): void + { + // Do nothing! + } +} \ No newline at end of file diff --git a/src/Types/Anime.php b/src/Types/Anime.php new file mode 100644 index 00000000..d3fd573a --- /dev/null +++ b/src/Types/Anime.php @@ -0,0 +1,40 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +/** + * Type representing an Anime object for display + */ +final class Anime extends AbstractType { + public $age_rating; + public $age_rating_guide; + public $cover_image; + public $episode_count; + public $episode_length; + public $genres; + public $id; + public $included; + public $show_type; + public $slug; + public $status; + public $streaming_links; + public $synopsis; + public $title; + public $titles; + public $trailer_id; + public $url; +} \ No newline at end of file diff --git a/src/Types/AnimeFormItem.php b/src/Types/AnimeFormItem.php new file mode 100644 index 00000000..af02e058 --- /dev/null +++ b/src/Types/AnimeFormItem.php @@ -0,0 +1,26 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +/** + * Type representing an Anime object for display + */ +final class AnimeFormItem extends AbstractType { + public $data; + public $id; + public $mal_id; +} diff --git a/src/Types/AnimeFormItemData.php b/src/Types/AnimeFormItemData.php new file mode 100644 index 00000000..88eb2a13 --- /dev/null +++ b/src/Types/AnimeFormItemData.php @@ -0,0 +1,30 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +/** + * Type representing an Anime object for display + */ +final class AnimeFormItemData extends AbstractType { + public $notes; + public $private; + public $progress; + public $rating; + public $reconsumeCount; + public $reconsuming; + public $status; +} diff --git a/src/Types/AnimeListItem.php b/src/Types/AnimeListItem.php new file mode 100644 index 00000000..0e80b04d --- /dev/null +++ b/src/Types/AnimeListItem.php @@ -0,0 +1,42 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +/** + * Type representing an Anime object for display + */ +final class AnimeListItem extends AbstractType { + public $id; + public $mal_id; + public $episodes = [ + 'length' => 0, + 'total' => 0, + 'watched' => '', + ]; + public $airing = [ + 'status' => '', + 'started' => '', + 'ended' => '', + ]; + public $anime; + public $watching_status; + public $notes; + public $rewatching; + public $rewatched; + public $user_rating; + public $private; +} From d29945eb964721fd70e8fa8ac1a8d80b88a1ca30 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Wed, 8 Aug 2018 11:18:57 -0400 Subject: [PATCH 04/17] Fix tests --- src/Model/Anime.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Anime.php b/src/Model/Anime.php index 0b37bba4..3c943bb1 100644 --- a/src/Model/Anime.php +++ b/src/Model/Anime.php @@ -21,7 +21,7 @@ use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus; use Aviat\AnimeClient\Types\{ Anime as AnimeType, AnimeFormItem, - AnimeListItem, + AnimeListItem }; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Json; From 3b3156e78a48882fd27879dab9005ca97c7c4503 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Wed, 8 Aug 2018 13:05:38 -0400 Subject: [PATCH 05/17] More refactoring, fix snapshot tests --- app/views/manga/cover.php | 2 +- app/views/manga/edit.php | 8 +- app/views/manga/list.php | 2 +- index.php | 9 +- public/css.js | 2 +- public/js.php | 11 +- public/js/cache/.gitkeep | 0 src/API/Kitsu/Model.php | 18 +- .../Transformer/MangaListTransformer.php | 45 ++-- .../Kitsu/Transformer/MangaTransformer.php | 14 +- src/API/MAL/Model.php | 6 +- src/Model/Anime.php | 2 +- src/Model/Manga.php | 34 ++- src/Types/AbstractType.php | 11 + src/Types/AnimeFormItem.php | 6 +- src/Types/AnimeFormItemData.php | 10 +- src/Types/FormItem.php | 27 ++ src/Types/FormItemData.php | 30 +++ src/Types/MangaFormItem.php | 23 ++ src/Types/MangaFormItemData.php | 19 ++ src/Types/MangaListItem.php | 40 +++ src/Types/MangaListItemDetail.php | 31 +++ src/Types/MangaPage.php | 35 +++ .../Transformer/MangaListTransformerTest.php | 12 +- ...eListTransformerTest__testTransform__1.php | 65 +++-- ...t__testUntransform with data set #0__1.php | 28 +- ...t__testUntransform with data set #1__1.php | 28 +- ...t__testUntransform with data set #2__1.php | 27 +- ...AnimeTransformerTest__testTransform__1.php | 42 +-- ...aListTransformerTest__testTransform__1.php | 247 +++++++++--------- ...MangaTransformerTest__testTransform__1.php | 34 ++- 31 files changed, 549 insertions(+), 319 deletions(-) mode change 100644 => 100755 public/js/cache/.gitkeep create mode 100644 src/Types/FormItem.php create mode 100644 src/Types/FormItemData.php create mode 100644 src/Types/MangaFormItem.php create mode 100644 src/Types/MangaFormItemData.php create mode 100644 src/Types/MangaListItem.php create mode 100644 src/Types/MangaListItemDetail.php create mode 100644 src/Types/MangaPage.php diff --git a/app/views/manga/cover.php b/app/views/manga/cover.php index 90d02e97..6ced8cae 100644 --- a/app/views/manga/cover.php +++ b/app/views/manga/cover.php @@ -26,7 +26,7 @@ " />
- html(array_shift($item['manga']['titles'])) ?> + html($item['manga']['title']) ?>
diff --git a/app/views/manga/edit.php b/app/views/manga/edit.php index 14105b2e..12b3c077 100644 --- a/app/views/manga/edit.php +++ b/app/views/manga/edit.php @@ -8,7 +8,7 @@ -

html(array_shift($item['manga']['titles'])) ?>

+

html($item['manga']['title']) ?>

html($title) ?>

@@ -44,12 +44,12 @@ / - + - / + / - */ ?> + diff --git a/app/views/manga/list.php b/app/views/manga/list.php index 89c2fe19..e7c81ed2 100644 --- a/app/views/manga/list.php +++ b/app/views/manga/list.php @@ -39,7 +39,7 @@
- +
diff --git a/index.php b/index.php index b13fc9ac..a23462f7 100644 --- a/index.php +++ b/index.php @@ -28,9 +28,12 @@ if ($timezone === '' || $timezone === FALSE) // Load composer autoloader require_once __DIR__ . '/vendor/autoload.php'; -$whoops = new \Whoops\Run; -$whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); -$whoops->register(); +// if (array_key_exists('ENV', $_ENV) && $_ENV['ENV'] === 'development') +{ + $whoops = new \Whoops\Run; + $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler); + $whoops->register(); +} // Define base directories $APP_DIR = _dir(__DIR__, 'app'); diff --git a/public/css.js b/public/css.js index 1db6c13e..df99fd96 100644 --- a/public/css.js +++ b/public/css.js @@ -7,7 +7,7 @@ const atImport = require('postcss-import'); const cssNext = require('postcss-cssnext'); const cssNano = require('cssnano'); -const css = fs.readFileSync('css/base.css', 'utf8'); +const css = fs.readFileSync('css/base.css', 'utf-8'); postcss() .use(atImport()) diff --git a/public/js.php b/public/js.php index cc9eaed6..8370c65d 100644 --- a/public/js.php +++ b/public/js.php @@ -22,7 +22,7 @@ use Aviat\AnimeClient\API\HummingbirdClient; use Aviat\Ion\{Json, JsonException}; // Include Amp and Artax -require_once('../vendor/autoload.php'); +require_once '../vendor/autoload.php'; //Creative rewriting of /g/groupname to ?g=groupname $pi = $_SERVER['PATH_INFO']; @@ -318,10 +318,11 @@ class JSMin { $lastModifiedDate = gmdate('D, d M Y H:i:s', $lastModified); $expiresDate = gmdate('D, d M Y H:i:s', $expires); - header("Content-Type: {$mimeType}; charset=utf8"); - header("Cache-control: public, max-age=691200, must-revalidate"); - header("Last-Modified: {$lastModifiedDate} GMT"); + header("Content-Type: {$mimeType}; charset=utf-8"); + header('Cache-control: public, max-age=691200, must-revalidate'); header("Expires: {$expiresDate} GMT"); + header("Last-Modified: {$lastModifiedDate} GMT"); + header('X-Content-Type-Options: no-sniff'); echo $content; @@ -335,7 +336,7 @@ class JSMin { */ public static function send304() { - header("status: 304 Not Modified", true, 304); + header('status: 304 Not Modified', true, 304); } } diff --git a/public/js/cache/.gitkeep b/public/js/cache/.gitkeep old mode 100644 new mode 100755 diff --git a/src/API/Kitsu/Model.php b/src/API/Kitsu/Model.php index 63e2e021..42963390 100644 --- a/src/API/Kitsu/Model.php +++ b/src/API/Kitsu/Model.php @@ -37,9 +37,11 @@ use Aviat\AnimeClient\API\Kitsu\Transformer\{ MangaListTransformer }; use Aviat\AnimeClient\Types\{ + AbstractType, Anime, - AnimeFormItem, - AnimeListItem + FormItem, + AnimeListItem, + MangaPage }; use Aviat\Ion\{Di\ContainerAware, Json}; @@ -562,15 +564,15 @@ final class Model { * Get information about a particular manga * * @param string $slug - * @return array + * @return MangaPage */ - public function getManga(string $slug): array + public function getManga(string $slug): MangaPage { $baseData = $this->getRawMediaData('manga', $slug); if (empty($baseData)) { - return []; + return new MangaPage([]); } $transformed = $this->mangaTransformer->transform($baseData); @@ -584,7 +586,7 @@ final class Model { * @param string $mangaId * @return array */ - public function getMangaById(string $mangaId): array + public function getMangaById(string $mangaId): MangaPage { $baseData = $this->getRawMediaDataById('manga', $mangaId); return $this->mangaTransformer->transform($baseData); @@ -837,10 +839,10 @@ final class Model { /** * Modify a list item * - * @param AnimeFormItem $data + * @param FormItem $data * @return Request */ - public function updateListItem(AnimeFormItem $data): Request + public function updateListItem(FormItem $data): Request { return $this->listItem->update($data['id'], $data['data']); } diff --git a/src/API/Kitsu/Transformer/MangaListTransformer.php b/src/API/Kitsu/Transformer/MangaListTransformer.php index 60ce4d19..b41bd805 100644 --- a/src/API/Kitsu/Transformer/MangaListTransformer.php +++ b/src/API/Kitsu/Transformer/MangaListTransformer.php @@ -17,6 +17,10 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer; use Aviat\AnimeClient\API\Kitsu; +use Aviat\AnimeClient\Types\{ + MangaFormItem, MangaFormItemData, + MangaListItem, MangaListItemDetail +}; use Aviat\Ion\StringWrapper; use Aviat\Ion\Transformer\AbstractTransformer; @@ -31,9 +35,9 @@ final class MangaListTransformer extends AbstractTransformer { * Remap zipped anime data to a more logical form * * @param array $item manga entry item - * @return array + * @return MangaListItem */ - public function transform($item): array + public function transform($item): MangaListItem { $included = $item['included']; $mangaId = $item['relationships']['media']['data']['id']; @@ -72,7 +76,10 @@ final class MangaListTransformer extends AbstractTransformer { } } - $map = [ + $titles = Kitsu::filterTitles($manga); + $title = array_shift($titles); + + $map = new MangaListItem([ 'id' => $item['id'], 'mal_id' => $MALid, 'chapters' => [ @@ -83,22 +90,22 @@ final class MangaListTransformer extends AbstractTransformer { 'read' => '-', //$item['attributes']['volumes_read'], 'total' => $totalVolumes ], - 'manga' => [ - 'id' => $mangaId, - 'titles' => Kitsu::filterTitles($manga), - 'alternate_title' => NULL, - 'slug' => $manga['slug'], - 'url' => 'https://kitsu.io/manga/' . $manga['slug'], - 'type' => $manga['mangaType'], - 'image' => $manga['posterImage']['small'], + 'manga' => new MangaListItemDetail([ 'genres' => $genres, - ], + 'id' => $mangaId, + 'image' => $manga['posterImage']['small'], + 'slug' => $manga['slug'], + 'title' => $title, + 'titles' => $titles, + 'type' => $manga['mangaType'], + 'url' => 'https://kitsu.io/manga/' . $manga['slug'], + ]), 'reading_status' => $item['attributes']['status'], 'notes' => $item['attributes']['notes'], 'rereading' => (bool)$item['attributes']['reconsuming'], 'reread' => $item['attributes']['reconsumeCount'], 'user_rating' => $rating, - ]; + ]); return $map; } @@ -107,22 +114,22 @@ final class MangaListTransformer extends AbstractTransformer { * Untransform data to update the api * * @param array $item - * @return array + * @return MangaFormItem */ - public function untransform($item): array + public function untransform($item): MangaFormItem { $rereading = array_key_exists('rereading', $item) && (bool)$item['rereading']; - $map = [ + $map = new MangaFormItem([ 'id' => $item['id'], 'mal_id' => $item['mal_id'], - 'data' => [ + 'data' => new MangaFormItemData([ 'status' => $item['status'], 'reconsuming' => $rereading, 'reconsumeCount' => (int)$item['reread_count'], 'notes' => $item['notes'], - ], - ]; + ]), + ]); if (is_numeric($item['chapters_read']) && $item['chapters_read'] > 0) { diff --git a/src/API/Kitsu/Transformer/MangaTransformer.php b/src/API/Kitsu/Transformer/MangaTransformer.php index 532b37a1..afd468d5 100644 --- a/src/API/Kitsu/Transformer/MangaTransformer.php +++ b/src/API/Kitsu/Transformer/MangaTransformer.php @@ -16,6 +16,7 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer; +use Aviat\AnimeClient\Types\MangaPage; use Aviat\Ion\Transformer\AbstractTransformer; /** @@ -28,23 +29,24 @@ final class MangaTransformer extends AbstractTransformer { * logical and workable structure * * @param array $item API library item - * @return array + * @return MangaPage */ - public function transform($item) + public function transform($item): MangaPage { + // \dump($item); $genres = []; foreach($item['included'] as $included) { - if ($included['type'] === 'genres') + if ($included['type'] === 'categories') { - $genres[] = $included['attributes']['name']; + $genres[] = $included['attributes']['title']; } } sort($genres); - return [ + return new MangaPage([ 'id' => $item['id'], 'title' => $item['canonicalTitle'], 'en_title' => $item['titles']['en'], @@ -56,7 +58,7 @@ final class MangaTransformer extends AbstractTransformer { 'synopsis' => $item['synopsis'], 'url' => "https://kitsu.io/manga/{$item['slug']}", 'genres' => $genres, - ]; + ]); } private function count(int $value = NULL) diff --git a/src/API/MAL/Model.php b/src/API/MAL/Model.php index b8160e00..0f245d81 100644 --- a/src/API/MAL/Model.php +++ b/src/API/MAL/Model.php @@ -24,7 +24,7 @@ use Aviat\AnimeClient\API\MAL\{ }; use Aviat\AnimeClient\API\XML; use Aviat\AnimeClient\API\Mapping\{AnimeWatchingStatus, MangaReadingStatus}; -use Aviat\AnimeClient\Types\{Anime, AnimeFormItem}; +use Aviat\AnimeClient\Types\{Anime, FormItem}; use Aviat\Ion\Di\ContainerAware; /** @@ -148,11 +148,11 @@ final class Model { /** * Update a list item * - * @param AnimeFormItem $data + * @param FormItem $data * @param string $type "anime" or "manga" * @return Request */ - public function updateListItem(AnimeFormItem $data, string $type = 'anime'): Request + public function updateListItem(FormItem $data, string $type = 'anime'): Request { $updateData = []; diff --git a/src/Model/Anime.php b/src/Model/Anime.php index 3c943bb1..34a5b366 100644 --- a/src/Model/Anime.php +++ b/src/Model/Anime.php @@ -29,7 +29,7 @@ use Aviat\Ion\Json; /** * Model for handling requests dealing with the anime list */ -final class Anime extends API { +class Anime extends API { /** * Model for making requests to Kitsu API * diff --git a/src/Model/Manga.php b/src/Model/Manga.php index 85c050c7..2cee710a 100644 --- a/src/Model/Manga.php +++ b/src/Model/Manga.php @@ -21,14 +21,18 @@ use Aviat\AnimeClient\API\{ Mapping\MangaReadingStatus, ParallelAPIRequest }; +use Aviat\AnimeClient\Types\{ + MangaFormItem, + MangaListItem, + MangaPage +}; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Json; /** * Model for handling requests dealing with the manga list */ -final class Manga extends API -{ +class Manga extends API { /** * Model for making requests to Kitsu API * @var \Aviat\AnimeClient\API\Kitsu\Model @@ -71,17 +75,18 @@ final class Manga extends API } $APIstatus = MangaReadingStatus::TITLE_TO_KITSU[$status]; - $data = $this->kitsuModel->getMangaList($APIstatus); - return $this->mapByStatus($data)[$status]; + $data = + $this->mapByStatus($this->kitsuModel->getMangaList($APIstatus)); + return $data[$status]; } /** * Get the details of a manga * * @param string $manga_id - * @return array + * @return MangaPage */ - public function getManga($manga_id): array + public function getManga($manga_id): MangaPage { return $this->kitsuModel->getManga($manga_id); } @@ -90,9 +95,9 @@ final class Manga extends API * Get anime by its kitsu id * * @param string $animeId - * @return array + * @return MangaPage */ - public function getMangaById(string $animeId): array + public function getMangaById(string $animeId): MangaPage { return $this->kitsuModel->getMangaById($animeId); } @@ -102,9 +107,9 @@ final class Manga extends API * for editing/updating that item * * @param string $itemId - * @return array + * @return MangaListItem */ - public function getLibraryItem(string $itemId): array + public function getLibraryItem(string $itemId): MangaListItem { return $this->kitsuModel->getListItem($itemId); } @@ -141,10 +146,10 @@ final class Manga extends API /** * Update a list entry * - * @param array $data + * @param MangaFormItem $data * @return array */ - public function updateLibraryItem(array $data): array + public function updateLibraryItem(MangaFormItem $data): array { $requester = new ParallelAPIRequest(); @@ -221,7 +226,10 @@ final class Manga extends API $output[$key][] = $entry; } - foreach ($output as &$val) { + unset($entry); + + foreach ($output as &$val) + { $this->sortByName($val, 'manga'); } diff --git a/src/Types/AbstractType.php b/src/Types/AbstractType.php index bbb3ed41..664f3fde 100644 --- a/src/Types/AbstractType.php +++ b/src/Types/AbstractType.php @@ -20,6 +20,17 @@ use ArrayAccess; use LogicException; abstract class AbstractType implements ArrayAccess { + /** + * Populate values for unserializing data + * + * @param $properties + * @return mixed + */ + public static function __set_state($properties) + { + return new static($properties); + } + /** * Sets the properties by using the constructor * diff --git a/src/Types/AnimeFormItem.php b/src/Types/AnimeFormItem.php index af02e058..69a72881 100644 --- a/src/Types/AnimeFormItem.php +++ b/src/Types/AnimeFormItem.php @@ -19,8 +19,4 @@ namespace Aviat\AnimeClient\Types; /** * Type representing an Anime object for display */ -final class AnimeFormItem extends AbstractType { - public $data; - public $id; - public $mal_id; -} +final class AnimeFormItem extends FormItem { } diff --git a/src/Types/AnimeFormItemData.php b/src/Types/AnimeFormItemData.php index 88eb2a13..3befff10 100644 --- a/src/Types/AnimeFormItemData.php +++ b/src/Types/AnimeFormItemData.php @@ -19,12 +19,4 @@ namespace Aviat\AnimeClient\Types; /** * Type representing an Anime object for display */ -final class AnimeFormItemData extends AbstractType { - public $notes; - public $private; - public $progress; - public $rating; - public $reconsumeCount; - public $reconsuming; - public $status; -} +final class AnimeFormItemData extends FormItemData {} diff --git a/src/Types/FormItem.php b/src/Types/FormItem.php new file mode 100644 index 00000000..084a1578 --- /dev/null +++ b/src/Types/FormItem.php @@ -0,0 +1,27 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +/** + * Type representing an Anime object for display + */ +abstract class FormItem extends AbstractType { + public $id; + public $mal_id; + public $data; +} + diff --git a/src/Types/FormItemData.php b/src/Types/FormItemData.php new file mode 100644 index 00000000..1539733e --- /dev/null +++ b/src/Types/FormItemData.php @@ -0,0 +1,30 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +/** + * Type representing an Anime object for display + */ +abstract class FormItemData extends AbstractType { + public $notes; + public $private; + public $progress; + public $rating; + public $reconsumeCount; + public $reconsuming; + public $status; +} diff --git a/src/Types/MangaFormItem.php b/src/Types/MangaFormItem.php new file mode 100644 index 00000000..ecc0dcb9 --- /dev/null +++ b/src/Types/MangaFormItem.php @@ -0,0 +1,23 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +/** + * Form data for updating a Manga List item + */ +final class MangaFormItem extends FormItem { } + diff --git a/src/Types/MangaFormItemData.php b/src/Types/MangaFormItemData.php new file mode 100644 index 00000000..64c9632d --- /dev/null +++ b/src/Types/MangaFormItemData.php @@ -0,0 +1,19 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +final class MangaFormItemData extends FormItemData {} diff --git a/src/Types/MangaListItem.php b/src/Types/MangaListItem.php new file mode 100644 index 00000000..2da37135 --- /dev/null +++ b/src/Types/MangaListItem.php @@ -0,0 +1,40 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +/** + * Type representing an Anime object for display + */ +final class MangaListItem extends AbstractType { + public $id; + public $mal_id; + public $chapters = [ + 'read' => 0, + 'total' => 0, + ]; + public $volumes = [ + 'read' => '-', + 'total' => 0, + ]; + public $manga; + public $reading_status; + public $notes; + public $rereading; + public $reread; + public $user_rating; +} + diff --git a/src/Types/MangaListItemDetail.php b/src/Types/MangaListItemDetail.php new file mode 100644 index 00000000..163901a6 --- /dev/null +++ b/src/Types/MangaListItemDetail.php @@ -0,0 +1,31 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +/** + * Type representing the manga represented by the list item + */ +final class MangaListItemDetail extends AbstractType { + public $genres; + public $id; + public $image; + public $slug; + public $title; + public $titles; + public $type; + public $url; +} diff --git a/src/Types/MangaPage.php b/src/Types/MangaPage.php new file mode 100644 index 00000000..5734d1a5 --- /dev/null +++ b/src/Types/MangaPage.php @@ -0,0 +1,35 @@ + + * @copyright 2015 - 2018 Timothy J. Warren + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @version 4.0 + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient + */ + +namespace Aviat\AnimeClient\Types; + +/** + * Type representing an Anime object for display + */ +final class MangaPage extends AbstractType { + public $chapter_count; + public $cover_image; + public $en_title; + public $genres; + public $id; + public $included; + public $jp_title; + public $manga_type; + public $synopsis; + public $title; + public $url; + public $volume_count; +} diff --git a/tests/API/Kitsu/Transformer/MangaListTransformerTest.php b/tests/API/Kitsu/Transformer/MangaListTransformerTest.php index b68db9d7..8ad6b632 100644 --- a/tests/API/Kitsu/Transformer/MangaListTransformerTest.php +++ b/tests/API/Kitsu/Transformer/MangaListTransformerTest.php @@ -19,6 +19,10 @@ namespace Aviat\AnimeClient\Tests\API\Kitsu\Transformer; use Aviat\AnimeClient\API\JsonAPI; use Aviat\AnimeClient\API\Kitsu\Transformer\MangaListTransformer; use Aviat\AnimeClient\Tests\AnimeClientTestCase; +use Aviat\AnimeClient\Types\{ + MangaFormItem, + MangaFormItemData, +}; use Aviat\Ion\Json; class MangaListTransformerTest extends AnimeClientTestCase { @@ -82,18 +86,18 @@ class MangaListTransformerTest extends AnimeClientTestCase { ]; $actual = $this->transformer->untransform($input); - $expected = [ + $expected = new MangaFormItem([ 'id' => '15084773', 'mal_id' => '26769', - 'data' => [ + 'data' => new MangaFormItemData([ 'status' => 'current', 'progress' => 67, 'reconsuming' => false, 'reconsumeCount' => 0, 'notes' => '', 'rating' => 4.5 - ] - ]; + ]) + ]); $this->assertEquals($expected, $actual); } diff --git a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testTransform__1.php b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testTransform__1.php index 0d1ac07b..d790a572 100644 --- a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testTransform__1.php +++ b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testTransform__1.php @@ -1,46 +1,53 @@ - '15839442', - 'mal_id' => '33206', - 'episodes' => + '15839442', + 'mal_id' => '33206', + 'episodes' => array ( 'watched' => '-', 'total' => '-', 'length' => NULL, ), - 'airing' => + 'airing' => array ( 'status' => 'Currently Airing', 'started' => '2017-01-12', 'ended' => NULL, ), - 'anime' => - array ( - 'id' => '12243', - 'age_rating' => NULL, - 'title' => 'Kobayashi-san Chi no Maid Dragon', - 'titles' => - array ( - 0 => 'Kobayashi-san Chi no Maid Dragon', - 1 => 'Miss Kobayashi\'s Dragon Maid', - 2 => '小林さんちのメイドラゴン', - ), - 'slug' => 'kobayashi-san-chi-no-maid-dragon', - 'type' => 'TV', - 'image' => 'https://media.kitsu.io/anime/poster_images/12243/small.jpg?1481144116', - 'genres' => + 'anime' => + Aviat\AnimeClient\Types\Anime::__set_state(array( + 'age_rating' => NULL, + 'age_rating_guide' => NULL, + 'cover_image' => 'https://media.kitsu.io/anime/poster_images/12243/small.jpg?1481144116', + 'episode_count' => NULL, + 'episode_length' => NULL, + 'genres' => array ( 0 => 'Comedy', 1 => 'Fantasy', 2 => 'Slice of Life', ), - 'streaming_links' => + 'id' => '12243', + 'included' => NULL, + 'show_type' => 'TV', + 'slug' => 'kobayashi-san-chi-no-maid-dragon', + 'status' => NULL, + 'streaming_links' => array ( ), - ), - 'watching_status' => 'current', - 'notes' => NULL, - 'rewatching' => false, - 'rewatched' => 0, - 'user_rating' => '-', - 'private' => false, -); + 'synopsis' => NULL, + 'title' => 'Kobayashi-san Chi no Maid Dragon', + 'titles' => + array ( + 0 => 'Miss Kobayashi\'s Dragon Maid', + 1 => '小林さんちのメイドラゴン', + ), + 'trailer_id' => NULL, + 'url' => NULL, + )), + 'watching_status' => 'current', + 'notes' => NULL, + 'rewatching' => false, + 'rewatched' => 0, + 'user_rating' => '-', + 'private' => false, +)); diff --git a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #0__1.php b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #0__1.php index 2db06bc8..eef4044d 100644 --- a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #0__1.php +++ b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #0__1.php @@ -1,14 +1,14 @@ - 14047981, - 'mal_id' => NULL, - 'data' => - array ( - 'status' => 'current', - 'reconsuming' => false, - 'reconsumeCount' => 0, - 'notes' => 'Very formulaic.', - 'progress' => 38, - 'private' => false, - 'rating' => 4, - ), -); + 14047981, + 'mal_id' => NULL, + 'data' => + Aviat\AnimeClient\Types\AnimeFormItemData::__set_state(array( + 'notes' => 'Very formulaic.', + 'private' => false, + 'progress' => 38, + 'rating' => 4, + 'reconsumeCount' => 0, + 'reconsuming' => false, + 'status' => 'current', + )), +)); diff --git a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #1__1.php b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #1__1.php index de278585..05b25d9f 100644 --- a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #1__1.php +++ b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #1__1.php @@ -1,14 +1,14 @@ - 14047981, - 'mal_id' => '12345', - 'data' => - array ( - 'status' => 'current', - 'reconsuming' => true, - 'reconsumeCount' => 0, - 'notes' => 'Very formulaic.', - 'progress' => 38, - 'private' => true, - 'rating' => 4, - ), -); + 14047981, + 'mal_id' => '12345', + 'data' => + Aviat\AnimeClient\Types\AnimeFormItemData::__set_state(array( + 'notes' => 'Very formulaic.', + 'private' => true, + 'progress' => 38, + 'rating' => 4, + 'reconsumeCount' => 0, + 'reconsuming' => true, + 'status' => 'current', + )), +)); diff --git a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #2__1.php b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #2__1.php index 79fc5db2..5da554fb 100644 --- a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #2__1.php +++ b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #2__1.php @@ -1,13 +1,14 @@ - 14047983, - 'mal_id' => '12347', - 'data' => - array ( - 'status' => 'current', - 'reconsuming' => true, - 'reconsumeCount' => 0, - 'notes' => '', - 'progress' => 12, - 'private' => true, - ), -); + 14047983, + 'mal_id' => '12347', + 'data' => + Aviat\AnimeClient\Types\AnimeFormItemData::__set_state(array( + 'notes' => '', + 'private' => true, + 'progress' => 12, + 'rating' => NULL, + 'reconsumeCount' => 0, + 'reconsuming' => true, + 'status' => 'current', + )), +)); diff --git a/tests/API/Kitsu/Transformer/__snapshots__/AnimeTransformerTest__testTransform__1.php b/tests/API/Kitsu/Transformer/__snapshots__/AnimeTransformerTest__testTransform__1.php index b6f6582c..788c598b 100644 --- a/tests/API/Kitsu/Transformer/__snapshots__/AnimeTransformerTest__testTransform__1.php +++ b/tests/API/Kitsu/Transformer/__snapshots__/AnimeTransformerTest__testTransform__1.php @@ -1,17 +1,18 @@ - 'R', - 'age_rating_guide' => 'Violence, Profanity', - 'cover_image' => 'https://media.kitsu.io/anime/poster_images/7442/small.jpg?1418580054', - 'episode_count' => 25, - 'episode_length' => 24, - 'genres' => + 'R', + 'age_rating_guide' => 'Violence, Profanity', + 'cover_image' => 'https://media.kitsu.io/anime/poster_images/7442/small.jpg?1418580054', + 'episode_count' => 25, + 'episode_length' => 24, + 'genres' => array ( ), - 'id' => 32344, - 'show_type' => 'TV', - 'slug' => 'attack-on-titan', - 'status' => 'Finished Airing', - 'streaming_links' => + 'id' => 32344, + 'included' => NULL, + 'show_type' => 'TV', + 'slug' => 'attack-on-titan', + 'status' => 'Finished Airing', + 'streaming_links' => array ( 0 => array ( @@ -86,16 +87,15 @@ ), ), ), - 'synopsis' => 'Several hundred years ago, humans were nearly exterminated by titans. Titans are typically several stories tall, seem to have no intelligence, devour human beings and, worst of all, seem to do it for the pleasure rather than as a food source. A small percentage of humanity survived by enclosing themselves in a city protected by extremely high walls, even taller than the biggest of titans. Flash forward to the present and the city has not seen a titan in over 100 years. Teenage boy Eren and his foster sister Mikasa witness something horrific as the city walls are destroyed by a colossal titan that appears out of thin air. As the smaller titans flood the city, the two kids watch in horror as their mother is eaten alive. Eren vows that he will murder every single titan and take revenge for all of mankind. + 'synopsis' => 'Several hundred years ago, humans were nearly exterminated by titans. Titans are typically several stories tall, seem to have no intelligence, devour human beings and, worst of all, seem to do it for the pleasure rather than as a food source. A small percentage of humanity survived by enclosing themselves in a city protected by extremely high walls, even taller than the biggest of titans. Flash forward to the present and the city has not seen a titan in over 100 years. Teenage boy Eren and his foster sister Mikasa witness something horrific as the city walls are destroyed by a colossal titan that appears out of thin air. As the smaller titans flood the city, the two kids watch in horror as their mother is eaten alive. Eren vows that he will murder every single titan and take revenge for all of mankind. (Source: ANN)', - 'title' => 'Attack on Titan', - 'titles' => + 'title' => 'Attack on Titan', + 'titles' => array ( - 0 => 'Attack on Titan', - 1 => 'Shingeki no Kyojin', - 2 => '進撃の巨人', + 0 => 'Shingeki no Kyojin', + 1 => '進撃の巨人', ), - 'trailer_id' => 'n4Nj6Y_SNYI', - 'url' => 'https://kitsu.io/anime/attack-on-titan', -); + 'trailer_id' => 'n4Nj6Y_SNYI', + 'url' => 'https://kitsu.io/anime/attack-on-titan', +)); diff --git a/tests/API/Kitsu/Transformer/__snapshots__/MangaListTransformerTest__testTransform__1.php b/tests/API/Kitsu/Transformer/__snapshots__/MangaListTransformerTest__testTransform__1.php index 49334993..1757e57c 100644 --- a/tests/API/Kitsu/Transformer/__snapshots__/MangaListTransformerTest__testTransform__1.php +++ b/tests/API/Kitsu/Transformer/__snapshots__/MangaListTransformerTest__testTransform__1.php @@ -1,31 +1,21 @@ - array ( - 'id' => '15084773', - 'mal_id' => '26769', - 'chapters' => + Aviat\AnimeClient\Types\MangaListItem::__set_state(array( + 'id' => '15084773', + 'mal_id' => '26769', + 'chapters' => array ( 'read' => 67, 'total' => '-', ), - 'volumes' => + 'volumes' => array ( 'read' => '-', 'total' => '-', ), - 'manga' => - array ( - 'id' => '20286', - 'titles' => - array ( - 0 => 'Bokura wa Minna Kawaisou', - ), - 'alternate_title' => NULL, - 'slug' => 'bokura-wa-minna-kawaisou', - 'url' => 'https://kitsu.io/manga/bokura-wa-minna-kawaisou', - 'type' => 'manga', - 'image' => 'https://media.kitsu.io/manga/poster_images/20286/small.jpg?1434293999', - 'genres' => + 'manga' => + Aviat\AnimeClient\Types\MangaListItemDetail::__set_state(array( + 'genres' => array ( 0 => 'Comedy', 1 => 'Romance', @@ -33,40 +23,39 @@ 3 => 'Slice of Life', 4 => 'Thriller', ), - ), - 'reading_status' => 'current', - 'notes' => '', - 'rereading' => false, - 'reread' => 0, - 'user_rating' => 9.0, - ), + 'id' => '20286', + 'image' => 'https://media.kitsu.io/manga/poster_images/20286/small.jpg?1434293999', + 'slug' => 'bokura-wa-minna-kawaisou', + 'title' => 'Bokura wa Minna Kawaisou', + 'titles' => + array ( + ), + 'type' => 'manga', + 'url' => 'https://kitsu.io/manga/bokura-wa-minna-kawaisou', + )), + 'reading_status' => 'current', + 'notes' => '', + 'rereading' => false, + 'reread' => 0, + 'user_rating' => 9.0, + )), 1 => - array ( - 'id' => '15085607', - 'mal_id' => '16', - 'chapters' => + Aviat\AnimeClient\Types\MangaListItem::__set_state(array( + 'id' => '15085607', + 'mal_id' => '16', + 'chapters' => array ( 'read' => 17, 'total' => 120, ), - 'volumes' => + 'volumes' => array ( 'read' => '-', 'total' => 14, ), - 'manga' => - array ( - 'id' => '47', - 'titles' => - array ( - 0 => 'Love Hina', - ), - 'alternate_title' => NULL, - 'slug' => 'love-hina', - 'url' => 'https://kitsu.io/manga/love-hina', - 'type' => 'manga', - 'image' => 'https://media.kitsu.io/manga/poster_images/47/small.jpg?1434249493', - 'genres' => + 'manga' => + Aviat\AnimeClient\Types\MangaListItemDetail::__set_state(array( + 'genres' => array ( 0 => 'Comedy', 1 => 'Ecchi', @@ -74,41 +63,39 @@ 3 => 'Romance', 4 => 'Sports', ), - ), - 'reading_status' => 'current', - 'notes' => '', - 'rereading' => false, - 'reread' => 0, - 'user_rating' => 7.0, - ), + 'id' => '47', + 'image' => 'https://media.kitsu.io/manga/poster_images/47/small.jpg?1434249493', + 'slug' => 'love-hina', + 'title' => 'Love Hina', + 'titles' => + array ( + ), + 'type' => 'manga', + 'url' => 'https://kitsu.io/manga/love-hina', + )), + 'reading_status' => 'current', + 'notes' => '', + 'rereading' => false, + 'reread' => 0, + 'user_rating' => 7.0, + )), 2 => - array ( - 'id' => '15084529', - 'mal_id' => '35003', - 'chapters' => + Aviat\AnimeClient\Types\MangaListItem::__set_state(array( + 'id' => '15084529', + 'mal_id' => '35003', + 'chapters' => array ( 'read' => 16, 'total' => '-', ), - 'volumes' => + 'volumes' => array ( 'read' => '-', 'total' => '-', ), - 'manga' => - array ( - 'id' => '11777', - 'titles' => - array ( - 0 => 'Yamada-kun to 7-nin no Majo', - 1 => 'Yamada-kun and the Seven Witches', - ), - 'alternate_title' => NULL, - 'slug' => 'yamada-kun-to-7-nin-no-majo', - 'url' => 'https://kitsu.io/manga/yamada-kun-to-7-nin-no-majo', - 'type' => 'manga', - 'image' => 'https://media.kitsu.io/manga/poster_images/11777/small.jpg?1438784325', - 'genres' => + 'manga' => + Aviat\AnimeClient\Types\MangaListItemDetail::__set_state(array( + 'genres' => array ( 0 => 'Comedy', 1 => 'Ecchi', @@ -118,89 +105,97 @@ 5 => 'Sports', 6 => 'Supernatural', ), - ), - 'reading_status' => 'current', - 'notes' => '', - 'rereading' => false, - 'reread' => 0, - 'user_rating' => 9.0, - ), + 'id' => '11777', + 'image' => 'https://media.kitsu.io/manga/poster_images/11777/small.jpg?1438784325', + 'slug' => 'yamada-kun-to-7-nin-no-majo', + 'title' => 'Yamada-kun to 7-nin no Majo', + 'titles' => + array ( + 0 => 'Yamada-kun and the Seven Witches', + ), + 'type' => 'manga', + 'url' => 'https://kitsu.io/manga/yamada-kun-to-7-nin-no-majo', + )), + 'reading_status' => 'current', + 'notes' => '', + 'rereading' => false, + 'reread' => 0, + 'user_rating' => 9.0, + )), 3 => - array ( - 'id' => '15312827', - 'mal_id' => '78523', - 'chapters' => + Aviat\AnimeClient\Types\MangaListItem::__set_state(array( + 'id' => '15312827', + 'mal_id' => '78523', + 'chapters' => array ( 'read' => 68, 'total' => '-', ), - 'volumes' => + 'volumes' => array ( 'read' => '-', 'total' => '-', ), - 'manga' => - array ( - 'id' => '27175', - 'titles' => - array ( - 0 => 'ReLIFE', - ), - 'alternate_title' => NULL, - 'slug' => 'relife', - 'url' => 'https://kitsu.io/manga/relife', - 'type' => 'manga', - 'image' => 'https://media.kitsu.io/manga/poster_images/27175/small.jpg?1464379411', - 'genres' => + 'manga' => + Aviat\AnimeClient\Types\MangaListItemDetail::__set_state(array( + 'genres' => array ( 0 => 'Romance', 1 => 'School', 2 => 'Slice of Life', ), - ), - 'reading_status' => 'current', - 'notes' => '', - 'rereading' => false, - 'reread' => 0, - 'user_rating' => '-', - ), + 'id' => '27175', + 'image' => 'https://media.kitsu.io/manga/poster_images/27175/small.jpg?1464379411', + 'slug' => 'relife', + 'title' => 'ReLIFE', + 'titles' => + array ( + ), + 'type' => 'manga', + 'url' => 'https://kitsu.io/manga/relife', + )), + 'reading_status' => 'current', + 'notes' => '', + 'rereading' => false, + 'reread' => 0, + 'user_rating' => '-', + )), 4 => - array ( - 'id' => '15084769', - 'mal_id' => '60815', - 'chapters' => + Aviat\AnimeClient\Types\MangaListItem::__set_state(array( + 'id' => '15084769', + 'mal_id' => '60815', + 'chapters' => array ( 'read' => 43, 'total' => '-', ), - 'volumes' => + 'volumes' => array ( 'read' => '-', 'total' => '-', ), - 'manga' => - array ( - 'id' => '25491', - 'titles' => - array ( - 0 => 'Joshikausei', - ), - 'alternate_title' => NULL, - 'slug' => 'joshikausei', - 'url' => 'https://kitsu.io/manga/joshikausei', - 'type' => 'manga', - 'image' => 'https://media.kitsu.io/manga/poster_images/25491/small.jpg?1434305043', - 'genres' => + 'manga' => + Aviat\AnimeClient\Types\MangaListItemDetail::__set_state(array( + 'genres' => array ( 0 => 'Comedy', 1 => 'School', 2 => 'Slice of Life', ), - ), - 'reading_status' => 'current', - 'notes' => '', - 'rereading' => false, - 'reread' => 0, - 'user_rating' => 8.0, - ), + 'id' => '25491', + 'image' => 'https://media.kitsu.io/manga/poster_images/25491/small.jpg?1434305043', + 'slug' => 'joshikausei', + 'title' => 'Joshikausei', + 'titles' => + array ( + ), + 'type' => 'manga', + 'url' => 'https://kitsu.io/manga/joshikausei', + )), + 'reading_status' => 'current', + 'notes' => '', + 'rereading' => false, + 'reread' => 0, + 'user_rating' => 8.0, + )), ); diff --git a/tests/API/Kitsu/Transformer/__snapshots__/MangaTransformerTest__testTransform__1.php b/tests/API/Kitsu/Transformer/__snapshots__/MangaTransformerTest__testTransform__1.php index 9699bafe..ec814886 100644 --- a/tests/API/Kitsu/Transformer/__snapshots__/MangaTransformerTest__testTransform__1.php +++ b/tests/API/Kitsu/Transformer/__snapshots__/MangaTransformerTest__testTransform__1.php @@ -1,21 +1,17 @@ - '20286', - 'title' => 'Bokura wa Minna Kawaisou', - 'en_title' => NULL, - 'jp_title' => 'Bokura wa Minna Kawaisou', - 'cover_image' => 'https://media.kitsu.io/manga/poster_images/20286/small.jpg?1434293999', - 'manga_type' => 'manga', - 'chapter_count' => '-', - 'volume_count' => '-', - 'synopsis' => 'Usa, a high-school student aspiring to begin a bachelor lifestyle, moves into a new apartment only to discover that he not only shares a room with a perverted roommate that has an obsession for underaged girls, but also that another girl, Ritsu, a love-at-first-sight, is living in the same building as well! -(Source: Kirei Cake)', - 'url' => 'https://kitsu.io/manga/bokura-wa-minna-kawaisou', - 'genres' => + '-', + 'cover_image' => 'https://media.kitsu.io/manga/poster_images/20286/small.jpg?1434293999', + 'en_title' => NULL, + 'genres' => array ( - 0 => 'Comedy', - 1 => 'Romance', - 2 => 'School', - 3 => 'Slice of Life', - 4 => 'Thriller', ), -); + 'id' => '20286', + 'included' => NULL, + 'jp_title' => 'Bokura wa Minna Kawaisou', + 'manga_type' => 'manga', + 'synopsis' => 'Usa, a high-school student aspiring to begin a bachelor lifestyle, moves into a new apartment only to discover that he not only shares a room with a perverted roommate that has an obsession for underaged girls, but also that another girl, Ritsu, a love-at-first-sight, is living in the same building as well! +(Source: Kirei Cake)', + 'title' => 'Bokura wa Minna Kawaisou', + 'url' => 'https://kitsu.io/manga/bokura-wa-minna-kawaisou', + 'volume_count' => '-', +)); From 7a1967b4045b1d9acc02c3d0cd077fd5450e2da7 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Wed, 8 Aug 2018 13:08:10 -0400 Subject: [PATCH 06/17] Fix PHP 7.1 test --- tests/API/Kitsu/Transformer/MangaListTransformerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/API/Kitsu/Transformer/MangaListTransformerTest.php b/tests/API/Kitsu/Transformer/MangaListTransformerTest.php index 8ad6b632..d4d1394e 100644 --- a/tests/API/Kitsu/Transformer/MangaListTransformerTest.php +++ b/tests/API/Kitsu/Transformer/MangaListTransformerTest.php @@ -21,7 +21,7 @@ use Aviat\AnimeClient\API\Kitsu\Transformer\MangaListTransformer; use Aviat\AnimeClient\Tests\AnimeClientTestCase; use Aviat\AnimeClient\Types\{ MangaFormItem, - MangaFormItemData, + MangaFormItemData }; use Aviat\Ion\Json; From 28e4f22d7c2e99bdce3ce26a66e265d7dc36e140 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Wed, 8 Aug 2018 17:04:35 -0400 Subject: [PATCH 07/17] First go at tabs for collection --- app/views/collection/cover.php | 57 ++++++++++++++------------ app/views/header.php | 4 +- app/views/manga/edit.php | 2 +- public/css/app.min.css | 2 +- public/css/base.css | 73 +++++++++++++++++++++++++++++++++- 5 files changed, 108 insertions(+), 30 deletions(-) diff --git a/app/views/collection/cover.php b/app/views/collection/cover.php index 6ae83460..9f82b9ae 100644 --- a/app/views/collection/cover.php +++ b/app/views/collection/cover.php @@ -5,40 +5,47 @@

There's nothing here!

+
+ $items): ?> -
+ type="radio" id="collection-tab-" name="collection-tabs" /> + +

- - +
-
+
+ +
diff --git a/app/views/header.php b/app/views/header.php index 5a95e909..4a7de884 100644 --- a/app/views/header.php +++ b/app/views/header.php @@ -1,11 +1,11 @@ + <?= $title ?> - - + diff --git a/app/views/manga/edit.php b/app/views/manga/edit.php index 12b3c077..29c34733 100644 --- a/app/views/manga/edit.php +++ b/app/views/manga/edit.php @@ -47,7 +47,7 @@ - / + */ ?> - / diff --git a/public/css/app.min.css b/public/css/app.min.css index d0884ff6..916e0608 100644 --- a/public/css/app.min.css +++ b/public/css/app.min.css @@ -1 +1 @@ -:root{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;line-height:1.4;overflow-y:scroll;-moz-text-size-adjust:100%;text-size-adjust:100%;scroll-behavior:smooth}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6em 1.6em;padding:0 16px 16px;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{background:#efefef;color:#444;font-family:"Anonymous Pro","Fira Code",Menlo,Monaco,Consolas,"Courier New",monospace;font-size:1.4em;font-size:14px;font-size:1.4rem;margin:1.6em 0;margin:16px 0;margin:1.6rem 0;overflow:auto;padding:1.6em;padding:16px;padding:1.6rem;word-break:break-all;word-wrap:break-word}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:1px solid #ccc;border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:8px;margin-bottom:.8rem;overflow:auto;padding:8px;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{border-style:solid;border-width:0;-webkit-box-sizing:inherit;box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{-webkit-transition:.25s ease;color:#1271db;text-decoration:none;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}button,input,select,textarea{border:1px solid #ccc;border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:"Anonymous Pro","Fira Code",Menlo,Monaco,Consolas,"Courier New",monospace}table{border-collapse:collapse;border-spacing:0;margin-bottom:16px;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:16px;font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 16px;margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;margin:2em 0 1.6em;margin:20px 0 16px;margin:2rem 0 1.6rem}h1{border-bottom:1px solid rgba(0,0,0,.2);border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:36px;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:30px;font-size:3rem}h3{font-size:2.4em;font-size:24px;font-size:2.4rem;font-style:normal;font-weight:500;margin:16px 0 4px;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:18px;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:16px 0 4px;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:16px;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:16px 0 4px;margin:1.6rem 0 .4rem}code,h6{font-size:14px;font-size:1.4rem}code{background:#efefef;color:#444;font-family:"Anonymous Pro","Fira Code",Menlo,Monaco,Consolas,"Courier New",monospace;word-break:break-all;word-wrap:break-word}a:focus,a:hover{text-decoration:none}dl{margin-bottom:16px;margin-bottom:1.6rem}dd{margin-left:40px;margin-left:4rem}ol,ul{margin-bottom:8px;margin-bottom:.8rem;padding-left:20px;padding-left:2rem}blockquote{border-left:2px solid #1271db;border-left:.2rem solid #1271db;font-style:italic;margin:16px 0;margin:1.6rem 0;padding-left:16px;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,"Times New Roman",serif}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:10px 0;padding:1rem 0;text-align:center}footer,hr{border-top:1px solid rgba(0,0,0,.2);border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:16px;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select{border:1px solid #ccc;border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:8px;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:1px solid #ccc;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:8px;padding:.8rem;text-align:left}input[type=color]{padding:8px 16px;padding:.8rem 1.6rem}input:not([type]):focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin solid #444}input:not([type])[disabled],input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],select[disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],select[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select{background-color:#fff;border:1px solid #ccc;border:.1rem solid #ccc}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:8px 0;padding:.8rem 0}legend{border-bottom:1px solid #ccc;border-bottom:.1rem solid #ccc;display:block;padding:8px 0;padding:.8rem 0;width:100%}button,input[type=submit],legend{color:#444;margin-bottom:8px;margin-bottom:.8rem}button,input[type=submit]{-moz-user-select:none;-ms-user-select:none;-webkit-transition:.25s ease;-webkit-user-drag:none;-webkit-user-select:none;border:2px solid #444;border:.2rem solid #444;border-radius:0;cursor:pointer;display:inline-block;margin-right:4px;margin-right:.4rem;padding:8px 16px;padding:.8rem 1.6rem;text-align:center;text-decoration:none;text-transform:uppercase;transition:.25s ease;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{-webkit-box-shadow:none;box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{-webkit-transition:.25s ease;border-bottom:2px solid transparent;border-bottom:.2rem solid transparent;color:#444;padding:8px 16px;padding:.8rem 1.6rem;text-decoration:none;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:8px 0;padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:8px;margin-bottom:.8rem}td,th{border:1px solid #ccc;border:.1rem solid #ccc;padding:8px 16px;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:8px;font-size:.8rem;font-style:italic;padding:16px 4px;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:rgba(255,255,255,.65);margin:0}table{min-width:85%;margin:0 auto}td{padding:1em;padding:10px;padding:1rem}thead td,thead th{padding:.5em;padding:5px;padding:.5rem}input[type=number]{width:4em}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db}.bracketed{color:#12db18}.bracketed,h1 a{text-shadow:1px 1px 1px #000}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12}.grow-1{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.flex-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-no-wrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-align-end{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.flex-align-space-around{-ms-flex-line-pack:distribute;align-content:space-around}.flex-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.flex-self-center{-ms-flex-item-align:center;align-self:center}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.small-font{font-size:16px;font-size:1.6rem}.justify{text-align:justify}.align_center{text-align:center!important}.align_left{text-align:left!important}.align_right{text-align:right!important}.valign_top{vertical-align:top}.no_border{border:none}.media-wrap{text-align:center;margin:0 auto}.danger{background-color:#ff4136;border-color:#924949;color:#fff}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#fff}.user-btn{border-color:#12db18;color:#12db18;text-shadow:1px 1px 1px #000;padding:0 .5em;padding:0 5px;padding:0 .5rem}.user-btn:active,.user-btn:hover{border-color:#db7d12;background-color:#db7d12}.full_width{width:100%}.cssload-loader{position:relative;left:calc(50% - 31px);width:62px;height:62px;border-radius:50%;-webkit-perspective:780px;perspective:780px}.cssload-inner{position:absolute;width:100%;height:100%;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:50%}.cssload-inner.cssload-one{left:0;top:0;-webkit-animation:a 1.15s linear infinite;animation:a 1.15s linear infinite;border-bottom:3px solid rgb(0,0,0)}.cssload-inner.cssload-two{right:0;top:0;-webkit-animation:b 1.15s linear infinite;animation:b 1.15s linear infinite;border-right:3px solid rgb(0,0,0)}.cssload-inner.cssload-three{right:0;bottom:0;-webkit-animation:c 1.15s linear infinite;animation:c 1.15s linear infinite;border-top:3px solid rgb(0,0,0)}@-webkit-keyframes a{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes a{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@-webkit-keyframes b{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes b{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@-webkit-keyframes c{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}@keyframes c{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}.sorting,.sorting_asc,.sorting_desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting_asc:before{content:" ↑\00a0"}.sorting_desc:before{content:" ↓\00a0"}.form{width:100%}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){text-align:right;min-width:25px;max-width:30%}.form tr>td:nth-child(2n){text-align:left;width:70%}.invisible tbody>tr:nth-child(odd){background:inherit}.invisible td,.invisible th,.invisible tr{border:0}.message{position:relative;margin:.5em auto;padding:.5em;width:95%}.message .close{width:1em;height:1em;position:absolute;right:.5em;top:.5em;text-align:center;vertical-align:middle;line-height:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;top:.5em;margin-right:1em}.message.error{border:1px solid #924949;background:#f3e6e6}.message.error .icon:after{content:"✘"}.message.success{border:1px solid #1f8454;background:#70dda9}.message.success .icon:after{content:"✔"}.message.info{border:1px solid #bfbe3a;background:#FFFFCC}.message.info .icon:after{content:"⚠"}.character,.media,.small_character{position:relative;vertical-align:top;display:inline-block;text-align:center;width:220px;height:311px;margin:.25em .125em}.character>img,.media>img,.small_character>img{width:100%}.media .edit_buttons>button{margin:.5em auto}.media_metadata>div,.medium_metadata>div,.name,.row{text-shadow:1px 2px 1px rgba(0,0,0,.85);background:#000;background:rgba(0,0,0,.45);color:#ffffff;padding:.25em .125em;text-align:right}.age_rating,.media_type{text-align:left}.media>.media_metadata{position:absolute;bottom:0;right:0}.media>.medium_metadata{position:absolute;bottom:0;left:0}.media>.name{position:absolute;top:0}.character:hover>.name,.media:hover>.media_metadata>div,.media:hover>.medium_metadata>div,.media:hover>.name,.media:hover>.table .row,.small_character:hover>.name{-webkit-transition:.25s ease;transition:.25s ease;background:rgba(0,0,0,.75)}.media:hover>.edit_buttons[hidden],.media:hover>button[hidden]{-webkit-transition:.25s ease;transition:.25s ease;display:block}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small_character>.name a,.small_character>.name a small{background:none;color:#fff;text-shadow:1px 2px 1px rgba(0,0,0,.85)}.anime .name,.manga .name{text-align:center;width:100%;padding:.5em .25em}.anime .age_rating,.anime .airing_status,.anime .completion,.anime .delete,.anime .edit,.anime .media_type,.anime .user_rating{background:none;text-align:center}.anime .table,.manga .table{position:absolute;bottom:0;left:0;width:100%}.anime .row,.manga .row{width:100%;background:#000;background:rgba(0,0,0,.45);display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-line-pack:distribute;align-content:space-around;-ms-flex-pack:distribute;justify-content:space-around;text-align:center;padding:0 inherit}.anime .row>span,.manga .row>span{text-align:left}.anime .row>div,.manga .row>div{font-size:.8em;display:flex-item;-ms-flex-item-align:center;align-self:center;text-align:center;vertical-align:middle}.anime .media>button.plus_one{position:absolute;top:138px;top:calc(50% - 21.5px);left:44px;left:calc(50% - 66.5px)}.manga .row{padding:1px}.manga .media{border:1px solid #ddd;height:310px;margin:.25em}.manga .media>.edit_buttons{position:absolute;top:86px;top:calc(50% - 58.5px);left:43.5px;left:calc(50% - 66.5px)}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35);background-size:cover;background-size:contain;background-repeat:no-repeat}.big-check{display:none}.big-check:checked+label{-webkit-transition:.25s ease;transition:.25s ease;background:rgba(0,0,0,.75)}.big-check:checked+label:after{content:"✓";font-size:15em;font-size:150px;font-size:15rem;text-align:center;color:greenyellow;position:absolute;top:147px;left:0;height:100%;width:100%}#series_list article.media{position:relative}#series_list .name,#series_list .name label{position:absolute;display:block;top:0;left:0;height:100%;width:100%;vertical-align:middle;line-height:1.25em}#series_list .name small{color:#fff}.details{margin:15px auto 0;margin:1.5rem auto 0;padding:10px;padding:1rem;font-size:inherit}.description{max-width:800px;max-width:80rem}.fixed{max-width:930px;max-width:93rem}.details .cover{display:block;width:284px}.details h2{margin-top:0}.details .flex>div{margin:10px;margin:1rem}.details .media_details{max-width:300px}.details .media_details td{padding:0 15px;padding:0 1.5rem}.details p{text-align:justify}.details .media_details td:nth-child(odd){width:1%;white-space:nowrap;text-align:right}.details .media_details td:nth-child(2n){text-align:left}.character,.small_character{background:rgba(0,0,0,.5);width:225px;height:350px;vertical-align:middle;white-space:nowrap}.small_character a{display:inline-block;width:100%;height:100%}.character .name,.small_character .name{position:absolute;bottom:0;left:0;z-index:2}.character img,.small_character img{position:relative;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);z-index:1;width:100%}.min-table{min-width:0;margin-left:0}.small_character{width:160px;height:250px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;width:100%;height:100%}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}.media{margin:2px 0}main{padding:0 0,5em .5em;padding:0 .5rem .5rem}}.streaming-logo{width:50px;height:50px;vertical-align:middle}.cover_streaming_link .streaming-logo{width:20px;height:20px}#loading-shadow{background:rgba(0,0,0,.8);z-index:3}#loading-shadow,#loading-shadow .loading-wrapper{position:fixed;top:0;left:0;width:100%;height:100%}#loading-shadow .loading-wrapper{z-index:4;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}#loading-shadow .loading-content{position:relative;color:#fff}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff} \ No newline at end of file +:root{-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-box-sizing:border-box;-webkit-text-size-adjust:100%;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;line-height:1.4;overflow-y:scroll;scroll-behavior:smooth;text-size-adjust:100%}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-size:1.4em;font-size:14px;font-size:1.4rem;margin:1.6rem 0;overflow:auto;padding:1.6rem;word-break:break-all;word-wrap:break-word}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:.8rem;overflow:auto;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{-webkit-box-sizing:inherit;border-style:solid;border-width:0;box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{-webkit-transition:.25s ease;color:#1271db;text-decoration:none;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}button,input,select,textarea{border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace}table{border-collapse:collapse;border-spacing:0;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:16px;font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;margin:2rem 0 1.6rem}h1{border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:36px;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:30px;font-size:3rem}h3{font-size:2.4em;font-size:24px;font-size:2.4rem;font-style:normal;font-weight:500;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:18px;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:16px;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}code,h6{font-size:14px;font-size:1.4rem}code{background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;word-break:break-all;word-wrap:break-word}a:focus,a:hover{text-decoration:none}dl{margin-bottom:1.6rem}dd{margin-left:4rem}ol,ul{margin-bottom:.8rem;padding-left:2rem}blockquote{border-left:.2rem solid #1271db;font-style:italic;margin:1.6rem 0;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,Times New Roman,serif}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:1rem 0;text-align:center}footer,hr{border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select{border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:.8rem;text-align:left}input[type=color]{padding:.8rem 1.6rem}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border-color:#b3d4fc}input:not([type]):focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:1px thin solid #444;outline:.1rem thin solid #444}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],select[disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input:not([type])[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],select[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select{background-color:#fff;border:.1rem solid #ccc}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:.8rem 0}legend{border-bottom:.1rem solid #ccc;color:#444;display:block;margin-bottom:.8rem;padding:.8rem 0;width:100%}button,input[type=submit]{-moz-user-select:none;-ms-user-select:none;-webkit-transition:.25s ease;-webkit-user-drag:none;-webkit-user-select:none;border:.2rem solid #444;border-radius:0;color:#444;cursor:pointer;display:inline-block;margin-bottom:.8rem;margin-right:.4rem;padding:.8rem 1.6rem;text-align:center;text-decoration:none;text-transform:uppercase;transition:.25s ease;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{-webkit-box-shadow:none;box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{-webkit-transition:.25s ease;border-bottom:.2rem solid transparent;color:#444;padding:.8rem 1.6rem;text-decoration:none;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:.8rem}td,th{border:.1rem solid #ccc;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:8px;font-size:.8rem;font-style:italic;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:hsla(0,0%,100%,.65);margin:0}table{margin:0 auto;min-width:85%}td{padding:1rem}thead td,thead th{padding:.5rem}input[type=number]{width:4em}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db}.bracketed{color:#12db18}.bracketed,h1 a{text-shadow:1px 1px 1px #000}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12}.grow-1{-ms-flex-positive:1;-webkit-box-flex:1;flex-grow:1}.flex-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-no-wrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-align-end{-ms-flex-align:end;-webkit-box-align:end;align-items:flex-end}.flex-align-space-around{-ms-flex-line-pack:distribute;align-content:space-around}.flex-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.flex-self-center{-ms-flex-item-align:center;align-self:center}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.small-font{font-size:16px;font-size:1.6rem}.justify{text-align:justify}.align_center{text-align:center!important}.align_left{text-align:left!important}.align_right{text-align:right!important}.valign_top{vertical-align:top}.no_border{border:none}.media-wrap{margin:0 auto;text-align:center}.danger{background-color:#ff4136;border-color:#924949;color:#fff}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#fff}.user-btn{border-color:#12db18;color:#12db18;padding:0 .5rem;text-shadow:1px 1px 1px #000}.user-btn:active,.user-btn:hover{background-color:#db7d12;border-color:#db7d12}.full_width{width:100%}.cssload-loader{-webkit-perspective:780px;border-radius:50%;height:62px;left:calc(50% - 31px);perspective:780px;position:relative;width:62px}.cssload-inner{-webkit-box-sizing:border-box;border-radius:50%;box-sizing:border-box;height:100%;position:absolute;width:100%}.cssload-inner.cssload-one{-webkit-animation:cssload-rotate-one 1.15s linear infinite;animation:cssload-rotate-one 1.15s linear infinite;border-bottom:3px solid #000;left:0;top:0}.cssload-inner.cssload-two{-webkit-animation:cssload-rotate-two 1.15s linear infinite;animation:cssload-rotate-two 1.15s linear infinite;border-right:3px solid #000;right:0;top:0}.cssload-inner.cssload-three{-webkit-animation:cssload-rotate-three 1.15s linear infinite;animation:cssload-rotate-three 1.15s linear infinite;border-top:3px solid #000;bottom:0;right:0}@-webkit-keyframes cssload-rotate-one{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes cssload-rotate-one{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-two{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes cssload-rotate-two{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-three{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}@keyframes cssload-rotate-three{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}.sorting,.sorting_asc,.sorting_desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting_asc:before{content:" ↑\00a0"}.sorting_desc:before{content:" ↓\00a0"}.form{width:100%}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){max-width:30%;min-width:25px;text-align:right}.form tr>td:nth-child(2n){text-align:left;width:70%}.invisible tbody>tr:nth-child(odd){background:inherit}.invisible td,.invisible th,.invisible tr{border:0}.message{margin:.5em auto;padding:.5em;position:relative;width:95%}.message .close{height:1em;line-height:1em;position:absolute;right:.5em;text-align:center;top:.5em;vertical-align:middle;width:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;margin-right:1em;top:.5em}.message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info{background:#ffc;border:1px solid #bfbe3a}.message.info .icon:after{content:"⚠"}.character,.media,.small_character{display:inline-block;height:311px;margin:.25em .125em;position:relative;text-align:center;vertical-align:top;width:220px}.character>img,.media>img,.small_character>img{width:100%}.media .edit_buttons>button{margin:.5em auto}.media_metadata>div,.medium_metadata>div,.name,.row{background:#000;background:rgba(0,0,0,.45);color:#fff;padding:.25em .125em;text-align:right;text-shadow:1px 2px 1px rgba(0,0,0,.85)}.age_rating,.media_type{text-align:left}.media>.media_metadata{bottom:0;position:absolute;right:0}.media>.medium_metadata{bottom:0;left:0;position:absolute}.media>.name{position:absolute;top:0}.character:hover>.name,.media:hover>.media_metadata>div,.media:hover>.medium_metadata>div,.media:hover>.name,.media:hover>.table .row,.small_character:hover>.name{-webkit-transition:.25s ease;background:rgba(0,0,0,.75);transition:.25s ease}.media:hover>.edit_buttons[hidden],.media:hover>button[hidden]{-webkit-transition:.25s ease;display:block;transition:.25s ease}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small_character>.name a,.small_character>.name a small{background:none;color:#fff;text-shadow:1px 2px 1px rgba(0,0,0,.85)}.anime .name,.manga .name{padding:.5em .25em;text-align:center;width:100%}.anime .age_rating,.anime .airing_status,.anime .completion,.anime .delete,.anime .edit,.anime .media_type,.anime .user_rating{background:none;text-align:center}.anime .table,.manga .table{bottom:0;left:0;position:absolute;width:100%}.anime .row,.manga .row{-ms-flex-line-pack:distribute;-ms-flex-pack:distribute;align-content:space-around;background:#000;background:rgba(0,0,0,.45);display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:space-around;padding:0 inherit;text-align:center;width:100%}.anime .row>span,.manga .row>span{text-align:left}.anime .row>div,.manga .row>div{-ms-flex-item-align:center;align-self:center;display:flex-item;font-size:.8em;text-align:center;vertical-align:middle}.anime .media>button.plus_one{left:44px;left:calc(50% - 66.5px);position:absolute;top:138px;top:calc(50% - 21.5px)}.manga .row{padding:1px}.manga .media{border:1px solid #ddd;height:310px;margin:.25em}.manga .media>.edit_buttons{left:43.5px;left:calc(50% - 66.5px);position:absolute;top:86px;top:calc(50% - 58.5px)}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35);background-repeat:no-repeat;background-size:cover;background-size:contain}.big-check{display:none}.big-check:checked+label{-webkit-transition:.25s ease;background:rgba(0,0,0,.75);transition:.25s ease}.big-check:checked+label:after{color:#adff2f;content:"✓";font-size:15em;font-size:150px;font-size:15rem;height:100%;left:0;position:absolute;text-align:center;top:147px;width:100%}#series_list article.media{position:relative}#series_list .name,#series_list .name label{display:block;height:100%;left:0;line-height:1.25em;position:absolute;top:0;vertical-align:middle;width:100%}#series_list .name small{color:#fff}.details{font-size:inherit;margin:1.5rem auto 0;padding:1rem}.description{max-width:800px;max-width:80rem}.fixed{max-width:930px;max-width:93rem}.details .cover{display:block;width:284px}.details h2{margin-top:0}.details .flex>div{margin:1rem}.details .media_details{max-width:300px}.details .media_details td{padding:0 1.5rem}.details p{text-align:justify}.details .media_details td:nth-child(odd){text-align:right;white-space:nowrap;width:1%}.details .media_details td:nth-child(2n){text-align:left}.character,.small_character{background:rgba(0,0,0,.5);height:350px;vertical-align:middle;white-space:nowrap;width:225px}.small_character a{display:inline-block;height:100%;width:100%}.character .name,.small_character .name{bottom:0;left:0;position:absolute;z-index:10}.character img,.small_character img{-webkit-transform:translateY(-50%);position:relative;top:50%;transform:translateY(-50%);width:100%;z-index:5}.min-table{margin-left:0;min-width:0}.small_character{height:250px;width:160px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;height:100%;width:100%}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}.media{margin:2px 0}main{padding:0 .5rem .5rem}}.streaming-logo{height:50px;vertical-align:middle;width:50px}.cover_streaming_link .streaming-logo{height:20px;width:20px}#loading-shadow{background:rgba(0,0,0,.8);z-index:500}#loading-shadow,#loading-shadow .loading-wrapper{height:100%;left:0;position:fixed;top:0;width:100%}#loading-shadow .loading-wrapper{-ms-flex-align:center;-ms-flex-pack:center;-webkit-box-align:center;-webkit-box-pack:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:center;z-index:501}#loading-shadow .loading-content{color:#fff;position:relative}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff}.tabs{-ms-flex-wrap:wrap;-webkit-box-shadow:0 48px 80px -32px rgba(0,0,0,.3);background:#efefef;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:-webkit-box;display:-ms-flexbox;display:flex;flex-wrap:wrap;margin-top:1.5em}.tabs label{-webkit-transition:background .1s,color .1s;background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:20px 30px;transition:background .1s,color .1s;width:100%}.tabs label:hover{background:#d8d8d8}.tabs label:active{background:#ccc}.tabs [type=radio]:focus+label{-webkit-box-shadow:inset 0 0 0 3px #2aa1c0;box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.tabs [type=radio]{opacity:0;position:absolute}.tabs [type=radio]:checked+label{background:#fff;border-bottom:1px solid #fff;color:#000}.tabs [type=radio]:checked+label+.content{background:#fff;border:1px solid #e5e5e5;border-top:0;display:block;padding:20px 30px 30px;width:100%}.tabs .content{display:none}@media (min-width:600px){.tabs label{width:auto}.tabs .content{-ms-flex-order:99;-webkit-box-ordinal-group:100;order:99}} \ No newline at end of file diff --git a/public/css/base.css b/public/css/base.css index 2e01381f..094e18d3 100644 --- a/public/css/base.css +++ b/public/css/base.css @@ -685,4 +685,75 @@ a:hover, a:active { .loading-content .cssload-inner.cssload-two, .loading-content .cssload-inner.cssload-three { border-color: #fff - } \ No newline at end of file + } + +/* ---------------------------------------------------------------------------- +CSS Tabs +-----------------------------------------------------------------------------*/ +.tabs { + display: flex; + flex-wrap: wrap; + background: #efefef; + box-shadow: 0 48px 80px -32px rgba(0,0,0,0.3); + margin-top: 1.5em; +} + +.tabs label { + border: 1px solid #e5e5e5; + width: 100%; + padding: 20px 30px; + background: #e5e5e5; + cursor: pointer; + font-weight: bold; + font-size: 18px; + color: #7f7f7f; + transition: background 0.1s, color 0.1s; + /* margin-left: 4em; */ +} + +.tabs label:hover { + background: #d8d8d8; +} + +.tabs label:active { + background: #ccc; +} + +.tabs [type=radio]:focus + label { + box-shadow: inset 0px 0px 0px 3px #2aa1c0; + z-index: 1; +} + +.tabs [type=radio] { + position: absolute; + opacity: 0; +} + +.tabs [type=radio]:checked + label { + border-bottom: 1px solid #fff; + background: #fff; + color: #000; +} + +.tabs [type=radio]:checked + label + .content{ + border: 1px solid #e5e5e5; + border-top: 0; + display: block; + padding: 20px 30px 30px; + background: #fff; + width: 100%; +} + +.tabs .content { + display: none; +} + +@media (min-width: 600px) { + .tabs label { + width: auto; + } + + .tabs .content { + order: 99; + } +} \ No newline at end of file From 6e588442869d2228f2b5442d301a7558997f8fd1 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Thu, 9 Aug 2018 11:14:57 -0400 Subject: [PATCH 08/17] More tabs for collections, see issue #2 --- app/views/collection/list.php | 9 ++++++++- public/css/app.min.css | 2 +- public/css/base.css | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/views/collection/list.php b/app/views/collection/list.php index 8d0bb6c3..f5ab3be5 100644 --- a/app/views/collection/list.php +++ b/app/views/collection/list.php @@ -5,7 +5,12 @@

There's nothing here!

+ +
$items): ?> + type="radio" id="collection-tab-" name="collection-tabs" /> + +

@@ -44,8 +49,10 @@
-
+
+ +
\ No newline at end of file diff --git a/public/css/app.min.css b/public/css/app.min.css index 916e0608..74963dfc 100644 --- a/public/css/app.min.css +++ b/public/css/app.min.css @@ -1 +1 @@ -:root{-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-box-sizing:border-box;-webkit-text-size-adjust:100%;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;line-height:1.4;overflow-y:scroll;scroll-behavior:smooth;text-size-adjust:100%}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-size:1.4em;font-size:14px;font-size:1.4rem;margin:1.6rem 0;overflow:auto;padding:1.6rem;word-break:break-all;word-wrap:break-word}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:.8rem;overflow:auto;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{-webkit-box-sizing:inherit;border-style:solid;border-width:0;box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{-webkit-transition:.25s ease;color:#1271db;text-decoration:none;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}button,input,select,textarea{border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace}table{border-collapse:collapse;border-spacing:0;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:16px;font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;margin:2rem 0 1.6rem}h1{border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:36px;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:30px;font-size:3rem}h3{font-size:2.4em;font-size:24px;font-size:2.4rem;font-style:normal;font-weight:500;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:18px;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:16px;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}code,h6{font-size:14px;font-size:1.4rem}code{background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;word-break:break-all;word-wrap:break-word}a:focus,a:hover{text-decoration:none}dl{margin-bottom:1.6rem}dd{margin-left:4rem}ol,ul{margin-bottom:.8rem;padding-left:2rem}blockquote{border-left:.2rem solid #1271db;font-style:italic;margin:1.6rem 0;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,Times New Roman,serif}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:1rem 0;text-align:center}footer,hr{border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select{border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:.8rem;text-align:left}input[type=color]{padding:.8rem 1.6rem}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border-color:#b3d4fc}input:not([type]):focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:1px thin solid #444;outline:.1rem thin solid #444}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],select[disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input:not([type])[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],select[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select{background-color:#fff;border:.1rem solid #ccc}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:.8rem 0}legend{border-bottom:.1rem solid #ccc;color:#444;display:block;margin-bottom:.8rem;padding:.8rem 0;width:100%}button,input[type=submit]{-moz-user-select:none;-ms-user-select:none;-webkit-transition:.25s ease;-webkit-user-drag:none;-webkit-user-select:none;border:.2rem solid #444;border-radius:0;color:#444;cursor:pointer;display:inline-block;margin-bottom:.8rem;margin-right:.4rem;padding:.8rem 1.6rem;text-align:center;text-decoration:none;text-transform:uppercase;transition:.25s ease;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{-webkit-box-shadow:none;box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{-webkit-transition:.25s ease;border-bottom:.2rem solid transparent;color:#444;padding:.8rem 1.6rem;text-decoration:none;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:.8rem}td,th{border:.1rem solid #ccc;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:8px;font-size:.8rem;font-style:italic;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:hsla(0,0%,100%,.65);margin:0}table{margin:0 auto;min-width:85%}td{padding:1rem}thead td,thead th{padding:.5rem}input[type=number]{width:4em}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db}.bracketed{color:#12db18}.bracketed,h1 a{text-shadow:1px 1px 1px #000}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12}.grow-1{-ms-flex-positive:1;-webkit-box-flex:1;flex-grow:1}.flex-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-no-wrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-align-end{-ms-flex-align:end;-webkit-box-align:end;align-items:flex-end}.flex-align-space-around{-ms-flex-line-pack:distribute;align-content:space-around}.flex-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.flex-self-center{-ms-flex-item-align:center;align-self:center}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.small-font{font-size:16px;font-size:1.6rem}.justify{text-align:justify}.align_center{text-align:center!important}.align_left{text-align:left!important}.align_right{text-align:right!important}.valign_top{vertical-align:top}.no_border{border:none}.media-wrap{margin:0 auto;text-align:center}.danger{background-color:#ff4136;border-color:#924949;color:#fff}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#fff}.user-btn{border-color:#12db18;color:#12db18;padding:0 .5rem;text-shadow:1px 1px 1px #000}.user-btn:active,.user-btn:hover{background-color:#db7d12;border-color:#db7d12}.full_width{width:100%}.cssload-loader{-webkit-perspective:780px;border-radius:50%;height:62px;left:calc(50% - 31px);perspective:780px;position:relative;width:62px}.cssload-inner{-webkit-box-sizing:border-box;border-radius:50%;box-sizing:border-box;height:100%;position:absolute;width:100%}.cssload-inner.cssload-one{-webkit-animation:cssload-rotate-one 1.15s linear infinite;animation:cssload-rotate-one 1.15s linear infinite;border-bottom:3px solid #000;left:0;top:0}.cssload-inner.cssload-two{-webkit-animation:cssload-rotate-two 1.15s linear infinite;animation:cssload-rotate-two 1.15s linear infinite;border-right:3px solid #000;right:0;top:0}.cssload-inner.cssload-three{-webkit-animation:cssload-rotate-three 1.15s linear infinite;animation:cssload-rotate-three 1.15s linear infinite;border-top:3px solid #000;bottom:0;right:0}@-webkit-keyframes cssload-rotate-one{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes cssload-rotate-one{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-two{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes cssload-rotate-two{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-three{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}@keyframes cssload-rotate-three{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}.sorting,.sorting_asc,.sorting_desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting_asc:before{content:" ↑\00a0"}.sorting_desc:before{content:" ↓\00a0"}.form{width:100%}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){max-width:30%;min-width:25px;text-align:right}.form tr>td:nth-child(2n){text-align:left;width:70%}.invisible tbody>tr:nth-child(odd){background:inherit}.invisible td,.invisible th,.invisible tr{border:0}.message{margin:.5em auto;padding:.5em;position:relative;width:95%}.message .close{height:1em;line-height:1em;position:absolute;right:.5em;text-align:center;top:.5em;vertical-align:middle;width:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;margin-right:1em;top:.5em}.message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info{background:#ffc;border:1px solid #bfbe3a}.message.info .icon:after{content:"⚠"}.character,.media,.small_character{display:inline-block;height:311px;margin:.25em .125em;position:relative;text-align:center;vertical-align:top;width:220px}.character>img,.media>img,.small_character>img{width:100%}.media .edit_buttons>button{margin:.5em auto}.media_metadata>div,.medium_metadata>div,.name,.row{background:#000;background:rgba(0,0,0,.45);color:#fff;padding:.25em .125em;text-align:right;text-shadow:1px 2px 1px rgba(0,0,0,.85)}.age_rating,.media_type{text-align:left}.media>.media_metadata{bottom:0;position:absolute;right:0}.media>.medium_metadata{bottom:0;left:0;position:absolute}.media>.name{position:absolute;top:0}.character:hover>.name,.media:hover>.media_metadata>div,.media:hover>.medium_metadata>div,.media:hover>.name,.media:hover>.table .row,.small_character:hover>.name{-webkit-transition:.25s ease;background:rgba(0,0,0,.75);transition:.25s ease}.media:hover>.edit_buttons[hidden],.media:hover>button[hidden]{-webkit-transition:.25s ease;display:block;transition:.25s ease}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small_character>.name a,.small_character>.name a small{background:none;color:#fff;text-shadow:1px 2px 1px rgba(0,0,0,.85)}.anime .name,.manga .name{padding:.5em .25em;text-align:center;width:100%}.anime .age_rating,.anime .airing_status,.anime .completion,.anime .delete,.anime .edit,.anime .media_type,.anime .user_rating{background:none;text-align:center}.anime .table,.manga .table{bottom:0;left:0;position:absolute;width:100%}.anime .row,.manga .row{-ms-flex-line-pack:distribute;-ms-flex-pack:distribute;align-content:space-around;background:#000;background:rgba(0,0,0,.45);display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:space-around;padding:0 inherit;text-align:center;width:100%}.anime .row>span,.manga .row>span{text-align:left}.anime .row>div,.manga .row>div{-ms-flex-item-align:center;align-self:center;display:flex-item;font-size:.8em;text-align:center;vertical-align:middle}.anime .media>button.plus_one{left:44px;left:calc(50% - 66.5px);position:absolute;top:138px;top:calc(50% - 21.5px)}.manga .row{padding:1px}.manga .media{border:1px solid #ddd;height:310px;margin:.25em}.manga .media>.edit_buttons{left:43.5px;left:calc(50% - 66.5px);position:absolute;top:86px;top:calc(50% - 58.5px)}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35);background-repeat:no-repeat;background-size:cover;background-size:contain}.big-check{display:none}.big-check:checked+label{-webkit-transition:.25s ease;background:rgba(0,0,0,.75);transition:.25s ease}.big-check:checked+label:after{color:#adff2f;content:"✓";font-size:15em;font-size:150px;font-size:15rem;height:100%;left:0;position:absolute;text-align:center;top:147px;width:100%}#series_list article.media{position:relative}#series_list .name,#series_list .name label{display:block;height:100%;left:0;line-height:1.25em;position:absolute;top:0;vertical-align:middle;width:100%}#series_list .name small{color:#fff}.details{font-size:inherit;margin:1.5rem auto 0;padding:1rem}.description{max-width:800px;max-width:80rem}.fixed{max-width:930px;max-width:93rem}.details .cover{display:block;width:284px}.details h2{margin-top:0}.details .flex>div{margin:1rem}.details .media_details{max-width:300px}.details .media_details td{padding:0 1.5rem}.details p{text-align:justify}.details .media_details td:nth-child(odd){text-align:right;white-space:nowrap;width:1%}.details .media_details td:nth-child(2n){text-align:left}.character,.small_character{background:rgba(0,0,0,.5);height:350px;vertical-align:middle;white-space:nowrap;width:225px}.small_character a{display:inline-block;height:100%;width:100%}.character .name,.small_character .name{bottom:0;left:0;position:absolute;z-index:10}.character img,.small_character img{-webkit-transform:translateY(-50%);position:relative;top:50%;transform:translateY(-50%);width:100%;z-index:5}.min-table{margin-left:0;min-width:0}.small_character{height:250px;width:160px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;height:100%;width:100%}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}.media{margin:2px 0}main{padding:0 .5rem .5rem}}.streaming-logo{height:50px;vertical-align:middle;width:50px}.cover_streaming_link .streaming-logo{height:20px;width:20px}#loading-shadow{background:rgba(0,0,0,.8);z-index:500}#loading-shadow,#loading-shadow .loading-wrapper{height:100%;left:0;position:fixed;top:0;width:100%}#loading-shadow .loading-wrapper{-ms-flex-align:center;-ms-flex-pack:center;-webkit-box-align:center;-webkit-box-pack:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:center;z-index:501}#loading-shadow .loading-content{color:#fff;position:relative}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff}.tabs{-ms-flex-wrap:wrap;-webkit-box-shadow:0 48px 80px -32px rgba(0,0,0,.3);background:#efefef;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:-webkit-box;display:-ms-flexbox;display:flex;flex-wrap:wrap;margin-top:1.5em}.tabs label{-webkit-transition:background .1s,color .1s;background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:20px 30px;transition:background .1s,color .1s;width:100%}.tabs label:hover{background:#d8d8d8}.tabs label:active{background:#ccc}.tabs [type=radio]:focus+label{-webkit-box-shadow:inset 0 0 0 3px #2aa1c0;box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.tabs [type=radio]{opacity:0;position:absolute}.tabs [type=radio]:checked+label{background:#fff;border-bottom:1px solid #fff;color:#000}.tabs [type=radio]:checked+label+.content{background:#fff;border:1px solid #e5e5e5;border-top:0;display:block;padding:20px 30px 30px;width:100%}.tabs .content{display:none}@media (min-width:600px){.tabs label{width:auto}.tabs .content{-ms-flex-order:99;-webkit-box-ordinal-group:100;order:99}} \ No newline at end of file +:root{-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;-webkit-box-sizing:border-box;-webkit-text-size-adjust:100%;box-sizing:border-box;cursor:default;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;line-height:1.4;overflow-y:scroll;scroll-behavior:smooth;text-size-adjust:100%}audio:not([controls]){display:none}details{display:block}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}main{margin:0 auto;padding:0 1.6rem 1.6rem}main,pre,summary{display:block}pre{background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;font-size:1.4em;font-size:14px;font-size:1.4rem;margin:1.6rem 0;overflow:auto;padding:1.6rem;word-break:break-all;word-wrap:break-word}progress{display:inline-block}small{color:#777;font-size:75%}big{font-size:125%}template{display:none}textarea{border:.1rem solid #ccc;border-radius:0;display:block;margin-bottom:.8rem;overflow:auto;padding:.8rem;resize:vertical;vertical-align:middle}[hidden]{display:none}[unselectable]{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}*,:after,:before{-webkit-box-sizing:inherit;border-style:solid;border-width:0;box-sizing:inherit}*{font-size:inherit;line-height:inherit;margin:0;padding:0}:after,:before{text-decoration:inherit;vertical-align:inherit}a{-webkit-transition:.25s ease;color:#1271db;text-decoration:none;transition:.25s ease}audio,canvas,iframe,img,svg,video{vertical-align:middle}button,input,select,textarea{border:.1rem solid #ccc;color:inherit;font-family:inherit;font-style:inherit;font-weight:inherit;min-height:1.4em}code,kbd,pre,samp{font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace}table{border-collapse:collapse;border-spacing:0;margin-bottom:1.6rem}::-moz-selection{background-color:#b3d4fc;text-shadow:none}::selection{background-color:#b3d4fc;text-shadow:none}button::-moz-focus-inner{border:0}body{color:#444;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;font-size:16px;font-size:1.6rem;font-style:normal;font-weight:400;padding:0}p{margin:0 0 1.6rem}h1,h2,h3,h4,h5,h6{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;margin:2rem 0 1.6rem}h1{border-bottom:.1rem solid rgba(0,0,0,.2);font-size:3.6em;font-size:36px;font-size:3.6rem}h1,h2{font-style:normal;font-weight:500}h2{font-size:3em;font-size:30px;font-size:3rem}h3{font-size:2.4em;font-size:24px;font-size:2.4rem;font-style:normal;font-weight:500;margin:1.6rem 0 .4rem}h4{font-size:1.8em;font-size:18px;font-size:1.8rem}h4,h5{font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}h5{font-size:1.6em;font-size:16px;font-size:1.6rem}h6{color:#777;font-size:1.4em;font-style:normal;font-weight:600;margin:1.6rem 0 .4rem}code,h6{font-size:14px;font-size:1.4rem}code{background:#efefef;color:#444;font-family:Anonymous Pro,Fira Code,Menlo,Monaco,Consolas,Courier New,monospace;word-break:break-all;word-wrap:break-word}a:focus,a:hover{text-decoration:none}dl{margin-bottom:1.6rem}dd{margin-left:4rem}ol,ul{margin-bottom:.8rem;padding-left:2rem}blockquote{border-left:.2rem solid #1271db;font-style:italic;margin:1.6rem 0;padding-left:1.6rem}blockquote,figcaption{font-family:Georgia,Times,Times New Roman,serif}html{font-size:62.5%}article,aside,details,footer,header,main,section,summary{display:block;height:auto;margin:0 auto;width:100%}footer{clear:both;display:inline-block;float:left;max-width:100%;padding:1rem 0;text-align:center}footer,hr{border-top:.1rem solid rgba(0,0,0,.2)}hr{display:block;margin-bottom:1.6rem;width:100%}img{height:auto;vertical-align:baseline}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select{border:.1rem solid #ccc;border-radius:0;display:inline-block;padding:.8rem;vertical-align:middle}input:not([type]){-webkit-appearance:none;background-clip:padding-box;background-color:#fff;border:.1rem solid #ccc;border-radius:0;color:#444;display:inline-block;padding:.8rem;text-align:left}input[type=color]{padding:.8rem 1.6rem}input:not([type]):focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border-color:#b3d4fc}input[type=checkbox],input[type=radio]{vertical-align:middle}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:1px thin solid #444;outline:.1rem thin solid #444}input:not([type])[disabled],input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled],select[disabled],textarea[disabled]{background-color:#efefef;color:#777;cursor:not-allowed}input[readonly],select[readonly],textarea[readonly]{background-color:#efefef;border-color:#ccc;color:#777}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{border-color:#e9322d;color:#b94a48}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#ff4136}select{background-color:#fff;border:.1rem solid #ccc}select[multiple]{height:auto}label{line-height:2}fieldset{border:0;margin:0;padding:.8rem 0}legend{border-bottom:.1rem solid #ccc;color:#444;display:block;margin-bottom:.8rem;padding:.8rem 0;width:100%}button,input[type=submit]{-moz-user-select:none;-ms-user-select:none;-webkit-transition:.25s ease;-webkit-user-drag:none;-webkit-user-select:none;border:.2rem solid #444;border-radius:0;color:#444;cursor:pointer;display:inline-block;margin-bottom:.8rem;margin-right:.4rem;padding:.8rem 1.6rem;text-align:center;text-decoration:none;text-transform:uppercase;transition:.25s ease;user-select:none;vertical-align:baseline}button a,input[type=submit] a{color:#444}button::-moz-focus-inner,input[type=submit]::-moz-focus-inner{padding:0}button:hover,input[type=submit]:hover{background:#444;border-color:#444;color:#fff}button:hover a,input[type=submit]:hover a{color:#fff}button:active,input[type=submit]:active{background:#6a6a6a;border-color:#6a6a6a;color:#fff}button:active a,input[type=submit]:active a{color:#fff}button:disabled,input[type=submit]:disabled{-webkit-box-shadow:none;box-shadow:none;cursor:not-allowed;opacity:.4}nav ul{list-style:none;margin:0;padding:0;text-align:center}nav ul li{display:inline}nav a{-webkit-transition:.25s ease;border-bottom:.2rem solid transparent;color:#444;padding:.8rem 1.6rem;text-decoration:none;transition:.25s ease}nav a:hover,nav li.selected a{border-color:rgba(0,0,0,.2)}nav a:active{border-color:rgba(0,0,0,.56)}caption{padding:.8rem 0}thead th{background:#efefef;color:#444}tr{background:#fff;margin-bottom:.8rem}td,th{border:.1rem solid #ccc;padding:.8rem 1.6rem;text-align:center;vertical-align:inherit}tfoot tr{background:none}tfoot td{color:#efefef;font-size:8px;font-size:.8rem;font-style:italic;padding:1.6rem .4rem}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){clip:rect(0)!important;position:absolute!important}}@media screen and max-width 40rem{article,aside,section{clear:both;display:block;max-width:100%}img{margin-right:1.6rem}}.media[hidden],[hidden=hidden],template{display:none}body{margin:.5em}button{background:hsla(0,0%,100%,.65);margin:0}table{margin:0 auto;min-width:85%}td{padding:1rem}thead td,thead th{padding:.5rem}input[type=number]{width:4em}tbody>tr:nth-child(odd){background:#ddd}a:active,a:hover{color:#7d12db}.bracketed{color:#12db18}.bracketed,h1 a{text-shadow:1px 1px 1px #000}.bracketed:before{content:"[\00a0"}.bracketed:after{content:"\00a0]"}.bracketed:active,.bracketed:hover{color:#db7d12}.grow-1{-ms-flex-positive:1;-webkit-box-flex:1;flex-grow:1}.flex-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-no-wrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-align-end{-ms-flex-align:end;-webkit-box-align:end;align-items:flex-end}.flex-align-space-around{-ms-flex-line-pack:distribute;align-content:space-around}.flex-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.flex-self-center{-ms-flex-item-align:center;align-self:center}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.small-font{font-size:16px;font-size:1.6rem}.justify{text-align:justify}.align_center{text-align:center!important}.align_left{text-align:left!important}.align_right{text-align:right!important}.valign_top{vertical-align:top}.no_border{border:none}.media-wrap{margin:0 auto;text-align:center}.danger{background-color:#ff4136;border-color:#924949;color:#fff}.danger:active,.danger:hover{background-color:#924949;border-color:#ff4136;color:#fff}.user-btn{border-color:#12db18;color:#12db18;padding:0 .5rem;text-shadow:1px 1px 1px #000}.user-btn:active,.user-btn:hover{background-color:#db7d12;border-color:#db7d12}.full_width{width:100%}.cssload-loader{-webkit-perspective:780px;border-radius:50%;height:62px;left:calc(50% - 31px);perspective:780px;position:relative;width:62px}.cssload-inner{-webkit-box-sizing:border-box;border-radius:50%;box-sizing:border-box;height:100%;position:absolute;width:100%}.cssload-inner.cssload-one{-webkit-animation:cssload-rotate-one 1.15s linear infinite;animation:cssload-rotate-one 1.15s linear infinite;border-bottom:3px solid #000;left:0;top:0}.cssload-inner.cssload-two{-webkit-animation:cssload-rotate-two 1.15s linear infinite;animation:cssload-rotate-two 1.15s linear infinite;border-right:3px solid #000;right:0;top:0}.cssload-inner.cssload-three{-webkit-animation:cssload-rotate-three 1.15s linear infinite;animation:cssload-rotate-three 1.15s linear infinite;border-top:3px solid #000;bottom:0;right:0}@-webkit-keyframes cssload-rotate-one{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@keyframes cssload-rotate-one{0%{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(0deg);transform:rotateX(35deg) rotateY(-45deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(-45deg) rotate(1turn);transform:rotateX(35deg) rotateY(-45deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-two{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@keyframes cssload-rotate-two{0%{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(0deg);transform:rotateX(50deg) rotateY(10deg) rotate(0deg)}to{-webkit-transform:rotateX(50deg) rotateY(10deg) rotate(1turn);transform:rotateX(50deg) rotateY(10deg) rotate(1turn)}}@-webkit-keyframes cssload-rotate-three{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}@keyframes cssload-rotate-three{0%{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(0deg);transform:rotateX(35deg) rotateY(55deg) rotate(0deg)}to{-webkit-transform:rotateX(35deg) rotateY(55deg) rotate(1turn);transform:rotateX(35deg) rotateY(55deg) rotate(1turn)}}.sorting,.sorting_asc,.sorting_desc{vertical-align:text-bottom}.sorting:before{content:" ↕\00a0"}.sorting_asc:before{content:" ↑\00a0"}.sorting_desc:before{content:" ↓\00a0"}.form{width:100%}.form thead th,.form thead tr{background:inherit;border:0}.form tr>td:nth-child(odd){max-width:30%;min-width:25px;text-align:right}.form tr>td:nth-child(2n){text-align:left;width:70%}.invisible tbody>tr:nth-child(odd){background:inherit}.invisible td,.invisible th,.invisible tr{border:0}.message{margin:.5em auto;padding:.5em;position:relative;width:95%}.message .close{height:1em;line-height:1em;position:absolute;right:.5em;text-align:center;top:.5em;vertical-align:middle;width:1em}.message:hover .close:after{content:"☒"}.message:hover{cursor:pointer}.message .icon{left:.5em;margin-right:1em;top:.5em}.message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info{background:#ffc;border:1px solid #bfbe3a}.message.info .icon:after{content:"⚠"}.character,.media,.small_character{display:inline-block;height:311px;margin:.25em .125em;position:relative;text-align:center;vertical-align:top;width:220px}.character>img,.media>img,.small_character>img{width:100%}.media .edit_buttons>button{margin:.5em auto}.media_metadata>div,.medium_metadata>div,.name,.row{background:#000;background:rgba(0,0,0,.45);color:#fff;padding:.25em .125em;text-align:right;text-shadow:1px 2px 1px rgba(0,0,0,.85)}.age_rating,.media_type{text-align:left}.media>.media_metadata{bottom:0;position:absolute;right:0}.media>.medium_metadata{bottom:0;left:0;position:absolute}.media>.name{position:absolute;top:0}.character:hover>.name,.media:hover>.media_metadata>div,.media:hover>.medium_metadata>div,.media:hover>.name,.media:hover>.table .row,.small_character:hover>.name{-webkit-transition:.25s ease;background:rgba(0,0,0,.75);transition:.25s ease}.media:hover>.edit_buttons[hidden],.media:hover>button[hidden]{-webkit-transition:.25s ease;display:block;transition:.25s ease}.character>.name a,.character>.name a small,.media>.name a,.media>.name a small,.small_character>.name a,.small_character>.name a small{background:none;color:#fff;text-shadow:1px 2px 1px rgba(0,0,0,.85)}.anime .name,.manga .name{padding:.5em .25em;text-align:center;width:100%}.anime .age_rating,.anime .airing_status,.anime .completion,.anime .delete,.anime .edit,.anime .media_type,.anime .user_rating{background:none;text-align:center}.anime .table,.manga .table{bottom:0;left:0;position:absolute;width:100%}.anime .row,.manga .row{-ms-flex-line-pack:distribute;-ms-flex-pack:distribute;align-content:space-around;background:#000;background:rgba(0,0,0,.45);display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:space-around;padding:0 inherit;text-align:center;width:100%}.anime .row>span,.manga .row>span{text-align:left}.anime .row>div,.manga .row>div{-ms-flex-item-align:center;align-self:center;display:flex-item;font-size:.8em;text-align:center;vertical-align:middle}.anime .media>button.plus_one{left:44px;left:calc(50% - 66.5px);position:absolute;top:138px;top:calc(50% - 21.5px)}.manga .row{padding:1px}.manga .media{border:1px solid #ddd;height:310px;margin:.25em}.manga .media>.edit_buttons{left:43.5px;left:calc(50% - 66.5px);position:absolute;top:86px;top:calc(50% - 58.5px)}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35);background-repeat:no-repeat;background-size:cover;background-size:contain}.big-check{display:none}.big-check:checked+label{-webkit-transition:.25s ease;background:rgba(0,0,0,.75);transition:.25s ease}.big-check:checked+label:after{color:#adff2f;content:"✓";font-size:15em;font-size:150px;font-size:15rem;height:100%;left:0;position:absolute;text-align:center;top:147px;width:100%}#series_list article.media{position:relative}#series_list .name,#series_list .name label{display:block;height:100%;left:0;line-height:1.25em;position:absolute;top:0;vertical-align:middle;width:100%}#series_list .name small{color:#fff}.details{font-size:inherit;margin:1.5rem auto 0;padding:1rem}.description{max-width:800px;max-width:80rem}.fixed{max-width:930px;max-width:93rem}.details .cover{display:block;width:284px}.details h2{margin-top:0}.details .flex>div{margin:1rem}.details .media_details{max-width:300px}.details .media_details td{padding:0 1.5rem}.details p{text-align:justify}.details .media_details td:nth-child(odd){text-align:right;white-space:nowrap;width:1%}.details .media_details td:nth-child(2n){text-align:left}.character,.small_character{background:rgba(0,0,0,.5);height:350px;vertical-align:middle;white-space:nowrap;width:225px}.small_character a{display:inline-block;height:100%;width:100%}.character .name,.small_character .name{bottom:0;left:0;position:absolute;z-index:10}.character img,.small_character img{-webkit-transform:translateY(-50%);position:relative;top:50%;transform:translateY(-50%);width:100%;z-index:5}.min-table{margin-left:0;min-width:0}.small_character{height:250px;width:160px}.user-page .media-wrap{text-align:left}.media a{display:inline-block;height:100%;width:100%}@media screen and (max-width:40em){nav a{line-height:4em;line-height:4rem}.media{margin:2px 0}main{padding:0 .5rem .5rem}}.streaming-logo{height:50px;vertical-align:middle;width:50px}.cover_streaming_link .streaming-logo{height:20px;width:20px}#loading-shadow{background:rgba(0,0,0,.8);z-index:500}#loading-shadow,#loading-shadow .loading-wrapper{height:100%;left:0;position:fixed;top:0;width:100%}#loading-shadow .loading-wrapper{-ms-flex-align:center;-ms-flex-pack:center;-webkit-box-align:center;-webkit-box-pack:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;justify-content:center;z-index:501}#loading-shadow .loading-content{color:#fff;position:relative}.loading-content .cssload-inner.cssload-one,.loading-content .cssload-inner.cssload-three,.loading-content .cssload-inner.cssload-two{border-color:#fff}.tabs{-ms-flex-wrap:wrap;-webkit-box-shadow:0 48px 80px -32px rgba(0,0,0,.3);background:#efefef;box-shadow:0 48px 80px -32px rgba(0,0,0,.3);display:-webkit-box;display:-ms-flexbox;display:flex;flex-wrap:wrap;margin-top:1.5em}.tabs label{-webkit-transition:background .1s,color .1s;background:#e5e5e5;border:1px solid #e5e5e5;color:#7f7f7f;cursor:pointer;font-size:18px;font-weight:700;padding:20px 30px;transition:background .1s,color .1s;width:100%}.tabs label:hover{background:#d8d8d8}.tabs label:active{background:#ccc}.tabs [type=radio]:focus+label{-webkit-box-shadow:inset 0 0 0 3px #2aa1c0;box-shadow:inset 0 0 0 3px #2aa1c0;z-index:1}.tabs [type=radio]{opacity:0;position:absolute}.tabs [type=radio]:checked+label{background:#fff;border-bottom:1px solid #fff;color:#000}.tabs [type=radio]:checked+label+.content{background:#fff;border:1px solid #e5e5e5;border-top:0;display:block;padding:20px 30px 30px;width:100%}.tabs .content{display:none}@media (min-width:600px){.tabs label{width:auto}.tabs .content{-ms-flex-order:99;-webkit-box-ordinal-group:100;order:99}} \ No newline at end of file diff --git a/public/css/base.css b/public/css/base.css index 094e18d3..6b500f27 100644 --- a/public/css/base.css +++ b/public/css/base.css @@ -756,4 +756,5 @@ CSS Tabs .tabs .content { order: 99; } -} \ No newline at end of file +} + From 3d51a813471fab282a5bf782f29121df84c1cbf7 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Thu, 9 Aug 2018 11:16:44 -0400 Subject: [PATCH 09/17] Remove references to MAL syncing, resolves #4 --- README.md | 4 ---- app/config/config.toml.example | 3 --- app/config/mal.toml.example | 6 ------ 3 files changed, 13 deletions(-) delete mode 100644 app/config/mal.toml.example diff --git a/README.md b/README.md index 0ff19caa..337f94f5 100644 --- a/README.md +++ b/README.md @@ -50,10 +50,6 @@ Update your anime/manga list on Kitsu.io and MyAnimeList.net * public/images/manga 5. Make sure the `console` script is executable -### Using MAL API -1. Update `app/config/mal.toml` with your username and password -2. Enable MAL api in `app/config/config.toml` - ### Server Setup See the [wiki](https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient/wiki) diff --git a/app/config/config.toml.example b/app/config/config.toml.example index 52e0f8ec..28f954b7 100644 --- a/app/config/config.toml.example +++ b/app/config/config.toml.example @@ -11,8 +11,5 @@ whose_list = "Tim" # do you wish to show the anime collection? show_anime_collection = true -# do you have a My Anime List account set up in mal.toml? -use_mal_api = false - # path to public directory on the server asset_dir = "/../../public" \ No newline at end of file diff --git a/app/config/mal.toml.example b/app/config/mal.toml.example deleted file mode 100644 index 0e3233e0..00000000 --- a/app/config/mal.toml.example +++ /dev/null @@ -1,6 +0,0 @@ -################################################################################ -# My Anime LIst Integration Config # -################################################################################ - -username = "timw4mail" -password = "mysecretpassword" \ No newline at end of file From 6f7d94641e0f2bca08b175b8d938f97e1733efde Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Thu, 9 Aug 2018 11:31:15 -0400 Subject: [PATCH 10/17] Better error handling for incrementing watched count on Anime list --- public/js/anime_edit.js | 11 +- public/js/base/AnimeClient.js | 2 +- public/package.json | 4 +- public/yarn.lock | 1177 ++++++++++++++++++++------------- 4 files changed, 743 insertions(+), 451 deletions(-) diff --git a/public/js/anime_edit.js b/public/js/anime_edit.js index a2002f40..98e79c22 100644 --- a/public/js/anime_edit.js +++ b/public/js/anime_edit.js @@ -39,7 +39,16 @@ data, dataType: 'json', type: 'POST', - success: () => { + success: (res) => { + const resData = JSON.parse(res); + + if (resData.errors) { + _.hide(_.$('#loading-shadow')[ 0 ]); + _.showMessage('error', `Failed to update ${title}. `); + _.scrollToTop(); + return; + } + if (data.data.status === 'completed') { _.hide(parentSel); } diff --git a/public/js/base/AnimeClient.js b/public/js/base/AnimeClient.js index 180a0756..7614063b 100644 --- a/public/js/base/AnimeClient.js +++ b/public/js/base/AnimeClient.js @@ -273,7 +273,7 @@ var AnimeClient = (function(w) { responseText = request.responseText; } - if (request.status > 400) { + if (request.status > 299) { config.error.call(null, request.status, responseText, request.response); } else { config.success.call(null, responseText, request.status); diff --git a/public/package.json b/public/package.json index 9ca608a9..f4da21bc 100644 --- a/public/package.json +++ b/public/package.json @@ -4,10 +4,10 @@ "watch": "watch 'npm run build' --filter=./cssfilter.js" }, "devDependencies": { - "cssnano": "^3.10.0", + "cssnano": "^4.0.5", "postcss-cachify": "^1.3.1", "postcss-cssnext": "^3.0.0", - "postcss-import": "^10.0.0", + "postcss-import": "^12.0.0", "watch": "^1.0.2" } } diff --git a/public/yarn.lock b/public/yarn.lock index 841b5d82..426f93b4 100644 --- a/public/yarn.lock +++ b/public/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: +alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -14,46 +14,35 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.1.0.tgz#09c202d5c917ec23188caa5c9cb9179cd9547750" +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" dependencies: - color-convert "^1.0.0" + color-convert "^1.9.0" argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" dependencies: sprintf-js "~1.0.2" -autoprefixer@^6.3.1: - version "6.7.7" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" - dependencies: - browserslist "^1.7.6" - caniuse-db "^1.0.30000634" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^5.2.16" - postcss-value-parser "^3.2.3" - autoprefixer@^7.1.1: - version "7.1.2" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.2.tgz#fbeaf07d48fd878e0682bf7cbeeade728adb2b18" + version "7.2.6" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.2.6.tgz#256672f86f7c735da849c4f07d008abb056067dc" dependencies: - browserslist "^2.1.5" - caniuse-lite "^1.0.30000697" + browserslist "^2.11.3" + caniuse-lite "^1.0.30000805" normalize-range "^0.1.2" num2fraction "^1.2.2" - postcss "^6.0.6" + postcss "^6.0.17" postcss-value-parser "^3.2.3" babel-runtime@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" dependencies: core-js "^2.4.0" - regenerator-runtime "^0.10.0" + regenerator-runtime "^0.11.0" balanced-match@0.1.0: version "0.1.0" @@ -67,35 +56,31 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +boolbase@^1.0.0, boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" dependencies: balanced-match "^1.0.0" concat-map "0.0.1" -browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: - version "1.7.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" +browserslist@^2.0.0, browserslist@^2.11.3: + version "2.11.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" dependencies: - caniuse-db "^1.0.30000639" - electron-to-chromium "^1.2.7" + caniuse-lite "^1.0.30000792" + electron-to-chromium "^1.3.30" -browserslist@^2.0.0, browserslist@^2.1.5: - version "2.1.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.1.5.tgz#e882550df3d1cd6d481c1a3e0038f2baf13a4711" +browserslist@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.0.1.tgz#61c05ce2a5843c7d96166408bc23d58b5416e818" dependencies: - caniuse-lite "^1.0.30000684" - electron-to-chromium "^1.3.14" - -caniuse-api@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" - dependencies: - browserslist "^1.3.6" - caniuse-db "^1.0.30000529" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" + caniuse-lite "^1.0.30000865" + electron-to-chromium "^1.3.52" + node-releases "^1.0.0-alpha.10" caniuse-api@^2.0.0: version "2.0.0" @@ -106,13 +91,18 @@ caniuse-api@^2.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000700" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000700.tgz#97cfc483865eea8577dc7a3674929b9abf553095" +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000684, caniuse-lite@^1.0.30000697: - version "1.0.30000700" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000700.tgz#6084871ec75c6fa62327de97622514f95d9db26a" +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805, caniuse-lite@^1.0.30000865: + version "1.0.30000874" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000874.tgz#a641b1f1c420d58d9b132920ef6ba87bbdcd2223" chalk@^1.1.3: version "1.1.3" @@ -124,39 +114,37 @@ chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.0.1.tgz#dbec49436d2ae15f536114e76d14656cdbc0f44d" +chalk@^2.0.1, chalk@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" dependencies: - ansi-styles "^3.1.0" + ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" - supports-color "^4.0.0" - -clap@^1.0.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.0.tgz#59c90fe3e137104746ff19469a27a634ff68c857" - dependencies: - chalk "^1.1.3" + supports-color "^5.3.0" clone@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" - -coa@~1.0.1: version "1.0.4" - resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + +coa@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.1.tgz#f3f8b0b15073e35d70263fb1042cb2c023db38af" dependencies: q "^1.1.2" -color-convert@^1.0.0, color-convert@^1.3.0, color-convert@^1.8.2: - version "1.9.0" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" +color-convert@^1.3.0, color-convert@^1.8.2, color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.2" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" dependencies: - color-name "^1.1.1" + color-name "1.1.1" -color-name@^1.0.0, color-name@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d" +color-name@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" + +color-name@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" color-string@^0.3.0: version "0.3.0" @@ -164,9 +152,9 @@ color-string@^0.3.0: dependencies: color-name "^1.0.0" -color-string@^1.4.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.2.tgz#26e45814bc3c9a7cbd6751648a41434514a773a9" +color-string@^1.4.0, color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" @@ -186,13 +174,19 @@ color@^1.0.3: color-convert "^1.8.2" color-string "^1.4.0" -colormin@^1.0.5: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" +color@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color/-/color-2.0.1.tgz#e4ed78a3c4603d0891eba5430b04b86314f4c839" dependencies: - color "^0.11.0" - css-color-names "0.0.4" - has "^1.0.1" + color-convert "^1.9.1" + color-string "^1.5.2" + +color@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" colors@~1.1.2: version "1.1.2" @@ -203,8 +197,8 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" connect-cachify-static@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/connect-cachify-static/-/connect-cachify-static-1.5.1.tgz#0450f9979ebc6df4a998941a831ef39b6d59e94e" + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-cachify-static/-/connect-cachify-static-1.6.0.tgz#f97eac98fa0ac6e6fe793fc32565f9ca028e9b38" dependencies: debug "~2" find "~0" @@ -213,109 +207,240 @@ connect-cachify-static@^1.3.0: parseurl "~1" core-js@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" -css-color-function@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/css-color-function/-/css-color-function-1.3.0.tgz#72c767baf978f01b8a8a94f42f17ba5d22a776fc" +cosmiconfig@^5.0.0: + version "5.0.5" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.5.tgz#a809e3c2306891ce17ab70359dc8bdf661fe2cd0" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + +css-color-function@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/css-color-function/-/css-color-function-1.3.3.tgz#8ed24c2c0205073339fafa004bc8c141fccb282e" dependencies: balanced-match "0.1.0" color "^0.11.0" - debug "~0.7.4" + debug "^3.1.0" rgb "~0.1.0" -css-color-names@0.0.4: +css-color-names@0.0.4, css-color-names@^0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" +css-declaration-sorter@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-3.0.1.tgz#d0e3056b0fd88dc1ea9dceff435adbe9c702a7f8" + dependencies: + postcss "^6.0.0" + timsort "^0.3.0" + +css-select-base-adapter@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.0.tgz#0102b3d14630df86c3eb9fa9f5456270106cf990" + +css-select@~1.3.0-rc0: + version "1.3.0-rc0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.3.0-rc0.tgz#6f93196aaae737666ea1036a8cb14a8fcb7a9231" + dependencies: + boolbase "^1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "^1.0.1" + +css-tree@1.0.0-alpha.29: + version "1.0.0-alpha.29" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39" + dependencies: + mdn-data "~1.1.0" + source-map "^0.5.3" + +css-tree@1.0.0-alpha25: + version "1.0.0-alpha25" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha25.tgz#1bbfabfbf6eeef4f01d9108ff2edd0be2fe35597" + dependencies: + mdn-data "^1.0.0" + source-map "^0.5.3" + css-unit-converter@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996" -cssnano@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" - dependencies: - autoprefixer "^6.3.1" - decamelize "^1.1.2" - defined "^1.0.0" - has "^1.0.1" - object-assign "^4.0.1" - postcss "^5.0.14" - postcss-calc "^5.2.0" - postcss-colormin "^2.1.8" - postcss-convert-values "^2.3.4" - postcss-discard-comments "^2.0.4" - postcss-discard-duplicates "^2.0.1" - postcss-discard-empty "^2.0.1" - postcss-discard-overridden "^0.1.1" - postcss-discard-unused "^2.2.1" - postcss-filter-plugins "^2.0.0" - postcss-merge-idents "^2.1.5" - postcss-merge-longhand "^2.0.1" - postcss-merge-rules "^2.0.3" - postcss-minify-font-values "^1.0.2" - postcss-minify-gradients "^1.0.1" - postcss-minify-params "^1.0.4" - postcss-minify-selectors "^2.0.4" - postcss-normalize-charset "^1.1.0" - postcss-normalize-url "^3.0.7" - postcss-ordered-values "^2.1.0" - postcss-reduce-idents "^2.2.2" - postcss-reduce-initial "^1.0.0" - postcss-reduce-transforms "^1.0.3" - postcss-svgo "^2.1.1" - postcss-unique-selectors "^2.0.2" - postcss-value-parser "^3.2.3" - postcss-zindex "^2.0.1" +css-url-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-1.1.0.tgz#83834230cc9f74c457de59eebd1543feeb83b7ec" -csso@~2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" +css-what@2.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" + +cssnano-preset-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.0.tgz#c334287b4f7d49fb2d170a92f9214655788e3b6b" dependencies: - clap "^1.0.9" - source-map "^0.5.3" + css-declaration-sorter "^3.0.0" + cssnano-util-raw-cache "^4.0.0" + postcss "^6.0.0" + postcss-calc "^6.0.0" + postcss-colormin "^4.0.0" + postcss-convert-values "^4.0.0" + postcss-discard-comments "^4.0.0" + postcss-discard-duplicates "^4.0.0" + postcss-discard-empty "^4.0.0" + postcss-discard-overridden "^4.0.0" + postcss-merge-longhand "^4.0.0" + postcss-merge-rules "^4.0.0" + postcss-minify-font-values "^4.0.0" + postcss-minify-gradients "^4.0.0" + postcss-minify-params "^4.0.0" + postcss-minify-selectors "^4.0.0" + postcss-normalize-charset "^4.0.0" + postcss-normalize-display-values "^4.0.0" + postcss-normalize-positions "^4.0.0" + postcss-normalize-repeat-style "^4.0.0" + postcss-normalize-string "^4.0.0" + postcss-normalize-timing-functions "^4.0.0" + postcss-normalize-unicode "^4.0.0" + postcss-normalize-url "^4.0.0" + postcss-normalize-whitespace "^4.0.0" + postcss-ordered-values "^4.0.0" + postcss-reduce-initial "^4.0.0" + postcss-reduce-transforms "^4.0.0" + postcss-svgo "^4.0.0" + postcss-unique-selectors "^4.0.0" + +cssnano-util-get-arguments@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" + +cssnano-util-get-match@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" + +cssnano-util-raw-cache@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.0.tgz#be0a2856e25f185f5f7a2bcc0624e28b7f179a9f" + dependencies: + postcss "^6.0.0" + +cssnano-util-same-parent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.0.tgz#d2a3de1039aa98bc4ec25001fa050330c2a16dac" + +cssnano@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.0.5.tgz#8789b5fdbe7be05d8a0f7e45c4c789ebe712f5aa" + dependencies: + cosmiconfig "^5.0.0" + cssnano-preset-default "^4.0.0" + is-resolvable "^1.0.0" + postcss "^6.0.0" + +csso@^3.5.0: + version "3.5.1" + resolved "https://registry.yarnpkg.com/csso/-/csso-3.5.1.tgz#7b9eb8be61628973c1b261e169d2f024008e758b" + dependencies: + css-tree "1.0.0-alpha.29" debug@^2.1.2, debug@~2: - version "2.6.8" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: ms "2.0.0" -debug@~0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" +debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" -decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" +dom-serializer@0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" + dependencies: + domelementtype "~1.1.1" + entities "~1.1.1" -electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.14: - version "1.3.15" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.15.tgz#08397934891cbcfaebbd18b82a95b5a481138369" +domelementtype@1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" + +domelementtype@~1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + dependencies: + dom-serializer "0" + domelementtype "1" + +dot-prop@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + dependencies: + is-obj "^1.0.0" + +electron-to-chromium@^1.3.30, electron-to-chromium@^1.3.52: + version "1.3.55" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.55.tgz#f150e10b20b77d9d41afcca312efe0c3b1a7fdce" + +entities@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.5.1, es-abstract@^1.6.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" -esprima@^2.6.0: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" exec-sh@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.0.tgz#14f75de3f20d286ef933099b2ce50a90359cef10" + version "0.2.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" dependencies: - merge "^1.1.3" + merge "^1.2.0" find@~0: - version "0.2.7" - resolved "https://registry.yarnpkg.com/find/-/find-0.2.7.tgz#7afbd00f8f08c5b622f97cda6f714173d547bb3f" + version "0.2.9" + resolved "https://registry.yarnpkg.com/find/-/find-0.2.9.tgz#4b73f1ff9e56ad91b76e716407fe5ffe6554bb8c" dependencies: traverse-chain "~0.1.0" @@ -323,9 +448,13 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" -function-bind@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +function-bind@^1.1.0, function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" has-ansi@^2.0.0: version "2.0.0" @@ -337,15 +466,27 @@ has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" -has@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" +has@^1.0.0, has@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" dependencies: - function-bind "^1.0.2" + function-bind "^1.1.1" + +hex-color-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" + +hsl-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" + +hsla-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" html-comment-regex@^1.1.0: version "1.1.1" @@ -359,34 +500,86 @@ is-absolute-url@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + is-arrayish@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.1.tgz#c2dfc386abaa0c3e33c48db3fe87059e69065efd" + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" -is-plain-obj@^1.0.0: +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + +is-color-stop@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" + dependencies: + css-color-names "^0.0.4" + hex-color-regex "^1.1.0" + hsl-regex "^1.0.0" + hsla-regex "^1.0.0" + rgb-regex "^1.0.1" + rgba-regex "^1.0.0" -is-svg@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + +is-svg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" dependencies: html-comment-regex "^1.1.0" +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + isnumeric@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/isnumeric/-/isnumeric-0.2.0.tgz#a2347ba360de19e33d0ffd590fddf7755cbf2e64" js-base64@^2.1.9: - version "2.1.9" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce" + version "2.4.8" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.8.tgz#57a9b130888f956834aa40c5b165ba59c758f033" -js-yaml@~3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" +js-yaml@^3.9.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" dependencies: argparse "^1.0.7" - esprima "^2.6.0" + esprima "^4.0.0" + +js-yaml@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" lodash._reinterpolate@~3.0.0: version "3.0.0" @@ -413,19 +606,15 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^4.17.4: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - -macaddress@^0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12" - math-expression-evaluator@^1.2.14: version "1.2.17" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" -merge@^1.1.3: +mdn-data@^1.0.0, mdn-data@~1.1.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01" + +merge@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" @@ -453,42 +642,72 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" +node-releases@^1.0.0-alpha.10: + version "1.0.0-alpha.10" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.0-alpha.10.tgz#61c8d5f9b5b2e05d84eba941d05b6f5202f68a2a" + dependencies: + semver "^5.3.0" + normalize-range@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" -normalize-url@^1.4.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" +normalize-url@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.2.0.tgz#98d0948afc82829f374320f405fe9ca55a5f8567" + +nth-check@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4" dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" + boolbase "~1.0.0" num2fraction@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" -object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-keys@^1.0.8: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.values@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.0.4.tgz#e524da09b4f66ff05df457546ec72ac99f13069a" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.6.1" + function-bind "^1.1.0" + has "^1.0.1" on-headers@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" onecolor@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/onecolor/-/onecolor-3.0.4.tgz#75a46f80da6c7aaa5b4daae17a47198bd9652494" + version "3.0.5" + resolved "https://registry.yarnpkg.com/onecolor/-/onecolor-3.0.5.tgz#36eff32201379efdf1180fb445e51a8e2425f9f6" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" parseurl@~1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" pify@^2.3.0: version "2.3.0" @@ -532,17 +751,9 @@ postcss-cachify@^1.3.1: debug "^2.1.2" postcss "^5.0.0" -postcss-calc@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" - dependencies: - postcss "^5.0.2" - postcss-message-helpers "^2.0.0" - reduce-css-calc "^1.2.6" - postcss-calc@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-6.0.0.tgz#b681b279c6d24fbe0e33ed9045803705445d613b" + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-6.0.1.tgz#3d24171bbf6e7629d422a436ebfe6dd9511f4330" dependencies: css-unit-converter "^1.1.1" postcss "^6.0.0" @@ -550,20 +761,20 @@ postcss-calc@^6.0.0: reduce-css-calc "^2.0.0" postcss-color-function@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-color-function/-/postcss-color-function-4.0.0.tgz#7e0106f4f6a1ecb1ad5b3a8553ace5e828aae187" + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-function/-/postcss-color-function-4.0.1.tgz#402b3f2cebc3f6947e618fb6be3654fbecef6444" dependencies: - css-color-function "^1.3.0" + css-color-function "~1.3.3" postcss "^6.0.1" postcss-message-helpers "^2.0.0" postcss-value-parser "^3.3.0" postcss-color-gray@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-4.0.0.tgz#681bf305097dd66bfef0e1e6282d5d99b5acc95d" + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-4.1.0.tgz#e5581ed57eaa826fb652ca11b1e2b7b136a9f9df" dependencies: - color "^1.0.3" - postcss "^6.0.1" + color "^2.0.1" + postcss "^6.0.14" postcss-message-helpers "^2.0.0" reduce-function-call "^1.0.2" @@ -593,11 +804,11 @@ postcss-color-hwb@^3.0.0: reduce-function-call "^1.0.2" postcss-color-rebeccapurple@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-3.0.0.tgz#eebaf03d363b4300b96792bd3081c19ed66513d3" + version "3.1.0" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-3.1.0.tgz#ce1269ecc2d0d8bf92aab44bd884e633124c33ec" dependencies: - postcss "^6.0.1" - postcss-value-parser "^3.3.0" + postcss "^6.0.22" + postcss-values-parser "^1.5.0" postcss-color-rgb@^2.0.0: version "2.0.0" @@ -614,24 +825,26 @@ postcss-color-rgba-fallback@^3.0.0: postcss-value-parser "^3.3.0" rgb-hex "^2.1.0" -postcss-colormin@^2.1.8: - version "2.2.2" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b" +postcss-colormin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.1.tgz#6f1c18a0155bc69613f2ff13843e2e4ae8ff0bbe" dependencies: - colormin "^1.0.5" - postcss "^5.0.13" - postcss-value-parser "^3.2.3" + browserslist "^4.0.0" + color "^3.0.0" + has "^1.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" -postcss-convert-values@^2.3.4: - version "2.6.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d" +postcss-convert-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.0.tgz#77d77d9aed1dc4e6956e651cc349d53305876f62" dependencies: - postcss "^5.0.11" - postcss-value-parser "^3.1.2" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" postcss-cssnext@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/postcss-cssnext/-/postcss-cssnext-3.0.2.tgz#63b77adb0b8a4c1d5ec32cd345539535a3417d48" + version "3.1.0" + resolved "https://registry.yarnpkg.com/postcss-cssnext/-/postcss-cssnext-3.1.0.tgz#927dc29341a938254cde38ea60a923b9dfedead9" dependencies: autoprefixer "^7.1.1" caniuse-api "^2.0.0" @@ -653,7 +866,7 @@ postcss-cssnext@^3.0.0: postcss-custom-media "^6.0.0" postcss-custom-properties "^6.1.0" postcss-custom-selectors "^4.0.1" - postcss-font-family-system-ui "^2.0.1" + postcss-font-family-system-ui "^3.0.0" postcss-font-variant "^3.0.0" postcss-image-set-polyfill "^0.3.5" postcss-initial "^2.0.0" @@ -672,11 +885,11 @@ postcss-custom-media@^6.0.0: postcss "^6.0.1" postcss-custom-properties@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-6.1.0.tgz#9caf1151ac41b1e9e64d3a2ff9ece996ca18977d" + version "6.3.1" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-6.3.1.tgz#5c52abde313d7ec9368c4abf67d27a656cba8b39" dependencies: balanced-match "^1.0.0" - postcss "^6.0.3" + postcss "^6.0.18" postcss-custom-selectors@^4.0.1: version "4.0.1" @@ -685,51 +898,35 @@ postcss-custom-selectors@^4.0.1: postcss "^6.0.1" postcss-selector-matches "^3.0.0" -postcss-discard-comments@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" +postcss-discard-comments@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.0.tgz#9684a299e76b3e93263ef8fd2adbf1a1c08fd88d" dependencies: - postcss "^5.0.14" + postcss "^6.0.0" -postcss-discard-duplicates@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932" +postcss-discard-duplicates@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.0.tgz#42f3c267f85fa909e042c35767ecfd65cb2bd72c" dependencies: - postcss "^5.0.4" + postcss "^6.0.0" -postcss-discard-empty@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" +postcss-discard-empty@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.0.tgz#55e18a59c74128e38c7d2804bcfa4056611fb97f" dependencies: - postcss "^5.0.14" + postcss "^6.0.0" -postcss-discard-overridden@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" +postcss-discard-overridden@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.0.tgz#4a0bf85978784cf1f81ed2c1c1fd9d964a1da1fa" dependencies: - postcss "^5.0.16" + postcss "^6.0.0" -postcss-discard-unused@^2.2.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" +postcss-font-family-system-ui@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-family-system-ui/-/postcss-font-family-system-ui-3.0.0.tgz#675fe7a9e029669f05f8dba2e44c2225ede80623" dependencies: - postcss "^5.0.14" - uniqs "^2.0.0" - -postcss-filter-plugins@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz#6d85862534d735ac420e4a85806e1f5d4286d84c" - dependencies: - postcss "^5.0.4" - uniqid "^4.0.0" - -postcss-font-family-system-ui@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-font-family-system-ui/-/postcss-font-family-system-ui-2.0.1.tgz#318a075fdcb84b864aa823a51935ef0a5872e911" - dependencies: - lodash "^4.17.4" - postcss "^6.0.1" - postcss-value-parser "^3.3.0" + postcss "^6.0" postcss-font-variant@^3.0.0: version "3.0.0" @@ -744,12 +941,11 @@ postcss-image-set-polyfill@^0.3.5: postcss "^6.0.1" postcss-media-query-parser "^0.2.3" -postcss-import@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-10.0.0.tgz#4c85c97b099136cc5ea0240dc1dfdbfde4e2ebbe" +postcss-import@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-12.0.0.tgz#149f96a4ef0b27525c419784be8517ebd17e92c5" dependencies: - object-assign "^4.0.1" - postcss "^6.0.1" + postcss "^7.0.1" postcss-value-parser "^3.2.3" read-cache "^1.0.0" resolve "^1.1.7" @@ -771,94 +967,149 @@ postcss-media-query-parser@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" -postcss-merge-idents@^2.1.5: - version "2.1.7" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" +postcss-merge-longhand@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.4.tgz#bffc7c6ffa146591c993a0bb8373d65f9a06d4d0" dependencies: - has "^1.0.1" - postcss "^5.0.10" - postcss-value-parser "^3.1.1" + css-color-names "0.0.4" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" + stylehacks "^4.0.0" -postcss-merge-longhand@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658" +postcss-merge-rules@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.1.tgz#430fd59b3f2ed2e8afcd0b31278eda39854abb10" dependencies: - postcss "^5.0.4" - -postcss-merge-rules@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721" - dependencies: - browserslist "^1.5.2" - caniuse-api "^1.5.2" - postcss "^5.0.4" - postcss-selector-parser "^2.2.2" + browserslist "^4.0.0" + caniuse-api "^3.0.0" + cssnano-util-same-parent "^4.0.0" + postcss "^6.0.0" + postcss-selector-parser "^3.0.0" vendors "^1.0.0" postcss-message-helpers@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" -postcss-minify-font-values@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" +postcss-minify-font-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.0.tgz#4cc33d283d6a81759036e757ef981d92cbd85bed" dependencies: - object-assign "^4.0.1" - postcss "^5.0.4" - postcss-value-parser "^3.0.2" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" -postcss-minify-gradients@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" +postcss-minify-gradients@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.0.tgz#3fc3916439d27a9bb8066db7cdad801650eb090e" dependencies: - postcss "^5.0.12" - postcss-value-parser "^3.3.0" + cssnano-util-get-arguments "^4.0.0" + is-color-stop "^1.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" -postcss-minify-params@^1.0.4: - version "1.2.2" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" +postcss-minify-params@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.0.tgz#05e9166ee48c05af651989ce84d39c1b4d790674" dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.2" - postcss-value-parser "^3.0.2" + alphanum-sort "^1.0.0" + cssnano-util-get-arguments "^4.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" uniqs "^2.0.0" -postcss-minify-selectors@^2.0.4: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" +postcss-minify-selectors@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.0.tgz#b1e9f6c463416d3fcdcb26e7b785d95f61578aad" dependencies: - alphanum-sort "^1.0.2" - has "^1.0.1" - postcss "^5.0.14" - postcss-selector-parser "^2.0.0" + alphanum-sort "^1.0.0" + has "^1.0.0" + postcss "^6.0.0" + postcss-selector-parser "^3.0.0" postcss-nesting@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-4.0.1.tgz#8fc2ce40cbfcfab7ee24e7b68fb6ebe84b641469" + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-4.2.1.tgz#0483bce338b3f0828ced90ff530b29b98b00300d" dependencies: - postcss "^6.0.1" + postcss "^6.0.11" -postcss-normalize-charset@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" +postcss-normalize-charset@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.0.tgz#24527292702d5e8129eafa3d1de49ed51a6ab730" dependencies: - postcss "^5.0.5" + postcss "^6.0.0" -postcss-normalize-url@^3.0.7: - version "3.0.8" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" +postcss-normalize-display-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.0.tgz#950e0c7be3445770a160fffd6b6644c3c0cd8f89" + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-positions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.0.tgz#ee9343ab981b822c63ab72615ecccd08564445a3" + dependencies: + cssnano-util-get-arguments "^4.0.0" + has "^1.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-repeat-style@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.0.tgz#b711c592cf16faf9ff575e42fa100b6799083eff" + dependencies: + cssnano-util-get-arguments "^4.0.0" + cssnano-util-get-match "^4.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.0.tgz#718cb6d30a6fac6ac6a830e32c06c07dbc66fe5d" + dependencies: + has "^1.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-timing-functions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.0.tgz#0351f29886aa981d43d91b2c2bd1aea6d0af6d23" + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-unicode@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.0.tgz#5acd5d47baea5d17674b2ccc4ae5166fa88cdf97" + dependencies: + postcss "^6.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-url@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.0.tgz#b7a9c8ad26cf26694c146eb2d68bd0cf49956f0d" dependencies: is-absolute-url "^2.0.0" - normalize-url "^1.4.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" + normalize-url "^3.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" -postcss-ordered-values@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d" +postcss-normalize-whitespace@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.0.tgz#1da7e76b10ae63c11827fa04fc3bb4a1efe99cc0" dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.1" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" + +postcss-ordered-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.0.0.tgz#58b40c74f72e022eb34152c12e4b0f9354482fc2" + dependencies: + cssnano-util-get-arguments "^4.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" postcss-pseudo-class-any-link@^4.0.0: version "4.0.0" @@ -873,26 +1124,23 @@ postcss-pseudoelements@^5.0.0: dependencies: postcss "^6.0.0" -postcss-reduce-idents@^2.2.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" +postcss-reduce-initial@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.1.tgz#f2d58f50cea2b0c5dc1278d6ea5ed0ff5829c293" dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.2" + browserslist "^4.0.0" + caniuse-api "^3.0.0" + has "^1.0.0" + postcss "^6.0.0" -postcss-reduce-initial@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" +postcss-reduce-transforms@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.0.tgz#f645fc7440c35274f40de8104e14ad7163edf188" dependencies: - postcss "^5.0.4" - -postcss-reduce-transforms@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" - dependencies: - has "^1.0.1" - postcss "^5.0.8" - postcss-value-parser "^3.0.1" + cssnano-util-get-match "^4.0.0" + has "^1.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" postcss-replace-overflow-wrap@^2.0.0: version "2.0.0" @@ -914,7 +1162,7 @@ postcss-selector-not@^3.0.1: balanced-match "^0.4.2" postcss "^6.0.1" -postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2, postcss-selector-parser@^2.2.3: +postcss-selector-parser@^2.2.2, postcss-selector-parser@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" dependencies: @@ -922,66 +1170,71 @@ postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2, postcss-selector indexes-of "^1.0.1" uniq "^1.0.1" -postcss-svgo@^2.1.1: - version "2.1.6" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" +postcss-selector-parser@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz#4f875f4afb0c96573d5cf4d74011aee250a7e865" dependencies: - is-svg "^2.0.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - svgo "^0.7.0" + dot-prop "^4.1.1" + indexes-of "^1.0.1" + uniq "^1.0.1" -postcss-unique-selectors@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" +postcss-svgo@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.0.tgz#c0bbad02520fc636c9d78b0e8403e2e515c32285" dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.4" + is-svg "^3.0.0" + postcss "^6.0.0" + postcss-value-parser "^3.0.0" + svgo "^1.0.0" + +postcss-unique-selectors@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.0.tgz#04c1e9764c75874261303402c41f0e9769fc5501" + dependencies: + alphanum-sort "^1.0.0" + postcss "^6.0.0" uniqs "^2.0.0" -postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: +postcss-value-parser@^3.0.0, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15" -postcss-zindex@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" +postcss-values-parser@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-1.5.0.tgz#5d9fa63e2bcb0179ce48f3235303765eb89f3047" dependencies: - has "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" -postcss@^5.0.0, postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.8, postcss@^5.2.16: - version "5.2.17" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.17.tgz#cf4f597b864d65c8a492b2eabe9d706c879c388b" +postcss@^5.0.0: + version "5.2.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" dependencies: chalk "^1.1.3" js-base64 "^2.1.9" source-map "^0.5.6" supports-color "^3.2.3" -postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.3, postcss@^6.0.5, postcss@^6.0.6: - version "6.0.6" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.6.tgz#bba4d58e884fc78c840d1539e10eddaabb8f73bd" +postcss@^6.0, postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.11, postcss@^6.0.14, postcss@^6.0.17, postcss@^6.0.18, postcss@^6.0.22, postcss@^6.0.5, postcss@^6.0.6: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" dependencies: - chalk "^2.0.1" - source-map "^0.5.6" - supports-color "^4.1.0" + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" -prepend-http@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" +postcss@^7.0.1: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.2.tgz#7b5a109de356804e27f95a960bef0e4d5bc9bb18" + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" q@^1.1.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" - -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" read-cache@^1.0.0: version "1.0.0" @@ -989,7 +1242,7 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -reduce-css-calc@^1.2.6, reduce-css-calc@^1.2.7: +reduce-css-calc@^1.2.7: version "1.3.0" resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" dependencies: @@ -998,8 +1251,8 @@ reduce-css-calc@^1.2.6, reduce-css-calc@^1.2.7: reduce-function-call "^1.0.1" reduce-css-calc@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.0.5.tgz#33c97838c5d4c711a5c14ef85ce4fde41483f7bd" + version "2.1.4" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.4.tgz#c20e9cda8445ad73d4ff4bea960c6f8353791708" dependencies: css-unit-converter "^1.1.1" postcss-value-parser "^3.3.0" @@ -1010,13 +1263,13 @@ reduce-function-call@^1.0.1, reduce-function-call@^1.0.2: dependencies: balanced-match "^0.4.2" -regenerator-runtime@^0.10.0: - version "0.10.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" resolve@^1.1.7: - version "1.3.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" + version "1.8.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" dependencies: path-parse "^1.0.5" @@ -1024,37 +1277,47 @@ rgb-hex@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/rgb-hex/-/rgb-hex-2.1.0.tgz#c773c5fe2268a25578d92539a82a7a5ce53beda6" +rgb-regex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" + rgb@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/rgb/-/rgb-0.1.0.tgz#be27b291e8feffeac1bd99729721bfa40fc037b5" -sax@~1.2.1: +rgba-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" + +sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" +semver@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" dependencies: is-arrayish "^0.3.1" -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - dependencies: - is-plain-obj "^1.0.0" - source-map@^0.5.3, source-map@^0.5.6: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" +stable@~0.1.6: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" strip-ansi@^3.0.0: version "3.0.1" @@ -1062,6 +1325,14 @@ strip-ansi@^3.0.0: dependencies: ansi-regex "^2.0.0" +stylehacks@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.0.tgz#64b323951c4a24e5fc7b2ec06c137bf32d155e8a" + dependencies: + browserslist "^4.0.0" + postcss "^6.0.0" + postcss-selector-parser "^3.0.0" + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -1072,23 +1343,34 @@ supports-color@^3.2.3: dependencies: has-flag "^1.0.0" -supports-color@^4.0.0, supports-color@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.0.tgz#ad986dc7eb2315d009b4d77c8169c2231a684037" +supports-color@^5.3.0, supports-color@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" dependencies: - has-flag "^2.0.0" + has-flag "^3.0.0" -svgo@^0.7.0: - version "0.7.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" +svgo@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.0.5.tgz#7040364c062a0538abacff4401cea6a26a7a389a" dependencies: - coa "~1.0.1" + coa "~2.0.1" colors "~1.1.2" - csso "~2.3.1" - js-yaml "~3.7.0" + css-select "~1.3.0-rc0" + css-select-base-adapter "~0.1.0" + css-tree "1.0.0-alpha25" + css-url-regex "^1.1.0" + csso "^3.5.0" + js-yaml "~3.10.0" mkdirp "~0.5.1" - sax "~1.2.1" - whet.extend "~0.9.9" + object.values "^1.0.4" + sax "~1.2.4" + stable "~0.1.6" + unquote "~1.1.1" + util.promisify "~1.0.0" + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" traverse-chain@~0.1.0: version "0.1.0" @@ -1098,12 +1380,6 @@ uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" -uniqid@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/uniqid/-/uniqid-4.1.1.tgz#89220ddf6b751ae52b5f72484863528596bb84c1" - dependencies: - macaddress "^0.2.8" - uniqs@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" @@ -1115,9 +1391,20 @@ units-css@^0.4.0: isnumeric "^0.2.0" viewport-dimensions "^0.2.0" +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + +util.promisify@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + vendors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22" + version "1.0.2" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.2.tgz#7fcb5eef9f5623b156bcea89ec37d63676f21801" viewport-dimensions@^0.2.0: version "0.2.0" @@ -1129,7 +1416,3 @@ watch@^1.0.2: dependencies: exec-sh "^0.2.0" minimist "^1.2.0" - -whet.extend@~0.9.9: - version "0.9.9" - resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" From 1dc13701154aec5abce19f5811b21e23b102bb4f Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Thu, 9 Aug 2018 11:34:02 -0400 Subject: [PATCH 11/17] Update some types * Remove empty values from types for serialization, so that empty values are not sent with API requests * Allow use of explicit setters for more complex types --- src/API/Kitsu/ListItem.php | 4 +- src/API/Kitsu/Model.php | 1 + .../Transformer/AnimeListTransformer.php | 4 +- src/API/ListItemInterface.php | 6 +-- src/Controller/Anime.php | 5 ++- src/Types/AbstractType.php | 39 +++++++++++++++---- src/Types/AnimeFormItem.php | 7 +++- src/Types/FormItem.php | 2 + src/Types/MangaFormItem.php | 7 +++- 9 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/API/Kitsu/ListItem.php b/src/API/Kitsu/ListItem.php index bb7be57b..e91ca394 100644 --- a/src/API/Kitsu/ListItem.php +++ b/src/API/Kitsu/ListItem.php @@ -25,7 +25,7 @@ use Aviat\AnimeClient\API\{ HummingbirdClient, ListItemInterface }; -use Aviat\AnimeClient\Types\AbstractType; +use Aviat\AnimeClient\Types\FormItemData; use Aviat\Ion\Di\ContainerAware; use Aviat\Ion\Json; @@ -112,7 +112,7 @@ final class ListItem implements ListItemInterface { return Json::decode(wait($response->getBody())); } - public function update(string $id, AbstractType $data): Request + public function update(string $id, FormItemData $data): Request { $authHeader = $this->getAuthHeader(); $requestData = [ diff --git a/src/API/Kitsu/Model.php b/src/API/Kitsu/Model.php index 42963390..634c5462 100644 --- a/src/API/Kitsu/Model.php +++ b/src/API/Kitsu/Model.php @@ -40,6 +40,7 @@ use Aviat\AnimeClient\Types\{ AbstractType, Anime, FormItem, + FormItemData, AnimeListItem, MangaPage }; diff --git a/src/API/Kitsu/Transformer/AnimeListTransformer.php b/src/API/Kitsu/Transformer/AnimeListTransformer.php index 19b01952..ab73ac50 100644 --- a/src/API/Kitsu/Transformer/AnimeListTransformer.php +++ b/src/API/Kitsu/Transformer/AnimeListTransformer.php @@ -125,13 +125,13 @@ final class AnimeListTransformer extends AbstractTransformer { $untransformed = new AnimeFormItem([ 'id' => $item['id'], 'mal_id' => $item['mal_id'] ?? NULL, - 'data' => new AnimeFormItemData([ + 'data' => [ 'status' => $item['watching_status'], 'reconsuming' => $rewatching, 'reconsumeCount' => $item['rewatched'], 'notes' => $item['notes'], 'private' => $privacy - ]) + ] ]); if (is_numeric($item['episodes_watched']) && $item['episodes_watched'] > 0) diff --git a/src/API/ListItemInterface.php b/src/API/ListItemInterface.php index 9fbcde48..2fb6404a 100644 --- a/src/API/ListItemInterface.php +++ b/src/API/ListItemInterface.php @@ -17,7 +17,7 @@ namespace Aviat\AnimeClient\API; use Amp\Artax\Request; -use Aviat\AnimeClient\Types\AbstractType; +use Aviat\AnimeClient\Types\FormItemData; /** * Common interface for anime and manga list item CRUD @@ -44,10 +44,10 @@ interface ListItemInterface { * Update a list item * * @param string $id - The id of the list item to update - * @param AbstractType $data - The data with which to update the list item + * @param FormItemData $data - The data with which to update the list item * @return Request */ - public function update(string $id, AbstractType $data): Request; + public function update(string $id, FormItemData $data): Request; /** * Delete a list item diff --git a/src/Controller/Anime.php b/src/Controller/Anime.php index d1ccb05e..4fec2e7f 100644 --- a/src/Controller/Anime.php +++ b/src/Controller/Anime.php @@ -20,6 +20,7 @@ use Aviat\AnimeClient\Controller as BaseController; use Aviat\AnimeClient\API\Kitsu\Transformer\AnimeListTransformer; use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus; use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus; +use Aviat\AnimeClient\Types\AnimeFormItem; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Json; use Aviat\Ion\StringWrapper; @@ -201,7 +202,7 @@ final class Anime extends BaseController { // large form-based updates $transformer = new AnimeListTransformer(); $postData = $transformer->untransform($data); - $fullResult = $this->model->updateLibraryItem($postData); + $fullResult = $this->model->updateLibraryItem(new AnimeFormItem($postData)); if ($fullResult['statusCode'] === 200) { @@ -232,7 +233,7 @@ final class Anime extends BaseController { $data = $this->request->getParsedBody(); } - $response = $this->model->updateLibraryItem($data); + $response = $this->model->updateLibraryItem(new AnimeFormItem($data)); $this->cache->clear(); $this->outputJSON($response['body'], $response['statusCode']); diff --git a/src/Types/AbstractType.php b/src/Types/AbstractType.php index 664f3fde..f4dd427d 100644 --- a/src/Types/AbstractType.php +++ b/src/Types/AbstractType.php @@ -34,12 +34,24 @@ abstract class AbstractType implements ArrayAccess { /** * Sets the properties by using the constructor * - * @param array $data + * @param mixed $data */ - public function __construct(array $data = []) + public function __construct($data = []) { - foreach ($data as $key => $value) { - $this->$key = $value; + $typeKeys = array_keys((array)$this); + $dataKeys = array_keys((array)$data); + + $unsetKeys = array_diff($typeKeys, $dataKeys); + + foreach ($data as $key => $value) + { + $this->__set($key, $value); + } + + // Remove unset keys so that they aren't serialized + foreach ($unsetKeys as $k) + { + unset($this->$k); } } @@ -63,7 +75,16 @@ abstract class AbstractType implements ArrayAccess { */ public function __set($name, $value): void { - if (!property_exists($this, $name)) { + $setterMethod = 'set' . ucfirst($name); + + if (method_exists($this, $setterMethod)) + { + $this->$setterMethod($value); + return; + } + + if (!property_exists($this, $name)) + { $existing = json_encode($this); throw new LogicException("Trying to set non-existent property: '$name'. Existing properties: $existing"); @@ -80,7 +101,8 @@ abstract class AbstractType implements ArrayAccess { */ public function __get($name) { - if (property_exists($this, $name)) { + if (property_exists($this, $name)) + { return $this->$name; } @@ -127,6 +149,9 @@ abstract class AbstractType implements ArrayAccess { */ public function offsetUnset($offset): void { - // Do nothing! + if ($this->offsetExists($offset)) + { + unset($this->$offset); + } } } \ No newline at end of file diff --git a/src/Types/AnimeFormItem.php b/src/Types/AnimeFormItem.php index 69a72881..69a6f501 100644 --- a/src/Types/AnimeFormItem.php +++ b/src/Types/AnimeFormItem.php @@ -19,4 +19,9 @@ namespace Aviat\AnimeClient\Types; /** * Type representing an Anime object for display */ -final class AnimeFormItem extends FormItem { } +final class AnimeFormItem extends FormItem { + public function setData($value): void + { + $this->data = new AnimeFormItemData($value); + } +} diff --git a/src/Types/FormItem.php b/src/Types/FormItem.php index 084a1578..f5a3a5d8 100644 --- a/src/Types/FormItem.php +++ b/src/Types/FormItem.php @@ -23,5 +23,7 @@ abstract class FormItem extends AbstractType { public $id; public $mal_id; public $data; + + abstract public function setData($value): void; } diff --git a/src/Types/MangaFormItem.php b/src/Types/MangaFormItem.php index ecc0dcb9..6b630c1a 100644 --- a/src/Types/MangaFormItem.php +++ b/src/Types/MangaFormItem.php @@ -19,5 +19,10 @@ namespace Aviat\AnimeClient\Types; /** * Form data for updating a Manga List item */ -final class MangaFormItem extends FormItem { } +final class MangaFormItem extends FormItem { + public function setData($value): void + { + $this->data = new MangaFormItemData($value); + } +} From b4a843e699e29372c0883612a376ab40fab2aee1 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Fri, 10 Aug 2018 11:01:30 -0400 Subject: [PATCH 12/17] Fix test snapshots --- .../AnimeListTransformerTest__testTransform__1.php | 8 -------- ...ansformerTest__testUntransform with data set #2__1.php | 1 - .../AnimeTransformerTest__testTransform__1.php | 1 - .../MangaTransformerTest__testTransform__1.php | 1 - 4 files changed, 11 deletions(-) diff --git a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testTransform__1.php b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testTransform__1.php index d790a572..8fb7c0d6 100644 --- a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testTransform__1.php +++ b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testTransform__1.php @@ -16,10 +16,7 @@ 'anime' => Aviat\AnimeClient\Types\Anime::__set_state(array( 'age_rating' => NULL, - 'age_rating_guide' => NULL, 'cover_image' => 'https://media.kitsu.io/anime/poster_images/12243/small.jpg?1481144116', - 'episode_count' => NULL, - 'episode_length' => NULL, 'genres' => array ( 0 => 'Comedy', @@ -27,22 +24,17 @@ 2 => 'Slice of Life', ), 'id' => '12243', - 'included' => NULL, 'show_type' => 'TV', 'slug' => 'kobayashi-san-chi-no-maid-dragon', - 'status' => NULL, 'streaming_links' => array ( ), - 'synopsis' => NULL, 'title' => 'Kobayashi-san Chi no Maid Dragon', 'titles' => array ( 0 => 'Miss Kobayashi\'s Dragon Maid', 1 => '小林さんちのメイドラゴン', ), - 'trailer_id' => NULL, - 'url' => NULL, )), 'watching_status' => 'current', 'notes' => NULL, diff --git a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #2__1.php b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #2__1.php index 5da554fb..0fb53da4 100644 --- a/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #2__1.php +++ b/tests/API/Kitsu/Transformer/__snapshots__/AnimeListTransformerTest__testUntransform with data set #2__1.php @@ -6,7 +6,6 @@ 'notes' => '', 'private' => true, 'progress' => 12, - 'rating' => NULL, 'reconsumeCount' => 0, 'reconsuming' => true, 'status' => 'current', diff --git a/tests/API/Kitsu/Transformer/__snapshots__/AnimeTransformerTest__testTransform__1.php b/tests/API/Kitsu/Transformer/__snapshots__/AnimeTransformerTest__testTransform__1.php index 788c598b..966a59dd 100644 --- a/tests/API/Kitsu/Transformer/__snapshots__/AnimeTransformerTest__testTransform__1.php +++ b/tests/API/Kitsu/Transformer/__snapshots__/AnimeTransformerTest__testTransform__1.php @@ -8,7 +8,6 @@ array ( ), 'id' => 32344, - 'included' => NULL, 'show_type' => 'TV', 'slug' => 'attack-on-titan', 'status' => 'Finished Airing', diff --git a/tests/API/Kitsu/Transformer/__snapshots__/MangaTransformerTest__testTransform__1.php b/tests/API/Kitsu/Transformer/__snapshots__/MangaTransformerTest__testTransform__1.php index ec814886..fa06654c 100644 --- a/tests/API/Kitsu/Transformer/__snapshots__/MangaTransformerTest__testTransform__1.php +++ b/tests/API/Kitsu/Transformer/__snapshots__/MangaTransformerTest__testTransform__1.php @@ -6,7 +6,6 @@ array ( ), 'id' => '20286', - 'included' => NULL, 'jp_title' => 'Bokura wa Minna Kawaisou', 'manga_type' => 'manga', 'synopsis' => 'Usa, a high-school student aspiring to begin a bachelor lifestyle, moves into a new apartment only to discover that he not only shares a room with a perverted roommate that has an obsession for underaged girls, but also that another girl, Ritsu, a love-at-first-sight, is living in the same building as well! From 787687abf8749e0ff3928a953780004308ae13b7 Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Fri, 10 Aug 2018 20:09:28 -0400 Subject: [PATCH 13/17] Update some styles --- app/views/anime/cover.php | 32 +- app/views/anime/list.php | 2 +- app/views/collection/cover-item.php | 27 ++ app/views/collection/cover.php | 30 +- app/views/collection/edit.php | 16 +- app/views/collection/list-item.php | 19 + app/views/collection/list.php | 94 ++-- app/views/main-menu.php | 4 +- app/views/manga/cover.php | 2 +- app/views/manga/edit.php | 18 +- app/views/manga/list.php | 4 +- public/css/app.min.css | 2 +- public/css/base.css | 657 +++++++++++++++++----------- public/js/anime_edit.js | 2 +- public/js/base/sort_tables.js | 85 ++-- 15 files changed, 574 insertions(+), 420 deletions(-) create mode 100644 app/views/collection/cover-item.php create mode 100644 app/views/collection/list-item.php diff --git a/app/views/anime/cover.php b/app/views/anime/cover.php index b4d52de8..7f6d5e66 100644 --- a/app/views/anime/cover.php +++ b/app/views/anime/cover.php @@ -1,4 +1,4 @@ -
+
isAuthenticated()): ?> Add Item @@ -24,27 +24,13 @@ " alt="" />
- isAuthenticated()): ?> -
- - Edit - -
- -
@@ -77,6 +63,20 @@
+ isAuthenticated()): ?> +
+ + Edit + +
+ +
Rating: / 10
Episodes: diff --git a/app/views/anime/list.php b/app/views/anime/list.php index 08172ebd..489bcc59 100644 --- a/app/views/anime/list.php +++ b/app/views/anime/list.php @@ -1,4 +1,4 @@ -
+
isAuthenticated()): ?> Add Item diff --git a/app/views/collection/cover-item.php b/app/views/collection/cover-item.php new file mode 100644 index 00000000..0244dd83 --- /dev/null +++ b/app/views/collection/cover-item.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/app/views/collection/cover.php b/app/views/collection/cover.php index 9f82b9ae..7441f79b 100644 --- a/app/views/collection/cover.php +++ b/app/views/collection/cover.php @@ -1,4 +1,4 @@ -
+
isAuthenticated()): ?> Add Item @@ -14,33 +14,7 @@

- +
diff --git a/app/views/collection/edit.php b/app/views/collection/edit.php index 6b7af08f..33882b9d 100644 --- a/app/views/collection/edit.php +++ b/app/views/collection/edit.php @@ -2,7 +2,7 @@

Edit Anime Collection Item

- +
- - - + + + + + isAuthenticated()): ?> + + + + + + + + + \ No newline at end of file diff --git a/app/views/collection/list.php b/app/views/collection/list.php index f5ab3be5..049a63be 100644 --- a/app/views/collection/list.php +++ b/app/views/collection/list.php @@ -1,58 +1,42 @@
-isAuthenticated()): ?> -Add Item - - -

There's nothing here!

- - -
- $items): ?> - type="radio" id="collection-tab-" name="collection-tabs" /> - -
-

-
- - - isAuthenticated()): ?> - - - - - - - - - - - - - - isAuthenticated()): ?> - - - - - - - - - - - -
ActionsTitleEpisode CountEpisode LengthShow TypeAge RatingNotes
- Edit - - - - - " . $item['alternate_title'] . "" : "" ?> -
-
- - -
- + isAuthenticated()): ?> + Add Item + + +

There's nothing here!

+ + +
+ $items): ?> + type="radio" id="collection-tab-" + name="collection-tabs"/> + +
+

+ + + + isAuthenticated()): ?> + + + + + + + + + + + + + + + +
ActionsTitleEpisode CountEpisode LengthShow TypeAge RatingNotes
+
+ + +
+
\ No newline at end of file diff --git a/app/views/main-menu.php b/app/views/main-menu.php index 7c424b57..f27ca846 100644 --- a/app/views/main-menu.php +++ b/app/views/main-menu.php @@ -7,7 +7,7 @@ $lastSegment = $urlGenerator->lastSegment(); $extraSegment = $lastSegment === 'list' ? '/list' : ''; ?> -

+

+