From 50b65d66e19dad1f7b221db3461bd2fe0b8d700e Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Fri, 26 Oct 2018 13:08:45 -0400 Subject: [PATCH] Ugly Progress Commit * Update Person pages to have series organized by character for Voice Acting * Miscellaneous style updates * Add placeholder images for items missing images --- app/views/anime/details.php | 14 ++--- app/views/character.php | 23 ++++++-- app/views/manga/details.php | 10 ++-- app/views/person/character-mapping.php | 62 +++++++++++++++++++++ app/views/{person.php => person/index.php} | 6 +- composer.json | 1 + index.php | 2 + public/css/app.min.css | 2 +- public/css/base.css | 35 ++++++++++-- public/images/placeholder.png | Bin 0 -> 242 bytes src/API/JsonAPI.php | 57 ++++++++++--------- src/API/Kitsu/Model.php | 25 +++++++-- src/AnimeClient.php | 48 ++++++++++++++-- src/Controller/Character.php | 8 +++ src/Controller/Index.php | 39 +++++++++++-- src/Controller/People.php | 51 ++++++++++++++++- 16 files changed, 316 insertions(+), 67 deletions(-) create mode 100644 app/views/person/character-mapping.php rename app/views/{person.php => person/index.php} (92%) create mode 100644 public/images/placeholder.png diff --git a/app/views/anime/details.php b/app/views/anime/details.php index 72aed462..fb500b89 100644 --- a/app/views/anime/details.php +++ b/app/views/anime/details.php @@ -1,6 +1,6 @@
-
-
+
+
-
+ +

@@ -85,13 +85,13 @@

Trailer

-
+
0): ?> -
+

Characters

-
+
$char): ?>
diff --git a/app/views/character.php b/app/views/character.php index d4b90e69..1e090e7c 100644 --- a/app/views/character.php +++ b/app/views/character.php @@ -4,18 +4,29 @@ use Aviat\AnimeClient\API\Kitsu; ?>
-
- +
-
-

+ +

Nicknames / Other names

+ +

+ + + +
+

+ +

+ + +

-
+
diff --git a/app/views/manga/details.php b/app/views/manga/details.php index 80ab7b3c..86492646 100644 --- a/app/views/manga/details.php +++ b/app/views/manga/details.php @@ -1,6 +1,6 @@
-
+
-
+ +

@@ -37,12 +37,12 @@

-
+
0): ?>

Characters

-
+
$char): ?>
diff --git a/app/views/person/character-mapping.php b/app/views/person/character-mapping.php new file mode 100644 index 00000000..a8f8499a --- /dev/null +++ b/app/views/person/character-mapping.php @@ -0,0 +1,62 @@ + + $casting): ?> + + + + + + + $character): ?> + + + + + +
CharacterSeries
+ + +
+ $series): ?> + + +
+
+ + diff --git a/app/views/person.php b/app/views/person/index.php similarity index 92% rename from app/views/person.php rename to app/views/person/index.php index 166cf687..1a1cd5e6 100644 --- a/app/views/person.php +++ b/app/views/person/index.php @@ -1,5 +1,4 @@
@@ -27,7 +26,11 @@ use Aviat\AnimeClient\API\Kitsu;

Castings

$entries): ?>

+ + + $casting): ?> +
@@ -68,6 +71,7 @@ use Aviat\AnimeClient\API\Kitsu;

