Updates Pages & API

This commit is contained in:
CodeKyana 2024-08-01 00:00:12 +02:00
parent 2c7b28d6a1
commit 62832e8deb
22 changed files with 552 additions and 23 deletions

16
package-lock.json generated
View File

@ -11,6 +11,7 @@
"@popperjs/core": "^2.11.8",
"flowbite": "^2.4.1",
"flowbite-svelte": "^0.46.15",
"svelte-device-info": "^1.0.5",
"tailwind-merge": "^2.4.0"
},
"devDependencies": {
@ -3890,6 +3891,15 @@
"svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0"
}
},
"node_modules/svelte-device-info": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/svelte-device-info/-/svelte-device-info-1.0.5.tgz",
"integrity": "sha512-ImYE588bWDufOQChS8xfb6bVstkJHPuDk8tDtwYgkYU55WvfSzKTzkpblZkizWRpUNvnrakgsx24yHr6O3rY1g==",
"license": "MIT",
"dependencies": {
"tslib": "^2.6.2"
}
},
"node_modules/svelte-eslint-parser": {
"version": "0.41.0",
"resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.41.0.tgz",
@ -4314,6 +4324,12 @@
"dev": true,
"license": "Apache-2.0"
},
"node_modules/tslib": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
"license": "0BSD"
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",

View File

@ -4,6 +4,7 @@
"private": true,
"scripts": {
"dev": "vite dev",
"dev:expose": "vite dev --host",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
@ -36,6 +37,7 @@
"@popperjs/core": "^2.11.8",
"flowbite": "^2.4.1",
"flowbite-svelte": "^0.46.15",
"svelte-device-info": "^1.0.5",
"tailwind-merge": "^2.4.0"
}
}

View File

@ -1,5 +1,5 @@
<!doctype html>
<html lang="fr">
<html lang="fr" prefix="og: https://ogp.me/ns#">
<head>
<meta charset="utf-8" />
<link
@ -26,8 +26,8 @@
color="#da532c"
/>
<link rel="shortcut icon" href="%sveltekit.assets%/assets/images/favicons/favicon.ico" />
<meta name="apple-mobile-web-app-title" content="Ninjin: DB" />
<meta name="application-name" content="Ninjin: DB" />
<meta name="apple-mobile-web-app-title" content="Dragon Ball Ninjin" />
<meta name="application-name" content="Dragon Ball Ninjin" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta
name="msapplication-TileImage"

View File

@ -17,7 +17,7 @@
},
{
name: 'Télécharger le Launcher',
url: '/api/redirect?to=launcher-download',
url: '/api/redirect?to=download/launcher',
icon: logoNinjin
}
];

View File