+
diff --git a/composer.json b/composer.json index e73f0926..894d8ae6 100644 --- a/composer.json +++ b/composer.json @@ -24,6 +24,7 @@ "aura/session": "^2.0", "aviat/banker": "^1.0.0", "aviat/ion": "^2.4.1", + "ext-iconv": "*", "ext-json": "*", "ext-gd":"*", "ext-pdo": "*", diff --git a/index.php b/index.php index 231b25e9..e249fd48 100644 --- a/index.php +++ b/index.php @@ -20,6 +20,8 @@ use Aviat\AnimeClient\Types\Config as ConfigType; use function Aviat\Ion\_dir; +setlocale(LC_CTYPE, 'en_US'); + // Work around the silly timezone error $timezone = ini_get('date.timezone'); if ($timezone === '' || $timezone === FALSE) diff --git a/public/css/app.min.css b/public/css/app.min.css index bf224823..e9f97e63 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,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}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}#main-nav a,.bracketed{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;position:relative;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%}#main-nav{border-bottom:.1rem solid rgba(0,0,0,.2);font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;font-size:3.6em;font-size:36px;font-size:3.6rem;font-style:normal;font-weight:500;margin:2rem 0 1.6rem}.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 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}.invisible tbody>tr:nth-child(odd){background:inherit}.invisible td,.invisible th,.invisible tr{border:0}.message,.static-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,.static-message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success,.static-message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info,.static-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;z-index:0}.details picture.cover,picture.cover{display:inline;display:initial;width:100%}.character>img,.media>img,.small_character>img{width:100%}.media .edit_buttons>button{margin:.5em auto}.media_metadata>div,.medium_metadata>div,.name,.row{color:#fff;padding:.25em .125em;text-align:right;text-shadow:2px 2px 2px #000;z-index:2}.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}.media>.name a{-webkit-transition:none;transition:none}.media .name a:before{content:"";display:block;height:311px;left:0;position:absolute;top:0;width:220px;z-index:-1}.media-list .media:hover .name a:before{background:rgba(0,0,0,.75)}.media>.name span.canonical{font-weight:700}.media>.name small{font-weight:400}.media:hover .name{background:rgba(0,0,0,.75)}.media-list .media>.name a:hover,.media-list .media>.name a:hover small{color:#1271db}.media:hover>.edit_buttons[hidden],.media:hover>button[hidden]{-webkit-transition:.25s ease;display:block;transition:.25s ease}.media:hover{-webkit-transition:.25s ease;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:2px 2px 2px #000}.anime .name,.manga .name{background:#000;background:rgba(0,0,0,.45);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;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;z-index:2}.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;z-index:2}.anime .media>button.plus_one{border-color:hsla(0,0%,100%,.65);left:44px;left:calc(50% - 66.5px);position:absolute;top:138px;top:calc(50% - 21.5px);z-index:50}.anime .media>button.plus_one:hover{background:#888;color:hsla(0,0%,100%,.65)}.anime .media>button.plus_one:active{background:#444}.manga .row{padding:1px}.manga .media{height:310px;margin:.25em}.manga .media>.edit_buttons{left:43.5px;left:calc(50% - 66.5px);position:absolute;top:86px;top:calc(50% - 22.4px);z-index:40}.manga .media>.edit_buttons button{border-color:hsla(0,0%,100%,.65)}.manga .media>.edit_buttons:hover button{background:#888;color:hsla(0,0%,100%,.65)}.manga .media>.edit_buttons button:active{background:#444}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35);background-repeat:no-repeat;background-size:cover;background-size:contain}.media.search>.row{z-index:6}.big-check,.mal-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%;z-index:5}#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{height:350px;vertical-align:middle;white-space:nowrap;width:225px}.character:hover .name,.small_character:hover .name{background:rgba(0,0,0,.8)}.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{display:none}.media:hover .cover_streaming_link{display:block}.cover_streaming_link .streaming-logo{-webkit-filter:drop-shadow(0 -1px 4px #fff);filter:drop-shadow(0 -1px 4px #fff);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}}.settings.form .content article{display:inline-block;margin:1em;width:auto} \ 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}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}#main-nav a,.bracketed{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-start{-ms-flex-line-pack:start;align-content:flex-start}.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-start{-ms-flex-pack:start;-webkit-box-pack:start;justify-content:flex-start}.flex-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.flex-self-center{-ms-flex-item-align:center;align-self:center}.flex-space-evenly{-ms-flex-pack:space-evenly;-webkit-box-pack:space-evenly;justify-content:space-evenly}.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;position:relative;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%}#main-nav{border-bottom:.1rem solid rgba(0,0,0,.2);font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Droid Sans,Helvetica Neue,sans-serif;font-size:3.6em;font-size:36px;font-size:3.6rem;font-style:normal;font-weight:500;margin:2rem 0 1.6rem}.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 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}.invisible tbody>tr:nth-child(odd){background:inherit}.invisible td,.invisible th,.invisible tr{border:0}.message,.static-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,.static-message.error{background:#f3e6e6;border:1px solid #924949}.message.error .icon:after{content:"✘"}.message.success,.static-message.success{background:#70dda9;border:1px solid #1f8454}.message.success .icon:after{content:"✔"}.message.info,.static-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;z-index:0}.details picture.cover,picture.cover{display:inline;display:initial;width:100%}.character>img,.media>img,.small_character>img{width:100%}.media .edit_buttons>button{margin:.5em auto}.media_metadata>div,.medium_metadata>div,.name,.row{color:#fff;padding:.25em .125em;text-align:right;text-shadow:2px 2px 2px #000;z-index:2}.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}.media>.name a{-webkit-transition:none;transition:none}.media .name a:before{content:"";display:block;height:311px;left:0;position:absolute;top:0;width:220px;z-index:-1}.media-list .media:hover .name a:before{background:rgba(0,0,0,.75)}.media>.name span.canonical{font-weight:700}.media>.name small{font-weight:400}.media:hover .name{background:rgba(0,0,0,.75)}.media-list .media>.name a:hover,.media-list .media>.name a:hover small{color:#1271db}.media:hover>.edit_buttons[hidden],.media:hover>button[hidden]{-webkit-transition:.25s ease;display:block;transition:.25s ease}.media:hover{-webkit-transition:.25s ease;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:2px 2px 2px #000}.anime .name,.manga .name{background:#000;background:rgba(0,0,0,.45);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;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;z-index:2}.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;z-index:2}.anime .media>button.plus_one{border-color:hsla(0,0%,100%,.65);left:44px;left:calc(50% - 66.5px);position:absolute;top:138px;top:calc(50% - 21.5px);z-index:50}.anime .media>button.plus_one:hover{background:#888;color:hsla(0,0%,100%,.65)}.anime .media>button.plus_one:active{background:#444}.manga .row{padding:1px}.manga .media{height:310px;margin:.25em}.manga .media>.edit_buttons{left:43.5px;left:calc(50% - 66.5px);position:absolute;top:86px;top:calc(50% - 22.4px);z-index:40}.manga .media>.edit_buttons button{border-color:hsla(0,0%,100%,.65)}.manga .media>.edit_buttons:hover button{background:#888;color:hsla(0,0%,100%,.65)}.manga .media>.edit_buttons button:active{background:#444}.media.search>.name{background-color:#555;background-color:rgba(0,0,0,.35);background-repeat:no-repeat;background-size:cover;background-size:contain}.media.search>.row{z-index:6}.big-check,.mal-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%;z-index:5}#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{margin:0 auto;max-width:1000px;max-width:100rem}.fixed .text{max-width:600px}.details .cover{display:block;width:284px}.details h2{margin-top:0}.details .flex>*{margin:1rem}.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{height:350px;vertical-align:middle;white-space:nowrap;width:225px}.character:hover .name,.small_character:hover .name{background:rgba(0,0,0,.8)}.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}aside.info{max-width:390px}aside.info img,aside.info picture{display:block;margin:0 auto}.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{display:none}.media:hover .cover_streaming_link{display:block}.cover_streaming_link .streaming-logo{-webkit-filter:drop-shadow(0 -1px 4px #fff);filter:drop-shadow(0 -1px 4px #fff);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}}.settings.form .content article{display:inline-block;margin:1em;width:auto} \ No newline at end of file diff --git a/public/css/base.css b/public/css/base.css index a3d48997..36527b75 100644 --- a/public/css/base.css +++ b/public/css/base.css @@ -91,6 +91,10 @@ a:hover, a:active { flex-wrap: nowrap } +.flex-align-start { + align-content: flex-start; +} + .flex-align-end { align-items: flex-end } @@ -99,6 +103,10 @@ a:hover, a:active { align-content: space-around } +.flex-justify-start { + justify-content: flex-start; +} + .flex-justify-space-around { justify-content: space-around } @@ -107,6 +115,10 @@ a:hover, a:active { align-self: center } +.flex-space-evenly { + justify-content: space-evenly; +} + .flex { display: flex } @@ -671,7 +683,13 @@ picture.cover { } .fixed { - max-width: 93rem; + max-width: 100rem; + /* max-width: 80%; */ + margin: 0 auto; +} + +.fixed .text { + max-width: 600px; } .details .cover { @@ -684,14 +702,10 @@ picture.cover { margin-top: 0; } -.details .flex > div { +.details .flex > * { margin: 1rem; } -.details .media_details { - max-width: 300px; -} - .details .media_details td { padding: 0 1.5rem; } @@ -752,6 +766,15 @@ picture.cover { margin-left: 0; } +aside.info { + max-width: 390px; +} + +aside.info picture, aside.info img { + display: block; + margin: 0 auto; +} + /* ---------------------------------------------------------------------------- User page styles -----------------------------------------------------------------------------*/ diff --git a/public/images/placeholder.png b/public/images/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..14327ee6d0c6995163296f45421123e9e4e283bc GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^DIm;M1%9UL4M{|(RviZGT0 z`2{mLJiCzwvL>4nJ@ErkR#;MwT(m=shPZ!4!i_^&o60D089x(PZ&UoVdaHHa9 z2?v|qb!>8*+3jz?Nx5-@-$3Pj&I3d9H@V)=5+8dec$irnNLD*o+$On#|HNkYPb&ZC ztbCsMxc)#wI>Qz9v%!Tk+I^K86&)WjM9gTe~DWM4fdSX?W literal 0 HcmV?d00001 diff --git a/src/API/JsonAPI.php b/src/API/JsonAPI.php index 234df2ec..989bad19 100644 --- a/src/API/JsonAPI.php +++ b/src/API/JsonAPI.php @@ -101,27 +101,28 @@ final class JsonAPI { continue; } + // Single data item - else if (array_key_exists('id', $props['data'])) + if (array_key_exists('id', $props['data'])) { $idKey = $props['data']['id']; - $typeKey = $props['data']['type']; + $dataType = $props['data']['type']; $relationship =& $item['relationships'][$relType]; unset($relationship['data']); - if (in_array($relType, $singular)) + if (\in_array($relType, $singular, TRUE)) { - $relationship = $included[$typeKey][$idKey]; + $relationship = $included[$dataType][$idKey]; continue; } - if ($relType === $typeKey) + if ($relType === $dataType) { - $relationship[$idKey] = $included[$typeKey][$idKey]; + $relationship[$idKey] = $included[$dataType][$idKey]; continue; } - $relationship[$typeKey][$idKey] = $included[$typeKey][$idKey]; + $relationship[$dataType][$idKey] = $included[$dataType][$idKey]; } // Multiple data items else @@ -129,16 +130,16 @@ final class JsonAPI { foreach($props['data'] as $j => $datum) { $idKey = $props['data'][$j]['id']; - $typeKey = $props['data'][$j]['type']; + $dataType = $props['data'][$j]['type']; $relationship =& $item['relationships'][$relType]; - if ($relType === $typeKey) + if ($relType === $dataType) { - $relationship[$idKey] = $included[$typeKey][$idKey]; + $relationship[$idKey] = $included[$dataType][$idKey]; continue; } - $relationship[$typeKey][$idKey][$j] = $included[$typeKey][$idKey]; + $relationship[$dataType][$idKey][$j] = $included[$dataType][$idKey]; } } } @@ -201,29 +202,33 @@ final class JsonAPI { { foreach($items as $id => $item) { - if (array_key_exists('relationships', $item) && is_array($item['relationships'])) + if (array_key_exists('relationships', $item) && \is_array($item['relationships'])) { foreach($item['relationships'] as $relType => $props) { - if (array_key_exists('data', $props) && is_array($props['data']) && array_key_exists('id', $props['data'])) + if (array_key_exists('data', $props) && \is_array($props['data']) && array_key_exists('id', $props['data'])) { - if (array_key_exists($props['data']['id'], $organized[$props['data']['type']])) + $idKey = $props['data']['id']; + $dataType = $props['data']['type']; + + if ( ! array_key_exists($dataType, $organized)) { - $idKey = $props['data']['id']; - $typeKey = $props['data']['type']; + $organized[$dataType] = []; + } + $relationship =& $organized[$type][$id]['relationships'][$relType]; + unset($relationship['links']); + unset($relationship['data']); - $relationship =& $organized[$type][$id]['relationships'][$relType]; - unset($relationship['links']); - unset($relationship['data']); + if ($relType === $dataType) + { + $relationship[$idKey] = $included[$dataType][$idKey]; + continue; + } - if ($relType === $typeKey) - { - $relationship[$idKey] = $included[$typeKey][$idKey]; - continue; - } - - $relationship[$typeKey][$idKey] = $organized[$typeKey][$idKey]; + if (array_key_exists($idKey, $organized[$dataType])) + { + $relationship[$dataType][$idKey] = $organized[$dataType][$idKey]; } } } diff --git a/src/API/Kitsu/Model.php b/src/API/Kitsu/Model.php index eb3fb05b..3a0751dc 100644 --- a/src/API/Kitsu/Model.php +++ b/src/API/Kitsu/Model.php @@ -229,11 +229,26 @@ final class Model { */ public function getPerson(string $id): array { - return $this->getRequest("people/{$id}", [ - 'query' => [ - 'include' => 'castings,castings.media,staff,staff.media,voices' - ], - ]); + $cacheItem = $this->cache->getItem("kitsu-person-{$id}"); + + if ( ! $cacheItem->isHit()) + { + $data = $this->getRequest("people/{$id}", [ + 'query' => [ + 'fields' => [ + 'characters' => 'canonicalName,slug,image', + 'anime' => 'canonicalTitle,titles,slug,posterImage', + 'manga' => 'canonicalTitle,titles,slug,posterImage', + ], + 'include' => 'castings.character,castings.media' + ], + ]); + + $cacheItem->set($data); + $cacheItem->save(); + } + + return $cacheItem->get(); } /** diff --git a/src/AnimeClient.php b/src/AnimeClient.php index a305c919..4d365042 100644 --- a/src/AnimeClient.php +++ b/src/AnimeClient.php @@ -206,14 +206,14 @@ function getLocalImg ($kitsuUrl): string { if ( ! is_string($kitsuUrl)) { - return '/404'; + return 'images/404/404.png'; } $parts = parse_url($kitsuUrl); if ($parts === FALSE) { - return '/404'; + return 'images/404/404.png'; } $file = basename($parts['path']); @@ -221,11 +221,51 @@ function getLocalImg ($kitsuUrl): string $ext = array_pop($fileParts); $segments = explode('/', trim($parts['path'], '/')); - // dump($segments); - $type = $segments[0] === 'users' ? $segments[1] : $segments[0]; $id = $segments[count($segments) - 2]; return implode('/', ['images', $type, "{$id}.{$ext}"]); +} + +/** + * Create a transparent placeholder image + * + * @param string $path + * @param int $width + * @param int $height + * @param string $text + */ +function createPlaceholderImage ($path, $width, $height, $text = 'Image Unavailable') +{ + $width = $width ?? 200; + $height = $height ?? 200; + + $img = imagecreate($width, $height); + + $path = rtrim($path, '/'); + + // Background is the first color by default + imagecolorallocatealpha($img, 255, 255, 255, 127); + $textColor = imagecolorallocate($img, 64, 64, 64); + + imagealphablending($img, TRUE); + + // Generate placeholder text + $fontSize = 10; + $fontWidth = imagefontwidth($fontSize); + $fontHeight = imagefontheight($fontSize); + $length = strlen($text); + $textWidth = $length * $fontWidth; + $fxPos = (int) ceil((imagesx($img) - $textWidth) / 2); + $fyPos = (int) ceil((imagesy($img) - $fontHeight) / 2); + + // Add the image text + imagestring($img, $fontSize, $fxPos, $fyPos, $text, $textColor); + + // Save the images + imagesavealpha($img, TRUE); + imagepng($img, $path . '/placeholder.png', 9); + + imagedestroy($img); } \ No newline at end of file diff --git a/src/Controller/Character.php b/src/Controller/Character.php index 6eba7d76..209253f6 100644 --- a/src/Controller/Character.php +++ b/src/Controller/Character.php @@ -59,6 +59,14 @@ class Character extends BaseController { $data = JsonAPI::organizeData($rawData); + $data['names'] = array_unique( + array_merge( + [ $data[0]['attributes']['canonicalName'] ], + $data[0]['attributes']['names'] + ) + ); + $data['name'] = array_shift($data['names']); + if (array_key_exists('included', $data)) { if (array_key_exists('anime', $data['included'])) diff --git a/src/Controller/Index.php b/src/Controller/Index.php index 5fad99ef..34e11da3 100644 --- a/src/Controller/Index.php +++ b/src/Controller/Index.php @@ -16,6 +16,7 @@ namespace Aviat\AnimeClient\Controller; +use function Aviat\AnimeClient\createPlaceholderImage; use function Amp\Promise\wait; use Aviat\AnimeClient\Controller as BaseController; @@ -269,45 +270,60 @@ final class Index extends BaseController { $fileName = str_replace('-original', '', $file); [$id, $ext] = explode('.', basename($fileName)); + $baseSavePath = $this->config->get('img_cache_path'); + $typeMap = [ 'anime' => [ 'kitsuUrl' => "anime/poster_images/{$id}/medium.{$ext}", 'width' => 220, + 'height' => 312, ], 'avatars' => [ 'kitsuUrl' => "users/avatars/{$id}/original.{$ext}", 'width' => null, + 'height' => null, ], 'characters' => [ 'kitsuUrl' => "characters/images/{$id}/original.{$ext}", 'width' => 225, + 'height' => 350, ], 'manga' => [ 'kitsuUrl' => "manga/poster_images/{$id}/medium.{$ext}", 'width' => 220, + 'height' => 312, ], 'people' => [ 'kitsuUrl' => "people/images/{$id}/original.{$ext}", 'width' => null, + 'height' => null, ], ]; if ( ! array_key_exists($type, $typeMap)) { - $this->notFound(); + $this->getPlaceholder($baseSavePath, 100, 100); return; } $kitsuUrl .= $typeMap[$type]['kitsuUrl']; $width = $typeMap[$type]['width']; + $height = $typeMap[$type]['height']; $promise = (new HummingbirdClient)->request($kitsuUrl); $response = wait($promise); + + if ($response->getStatus() !== 200) + { + if ($display) + { + $this->getPlaceholder("{$baseSavePath}/{$type}", $width, $height); + } + return; + } + $data = wait($response->getBody()); - // echo "Fetching {$kitsuUrl}\n"; - - $baseSavePath = $this->config->get('img_cache_path'); $filePrefix = "{$baseSavePath}/{$type}/{$id}"; [$origWidth] = getimagesizefromstring($data); @@ -371,4 +387,19 @@ final class Index extends BaseController { return $output; } + + private function getPlaceholder (string $path, ?int $width = 200, ?int $height = NULL): void + { + $height = $height ?? $width; + + $filename = $path . '/placeholder.png'; + + if ( ! file_exists($path . '/placeholder.png')) + { + createPlaceholderImage($path, $width, $height); + } + + header('Content-Type: image/png'); + echo file_get_contents($filename); + } } \ No newline at end of file diff --git a/src/Controller/People.php b/src/Controller/People.php index c20b5169..0b36b957 100644 --- a/src/Controller/People.php +++ b/src/Controller/People.php @@ -62,11 +62,12 @@ final class People extends BaseController { if (array_key_exists('included', $data) && array_key_exists('castings', $data['included'])) { + $viewData['included'] = $data['included']; $viewData['castings'] = $this->organizeCast($data['included']['castings']); $viewData['castCount'] = count($viewData['castings']); } - $this->outputHTML('person', $viewData); + $this->outputHTML('person/index', $viewData); } protected function organizeCast(array $cast): array @@ -82,6 +83,52 @@ final class People extends BaseController { $roleName = $role['attributes']['role']; $media = $role['relationships']['media']; + $chars = $role['relationships']['character']['characters'] ?? []; + + if ( ! array_key_exists($roleName, $output)) + { + $output[$roleName] = [ + 'characters' => [], + ]; + } + + if ( ! empty($chars)) + { + $relatedMedia = []; + + if (array_key_exists('anime', $media)) + { + foreach($media['anime'] as $sid => $series) + { + $relatedMedia[$sid] = $series['attributes']; + } + } + + foreach($chars as $cid => $character) + { + // To make sure all the media are properly associated, + // merge the found media for this iteration with + // existing media, making sure to preserve array keys + $existingMedia = array_key_exists($cid, $output[$roleName]['characters']) + ? $output[$roleName]['characters'][$cid]['media'] + : []; + + $includedMedia = array_replace_recursive($existingMedia, $relatedMedia); + + uasort($includedMedia, function ($a, $b) { + return $a['canonicalTitle'] <=> $b['canonicalTitle']; + }); + + $output[$roleName]['characters'][$cid] = [ + 'character' => $character['attributes'], + 'media' => $includedMedia, + ]; + } + + uasort($output[$roleName]['characters'], function ($a, $b) { + return $a['character']['canonicalName'] <=> $b['character']['canonicalName']; + }); + } if (array_key_exists('anime', $media)) { @@ -99,7 +146,7 @@ final class People extends BaseController { { $output[$roleName]['manga'][$sid] = $series; } - uasort($output[$roleName]['anime'], function ($a, $b) { + uasort($output[$roleName]['manga'], function ($a, $b) { return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle']; }); }