@ -1,6 +1,5 @@
<script>
// @ts-nocheck
import { page } from '$app/stores';
import {
Button,
@ -37,7 +36,7 @@
</script>
<header>
<nav class="bg-[#191e14] shadow">
<nav class="bg-opacity-50 bg-[#191e14] shadow">
<div class="container flex items-center justify-center p-3.5 mx-auto capitalize">
<div class="large-screen hidden md:block">
{#each links as link}

View File

@ -0,0 +1,69 @@
<script>
import { page } from '$app/stores';
let url = `${$page.url.protocol}//${$page.url.hostname}${$page.url.pathname == '/' ? '' : $page.url.pathname}`;
/**
* @type {string}
* @default undefined
* @required
*/
export let title;
/**
* @type {string}
* @default undefined
* @required
*/
export let description;
/**
* @type {any}
* @default null
* @optional
*/
export let image = `/api/og-images?title=${title.replaceAll(' ', '+')}&path=${$page.url.hostname}${$page.url.pathname == '/' ? '/' : $page.url.pathname}`;
/**
* @type {any}
* @default null
* @optional
*/
export let imageAlt = 'API OG Images';
/**
* @type {any}
* @default null
* @optional
*/
export let twitterCard = null;
</script>
<svelte:head>
<title>{`${title} - Dragon Ball Ninjin`}</title>
<meta name="title" content={`${title} - Dragon Ball Ninjin`} />
<meta property="og:title" content={`${title} - Dragon Ball Ninjin`} />
<meta property="twitter:title" content={`${title} - Dragon Ball Ninjin`} />
<meta name="description" content={description} />
<meta property="og:description" content={description} />
<meta property="twitter:description" content={description} />
<meta
name="author"
content={`Web V2: AnotherFrench.vercel.app (@AnotherFrench) / Server: Hedaox (@Hedaox) & Xamora`}
/>
<meta property="og:site_name" content="Dragon Ball Ninjin" />
{#if image}
<meta property="og:image" content={image} />
<meta property="twitter:image" content={image} />
{/if}
{#if imageAlt}
<meta property="og:image:alt" content={imageAlt} />
<meta property="twitter:image:alt" content={imageAlt} />
{/if}
{#if twitterCard}
<meta property="twitter:card" content={twitterCard} />
{:else}
<meta property="twitter:card" content="summary_large_image" />
{/if}
<meta property="og:url" content={url} />
<meta property="twitter:url" content={url} />
</svelte:head>

View File

@ -0,0 +1,44 @@
<script>
export let url,
video_or_image,
link_global = false,
name = 'default name',
title = 'default title',
target = '_blank';
const _class = {
image:
'w-full max-w-3xl h-auto max-w-2xl rounded-md bg-gradient-to-r from-red-500 via-orange-500 to-yellow-500 p-1',
video:
'w-full aspect-video max-w-2xl h-auto rounded-md bg-gradient-to-r from-red-500 via-orange-500 to-yellow-500 p-1'
};
</script>
{#if video_or_image == 'image'}
<div class="flex justify-center mt-6">
{#if link_global}
<a href={url} {target} rel="noopener noreferrer" {title}>
<img src={url} alt={name} draggable="false" class={_class['image']} />
</a>
{:else}
<img src={url} alt={name} draggable="false" class={_class['image']} />
{/if}
</div>
{:else if video_or_image == 'video'}
<div class="mt-5 flex items-center justify-center">
<iframe
class={_class['video']}
width="560"
height="315"
src={`https://www.youtube-nocookie.com/embed/${url}`}
{title}
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
>
<p class="text-center text-lg z-0">Your browser does not support the video tag.</p>
</iframe>
</div>
{:else}
<!-- ??? Je fou quoi ici moi... -->
{/if}

View File

@ -0,0 +1,27 @@
<script>
export let name,
channel_id = '#',
guild_id = '#';
const _class = {
span: 'inline-flex items-center bg-gray-700 text-white px-2 py-1 rounded-md font-semibold',
text_span: 'text-blue-400'
};
</script>
{#if channel_id == '#' || guild_id == '#'}
<span class={_class['span']}>
<span class={_class['text_span']}>#</span>{name}
</span>
{:else}
<a
href={`/api/redirect?to=discord&guild_id=${guild_id}&channel_id=${channel_id}`}
title={`Voir le canal ${name} sur Discord`}
target="_blank"
rel="noopener"
>
<span class={_class['span']}>
<span class={_class['text_span']}>#</span>{name}
</span>
</a>
{/if}

View File

@ -0,0 +1,6 @@
<script>
export let title, description;
</script>
<p class="mt-5 font-bold">{title}</p>
<p class="mb-5">{@html description}</p>

View File

@ -2,8 +2,8 @@
/** @type {import('./$types').PageData} */
export let data;
import '$lib/assets/css/tailwind.css';
import Header from '../components/Header.svelte';
import Footer from '../components/Footer.svelte';
import Header from '$lib/components/Layouts/Header.svelte';
import Footer from '$lib/components/Layouts/Footer.svelte';
import logoHeader from '$lib/assets/images/logo_header.png';
import logoHeaderRevert from '$lib/assets/images/logo_header_revert.png';
@ -13,8 +13,8 @@
}
</script>
<div class="container mx-auto px-4">
<Header />
<div class="container max-w-6xl mx-auto px-4">
<main class="text-center mt-4 relative z-20">
<img src={logo} alt="Ninjin Logo" class="w-full max-w-2xl mx-auto" draggable="false" />

View File

@ -1,2 +1,53 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
<script context="module">
import Device from 'svelte-device-info';
</script>
<script>
import { onMount } from 'svelte';
import BigVideoOrImage from '$lib/components/Pages/BigVideoOrImage.svelte';
onMount(() => {
let isPC;
switch (true) {
case Device.isMobile:
isPC = false;
break;
case Device.isPhone:
isPC = false;
break;
case Device.isTablet:
isPC = false;
break;
default:
isPC = true;
break;
}
if (isPC) {
document.body.style.overflow = 'hidden';
console.log('Running on a PC device, overflow is disabled');
} else {
document.body.style.overflow = 'auto';
console.log('Running on a mobile device, overflow is auto');
}
});
var spanCss =
'text-transparent bg-clip-text bg-gradient-to-r from-red-500 via-orange-500 to-yellow-500';
var smallCss = 'ms-2 font-semibold';
</script>
<h1 class="text-5xl font-extrabold mb-5">
<span class={spanCss}>Dragon Ball Ninjin</span><small class={smallCss}>est un serveur DB</small>
</h1>
<p class="text-center text-lg mt-4">
Il s'agit d'un projet de <b>serveur Minecraft survival et semi-RP Francophone</b>, le but étant de
se rapprocher le plus <b>fidèlement</b> possible de l'ambiance de l'<b>univers de Dragon Ball</b> décrit
dans le manga et anime éponyme.
</p>
<BigVideoOrImage
url="mtTeNcnHUBE"
video_or_image="video"
title="Dragon Ball Ninjin: Trailer (Video Player by YouTube)"
/>

View File

@ -3,7 +3,7 @@ export function load({ cookies }) {
if (!revertNinjinLogo || revertNinjinLogo === 'false') {
cookies.set('ninjin_af#eg@api/activate-revert-logo', 'true', {
path: '/api/activate-revert-logo',
path: '/',
httpOnly: true,
sameSite: 'strict',
maxAge: 60 * 60 * 24 * 30

View File

@ -0,0 +1,14 @@
import { redirect } from '@sveltejs/kit';
/** @type {import('./$types').PageLoad} */
export function load({ url }) {
let title = url.searchParams.get('title') || 'Undefined';
let pathName = url.searchParams.get('path') || '/';
var ogImage = 'https://dynamic-og-image-generator.vercel.app/api/generate';
var avatar = 'https://ninjin.eu.org/assets/images/ninjin_avatar.png';
redirect(
302,
`${ogImage}?title=${title}&author=Dragon+Ball+Ninjin&avatar=${avatar}&websiteUrl=${pathName}&theme=Default`
);
}

View File

@ -4,10 +4,21 @@ import { redirect } from '@sveltejs/kit';
export function load({ params, url }) {
let goTo = url.searchParams.get('to');
let repository = url.searchParams.get('repo');
let channelId = url.searchParams.get('channel_id');
let guildId = url.searchParams.get('guild_id');
switch (goTo) {
case 'discord':
if (!guildId || !channelId || (!guildId && !channelId)) {
redirect(302, `https://discord.gg/JcbAENk`);
}
switch (guildId && channelId) {
case guildId && channelId:
redirect(302, `https://discord.com/channels/${guildId}/${channelId}`);
default:
redirect(302, `https://discord.gg/JcbAENk`);
}
case 'youtube':
redirect(302, `https://www.youtube.com/channel/UCRQcMWRLBLC-jj1XvyCv7yA`);
case 'github-dev':
@ -19,7 +30,12 @@ export function load({ params, url }) {
default:
redirect(302, `https://github.com/NinjinMC`);
}
case 'launcher-download':
case 'download/java':
redirect(
302,
`https://javadl.oracle.com/webapps/download/AutoDL?BundleId=238729_478a62b7d4e34b78b671c754eaaf38ab`
);
case 'download/launcher':
redirect(
302,
`https://github.com/NinjinMC/Ninjin/raw/master/download/NinjinLauncherBootstrap.jar`

View File

@ -0,0 +1,200 @@
<script>
import { Tooltip } from 'flowbite-svelte';
import FeaturesText from '$lib/components/Pages/FeaturesText.svelte';
const mods = [
{
id: 0,
name: 'Dragon Block C',
description:
'Un super mod très complet de Dragon Ball créé par Jinryuu, maintenant décédé, qui a été repris par son frère Benjamìn.',
link: 'https://main.jingames.net/minecraft-mods/dragon-block-c/',
valid: true
},
{
id: 1,
name: 'JyearsC',
description:
'Un mod qui permet au joueur de vieillir, ainsi que de pouvoir jouer un enfant. Aussi créé par JinRyuu.',
link: 'https://main.jingames.net/jinryuus-years-c/',
valid: true
},
{
id: 2,
name: 'Custom NPC',
description:
'Un mod qui permet de créer des PNJs avec aussi un système de quêtes et un système de script. Créé par Noppes.',
link: 'https://www.kodevelopment.nl/minecraft/customnpcs',
valid: true
},
{
id: 3,
name: 'Dragon Block V',
description:
'Malheureusement non... Même si plus complet que Dragon Block C, il est en développement depuis +4 ans...',
link: 'https://dragonblockv.wiki.gg/wiki/Dragon_Block_V_Wiki',
valid: false
},
{
id: 4,
name: 'Hytale',
description:
"Malheureusement non... Même si c'est potentiellement un Minecraft 2.0 ou en mieux, cela fait +5 ans qu'on l'attend aussi...",
link: 'https://hytale.com/',
valid: false
}
];
</script>
<h1 class="text-5xl font-extrabold mb-5">
<small class="ms-2 font-semibold">Les</small> Features<small class="ms-2 font-semibold"
>de DB Ninjin ?</small
>
</h1>
<p class="text-lg mt-4">
Pour fonctionner le serveur utilise des mods basés sur Forge, <br /> un framework permettant de créer
et d'utiliser des mods sur Minecraft.
</p>
<h2 class="mb-2 mt-5 text-xl font-semibold">Parmis ces mods nous utilisons</h2>
<div class="flex justify-center">
<ul class="max-w-md space-y-1 list-inside">
{#each mods as mod}
<li class="flex items-center">
{#if mod.valid === true}
<svg
class="w-3.5 h-3.5 me-2 text-green-500 dark:text-green-400 flex-shrink-0"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 8.207-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L9 10.586l3.293-3.293a1 1 0 0 1 1.414 1.414Z"
/>
</svg>
{:else if mod.valid === false}
<svg
class="w-3.5 h-3.5 me-2 text-gray-500 dark:text-gray-400 flex-shrink-0"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 8.207-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L9 10.586l3.293-3.293a1 1 0 0 1 1.414 1.414Z"
/>
</svg>
{/if}
<a
href={mod.link}
title={`Voir plus sur ${mod.name}`}
id={`tooltip-mod-${mod.id}`}
rel="noopener"
target="_blank"
>
{mod.name}
</a>
<Tooltip type="dark" triggeredBy={`#tooltip-mod-${mod.id}`} placement="right">
{mod.description}
</Tooltip>
</li>
{/each}
</ul>
</div>
<h2 class="mb-2 mt-5 text-xl font-semibold">
Les fonctionnalitées du serveur en plus de ceux de Dragon Block C
</h2>
<FeaturesText
title="La Map"
description="Une map essayant de respecter l'univers du manga, voire section <a href='/map' title='Voir la map' rel='noopener' target='_self'>map</a>. <br />
Si vous essayez de sortir de la map, le jeu vous téléportera de l'autre côté de la map, comme s'il s'agissait d'une planète !"
/>
<FeaturesText
title="Chat Vocal"
description="Fonctionnant avec le mod GlibysVC permet de discuter vocalement avec les joueurs proches."
/>
<FeaturesText
title="Saga améliorée"
description="Puissance des pnj a été modifié pour être <i>(subjectivement)</i> fidèle au manga. <br />
Certaines parties de la saga ont aussi été améliorées avec de nouveaux PNJs. <br />
De plus leur IA utilsent le même système que DBC de base <i>(pouvoir voler et envoyer des Kikohas.)</i>"
/>
<FeaturesText
title="Saga étendue"
description="De Goku Enfant à Broly Super, la saga a été étendue pour pouvoir parcourir tout l'univers de Dragon Ball ! <br />
De plus vous ne combatterez pas uniquement les méchants, mais vous pourrez aussi vous entraîner avec les gentils !"
/>
<FeaturesText
title="Saga secondaire"
description="Saga secondaire contient tout les ennemis des film DBZ !"
/>
<FeaturesText
title="Knockback améliorée"
description="Proportionellement à votre puissance, vous enverrez baladez les flaibards, <br />
mais vous ne pourrez même pas égratigner quelqu'un de bien plus fort que vous."
/>
<FeaturesText
title="BloodBath"
description="Quand vous serez blessé, des plaies ouvertes apparaîtront sur votre corps, à partir de ses plaies du sang commencera à couler. <br />
Vous soigner enlèvera les plaies, mais le sang restera tant que vous n'aurez pas pris un bain."
/>
<FeaturesText
title="Musique"
description="Des musiques personalisées venant des jeux, anime ou films, changeant en fonction de l'environement."
/>
<FeaturesText
title="Economie"
description="Rajout d'une monnaie dans le jeu: le Zeni ainsi que des marchands afin d'acheter vêtements, armes, équipement etc..."
/>
<FeaturesText
title="Système de quêtes dynamiques"
description="Ajout d'un système de géolocalisation activable en appuyant sur <b>P</b> <i>(touche par défaut)</i>. <br />
Ce système permet aux joueurs de proposer des quêtes ou d'appeler à l'aide, en pouvant donner leur position et pourquoi pas une récompense."
/>
<FeaturesText
title="Amélioration de l'entraînement"
description="Les poids, la gravité, la salle du temps tout cela vous permettra de vous entraîner de façon bien plus efficace qu'avant ! <br />
De plus s'entraîner avec des joueurs fort vous entraînera encore plus vite ! <br />
Par contre si vous vous entrainez toujours avec le même mob/joueur votre entraînement sera moins efficace, grâce à un nouveau système d'habitude !"
/>
<FeaturesText
title="Meilleure Namekien et Humain"
description="Les namekien ont la possibilité de fusionner avec Kami et Nail durant l'histoire les rendant bien plus fort, les humains ont la possibilité de devenir Cyborg !"
/>
<h2 class="mb-2 mt-5 text-xl font-semibold">
Les fonctionalités qui seront constamment travailées
</h2>
<FeaturesText
title="Amélioration de la saga"
description="De nouveaux ennemies pour la saga (Canon et non Canon). <br />
Différentes branches de l'histoire qu'on pourrait prendre..."
/>
<FeaturesText
title="Nouveaux PNJs, batiments, skills"
description="Pourquoi pas dans le futur rajouter de nouveau PNJs et batiments afin de rendre l'univers plus
intéressant."
/>
<FeaturesText
title="Réalisme"
description="Eau réaliste, inventaire réaliste, arbres réalistes etc... <br />
Tout pour améliorer l'immersion."
/>

View File

@ -0,0 +1,53 @@
<script>
import MetaData from '$lib/components/Layouts/MetaData.svelte';
import BigVideoOrImage from '$lib/components/Pages/BigVideoOrImage.svelte';
import DiscordChannel from '$lib/components/Pages/DiscordChannel.svelte';
</script>
<MetaData
title="Nous rejoindre"
description="Sur cette page, vous allez apprendre comment rejoindre le serveur DB Ninjin ainsi que de découvrir une vidéo explicative pour mieux vous aider."
/>
<h1 class="text-5xl font-extrabold mb-5">
<small class="ms-2 font-semibold">Comment</small> Rejoindre<small class="ms-2 font-semibold"
>D.B. Ninjin ?</small
>
</h1>
<p class="text-center text-lg mt-4">
Pour nous rejoindre vous devez d'abord rejoindre le Discord afin d'être whitelist en allant sur le
channel <DiscordChannel
name="👤│demande-whitelist"
guild_id="452572573532684309"
channel_id="615641331494289409"
/> mais avant veuillez lire les <DiscordChannel
name="👤│instructions-whitelist"
guild_id="452572573532684309"
channel_id="696852947837124758"
/>.
</p>
<BigVideoOrImage
url="tTDmJj8PLJE"
video_or_image="video"
name="Comment rejoindre le serveur D.B. Ninjin ? (Video Player by YouTube)"
/>
<p class="text-center text-lg mt-4">
En cas de crash, vérifiez que vous avez bien <a
href="/api/redirect?to=download/java"
title="Télécharger Java en 64 bit."
rel="noopener"
target="_self"><b>Java 64 bit</b></a
>, en cas de problème persistant veuillez regarder la <DiscordChannel
name="❓│faq"
guild_id="452572573532684309"
channel_id="574926744767954954"
/> et les <DiscordChannel
name="📎│liens-utiles"
guild_id="452572573532684309"
channel_id="452795124452294661"
/>, si malgré tout les soucis persiste, n'hésitez pas à en parler avec les membres du Discord/du
Staff peut-être que nous pourrons vous aider.
</p>

View File

@ -1,13 +1,21 @@
<script>
import map from '$lib/assets/images/ninjin_map.png';
import BigVideoOrImage from '$lib/components/Pages/BigVideoOrImage.svelte';
</script>
<h2 class="text-center text-4xl">Map</h2>
<h1 class="text-5xl font-extrabold mb-5">
Map<small class="ms-2 font-semibold">de DB Ninjin</small>
</h1>
<p class="text-center text-lg mt-4">
Voici la map du serveur, les dimensions sont 10000x8000 blocks.
</p>
<div class="flex justify-center mt-6">
<a href={map} target="_blank" rel="noopener noreferrer" title="Voir la map en plein écran">
<img src={map} alt="map" draggable="false" class="w-full max-w-3xl h-auto rounded-lg" />
</a>
</div>
<BigVideoOrImage
url={map}
video_or_image="image"
link_global={true}
name="map"
title="Voir la map en plus grande"
target="_blank"
/>

View File

@ -0,0 +1,24 @@
<script>
import DiscordChannel from '$lib/components/Pages/DiscordChannel.svelte';
</script>
<h1 class="text-5xl font-extrabold mb-5">
<small class="ms-2 font-semibold">Les</small> Règles<small class="ms-2 font-semibold"
>de DB Ninjin</small
>
</h1>
<p class="text-lg mt-4">
Pour éviter de vous montrer des règles incomplètes ou pas à jour sur le site internet, <br />
nous vous conseillons de regarder les <DiscordChannel
guild_id="452572573532684309"
channel_id="474160253509042177"
name="📃│règles"
/> sur le serveur Discord.
</p>
<p class="text-lg mt-4">
Néanmoins, veuillez dès maintenant retenir quelques bases, le respect est primordial, <br />
les publicités ainsi que les spams sont strictement interdits, tout comme le cheat, griefing, le non
fair-play.
</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

View File

@ -1,6 +1,6 @@
{
"name": "Ninjin: DB",
"short_name": "Ninjin: DB",
"name": "Dragon Ball Ninjin",
"short_name": "DB Ninjin",
"icons": [
{
"src": "/assets/images/favicons/android-chrome-36x36.png",