first commit

This commit is contained in:
Polaris 2023-12-08 13:25:54 -05:00
commit 7d6ab2c50c
52 changed files with 15545 additions and 0 deletions

4
.eslintrc.json Normal file
View File

@ -0,0 +1,4 @@
{
"extends": "next/core-web-vitals",
"rules": { "react/no-unescaped-entities": 0 }
}

39
.gitignore vendored Normal file
View File

@ -0,0 +1,39 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
/.vscode/
# testing
/coverage
/public
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
.env
.vercel

83
README.md Normal file
View File

@ -0,0 +1,83 @@
[Artemis API](https://github.com/PolarisPyra/ArtemisApi): Needed for Cozynet
# Welcome to CozyNet!
Cozy net is a self maintainable web ui for the [Artemis server](https://gitea.tendokyu.moe/Hay1tsme/artemis)
# How configure assets
- Run the following python files in your favorite terminal emulator! They are located inside of `CozyNet\pythonscripts` as follows
prerequisites
- python 3.12
- tqdm
> $ > `python imagegrabber.py "C:\Users\polaris\Documents\Chunithm SUN (SDHD 2.10.01)\App\data" "C:\Users\<name>\Documents\Chunithm SUN (SDHD 2.10.01)\App\bin\option" "C:\Users\<name>\Desktop\output""
` this process might take awhile.
prerequisites
- python 3.12
- tqdm
- pillow
> $ > `python datagrabber.py "C:\Users\polaris\Documents\Chunithm SUN (SDHD 2.10.01)" "C:\Users\<name>\Desktop\output"
` this process will be a lot faster!
- Move the files from output\public into `CozyNet\public` unfortunately you will need to download the systemvoice audio files unless you know how to grab them yourself. You can do that [here](https://pixeldrain.com/u/NQcs2Pfr)
-
- Move the files from \data into CozyNet\src\lib these include the `accessory, mapicon, nameplate, systemvoice, and trophy` typescript files!
# How configure and start the api
How to start the artemisApi:
git clone artemiApi
> $ cd artemisApi
> $ npm install
```
npm run start:dev
npm run start:prod
```
in .env.development or env.production
```
host=aime
user=aime
password=dbpassword
database=aime
port=3306
JWT_SECRET=mystrongsecret
```
# How configure and start the webui
prerequisites
- Lastest version of node
- nextjs `npm install -g next`
Cozy net also uses .env for configuration
``
`NEXT_PUBLIC_ARTEMIS_API_URL=http://localhost:4000`
`NEXT_PUBLIC_CDN=/`
NEXT_PUBLIC_CDN=cdn link or local image path
place these variables inside a .env file in the root directory before starting!
git clone CozyNet
> $ cd CozyNet
> $ npm install
> $ npm run dev
it should now be started at localhost:3000

16
components.json Normal file
View File

@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "zinc",
"cssVariables": false
},
"aliases": {
"utils": "@/lib/utils",
"components": "@/components"
}
}

28
next.config.js Normal file
View File

@ -0,0 +1,28 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
module.exports = nextConfig;
module.exports = {
eslint: {
// Warning: This allows production builds to successfully complete even if
// your project has ESLint errors.
ignoreDuringBuilds: true,
reactStrictMode: true,
},
};
module.exports = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "**",
},
],
},
};
module.exports = {
images: {
unoptimized: true,
},
};

5148
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

51
package.json Normal file
View File

@ -0,0 +1,51 @@
{
"name": "artemisfrontend",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@boiseitguru/cookie-cutter": "^0.2.1",
"@radix-ui/react-icons": "^1.3.0",
"@types/bcrypt": "^5.0.2",
"@types/cookie": "^0.5.4",
"@types/js-cookie": "^3.0.5",
"@types/jsonwebtoken": "^9.0.5",
"@vercel/analytics": "^1.1.1",
"axios": "^1.6.0",
"bcrypt": "^5.1.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"cookie": "^0.5.0",
"js-cookie": "^3.0.5",
"jsonwebtoken": "^9.0.2",
"lucide-react": "^0.292.0",
"mysql2": "^3.6.3",
"next": "14.0.1",
"next-client-cookies": "^1.0.6",
"pnpm": "^8.11.0",
"react": "^18",
"react-dom": "^18",
"react-icons": "^4.12.0",
"react-toastify": "^9.1.3",
"sdds": "^0.0.2",
"tailwind-merge": "^2.1.0",
"tailwindcss-animate": "^1.0.7",
"uuidv4": "^6.2.13"
},
"devDependencies": {
"@types/node": "20.9.3",
"@types/react": "18.2.38",
"@types/react-dom": "^18",
"autoprefixer": "^10.4.16",
"eslint": "^8",
"eslint-config-next": "14.0.1",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"typescript": "5.3.2"
}
}

6
postcss.config.js Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

View File

@ -0,0 +1,150 @@
import os
import xml.etree.ElementTree as ET
from pathlib import Path
from tqdm import tqdm
import argparse
def parse_xml(file_path):
tree = ET.parse(file_path)
return tree.getroot()
def find_data(xml_path, data_type):
root = parse_xml(xml_path)
id_element = root.find('.//name/id')
str_element = root.find('.//name/str')
data = {}
if data_type == "accessory":
image_path_element = root.find('.//image/path')
category_element = root.find('.//category')
sort_name_element = root.find('.//sortName')
net_open_name_element = root.find('.//netOpenName/str')
if id_element is not None and str_element is not None:
data['id'] = id_element.text
data['str'] = str_element.text
data['imagePath'] = image_path_element.text if image_path_element is not None else ""
data['sortName'] = sort_name_element.text if sort_name_element is not None else ""
data['category'] = category_element.text if category_element is not None else ""
data['netOpenName'] = net_open_name_element.text if net_open_name_element is not None else ""
elif data_type in ["nameplate", "systemvoice"]:
image_path_element = root.find('.//image/path')
sort_name_element = root.find('.//sortName')
if id_element is not None and str_element is not None:
data['id'] = id_element.text
data['str'] = str_element.text
data['imagePath'] = image_path_element.text if image_path_element is not None else ""
data['sortName'] = sort_name_element.text if sort_name_element is not None else ""
elif data_type == "trophy":
rare_type_element = root.find('.//rareType')
net_open_name_element = root.find('.//netOpenName/str')
if id_element is not None and str_element is not None:
data['id'] = id_element.text
data['str'] = str_element.text
data['rareType'] = rare_type_element.text if rare_type_element is not None else ""
data['netOpenName'] = net_open_name_element.text if net_open_name_element is not None else ""
elif data_type == "mapicon":
image_path_element = root.find('.//image/path')
sort_name_element = root.find('.//sortName')
if id_element is not None and str_element is not None:
data['id'] = id_element.text
data['str'] = str_element.text
data['imagePath'] = image_path_element.text if image_path_element is not None else ""
data['sortName'] = sort_name_element.text if sort_name_element is not None else ""
return data
def find_xml_files(directory, xml_file_name):
"""
Recursively searches for XML files matching the specified name within the given directory.
"""
for dirpath, dirnames, filenames in os.walk(directory):
for filename in filenames:
if filename == xml_file_name:
yield Path(dirpath) / filename
def write_to_file(data, output_file, data_type):
output_dir = os.path.dirname(output_file)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
with open(output_file, 'w', encoding='utf-8') as file:
file.write(f'export const {data_type} = [\n')
for item in data:
item_str = ', '.join([f'{k}: `{v}`' for k, v in item.items()])
file.write(f' {{ {item_str} }},\n')
file.write(']\n')
def process_directories(base_path, output_directory, data_types, xml_file_names):
for data_type, xml_file_name in zip(data_types, xml_file_names):
base_directories = construct_paths(base_path, data_type)
matched_data = []
# Initialize tqdm progress bar
progress_bar = tqdm(total=sum(1 for _ in find_xml_files(base_path, xml_file_name)),
desc=f'Processing {data_type}', unit='file')
for directory in base_directories:
for xml_path in find_xml_files(directory, xml_file_name):
data = find_data(xml_path, data_type)
if data:
matched_data.append(data)
progress_bar.update(1)
progress_bar.close()
if matched_data:
output_file = Path(output_directory) / f'{data_type}.ts'
write_to_file(matched_data, output_file, data_type)
else:
print(f"No data to write for {data_type}")
def construct_paths(base_path, data_type):
subdirectories = {
'accessory': ['App/data/A000/avatarAccessory', 'App/bin/option'],
'nameplate': ['App/data/A000/namePlate', 'App/bin/option'],
'systemvoice': ['App/data/A000/systemVoice', 'App/bin/option'],
'trophy': ['App/data/A000/trophy', 'App/bin/option'],
'mapicon': ['App/data/A000/mapIcon', 'App/bin/option']
}
return [Path(base_path) / sub for sub in subdirectories[data_type]]
def main():
parser = argparse.ArgumentParser(
description='Process XML files and write data to TypeScript files.')
parser.add_argument('base_path', type=str,
help='Base path to the Chunithm data directory')
parser.add_argument('output_directory', type=str,
help='Output directory for TypeScript files')
args = parser.parse_args()
base_path = args.base_path
output_directory = args.output_directory
data_types = ['accessory', 'nameplate', 'systemvoice', 'trophy', 'mapicon']
xml_file_names = ['AvatarAccessory.xml',
'NamePlate.xml', 'SystemVoice.xml', 'Trophy.xml', 'MapIcon.xml']
process_directories(base_path, output_directory,
data_types, xml_file_names)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,160 @@
import os
import re
from pathlib import Path
from PIL import Image
from tqdm import tqdm
import argparse
def find_dds_files(source_folders, file_pattern=None):
dds_files = []
for source_folder in source_folders:
for root, _, files in os.walk(source_folder):
for file in files:
if file.endswith('.dds') and (file_pattern is None or file_pattern.match(file)):
dds_files.append(os.path.join(root, file))
return dds_files
def convert_dds_to_png(dds_file_path, png_file_path, scale_percent=50):
with Image.open(dds_file_path) as img:
new_width = int(img.width * scale_percent / 100)
new_height = int(img.height * scale_percent / 100)
img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
img.save(png_file_path, 'PNG')
def process_files(files, destination_folder, progress_prefix, scale_percent=100):
files_to_convert = []
for file_path in files:
file_name = os.path.splitext(os.path.basename(file_path))[0] + '.png'
png_file_path = os.path.join(destination_folder, file_name)
if not os.path.exists(png_file_path):
files_to_convert.append(file_path)
if not files_to_convert:
print(f"{progress_prefix}: Already converted!")
return
for file_path in tqdm(files_to_convert, desc=progress_prefix, unit='file'):
file_name = os.path.splitext(os.path.basename(file_path))[0] + '.png'
png_file_path = os.path.join(destination_folder, file_name)
convert_dds_to_png(file_path, png_file_path, scale_percent)
def process_avatarAccessory(source_folders, destination_folder, progress_prefix):
avatar_accessory_files = find_dds_files(source_folders)
if not os.path.exists(destination_folder):
os.makedirs(destination_folder)
process_files(avatar_accessory_files, destination_folder,
progress_prefix, scale_percent=50)
def process_nameplates(source_folders, destination_folder, progress_prefix):
nameplate_files = find_dds_files(source_folders)
if not os.path.exists(destination_folder):
os.makedirs(destination_folder)
process_files(nameplate_files, destination_folder, progress_prefix)
def process_systemVoiceImages(source_folders, destination_folder, progress_prefix):
nameplate_files = find_dds_files(source_folders)
if not os.path.exists(destination_folder):
os.makedirs(destination_folder)
process_files(nameplate_files, destination_folder, progress_prefix)
def process_JacketArt(source_folders, destination_folder, progress_prefix):
nameplate_files = find_dds_files(source_folders)
if not os.path.exists(destination_folder):
os.makedirs(destination_folder)
process_files(nameplate_files, destination_folder, progress_prefix)
def process_mapIcon(source_folders, destination_folder, progress_prefix):
nameplate_files = find_dds_files(source_folders)
if not os.path.exists(destination_folder):
os.makedirs(destination_folder)
process_files(nameplate_files, destination_folder, progress_prefix)
def process_partners(source_folders, destination_chunithm, destination_chusan):
pattern_chunithm = re.compile(
r'CHU_UI_Character_0([0-9]{3})_(00|01)_[0-9]{2}\.dds$')
pattern_chusan = re.compile(
r'CHU_UI_Character_([1-9]\d{3,})_(00|01)_[0-9]{2}\.dds$')
chunithm_files = find_dds_files(source_folders, pattern_chunithm)
chusan_files = find_dds_files(source_folders, pattern_chusan)
if not os.path.exists(destination_chunithm):
os.makedirs(destination_chunithm)
process_files(chunithm_files, destination_chunithm,
"Chunithm Partners")
if not os.path.exists(destination_chusan):
os.makedirs(destination_chusan)
process_files(chusan_files, destination_chusan,
"Chusan Partners")
def find_subdirectories(base_directories, subdirectory_names):
subdirectory_paths = {name: [] for name in subdirectory_names}
for base_directory in base_directories:
for subdir in Path(base_directory).rglob('*'):
if subdir.is_dir() and subdir.name in subdirectory_names:
subdirectory_paths[subdir.name].append(str(subdir))
return subdirectory_paths
def main(data_folder, option_folder, output_folder):
relevant_subdirs = ['music', 'avatarAccessory',
'mapIcon', 'namePlate', 'ddsImage', 'systemVoice']
subdirectories = find_subdirectories(
[data_folder, option_folder], relevant_subdirs)
output_path = os.path.join(
os.path.expanduser('~'), 'Desktop', output_folder)
if not os.path.exists(output_path):
os.makedirs(output_path)
process_partners(subdirectories['ddsImage'], os.path.join(
output_path, 'public', 'chunithm_partners'), os.path.join(output_path, 'public', 'chusan_partners'))
process_nameplates(subdirectories['namePlate'], os.path.join(
output_path, 'public', 'namePlates'), 'namePlate')
process_systemVoiceImages(subdirectories['systemVoice'], os.path.join(
output_path, 'public', 'systemVoiceThumbnails'), 'systemVoice thumbnail')
process_JacketArt(subdirectories['music'], os.path.join(
output_path, 'public', 'JacketArt'), 'jacket art')
process_mapIcon(subdirectories['mapIcon'], os.path.join(
output_path, 'public', 'mapIcon'), 'map icon')
process_avatarAccessory(subdirectories['avatarAccessory'], os.path.join(
output_path, 'public', 'avatarAccessory'), 'avatarAccessory Progress')
print("All conversions and transfers complete.")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='Converts Chunithm dds files to pngs for CozyNet webUI.')
parser.add_argument('data_folder', type=str, help='Path to data folder')
parser.add_argument('option_folder', type=str,
help='Path to option folder')
parser.add_argument('output_folder', type=str,
help='Path to the output folder')
args = parser.parse_args()
main(args.data_folder, args.option_folder, args.output_folder)

View File

@ -0,0 +1,48 @@
import { serialize } from "cookie";
import { COOKIE_NAME, MAX_EXPIRE_AGE } from "@/constants";
import axios from "axios";
export async function POST(request: Request) {
try {
const body = await request.json();
const { username, password } = body;
// Authenticate the user by verifying their credentials
const { data } = await axios.post(
`${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/verifyUser`,
{
username,
password,
}
);
// Use data.token directly without signing again
const token = data.token;
// Serialize cookies
const cookieOptions = {
httpOnly: false,
secure: true,
sameSite: "strict" as const, // as const assertion for string literal types
maxAge: MAX_EXPIRE_AGE,
path: "/",
};
const serializedToken = serialize(COOKIE_NAME, token, cookieOptions);
// Return a response with the token cookie set (excluding USER_ID_COOKIE)
return new Response("", {
status: 200,
headers: {
"Set-Cookie": serializedToken,
},
});
} catch (error) {
// Check if it's an AxiosError and extract the status code if available
if (axios.isAxiosError(error) && error.response) {
return new Response("", { status: error.response.status });
}
// For other types of errors, return a generic server error
return new Response("", { status: 500 });
}
}

View File

@ -0,0 +1,21 @@
import { serialize } from "cookie";
const removeCookie = (cookieName: string): string =>
serialize(cookieName, "", {
httpOnly: false,
secure: true,
sameSite: "strict",
maxAge: -1,
path: "/",
});
export async function POST(): Promise<Response> {
const serializedToken = removeCookie("LOGIN_INFO");
return new Response("", {
status: 200,
headers: {
"Set-Cookie": serializedToken,
},
});
}

View File

@ -0,0 +1,30 @@
// check if user is authenticated
import { COOKIE_NAME } from "@/constants";
import { cookies } from "next/headers";
export async function GET() {
const cookieStore = cookies();
const token = cookieStore.get(COOKIE_NAME);
if (!token) {
return new Response("", { status: 401 });
}
// Remove the token verification part
// const { value } = token;
// const secret = process.env.JWT_SECRET || "";
// try {
// verify(value, secret);
const response = {
user: "Authenticated",
};
return new Response(JSON.stringify(response), {
status: 200,
});
// } catch (e) {
// return new Response("", { status: 400 });
// }
}

View File

@ -0,0 +1,55 @@
import { serialize } from "cookie";
import { COOKIE_NAME, MAX_EXPIRE_AGE } from "@/constants";
import axios from "axios";
export async function POST(request: Request) {
const body = await request.json();
const { email, accessCode, username, password } = body;
try {
if (!accessCode) {
return new Response("", { status: 400 }); // 400 indicates Bad Request
}
// Attempt to register the user
const registrationResponse = await axios.post(
`${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/registerUser`,
{
email,
accessCode,
username,
password,
}
);
const userData = registrationResponse.data;
// Use accessCode directly without signing again
const token = userData.token;
// Serialize the token cookie
const serializedToken = serialize(COOKIE_NAME, token, {
httpOnly: false,
secure: true,
sameSite: "strict",
maxAge: MAX_EXPIRE_AGE,
path: "/",
});
// Do not serialize the access code cookie with userId
// Return a response with only the token cookie set
return new Response(JSON.stringify({ message: "Signup successful" }), {
status: 200,
headers: {
"Set-Cookie": serializedToken,
},
});
} catch (error) {
if (axios.isAxiosError(error) && error.response) {
return new Response("", { status: error.response.status });
}
return new Response("", { status: 500 });
}
}

View File

@ -0,0 +1,58 @@
"use client";
import axios from "axios";
import { useState, useEffect } from "react";
import { AxiosError } from "axios";
import { useRouter } from "next/navigation";
interface UserResponse {
user: string | null;
error: AxiosError | null;
}
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
const [isSuccess, setIsSuccess] = useState<boolean>(false);
const router = useRouter();
useEffect(() => {
(async () => {
const { user, error } = await getUser();
if (error) {
router.push("/");
return;
}
setIsSuccess(true);
})();
}, [router]);
if (!isSuccess) {
}
return (
<main>
{children}
</main>
);
async function getUser(): Promise<UserResponse> {
try {
const { data } = await axios.get("/api/auth/me");
return {
user: data,
error: null,
};
} catch (e) {
const error = e as AxiosError;
return {
user: null,
error: error,
};
}
}
}

22
src/app/chunithm/page.tsx Normal file
View File

@ -0,0 +1,22 @@
import CharacterCard from "@/components/CharacterCard/Page";
import ScoreFilter from "@/components/TopScores/Page";
import NavigationBar from "@/components/shared/NavigationBar/NavigationBar";
import ScoreCardList from "@/components/ScoreCard/ScoreCard";
export default function Chunithm() {
return (
<div className="p-2 min-h-screen bg-base">
<NavigationBar />
<div className="flex flex-col gap-4 mt-2 md:gap-6 lg:flex-row lg:gap-8">
<div className="w-full lg:w-1/4 xl:w-1/5">
<ScoreFilter />
</div>
<div className="flex flex-col w-full lg:w-3/4 xl:w-4/5 lg:flex-row">
<div className="w-full lg:w-1/2 lg-md-[1300px] lg-w-[1300px] xl-w-[1300px]">
<CharacterCard />
<ScoreCardList />
</div>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,58 @@
"use client";
import axios from "axios";
import { useState, useEffect } from "react";
import { AxiosError } from "axios";
import { useRouter } from "next/navigation";
interface UserResponse {
user: string | null;
error: AxiosError | null;
}
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
const [isSuccess, setIsSuccess] = useState<boolean>(false);
const router = useRouter();
useEffect(() => {
(async () => {
const { user, error } = await getUser();
if (error) {
router.push("/");
return;
} // if error duid not happen everything is alright
setIsSuccess(true);
})();
}, [router]);
if (!isSuccess) {
}
return (
<main>
{children}
</main>
);
async function getUser(): Promise<UserResponse> {
try {
const { data } = await axios.get("/api/auth/me");
return {
user: data,
error: null,
};
} catch (e) {
const error = e as AxiosError;
return {
user: null,
error: error,
};
}
}
}

View File

@ -0,0 +1,7 @@
import NavigationBar from "@/components/shared/NavigationBar/NavigationBar";
export default function Dashboard() {
return <div className="p-4 min-h-screen bg-base lg:p-2">
<NavigationBar/>
</div>;
}

BIN
src/app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

313
src/app/globals.css Normal file
View File

@ -0,0 +1,313 @@
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap");
@tailwind base;
@tailwind components;
@tailwind utilities;
.cont {
height: 100vh;
margin: 0;
padding: 0;
display: flex;
}
.icon-color {
fill: #a6da95;
}
img,
video {
max-width: revert;
height: revert;
}
.sidebar {
display: inline-flex;
height: 100vh;
/* width: fit-content; */
padding: 0 10px;
flex-direction: column;
background-color: #141414;
overflow: hidden;
color: #f9f9f9;
}
.item {
margin: 10px 0;
padding: 8px 10px;
border-radius: 3px;
transition: background-color 0.3s;
}
.item:hover {
background-color: blueviolet;
cursor: pointer;
}
.item:active {
background-color: #0052cc;
}
.line {
margin: 15px 10px;
border-radius: 3px;
border: 1px solid grey;
}
.rainbow-text {
background: linear-gradient(
to left,
violet,
indigo,
blue,
green,
yellow,
orange,
red
);
-webkit-background-clip: text;
color: transparent;
}
/*
* CHUSAN AVATAR
*/
.avatar_group {
width: 420px;
height: 330px;
margin: 0px auto 0px auto;
/* background-color: red; */
position: relative;
}
/* Mobile Styles */
@media screen and (max-width: 480px) {
.avatar_group {
width: 100%; /* Adjust width for mobile */
height: auto; /* Adjust height as needed */
/* You can also adjust other properties as needed */
}
}
/* アバター土台 */
.avatar_base {
width: 272px;
height: 330px;
padding: 10px 0 0 0;
position: relative;
margin: 0px auto 0px auto;
overflow: hidden;
}
/* 背景 */
.avatar_back {
display: block;
width: 272px;
height: 330px;
position: absolute;
top: 25px;
z-index: 100;
}
/* 右足 */
.avatar_skinfoot_r {
display: block;
width: 42px;
height: 52px;
position: absolute;
overflow: hidden;
z-index: 101;
top: 280px;
left: 84px;
}
.avatar_skinfoot_r img {
transform: translate(0px, -204px);
}
/* 左足 */
.avatar_skinfoot_l {
display: block;
width: 42px;
height: 52px;
position: absolute;
overflow: hidden;
z-index: 102;
top: 280px;
left: 147px;
}
.avatar_skinfoot_l img {
transform: translate(-42px, -204px);
}
/* デフォルト髪の毛 */
.avatar_hair {
display: block;
width: 46px;
height: 78px;
position: absolute;
overflow: hidden;
z-index: 103;
top: 21px;
left: 110px;
}
.avatar_hair img {
transform: translate(0px, 0px);
}
/* 体色 */
.avatar_skin {
display: block;
width: 128px;
height: 204px;
position: absolute;
overflow: hidden;
z-index: 104;
top: 93px;
left: 72px;
}
.avatar_skin img {
transform: translate(0px, 0px);
}
/* 衣装 */
.avatar_wear {
display: block;
width: 258px;
height: 218px;
position: absolute;
overflow: hidden;
z-index: 105;
top: 106px;
left: 7px;
}
.avatar_wear img {
transform: translate(0px, 0px);
}
/* 表情 */
.avatar_face {
display: block;
width: 58px;
height: 64px;
position: absolute;
overflow: hidden;
z-index: 106;
top: 100px;
left: 107px;
}
.avatar_face img {
transform: translate(0px, 0px);
}
/* 表情 */
.avatar_face_static {
display: block;
width: 58px;
height: 64px;
position: absolute;
overflow: hidden;
z-index: 106;
top: 100px;
left: 107px;
}
.avatar_face img {
transform: translate(0px, 0px);
}
/* フェイスカバー */
.avatar_face {
display: block;
width: 116px;
height: 104px;
position: absolute;
overflow: hidden;
z-index: 107;
top: 96px;
left: 78px;
}
.avatar_faceCover img {
transform: translate(0px, 0px);
}
/* 頭 */
.avatar_head {
display: block;
width: 200px;
height: 150px;
position: absolute;
overflow: hidden;
z-index: 108;
top: 28px;
left: 37px;
}
.avatar_head img {
transform: translate(0px, 0px);
}
/* 右手 */
.avatar_hand_r {
display: block;
width: 36px;
height: 72px;
position: absolute;
overflow: hidden;
z-index: 108;
top: 178px;
left: 52px;
}
.avatar_hand_r img {
transform: translate(0px, 0px);
}
/* 左手 */
.avatar_hand_l {
display: block;
width: 36px;
height: 72px;
position: absolute;
overflow: hidden;
z-index: 109;
top: 178px;
left: 184px;
}
.avatar_hand_l img {
transform: translate(0px, 0px);
}
/* 右アイテム */
.avatar_item_r {
display: block;
width: 100px;
height: 272px;
position: absolute;
overflow: hidden;
z-index: 109;
transform: rotate(-5deg);
top: 50px;
left: 9px;
}
.avatar_item_r img {
transform: translate(0px, 0px);
}
/* 左アイテム */
.avatar_item_l {
display: block;
width: 100px;
height: 272px;
position: absolute;
overflow: hidden;
z-index: 110;
transform: rotate(5deg);
top: 50px;
left: 163px;
}
.avatar_item_l img {
transform: translate(-100px, 0px);
}

View File

@ -0,0 +1,420 @@
import { Dispatch, SetStateAction, useEffect } from "react";
import axios from "axios";
import { useCookies } from "next-client-cookies";
import jwt from "jsonwebtoken";
type AvatarCustomizationProfileData = any;
interface UseAvatarCustomizationParams {
setAvatarCustomization: Dispatch<SetStateAction<AvatarCustomizationProfileData[]>>;
setLoading: Dispatch<SetStateAction<boolean>>;
setError: Dispatch<SetStateAction<string | null>>;
}
export const UseAvatarCustomization = ({
setAvatarCustomization,
setLoading,
setError,
}: UseAvatarCustomizationParams) => {
const { get } = useCookies();
const token = get("LOGIN_INFO");
useEffect(() => {
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token as string) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/avatar_customization?user=${decodedToken.userId}`;
const source = axios.CancelToken.source();
axios
.get(apiUrl, { cancelToken: source.token })
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
setAvatarCustomization(response.data);
setLoading(false);
})
.catch((err) => {
if (!axios.isCancel(err)) {
setError(err.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
}, [token, setError, setLoading, setAvatarCustomization]);
};
type AvatarItemList = any;
interface UseAvatarItemListParams {
setAvatarItemList: Dispatch<SetStateAction<AvatarItemList[]>>;
setLoading: Dispatch<SetStateAction<boolean>>;
setError: Dispatch<SetStateAction<string | null>>;
}
export const UseAvatarItemList = ({
setAvatarItemList,
setLoading,
setError,
}: UseAvatarItemListParams) => {
const cookies = useCookies();
const token = cookies.get("LOGIN_INFO");
useEffect(() => {
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token as string) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
const source = axios.CancelToken.source();
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/chuni_item_item?user=${decodedToken.userId}`;
axios
.get(apiUrl, { cancelToken: source.token })
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
setAvatarItemList(response.data);
setLoading(false);
})
.catch((err) => {
if (axios.isCancel(err)) {
} else {
setError(err.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
}, [cookies, setAvatarItemList, setLoading, setError]);
};
type BestTop = any;
interface UseBestTopScoresParams {
setBestTop: Dispatch<SetStateAction<BestTop[]>>;
setLoading: Dispatch<SetStateAction<boolean>>;
setError: Dispatch<SetStateAction<string | null>>;
}
export const useBestTop = ({
setBestTop,
setLoading,
setError,
}: UseBestTopScoresParams) => {
const cookies = useCookies();
const token = cookies.get("LOGIN_INFO");
useEffect(() => {
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token as string) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/chuni_best_and_top?user=${decodedToken.userId}`;
const source = axios.CancelToken.source();
axios
.get(apiUrl, { cancelToken: source.token })
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
setBestTop(response.data);
setLoading(false);
})
.catch((err) => {
if (!axios.isCancel(err)) {
setError(err.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
}, [cookies, setBestTop, setLoading, setError]);
};
type PlayerProfileData = any;
interface UseCharacterDataParams {
setPlayerInfo: Dispatch<SetStateAction<PlayerProfileData[]>>;
setLoading: Dispatch<SetStateAction<boolean>>;
setError: Dispatch<SetStateAction<string | null>>;
}
export const usePlayerInfo = ({
setPlayerInfo,
setLoading,
setError,
}: UseCharacterDataParams) => {
const cookies = useCookies();
const token = cookies.get("LOGIN_INFO");
useEffect(() => {
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token as string) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
const source = axios.CancelToken.source();
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/profile_data?user=${decodedToken.userId}`;
axios
.get(apiUrl, { cancelToken: source.token })
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
setPlayerInfo(response.data);
setLoading(false);
})
.catch((err) => {
if (axios.isCancel(err)) {
// Handle cancellation if needed
} else {
setError(err.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
}, [token, setPlayerInfo, setLoading, setError]);
};
type PlayerScoreLogType = any[];
interface UseFetchPlayerScoreLogParams {
setPlayerScoreLog: Dispatch<SetStateAction<PlayerScoreLogType>>;
setLoading: Dispatch<SetStateAction<boolean>>;
setError: Dispatch<SetStateAction<string | null>>;
}
export const useFetchPlayerScoreLog = ({
setPlayerScoreLog,
setLoading,
setError,
}: UseFetchPlayerScoreLogParams) => {
const cookies = useCookies();
const token = cookies.get("LOGIN_INFO");
useEffect(() => {
let isMounted = true;
const source = axios.CancelToken.source();
async function fetchProfileData() {
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token as string) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/chuni_score_playlog?user=${decodedToken.userId}`;
try {
const response = await axios.get(apiUrl, { cancelToken: source.token });
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
if (isMounted) {
setPlayerScoreLog(response.data);
setLoading(false);
}
} catch (error) {
if (axios.isCancel(error)) {
} else if (error instanceof Error) {
setError(error.message);
setLoading(false);
} else {
setError("An unknown error occurred");
setLoading(false);
}
}
}
fetchProfileData();
return () => {
isMounted = false;
source.cancel("Operation canceled by the user.");
};
}, [cookies, setError, setLoading, setPlayerScoreLog]);
};
type PlayerTeam = any;
interface usePlayerTeamsParams {
setPlayerTeams: Dispatch<SetStateAction<PlayerTeam[]>>;
setLoading: Dispatch<SetStateAction<boolean>>;
setError: Dispatch<SetStateAction<string | null>>;
}
export const UsePlayerTeams = ({
setPlayerTeams,
setLoading,
setError,
}: usePlayerTeamsParams) => {
const cookies = useCookies();
const token = cookies.get("LOGIN_INFO");
useEffect(() => {
const source = axios.CancelToken.source();
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token as string) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/chuni_player_team?user=${decodedToken.userId}`;
axios
.get(apiUrl, { cancelToken: source.token })
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
setPlayerTeams(response.data);
setLoading(false);
})
.catch((err) => {
if (axios.isCancel(err)) {
} else {
setError(err.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
}, [cookies, setPlayerTeams, setLoading, setError]);
};
type SystemVoiceData = any;
interface useSystemVoiceParams {
setSystemVoice: Dispatch<SetStateAction<SystemVoiceData[]>>;
setLoading: Dispatch<SetStateAction<boolean>>;
setError: Dispatch<SetStateAction<string | null>>;
}
export const UseSystemVoice = ({
setSystemVoice,
setLoading,
setError,
}: useSystemVoiceParams) => {
const cookies = useCookies();
const token = cookies.get("LOGIN_INFO");
useEffect(() => {
const source = axios.CancelToken.source();
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token as string) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/profile_data?user=${decodedToken.userId}`;
axios
.get(apiUrl, { cancelToken: source.token })
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
setSystemVoice(response.data);
setLoading(false);
})
.catch((err) => {
if (axios.isCancel(err)) {
} else {
setError(err.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
}, [cookies, setSystemVoice, setLoading, setError]);
};

View File

@ -0,0 +1,603 @@
import axios from "axios";
import { useCookies } from "next-client-cookies";
import jwt from "jsonwebtoken"; // Import the jsonwebtoken library
type AvatarData = any;
interface UsePostAvatarItemListParams {
onPostSuccess: (data: AvatarData) => void;
setLoading: (loading: boolean) => void;
setError: (error: string | null) => void;
}
export const UsePostAvatarItemList = ({
onPostSuccess,
setLoading,
setError,
}: UsePostAvatarItemListParams) => {
const cookies = useCookies();
const postAvatarData = (avatarData: AvatarData) => {
setLoading(true);
const source = axios.CancelToken.source();
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO");
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/updateAvatarCustomization?user=${decodedToken.userId}`;
axios
.post(apiUrl, avatarData, {
cancelToken: source.token,
})
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
onPostSuccess(response.data);
setLoading(false);
})
.catch((error) => {
if (axios.isCancel(error)) {
} else {
setError(error.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
};
return { postAvatarData };
};
type KeychipCreation = any;
interface UsePostNewKeychipParams {
onPostSuccess: (data: KeychipCreation) => void;
setLoading: (loading: boolean) => void;
setError: (error: string | null) => void;
}
export const UsePostNewKeychip = ({
onPostSuccess,
setLoading,
setError,
}: UsePostNewKeychipParams) => {
const cookies = useCookies();
const createNewKeychip = (postTeamData: KeychipCreation) => {
setLoading(true);
const source = axios.CancelToken.source();
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO");
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/create_keychip?user=${decodedToken.userId}`;
axios
.post(apiUrl, postTeamData, {
cancelToken: source.token,
})
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
onPostSuccess(response.data);
setLoading(false);
})
.catch((error) => {
if (axios.isCancel(error)) {
} else {
setError(error.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
};
return { createNewKeychip };
};
type MapIcon = any;
interface UsePostMapIconParams {
onPostSuccess: (data: MapIcon) => void;
setLoading: (loading: boolean) => void;
setError: (error: string | null) => void;
}
export const UsePostMapIcon = ({
onPostSuccess,
setLoading,
setError,
}: UsePostMapIconParams) => {
const cookies = useCookies();
const postMapIcon = (avatarData: MapIcon) => {
setLoading(true);
const source = axios.CancelToken.source();
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO");
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/update_chuni_item_mapchar?user=${decodedToken.userId}`;
axios
.post(apiUrl, avatarData, {
cancelToken: source.token,
})
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
onPostSuccess(response.data);
setLoading(false);
})
.catch((error) => {
if (axios.isCancel(error)) {
} else {
setError(error.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
};
return { postMapIcon };
};
type NameplateId = any;
interface UsePostNameplateIdParams {
onPostSuccess: (data: NameplateId) => void;
setLoading: (loading: boolean) => void;
setError: (error: string | null) => void;
}
export const UsePostNamePlate = ({
onPostSuccess,
setLoading,
setError,
}: UsePostNameplateIdParams) => {
const cookies = useCookies();
const postNamePlate = (avatarData: NameplateId) => {
setLoading(true);
const source = axios.CancelToken.source();
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO");
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/update_nameplateId?user=${decodedToken.userId}`;
axios
.post(apiUrl, avatarData, {
cancelToken: source.token,
})
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
onPostSuccess(response.data);
setLoading(false);
})
.catch((error) => {
if (axios.isCancel(error)) {
} else {
setError(error.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
};
return { postNamePlate };
};
type PlayerTeam = any;
interface UsePostPlayerTeamParams {
onPostSuccess: (data: PlayerTeam) => void;
setLoading: (loading: boolean) => void;
setError: (error: string | null) => void;
}
export const UsePostPlayerTeam = ({
onPostSuccess,
setLoading,
setError,
}: UsePostPlayerTeamParams) => {
const cookies = useCookies();
const postTeamName = (PostTeamData: PlayerTeam) => {
setLoading(true);
const source = axios.CancelToken.source();
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO");
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/update_chuni_player_team?user=${decodedToken.userId}`;
axios
.post(apiUrl, PostTeamData, {
cancelToken: source.token,
})
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
onPostSuccess(response.data);
setLoading(false);
})
.catch((error) => {
if (axios.isCancel(error)) {
} else {
setError(error.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
};
return { postTeamName };
};
type PlayerTeamProfile = any;
interface UsePostPlayerTeamProfileParams {
onPostSuccess: (data: PlayerTeamProfile) => void;
setLoading: (loading: boolean) => void;
setError: (error: string | null) => void;
}
export const UsePostPlayerTeamProfile = ({
onPostSuccess,
setLoading,
setError,
}: UsePostPlayerTeamProfileParams) => {
const cookies = useCookies();
const postTeamNameProfile = (postPlayerTeamProfileData: PlayerTeamProfile) => {
setLoading(true);
const source = axios.CancelToken.source();
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO");
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/update_chuni_profile_player_team?user=${decodedToken.userId}`;
axios
.post(apiUrl, postPlayerTeamProfileData, {
cancelToken: source.token,
})
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
onPostSuccess(response.data);
setLoading(false);
})
.catch((error) => {
if (axios.isCancel(error)) {
} else {
setError(error.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
};
return { postTeamNameProfile };
};
type SystemVoice = any;
interface UsePostSystemVoiceParams {
onPostSuccess: (data: SystemVoice) => void;
setLoading: (loading: boolean) => void;
setError: (error: string | null) => void;
}
export const UsePostSystemVoice = ({
onPostSuccess,
setLoading,
setError,
}: UsePostSystemVoiceParams) => {
const cookies = useCookies();
const postVoiceID = (avatarData: SystemVoice) => {
setLoading(true);
const source = axios.CancelToken.source();
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO");
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/update_chuni_item_duel?user=${decodedToken.userId}`;
axios
.post(apiUrl, avatarData, {
cancelToken: source.token,
})
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
onPostSuccess(response.data);
setLoading(false);
})
.catch((error) => {
if (axios.isCancel(error)) {
} else {
setError(error.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
};
return { postVoiceID };
};
type TrophyName = any;
interface UsePostTrophyParams {
onPostSuccess: (data: TrophyName) => void;
setLoading: (loading: boolean) => void;
setError: (error: string | null) => void;
}
export const UsePostTrophy = ({
onPostSuccess,
setLoading,
setError,
}: UsePostTrophyParams) => {
const cookies = useCookies();
const postTrophy = (avatarData: TrophyName) => {
setLoading(true);
const source = axios.CancelToken.source();
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO");
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/update_trophyid?user=${decodedToken.userId}`;
axios
.post(apiUrl, avatarData, {
cancelToken: source.token,
})
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
onPostSuccess(response.data);
setLoading(false);
})
.catch((error) => {
if (axios.isCancel(error)) {
} else {
setError(error.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
};
return { postTrophy };
};
type playerRivals = any;
interface UsePostPlayerRivalParams {
onPostSuccess: (data: playerRivals) => void;
setLoading: (loading: boolean) => void;
setError: (error: string | null) => void;
}
export const UsePostPlayerRival = ({
onPostSuccess,
setLoading,
setError,
}: UsePostPlayerRivalParams) => {
const cookies = useCookies();
const postRival = (avatarData: playerRivals) => {
setLoading(true);
const source = axios.CancelToken.source();
// Get the user ID from the decoded token
const token = cookies.get("LOGIN_INFO");
if (!token) {
setError("JWT token not available");
setLoading(false);
return;
}
const decodedToken = jwt.decode(token) as { userId?: string };
if (!decodedToken.userId) {
setError("User ID not available");
setLoading(false);
return;
}
// Include the user ID in the request URL
const apiUrl = `${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}/update_chuni_player_rivals?user=${decodedToken.userId}`;
axios
.post(apiUrl, avatarData, {
cancelToken: source.token,
})
.then((response) => {
if (response.status !== 200) {
throw new Error("Network response was not ok");
}
onPostSuccess(response.data);
setLoading(false);
})
.catch((error) => {
if (axios.isCancel(error)) {
} else {
setError(error.message);
setLoading(false);
}
});
return () => {
source.cancel("Operation canceled by the user.");
};
};
return { postRival };
};

27
src/app/layout.tsx Normal file
View File

@ -0,0 +1,27 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { ClientCookiesProvider } from "@/components/shared/cookieProvider/Page";
import { cookies } from 'next/headers';
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Cozy Net",
description: "A Cozy ALL.net Emulation Frontend",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>
<ClientCookiesProvider value={cookies().getAll()}>
{children}
</ClientCookiesProvider>
</body>
</html>
);
}

152
src/app/page.tsx Normal file
View File

@ -0,0 +1,152 @@
"use client";
import { useRouter } from "next/navigation";
import axios from "axios";
import Link from "next/link";
import { toast, ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
export default function Home() {
const { push } = useRouter();
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const payload = {
username: event.currentTarget.username.value,
password: event.currentTarget.password.value,
};
try {
await axios.post("/api/auth/login", payload);
toast.success("Login successful!", {
className: "success-toast",
bodyClassName: "toast-body",
closeButton: false,
theme: "colored",
});
push("/chunithm");
} catch (error) {
handleLoginError(error);
}
};
function handleLoginError(error: any) {
if (axios.isAxiosError(error)) {
if (error.response && error.response.status === 404) {
toast.error("Invalid credentials, please try again.", {
className: "error-toast",
bodyClassName: "toast-body",
closeButton: false,
theme: "colored",
});
}
}
}
return (
<main>
<div className="flex justify-center items-center px-6 min-h-screen bg-base">
<div className="w-full max-w-md">
<div className="overflow-hidden rounded-lg shadow-xl bg-crust">
<div className="px-10 py-8">
<div className="mb-8 text-center">
<h1 className="text-2xl font-semibold text-text">USER LOGIN</h1>
</div>
<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label
htmlFor="username"
className="block mb-2 text-sm font-medium text-text"
>
Username
</label>
<input
type="text"
id="username"
name="username"
required
className="px-4 py-2 w-full rounded-md border focus:border-blue-500 focus:ring focus:ring-blue-300 focus:ring-opacity-50"
/>
</div>
<div>
<label
htmlFor="password"
className="block mb-2 text-sm font-medium text-text"
>
Password
</label>
<input
type="password"
id="password"
name="password"
required
className="px-4 py-2 w-full rounded-md border focus:border-blue-500 focus:ring focus:ring-blue-300 focus:ring-opacity-50"
/>
</div>
<div className="flex justify-end items-center">
<Link
href="/signup"
className="text-sm font-bold uppercase cursor-pointer text-text start hover:underline"
>
Forgot Password?
</Link>
</div>
<div className="px-10 py-4 text-center">
<button
type="submit"
className="text-sm font-bold uppercase cursor-pointer text-text hover:underline"
>
Login
</button>
</div>
</form>
</div>
<div className="px-10 py-4 text-center bg-mantle">
<Link
href="/signup"
className="text-sm font-bold uppercase cursor-pointer text-text start hover:underline"
>
Create account
</Link>
</div>
<ToastContainer
position="top-center"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
limit={3}
toastClassName="toast-class"
/>
</div>
</div>
</div>
<style jsx>{`
.toast-class {
background-color: #2a2a2a;
color: white;
border-radius: 8px;
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
}
.success-toast {
background-color: #4caf50;
}
.error-toast {
background-color: #f44336;
}
.toast-body {
font-size: 0.9rem;
padding: 15px;
}
`}</style>
</main>
);
}

203
src/app/signup/page.tsx Normal file
View File

@ -0,0 +1,203 @@
"use client"
import { useRouter } from "next/navigation";
import axios from "axios";
import Link from "next/link";
import { toast, ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
function handleSignUpError(error: any) {
if (axios.isAxiosError(error)) {
if (error.response && error.response.status === 404) {
toast.error(
"Please play at least one credit before signing in to the web UI",
{
className: "error-toast",
bodyClassName: "toast-body",
closeButton: false,
theme: "colored",
}
);
}
if (error.response && error.response.status === 500) {
toast.error("Username, email, or password already exists", {
className: "error-toast",
bodyClassName: "toast-body",
closeButton: false,
theme: "colored",
});
}
if (error.response && error.response.status === 409) {
toast.error(
"Cannot change username, email, or password during sign-up",
{
className: "error-toast",
bodyClassName: "toast-body",
closeButton: false,
theme: "colored",
}
);
}
}
}
interface InputFieldProps {
id: string;
type: string;
name: string;
labelText: string;
required: boolean;
className?: string;
}
const InputField: React.FC<InputFieldProps> = ({
id,
type,
name,
labelText,
required,
className,
}) => (
<div>
<label htmlFor={id} className="text-sm font-medium text-text block mb-2">
{labelText}
</label>
<input
type={type}
id={id}
name={name}
required={required}
className={`w-full px-4 py-2 border rounded-md focus:border-blue-500 focus:ring focus:ring-blue-300 focus:ring-opacity-50 ${className}`}
/>
</div>
);
export default function Signup() {
const { push } = useRouter();
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const payload = {
email: event.currentTarget.email.value,
accessCode: event.currentTarget.accessCode.value,
username: event.currentTarget.username.value,
password: event.currentTarget.password.value,
};
try {
await axios.post("/api/auth/signup", payload);
toast.success("Signup successful!", {
className: "success-toast",
bodyClassName: "toast-body",
closeButton: false,
theme: "colored",
});
push("/chunithm");
} catch (error) {
handleSignUpError(error);
}
};
return (
<main>
<div className="min-h-screen bg-base flex items-center justify-center px-6">
<div className="w-full max-w-md">
<div className="bg-crust shadow-xl rounded-lg overflow-hidden">
<div className="px-10 py-8">
<div className="text-center mb-8">
<h1 className="text-2xl font-semibold text-text">
USER SIGNUP
</h1>
</div>
<form onSubmit={handleSubmit} className="space-y-6">
<InputField
id="email"
type="email"
name="email"
labelText="Email"
required={true}
className=""
/>
<InputField
id="accessCode"
type="text"
name="accessCode"
labelText="Access Code"
required={true}
className=""
/>
<InputField
id="username"
type="text"
name="username"
labelText="Username"
required={true}
className=""
/>
<InputField
id="password"
type="password"
name="password"
labelText="Password"
required={true}
className=""
/>
<div className="px-10 py-4 text-center">
<button
type="submit"
className="text-sm text-text uppercase font-bold hover:underline cursor-pointer"
>
Sign up
</button>
</div>
</form>
</div>
<div className="px-10 py-4 bg-mantle text-center">
<Link
href="/"
className="text-sm text-text start uppercase font-bold hover:underline cursor-pointer"
>
Already have an account? Login
</Link>
</div>
<ToastContainer
position="top-center"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
limit={3}
toastClassName="toast-class"
/>
</div>
</div>
</div>
<style jsx>{`
.toast-class {
background-color: #2a2a2a;
color: white;
border-radius: 8px;
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
}
.success-toast {
background-color: #4caf50;
}
.error-toast {
background-color: #f44336;
}
.toast-body {
font-size: 0.9rem;
padding: 15px;
}
`}</style>
</main>
);
}

View File

@ -0,0 +1,58 @@
"use client";
import axios from "axios";
import { useState, useEffect } from "react";
import { AxiosError } from "axios";
import { useRouter } from "next/navigation";
interface UserResponse {
user: string | null;
error: AxiosError | null;
}
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
const [isSuccess, setIsSuccess] = useState<boolean>(false);
const router = useRouter();
useEffect(() => {
(async () => {
const { user, error } = await getUser();
if (error) {
router.push("/");
return;
}
setIsSuccess(true);
})();
}, [router]);
if (!isSuccess) {
}
return (
<main>
{children}
</main>
);
async function getUser(): Promise<UserResponse> {
try {
const { data } = await axios.get("/api/auth/me");
return {
user: data,
error: null,
};
} catch (e) {
const error = e as AxiosError;
return {
user: null,
error: error,
};
}
}
}

50
src/app/userbox/page.tsx Normal file
View File

@ -0,0 +1,50 @@
import AvatarCustomizationData from "@/components/CharacterCustomization/Page";
import PlayerMapIconComponent from "@/components/PlayerMapIcon/page";
import SystemVoiceComponent from "@/components/SystemVoiceUserBox/page";
import PlayerTeamComponent from "@/components/UserTeams/page";
import NavigationBar from "@/components/shared/NavigationBar/NavigationBar";
import NewKeychipComponent from "@/components/whitelistKeychips/page";
import PlayerTrophyComponent from "@/components/PlayerTrophySelector/page";
import PlayerNamePlateComponent from "@/components/PlayerNameplate/page";
import RivalComponent from "@/components/PlayerRivals/page";
const UserBox = () => {
return (
<div className="bg-base min-h-screen p-4 lg:p-2">
<NavigationBar />
<div className="bg-base min-h-screen flex flex-col items-center ">
<div className="text-maroon mt-2 font-bold">
<span>THIS USERBOX ASSUMES YOU HAVE EVERYTHING UNLOCKED AND THAT YOU'RE PLAYING ON CHUNITHM NEW-SUN
</span>
</div>
<div className="">
<div className="mt-2 w-full">
<AvatarCustomizationData />
</div>
<div className="mt-4 w-full">
<PlayerNamePlateComponent />
</div>
<div className="mt-4 w-full">
<PlayerTrophyComponent />
</div>
<div className="mt-4 w-full">
<SystemVoiceComponent />
</div>
<div className="mt-4 w-full">
<PlayerMapIconComponent />
</div>
<div className="mt-4 w-full">
<PlayerTeamComponent />
</div>
<div className="mt-4 w-full">
<RivalComponent />
</div>
<div className="mt-4 w-full">
<NewKeychipComponent />
</div>
</div>
</div>
</div>
);
};
export default UserBox;

View File

@ -0,0 +1,107 @@
import React from "react";
import Link from "next/link";
interface NavItemProps {
href: string;
icon: React.ReactNode;
label: string;
notificationCount?: number;
}
const NavItem: React.FC<NavItemProps> = ({
href,
icon,
label,
notificationCount,
}) => {
return (
<Link href={href} passHref>
<div className="flex items-center p-2 rounded-lg text-text dark:text-white hover:bg-mantle dark:hover:bg-gray-700 group">
{icon}
<span className="flex-1 ml-3 whitespace-nowrap">{label}</span>
{typeof notificationCount === "number" && (
<span className="inline-flex justify-center items-center p-3 ml-3 w-3 h-3 text-sm font-medium text-blue-800 bg-blue-100 rounded-full dark:bg-blue-900 dark:text-blue-300">
{notificationCount}
</span>
)}
</div>
</Link>
);
};
const ArcadeWhiteListUI: React.FC = () => {
return (
<div>
<aside
id="default-sidebar"
className="fixed top-0 left-0 z-40 w-64 h-screen transition-transform -translate-x-full sm:translate-x-0"
aria-label="Sidebar"
>
<div className="overflow-y-auto px-3 py-4 h-full bg-crust dark:bg-gray-800">
<ul className="space-y-2 font-medium">
<li>
<NavItem
href="/banned-users"
icon={
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
className="bi bi-controller"
viewBox="0 0 16 16"
>
<path d="M11.5 6.027a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-1.5 1.5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zm2.5-.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-1.5 1.5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zm-6.5-3h1v1h1v1h-1v1h-1v-1h-1v-1h1v-1z" />
<path d="M3.051 3.26a.5.5 0 0 1 .354-.613l1.932-.518a.5.5 0 0 1 .62.39c.655-.079 1.35-.117 2.043-.117.72 0 1.443.041 2.12.126a.5.5 0 0 1 .622-.399l1.932.518a.5.5 0 0 1 .306.729c.14.09.266.19.373.297.408.408.78 1.05 1.095 1.772.32.733.599 1.591.805 2.466.206.875.34 1.78.364 2.606.024.816-.059 1.602-.328 2.21a1.42 1.42 0 0 1-1.445.83c-.636-.067-1.115-.394-1.513-.773-.245-.232-.496-.526-.739-.808-.126-.148-.25-.292-.368-.423-.728-.804-1.597-1.527-3.224-1.527-1.627 0-2.496.723-3.224 1.527-.119.131-.242.275-.368.423-.243.282-.494.575-.739.808-.398.38-.877.706-1.513.773a1.42 1.42 0 0 1-1.445-.83c-.27-.608-.352-1.395-.329-2.21.024-.826.16-1.73.365-2.606.206-.875.486-1.733.805-2.466.315-.722.687-1.364 1.094-1.772a2.34 2.34 0 0 1 .433-.335.504.504 0 0 1-.028-.079zm2.036.412c-.877.185-1.469.443-1.733.708-.276.276-.587.783-.885 1.465a13.748 13.748 0 0 0-.748 2.295 12.351 12.351 0 0 0-.339 2.406c-.022.755.062 1.368.243 1.776a.42.42 0 0 0 .426.24c.327-.034.61-.199.929-.502.212-.202.4-.423.615-.674.133-.156.276-.323.44-.504C4.861 9.969 5.978 9.027 8 9.027s3.139.942 3.965 1.855c.164.181.307.348.44.504.214.251.403.472.615.674.318.303.601.468.929.503a.42.42 0 0 0 .426-.241c.18-.408.265-1.02.243-1.776a12.354 12.354 0 0 0-.339-2.406 13.753 13.753 0 0 0-.748-2.295c-.298-.682-.61-1.19-.885-1.465-.264-.265-.856-.523-1.733-.708-.85-.179-1.877-.27-2.913-.27-1.036 0-2.063.091-2.913.27z" />
</svg>
}
label="Arcades"
/>
</li>
<li>
<NavItem
href="/banned-users"
icon={
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
className="bi bi-controller"
viewBox="0 0 16 16"
>
<path d="M11.5 6.027a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-1.5 1.5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zm2.5-.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-1.5 1.5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zm-6.5-3h1v1h1v1h-1v1h-1v-1h-1v-1h1v-1z" />
<path d="M3.051 3.26a.5.5 0 0 1 .354-.613l1.932-.518a.5.5 0 0 1 .62.39c.655-.079 1.35-.117 2.043-.117.72 0 1.443.041 2.12.126a.5.5 0 0 1 .622-.399l1.932.518a.5.5 0 0 1 .306.729c.14.09.266.19.373.297.408.408.78 1.05 1.095 1.772.32.733.599 1.591.805 2.466.206.875.34 1.78.364 2.606.024.816-.059 1.602-.328 2.21a1.42 1.42 0 0 1-1.445.83c-.636-.067-1.115-.394-1.513-.773-.245-.232-.496-.526-.739-.808-.126-.148-.25-.292-.368-.423-.728-.804-1.597-1.527-3.224-1.527-1.627 0-2.496.723-3.224 1.527-.119.131-.242.275-.368.423-.243.282-.494.575-.739.808-.398.38-.877.706-1.513.773a1.42 1.42 0 0 1-1.445-.83c-.27-.608-.352-1.395-.329-2.21.024-.826.16-1.73.365-2.606.206-.875.486-1.733.805-2.466.315-.722.687-1.364 1.094-1.772a2.34 2.34 0 0 1 .433-.335.504.504 0 0 1-.028-.079zm2.036.412c-.877.185-1.469.443-1.733.708-.276.276-.587.783-.885 1.465a13.748 13.748 0 0 0-.748 2.295 12.351 12.351 0 0 0-.339 2.406c-.022.755.062 1.368.243 1.776a.42.42 0 0 0 .426.24c.327-.034.61-.199.929-.502.212-.202.4-.423.615-.674.133-.156.276-.323.44-.504C4.861 9.969 5.978 9.027 8 9.027s3.139.942 3.965 1.855c.164.181.307.348.44.504.214.251.403.472.615.674.318.303.601.468.929.503a.42.42 0 0 0 .426-.241c.18-.408.265-1.02.243-1.776a12.354 12.354 0 0 0-.339-2.406 13.753 13.753 0 0 0-.748-2.295c-.298-.682-.61-1.19-.885-1.465-.264-.265-.856-.523-1.733-.708-.85-.179-1.877-.27-2.913-.27-1.036 0-2.063.091-2.913.27z" />
</svg>
}
label="Machines"
/>
</li>
<li>
<NavItem
href="/banned-users"
icon={
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
className="bi bi-controller"
viewBox="0 0 16 16"
>
<path d="M11.5 6.027a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-1.5 1.5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zm2.5-.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-1.5 1.5a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zm-6.5-3h1v1h1v1h-1v1h-1v-1h-1v-1h1v-1z" />
<path d="M3.051 3.26a.5.5 0 0 1 .354-.613l1.932-.518a.5.5 0 0 1 .62.39c.655-.079 1.35-.117 2.043-.117.72 0 1.443.041 2.12.126a.5.5 0 0 1 .622-.399l1.932.518a.5.5 0 0 1 .306.729c.14.09.266.19.373.297.408.408.78 1.05 1.095 1.772.32.733.599 1.591.805 2.466.206.875.34 1.78.364 2.606.024.816-.059 1.602-.328 2.21a1.42 1.42 0 0 1-1.445.83c-.636-.067-1.115-.394-1.513-.773-.245-.232-.496-.526-.739-.808-.126-.148-.25-.292-.368-.423-.728-.804-1.597-1.527-3.224-1.527-1.627 0-2.496.723-3.224 1.527-.119.131-.242.275-.368.423-.243.282-.494.575-.739.808-.398.38-.877.706-1.513.773a1.42 1.42 0 0 1-1.445-.83c-.27-.608-.352-1.395-.329-2.21.024-.826.16-1.73.365-2.606.206-.875.486-1.733.805-2.466.315-.722.687-1.364 1.094-1.772a2.34 2.34 0 0 1 .433-.335.504.504 0 0 1-.028-.079zm2.036.412c-.877.185-1.469.443-1.733.708-.276.276-.587.783-.885 1.465a13.748 13.748 0 0 0-.748 2.295 12.351 12.351 0 0 0-.339 2.406c-.022.755.062 1.368.243 1.776a.42.42 0 0 0 .426.24c.327-.034.61-.199.929-.502.212-.202.4-.423.615-.674.133-.156.276-.323.44-.504C4.861 9.969 5.978 9.027 8 9.027s3.139.942 3.965 1.855c.164.181.307.348.44.504.214.251.403.472.615.674.318.303.601.468.929.503a.42.42 0 0 0 .426-.241c.18-.408.265-1.02.243-1.776a12.354 12.354 0 0 0-.339-2.406 13.753 13.753 0 0 0-.748-2.295c-.298-.682-.61-1.19-.885-1.465-.264-.265-.856-.523-1.733-.708-.85-.179-1.877-.27-2.913-.27-1.036 0-2.063.091-2.913.27z" />
</svg>
}
label="Banned Users"
notificationCount={3}
/>
</li>
</ul>
</div>
</aside>
</div>
);
};
export default ArcadeWhiteListUI;

View File

@ -0,0 +1,167 @@
"use client";
import React, { useState } from "react";
import Image from "next/image";
import { usePlayerInfo } from "@/app/hooks/useFetchApi";
interface CharacterImageProps {
characterId: number;
}
const CharacterImage = ({ characterId }: CharacterImageProps) => {
let calculatedId = Math.floor(characterId / 10);
const calculatedIdStr = calculatedId.toString();
if (calculatedIdStr.length > 4) {
calculatedId = parseInt(calculatedIdStr.slice(0, -1));
}
const baseDirectory = `${process.env.NEXT_PUBLIC_CDN}chusan_partners/CHU_UI_Character_${calculatedId}_00_02.png`;
const fallbackDirectory = `${process.env.NEXT_PUBLIC_CDN}chunithm_partners/CHU_UI_Character_0${calculatedId}_00_02.png`;
const [imageUrl, setImageUrl] = useState(baseDirectory);
const [attemptedFallback, setAttemptedFallback] = useState(false);
const handleError = () => {
if (!attemptedFallback) {
setImageUrl(fallbackDirectory);
setAttemptedFallback(true);
} else {
}
};
return (
<Image
src={imageUrl}
onError={handleError}
alt="Character Image"
width={64}
height={64}
className="absolute top-2 left-2 w-10 h-10 border-4 md:w-20 md:h-20 md:top-4 md:left-6 border-mantle"
/>
);
};
type TeamInfoProps = {
teamName?: string;
};
const TeamInfo = ({ teamName }: TeamInfoProps) => (
<div className="absolute top-2 left-24 p-1 mt-1 text-xs uppercase rounded-sm bg-mantle text-text md:p-3 md:mt-2 md:top-6 md:left-28">
{teamName
? `Belongs to team ${teamName}`
: "You are not belong to a team."}
</div>
);
const CharacterCard = () => {
const [profileData, setPlayerInfo] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
usePlayerInfo({ setPlayerInfo, setLoading, setError });
if (Array.isArray(profileData) && profileData.length === 0) {
return (
<div className="text-left rounded-sm md:px-0 md:mx-auto bg-crust">
<div className="pt-5 font-bold text-center uppercase text-text">
<div className="flex justify-start items-center pb-5 pl-10">
<div className="flex space-x-4 animate-pulse">
<div className="w-14 h-14 rounded-sm bg-slate-700"></div>
<div className="flex-1 py-1 space-y-6">
<div className="h-2 bg-slate-700 rounded w-[400px]"></div>
<div className="space-y-3">
<div className="grid grid-cols-3 gap-4">
<div className="col-span-2 h-2 rounded bg-slate-700"></div>
<div className="col-span-1 h-2 rounded bg-slate-700"></div>
</div>
<div className="h-2 rounded bg-slate-700"></div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
return (
<div className="md:px-0 md:mx-auto">
{Array.isArray(profileData) &&
profileData.map((user, index) => {
const {
lastCountryCode,
level,
userName,
playerRating,
highestRating,
overPowerRate,
lastPlayDate,
characterId,
reincarnationNum,
teamName
} = user;
return (
<div
key={index}
className="bg-crust p-2 md:p-6 rounded-sm relative mb-2 w-full sm:w-[200px] md:w-[200px] lg:w-[700px] xl:w-[1400px]"
>
<div className="flex items-center">
<CharacterImage characterId={characterId} />
</div>
<TeamInfo teamName={teamName} />
<div className="pt-14 md:pt-20">
<div className="mt-2 mb-2 ml-1 text-xs uppercase md:text-sm md:-ml-1">
<span className="px-2 py-1 font-bold rounded-sm bg-yellow text-mantle">
{lastCountryCode || "New comer"}
</span>
</div>
<div className="mb-2 md:mb-2">
<span className="text-xs uppercase text-text">
Lv.
{reincarnationNum > 0 && (
<span className="text-xs uppercase text-text">
<span className="text-lg font-bold"> {reincarnationNum}{level}</span>
</span>
)}
{reincarnationNum < 1 && (
<span className="text-lg font-bold"> {level}
</span>
)}
</span>
<span className="ml-2 font-bold md:text-lg md:ml-2 text-text">
{userName}
</span>
</div>
<div className="mb-2 md:mb-2">
<span className="text-xs uppercase text-text">Rating</span>
<div className="flex items-center">
<span className="mr-1 font-bold text-text">
{(playerRating / 100).toFixed(2)}
</span>
<span className="ml-1 text-xs font-bold text-text">
(max): {(highestRating / 100).toFixed(2)}
</span>
</div>
</div>
<div className="mb-2 md:mb-2">
<span className="text-xs uppercase text-text">
Over Power
</span>
<div className="flex items-center text-text">
<span className="mr-1 font-bold text-text">
{(overPowerRate / 100).toFixed(2)} %
</span>
</div>
</div>
<div className="text-xs text-text">
Last play date{" "}
<span className="font-bold">
{lastPlayDate || "Not available"}
</span>
</div>
</div>
</div>
);
})}
</div>
);
};
export default CharacterCard;

View File

@ -0,0 +1,217 @@
"use client";
import React, { useState } from "react";
import { accessory } from "@/lib/accessory";
import { UseAvatarCustomization } from "@/app/hooks/useFetchApi";
import { UsePostAvatarItemList } from "@/app/hooks/usePostApi";
UsePostAvatarItemList
type PlayerData = {
avatarBack: string;
avatarItem: string;
avatarWear: string;
avatarFront: string;
avatarSkin: string;
avatarHead: string;
avatar_skinfoot_l: string;
avatar_skinfoot_r: string;
avatarFace: string;
};
type AvatarParts = {
[key: string]: string;
};
type DropdownOption = {
label: string;
value: string;
category: string;
sortName: string;
};
type DropdownProps = {
options: DropdownOption[];
onChange: (value: string) => void;
label: string;
value: string;
};
const Dropdown: React.FC<DropdownProps & { className?: string }> = ({
options,
onChange,
label,
value,
className,
}) => {
return (
<div className={`dropdown-container relative ${className}`}>
<label className="block text-sm font-medium text-text pb-1 pt-2 ">
{label}
</label>
<div className="mt-1 relative">
<select
value={value}
onChange={(e) => onChange(e.target.value)}
className=" w-[300px] md:w-[200px] lg:w-[300px] sm:w-[200px] pl-3 pr-10 py-2 border-gray-300 focus:outline-none sm:text-sm rounded-md shadow-sm"
>
{options.map((option, index) => (
<option
key={`${option.value}-${index}`}
value={option.value}
className="text-gray-900"
>
{option.label}
</option>
))}
</select>
</div>
</div>
);
};
const AvatarCustomizationData = () => {
const [avatarCustomizationData, setAvatarCustomization] = useState<
PlayerData[]
>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
UseAvatarCustomization({ setAvatarCustomization, setLoading, setError });
const { postAvatarData } = UsePostAvatarItemList({
onPostSuccess: (data) => {
console.log("Data posted successfully:", data);
},
setLoading,
setError,
});
const getAvatarParts = (playerData: PlayerData): AvatarParts => ({
avatar_back: `${process.env.NEXT_PUBLIC_CDN}avatarAccessory/CHU_UI_Avatar_Tex_0${playerData.avatarBack}.png`,
avatar_face_static: `${process.env.NEXT_PUBLIC_CDN}avatarStatic/CHU_UI_Avatar_Tex_Face.png`,
avatar_face: `${process.env.NEXT_PUBLIC_CDN}avatarAccessory/CHU_UI_Avatar_Tex_0${playerData.avatarFace}.png`,
avatar_item_r: `${process.env.NEXT_PUBLIC_CDN}avatarAccessory/CHU_UI_Avatar_Tex_0${playerData.avatarItem}.png`,
avatar_item_l: `${process.env.NEXT_PUBLIC_CDN}avatarAccessory/CHU_UI_Avatar_Tex_0${playerData.avatarItem}.png`,
avatar_wear: `${process.env.NEXT_PUBLIC_CDN}avatarAccessory/CHU_UI_Avatar_Tex_0${playerData.avatarWear}.png`,
avatar_Front: `${process.env.NEXT_PUBLIC_CDN}avatarAccessory/CHU_UI_Avatar_Tex_0${playerData.avatarFront}.png`,
avatar_skin: `${process.env.NEXT_PUBLIC_CDN}avatarAccessory/CHU_UI_Avatar_Tex_0${playerData.avatarSkin}.png`,
avatar_head: `${process.env.NEXT_PUBLIC_CDN}avatarAccessory/CHU_UI_Avatar_Tex_0${playerData.avatarHead}.png`,
avatar_skinfoot_l: `${process.env.NEXT_PUBLIC_CDN}avatarAccessory/CHU_UI_Avatar_Tex_0${playerData.avatarSkin}.png`,
avatar_skinfoot_r: `${process.env.NEXT_PUBLIC_CDN}avatarAccessory/CHU_UI_Avatar_Tex_0${playerData.avatarSkin}.png`,
avatar_hand_r: `${process.env.NEXT_PUBLIC_CDN}avatarStatic/CHU_UI_Avatar_Tex_RightHand.png`,
avatar_hand_l: `${process.env.NEXT_PUBLIC_CDN}avatarStatic/CHU_UI_Avatar_Tex_LeftHand.png`,
});
const handleSelectionChange = (part: keyof PlayerData, value: string) => {
setAvatarCustomization(
avatarCustomizationData.map((data, index) =>
index === 0 ? { ...data, [part]: value } : data
)
);
};
const handlePostData = () => {
if (avatarCustomizationData.length > 0) {
const { avatarItem, avatarBack, avatarFace, avatarWear, avatarHead } =
avatarCustomizationData[0];
const dataToPost = {
avatarItem,
avatarBack,
avatarFace,
avatarWear,
avatarHead,
};
postAvatarData(dataToPost);
console.log("Attempting to post data", dataToPost);
}
};
if (loading) return <div></div>;
if (error) return <div>Error: {error}</div>;
if (
!Array.isArray(avatarCustomizationData) ||
avatarCustomizationData.length === 0
) {
return <div>No player data found.</div>;
}
const playerCustomization = getAvatarParts(avatarCustomizationData[0]);
const dropdownOptions: DropdownOption[] = accessory.map((option) => ({
label: option.str,
value: option.id,
category: option.category,
sortName: option.sortName,
}));
const avatarHeadOptions = dropdownOptions.filter((option) => option.category === "2");
const avatarFaceCoverOptions = dropdownOptions.filter((option) => option.category === "3");
const avatarItemOptions = dropdownOptions.filter((option) => option.category === "5");
const avatarBackOptions = dropdownOptions.filter((option) => option.category === "7");
const avatarWearOptions = dropdownOptions.filter((option) => option.category === "1");
return (
<div className="bg-crust rounded-sm w-[380px] sm:w-[700px] mx-auto">
<div className="flex flex-col md:flex-row justify-center items-center">
<div className="avatar_group w-full md:w-1/2 flex justify-center items-center">
<div className="avatar_base">
{Object.entries(playerCustomization).map(([className, src]) => (
<div className={className} key={className}>
<img src={src} alt={className} />
</div>
))}
</div>
</div>
<div className="avatar_customization_dropdowns w-full md:w-1/2 flex flex-col justify-center items-center">
<Dropdown
options={avatarHeadOptions}
onChange={(value) => handleSelectionChange("avatarHead", value)}
label="Head Options: "
value={avatarCustomizationData[0].avatarHead}
/>
<Dropdown
options={avatarFaceCoverOptions}
onChange={(value) => handleSelectionChange("avatarFace", value)}
label="Face Cover Options: "
value={avatarCustomizationData[0].avatarFace}
/>
<Dropdown
options={avatarItemOptions}
onChange={(value) => handleSelectionChange("avatarItem", value)}
label="Item Options: "
value={avatarCustomizationData[0].avatarItem}
/>
<Dropdown
options={avatarBackOptions}
onChange={(value) => handleSelectionChange("avatarBack", value)}
label="Back Options: "
value={avatarCustomizationData[0].avatarBack}
/>
<Dropdown
options={avatarWearOptions}
onChange={(value) => handleSelectionChange("avatarWear", value)}
label="Outfit Options: "
value={avatarCustomizationData[0].avatarWear}
/>
<div className="pt-4">
<button
onClick={handlePostData}
className="text-text px-3 py-2 mb-3 border border-transparent font-medium rounded-sm bg-mantle hover:bg-yellow hover:text-black focus:outline-none transition duration-150 ease-in-out whitespace-nowrap"
>
Update Avatar
</button>
</div>
</div>
</div>
</div>
);
};
export default AvatarCustomizationData;

View File

@ -0,0 +1,146 @@
/* eslint-disable @next/next/no-img-element */
"use client";
import React, { useEffect, useState } from "react";
import { mapicon } from "@/lib/mapicon";
import { usePlayerInfo } from "@/app/hooks/useFetchApi";
import { UsePostMapIcon } from "@/app/hooks/usePostApi";
type PlayerData = {
mapIconId: string;
};
type SystemVoice = {
[key: string]: string;
};
type DropdownOption = {
str: string;
id: string;
sortName: string;
imagePath: string;
};
type DropdownProps = {
options: DropdownOption[];
onChange: (value: string) => void;
label: string;
value: string;
};
const Dropdown: React.FC<DropdownProps & { className?: string }> = ({
options,
onChange,
label,
value,
className,
}) => {
return (
<div className={`dropdown-container relative ${className}`}>
<label className="block text-sm font-medium text-text pb-1 pt-2 ">
{label}
</label>
<div className="mt-1 relative">
<select
value={value}
onChange={(e) => onChange(e.target.value)}
className=" w-[300px] md:w-[200px] lg:w-[300px] sm:w-[200px] pl-3 pr-10 py-2 border-gray-300 focus:outline-none sm:text-sm rounded-md shadow-sm"
>
{options.map((option) => (
<option
key={option.id}
value={option.id}
className="text-gray-900"
>
{option.str}
</option>
))}
</select>
</div>
</div>
);
};
const PlayerMapIconComponent = () => {
const [mapIconData, setPlayerInfo] = useState<PlayerData[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
usePlayerInfo({ setPlayerInfo, setLoading, setError });
const { postMapIcon } = UsePostMapIcon({
onPostSuccess: (data) => {
console.log("Data posted successfully:", data);
},
setLoading,
setError,
});
const getSystemVoiceIcons = (playerData: PlayerData): SystemVoice => {
let mapIconStr = String(playerData.mapIconId);
mapIconStr =
mapIconStr.length < 2
? mapIconStr.padStart(2, "0")
: mapIconStr;
return {
mapIcon: `https://dean.nyc3.cdn.digitaloceanspaces.com/mapIcon/CHU_UI_MapIcon_000000${mapIconStr}.png`,
};
};
const handleSelectionChange = (part: keyof PlayerData, value: string) => {
setPlayerInfo(
mapIconData.map((data, index) =>
index === 0 ? { ...data, [part]: value } : data
)
);
};
const handlePostData = () => {
if (mapIconData.length > 0) {
const { mapIconId } = mapIconData[0];
// Construct an object with only the required fields
const dataToPost = {
mapIconId,
};
postMapIcon(dataToPost); // Post this data
console.log("Attempting to post data", dataToPost);
}
};
if (loading) return <div></div>;
if (error) return <div>Error: {error}</div>;
if (!Array.isArray(mapIconData) || mapIconData.length === 0) {
return <div>No player data found.</div>;
}
const mapIconList = getSystemVoiceIcons(mapIconData[0]);
const DEFAULT_IMAGE = "https://dean.nyc3.cdn.digitaloceanspaces.com/mapIcon/CHU_UI_MapIcon_00000001.png";
return (
<div className="bg-crust rounded-sm w-[380px] sm:w-[700px] md:flex-row justify-start pl-4 items-center ">
<img
src={mapIconList.mapIcon}
alt="Map Icons"
onError={(e) => {
e.currentTarget.src = DEFAULT_IMAGE;
}}
/>
<div className="flex flex-col items-start w-full md:w-auto">
<Dropdown
options={mapicon}
onChange={(value) => handleSelectionChange("mapIconId", value)}
label="Map Icons: "
value={mapIconData[0].mapIconId}
/>
<div className="flex items-center mt-4">
<button
onClick={handlePostData}
className="text-text px-3 py-2 mb-3 border-transparent font-medium rounded-sm bg-mantle hover:bg-yellow hover:text-black focus:outline-none transition duration-150 ease-in-out whitespace-nowrap"
>
Update Map Icon
</button>
</div>
</div>
</div>
);
};
export default PlayerMapIconComponent;

View File

@ -0,0 +1,142 @@
"use client";
import React, { useState } from "react";
import { UsePostNamePlate } from "@/app/hooks/usePostApi";
import { nameplate } from "@/lib/nameplate";
import { usePlayerInfo } from "@/app/hooks/useFetchApi";
type PlayerData = {
nameplateId: string;
};
type NamePlate = {
[key: string]: string;
};
type DropdownOption = {
str: string;
id: string;
sortName: string;
imagePath: string;
};
type DropdownProps = {
options: DropdownOption[];
onChange: (value: string) => void;
str: string;
id: string;
};
const Dropdown: React.FC<DropdownProps & { className?: string }> = ({
options,
onChange,
str,
id,
className,
}) => {
return (
<div className={`dropdown-container relative ${className}`}>
<label className="block text-sm font-medium text-text pb-1 pt-2 ">
{str}
</label>
<div className="mt-1 relative">
<select
value={id}
onChange={(e) => onChange(e.target.value)}
className="w-[300px] md:w-[200px] lg:w-[300px] sm:w-[200px] pl-3 pr-10 py-2 border-gray-300 focus:outline-none sm:text-sm rounded-md shadow-sm"
>
{options.map((option, index) => (
<option
key={`${option.id}-${index}`}
value={option.id}
className="text-gray-900"
>
{option.str}
</option>
))}
</select>
</div>
</div>
);
};
const PlayerNamePlateComponent = () => {
const [nameplateData, setPlayerInfo] = useState<PlayerData[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
usePlayerInfo({ setPlayerInfo, setLoading, setError });
const { postNamePlate } = UsePostNamePlate({
onPostSuccess: (data) => {
console.log("Data posted successfully:", data);
},
setLoading,
setError,
});
const getNamePlateIcons = (playerData: PlayerData): NamePlate => {
let namePlateStr = String(playerData.nameplateId);
const totalLength = 8;
const paddedNamePlateStr = namePlateStr.padStart(totalLength, "0");
return {
nameplateIcon: `${process.env.NEXT_PUBLIC_CDN}namePlates/CHU_UI_NamePlate_${paddedNamePlateStr}.png`,
};
};
const handleSelectionChange = (part: keyof PlayerData, value: string) => {
setPlayerInfo(
nameplateData.map((data, index) =>
index === 0 ? { ...data, [part]: value } : data
)
);
};
const handlePostData = () => {
if (nameplateData.length > 0) {
const { nameplateId } = nameplateData[0];
const dataToPost = {
nameplateId,
};
postNamePlate(dataToPost);
console.log("Attempting to post data", dataToPost);
}
};
if (loading) return <div></div>;
if (error) return <div>Error: {error}</div>;
if (!Array.isArray(nameplateData) || nameplateData.length === 0) {
return <div>No player data found.</div>;
}
const nameplateList = getNamePlateIcons(nameplateData[0]);
const DEFAULT_IMAGE = "/namePlates/CHU_UI_NamePlate_00000001.png";
return (
<div className="bg-crust rounded-sm sm w-[380px] sm:w-[700px] md:flex-row justify-start pl-4 items-center pt-4 ">
<img
className="w-[300px]"
src={nameplateList.nameplateIcon}
alt="Map Icons"
onError={(e) => {
e.currentTarget.src = DEFAULT_IMAGE;
}}
/>
<div className="flex flex-col items-start w-full md:w-auto pb-2 -mt-2">
<Dropdown
options={nameplate}
onChange={(value) => handleSelectionChange("nameplateId", value)}
str="Namplates: "
id={nameplateData[0].nameplateId}
/>
<div className="flex items-center mt-4">
<button
onClick={handlePostData}
className="text-text px-3 py-2 mb-3 border-transparent font-medium rounded-sm bg-mantle hover:bg-yellow hover:text-black focus:outline-none transition duration-150 ease-in-out whitespace-nowrap"
>
Update Nameplate
</button>
</div>
</div>
</div>
);
};
export default PlayerNamePlateComponent;

View File

@ -0,0 +1,104 @@
"use client";
import React, { useEffect, useState } from "react";
import { UsePostPlayerRival } from "@/app/hooks/usePostApi";
import axios from "axios";
import { useCookies } from "next-client-cookies";
import jwt from "jsonwebtoken";
type RivalData = {
user1: string;
user2: string;
version: number;
};
const RivalComponent = () => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [successMessage, setSuccessMessage] = useState<string | null>(null);
const [rivalData, setRivalData] = useState<RivalData>({
user1: "",
user2: "",
version: 13,
});
const { postRival } = UsePostPlayerRival({
onPostSuccess: (data) => {
// console.log("Data posted successfully:", data);
setSuccessMessage("Rival added successfully!");
setError(null);
},
setLoading,
setError,
});
const handleInputChange = (field: keyof RivalData, value: string) => {
setRivalData((prevData) => ({ ...prevData, [field]: value }));
};
const handlePostRival = () => {
if (rivalData.user1 && rivalData.user2) {
postRival({
user1: rivalData.user1,
user2: rivalData.user2,
version: rivalData.version,
});
console.log("Attempting to post rival data", rivalData);
}
};
const { get } = useCookies();
const token = get("LOGIN_INFO");
const decodedToken = jwt.decode(token as string) as { userId?: string };
useEffect(() => {
if (decodedToken.userId) {
handleInputChange("user1", decodedToken.userId);
}
}, [decodedToken.userId]);
useEffect(() => {
const successTimeout = setTimeout(() => {
setSuccessMessage(null);
}, 3000);
return () => {
clearTimeout(successTimeout);
};
}, [successMessage]);
if (!rivalData.user1) {
return null;
}
return (
<div className="bg-crust rounded-sm w-[380px] sm:w-[700px] md:flex-row justify-start pl-4 items-start pt-4 md:pt-0">
<div className="flex flex-col items-start w-full md:w-auto">
<div className="mt-1 relative">
<label className="block text-sm font-medium text-text pb-1 pt-2">
Enter Rival Aime Card:
</label>
<input
type="text"
value={rivalData.user2}
onChange={(e) => handleInputChange("user2", e.target.value)}
className="w-[300px] md:w-[200px] lg:w-[300px] sm:w-[200px] pl-3 pr-10 py-2 border-gray-300 focus:outline-none sm:text-sm rounded-md shadow-sm"
/>
</div>
{successMessage && (
<div className="text-green mt-2">{successMessage}</div>
)}
<div className="flex items-center mt-4">
<button
onClick={handlePostRival}
className="text-text px-3 py-2 mb-3 border-transparent font-medium rounded-sm bg-mantle hover:bg-yellow hover:text-black focus:outline-none transition duration-150 ease-in-out whitespace-nowrap"
>
Add Rival
</button>
</div>
</div>
</div>
);
};
export default RivalComponent;

View File

@ -0,0 +1,120 @@
"use client";
import { UsePostTrophy } from "@/app/hooks/usePostApi";
import React, { useEffect, useState } from "react";
import { trophy } from "@/lib/trophy";
import { usePlayerInfo } from "@/app/hooks/useFetchApi";
type PlayerData = {
trophyId: string;
};
type DropdownOption = {
str: string;
id: string;
rareType: string;
};
type DropdownProps = {
options: DropdownOption[];
onChange: (id: string) => void;
label: string;
id: string;
};
const Dropdown: React.FC<DropdownProps & { className?: string }> = ({
options,
onChange,
label,
id,
className,
}) => {
return (
<div className={`dropdown-container relative ${className}`}>
<label className="block text-sm font-medium text-text pb-1 pt-2 ">
{label}
</label>
<div className="mt-1 relative">
<select
value={id}
onChange={(e) => onChange(e.target.value)}
className=" w-[300px] md:w-[200px] lg:w-[300px] sm:w-[200px] pl-3 pr-10 py-2 border-gray-300 focus:outline-none sm:text-sm rounded-md shadow-sm"
>
{options.map((option, index) => (
<option
key={`${option.id}-${index}`}
value={option.id}
className="text-gray-900"
>
{option.id} {option.str}
</option>
))}
</select>
</div>
</div>
);
};
const PlayerTropyComponent = () => {
const [playerTrophyData, setPlayerInfo] = useState<PlayerData[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
usePlayerInfo({ setPlayerInfo, setLoading, setError });
const { postTrophy } = UsePostTrophy({
onPostSuccess: (data) => {
},
setLoading,
setError,
});
const handleSelectionChange = (part: keyof PlayerData, value: string) => {
setPlayerInfo(
playerTrophyData.map((data, index) =>
index === 0 ? { ...data, [part]: value } : data,
),
);
};
const handlePostData = () => {
if (playerTrophyData.length > 0) {
const { trophyId } = playerTrophyData[0];
const dataToPost = {
trophyId,
};
postTrophy(dataToPost);
}
};
if (loading) return <div></div>;
if (error) return <div>Error: {error}</div>;
if (!Array.isArray(playerTrophyData) || playerTrophyData.length === 0) {
return <div>No player data found.</div>;
}
return (
<div className="bg-crust rounded-sm w-[380px] sm:w-[700px] mx-auto flex flex-col md:flex-row justify-start pl-4 items-center pt-4 md:pt-0">
<div className="flex flex-col items- w-full md:w-auto">
<Dropdown
options={trophy}
onChange={(value) => handleSelectionChange("trophyId", value)}
label="System Trophy: "
id={playerTrophyData[0].trophyId}
/>
<div className=" mt-4">
<button
onClick={handlePostData}
className="text-text px-3 py-2 mb-3 border-transparent font-medium rounded-sm bg-mantle hover:bg-yellow hover:text-black focus:outline-none transition duration-150 ease-in-out whitespace-nowrap"
>
Update Trophy
</button>
</div>
</div>
</div>
);
};
export default PlayerTropyComponent;

View File

@ -0,0 +1,364 @@
"use client";
import React, { useEffect, useState } from "react";
import Image from "next/image";
import { useFetchPlayerScoreLog } from "@/app/hooks/useFetchApi";
interface JacketImageProps {
jacketPath: string;
}
// JacketImage Component
const JacketImage: React.FC<JacketImageProps> = ({ jacketPath }) => (
<Image
src={jacketPath}
alt="Character Image"
width={90}
height={90}
className="mt-4 ml-1 border-4 border-gray-400 border-sm"
/>
);
interface ScoreCardProps {
userPlayDate: string;
title: string;
rating_change: string;
genre: string;
score: number;
isNewRecord: number; // or number, depending on your data structure
isAllJustice: number; // or number, as appropriate
judgeJustice: number;
judgeAttack: number;
chartId: number; // or number, depending on your data
judgeGuilty: number;
artist: string;
judgeHeaven: number;
judgeCritical: number;
level: string; // assuming it's a number
isClear: number; // or number
isFullCombo: number; // or number
maxCombo: number;
jacketPath: string;
}
const ScoreCard: React.FC<ScoreCardProps> = ({
userPlayDate,
title,
rating_change,
genre,
score,
isNewRecord,
isAllJustice,
judgeJustice,
judgeAttack,
chartId,
judgeGuilty,
artist,
judgeHeaven,
judgeCritical,
level,
isClear,
isFullCombo,
maxCombo,
jacketPath,
}) => {
const formattedJacketPath = `${process.env.NEXT_PUBLIC_CDN}JacketArt/${jacketPath.slice(0, -3)}png`;
const realJusticeCritical = judgeCritical + judgeHeaven;
return (
<div className="rounded-sm bg-crust text-text h-50">
<div className="flex justify-between items-center">
<span className="text-lg text-text">{userPlayDate}</span>
<div className="flex justify-end">
<div className="flex flex-col justify-center items-end">
<div className="flex items-center">
<span
className={`justify-center p-1 text-sm font-bold text-center rounded-sm ${getDifficultyClass(
chartId
)} text-crust`}
>
{getDifficultyText(chartId)}{" "}
{level !== undefined ? level.toString() : "N/A"}{" "}
</span>
{isNewRecord !== 0 && isNewRecord ? (
<span className="p-1 ml-2 text-sm font-bold rounded-sm bg-pink text-crust">
NEW!!
</span>
) : (
<span className=""></span>
)}
</div>
</div>
</div>
</div>
<div className={`text-xs ${getRatingChangeColor(rating_change)}`}>
Rating: {rating_change}
</div>
<div className="flex">
<div className="flex items-start space-x-4">
<JacketImage jacketPath={formattedJacketPath} />
<div className="flex flex-col justify-center pt-3">
<h2 className="text-xs truncate pb-2 w-[200px] lg:w-[310px]">
{title}
</h2>
<div className="w-[140px] h-[1] overflow-hidden text-xs truncate pb-2">
{artist}
</div>
<div className="text-xs">{genre}</div>
</div>
</div>
</div>
<div className="pt-4 pl-1">
<button
className={`bg-yellow font-bold mr-2 text-crust px-2 py-1 rounded-sm text-sm shadow-lg ${isFullCombo ? "bg-blue-500" : isAllJustice ? "bg-green-500" : ""
}`}
>
{isAllJustice
? "All Justice"
: isFullCombo
? "Full Combo"
: `Combo: ${maxCombo}`}
</button>
<button
className={`bg-yellow font-bold mr-2 text-crust px-4 py-1 rounded-sm text-sm shadow-lg ${isClear === 0 ? "bg-red-500" : ""
}`}
>
{isClear === 1 ? "CLEAR" : "UNCLEARED"}
</button>
<button className="px-4 py-1 text-sm font-bold rounded-sm shadow-lg bg-yellow text-crust">
{getGrade(score)}
</button>
</div>
<div className="flex justify-start items-center pt-2">
<div className="pr-1 text-xs text-yellow md:pr-2">
Score: {score.toLocaleString()}
</div>
<div className="flex justify-start items-center">
<div className="pr-1 text-xs text-yellow md:pr-2">
Justice Critical: {realJusticeCritical}
</div>
<div className="pr-1 text-xs text-orange-400 md:pr-2">
Justice: {judgeJustice}
</div>
<div className="pr-1 text-xs text-green md:pr-2">
Attack: {judgeAttack}
</div>
<div className="text-xs text-gray">Miss: {judgeGuilty}</div>
</div>
</div>
</div>
);
};
// Helper functions
const getDifficultyClass = (difficulty: any) => {
if (difficulty === undefined || difficulty === null) {
// Handle undefined or null difficulty
// You can return a default class or handle the error as needed
return "default-class"; // Replace with an appropriate default class or error handling
}
switch (difficulty.toString()) {
case "0":
return "bg-green"; // Green for easy
case "1":
return "bg-yellow-300"; // Yellow for hard
case "2":
return "bg-red"; // Red for expert
case "3":
return "bg-mauve"; // Purple for master
case "4":
return "bg-[radial-gradient(ellipse_at_top_left,_var(--tw-gradient-stops))] from-black via-red to-black"; // Gradient for another level
case "5":
return "bg-teal"; // Teal for another level
default:
return "default-class"; // Replace with an appropriate default class for unknown difficulty
}
};
const getGrade = (score: number) => {
if (score >= 1009000) return "SSS+";
if (score >= 1007500 && score <= 1008999) return "SSS";
if (score >= 1005000 && score <= 1007499) return "SS+";
if (score >= 1000000 && score <= 1004999) return "SS";
if (score >= 990000 && score <= 999999) return "S+";
if (score >= 975000 && score <= 990000) return "S";
if (score >= 950000 && score <= 974999) return "AAA";
if (score >= 925000 && score <= 949999) return "AA";
if (score >= 900000 && score <= 924999) return "A";
if (score >= 800000 && score <= 899999) return "BBB";
if (score >= 700000 && score <= 799999) return "BB";
if (score >= 600000 && score <= 699999) return "B";
if (score >= 500000 && score <= 599999) return "C";
if (score < 500000) return "D";
return "";
};
const getDifficultyText = (chartId: any) => {
switch (chartId) {
case 0:
return "EASY"; // Text for any other difficulty
case 1:
return "ADVANCE";
case 2:
return "EXPERT";
case 3:
return "MASTER";
case 4:
return "ULTIMA";
case 5:
return "WORLDS END";
}
};
const getRatingChangeColor = (ratingChange: string) => {
switch (ratingChange) {
case "Increase":
return "text-green"; // Green for Increase
case "Same":
return "text-blue"; // Blue for Same
case "Decrease":
return "text-red"; // Red for Decrease
default:
return "text-gray"; // Default color
}
};
interface NavigationButtonsProps {
currentPage: number;
totalPages: number;
onPageChange: (page: number) => void;
onNext: () => void;
onPrevious: () => void;
}
// NavigationButtons Component
const NavigationButtons: React.FC<NavigationButtonsProps> = ({
currentPage,
totalPages,
onPageChange,
onNext,
onPrevious,
}) => {
// Only show a maximum of 5 page buttons around the current page
const rangeStart = 5 * Math.floor((currentPage - 1) / 5) + 1;
const rangeEnd = Math.min(rangeStart + 4, totalPages);
const pages = Array.from(
{ length: rangeEnd - rangeStart + 1 },
(_, index) => rangeStart + index
);
return (
<div className="flex justify-center items-center space-x-1">
<button
onClick={onPrevious}
disabled={currentPage === 1}
className="px-4 font-bold bg-blue-500 rounded hover:bg-blue-700 text-text disabled:opacity-50"
>
Previous
</button>
{pages.map((page) => (
<button
key={page}
onClick={() => onPageChange(page)}
disabled={currentPage === page}
className={`bg-blue-500 hover:bg-blue-700 text-white font-bold px-2 rounded ${currentPage === page ? "bg-blue" : ""
}`}
>
{page}
</button>
))}
<button
onClick={onNext}
disabled={currentPage === totalPages}
className="px-4 font-bold text-white bg-blue-500 rounded hover:bg-blue-700 disabled:opacity-50"
>
Next
</button>
</div>
);
};
// ScoreCardList Component
const ScoreCardList = () => {
const [profileData, setPlayerScoreLog] = useState<any[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const [itemsPerPage] = useState<number>(9);
const [currentPage, setCurrentPage] = useState<number>(1);
const [searchQuery, setSearchQuery] = useState("");
const [filteredData, setFilteredData] = useState<any[]>([]);
useFetchPlayerScoreLog({ setPlayerScoreLog, setLoading, setError });
useEffect(() => {
const filtered = profileData.filter((item) => {
const queryLower = searchQuery.toLowerCase();
return item.title && item.title.toLowerCase().includes(queryLower);
});
setFilteredData(filtered);
}, [searchQuery, profileData]);
const totalPages = Math.ceil(filteredData.length / itemsPerPage);
// Get current items for the current page
const indexLastItem = currentPage * itemsPerPage;
const indexFirstItem = indexLastItem - itemsPerPage;
const currentItems = filteredData.slice(indexFirstItem, indexLastItem);
// Go to the next page
const handleNext = () => {
setCurrentPage((prevCurrentPage) =>
Math.min(prevCurrentPage + 1, totalPages)
);
};
// Go to the previous page
const handlePrevious = () => {
setCurrentPage((prevCurrentPage) => Math.max(prevCurrentPage - 1, 1));
};
// Go to the specific page
const handlePageChange = (page: number) => {
setCurrentPage(page);
};
if (loading) {
return <div></div>; // Display loading state
}
if (error) {
return <div>Error: {error}</div>; // Display error state
}
return (
<div className="w-fullsm:w-[650px] md:w-[850px] lg:w-[700px] xl:w-[900px] 2xl:w-[1400px]">
<div className="my-2 w">
<input
type="text"
placeholder="Search by title, artist, or level"
className="w-full bg-transparent border-b border-gray-300 transition duration-300 ease-in-out focus:outline-none text-text"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
<div className="sm:w-[650px] md:w-[850px] lg:w-[700px] xl:w-[900px] 2xl:w-[1400px] grid grid-cols-1 sm:grid-cols-1 md:grid-cols-1 lg:grid-cols-1 xl:grid-cols-1 2xl:grid-cols-3 gap-2 gap-y-0">
{currentItems.map((scoreCardInfo, index) => (
<div key={index} className="p-2 mb-2 rounded-sm shadow-lg bg-crust">
<ScoreCard {...scoreCardInfo} />
</div>
))}
</div>
<div className="flex justify-around ">
<div className="py-2 rounded-md bg-crust ">
<NavigationButtons
currentPage={currentPage}
totalPages={totalPages}
onPageChange={handlePageChange}
onNext={handleNext}
onPrevious={handlePrevious}
/>
</div>
</div>
</div>
);
};
export default ScoreCardList;

View File

@ -0,0 +1,157 @@
/* eslint-disable @next/next/no-img-element */
"use client";
import React, { useEffect, useState } from "react";
import { UsePostSystemVoice } from "@/app/hooks/usePostApi";
import { systemvoice } from "@/lib/systemvoice";
import { UseSystemVoice } from "@/app/hooks/useFetchApi";
import AudioPlayer from "../shared/audioPlayer/page";
type PlayerData = {
voiceId: string;
};
type SystemVoice = {
[key: string]: string;
};
type DropdownOption = {
str: string;
id: string;
sortName: string;
imagePath: string;
};
type DropdownProps = {
options: DropdownOption[];
onChange: (id: string) => void;
str: string;
id: string;
sortName: string;
};
const Dropdown: React.FC<DropdownProps & { className?: string }> = ({
options,
onChange,
str,
id,
className,
}) => {
return (
<div className={`dropdown-container relative ${className}`}>
<label className="block text-sm font-medium text-text pb-1 pt-2 ">
{str}
</label>
<div className="mt-1 relative">
<select
value={id}
onChange={(e) => onChange(e.target.value)}
className=" w-[300px] md:w-[200px] lg:w-[300px] sm:w-[200px] pl-3 pr-10 py-2 border-gray-300 focus:outline-none sm:text-sm rounded-md shadow-sm"
>
{options.map((option, index) => (
<option
key={`${option.id}-${index}`}
value={option.id}
className="text-gray-900"
>
{option.str}
</option>
))}
</select>
</div>
</div>
);
};
const SystemVoiceComponent = () => {
const [systemVoiceData, setSystemVoice] = useState<PlayerData[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
UseSystemVoice({ setSystemVoice, setLoading, setError });
const { postVoiceID } = UsePostSystemVoice({
onPostSuccess: (data) => {
console.log("Data posted successfully:", data);
},
setLoading,
setError,
});
const getSystemVoiceIcons = (playerData: PlayerData): SystemVoice => {
let systemVoiceStr = String(playerData.voiceId);
systemVoiceStr =
systemVoiceStr.length < 2
? systemVoiceStr.padStart(2, "0")
: systemVoiceStr;
return {
systemVoice: `${process.env.NEXT_PUBLIC_CDN}systemVoiceThumbnails/CHU_UI_SystemVoice_000000${systemVoiceStr}.png`,
audio: `${process.env.NEXT_PUBLIC_CDN}systemVoice/systemvoice00${systemVoiceStr}/00001.wav`,
};
};
const handleSelectionChange = (part: keyof PlayerData, id: string) => {
setSystemVoice(
systemVoiceData.map((data, index) =>
index === 0 ? { ...data, [part]: id } : data
)
);
};
const handlePostData = () => {
if (systemVoiceData.length > 0) {
const { voiceId } = systemVoiceData[0];
// Construct an object with only the required fields
const dataToPost = {
voiceId,
};
postVoiceID(dataToPost); // Post this data
console.log("Attempting to post data", dataToPost);
}
};
if (loading) return <div></div>;
if (error) return <div>Error: {error}</div>;
if (!Array.isArray(systemVoiceData) || systemVoiceData.length === 0) {
return <div>No player data found.</div>;
}
const SystemVoiceList = getSystemVoiceIcons(systemVoiceData[0]);
const DEFAULT_IMAGE = `${process.env.NEXT_PUBLIC_CDN}chusan_systemVoices/CHU_UI_SystemVoice_00000001.png`;
return (
<div className="bg-crust rounded-sm w-[380px] sm:w-[700px] md:flex-row justify-start pl-4 items-start pt-4 md:pt-0">
<img
src={SystemVoiceList.systemVoice}
alt="System Voice"
onError={(e) => {
e.currentTarget.src = DEFAULT_IMAGE;
}}
className="pt-2 md:mb-0 md:mr-4 self-center"
/>
<div className="flex flex-col items-start w-full md:w-auto">
<Dropdown
options={systemvoice}
onChange={(value) => handleSelectionChange("voiceId", value)}
str="System Voice Options: "
sortName=""
id={systemVoiceData[0].voiceId}
/>
<div className="flex items-center mt-4">
<button
onClick={handlePostData}
className="text-text px-3 py-2 mb-3 border-transparent font-medium rounded-sm bg-mantle hover:bg-yellow hover:text-black focus:outline-none transition duration-150 ease-in-out whitespace-nowrap"
>
Update System Voice
</button>
<div>
<AudioPlayer src={SystemVoiceList.audio} />
</div>
</div>
</div>
</div>
);
};
export default SystemVoiceComponent;

View File

@ -0,0 +1,107 @@
"use client";
import React, { useEffect, useState } from "react";
import Image from "next/image";
import { useBestTop } from "@/app/hooks/useFetchApi";
const PlayerInfo = () => {
const [bestTop, setBestTop] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [selectedSegment, setSelectedSegment] = useState("Top30"); // Set "Top30" as the default
const [displayedData, setDisplayedData] = useState<any[]>([]);
useBestTop({ setBestTop, setLoading, setError });
useEffect(() => {
const sortedData = [...bestTop].sort((a, b) => b.rating - a.rating);
if (selectedSegment === "Recent10") {
setDisplayedData(sortedData.slice(0, 10));
} else {
const increasedRatingData = sortedData.filter(
(entry) =>
entry.rating_change === "Increase" ||
entry.score_change === "Increase"
);
const uniqueData = increasedRatingData.filter(
(entry, index, self) =>
index === self.findIndex((e) => e.title === entry.title)
);
setDisplayedData(uniqueData.slice(0, 30));
}
}, [bestTop, selectedSegment]);
return (
<div className="md:px-0 md:mx-auto justify-center">
<div className="flex justify-end mb-4">
<div className="inline-flex rounded-md shadow-sm" role="group">
<button
onClick={() => setSelectedSegment("Top30")}
className={`${selectedSegment === "Top30"
? "bg-yellow text-black shadow"
: "bg-crust text-text hover:bg-mantle"
} text-sm font-medium py-2 px-4 rounded-l-lg focus:outline-none transition-colors duration-300`}
>
Top 30 Scores
</button>
<button
onClick={() => setSelectedSegment("Recent10")}
className={`${selectedSegment === "Recent10"
? "bg-yellow shadow"
: "bg-crust text-text hover:bg-mantle"
} text-sm font-medium py-2 px-4 rounded-r-lg focus:outline-none transition-colors duration-300`}
>
Recent 10 Scores
</button>
</div>
</div>
<div>
{loading && <div></div>}
{error && <div>Error: {error}</div>}
<div style={{ height: "1095px", overflowY: "auto" }}>
{displayedData.map((user, index) => {
const formattedJacketPath = `${process.env.NEXT_PUBLIC_CDN}JacketArt/${user.jacketPath.slice(
0,
-3
)}png`;
return (
<div
key={index}
className="bg-crust p-2 rounded-sm relative mb-4 flex items-center"
>
<div className="text-maroon text-lg font-bold flex items-center pr-2">
{index + 1}.
</div>
<div className="flex-none">
<Image
src={formattedJacketPath}
alt={`${user.title} Jacket Art`}
width={90}
height={90}
className="border-sm border-4 border-gray-400"
/>
</div>
<div className="flex-grow pl-2">
<div className="text-maroon "> {user.title}</div>
<div className="text-text pt-1">
{user.level}
<span className="text-red">
{" "}
{(user.rating / 100).toFixed(2)}
</span>
</div>
<div className="text-yellow pt-1">
{user.score.toLocaleString()}
</div>
</div>
</div>
);
})}
</div>
</div>
</div>
);
};
export default PlayerInfo;

View File

@ -0,0 +1,144 @@
/* eslint-disable @next/next/no-img-element */
"use client";
import React, { useState, useEffect } from "react";
import { UsePlayerTeams } from "@/app/hooks/useFetchApi";
import { UsePostPlayerTeamProfile } from "@/app/hooks/usePostApi";
import { UsePostPlayerTeam } from "@/app/hooks/usePostApi";
type PlayerData = {
teamName: string;
id: string;
};
const PlayerTeamComponent = () => {
const [playerTeamData, setPlayerTeams] = useState<PlayerData[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [newTeamName, setNewTeamName] = useState<string>("");
const [selectedTeam, setSelectedTeam] = useState<string>("");
const [successMessage, setSuccessMessage] = useState<string | null>(null);
const [refreshTeams, setRefreshTeams] = useState(false);
UsePlayerTeams({ setPlayerTeams, setLoading, setError });
const { postTeamName } = UsePostPlayerTeam({
onPostSuccess: (data) => {
console.log("Data posted successfully:", data);
setSuccessMessage("Team created successfully!");
setTimeout(() => {
setSuccessMessage(null);
}, 3000);
setNewTeamName("");
setPlayerTeams(data.teams);
},
setLoading,
setError,
});
const { postTeamNameProfile } = UsePostPlayerTeamProfile({
onPostSuccess: (data) => {
console.log("Player team profile updated successfully:", data);
},
setLoading,
setError,
});
const handlePostData = () => {
if (newTeamName.trim() !== "") {
const isTeamNameExists = playerTeamData.some(
(team) => team.teamName.toLowerCase() === newTeamName.toLowerCase()
);
if (isTeamNameExists) {
setError("Team name already exists. Please choose a different name.");
setSuccessMessage(null);
setTimeout(() => {
setError(null);
}, 3000);
return;
}
const dataToPost = { teamName: newTeamName };
postTeamName(dataToPost);
console.log("Attempting to post data", dataToPost);
}
};
const handleSelectTeam = (e: React.ChangeEvent<HTMLSelectElement>) => {
setSelectedTeam(e.target.value);
};
const handlePostPlayerTeamProfile = () => {
if (selectedTeam) {
const dataToPost = { teamId: selectedTeam };
postTeamNameProfile(dataToPost);
console.log("Posting player team profile data", dataToPost);
} else {
console.error("No team selected");
}
};
useEffect(() => {
if (refreshTeams) {
setRefreshTeams(false);
}
}, [refreshTeams]);
if (loading) return <div>Loading...</div>;
return (
<div className="bg-crust rounded-sm w-[380px] sm:w-[700px] mx-auto flex flex-col justify-start items-start p-4">
<div className="flex flex-col w-full">
<div className="flex items-center mb-4">
<input
type="text"
placeholder="Enter Team Name"
value={newTeamName}
onChange={(e) => setNewTeamName(e.target.value)}
className="w-[150px] md:w-[200px] lg:w-[200px] sm:w-[200px] pl-3 py-2 border-gray-300 focus:outline-none sm:text-sm rounded-md shadow-sm"
/>
<div className="pl-2">
<button
onClick={handlePostData}
className="text-text py-2 border-transparent font-medium rounded-sm bg-mantle hover:bg-yellow hover:text-black focus:outline-none transition duration-150 ease-in-out w-[190px] "
>
Create Team
</button>
</div>
</div>
<div className="flex items-center mb-4">
<select
value={selectedTeam}
onChange={handleSelectTeam}
className="w-[150px] md:w-[200px] lg:w-[200px] sm:w-[200px] pl-3 py-2 border-gray-300 focus:outline-none sm:text-sm rounded-md shadow-sm"
>
<option value="">Select a Team</option>
{playerTeamData.map((team) => (
<option key={team.id} value={team.id}>
{team.teamName}
</option>
))}
</select>
<div className="pl-5 md:pl-2 lg:pl-2 xl:pl-2">
<button
onClick={handlePostPlayerTeamProfile}
className="text-text py-2 border-transparent font-medium rounded-sm bg-mantle hover:bg-yellow hover:text-black focus:outline-none transition duration-150 ease-in-out w-[190px]"
>
Set Player Team
</button>
</div>
</div>
{successMessage && (
<div className="text-green mb-2">{successMessage}</div>
)}
{error && <div className="text-red mb-2">{error}</div>}
</div>
</div>
);
};
export default PlayerTeamComponent;

View File

@ -0,0 +1,61 @@
// LogoutButton.jsx
import { serialize } from "cookie";
import axios, { AxiosError } from "axios";
import { useRouter } from "next/navigation";
const removeCookie = (cookieName: string): string =>
serialize(cookieName, "", {
httpOnly: true, // Change to true for better security
secure: process.env.NODE_ENV === "production",
sameSite: "strict",
maxAge: -1,
path: "/",
});
const removeLoginInfoCookie = async (): Promise<void> => {
const serializedToken = removeCookie("LOGIN_INFO");
try {
await fetch("/api/auth/logout", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
// Remove the LOGIN_INFO cookie
document.cookie = serializedToken;
} catch (e) {
const error = e as AxiosError;
// Handle errors if needed
console.error("Logout failed:", error);
}
};
const LogoutButton = () => {
const { push } = useRouter();
const handleLogout = async () => {
try {
console.log("Logging out...");
await removeLoginInfoCookie();
console.log("Logout successful.");
push("/");
} catch (error) {
console.error("Logout failed:", error);
}
};
return (
<main>
<button
onClick={handleLogout}
className="pl-4 text-text font-bold uppercase hover:text-blue"
>
Logout
</button>
</main>
);
};
export default LogoutButton;

View File

@ -0,0 +1,85 @@
"use client"
import { useState } from 'react';
import Link from 'next/link';
import LogoutButton from '../LogoutButton/Page';
const NavigationBar = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
let touchStartX = 0;
const handleTouchStart = (e: any) => {
touchStartX = e.touches[0].clientX;
};
const handleTouchEnd = (e: any) => {
const touchEndX = e.changedTouches[0].clientX;
// Close menu if swipe left (startX is greater than endX)
if (touchStartX > touchEndX + 50) {
setIsMenuOpen(false);
};
};
return (
<div>
<nav className="flex z-50 justify-between items-center p-5 mt-1 rounded-sm bg-crust">
{/* Hamburger Icon */}
<div className="z-50 md:hidden" onClick={() => setIsMenuOpen(true)}>
<svg
className="w-6 h-6"
fill="none"
stroke="#CAD3F5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16m-7 6h7"
/>
</svg>
</div>
<div className="hidden flex-1 justify-end md:flex">
{/* <Link href="/dashboard" className="pl-2 font-bold uppercase text-text hover:text-blue">Home</Link> */}
<Link href="/chunithm" className="pl-2 font-bold uppercase text-text hover:text-blue">CHUNITHM SCORES</Link>
<Link href="/userbox" className="pl-2 font-bold uppercase text-text hover:text-blue">CHUNITHM USERBOX</Link>
{/* <Link href="/maimai" className="pl-2 font-bold uppercase text-text hover:text-blue">MAIMAI</Link>
<Link href="/diva" className="pl-2 font-bold uppercase text-text hover:text-blue">PROJECT DIVA</Link>
<Link href="/arcade" className="pl-2 font-bold uppercase text-text hover:text-blue">ARCADE MANAGEMENT</Link> */}
<LogoutButton />
</div>
</nav>
{/* Side Menu */}
<div
className={`fixed top-0 left-0 w-64 h-full bg-mantle transform ease-in-out transition-all duration-300 z-300 ${isMenuOpen ? 'translate-x-0 ' : '-translate-x-full'}`}
onTouchStart={handleTouchStart}
onTouchEnd={handleTouchEnd}
> <div className="flex flex-col mt-10">
{/* <Link href="/dashboard" className="pb-2 pl-2 font-bold uppercase text-text hover:text-blue">Home</Link> */}
<Link href="/chunithm" className="pb-2 pl-4 font-bold uppercase text-text hover:text-blue">CHUNITHM</Link>
<Link href="/userbox" className="pb-2 pl-4 font-bold uppercase text-text hover:text-blue">USERBOX</Link>
{/* <Link href="/maimai" className="pb-2 pl-2 font-bold uppercase text-text hover:text-blue">MAIMAI</Link>
<Link href="/diva" className="pb-2 pl-2 font-bold uppercase text-text hover:text-blue">PROJECT DIVA</Link>
<Link href="/arcade" className="pb-2 pl-2 font-bold uppercase text-text hover:text-blue">ARCADE MANAGEMENT</Link> */}
<div className='pb-2'>
<LogoutButton />
</div>
</div>
<button className="pb-2 pl-4 font-bold uppercase text-text hover:text-blue" onClick={() => setIsMenuOpen(false)}>CLOSE MENU</button>
</div>
{/* Overlay */}
{isMenuOpen && (
<div className="fixed inset-0 z-30 bg-black bg-opacity-50" onClick={() => setIsMenuOpen(false)}></div>
)}
</div>
);
};
export default NavigationBar;

View File

@ -0,0 +1,88 @@
"use client";
import React, { useState, useEffect, useRef } from "react";
interface AudioPlayerProps {
src: string; // Define the type for src here
}
const AudioPlayer: React.FC<AudioPlayerProps> = ({ src }) => {
const audioRef = useRef(new Audio(src));
const [isPlaying, setIsPlaying] = useState(false);
const [progress, setProgress] = useState(0); // Progress bar state
const togglePlayPause = () => {
const audio = audioRef.current;
if (isPlaying) {
audio.pause();
} else {
audio.play();
}
setIsPlaying(!isPlaying);
};
// Update the progress as the audio plays
const onPlaying = () => {
const audio = audioRef.current;
setProgress((audio.currentTime / audio.duration) * 100);
};
// Seek the audio when the progress bar is clicked
const onProgressClick = (e: any) => {
const audio = audioRef.current;
const clickX = e.nativeEvent.offsetX;
const width = e.target.clientWidth;
const duration = audio.duration;
audio.currentTime = (clickX / width) * duration;
};
useEffect(() => {
const audio = audioRef.current;
audio.addEventListener("play", () => setIsPlaying(true));
audio.addEventListener("pause", () => setIsPlaying(false));
audio.addEventListener("timeupdate", onPlaying); // Add this line
return () => {
audio.removeEventListener("play", () => setIsPlaying(true));
audio.removeEventListener("pause", () => setIsPlaying(false));
audio.removeEventListener("timeupdate", onPlaying); // And this line
};
}, []);
return (
<div className="flex flex-col items-end">
<div className="flex pb-3 pl-2 ">
<button onClick={togglePlayPause} className="focus:outline-none text">
{isPlaying ? (
<svg
xmlns="http://www.w3.org/2000/svg"
height="20"
viewBox="0 0 320 512"
className="w-6 h-6 icon-color"
>
<path d="M48 64C21.5 64 0 85.5 0 112V400c0 26.5 21.5 48 48 48H80c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H48zm192 0c-26.5 0-48 21.5-48 48V400c0 26.5 21.5 48 48 48h32c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H240z" />
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
height="20"
viewBox="0 0 384 512"
className="w-6 h-6 icon-color"
>
<path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z" />
</svg>
)}
</button>
{/* <div
onClick={onProgressClick}
className="w-full bg-gray-300 rounded-full h-1.5 cursor-pointer"
>
<div
className="bg-yellow h-1.5 rounded-full"
style={{ width: `${progress}%` }}
></div>
</div> */}
</div>
</div>
);
};
export default AudioPlayer;

View File

@ -0,0 +1,7 @@
'use client';
import { CookiesProvider } from 'next-client-cookies';
export const ClientCookiesProvider: typeof CookiesProvider = (props) => (
<CookiesProvider {...props} />
);

View File

@ -0,0 +1,126 @@
"use client";
import React, { useState } from "react";
import jwt from "jsonwebtoken";
import { useCookies } from "next-client-cookies";
import { UsePostNewKeychip } from "@/app/hooks/usePostApi";
const NewKeychipComponent = () => {
const { get } = useCookies();
const token = get("LOGIN_INFO");
const decodedToken = jwt.decode(token as string) as { userId?: string };
const initialKeychipData = {
arcade_nickname: "",
name: "",
serial: "",
namcopcbid: "",
user: `${decodedToken.userId}`,
};
const [keychipData, setKeychipData] = useState(initialKeychipData);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [accessCodeError, setAccessCodeError] = useState<string | null>(null);
const [successMessage, setSuccessMessage] = useState<string>("");
const { createNewKeychip } = UsePostNewKeychip({
onPostSuccess: (data) => {
console.log("Keychip created successfully:", data);
setSuccessMessage("Keychip created successfully!");
setKeychipData(initialKeychipData);
setAccessCodeError(null);
},
setLoading,
setError,
});
const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>,
) => {
setKeychipData({ ...keychipData, [e.target.name]: e.target.value });
};
const allowedUserIds = ["10000", "10011"];
const handleSubmit = () => {
if (allowedUserIds.includes(keychipData.user)) {
createNewKeychip(keychipData);
console.log("Submitting keychip data", keychipData);
} else {
setAccessCodeError("Invalid access code. Please check and try again.");
}
};
const generateRandomSerial = () => {
let uniqueNumbers = "";
while (uniqueNumbers.length < 4) {
const digit = Math.floor(Math.random() * 10);
if (!uniqueNumbers.includes(digit.toString())) {
uniqueNumbers += digit;
}
}
const randomNumbers = Math.floor(1000 + Math.random() * 9000);
const randomSerial = `A69E01A${uniqueNumbers}${randomNumbers}`;
setKeychipData({ ...keychipData, serial: randomSerial });
};
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!allowedUserIds.includes(keychipData.user)) {
return <div></div>;
}
return (
<div className="container mx-auto p-6 max-w-md bg-crust rounded-sm">
<h2 className="text-lg font-semibold text-text mb-4">
Create New Keychip
</h2>
{successMessage && (
<div className="text-green mb-4">{successMessage}</div>
)}
{accessCodeError && (
<div className="text-red-500 mb-4">{accessCodeError}</div>
)}
<div>
<input
type="text"
name="name"
value={keychipData.name}
onChange={handleChange}
placeholder="Arcade Name"
className="w-full p-2 mb-4 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<input
type="text"
name="arcade_nickname"
value={keychipData.arcade_nickname}
onChange={handleChange}
placeholder="Arcade Nickname"
className="w-full p-2 mb-4 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<input
type="text"
name="serial"
value={keychipData.serial}
onChange={handleChange}
placeholder="Serial Number"
className="w-full p-2 mb-4 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<button
onClick={generateRandomSerial}
className="w-full bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded-md transition duration-300 mb-4"
>
Generate Random Serial
</button>
<button
onClick={handleSubmit}
className="w-full bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-md transition duration-300"
>
Create New Keychip
</button>
</div>
</div>
);
};
export default NewKeychipComponent;

2
src/constants/index.ts Normal file
View File

@ -0,0 +1,2 @@
export const COOKIE_NAME = "LOGIN_INFO";
export const MAX_EXPIRE_AGE = 60 * 60 * 24 * 7; // 7 days

461
src/lib/accessory.ts Normal file
View File

@ -0,0 +1,461 @@
export const accessory = [
{ id: `1100001`, str: `ノーマル`, imagePath: `CHU_UI_Avatar_Icon_01100001.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `1200001`, str: `ノーマル`, imagePath: `CHU_UI_Avatar_Icon_01200001.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `1300001`, str: `ノーマル`, imagePath: `CHU_UI_Avatar_Icon_01300001.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `1400001`, str: `ノーマル`, imagePath: `CHU_UI_Avatar_Icon_01400001.dds`, sortName: ``, category: `4`, netOpenName: `v2_10 00_0` },
{ id: `1500001`, str: `ノーマル`, imagePath: `CHU_UI_Avatar_Icon_01500001.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `1600001`, str: `ノーマル`, imagePath: `CHU_UI_Avatar_Icon_01600001.dds`, sortName: ``, category: `6`, netOpenName: `v2_10 00_0` },
{ id: `1700001`, str: `ノーマル`, imagePath: `CHU_UI_Avatar_Icon_01700001.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `2100001`, str: `Tシャツ「CHUNITHM」`, imagePath: `CHU_UI_Avatar_Icon_02100001.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100002`, str: `Tシャツ「CHUNITHM AIR」`, imagePath: `CHU_UI_Avatar_Icon_02100002.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100003`, str: `Tシャツ「CHUNITHM STAR」`, imagePath: `CHU_UI_Avatar_Icon_02100003.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100004`, str: `Tシャツ「CHUNITHM AMAZON」`, imagePath: `CHU_UI_Avatar_Icon_02100004.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100005`, str: `Tシャツ「CHUNITHM CRYSTAL」`, imagePath: `CHU_UI_Avatar_Icon_02100005.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100006`, str: `Tシャツ「CHUNITHM PARADISE」`, imagePath: `CHU_UI_Avatar_Icon_02100006.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100007`, str: `Tシャツ「CHUNITHM NEW」`, imagePath: `CHU_UI_Avatar_Icon_02100007.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100008`, str: `Tシャツ「maimai」`, imagePath: `CHU_UI_Avatar_Icon_02100008.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100009`, str: `Tシャツ「maimai GreeN」`, imagePath: `CHU_UI_Avatar_Icon_02100009.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100010`, str: `Tシャツ「maimai ORANGE」`, imagePath: `CHU_UI_Avatar_Icon_02100010.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100011`, str: `Tシャツ「maimai PiNK」`, imagePath: `CHU_UI_Avatar_Icon_02100011.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100012`, str: `Tシャツ「maimai MURASAKi」`, imagePath: `CHU_UI_Avatar_Icon_02100012.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100013`, str: `Tシャツ「maimai MiLK」`, imagePath: `CHU_UI_Avatar_Icon_02100013.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100014`, str: `Tシャツ「maimai FiNALE」`, imagePath: `CHU_UI_Avatar_Icon_02100014.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100015`, str: `Tシャツ「maimai でらっくす」`, imagePath: `CHU_UI_Avatar_Icon_02100015.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100016`, str: `Tシャツ「maimai でらっくす Splash」`, imagePath: `CHU_UI_Avatar_Icon_02100016.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100017`, str: `Tシャツ「オンゲキ」`, imagePath: `CHU_UI_Avatar_Icon_02100017.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100018`, str: `Tシャツ「オンゲキ SUMMER」`, imagePath: `CHU_UI_Avatar_Icon_02100018.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100019`, str: `Tシャツ「オンゲキ R.E.D.」`, imagePath: `CHU_UI_Avatar_Icon_02100019.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100020`, str: `Tシャツ「ゲキチュウマイ」`, imagePath: `CHU_UI_Avatar_Icon_02100020.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100021`, str: `Tシャツ「イロドリミドリ」`, imagePath: `CHU_UI_Avatar_Icon_02100021.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100022`, str: `Tシャツ「イロドリミドリ 2nd season」`, imagePath: `CHU_UI_Avatar_Icon_02100022.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100023`, str: `Tシャツ「FULL COMBO」`, imagePath: `CHU_UI_Avatar_Icon_02100023.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100024`, str: `Tシャツ「ALL JUSTICE」`, imagePath: `CHU_UI_Avatar_Icon_02100024.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100025`, str: `Tシャツ「FULL CHAIN」`, imagePath: `CHU_UI_Avatar_Icon_02100025.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100026`, str: `Tシャツ「TAP」`, imagePath: `CHU_UI_Avatar_Icon_02100026.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100027`, str: `Tシャツ「ExTAP」`, imagePath: `CHU_UI_Avatar_Icon_02100027.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100028`, str: `Tシャツ「やべー ExTAP」`, imagePath: `CHU_UI_Avatar_Icon_02100028.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100029`, str: `Tシャツ「HOLD」`, imagePath: `CHU_UI_Avatar_Icon_02100029.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100030`, str: `Tシャツ「SLIDE」`, imagePath: `CHU_UI_Avatar_Icon_02100030.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100031`, str: `Tシャツ「イカす SLIDE」`, imagePath: `CHU_UI_Avatar_Icon_02100031.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100032`, str: `Tシャツ「FLICK」`, imagePath: `CHU_UI_Avatar_Icon_02100032.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100033`, str: `Tシャツ「AIR(上)」`, imagePath: `CHU_UI_Avatar_Icon_02100033.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100034`, str: `Tシャツ「AIR(下)」`, imagePath: `CHU_UI_Avatar_Icon_02100034.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100035`, str: `Tシャツ「AIR-HOLD」`, imagePath: `CHU_UI_Avatar_Icon_02100035.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100036`, str: `Tシャツ「AIR-SLIDE」`, imagePath: `CHU_UI_Avatar_Icon_02100036.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100037`, str: `Tシャツ「AIR-ACTION」`, imagePath: `CHU_UI_Avatar_Icon_02100037.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100038`, str: `Tシャツ「AIR-CRASH」`, imagePath: `CHU_UI_Avatar_Icon_02100038.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100039`, str: `Tシャツ「ダメージーツ」`, imagePath: `CHU_UI_Avatar_Icon_02100039.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100040`, str: `Tシャツ「ドルチェ」`, imagePath: `CHU_UI_Avatar_Icon_02100040.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100041`, str: `Tシャツ「マイル」`, imagePath: `CHU_UI_Avatar_Icon_02100041.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100042`, str: `Tシャツ「ベガス」`, imagePath: `CHU_UI_Avatar_Icon_02100042.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100043`, str: `Tシャツ「ミート」`, imagePath: `CHU_UI_Avatar_Icon_02100043.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100044`, str: `Tシャツ「カラット」`, imagePath: `CHU_UI_Avatar_Icon_02100044.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100045`, str: `Tシャツ「アッポー」`, imagePath: `CHU_UI_Avatar_Icon_02100045.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100046`, str: `Tシャツ「ブラン」`, imagePath: `CHU_UI_Avatar_Icon_02100046.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100085`, str: `Tシャツ「maimai でらっくす UNiVERSE」`, imagePath: `CHU_UI_Avatar_Icon_02100085.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2100086`, str: `Tシャツ「オンゲキ bright」`, imagePath: `CHU_UI_Avatar_Icon_02100086.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2200001`, str: `ドレッド`, imagePath: `CHU_UI_Avatar_Icon_02200001.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200002`, str: `リーゼント`, imagePath: `CHU_UI_Avatar_Icon_02200002.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200003`, str: `べん髪`, imagePath: `CHU_UI_Avatar_Icon_02200003.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200004`, str: `ヴィジュアル系ウィッグ`, imagePath: `CHU_UI_Avatar_Icon_02200004.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200005`, str: `角刈り`, imagePath: `CHU_UI_Avatar_Icon_02200005.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200006`, str: `モヒカン(緑)`, imagePath: `CHU_UI_Avatar_Icon_02200006.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200007`, str: `ツインテール`, imagePath: `CHU_UI_Avatar_Icon_02200007.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200008`, str: `芸者`, imagePath: `CHU_UI_Avatar_Icon_02200008.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200009`, str: `チョンマゲ`, imagePath: `CHU_UI_Avatar_Icon_02200009.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200010`, str: `おかっぱ`, imagePath: `CHU_UI_Avatar_Icon_02200010.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200011`, str: `坊主`, imagePath: `CHU_UI_Avatar_Icon_02200011.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200012`, str: `ロングヘアー(銀)`, imagePath: `CHU_UI_Avatar_Icon_02200012.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200013`, str: `リボン`, imagePath: `CHU_UI_Avatar_Icon_02200013.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200014`, str: `イワトビペンギンのトサカ`, imagePath: `CHU_UI_Avatar_Icon_02200014.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200015`, str: `アフロ(黄)`, imagePath: `CHU_UI_Avatar_Icon_02200015.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200016`, str: `うさみみカチューシャ`, imagePath: `CHU_UI_Avatar_Icon_02200016.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2200017`, str: `ヘッドホン`, imagePath: `CHU_UI_Avatar_Icon_02200017.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `2300001`, str: `マスク`, imagePath: `CHU_UI_Avatar_Icon_02300001.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300002`, str: `サングラス`, imagePath: `CHU_UI_Avatar_Icon_02300002.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300003`, str: `ラウンドメガネ`, imagePath: `CHU_UI_Avatar_Icon_02300003.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300004`, str: `星メガネ`, imagePath: `CHU_UI_Avatar_Icon_02300004.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300005`, str: `ハートメガネ`, imagePath: `CHU_UI_Avatar_Icon_02300005.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300006`, str: `3Dメガネ`, imagePath: `CHU_UI_Avatar_Icon_02300006.dds`, sortName: `3`, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300007`, str: `鼻メガネ`, imagePath: `CHU_UI_Avatar_Icon_02300007.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300008`, str: `モノクル`, imagePath: `CHU_UI_Avatar_Icon_02300008.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300009`, str: `スクエアメガネ`, imagePath: `CHU_UI_Avatar_Icon_02300009.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300010`, str: `アイマスク`, imagePath: `CHU_UI_Avatar_Icon_02300010.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300011`, str: `レーティング測定器`, imagePath: `CHU_UI_Avatar_Icon_02300011.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300012`, str: `ヘッドマウントディスプレイ`, imagePath: `CHU_UI_Avatar_Icon_02300012.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300013`, str: `ラウンド髭`, imagePath: `CHU_UI_Avatar_Icon_02300013.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300014`, str: `ちょび髭`, imagePath: `CHU_UI_Avatar_Icon_02300014.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300015`, str: `カイゼル髭`, imagePath: `CHU_UI_Avatar_Icon_02300015.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300016`, str: `豚の付け鼻`, imagePath: `CHU_UI_Avatar_Icon_02300016.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300017`, str: `おしゃぶり`, imagePath: `CHU_UI_Avatar_Icon_02300017.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300018`, str: `ガスマスク`, imagePath: `CHU_UI_Avatar_Icon_02300018.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300019`, str: `顔パック`, imagePath: `CHU_UI_Avatar_Icon_02300019.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300020`, str: `泥パック`, imagePath: `CHU_UI_Avatar_Icon_02300020.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300021`, str: `鼻水`, imagePath: `CHU_UI_Avatar_Icon_02300021.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300022`, str: `よだれ`, imagePath: `CHU_UI_Avatar_Icon_02300022.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300023`, str: `ばんそうこう`, imagePath: `CHU_UI_Avatar_Icon_02300023.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300024`, str: `風船ガム`, imagePath: `CHU_UI_Avatar_Icon_02300024.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300025`, str: `傷あと`, imagePath: `CHU_UI_Avatar_Icon_02300025.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300026`, str: `マスカレイドマスク`, imagePath: `CHU_UI_Avatar_Icon_02300026.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2300027`, str: ``, imagePath: `CHU_UI_Avatar_Icon_02300027.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `2500001`, str: `バット(木製)`, imagePath: `CHU_UI_Avatar_Icon_02500001.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500002`, str: `バット(金属)`, imagePath: `CHU_UI_Avatar_Icon_02500002.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500003`, str: `釘バット`, imagePath: `CHU_UI_Avatar_Icon_02500003.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500004`, str: `ツルハシ(木)`, imagePath: `CHU_UI_Avatar_Icon_02500004.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500005`, str: `ツルハシ(石)`, imagePath: `CHU_UI_Avatar_Icon_02500005.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500006`, str: `ツルハシ(鉄)`, imagePath: `CHU_UI_Avatar_Icon_02500006.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500007`, str: `ツルハシ(金)`, imagePath: `CHU_UI_Avatar_Icon_02500007.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500008`, str: `ツルハシ(ダイヤモンド)`, imagePath: `CHU_UI_Avatar_Icon_02500008.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500009`, str: `ライトスティック(オレンジ)`, imagePath: `CHU_UI_Avatar_Icon_02500009.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500010`, str: `ライトスティック(イエロー)`, imagePath: `CHU_UI_Avatar_Icon_02500010.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500011`, str: `ライトスティック(ピンク)`, imagePath: `CHU_UI_Avatar_Icon_02500011.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500012`, str: `ライトスティック(ブルー)`, imagePath: `CHU_UI_Avatar_Icon_02500012.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500013`, str: `ライトスティック(ライトブルー)`, imagePath: `CHU_UI_Avatar_Icon_02500013.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500014`, str: `ライトスティック(グリーン)`, imagePath: `CHU_UI_Avatar_Icon_02500014.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500015`, str: `ライトスティック(レッド)`, imagePath: `CHU_UI_Avatar_Icon_02500015.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500016`, str: `バスケットボール`, imagePath: `CHU_UI_Avatar_Icon_02500016.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500017`, str: `サッカーボール`, imagePath: `CHU_UI_Avatar_Icon_02500017.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500018`, str: `バレーボール`, imagePath: `CHU_UI_Avatar_Icon_02500018.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500019`, str: `ソウルオブスタチュウ`, imagePath: `CHU_UI_Avatar_Icon_02500019.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500020`, str: `ショウニスタチュウ`, imagePath: `CHU_UI_Avatar_Icon_02500020.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500021`, str: `ペンギンスタチュウ`, imagePath: `CHU_UI_Avatar_Icon_02500021.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500022`, str: `札束`, imagePath: `CHU_UI_Avatar_Icon_02500022.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500023`, str: `コイン`, imagePath: `CHU_UI_Avatar_Icon_02500023.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500024`, str: `手袋(赤)`, imagePath: `CHU_UI_Avatar_Icon_02500024.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500025`, str: `手袋(緑)`, imagePath: `CHU_UI_Avatar_Icon_02500025.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500026`, str: `手袋(黒)`, imagePath: `CHU_UI_Avatar_Icon_02500026.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500027`, str: `ダンベル`, imagePath: `CHU_UI_Avatar_Icon_02500027.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500028`, str: `スマートフォン`, imagePath: `CHU_UI_Avatar_Icon_02500028.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500029`, str: `バチ`, imagePath: `CHU_UI_Avatar_Icon_02500029.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500030`, str: `ペットボトル`, imagePath: `CHU_UI_Avatar_Icon_02500030.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500031`, str: `タオル`, imagePath: `CHU_UI_Avatar_Icon_02500031.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500032`, str: `マイク`, imagePath: `CHU_UI_Avatar_Icon_02500032.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500033`, str: `指差し棒`, imagePath: `CHU_UI_Avatar_Icon_02500033.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500034`, str: `じゃんけん棒(グー)`, imagePath: `CHU_UI_Avatar_Icon_02500034.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500035`, str: `じゃんけん棒(チョキ)`, imagePath: `CHU_UI_Avatar_Icon_02500035.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500036`, str: `じゃんけん棒(パー)`, imagePath: `CHU_UI_Avatar_Icon_02500036.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500037`, str: `じゃんけん棒(無敵)`, imagePath: `CHU_UI_Avatar_Icon_02500037.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2500038`, str: `レコード`, imagePath: `CHU_UI_Avatar_Icon_02500038.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `2700001`, str: ``, imagePath: `CHU_UI_Avatar_Icon_02700001.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `2700002`, str: `バスターソード`, imagePath: `CHU_UI_Avatar_Icon_02700002.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `2700003`, str: `リュックとポスター`, imagePath: `CHU_UI_Avatar_Icon_02700003.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `2700004`, str: `ビット`, imagePath: `CHU_UI_Avatar_Icon_02700004.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `2700005`, str: `クジャクの羽`, imagePath: `CHU_UI_Avatar_Icon_02700005.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `2700006`, str: `ジェットパック`, imagePath: `CHU_UI_Avatar_Icon_02700006.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `2700007`, str: `空飛ぶ風船`, imagePath: `CHU_UI_Avatar_Icon_02700007.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `2700008`, str: `パラシュート`, imagePath: `CHU_UI_Avatar_Icon_02700008.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `3100101`, str: `ノーマル(シルバー)`, imagePath: `CHU_UI_Avatar_Icon_03100101.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100201`, str: `ノーマル(ゴールド)`, imagePath: `CHU_UI_Avatar_Icon_03100201.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100301`, str: `プレートアーマー(シルバー)`, imagePath: `CHU_UI_Avatar_Icon_03100301.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100302`, str: `プレートアーマー(ゴールド)`, imagePath: `CHU_UI_Avatar_Icon_03100302.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100401`, str: `ドレス(赤)`, imagePath: `CHU_UI_Avatar_Icon_03100401.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100402`, str: `ドレス(青)`, imagePath: `CHU_UI_Avatar_Icon_03100402.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100403`, str: `ドレス(黄)`, imagePath: `CHU_UI_Avatar_Icon_03100403.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100501`, str: `カウボーイの服`, imagePath: `CHU_UI_Avatar_Icon_03100501.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100601`, str: `王様の服`, imagePath: `CHU_UI_Avatar_Icon_03100601.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100701`, str: `海賊の服`, imagePath: `CHU_UI_Avatar_Icon_03100701.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100801`, str: `警察官の服`, imagePath: `CHU_UI_Avatar_Icon_03100801.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100901`, str: `野球ユニフォーム(黄)`, imagePath: `CHU_UI_Avatar_Icon_03100901.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3100902`, str: `野球ユニフォーム(オレンジ)`, imagePath: `CHU_UI_Avatar_Icon_03100902.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101001`, str: `忍者の服(黒)`, imagePath: `CHU_UI_Avatar_Icon_03101001.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101002`, str: `忍者の服(赤)`, imagePath: `CHU_UI_Avatar_Icon_03101002.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101101`, str: `道着(白帯)`, imagePath: `CHU_UI_Avatar_Icon_03101101.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101102`, str: `道着(黒帯)`, imagePath: `CHU_UI_Avatar_Icon_03101102.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101201`, str: `ロンパース`, imagePath: `CHU_UI_Avatar_Icon_03101201.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101301`, str: `スモック(青)`, imagePath: `CHU_UI_Avatar_Icon_03101301.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101302`, str: `スモック(赤)`, imagePath: `CHU_UI_Avatar_Icon_03101302.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101401`, str: `学生服`, imagePath: `CHU_UI_Avatar_Icon_03101401.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101501`, str: `セーラー服`, imagePath: `CHU_UI_Avatar_Icon_03101501.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101601`, str: `スーツ`, imagePath: `CHU_UI_Avatar_Icon_03101601.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101701`, str: `探検服`, imagePath: `CHU_UI_Avatar_Icon_03101701.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101801`, str: `ヒーロースーツ(レッド)`, imagePath: `CHU_UI_Avatar_Icon_03101801.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101802`, str: `ヒーロースーツ(ブルー)`, imagePath: `CHU_UI_Avatar_Icon_03101802.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101803`, str: `ヒーロースーツ(イエロー)`, imagePath: `CHU_UI_Avatar_Icon_03101803.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101804`, str: `ヒーロースーツ(グリーン)`, imagePath: `CHU_UI_Avatar_Icon_03101804.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101805`, str: `ヒーロースーツ(ピンク)`, imagePath: `CHU_UI_Avatar_Icon_03101805.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3101901`, str: `ピエロの服`, imagePath: `CHU_UI_Avatar_Icon_03101901.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3102301`, str: `ミリタリー服`, imagePath: `CHU_UI_Avatar_Icon_03102301.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3102401`, str: `プロレススーツ`, imagePath: `CHU_UI_Avatar_Icon_03102401.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3102501`, str: `宇宙服`, imagePath: `CHU_UI_Avatar_Icon_03102501.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3102801`, str: `板前の服`, imagePath: `CHU_UI_Avatar_Icon_03102801.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3102901`, str: `ナース服`, imagePath: `CHU_UI_Avatar_Icon_03102901.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `3200101`, str: `ノーマル(シルバー)`, imagePath: `CHU_UI_Avatar_Icon_03200101.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3200201`, str: `ノーマル(ゴールド)`, imagePath: `CHU_UI_Avatar_Icon_03200201.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3200301`, str: `プレートアーマーヘルメット(シルバー)`, imagePath: `CHU_UI_Avatar_Icon_03200301.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3200302`, str: `プレートアーマーヘルメット(ゴールド)`, imagePath: `CHU_UI_Avatar_Icon_03200302.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3200401`, str: `ティアラ`, imagePath: `CHU_UI_Avatar_Icon_03200401.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3200501`, str: `テンガロンハット`, imagePath: `CHU_UI_Avatar_Icon_03200501.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3200601`, str: `王冠`, imagePath: `CHU_UI_Avatar_Icon_03200601.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3200701`, str: `海賊の帽子`, imagePath: `CHU_UI_Avatar_Icon_03200701.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3200801`, str: `警察官の帽子`, imagePath: `CHU_UI_Avatar_Icon_03200801.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3200901`, str: `野球帽(黄)`, imagePath: `CHU_UI_Avatar_Icon_03200901.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3200902`, str: `野球帽(オレンジ)`, imagePath: `CHU_UI_Avatar_Icon_03200902.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201001`, str: `忍者の頭巾(黒)`, imagePath: `CHU_UI_Avatar_Icon_03201001.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201002`, str: `忍者の頭巾(赤)`, imagePath: `CHU_UI_Avatar_Icon_03201002.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201201`, str: `赤ちゃんの帽子`, imagePath: `CHU_UI_Avatar_Icon_03201201.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201301`, str: `通学帽`, imagePath: `CHU_UI_Avatar_Icon_03201301.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201401`, str: `学生帽`, imagePath: `CHU_UI_Avatar_Icon_03201401.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201701`, str: `探検帽`, imagePath: `CHU_UI_Avatar_Icon_03201701.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201801`, str: `ヒーローヘルメット(レッド)`, imagePath: `CHU_UI_Avatar_Icon_03201801.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201802`, str: `ヒーローヘルメット(ブルー)`, imagePath: `CHU_UI_Avatar_Icon_03201802.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201803`, str: `ヒーローヘルメット(イエロー)`, imagePath: `CHU_UI_Avatar_Icon_03201803.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201804`, str: `ヒーローヘルメット(グリーン)`, imagePath: `CHU_UI_Avatar_Icon_03201804.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201805`, str: `ヒーローヘルメット(ピンク)`, imagePath: `CHU_UI_Avatar_Icon_03201805.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3201901`, str: `ピエロの帽子`, imagePath: `CHU_UI_Avatar_Icon_03201901.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3202401`, str: `プロレスマスク`, imagePath: `CHU_UI_Avatar_Icon_03202401.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3202501`, str: `宇宙ヘルメット`, imagePath: `CHU_UI_Avatar_Icon_03202501.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3202801`, str: `和帽子`, imagePath: `CHU_UI_Avatar_Icon_03202801.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3202901`, str: `ナースキャップ`, imagePath: `CHU_UI_Avatar_Icon_03202901.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `3300601`, str: `巻き髭`, imagePath: `CHU_UI_Avatar_Icon_03300601.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `3300701`, str: `海賊の眼帯`, imagePath: `CHU_UI_Avatar_Icon_03300701.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `3300801`, str: `ティアドロップサングラス`, imagePath: `CHU_UI_Avatar_Icon_03300801.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `3301901`, str: `ピエロの仮面`, imagePath: `CHU_UI_Avatar_Icon_03301901.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `3302301`, str: `迷彩フェイスペイント`, imagePath: `CHU_UI_Avatar_Icon_03302301.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `3500301`, str: `片手剣(シルバー)`, imagePath: `CHU_UI_Avatar_Icon_03500301.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3500302`, str: `片手剣(ゴールド)`, imagePath: `CHU_UI_Avatar_Icon_03500302.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3500501`, str: `ムチ`, imagePath: `CHU_UI_Avatar_Icon_03500501.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3500601`, str: `王様の杖`, imagePath: `CHU_UI_Avatar_Icon_03500601.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3500701`, str: `カトラス`, imagePath: `CHU_UI_Avatar_Icon_03500701.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3500801`, str: `警察手帳`, imagePath: `CHU_UI_Avatar_Icon_03500801.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3501001`, str: `手裏剣`, imagePath: `CHU_UI_Avatar_Icon_03501001.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3501601`, str: `ビジネスバッグ`, imagePath: `CHU_UI_Avatar_Icon_03501601.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3501701`, str: `双眼鏡`, imagePath: `CHU_UI_Avatar_Icon_03501701.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3501901`, str: `風船`, imagePath: `CHU_UI_Avatar_Icon_03501901.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3502301`, str: `4連装ロケットランチャー`, imagePath: `CHU_UI_Avatar_Icon_03502301.dds`, sortName: `4`, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3502401`, str: `チャンピオンベルト`, imagePath: `CHU_UI_Avatar_Icon_03502401.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3502501`, str: `宇宙飛行士の旗`, imagePath: `CHU_UI_Avatar_Icon_03502501.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3502801`, str: ``, imagePath: `CHU_UI_Avatar_Icon_03502801.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `3502901`, str: `注射器`, imagePath: `CHU_UI_Avatar_Icon_03502901.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4101101`, str: `バスタオル`, imagePath: `CHU_UI_Avatar_Icon_04101101.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101102`, str: ``, imagePath: `CHU_UI_Avatar_Icon_04101102.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101201`, str: `サンタの服`, imagePath: `CHU_UI_Avatar_Icon_04101201.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101301`, str: ``, imagePath: `CHU_UI_Avatar_Icon_04101301.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101401`, str: `鬼の服(赤)`, imagePath: `CHU_UI_Avatar_Icon_04101401.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101402`, str: `鬼の服(青)`, imagePath: `CHU_UI_Avatar_Icon_04101402.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101501`, str: `お雛様の服`, imagePath: `CHU_UI_Avatar_Icon_04101501.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101502`, str: `お内裏様の服`, imagePath: `CHU_UI_Avatar_Icon_04101502.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101601`, str: `イースターエッグの体`, imagePath: `CHU_UI_Avatar_Icon_04101601.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101602`, str: `ひよこのきぐるみ`, imagePath: `CHU_UI_Avatar_Icon_04101602.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101701`, str: `武士の鎧`, imagePath: `CHU_UI_Avatar_Icon_04101701.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101702`, str: `鯉のぼり(母と子)`, imagePath: `CHU_UI_Avatar_Icon_04101702.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101801`, str: `レインコート`, imagePath: `CHU_UI_Avatar_Icon_04101801.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101802`, str: `てるてる坊主の体`, imagePath: `CHU_UI_Avatar_Icon_04101802.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4101901`, str: `海水浴の服`, imagePath: `CHU_UI_Avatar_Icon_04101901.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4102001`, str: `虫取りの服`, imagePath: `CHU_UI_Avatar_Icon_04102001.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4102002`, str: `甲虫の体`, imagePath: `CHU_UI_Avatar_Icon_04102002.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4102101`, str: `祭りのはっぴ`, imagePath: `CHU_UI_Avatar_Icon_04102101.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `4201101`, str: `温泉タオル`, imagePath: `CHU_UI_Avatar_Icon_04201101.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201102`, str: ``, imagePath: `CHU_UI_Avatar_Icon_04201102.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201103`, str: `アヒルのおもちゃ`, imagePath: `CHU_UI_Avatar_Icon_04201103.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201201`, str: `サンタの帽子`, imagePath: `CHU_UI_Avatar_Icon_04201201.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201301`, str: `しめ飾り`, imagePath: `CHU_UI_Avatar_Icon_04201301.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201302`, str: `トラのかぶりもの`, imagePath: `CHU_UI_Avatar_Icon_04201302.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201303`, str: `2022冠`, imagePath: `CHU_UI_Avatar_Icon_04201303.dds`, sortName: `2`, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201401`, str: `鬼のお面(赤)`, imagePath: `CHU_UI_Avatar_Icon_04201401.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201402`, str: `鬼のお面(青)`, imagePath: `CHU_UI_Avatar_Icon_04201402.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201403`, str: `おかめのお面`, imagePath: `CHU_UI_Avatar_Icon_04201403.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201501`, str: `お雛様の髪飾り`, imagePath: `CHU_UI_Avatar_Icon_04201501.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201502`, str: `お内裏様の冠`, imagePath: `CHU_UI_Avatar_Icon_04201502.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201503`, str: `ぼんぼり`, imagePath: `CHU_UI_Avatar_Icon_04201503.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201601`, str: `イースターエッグの頭`, imagePath: `CHU_UI_Avatar_Icon_04201601.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201602`, str: `イースターバニーの帽子`, imagePath: `CHU_UI_Avatar_Icon_04201602.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201603`, str: `ひよこのかぶりもの`, imagePath: `CHU_UI_Avatar_Icon_04201603.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201701`, str: `折り紙の兜`, imagePath: `CHU_UI_Avatar_Icon_04201701.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201702`, str: `武士の兜`, imagePath: `CHU_UI_Avatar_Icon_04201702.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201703`, str: `鯉のぼり(父)`, imagePath: `CHU_UI_Avatar_Icon_04201703.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201801`, str: `レインフード`, imagePath: `CHU_UI_Avatar_Icon_04201801.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201802`, str: `てるてる坊主の頭`, imagePath: `CHU_UI_Avatar_Icon_04201802.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201901`, str: `水泳帽`, imagePath: `CHU_UI_Avatar_Icon_04201901.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4201902`, str: `ワカメ`, imagePath: `CHU_UI_Avatar_Icon_04201902.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4202001`, str: `麦わら帽子`, imagePath: `CHU_UI_Avatar_Icon_04202001.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4202002`, str: `カブトムシの角`, imagePath: `CHU_UI_Avatar_Icon_04202002.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4202003`, str: `クワガタの角`, imagePath: `CHU_UI_Avatar_Icon_04202003.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4202101`, str: `祭りの鉢巻`, imagePath: `CHU_UI_Avatar_Icon_04202101.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4202102`, str: `提灯`, imagePath: `CHU_UI_Avatar_Icon_04202102.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `4301201`, str: `サンタの髭`, imagePath: `CHU_UI_Avatar_Icon_04301201.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `4301301`, str: ``, imagePath: `CHU_UI_Avatar_Icon_04301301.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `4301601`, str: `ウサギの付け鼻`, imagePath: `CHU_UI_Avatar_Icon_04301601.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `4301901`, str: `シュノーケル`, imagePath: `CHU_UI_Avatar_Icon_04301901.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `4501101`, str: ``, imagePath: `CHU_UI_Avatar_Icon_04501101.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501201`, str: `サンタの袋`, imagePath: `CHU_UI_Avatar_Icon_04501201.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501202`, str: `クリスマスプレゼント`, imagePath: `CHU_UI_Avatar_Icon_04501202.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501301`, str: `羽子板`, imagePath: `CHU_UI_Avatar_Icon_04501301.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501302`, str: ``, imagePath: `CHU_UI_Avatar_Icon_04501302.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501401`, str: `こん棒`, imagePath: `CHU_UI_Avatar_Icon_04501401.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501402`, str: `節分豆`, imagePath: `CHU_UI_Avatar_Icon_04501402.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501403`, str: `恵方巻`, imagePath: `CHU_UI_Avatar_Icon_04501403.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501501`, str: `お雛様の扇`, imagePath: `CHU_UI_Avatar_Icon_04501501.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501502`, str: `お内裏様のしゃく`, imagePath: `CHU_UI_Avatar_Icon_04501502.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501601`, str: `イースターエッグのバスケット`, imagePath: `CHU_UI_Avatar_Icon_04501601.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501602`, str: `イースターエッグの風船`, imagePath: `CHU_UI_Avatar_Icon_04501602.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501701`, str: `武士の刀`, imagePath: `CHU_UI_Avatar_Icon_04501701.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501702`, str: `武士の弓`, imagePath: `CHU_UI_Avatar_Icon_04501702.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501801`, str: `傘(赤)`, imagePath: `CHU_UI_Avatar_Icon_04501801.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501802`, str: `傘(青)`, imagePath: `CHU_UI_Avatar_Icon_04501802.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4501901`, str: `モリ`, imagePath: `CHU_UI_Avatar_Icon_04501901.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4502001`, str: `虫網`, imagePath: `CHU_UI_Avatar_Icon_04502001.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4502101`, str: `祭りのうちわ`, imagePath: `CHU_UI_Avatar_Icon_04502101.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4502102`, str: `手持ち花火`, imagePath: `CHU_UI_Avatar_Icon_04502102.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4502103`, str: `わたあめ`, imagePath: `CHU_UI_Avatar_Icon_04502103.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `4702001`, str: `甲虫の羽`, imagePath: `CHU_UI_Avatar_Icon_04702001.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `9199997`, str: `CPU01`, imagePath: `CHU_UI_Avatar_Icon_09199997.dds`, sortName: `C`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `9199998`, str: `CPU02`, imagePath: `CHU_UI_Avatar_Icon_09199998.dds`, sortName: `C`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `9199999`, str: `CPU03`, imagePath: `CHU_UI_Avatar_Icon_09199999.dds`, sortName: `C`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `9299997`, str: `CPU01`, imagePath: `CHU_UI_Avatar_Icon_09299997.dds`, sortName: `C`, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `9299998`, str: `CPU02`, imagePath: `CHU_UI_Avatar_Icon_09299998.dds`, sortName: `C`, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `9299999`, str: `CPU03`, imagePath: `CHU_UI_Avatar_Icon_09299999.dds`, sortName: `C`, category: `2`, netOpenName: `v2_10 00_0` },
{ id: `9399997`, str: `CPU01`, imagePath: `CHU_UI_Avatar_Icon_09399997.dds`, sortName: `C`, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `9399998`, str: `CPU02`, imagePath: `CHU_UI_Avatar_Icon_09399998.dds`, sortName: `C`, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `9399999`, str: `CPU03`, imagePath: `CHU_UI_Avatar_Icon_09399999.dds`, sortName: `C`, category: `3`, netOpenName: `v2_10 00_0` },
{ id: `9499997`, str: `CPU01`, imagePath: `CHU_UI_Avatar_Icon_09499997.dds`, sortName: `C`, category: `4`, netOpenName: `v2_10 00_0` },
{ id: `9499998`, str: `CPU02`, imagePath: `CHU_UI_Avatar_Icon_09499998.dds`, sortName: `C`, category: `4`, netOpenName: `v2_10 00_0` },
{ id: `9499999`, str: `CPU03`, imagePath: `CHU_UI_Avatar_Icon_09499999.dds`, sortName: `C`, category: `4`, netOpenName: `v2_10 00_0` },
{ id: `9599997`, str: `CPU01`, imagePath: `CHU_UI_Avatar_Icon_09599997.dds`, sortName: `C`, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `9599998`, str: `CPU02`, imagePath: `CHU_UI_Avatar_Icon_09599998.dds`, sortName: `C`, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `9599999`, str: `CPU03`, imagePath: `CHU_UI_Avatar_Icon_09599999.dds`, sortName: `C`, category: `5`, netOpenName: `v2_10 00_0` },
{ id: `9699997`, str: `CPU01`, imagePath: `CHU_UI_Avatar_Icon_09699997.dds`, sortName: `C`, category: `6`, netOpenName: `v2_10 00_0` },
{ id: `9699998`, str: `CPU02`, imagePath: `CHU_UI_Avatar_Icon_09699998.dds`, sortName: `C`, category: `6`, netOpenName: `v2_10 00_0` },
{ id: `9699999`, str: `CPU03`, imagePath: `CHU_UI_Avatar_Icon_09699999.dds`, sortName: `C`, category: `6`, netOpenName: `v2_10 00_0` },
{ id: `9799997`, str: `CPU01`, imagePath: `CHU_UI_Avatar_Icon_09799997.dds`, sortName: `C`, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `9799998`, str: `CPU02`, imagePath: `CHU_UI_Avatar_Icon_09799998.dds`, sortName: `C`, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `9799999`, str: `CPU03`, imagePath: `CHU_UI_Avatar_Icon_09799999.dds`, sortName: `C`, category: `7`, netOpenName: `v2_10 00_0` },
{ id: `2100087`, str: `Tシャツ「CHUNITHM SUN」`, imagePath: `CHU_UI_Avatar_Icon_02100087.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_1` },
{ id: `2100088`, str: `Tシャツ「ルクス」`, imagePath: `CHU_UI_Avatar_Icon_02100088.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_1` },
{ id: `2500039`, str: `虹限スタチュウ`, imagePath: `CHU_UI_Avatar_Icon_02500039.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_1` },
{ id: `4102201`, str: `ドラキュラの服`, imagePath: `CHU_UI_Avatar_Icon_04102201.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_1` },
{ id: `4202201`, str: `パンプキンのかぶりもの`, imagePath: `CHU_UI_Avatar_Icon_04202201.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_1` },
{ id: `4502201`, str: `ジャック・オー・ランタン`, imagePath: `CHU_UI_Avatar_Icon_04502201.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_1` },
{ id: `4502202`, str: `ペロペロキャンディ`, imagePath: `CHU_UI_Avatar_Icon_04502202.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_1` },
{ id: `4502203`, str: `ハロウィンのバスケット`, imagePath: `CHU_UI_Avatar_Icon_04502203.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_1` },
{ id: `6100101`, str: `明坂 芹菜の服`, imagePath: `CHU_UI_Avatar_Icon_06100101.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_1` },
{ id: `6102101`, str: `星咲 あかりの服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06102101.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_1` },
{ id: `6102201`, str: `藤沢 柚子の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06102201.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_1` },
{ id: `6102301`, str: `三角 葵の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06102301.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_1` },
{ id: `6102401`, str: `高瀬 梨緒の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06102401.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_1` },
{ id: `6102501`, str: `結城 莉玖の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06102501.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_1` },
{ id: `6102601`, str: `藍原 椿の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06102601.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_1` },
{ id: `6200101`, str: `明坂 芹菜の頭`, imagePath: `CHU_UI_Avatar_Icon_06200101.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_1` },
{ id: `6202101`, str: `星咲 あかりの頭(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06202101.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_1` },
{ id: `8100001`, str: `譜面ボーイズの服`, imagePath: `CHU_UI_Avatar_Icon_08100001.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 00_1` },
{ id: `8200001`, str: `譜面ボーイズの頭`, imagePath: `CHU_UI_Avatar_Icon_08200001.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 00_1` },
{ id: `8500001`, str: `譜面ボーイズのアイテム`, imagePath: `CHU_UI_Avatar_Icon_08500001.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 00_1` },
{ id: `3102001`, str: `メイド服`, imagePath: `CHU_UI_Avatar_Icon_03102001.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 10_1` },
{ id: `3202001`, str: `ホワイトブリム`, imagePath: `CHU_UI_Avatar_Icon_03202001.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 10_1` },
{ id: `3502001`, str: `萌え萌えオムライス`, imagePath: `CHU_UI_Avatar_Icon_03502001.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 10_1` },
{ id: `6502701`, str: `桜井 春菜のフラワーブーケ`, imagePath: `CHU_UI_Avatar_Icon_06502701.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 10_1` },
{ id: `6502801`, str: `早乙女 彩華の二丁拳銃`, imagePath: `CHU_UI_Avatar_Icon_06502801.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 10_1` },
{ id: `4102301`, str: `リスのきぐるみ`, imagePath: `CHU_UI_Avatar_Icon_04102301.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 11_1` },
{ id: `4102302`, str: `落ち葉`, imagePath: `CHU_UI_Avatar_Icon_04102302.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 11_1` },
{ id: `4202301`, str: `リスのかぶりもの`, imagePath: `CHU_UI_Avatar_Icon_04202301.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 11_1` },
{ id: `4202302`, str: `枯れ葉`, imagePath: `CHU_UI_Avatar_Icon_04202302.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 11_1` },
{ id: `4502301`, str: `どんぐり`, imagePath: `CHU_UI_Avatar_Icon_04502301.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 11_1` },
{ id: `4502302`, str: `モミジ`, imagePath: `CHU_UI_Avatar_Icon_04502302.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 11_1` },
{ id: `6100201`, str: `御形 アリシアナの服`, imagePath: `CHU_UI_Avatar_Icon_06100201.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 11_1` },
{ id: `6102901`, str: `井之原 小星の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06102901.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 11_1` },
{ id: `6103001`, str: `柏木 咲姫の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06103001.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 11_1` },
{ id: `6200201`, str: `御形 アリシアナの頭`, imagePath: `CHU_UI_Avatar_Icon_06200201.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 11_1` },
{ id: `6202201`, str: `藤沢 柚子の頭(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06202201.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 11_1` },
{ id: `3103101`, str: `ラーメン屋の服`, imagePath: `CHU_UI_Avatar_Icon_03103101.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 11_2` },
{ id: `3203101`, str: `タオルバンダナ`, imagePath: `CHU_UI_Avatar_Icon_03203101.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 11_2` },
{ id: `3503101`, str: `ラーメン`, imagePath: `CHU_UI_Avatar_Icon_03503101.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 11_2` },
{ id: `6502901`, str: `井之原 小星のコントローラー`, imagePath: `CHU_UI_Avatar_Icon_06502901.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 11_2` },
{ id: `4102401`, str: `トナカイのきぐるみ`, imagePath: `CHU_UI_Avatar_Icon_04102401.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 12_1` },
{ id: `4102402`, str: `クリスマスの靴下`, imagePath: `CHU_UI_Avatar_Icon_04102402.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 12_1` },
{ id: `4202401`, str: `トナカイのかぶりもの`, imagePath: `CHU_UI_Avatar_Icon_04202401.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 12_1` },
{ id: `4202402`, str: `クリスマスリース`, imagePath: `CHU_UI_Avatar_Icon_04202402.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 12_1` },
{ id: `4502401`, str: `クリスマスチキン`, imagePath: `CHU_UI_Avatar_Icon_04502401.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 12_1` },
{ id: `4702401`, str: `クリスマスのソリ`, imagePath: `CHU_UI_Avatar_Icon_04702401.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 12_1` },
{ id: `6100301`, str: `天王洲 なずなの服`, imagePath: `CHU_UI_Avatar_Icon_06100301.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 12_1` },
{ id: `6200301`, str: `天王洲 なずなの頭`, imagePath: `CHU_UI_Avatar_Icon_06200301.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 12_1` },
{ id: `6202301`, str: `三角 葵の頭(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06202301.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 12_1` },
{ id: `6300301`, str: `天王洲 なずなのメガネ`, imagePath: `CHU_UI_Avatar_Icon_06300301.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 12_1` },
{ id: `3103001`, str: `バニースーツ`, imagePath: `CHU_UI_Avatar_Icon_03103001.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 12_2` },
{ id: `3203001`, str: `バニーの耳`, imagePath: `CHU_UI_Avatar_Icon_03203001.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 12_2` },
{ id: `3503001`, str: `カクテルトレイ`, imagePath: `CHU_UI_Avatar_Icon_03503001.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 12_2` },
{ id: `6102701`, str: `桜井 春菜の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06102701.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 12_2` },
{ id: `6102801`, str: `早乙女 彩華の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06102801.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 12_2` },
{ id: `6503001`, str: `柏木 咲姫の騎士剣`, imagePath: `CHU_UI_Avatar_Icon_06503001.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 12_2` },
{ id: `4102501`, str: `着物`, imagePath: `CHU_UI_Avatar_Icon_04102501.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 13_1` },
{ id: `4202501`, str: `ウサギのかぶりもの`, imagePath: `CHU_UI_Avatar_Icon_04202501.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 13_1` },
{ id: `4202502`, str: `2023冠`, imagePath: `CHU_UI_Avatar_Icon_04202502.dds`, sortName: `2`, category: `2`, netOpenName: `v2_10 13_1` },
{ id: `4302501`, str: `おみくじ(大吉)`, imagePath: `CHU_UI_Avatar_Icon_04302501.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 13_1` },
{ id: `4302502`, str: `おみくじ(凶)`, imagePath: `CHU_UI_Avatar_Icon_04302502.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 13_1` },
{ id: `4502501`, str: `絵馬`, imagePath: `CHU_UI_Avatar_Icon_04502501.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 13_1` },
{ id: `6100401`, str: `小仏 凪の服`, imagePath: `CHU_UI_Avatar_Icon_06100401.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 13_1` },
{ id: `6200401`, str: `小仏 凪の頭`, imagePath: `CHU_UI_Avatar_Icon_06200401.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 13_1` },
{ id: `6202401`, str: `高瀬 梨緒の頭(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06202401.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 13_1` },
{ id: `3102601`, str: `ツタンカーメンの服`, imagePath: `CHU_UI_Avatar_Icon_03102601.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 13_2` },
{ id: `3202601`, str: `ツタンカーメンの仮面`, imagePath: `CHU_UI_Avatar_Icon_03202601.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 13_2` },
{ id: `3502601`, str: `ツタンカーメンの杖`, imagePath: `CHU_UI_Avatar_Icon_03502601.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 13_2` },
{ id: `6103101`, str: `九條 楓の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06103101.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 13_2` },
{ id: `6103201`, str: `逢坂 茜の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06103201.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 13_2` },
{ id: `6103301`, str: `珠洲島 有栖の服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06103301.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 13_2` },
{ id: `6503101`, str: `九條 楓の刀`, imagePath: `CHU_UI_Avatar_Icon_06503101.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 13_2` },
{ id: `6702901`, str: `井之原 小星のゲーミングPC`, imagePath: `CHU_UI_Avatar_Icon_06702901.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 13_2` },
{ id: `4102601`, str: `コックコート(バレンタイン)`, imagePath: `CHU_UI_Avatar_Icon_04102601.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 14_1` },
{ id: `4202601`, str: `コック帽(バレンタイン)`, imagePath: `CHU_UI_Avatar_Icon_04202601.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 14_1` },
{ id: `4302601`, str: `チョコレートの汚れ`, imagePath: `CHU_UI_Avatar_Icon_04302601.dds`, sortName: ``, category: `3`, netOpenName: `v2_10 14_1` },
{ id: `4502601`, str: `チョコレートボウル`, imagePath: `CHU_UI_Avatar_Icon_04502601.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 14_1` },
{ id: `4502602`, str: `バレンタインチョコレート(本命)`, imagePath: `CHU_UI_Avatar_Icon_04502602.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 14_1` },
{ id: `4502603`, str: `バレンタインチョコレート(義理)`, imagePath: `CHU_UI_Avatar_Icon_04502603.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 14_1` },
{ id: `6100501`, str: `箱部 なるの服`, imagePath: `CHU_UI_Avatar_Icon_06100501.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 14_1` },
{ id: `6200501`, str: `箱部 なるの頭`, imagePath: `CHU_UI_Avatar_Icon_06200501.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 14_1` },
{ id: `6202501`, str: `結城 莉玖の頭(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06202501.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 14_1` },
{ id: `3102701`, str: `バブリースーツ`, imagePath: `CHU_UI_Avatar_Icon_03102701.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 14_2` },
{ id: `3202701`, str: `バブリーヘアー`, imagePath: `CHU_UI_Avatar_Icon_03202701.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 14_2` },
{ id: `3502701`, str: `バブリー扇子`, imagePath: `CHU_UI_Avatar_Icon_03502701.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 14_2` },
{ id: `6703201`, str: `逢坂 茜のロケットランチャー`, imagePath: `CHU_UI_Avatar_Icon_06703201.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 14_2` },
{ id: `4102701`, str: `アカデミックガウン`, imagePath: `CHU_UI_Avatar_Icon_04102701.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 15_2` },
{ id: `4102702`, str: `学生服(卒業)`, imagePath: `CHU_UI_Avatar_Icon_04102702.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 15_2` },
{ id: `4202701`, str: `モルタルボード`, imagePath: `CHU_UI_Avatar_Icon_04202701.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 15_2` },
{ id: `4202702`, str: `白い鳩`, imagePath: `CHU_UI_Avatar_Icon_04202702.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 15_2` },
{ id: `4502701`, str: `卒業証書`, imagePath: `CHU_UI_Avatar_Icon_04502701.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 15_2` },
{ id: `4702701`, str: `卒業式の立て看板`, imagePath: `CHU_UI_Avatar_Icon_04702701.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 15_2` },
{ id: `6100601`, str: `月鈴 那知の服`, imagePath: `CHU_UI_Avatar_Icon_06100601.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 15_2` },
{ id: `6200601`, str: `月鈴 那知の頭`, imagePath: `CHU_UI_Avatar_Icon_06200601.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 15_2` },
{ id: `6202601`, str: `藍原 椿の頭(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06202601.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 15_2` },
{ id: `2100085`, str: `Tシャツ「maimai でらっくす UNiVERSE」`, imagePath: `CHU_UI_Avatar_Icon_02100085.dds`, sortName: `T`, category: `1`, netOpenName: `v2_10 00_0` },
{ id: `2300014`, str: `口髭`, imagePath: `CHU_UI_Avatar_Icon_02300014.dds`, sortName: ``, category: `3`, netOpenName: `v2_15 00_0` },
{ id: `2200003`, str: `とんがりヘア`, imagePath: `CHU_UI_Avatar_Icon_02200003.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 00_0` },
{ id: `3103701`, str: `インバネスコート`, imagePath: `CHU_UI_Avatar_Icon_03103701.dds`, sortName: ``, category: `1`, netOpenName: `v2_15 10_2` },
{ id: `3203601`, str: `シルクハット`, imagePath: `CHU_UI_Avatar_Icon_03203601.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 10_2` },
{ id: `3303601`, str: `ドミノマスク`, imagePath: `CHU_UI_Avatar_Icon_03303601.dds`, sortName: ``, category: `3`, netOpenName: `v2_15 10_2` },
{ id: `4103001`, str: `カエルのきぐるみ`, imagePath: `CHU_UI_Avatar_Icon_04103001.dds`, sortName: ``, category: `1`, netOpenName: `v2_15 10_2` },
{ id: `4203001`, str: `カエルのかぶりもの`, imagePath: `CHU_UI_Avatar_Icon_04203001.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 10_2` },
{ id: `4203002`, str: `アジサイ`, imagePath: `CHU_UI_Avatar_Icon_04203002.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 10_2` },
{ id: `4203003`, str: `カタツムリの触角`, imagePath: `CHU_UI_Avatar_Icon_04203003.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 10_2` },
{ id: `4503001`, str: `葉っぱ傘`, imagePath: `CHU_UI_Avatar_Icon_04503001.dds`, sortName: ``, category: `5`, netOpenName: `v2_15 10_2` },
{ id: `4703001`, str: `カタツムリの殻`, imagePath: `CHU_UI_Avatar_Icon_04703001.dds`, sortName: ``, category: `7`, netOpenName: `v2_15 10_2` },
{ id: `6100901`, str: `萩原 七々瀬の服`, imagePath: `CHU_UI_Avatar_Icon_06100901.dds`, sortName: ``, category: `1`, netOpenName: `v2_15 10_2` },
{ id: `6200901`, str: `萩原 七々瀬の頭`, imagePath: `CHU_UI_Avatar_Icon_06200901.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 10_2` },
{ id: `6202901`, str: `井之原 小星の頭(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06202901.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 10_2` },
{ id: `6503501`, str: `日向 千夏の指揮杖`, imagePath: `CHU_UI_Avatar_Icon_06503501.dds`, sortName: ``, category: `5`, netOpenName: `v2_15 10_2` },
{ id: `3102201`, str: `悪魔の服`, imagePath: `CHU_UI_Avatar_Icon_03102201.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 08_2` },
{ id: `3202201`, str: `悪魔の角`, imagePath: `CHU_UI_Avatar_Icon_03202201.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 08_2` },
{ id: `3502101`, str: `天使の弓矢`, imagePath: `CHU_UI_Avatar_Icon_03502101.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 09_1` },
{ id: `3702201`, str: `悪魔の羽`, imagePath: `CHU_UI_Avatar_Icon_03702201.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 08_2` },
{ id: `4102801`, str: `袴(桜)`, imagePath: `CHU_UI_Avatar_Icon_04102801.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 09_1` },
{ id: `4102802`, str: `団子(白と緑)`, imagePath: `CHU_UI_Avatar_Icon_04102802.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 09_1` },
{ id: `4202801`, str: ``, imagePath: `CHU_UI_Avatar_Icon_04202801.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 09_1` },
{ id: `4202802`, str: `桜提灯`, imagePath: `CHU_UI_Avatar_Icon_04202802.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 09_1` },
{ id: `4202803`, str: `団子(ピンク)`, imagePath: `CHU_UI_Avatar_Icon_04202803.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 09_1` },
{ id: `4502801`, str: `桜の折り紙`, imagePath: `CHU_UI_Avatar_Icon_04502801.dds`, sortName: ``, category: `5`, netOpenName: `v2_10 09_1` },
{ id: `6100701`, str: `月鈴 白奈の服`, imagePath: `CHU_UI_Avatar_Icon_06100701.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 09_1` },
{ id: `6103701`, str: `皇城 セツナの服(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06103701.dds`, sortName: ``, category: `1`, netOpenName: `v2_10 08_2` },
{ id: `6200701`, str: `月鈴 白奈の頭`, imagePath: `CHU_UI_Avatar_Icon_06200701.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 09_1` },
{ id: `6202401`, str: `高瀬 梨緒の頭(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06202401.dds`, sortName: ``, category: `2`, netOpenName: `v2_10 09_1` },
{ id: `6703301`, str: `珠洲島 有栖のぷかぷか水`, imagePath: `CHU_UI_Avatar_Icon_06703301.dds`, sortName: ``, category: `7`, netOpenName: `v2_10 08_2` },
{ id: `6101001`, str: `葛城 華の服`, imagePath: `CHU_UI_Avatar_Icon_06101001.dds`, sortName: ``, category: `1`, netOpenName: `v2_15 11_2` },
{ id: `6201001`, str: `葛城 華の頭`, imagePath: `CHU_UI_Avatar_Icon_06201001.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 11_2` },
{ id: `6203001`, str: `柏木 咲姫の頭(シュータードレス)`, imagePath: `CHU_UI_Avatar_Icon_06203001.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 11_2` },
{ id: `3103801`, str: `原始人の服`, imagePath: `CHU_UI_Avatar_Icon_03103801.dds`, sortName: ``, category: `1`, netOpenName: `v2_15 12_1` },
{ id: `3203701`, str: `ディアストーカー`, imagePath: `CHU_UI_Avatar_Icon_03203701.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 12_1` },
{ id: `3503701`, str: `虫眼鏡`, imagePath: `CHU_UI_Avatar_Icon_03503701.dds`, sortName: ``, category: `5`, netOpenName: `v2_15 12_1` },
{ id: `4103101`, str: `織姫の服`, imagePath: `CHU_UI_Avatar_Icon_04103101.dds`, sortName: ``, category: `1`, netOpenName: `v2_15 12_1` },
{ id: `4103102`, str: `彦星の服`, imagePath: `CHU_UI_Avatar_Icon_04103102.dds`, sortName: ``, category: `1`, netOpenName: `v2_15 12_1` },
{ id: `4203101`, str: `織姫の髪飾り`, imagePath: `CHU_UI_Avatar_Icon_04203101.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 12_1` },
{ id: `4203102`, str: `彦星の冠`, imagePath: `CHU_UI_Avatar_Icon_04203102.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 12_1` },
{ id: `4203103`, str: `流れ星`, imagePath: `CHU_UI_Avatar_Icon_04203103.dds`, sortName: ``, category: `2`, netOpenName: `v2_15 12_1` },
{ id: `4703101`, str: `七夕の笹`, imagePath: `CHU_UI_Avatar_Icon_04703101.dds`, sortName: ``, category: `7`, netOpenName: `v2_15 12_1` },
{ id: `6503601`, str: `東雲 つむぎのマーチングドラム`, imagePath: `CHU_UI_Avatar_Icon_06503601.dds`, sortName: ``, category: `5`, netOpenName: `v2_15 12_1` },
]

55
src/lib/mapicon.ts Normal file
View File

@ -0,0 +1,55 @@
export const mapicon = [
{ id: `1`, str: `ノーマル`, imagePath: `CHU_UI_MapIcon_00000001.dds`, sortName: `` },
{ id: `2`, str: `GOD`, imagePath: `CHU_UI_MapIcon_00000002.dds`, sortName: `G` },
{ id: `3`, str: `月鈴 白奈`, imagePath: `CHU_UI_MapIcon_00000003.dds`, sortName: `` },
{ id: `4`, str: `箱部 なる`, imagePath: `CHU_UI_MapIcon_00000004.dds`, sortName: `` },
{ id: `5`, str: `スザク`, imagePath: `CHU_UI_MapIcon_00000005.dds`, sortName: `` },
{ id: `6`, str: `天王洲 なずな`, imagePath: `CHU_UI_MapIcon_00000006.dds`, sortName: `` },
{ id: `7`, str: `明坂 芹菜`, imagePath: `CHU_UI_MapIcon_00000007.dds`, sortName: `` },
{ id: `8`, str: `トリスメギストス`, imagePath: `CHU_UI_MapIcon_00000008.dds`, sortName: `` },
{ id: `9`, str: `MIR-202【アルテミス・レナ】`, imagePath: `CHU_UI_MapIcon_00000009.dds`, sortName: `M` },
{ id: `10`, str: `小仏 凪`, imagePath: `CHU_UI_MapIcon_00000010.dds`, sortName: `` },
{ id: `11`, str: `御形 アリシアナ`, imagePath: `CHU_UI_MapIcon_00000011.dds`, sortName: `` },
{ id: `12`, str: `リリアリス・コルチカム`, imagePath: `CHU_UI_MapIcon_00000012.dds`, sortName: `` },
{ id: `13`, str: `月鈴 那知`, imagePath: `CHU_UI_MapIcon_00000013.dds`, sortName: `` },
{ id: `14`, str: `リヒトシュッツェ`, imagePath: `CHU_UI_MapIcon_00000014.dds`, sortName: `` },
{ id: `15`, str: `HAR-ヒロイン09【ネレイダム】`, imagePath: `CHU_UI_MapIcon_00000015.dds`, sortName: `H` },
{ id: `16`, str: `五十嵐 撫子`, imagePath: `CHU_UI_MapIcon_00000016.dds`, sortName: `` },
{ id: `17`, str: `ダオ・トッテナ`, imagePath: `CHU_UI_MapIcon_00000017.dds`, sortName: `` },
{ id: `18`, str: `萩原 七々瀬`, imagePath: `CHU_UI_MapIcon_00000018.dds`, sortName: `` },
{ id: `19`, str: `八咫烏 鋼太郎`, imagePath: `CHU_UI_MapIcon_00000019.dds`, sortName: `` },
{ id: `20`, str: `黒亀 北斗`, imagePath: `CHU_UI_MapIcon_00000020.dds`, sortName: `` },
{ id: `21`, str: `暴虐のギーゼグール`, imagePath: `CHU_UI_MapIcon_00000021.dds`, sortName: `` },
{ id: `22`, str: `小野 美苗`, imagePath: `CHU_UI_MapIcon_00000022.dds`, sortName: `` },
{ id: `23`, str: `渋沢 `, imagePath: `CHU_UI_MapIcon_00000023.dds`, sortName: `` },
{ id: `24`, str: `葛城 華`, imagePath: `CHU_UI_MapIcon_00000024.dds`, sortName: `` },
{ id: `25`, str: `新井 桃子`, imagePath: `CHU_UI_MapIcon_00000025.dds`, sortName: `` },
{ id: `26`, str: `MIR-201【ヘカティ・ベアトリクス】`, imagePath: `CHU_UI_MapIcon_00000026.dds`, sortName: `M` },
{ id: `27`, str: `テスタメントネメシス`, imagePath: `CHU_UI_MapIcon_00000027.dds`, sortName: `` },
{ id: `28`, str: `DJ-MEGA`, imagePath: `CHU_UI_MapIcon_00000028.dds`, sortName: `D` },
{ id: `29`, str: `藤堂 陽南袴`, imagePath: `CHU_UI_MapIcon_00000029.dds`, sortName: `` },
{ id: `30`, str: `桔梗 小夜曲`, imagePath: `CHU_UI_MapIcon_00000030.dds`, sortName: `` },
{ id: `31`, str: `MDA-01【シリウス】`, imagePath: `CHU_UI_MapIcon_00000031.dds`, sortName: `M` },
{ id: `32`, str: `芒崎 奏`, imagePath: `CHU_UI_MapIcon_00000032.dds`, sortName: `` },
{ id: `33`, str: `ティフォン`, imagePath: `CHU_UI_MapIcon_00000033.dds`, sortName: `` },
{ id: `34`, str: `イングリット・オーリック・コーネル`, imagePath: `CHU_UI_MapIcon_00000034.dds`, sortName: `` },
{ id: `35`, str: `シルヴィアス`, imagePath: `CHU_UI_MapIcon_00000035.dds`, sortName: `` },
{ id: `36`, str: `ジョニー・サイアスティン`, imagePath: `CHU_UI_MapIcon_00000036.dds`, sortName: `` },
{ id: `37`, str: `魔法使いアルテラ`, imagePath: `CHU_UI_MapIcon_00000037.dds`, sortName: `` },
{ id: `38`, str: `新田 ちえ`, imagePath: `CHU_UI_MapIcon_00000038.dds`, sortName: `` },
{ id: `39`, str: `MDA-21【レグルス】`, imagePath: `CHU_UI_MapIcon_00000039.dds`, sortName: `M` },
{ id: `40`, str: `ジュナ・サラキア`, imagePath: `CHU_UI_MapIcon_00000040.dds`, sortName: `` },
{ id: `41`, str: `マリーメイア・クレスケンス`, imagePath: `CHU_UI_MapIcon_00000041.dds`, sortName: `` },
{ id: `42`, str: `伊賀崎ノ楠子`, imagePath: `CHU_UI_MapIcon_00000042.dds`, sortName: `` },
{ id: `43`, str: `ワイズマン`, imagePath: `CHU_UI_MapIcon_00000043.dds`, sortName: `` },
{ id: `44`, str: `ヴェルゼビュートネメシス`, imagePath: `CHU_UI_MapIcon_00000044.dds`, sortName: `` },
{ id: `45`, str: `イロドリミドリ/色彩過剰のダイアリーミュージック`, imagePath: `CHU_UI_MapIcon_00000045.dds`, sortName: `` },
{ id: `46`, str: `オールドブルー`, imagePath: `CHU_UI_MapIcon_00000046.dds`, sortName: `` },
{ id: `47`, str: `クーデルカ・プルミエール`, imagePath: `CHU_UI_MapIcon_00000047.dds`, sortName: `` },
{ id: `48`, str: `エイハヴ`, imagePath: `CHU_UI_MapIcon_00000048.dds`, sortName: `` },
{ id: `49`, str: `第八皇女エルルーン`, imagePath: `CHU_UI_MapIcon_00000049.dds`, sortName: `` },
{ id: `50`, str: `宍戸 美鈴`, imagePath: `CHU_UI_MapIcon_00000050.dds`, sortName: `` },
{ id: `51`, str: `リー・メイメイ`, imagePath: `CHU_UI_MapIcon_00000051.dds`, sortName: `` },
{ id: `52`, str: `ティータ・アヴェニアス`, imagePath: `CHU_UI_MapIcon_00000052.dds`, sortName: `` },
{ id: `53`, str: `MIR-203【セレネ・シェリル】`, imagePath: `CHU_UI_MapIcon_00000053.dds`, sortName: `M` },
]

564
src/lib/nameplate.ts Normal file
View File

@ -0,0 +1,564 @@
export const nameplate = [
{ id: `1`, str: `ノーマル`, imagePath: `CHU_UI_NamePlate_00000001.dds`, sortName: `` },
{ id: `2`, str: `チュウニペンギン`, imagePath: `CHU_UI_NamePlate_00000002.dds`, sortName: `` },
{ id: `3`, str: `AIR`, imagePath: `CHU_UI_NamePlate_00000003.dds`, sortName: `A` },
{ id: `4`, str: `あの日見た花の名前を僕達はまだ知らない。`, imagePath: `CHU_UI_NamePlate_00000004.dds`, sortName: `` },
{ id: `5`, str: `イロドリミドリ`, imagePath: `CHU_UI_NamePlate_00000005.dds`, sortName: `` },
{ id: `6`, str: `初音ミク/マイディアバニー`, imagePath: `CHU_UI_NamePlate_00000006.dds`, sortName: `` },
{ id: `7`, str: `東方紅魔郷`, imagePath: `CHU_UI_NamePlate_00000007.dds`, sortName: `` },
{ id: `8`, str: `東方妖々夢`, imagePath: `CHU_UI_NamePlate_00000008.dds`, sortName: `` },
{ id: `9`, str: `東方永夜抄`, imagePath: `CHU_UI_NamePlate_00000009.dds`, sortName: `` },
{ id: `10`, str: `ノーゲーム・ノーライフ 【1】`, imagePath: `CHU_UI_NamePlate_00000010.dds`, sortName: `` },
{ id: `11`, str: `冴えない彼女の育てかた`, imagePath: `CHU_UI_NamePlate_00000011.dds`, sortName: `` },
{ id: `12`, str: `干物妹!うまるちゃん`, imagePath: `CHU_UI_NamePlate_00000012.dds`, sortName: `` },
{ id: `14`, str: `僕は友達が少ないNEXT 【1】`, imagePath: `CHU_UI_NamePlate_00000014.dds`, sortName: `` },
{ id: `15`, str: `ミカグラ学園組曲`, imagePath: `CHU_UI_NamePlate_00000015.dds`, sortName: `` },
{ id: `16`, str: `PRIUS! IMPOSSIBLE GIRLS`, imagePath: `CHU_UI_NamePlate_00000016.dds`, sortName: `P` },
{ id: `17`, str: `ご注文はうさぎですか?? 【1】`, imagePath: `CHU_UI_NamePlate_00000017.dds`, sortName: `` },
{ id: `18`, str: `チェインクロニクル ~ヘクセイタスの閃~`, imagePath: `CHU_UI_NamePlate_00000018.dds`, sortName: `` },
{ id: `19`, str: `ラグナロクオンライン`, imagePath: `CHU_UI_NamePlate_00000019.dds`, sortName: `` },
{ id: `20`, str: `ばくおん!!`, imagePath: `CHU_UI_NamePlate_00000020.dds`, sortName: `` },
{ id: `21`, str: `蒼き鋼のアルペジオ -アルス・ノヴァ-`, imagePath: `CHU_UI_NamePlate_00000021.dds`, sortName: `` },
{ id: `22`, str: `きんいろモザイク 【1】`, imagePath: `CHU_UI_NamePlate_00000022.dds`, sortName: `` },
{ id: `23`, str: `Tokyo 7th シスターズ/セブンスシスターズ`, imagePath: `CHU_UI_NamePlate_00000023.dds`, sortName: `T` },
{ id: `24`, str: `カゲロウプロジェクト`, imagePath: `CHU_UI_NamePlate_00000024.dds`, sortName: `` },
{ id: `25`, str: `イロドリミドリ(月鈴姉妹)`, imagePath: `CHU_UI_NamePlate_00000025.dds`, sortName: `` },
{ id: `26`, str: `東方Extra`, imagePath: `CHU_UI_NamePlate_00000026.dds`, sortName: `` },
{ id: `27`, str: `三者三葉 【1】`, imagePath: `CHU_UI_NamePlate_00000027.dds`, sortName: `` },
{ id: `28`, str: `Angel Beats!`, imagePath: `CHU_UI_NamePlate_00000028.dds`, sortName: `A` },
{ id: `30`, str: `葉Project 【1】`, imagePath: `CHU_UI_NamePlate_00000030.dds`, sortName: `` },
{ id: `31`, str: `君の名は。 【1】`, imagePath: `CHU_UI_NamePlate_00000031.dds`, sortName: `` },
{ id: `32`, str: `君の名は。 【2】`, imagePath: `CHU_UI_NamePlate_00000032.dds`, sortName: `` },
{ id: `33`, str: `Re:ゼロから始める異世界生活 【1】`, imagePath: `CHU_UI_NamePlate_00000033.dds`, sortName: `R` },
{ id: `34`, str: `Re:ゼロから始める異世界生活 【2】`, imagePath: `CHU_UI_NamePlate_00000034.dds`, sortName: `R` },
{ id: `35`, str: `化物語`, imagePath: `CHU_UI_NamePlate_00000035.dds`, sortName: `` },
{ id: `36`, str: `葉Project 【2】`, imagePath: `CHU_UI_NamePlate_00000036.dds`, sortName: `` },
{ id: `37`, str: `NEW GAME! 【1】`, imagePath: `CHU_UI_NamePlate_00000037.dds`, sortName: `N` },
{ id: `38`, str: `NEW GAME! 【2】`, imagePath: `CHU_UI_NamePlate_00000038.dds`, sortName: `N` },
{ id: `39`, str: `魔法少女まどか☆マギカ 【1】`, imagePath: `CHU_UI_NamePlate_00000039.dds`, sortName: `` },
{ id: `40`, str: `魔法少女まどか☆マギカ 【2】`, imagePath: `CHU_UI_NamePlate_00000040.dds`, sortName: `` },
{ id: `41`, str: `イロドリミドリ Live!`, imagePath: `CHU_UI_NamePlate_00000041.dds`, sortName: `` },
{ id: `42`, str: `東方風神録`, imagePath: `CHU_UI_NamePlate_00000042.dds`, sortName: `` },
{ id: `43`, str: `東方Project 【1】`, imagePath: `CHU_UI_NamePlate_00000043.dds`, sortName: `` },
{ id: `44`, str: `結城友奈は勇者である 【1】`, imagePath: `CHU_UI_NamePlate_00000044.dds`, sortName: `` },
{ id: `45`, str: `結城友奈は勇者である 【2】`, imagePath: `CHU_UI_NamePlate_00000045.dds`, sortName: `` },
{ id: `46`, str: `とらドラ! 【1】`, imagePath: `CHU_UI_NamePlate_00000046.dds`, sortName: `` },
{ id: `47`, str: `とらドラ! 【2】`, imagePath: `CHU_UI_NamePlate_00000047.dds`, sortName: `` },
{ id: `48`, str: `バーチャル・シンガー 【1】`, imagePath: `CHU_UI_NamePlate_00000048.dds`, sortName: `` },
{ id: `49`, str: `バーチャル・シンガー 【2】`, imagePath: `CHU_UI_NamePlate_00000049.dds`, sortName: `` },
{ id: `50`, str: `Hi☆sCoool! セハガール 【1】`, imagePath: `CHU_UI_NamePlate_00000050.dds`, sortName: `H` },
{ id: `51`, str: `PHANTASY STAR ONLINE 2 【1】`, imagePath: `CHU_UI_NamePlate_00000051.dds`, sortName: `P` },
{ id: `52`, str: `PHANTASY STAR ONLINE 2 【2】`, imagePath: `CHU_UI_NamePlate_00000052.dds`, sortName: `P` },
{ id: `53`, str: `ご注文はうさぎですか?? 【2】`, imagePath: `CHU_UI_NamePlate_00000053.dds`, sortName: `` },
{ id: `54`, str: `うたわれるもの 偽りの仮面 【1】`, imagePath: `CHU_UI_NamePlate_00000054.dds`, sortName: `` },
{ id: `55`, str: `うたわれるもの 偽りの仮面 【2】`, imagePath: `CHU_UI_NamePlate_00000055.dds`, sortName: `` },
{ id: `56`, str: `ラストバトル`, imagePath: `CHU_UI_NamePlate_00000056.dds`, sortName: `` },
{ id: `57`, str: `うたわれるもの 二人の白皇 【1】`, imagePath: `CHU_UI_NamePlate_00000057.dds`, sortName: `` },
{ id: `58`, str: `うたわれるもの 二人の白皇 【2】`, imagePath: `CHU_UI_NamePlate_00000058.dds`, sortName: `` },
{ id: `59`, str: `戦姫絶唱シンフォギアG 【1】`, imagePath: `CHU_UI_NamePlate_00000059.dds`, sortName: `` },
{ id: `60`, str: `戦姫絶唱シンフォギアG 【2】`, imagePath: `CHU_UI_NamePlate_00000060.dds`, sortName: `` },
{ id: `61`, str: `アキバ帝国`, imagePath: `CHU_UI_NamePlate_00000061.dds`, sortName: `` },
{ id: `62`, str: `GEMINI -C-`, imagePath: `CHU_UI_NamePlate_00000062.dds`, sortName: `G` },
{ id: `63`, str: `Contrapasso -inferno-`, imagePath: `CHU_UI_NamePlate_00000063.dds`, sortName: `C` },
{ id: `64`, str: `京急電鉄 駅名看板`, imagePath: `CHU_UI_NamePlate_00000064.dds`, sortName: `` },
{ id: `65`, str: `アテインリレイション`, imagePath: `CHU_UI_NamePlate_00000065.dds`, sortName: `` },
{ id: `66`, str: `エロマンガ先生 【1】`, imagePath: `CHU_UI_NamePlate_00000066.dds`, sortName: `` },
{ id: `67`, str: `エロマンガ先生 【2】`, imagePath: `CHU_UI_NamePlate_00000067.dds`, sortName: `` },
{ id: `68`, str: `ノラと皇女と野良猫ハート 【1】`, imagePath: `CHU_UI_NamePlate_00000068.dds`, sortName: `` },
{ id: `69`, str: `ノラと皇女と野良猫ハート 【2】`, imagePath: `CHU_UI_NamePlate_00000069.dds`, sortName: `` },
{ id: `70`, str: `Re:ゼロから始める異世界生活 【3】`, imagePath: `CHU_UI_NamePlate_00000070.dds`, sortName: `R` },
{ id: `71`, str: `#コンパス 【1】`, imagePath: `CHU_UI_NamePlate_00000071.dds`, sortName: `` },
{ id: `72`, str: `#コンパス 【2】`, imagePath: `CHU_UI_NamePlate_00000072.dds`, sortName: `` },
{ id: `73`, str: `温泉むすめ 【1】`, imagePath: `CHU_UI_NamePlate_00000073.dds`, sortName: `` },
{ id: `74`, str: `温泉むすめ 【2】`, imagePath: `CHU_UI_NamePlate_00000074.dds`, sortName: `` },
{ id: `75`, str: `温泉むすめ 【3】`, imagePath: `CHU_UI_NamePlate_00000075.dds`, sortName: `` },
{ id: `76`, str: `MANIAなBEAT`, imagePath: `CHU_UI_NamePlate_00000076.dds`, sortName: `M` },
{ id: `77`, str: `東方Extra 2`, imagePath: `CHU_UI_NamePlate_00000077.dds`, sortName: `` },
{ id: `78`, str: `東方Project 【2】`, imagePath: `CHU_UI_NamePlate_00000078.dds`, sortName: `` },
{ id: `79`, str: `東方Project 【3】`, imagePath: `CHU_UI_NamePlate_00000079.dds`, sortName: `` },
{ id: `80`, str: `SeelischTact`, imagePath: `CHU_UI_NamePlate_00000080.dds`, sortName: `S` },
{ id: `81`, str: `天使の3P 【1】`, imagePath: `CHU_UI_NamePlate_00000081.dds`, sortName: `` },
{ id: `82`, str: `天使の3P 【2】`, imagePath: `CHU_UI_NamePlate_00000082.dds`, sortName: `` },
{ id: `83`, str: `ノーゲーム・ノーライフ 【2】`, imagePath: `CHU_UI_NamePlate_00000083.dds`, sortName: `` },
{ id: `84`, str: `スターダストメモリーズ`, imagePath: `CHU_UI_NamePlate_00000084.dds`, sortName: `` },
{ id: `85`, str: `ツインエンジェルBREAK 【1】`, imagePath: `CHU_UI_NamePlate_00000085.dds`, sortName: `` },
{ id: `86`, str: `ツインエンジェルBREAK 【2】`, imagePath: `CHU_UI_NamePlate_00000086.dds`, sortName: `` },
{ id: `87`, str: `ツインエンジェルBREAK 【3】`, imagePath: `CHU_UI_NamePlate_00000087.dds`, sortName: `` },
{ id: `88`, str: `ガヴリールドロップアウト 【1】`, imagePath: `CHU_UI_NamePlate_00000088.dds`, sortName: `` },
{ id: `89`, str: `ガヴリールドロップアウト 【2】`, imagePath: `CHU_UI_NamePlate_00000089.dds`, sortName: `` },
{ id: `90`, str: `うたわれるもの 二人の白皇 【3】`, imagePath: `CHU_UI_NamePlate_00000090.dds`, sortName: `` },
{ id: `91`, str: `うたわれるもの 二人の白皇 【4】`, imagePath: `CHU_UI_NamePlate_00000091.dds`, sortName: `` },
{ id: `94`, str: `Wonderland Wars 【1】`, imagePath: `CHU_UI_NamePlate_00000094.dds`, sortName: `W` },
{ id: `95`, str: `Wonderland Wars 【2】`, imagePath: `CHU_UI_NamePlate_00000095.dds`, sortName: `W` },
{ id: `96`, str: `アストラル・リベレイション`, imagePath: `CHU_UI_NamePlate_00000096.dds`, sortName: `` },
{ id: `97`, str: `この素晴らしい世界に祝福を2 【1】`, imagePath: `CHU_UI_NamePlate_00000097.dds`, sortName: `` },
{ id: `98`, str: `この素晴らしい世界に祝福を2 【2】`, imagePath: `CHU_UI_NamePlate_00000098.dds`, sortName: `` },
{ id: `99`, str: `ひなこのーと 【1】`, imagePath: `CHU_UI_NamePlate_00000099.dds`, sortName: `` },
{ id: `100`, str: `ひなこのーと 【2】`, imagePath: `CHU_UI_NamePlate_00000100.dds`, sortName: `` },
{ id: `101`, str: `福音の書`, imagePath: `CHU_UI_NamePlate_00000101.dds`, sortName: `` },
{ id: `102`, str: `僕は友達が少ないNEXT 【2】`, imagePath: `CHU_UI_NamePlate_00000102.dds`, sortName: `` },
{ id: `103`, str: `てーきゅう 【1】`, imagePath: `CHU_UI_NamePlate_00000103.dds`, sortName: `` },
{ id: `104`, str: `てーきゅう 【2】`, imagePath: `CHU_UI_NamePlate_00000104.dds`, sortName: `` },
{ id: `105`, str: `NAOKI`, imagePath: `CHU_UI_NamePlate_00000105.dds`, sortName: `N` },
{ id: `106`, str: `新甲虫王者ムシキング 【1】`, imagePath: `CHU_UI_NamePlate_00000106.dds`, sortName: `` },
{ id: `107`, str: `新甲虫王者ムシキング 【2】`, imagePath: `CHU_UI_NamePlate_00000107.dds`, sortName: `` },
{ id: `108`, str: `新甲虫王者ムシキング 【3】`, imagePath: `CHU_UI_NamePlate_00000108.dds`, sortName: `` },
{ id: `109`, str: `新甲虫王者ムシキング 【4】`, imagePath: `CHU_UI_NamePlate_00000109.dds`, sortName: `` },
{ id: `111`, str: `KING OF BAND '18`, imagePath: `CHU_UI_NamePlate_00000111.dds`, sortName: `K` },
{ id: `112`, str: `とある科学の超電磁砲S 【1】`, imagePath: `CHU_UI_NamePlate_00000112.dds`, sortName: `` },
{ id: `113`, str: `とある科学の超電磁砲S 【2】`, imagePath: `CHU_UI_NamePlate_00000113.dds`, sortName: `` },
{ id: `114`, str: `とある科学の超電磁砲S 【3】`, imagePath: `CHU_UI_NamePlate_00000114.dds`, sortName: `` },
{ id: `115`, str: `ポプテピピック 【1】`, imagePath: `CHU_UI_NamePlate_00000115.dds`, sortName: `` },
{ id: `116`, str: `ポプテピピック 【2】`, imagePath: `CHU_UI_NamePlate_00000116.dds`, sortName: `` },
{ id: `117`, str: `ポプテピピック 【3】`, imagePath: `CHU_UI_NamePlate_00000117.dds`, sortName: `` },
{ id: `118`, str: `GOD`, imagePath: `CHU_UI_NamePlate_00000118.dds`, sortName: `G` },
{ id: `119`, str: `東方地霊殿`, imagePath: `CHU_UI_NamePlate_00000119.dds`, sortName: `` },
{ id: `120`, str: `東方Project 【4】`, imagePath: `CHU_UI_NamePlate_00000120.dds`, sortName: `` },
{ id: `121`, str: `東方Project 【5】`, imagePath: `CHU_UI_NamePlate_00000121.dds`, sortName: `` },
{ id: `122`, str: `元祖アイドルプロデューサー`, imagePath: `CHU_UI_NamePlate_00000122.dds`, sortName: `` },
{ id: `123`, str: `りゅうおうのおしごと! 【1】`, imagePath: `CHU_UI_NamePlate_00000123.dds`, sortName: `` },
{ id: `124`, str: `りゅうおうのおしごと! 【2】`, imagePath: `CHU_UI_NamePlate_00000124.dds`, sortName: `` },
{ id: `125`, str: `ペルソナ5 ダンシング・スターナイト 【1】`, imagePath: `CHU_UI_NamePlate_00000125.dds`, sortName: `` },
{ id: `126`, str: `ペルソナ5 ダンシング・スターナイト 【2】`, imagePath: `CHU_UI_NamePlate_00000126.dds`, sortName: `` },
{ id: `127`, str: `ペルソナ4 ダンシング・オールナイト 【1】`, imagePath: `CHU_UI_NamePlate_00000127.dds`, sortName: `` },
{ id: `128`, str: `ペルソナ4 ダンシング・オールナイト 【2】`, imagePath: `CHU_UI_NamePlate_00000128.dds`, sortName: `` },
{ id: `129`, str: `月鈴 白奈`, imagePath: `CHU_UI_NamePlate_00000129.dds`, sortName: `` },
{ id: `130`, str: `ペルソナ3 ダンシング・ムーンナイト 【1】`, imagePath: `CHU_UI_NamePlate_00000130.dds`, sortName: `` },
{ id: `131`, str: `ペルソナ3 ダンシング・ムーンナイト 【2】`, imagePath: `CHU_UI_NamePlate_00000131.dds`, sortName: `` },
{ id: `132`, str: `バーチャル・シンガー 【3】`, imagePath: `CHU_UI_NamePlate_00000132.dds`, sortName: `` },
{ id: `133`, str: `バーチャル・シンガー 【4】`, imagePath: `CHU_UI_NamePlate_00000133.dds`, sortName: `` },
{ id: `134`, str: `宇宙よりも遠い場所 【1】`, imagePath: `CHU_UI_NamePlate_00000134.dds`, sortName: `` },
{ id: `135`, str: `宇宙よりも遠い場所 【2】`, imagePath: `CHU_UI_NamePlate_00000135.dds`, sortName: `` },
{ id: `136`, str: `箱部 なる`, imagePath: `CHU_UI_NamePlate_00000136.dds`, sortName: `` },
{ id: `137`, str: `ようこそ!ハッピーアニマリア`, imagePath: `CHU_UI_NamePlate_00000137.dds`, sortName: `` },
{ id: `138`, str: `咲-Saki-阿知賀編 episode of side-A 【1】`, imagePath: `CHU_UI_NamePlate_00000138.dds`, sortName: `` },
{ id: `139`, str: `咲-Saki-阿知賀編 episode of side-A 【2】`, imagePath: `CHU_UI_NamePlate_00000139.dds`, sortName: `` },
{ id: `140`, str: `きんいろモザイク 【2】`, imagePath: `CHU_UI_NamePlate_00000140.dds`, sortName: `` },
{ id: `141`, str: `きんいろモザイク 【3】`, imagePath: `CHU_UI_NamePlate_00000141.dds`, sortName: `` },
{ id: `142`, str: `スザク`, imagePath: `CHU_UI_NamePlate_00000142.dds`, sortName: `` },
{ id: `143`, str: `トリニティヴァーテックス`, imagePath: `CHU_UI_NamePlate_00000143.dds`, sortName: `` },
{ id: `144`, str: `オーバーロード 【1】`, imagePath: `CHU_UI_NamePlate_00000144.dds`, sortName: `` },
{ id: `145`, str: `オーバーロード 【2】`, imagePath: `CHU_UI_NamePlate_00000145.dds`, sortName: `` },
{ id: `146`, str: `三者三葉 【2】`, imagePath: `CHU_UI_NamePlate_00000146.dds`, sortName: `` },
{ id: `147`, str: `三者三葉 【3】`, imagePath: `CHU_UI_NamePlate_00000147.dds`, sortName: `` },
{ id: `148`, str: `天王洲 なずな`, imagePath: `CHU_UI_NamePlate_00000148.dds`, sortName: `` },
{ id: `149`, str: `アトリエ ~アーランドの錬金術士~ 【1】`, imagePath: `CHU_UI_NamePlate_00000149.dds`, sortName: `` },
{ id: `150`, str: `アトリエ ~アーランドの錬金術士~ 【2】`, imagePath: `CHU_UI_NamePlate_00000150.dds`, sortName: `` },
{ id: `151`, str: `アトリエ ~アーランドの錬金術士~ 【3】`, imagePath: `CHU_UI_NamePlate_00000151.dds`, sortName: `` },
{ id: `152`, str: `光吉 猛修/謎`, imagePath: `CHU_UI_NamePlate_00000152.dds`, sortName: `` },
{ id: `153`, str: `松丸 亮吾/謎`, imagePath: `CHU_UI_NamePlate_00000153.dds`, sortName: `` },
{ id: `154`, str: `幻想英雄伝‐目覚めし紋章の力‐`, imagePath: `CHU_UI_NamePlate_00000154.dds`, sortName: `` },
{ id: `155`, str: `グランブルーファンタジー 【1】`, imagePath: `CHU_UI_NamePlate_00000155.dds`, sortName: `` },
{ id: `156`, str: `グランブルーファンタジー 【2】`, imagePath: `CHU_UI_NamePlate_00000156.dds`, sortName: `` },
{ id: `157`, str: `グランブルーファンタジー 【3】`, imagePath: `CHU_UI_NamePlate_00000157.dds`, sortName: `` },
{ id: `158`, str: `グランブルーファンタジー 【4】`, imagePath: `CHU_UI_NamePlate_00000158.dds`, sortName: `` },
{ id: `159`, str: `ゆるキャン△ 【1】`, imagePath: `CHU_UI_NamePlate_00000159.dds`, sortName: `` },
{ id: `160`, str: `ゆるキャン△ 【2】`, imagePath: `CHU_UI_NamePlate_00000160.dds`, sortName: `` },
{ id: `161`, str: `ポプテピピック 【4】`, imagePath: `CHU_UI_NamePlate_00000161.dds`, sortName: `` },
{ id: `162`, str: `ポプテピピック 【5】`, imagePath: `CHU_UI_NamePlate_00000162.dds`, sortName: `` },
{ id: `163`, str: `ポプテピピック 【6】`, imagePath: `CHU_UI_NamePlate_00000163.dds`, sortName: `` },
{ id: `164`, str: `明坂 芹菜`, imagePath: `CHU_UI_NamePlate_00000164.dds`, sortName: `` },
{ id: `165`, str: `東方天空璋`, imagePath: `CHU_UI_NamePlate_00000165.dds`, sortName: `` },
{ id: `166`, str: `東方Project 【6】`, imagePath: `CHU_UI_NamePlate_00000166.dds`, sortName: `` },
{ id: `167`, str: `トリスメギストス`, imagePath: `CHU_UI_NamePlate_00000167.dds`, sortName: `` },
{ id: `168`, str: `天獄と魔縁`, imagePath: `CHU_UI_NamePlate_00000168.dds`, sortName: `` },
{ id: `169`, str: `Arcaea 【1】`, imagePath: `CHU_UI_NamePlate_00000169.dds`, sortName: `A` },
{ id: `170`, str: `Arcaea 【2】`, imagePath: `CHU_UI_NamePlate_00000170.dds`, sortName: `A` },
{ id: `171`, str: `MIR-202【アルテミス・レナ】`, imagePath: `CHU_UI_NamePlate_00000171.dds`, sortName: `M` },
{ id: `172`, str: `Tokyo 7th シスターズ 4U The QUEEN of PURPLE 【1】`, imagePath: `CHU_UI_NamePlate_00000172.dds`, sortName: `T` },
{ id: `173`, str: `Tokyo 7th シスターズ 4U The QUEEN of PURPLE 【2】`, imagePath: `CHU_UI_NamePlate_00000173.dds`, sortName: `T` },
{ id: `174`, str: `Tokyo 7th シスターズ 4U The QUEEN of PURPLE 【3】`, imagePath: `CHU_UI_NamePlate_00000174.dds`, sortName: `T` },
{ id: `175`, str: `Tokyo 7th シスターズ 4U The QUEEN of PURPLE 【4】`, imagePath: `CHU_UI_NamePlate_00000175.dds`, sortName: `T` },
{ id: `176`, str: `ガヴリールドロップアウト 【3】`, imagePath: `CHU_UI_NamePlate_00000176.dds`, sortName: `` },
{ id: `177`, str: `ガヴリールドロップアウト 【4】`, imagePath: `CHU_UI_NamePlate_00000177.dds`, sortName: `` },
{ id: `178`, str: `ES計画`, imagePath: `CHU_UI_NamePlate_00000178.dds`, sortName: `E` },
{ id: `179`, str: `龍が如く 【1】`, imagePath: `CHU_UI_NamePlate_00000179.dds`, sortName: `` },
{ id: `180`, str: `龍が如く 【2】`, imagePath: `CHU_UI_NamePlate_00000180.dds`, sortName: `` },
{ id: `181`, str: `ヒナまつり 【1】`, imagePath: `CHU_UI_NamePlate_00000181.dds`, sortName: `` },
{ id: `182`, str: `ヒナまつり 【2】`, imagePath: `CHU_UI_NamePlate_00000182.dds`, sortName: `` },
{ id: `183`, str: `小仏 凪`, imagePath: `CHU_UI_NamePlate_00000183.dds`, sortName: `` },
{ id: `184`, str: `はるかなレシーブ 【1】`, imagePath: `CHU_UI_NamePlate_00000184.dds`, sortName: `` },
{ id: `185`, str: `はるかなレシーブ 【2】`, imagePath: `CHU_UI_NamePlate_00000185.dds`, sortName: `` },
{ id: `186`, str: `新甲虫王者ムシキング 【5】`, imagePath: `CHU_UI_NamePlate_00000186.dds`, sortName: `` },
{ id: `187`, str: `新甲虫王者ムシキング 【6】`, imagePath: `CHU_UI_NamePlate_00000187.dds`, sortName: `` },
{ id: `188`, str: `新甲虫王者ムシキング 【7】`, imagePath: `CHU_UI_NamePlate_00000188.dds`, sortName: `` },
{ id: `189`, str: `新甲虫王者ムシキング 【8】`, imagePath: `CHU_UI_NamePlate_00000189.dds`, sortName: `` },
{ id: `190`, str: `ノラと皇女と野良猫ハート 【3】`, imagePath: `CHU_UI_NamePlate_00000190.dds`, sortName: `` },
{ id: `191`, str: `ノラと皇女と野良猫ハート 【4】`, imagePath: `CHU_UI_NamePlate_00000191.dds`, sortName: `` },
{ id: `192`, str: `赤月城ヴァムピーラ`, imagePath: `CHU_UI_NamePlate_00000192.dds`, sortName: `` },
{ id: `193`, str: `御形 アリシアナ`, imagePath: `CHU_UI_NamePlate_00000193.dds`, sortName: `` },
{ id: `194`, str: `プリンセス・プリンシパル 【1】`, imagePath: `CHU_UI_NamePlate_00000194.dds`, sortName: `` },
{ id: `195`, str: `プリンセス・プリンシパル 【2】`, imagePath: `CHU_UI_NamePlate_00000195.dds`, sortName: `` },
{ id: `196`, str: `プリンセス・プリンシパル 【3】`, imagePath: `CHU_UI_NamePlate_00000196.dds`, sortName: `` },
{ id: `197`, str: `プリンセス・プリンシパル 【4】`, imagePath: `CHU_UI_NamePlate_00000197.dds`, sortName: `` },
{ id: `198`, str: `温泉むすめ 【4】`, imagePath: `CHU_UI_NamePlate_00000198.dds`, sortName: `` },
{ id: `199`, str: `温泉むすめ 【5】`, imagePath: `CHU_UI_NamePlate_00000199.dds`, sortName: `` },
{ id: `200`, str: `温泉むすめ 【6】`, imagePath: `CHU_UI_NamePlate_00000200.dds`, sortName: `` },
{ id: `201`, str: `リリアリス・コルチカム`, imagePath: `CHU_UI_NamePlate_00000201.dds`, sortName: `` },
{ id: `202`, str: `たまゆらリレイション`, imagePath: `CHU_UI_NamePlate_00000202.dds`, sortName: `` },
{ id: `203`, str: `魔法少女リリカルなのは Detonation 【1】`, imagePath: `CHU_UI_NamePlate_00000203.dds`, sortName: `` },
{ id: `204`, str: `魔法少女リリカルなのは Detonation 【2】`, imagePath: `CHU_UI_NamePlate_00000204.dds`, sortName: `` },
{ id: `205`, str: `魔法少女リリカルなのは Detonation 【3】`, imagePath: `CHU_UI_NamePlate_00000205.dds`, sortName: `` },
{ id: `206`, str: `異世界食堂 【1】`, imagePath: `CHU_UI_NamePlate_00000206.dds`, sortName: `` },
{ id: `207`, str: `異世界食堂 【2】`, imagePath: `CHU_UI_NamePlate_00000207.dds`, sortName: `` },
{ id: `208`, str: `異世界食堂 【3】`, imagePath: `CHU_UI_NamePlate_00000208.dds`, sortName: `` },
{ id: `209`, str: `異世界食堂 【4】`, imagePath: `CHU_UI_NamePlate_00000209.dds`, sortName: `` },
{ id: `210`, str: `天使の3P 【3】`, imagePath: `CHU_UI_NamePlate_00000210.dds`, sortName: `` },
{ id: `211`, str: `天使の3P 【4】`, imagePath: `CHU_UI_NamePlate_00000211.dds`, sortName: `` },
{ id: `212`, str: `月鈴 那知`, imagePath: `CHU_UI_NamePlate_00000212.dds`, sortName: `` },
{ id: `213`, str: `アトリエ ~アーランドの錬金術士~ 【4】`, imagePath: `CHU_UI_NamePlate_00000213.dds`, sortName: `` },
{ id: `214`, str: `アトリエ ~アーランドの錬金術士~ 【5】`, imagePath: `CHU_UI_NamePlate_00000214.dds`, sortName: `` },
{ id: `215`, str: `ショウニペンギンAIR`, imagePath: `CHU_UI_NamePlate_00000215.dds`, sortName: `` },
{ id: `216`, str: `KING OF BAND '19`, imagePath: `CHU_UI_NamePlate_00000216.dds`, sortName: `K` },
{ id: `217`, str: `魔法科高校の劣等生 【1】`, imagePath: `CHU_UI_NamePlate_00000217.dds`, sortName: `` },
{ id: `218`, str: `魔法科高校の劣等生 【2】`, imagePath: `CHU_UI_NamePlate_00000218.dds`, sortName: `` },
{ id: `219`, str: `魔法科高校の劣等生 【3】`, imagePath: `CHU_UI_NamePlate_00000219.dds`, sortName: `` },
{ id: `220`, str: `魔法科高校の劣等生 【4】`, imagePath: `CHU_UI_NamePlate_00000220.dds`, sortName: `` },
{ id: `221`, str: `魔法科高校の劣等生 【5】`, imagePath: `CHU_UI_NamePlate_00000221.dds`, sortName: `` },
{ id: `222`, str: `SSSS.GRIDMAN 【1】`, imagePath: `CHU_UI_NamePlate_00000222.dds`, sortName: `S` },
{ id: `223`, str: `SSSS.GRIDMAN 【2】`, imagePath: `CHU_UI_NamePlate_00000223.dds`, sortName: `S` },
{ id: `224`, str: `エロマンガ先生 【3】`, imagePath: `CHU_UI_NamePlate_00000224.dds`, sortName: `` },
{ id: `225`, str: `八咫烏 鋼太郎`, imagePath: `CHU_UI_NamePlate_00000225.dds`, sortName: `` },
{ id: `226`, str: `結月ゆかり`, imagePath: `CHU_UI_NamePlate_00000226.dds`, sortName: `` },
{ id: `227`, str: `紲星あかり`, imagePath: `CHU_UI_NamePlate_00000227.dds`, sortName: `` },
{ id: `228`, str: `琴葉 茜・葵 【1】`, imagePath: `CHU_UI_NamePlate_00000228.dds`, sortName: `` },
{ id: `229`, str: `PHANTASY STAR ONLINE 2 【3】`, imagePath: `CHU_UI_NamePlate_00000229.dds`, sortName: `P` },
{ id: `230`, str: `PHANTASY STAR ONLINE 2 【4】`, imagePath: `CHU_UI_NamePlate_00000230.dds`, sortName: `P` },
{ id: `231`, str: `GN計画`, imagePath: `CHU_UI_NamePlate_00000231.dds`, sortName: `G` },
{ id: `232`, str: `ネコぱら 【1】`, imagePath: `CHU_UI_NamePlate_00000232.dds`, sortName: `` },
{ id: `233`, str: `ネコぱら 【2】`, imagePath: `CHU_UI_NamePlate_00000233.dds`, sortName: `` },
{ id: `234`, str: `ネコぱら 【3】`, imagePath: `CHU_UI_NamePlate_00000234.dds`, sortName: `` },
{ id: `235`, str: `ネコぱら 【4】`, imagePath: `CHU_UI_NamePlate_00000235.dds`, sortName: `` },
{ id: `236`, str: `HAR-ヒロイン09【ネレイダム】`, imagePath: `CHU_UI_NamePlate_00000236.dds`, sortName: `H` },
{ id: `237`, str: `とらドラ! 【3】`, imagePath: `CHU_UI_NamePlate_00000237.dds`, sortName: `` },
{ id: `238`, str: `おにまむしけ`, imagePath: `CHU_UI_NamePlate_00000238.dds`, sortName: `` },
{ id: `239`, str: `賭ケグルイ×× 【1】`, imagePath: `CHU_UI_NamePlate_00000239.dds`, sortName: `` },
{ id: `240`, str: `賭ケグルイ×× 【2】`, imagePath: `CHU_UI_NamePlate_00000240.dds`, sortName: `` },
{ id: `241`, str: `てーきゅう 【3】`, imagePath: `CHU_UI_NamePlate_00000241.dds`, sortName: `` },
{ id: `242`, str: `てーきゅう 【4】`, imagePath: `CHU_UI_NamePlate_00000242.dds`, sortName: `` },
{ id: `243`, str: `五十嵐 撫子`, imagePath: `CHU_UI_NamePlate_00000243.dds`, sortName: `` },
{ id: `244`, str: `私に天使が舞い降りた! 【1】`, imagePath: `CHU_UI_NamePlate_00000244.dds`, sortName: `` },
{ id: `245`, str: `私に天使が舞い降りた! 【2】`, imagePath: `CHU_UI_NamePlate_00000245.dds`, sortName: `` },
{ id: `246`, str: `ストライク・ザ・ブラッド 【1】`, imagePath: `CHU_UI_NamePlate_00000246.dds`, sortName: `` },
{ id: `247`, str: `ストライク・ザ・ブラッド 【2】`, imagePath: `CHU_UI_NamePlate_00000247.dds`, sortName: `` },
{ id: `248`, str: `この素晴らしい世界に祝福を2 【3】`, imagePath: `CHU_UI_NamePlate_00000248.dds`, sortName: `` },
{ id: `249`, str: `この素晴らしい世界に祝福を2 【4】`, imagePath: `CHU_UI_NamePlate_00000249.dds`, sortName: `` },
{ id: `250`, str: `ダオ・トッテナ`, imagePath: `CHU_UI_NamePlate_00000250.dds`, sortName: `` },
{ id: `251`, str: `THE DARK SIDE NEMESIS`, imagePath: `CHU_UI_NamePlate_00000251.dds`, sortName: `T` },
{ id: `252`, str: `東方星蓮船`, imagePath: `CHU_UI_NamePlate_00000252.dds`, sortName: `` },
{ id: `253`, str: `東方Project 【7】`, imagePath: `CHU_UI_NamePlate_00000253.dds`, sortName: `` },
{ id: `254`, str: `萩原 七々瀬`, imagePath: `CHU_UI_NamePlate_00000254.dds`, sortName: `` },
{ id: `255`, str: `ゾンビランドサガ 【1】`, imagePath: `CHU_UI_NamePlate_00000255.dds`, sortName: `` },
{ id: `256`, str: `ゾンビランドサガ 【2】`, imagePath: `CHU_UI_NamePlate_00000256.dds`, sortName: `` },
{ id: `257`, str: `Hi☆sCoool! セハガール 【2】`, imagePath: `CHU_UI_NamePlate_00000257.dds`, sortName: `H` },
{ id: `258`, str: `Hi☆sCoool! セハガール 【3】`, imagePath: `CHU_UI_NamePlate_00000258.dds`, sortName: `H` },
{ id: `259`, str: `Hi☆sCoool! セハガール 【4】`, imagePath: `CHU_UI_NamePlate_00000259.dds`, sortName: `H` },
{ id: `260`, str: `THE LIGHT SIDE ORIGIN`, imagePath: `CHU_UI_NamePlate_00000260.dds`, sortName: `T` },
{ id: `261`, str: `ゴブリンスレイヤー 【1】`, imagePath: `CHU_UI_NamePlate_00000261.dds`, sortName: `` },
{ id: `262`, str: `ゴブリンスレイヤー 【2】`, imagePath: `CHU_UI_NamePlate_00000262.dds`, sortName: `` },
{ id: `263`, str: `黒亀 北斗`, imagePath: `CHU_UI_NamePlate_00000263.dds`, sortName: `` },
{ id: `264`, str: `緋弾のアリアAA 【1】`, imagePath: `CHU_UI_NamePlate_00000264.dds`, sortName: `` },
{ id: `265`, str: `緋弾のアリアAA 【2】`, imagePath: `CHU_UI_NamePlate_00000265.dds`, sortName: `` },
{ id: `266`, str: `ストライク・ザ・ブラッド 【3】`, imagePath: `CHU_UI_NamePlate_00000266.dds`, sortName: `` },
{ id: `267`, str: `ストライク・ザ・ブラッド 【4】`, imagePath: `CHU_UI_NamePlate_00000267.dds`, sortName: `` },
{ id: `268`, str: `リヒトシュッツェ`, imagePath: `CHU_UI_NamePlate_00000268.dds`, sortName: `` },
{ id: `269`, str: `ダンベル何キロ持てる? 【1】`, imagePath: `CHU_UI_NamePlate_00000269.dds`, sortName: `` },
{ id: `270`, str: `ダンベル何キロ持てる? 【2】`, imagePath: `CHU_UI_NamePlate_00000270.dds`, sortName: `` },
{ id: `271`, str: `Arcaea 【3】`, imagePath: `CHU_UI_NamePlate_00000271.dds`, sortName: `A` },
{ id: `272`, str: `Arcaea 【4】`, imagePath: `CHU_UI_NamePlate_00000272.dds`, sortName: `A` },
{ id: `273`, str: `暴虐のギーゼグール`, imagePath: `CHU_UI_NamePlate_00000273.dds`, sortName: `` },
{ id: `274`, str: `白猫プロジェクト 【1】`, imagePath: `CHU_UI_NamePlate_00000274.dds`, sortName: `` },
{ id: `275`, str: `白猫プロジェクト 【2】`, imagePath: `CHU_UI_NamePlate_00000275.dds`, sortName: `` },
{ id: `276`, str: `アイカツオンパレード! 【1】`, imagePath: `CHU_UI_NamePlate_00000276.dds`, sortName: `` },
{ id: `277`, str: `アイカツオンパレード! 【2】`, imagePath: `CHU_UI_NamePlate_00000277.dds`, sortName: `` },
{ id: `278`, str: `小野 美苗`, imagePath: `CHU_UI_NamePlate_00000278.dds`, sortName: `` },
{ id: `279`, str: `三賢者`, imagePath: `CHU_UI_NamePlate_00000279.dds`, sortName: `` },
{ id: `280`, str: `東方紅魔郷 STAGE 2`, imagePath: `CHU_UI_NamePlate_00000280.dds`, sortName: `` },
{ id: `281`, str: `東方Project 【8】`, imagePath: `CHU_UI_NamePlate_00000281.dds`, sortName: `` },
{ id: `282`, str: `渋沢 `, imagePath: `CHU_UI_NamePlate_00000282.dds`, sortName: `` },
{ id: `283`, str: `チュウニペンギン&ショウニペンギン (STAR)`, imagePath: `CHU_UI_NamePlate_00000283.dds`, sortName: `` },
{ id: `284`, str: `#コンパス 【3】`, imagePath: `CHU_UI_NamePlate_00000284.dds`, sortName: `` },
{ id: `285`, str: `#コンパス 【4】`, imagePath: `CHU_UI_NamePlate_00000285.dds`, sortName: `` },
{ id: `286`, str: `#コンパス 【5】`, imagePath: `CHU_UI_NamePlate_00000286.dds`, sortName: `` },
{ id: `287`, str: `#コンパス 【6】`, imagePath: `CHU_UI_NamePlate_00000287.dds`, sortName: `` },
{ id: `288`, str: `りゅうおうのおしごと! 【3】`, imagePath: `CHU_UI_NamePlate_00000288.dds`, sortName: `` },
{ id: `289`, str: `りゅうおうのおしごと! 【4】`, imagePath: `CHU_UI_NamePlate_00000289.dds`, sortName: `` },
{ id: `290`, str: `ようこそハッピーアニマリア2`, imagePath: `CHU_UI_NamePlate_00000290.dds`, sortName: `` },
{ id: `291`, str: `葛城 華`, imagePath: `CHU_UI_NamePlate_00000291.dds`, sortName: `` },
{ id: `292`, str: `八月のシンデレラナイン 【1】`, imagePath: `CHU_UI_NamePlate_00000292.dds`, sortName: `` },
{ id: `293`, str: `八月のシンデレラナイン 【2】`, imagePath: `CHU_UI_NamePlate_00000293.dds`, sortName: `` },
{ id: `294`, str: `WIXOSS 【1】`, imagePath: `CHU_UI_NamePlate_00000294.dds`, sortName: `W` },
{ id: `295`, str: `WIXOSS 【2】`, imagePath: `CHU_UI_NamePlate_00000295.dds`, sortName: `W` },
{ id: `296`, str: `新井 桃子`, imagePath: `CHU_UI_NamePlate_00000296.dds`, sortName: `` },
{ id: `297`, str: `餓音 MUSIC OF THE WAVES`, imagePath: `CHU_UI_NamePlate_00000297.dds`, sortName: `` },
{ id: `298`, str: `新サクラ大戦 【1】`, imagePath: `CHU_UI_NamePlate_00000298.dds`, sortName: `` },
{ id: `299`, str: `新サクラ大戦 【2】`, imagePath: `CHU_UI_NamePlate_00000299.dds`, sortName: `` },
{ id: `300`, str: `チャージマン研! 【1】`, imagePath: `CHU_UI_NamePlate_00000300.dds`, sortName: `` },
{ id: `301`, str: `チャージマン研! 【2】`, imagePath: `CHU_UI_NamePlate_00000301.dds`, sortName: `` },
{ id: `302`, str: `チャージマン研! 【3】`, imagePath: `CHU_UI_NamePlate_00000302.dds`, sortName: `` },
{ id: `303`, str: `チャージマン研! 【4】`, imagePath: `CHU_UI_NamePlate_00000303.dds`, sortName: `` },
{ id: `305`, str: `MIR-201【ヘカティ・ベアトリクス】`, imagePath: `CHU_UI_NamePlate_00000305.dds`, sortName: `M` },
{ id: `306`, str: `オーバーロード 【3】`, imagePath: `CHU_UI_NamePlate_00000306.dds`, sortName: `` },
{ id: `307`, str: `オーバーロード 【4】`, imagePath: `CHU_UI_NamePlate_00000307.dds`, sortName: `` },
{ id: `308`, str: `審判正義の星女神`, imagePath: `CHU_UI_NamePlate_00000308.dds`, sortName: `` },
{ id: `309`, str: `世話やきキツネの仙狐さん 【1】`, imagePath: `CHU_UI_NamePlate_00000309.dds`, sortName: `` },
{ id: `310`, str: `世話やきキツネの仙狐さん 【2】`, imagePath: `CHU_UI_NamePlate_00000310.dds`, sortName: `` },
{ id: `311`, str: `テスタメントネメシス`, imagePath: `CHU_UI_NamePlate_00000311.dds`, sortName: `` },
{ id: `312`, str: `神位の簒奪者`, imagePath: `CHU_UI_NamePlate_00000312.dds`, sortName: `` },
{ id: `313`, str: `ダンジョンに出会いを求めるのは間違っているだろうかⅡ 【1】`, imagePath: `CHU_UI_NamePlate_00000313.dds`, sortName: `` },
{ id: `314`, str: `ダンジョンに出会いを求めるのは間違っているだろうかⅡ 【2】`, imagePath: `CHU_UI_NamePlate_00000314.dds`, sortName: `` },
{ id: `315`, str: `緑と水のソルナ`, imagePath: `CHU_UI_NamePlate_00000315.dds`, sortName: `` },
{ id: `316`, str: `青春ブタ野郎はバニーガール先輩の夢を見ない 【1】`, imagePath: `CHU_UI_NamePlate_00000316.dds`, sortName: `` },
{ id: `317`, str: `青春ブタ野郎はバニーガール先輩の夢を見ない 【2】`, imagePath: `CHU_UI_NamePlate_00000317.dds`, sortName: `` },
{ id: `318`, str: `青春ブタ野郎はバニーガール先輩の夢を見ない 【3】`, imagePath: `CHU_UI_NamePlate_00000318.dds`, sortName: `` },
{ id: `319`, str: `プロジェクトセカイ カラフルステージ! feat. 初音ミク 【1】`, imagePath: `CHU_UI_NamePlate_00000319.dds`, sortName: `` },
{ id: `320`, str: `プロジェクトセカイ カラフルステージ! feat. 初音ミク 【2】`, imagePath: `CHU_UI_NamePlate_00000320.dds`, sortName: `` },
{ id: `322`, str: `Arcaea 【5】`, imagePath: `CHU_UI_NamePlate_00000322.dds`, sortName: `A` },
{ id: `323`, str: `Arcaea 【6】`, imagePath: `CHU_UI_NamePlate_00000323.dds`, sortName: `A` },
{ id: `324`, str: `とある科学の超電磁砲S 【4】`, imagePath: `CHU_UI_NamePlate_00000324.dds`, sortName: `` },
{ id: `325`, str: `とある科学の超電磁砲S 【5】`, imagePath: `CHU_UI_NamePlate_00000325.dds`, sortName: `` },
{ id: `326`, str: `DJ-MEGA`, imagePath: `CHU_UI_NamePlate_00000326.dds`, sortName: `D` },
{ id: `327`, str: `藤堂 陽南袴`, imagePath: `CHU_UI_NamePlate_00000327.dds`, sortName: `` },
{ id: `328`, str: `初恋`, imagePath: `CHU_UI_NamePlate_00000328.dds`, sortName: `` },
{ id: `329`, str: `虚構推理 【1】`, imagePath: `CHU_UI_NamePlate_00000329.dds`, sortName: `` },
{ id: `330`, str: `虚構推理 【2】`, imagePath: `CHU_UI_NamePlate_00000330.dds`, sortName: `` },
{ id: `331`, str: `虚構推理 【3】`, imagePath: `CHU_UI_NamePlate_00000331.dds`, sortName: `` },
{ id: `332`, str: `ホロライブ 【1】`, imagePath: `CHU_UI_NamePlate_00000332.dds`, sortName: `` },
{ id: `333`, str: `ホロライブ 【2】`, imagePath: `CHU_UI_NamePlate_00000333.dds`, sortName: `` },
{ id: `334`, str: `ホロライブ 【3】`, imagePath: `CHU_UI_NamePlate_00000334.dds`, sortName: `` },
{ id: `335`, str: `ホロライブ 【4】`, imagePath: `CHU_UI_NamePlate_00000335.dds`, sortName: `` },
{ id: `336`, str: `ヒナまつり 【3】`, imagePath: `CHU_UI_NamePlate_00000336.dds`, sortName: `` },
{ id: `337`, str: `ヒナまつり 【4】`, imagePath: `CHU_UI_NamePlate_00000337.dds`, sortName: `` },
{ id: `338`, str: `宇宙よりも遠い場所 【3】`, imagePath: `CHU_UI_NamePlate_00000338.dds`, sortName: `` },
{ id: `339`, str: `KING of Performai 2020 ~優勝~`, imagePath: `CHU_UI_NamePlate_00000339.dds`, sortName: `K` },
{ id: `340`, str: `KING of Performai 2020 FINALIST`, imagePath: `CHU_UI_NamePlate_00000340.dds`, sortName: `K` },
{ id: `341`, str: `桔梗 小夜曲`, imagePath: `CHU_UI_NamePlate_00000341.dds`, sortName: `` },
{ id: `342`, str: `グルーヴコースター 【1】`, imagePath: `CHU_UI_NamePlate_00000342.dds`, sortName: `` },
{ id: `343`, str: `グルーヴコースター 【2】`, imagePath: `CHU_UI_NamePlate_00000343.dds`, sortName: `` },
{ id: `344`, str: `グルーヴコースター 【3】`, imagePath: `CHU_UI_NamePlate_00000344.dds`, sortName: `` },
{ id: `345`, str: `世にも不思議な物語`, imagePath: `CHU_UI_NamePlate_00000345.dds`, sortName: `` },
{ id: `346`, str: `三国志大戦 【1】`, imagePath: `CHU_UI_NamePlate_00000346.dds`, sortName: `` },
{ id: `347`, str: `三国志大戦 【2】`, imagePath: `CHU_UI_NamePlate_00000347.dds`, sortName: `` },
{ id: `348`, str: `パリピ孔明`, imagePath: `CHU_UI_NamePlate_00000348.dds`, sortName: `` },
{ id: `349`, str: `ゾンビランドサガ 【3】`, imagePath: `CHU_UI_NamePlate_00000349.dds`, sortName: `` },
{ id: `350`, str: `ゴブリンスレイヤー 【3】`, imagePath: `CHU_UI_NamePlate_00000350.dds`, sortName: `` },
{ id: `351`, str: `緋弾のアリアAA 【3】`, imagePath: `CHU_UI_NamePlate_00000351.dds`, sortName: `` },
{ id: `352`, str: `緋弾のアリアAA 【4】`, imagePath: `CHU_UI_NamePlate_00000352.dds`, sortName: `` },
{ id: `353`, str: `MDA-01【シリウス】`, imagePath: `CHU_UI_NamePlate_00000353.dds`, sortName: `M` },
{ id: `354`, str: `恋する小惑星 【1】`, imagePath: `CHU_UI_NamePlate_00000354.dds`, sortName: `` },
{ id: `355`, str: `恋する小惑星 【2】`, imagePath: `CHU_UI_NamePlate_00000355.dds`, sortName: `` },
{ id: `356`, str: `ストライク・ザ・ブラッド 【5】`, imagePath: `CHU_UI_NamePlate_00000356.dds`, sortName: `` },
{ id: `357`, str: `ストライク・ザ・ブラッド 【6】`, imagePath: `CHU_UI_NamePlate_00000357.dds`, sortName: `` },
{ id: `358`, str: `プリンセス・プリンシパル 【5】`, imagePath: `CHU_UI_NamePlate_00000358.dds`, sortName: `` },
{ id: `359`, str: `プリンセス・プリンシパル 【6】`, imagePath: `CHU_UI_NamePlate_00000359.dds`, sortName: `` },
{ id: `360`, str: `ゆるキャン△ 【3】`, imagePath: `CHU_UI_NamePlate_00000360.dds`, sortName: `` },
{ id: `361`, str: `ゆるキャン△ 【4】`, imagePath: `CHU_UI_NamePlate_00000361.dds`, sortName: `` },
{ id: `362`, str: `咲-Saki-阿知賀編 episode of side-A 【3】`, imagePath: `CHU_UI_NamePlate_00000362.dds`, sortName: `` },
{ id: `363`, str: `託されたチカラ`, imagePath: `CHU_UI_NamePlate_00000363.dds`, sortName: `` },
{ id: `364`, str: `まちカドまぞく 【1】`, imagePath: `CHU_UI_NamePlate_00000364.dds`, sortName: `` },
{ id: `365`, str: `まちカドまぞく 【2】`, imagePath: `CHU_UI_NamePlate_00000365.dds`, sortName: `` },
{ id: `366`, str: `異世界かるてっと 【1】`, imagePath: `CHU_UI_NamePlate_00000366.dds`, sortName: `` },
{ id: `367`, str: `異世界かるてっと 【2】`, imagePath: `CHU_UI_NamePlate_00000367.dds`, sortName: `` },
{ id: `368`, str: `芒崎 奏`, imagePath: `CHU_UI_NamePlate_00000368.dds`, sortName: `` },
{ id: `369`, str: `ぷよぷよ!! 【1】`, imagePath: `CHU_UI_NamePlate_00000369.dds`, sortName: `` },
{ id: `370`, str: `ぷよぷよ!! 【2】`, imagePath: `CHU_UI_NamePlate_00000370.dds`, sortName: `` },
{ id: `371`, str: `龍が如く 【3】`, imagePath: `CHU_UI_NamePlate_00000371.dds`, sortName: `` },
{ id: `372`, str: `東方Extra 3`, imagePath: `CHU_UI_NamePlate_00000372.dds`, sortName: `` },
{ id: `373`, str: `東方Project 【9】`, imagePath: `CHU_UI_NamePlate_00000373.dds`, sortName: `` },
{ id: `374`, str: `ティフォン`, imagePath: `CHU_UI_NamePlate_00000374.dds`, sortName: `` },
{ id: `375`, str: `ワールドヒロインズ BLOOD`, imagePath: `CHU_UI_NamePlate_00000375.dds`, sortName: `` },
{ id: `376`, str: `メイドインアビス 【1】`, imagePath: `CHU_UI_NamePlate_00000376.dds`, sortName: `` },
{ id: `377`, str: `メイドインアビス 【2】`, imagePath: `CHU_UI_NamePlate_00000377.dds`, sortName: `` },
{ id: `378`, str: `異世界食堂 【5】`, imagePath: `CHU_UI_NamePlate_00000378.dds`, sortName: `` },
{ id: `379`, str: `はるかなレシーブ 【3】`, imagePath: `CHU_UI_NamePlate_00000379.dds`, sortName: `` },
{ id: `380`, str: `チュウニペンギン&ショウニペンギン (AMAZON)`, imagePath: `CHU_UI_NamePlate_00000380.dds`, sortName: `` },
{ id: `10001`, str: `僕のヒーローアカデミア 【1】`, imagePath: `CHU_UI_NamePlate_00010001.dds`, sortName: `` },
{ id: `10002`, str: `僕のヒーローアカデミア 【2】`, imagePath: `CHU_UI_NamePlate_00010002.dds`, sortName: `` },
{ id: `10003`, str: `アイドルマスター 【1】`, imagePath: `CHU_UI_NamePlate_00010003.dds`, sortName: `` },
{ id: `10004`, str: `アイドルマスター 【2】`, imagePath: `CHU_UI_NamePlate_00010004.dds`, sortName: `` },
{ id: `10005`, str: `アイドルマスター 【3】`, imagePath: `CHU_UI_NamePlate_00010005.dds`, sortName: `` },
{ id: `10006`, str: `アイドルマスター 【4】`, imagePath: `CHU_UI_NamePlate_00010006.dds`, sortName: `` },
{ id: `10007`, str: `アイドルマスター 【5】`, imagePath: `CHU_UI_NamePlate_00010007.dds`, sortName: `` },
{ id: `10008`, str: `アイドルマスター 【6】`, imagePath: `CHU_UI_NamePlate_00010008.dds`, sortName: `` },
{ id: `10009`, str: `アイドルマスター 【7】`, imagePath: `CHU_UI_NamePlate_00010009.dds`, sortName: `` },
{ id: `10010`, str: `アイドルマスター シンデレラガールズ 【1】`, imagePath: `CHU_UI_NamePlate_00010010.dds`, sortName: `` },
{ id: `10011`, str: `アイドルマスター シンデレラガールズ 【2】`, imagePath: `CHU_UI_NamePlate_00010011.dds`, sortName: `` },
{ id: `10012`, str: `アイドルマスター シンデレラガールズ 【3】`, imagePath: `CHU_UI_NamePlate_00010012.dds`, sortName: `` },
{ id: `10013`, str: `アイドルマスター シンデレラガールズ 【4】`, imagePath: `CHU_UI_NamePlate_00010013.dds`, sortName: `` },
{ id: `10014`, str: `アイドルマスター シンデレラガールズ 【5】`, imagePath: `CHU_UI_NamePlate_00010014.dds`, sortName: `` },
{ id: `10015`, str: `アイドルマスター シンデレラガールズ 【6】`, imagePath: `CHU_UI_NamePlate_00010015.dds`, sortName: `` },
{ id: `10016`, str: `バンドリ! ガールズバンドパーティ! 【1】`, imagePath: `CHU_UI_NamePlate_00010016.dds`, sortName: `` },
{ id: `10017`, str: `バンドリ! ガールズバンドパーティ! 【2】`, imagePath: `CHU_UI_NamePlate_00010017.dds`, sortName: `` },
{ id: `10018`, str: `バンドリ! ガールズバンドパーティ! 【3】`, imagePath: `CHU_UI_NamePlate_00010018.dds`, sortName: `` },
{ id: `10019`, str: `ひぐらしのなく頃に 業 【1】`, imagePath: `CHU_UI_NamePlate_00010019.dds`, sortName: `` },
{ id: `10020`, str: `ひぐらしのなく頃に 業 【2】`, imagePath: `CHU_UI_NamePlate_00010020.dds`, sortName: `` },
{ id: `10021`, str: `東方LostWord 【1】`, imagePath: `CHU_UI_NamePlate_00010021.dds`, sortName: `` },
{ id: `10022`, str: `東方LostWord 【2】`, imagePath: `CHU_UI_NamePlate_00010022.dds`, sortName: `` },
{ id: `10023`, str: `乙女ゲームの破滅フラグしかない悪役令嬢に転生してしまった… 【1】`, imagePath: `CHU_UI_NamePlate_00010023.dds`, sortName: `` },
{ id: `10024`, str: `乙女ゲームの破滅フラグしかない悪役令嬢に転生してしまった… 【2】`, imagePath: `CHU_UI_NamePlate_00010024.dds`, sortName: `` },
{ id: `10025`, str: `ご注文はうさぎですかBLOOM 【1】`, imagePath: `CHU_UI_NamePlate_00010025.dds`, sortName: `` },
{ id: `10026`, str: `ご注文はうさぎですかBLOOM 【2】`, imagePath: `CHU_UI_NamePlate_00010026.dds`, sortName: `` },
{ id: `10027`, str: `ご注文はうさぎですかBLOOM 【3】`, imagePath: `CHU_UI_NamePlate_00010027.dds`, sortName: `` },
{ id: `10028`, str: `ご注文はうさぎですかBLOOM 【4】`, imagePath: `CHU_UI_NamePlate_00010028.dds`, sortName: `` },
{ id: `10029`, str: `Re:ゼロから始める異世界生活 2nd season 【1】`, imagePath: `CHU_UI_NamePlate_00010029.dds`, sortName: `R` },
{ id: `10030`, str: `Re:ゼロから始める異世界生活 2nd season 【2】`, imagePath: `CHU_UI_NamePlate_00010030.dds`, sortName: `R` },
{ id: `10031`, str: `ありふれた職業で世界最強 【1】`, imagePath: `CHU_UI_NamePlate_00010031.dds`, sortName: `` },
{ id: `10032`, str: `ありふれた職業で世界最強 【2】`, imagePath: `CHU_UI_NamePlate_00010032.dds`, sortName: `` },
{ id: `10033`, str: `ありふれた職業で世界最強 【3】`, imagePath: `CHU_UI_NamePlate_00010033.dds`, sortName: `` },
{ id: `10034`, str: `プリンセスコネクトRe:Dive 【1】`, imagePath: `CHU_UI_NamePlate_00010034.dds`, sortName: `` },
{ id: `10035`, str: `プリンセスコネクトRe:Dive 【2】`, imagePath: `CHU_UI_NamePlate_00010035.dds`, sortName: `` },
{ id: `10036`, str: `プリンセスコネクトRe:Dive 【3】`, imagePath: `CHU_UI_NamePlate_00010036.dds`, sortName: `` },
{ id: `10037`, str: `宇崎ちゃんは遊びたい! 【1】`, imagePath: `CHU_UI_NamePlate_00010037.dds`, sortName: `` },
{ id: `10038`, str: `宇崎ちゃんは遊びたい! 【2】`, imagePath: `CHU_UI_NamePlate_00010038.dds`, sortName: `` },
{ id: `10039`, str: `「七つの大罪 憤怒の審判」 【1】`, imagePath: `CHU_UI_NamePlate_00010039.dds`, sortName: `` },
{ id: `10040`, str: `「七つの大罪 憤怒の審判」 【2】`, imagePath: `CHU_UI_NamePlate_00010040.dds`, sortName: `` },
{ id: `10041`, str: `東方妖々夢 STAGE 2 【1】`, imagePath: `CHU_UI_NamePlate_00010041.dds`, sortName: `` },
{ id: `10042`, str: `東方妖々夢 STAGE 2 【2】`, imagePath: `CHU_UI_NamePlate_00010042.dds`, sortName: `` },
{ id: `10043`, str: `プロジェクトセカイ カラフルステージ! feat. 初音ミク 【3】`, imagePath: `CHU_UI_NamePlate_00010043.dds`, sortName: `` },
{ id: `10044`, str: `プロジェクトセカイ カラフルステージ! feat. 初音ミク 【4】`, imagePath: `CHU_UI_NamePlate_00010044.dds`, sortName: `` },
{ id: `10045`, str: `プロジェクトセカイ カラフルステージ! feat. 初音ミク 【5】`, imagePath: `CHU_UI_NamePlate_00010045.dds`, sortName: `` },
{ id: `10046`, str: `プロジェクトセカイ カラフルステージ! feat. 初音ミク 【6】`, imagePath: `CHU_UI_NamePlate_00010046.dds`, sortName: `` },
{ id: `10047`, str: `東京リベンジャーズ 【1】`, imagePath: `CHU_UI_NamePlate_00010047.dds`, sortName: `` },
{ id: `10048`, str: `東京リベンジャーズ 【2】`, imagePath: `CHU_UI_NamePlate_00010048.dds`, sortName: `` },
{ id: `10050`, str: `魔法科高校の劣等生 【6】`, imagePath: `CHU_UI_NamePlate_00010050.dds`, sortName: `` },
{ id: `10051`, str: `魔法科高校の劣等生 【7】`, imagePath: `CHU_UI_NamePlate_00010051.dds`, sortName: `` },
{ id: `10052`, str: `魔法科高校の劣等生 【8】`, imagePath: `CHU_UI_NamePlate_00010052.dds`, sortName: `` },
{ id: `10053`, str: `魔法科高校の劣等生 【9】`, imagePath: `CHU_UI_NamePlate_00010053.dds`, sortName: `` },
{ id: `10054`, str: `東方Extra 4 【1】`, imagePath: `CHU_UI_NamePlate_00010054.dds`, sortName: `` },
{ id: `10055`, str: `東方Extra 4 【2】`, imagePath: `CHU_UI_NamePlate_00010055.dds`, sortName: `` },
{ id: `10056`, str: `D4DJ Groovy Mix 【1】`, imagePath: `CHU_UI_NamePlate_00010056.dds`, sortName: `D` },
{ id: `10057`, str: `D4DJ Groovy Mix 【2】`, imagePath: `CHU_UI_NamePlate_00010057.dds`, sortName: `D` },
{ id: `10058`, str: `D4DJ Groovy Mix 【3】`, imagePath: `CHU_UI_NamePlate_00010058.dds`, sortName: `D` },
{ id: `10059`, str: `ネコぱら 【5】`, imagePath: `CHU_UI_NamePlate_00010059.dds`, sortName: `` },
{ id: `10060`, str: `ネコぱら 【6】`, imagePath: `CHU_UI_NamePlate_00010060.dds`, sortName: `` },
{ id: `10061`, str: `ツユ 【1】`, imagePath: `CHU_UI_NamePlate_00010061.dds`, sortName: `` },
{ id: `10062`, str: `ツユ 【2】`, imagePath: `CHU_UI_NamePlate_00010062.dds`, sortName: `` },
{ id: `10063`, str: `ツユ 【3】`, imagePath: `CHU_UI_NamePlate_00010063.dds`, sortName: `` },
{ id: `10064`, str: `ツユ 【4】`, imagePath: `CHU_UI_NamePlate_00010064.dds`, sortName: `` },
{ id: `10065`, str: `小林さんちのメイドラゴンS 【1】`, imagePath: `CHU_UI_NamePlate_00010065.dds`, sortName: `` },
{ id: `10066`, str: `小林さんちのメイドラゴンS 【2】`, imagePath: `CHU_UI_NamePlate_00010066.dds`, sortName: `` },
{ id: `10067`, str: `結月ゆかり・紲星あかり`, imagePath: `CHU_UI_NamePlate_00010067.dds`, sortName: `` },
{ id: `10068`, str: `琴葉 茜・葵 【2】`, imagePath: `CHU_UI_NamePlate_00010068.dds`, sortName: `` },
{ id: `10069`, str: `さんばか 【1】`, imagePath: `CHU_UI_NamePlate_00010069.dds`, sortName: `` },
{ id: `10070`, str: `さんばか 【2】`, imagePath: `CHU_UI_NamePlate_00010070.dds`, sortName: `` },
{ id: `10071`, str: `さんばか 【3】`, imagePath: `CHU_UI_NamePlate_00010071.dds`, sortName: `` },
{ id: `10072`, str: `進撃の巨人 【1】`, imagePath: `CHU_UI_NamePlate_00010072.dds`, sortName: `` },
{ id: `10073`, str: `進撃の巨人 【2】`, imagePath: `CHU_UI_NamePlate_00010073.dds`, sortName: `` },
{ id: `10074`, str: `進撃の巨人 【3】`, imagePath: `CHU_UI_NamePlate_00010074.dds`, sortName: `` },
{ id: `10075`, str: `私に天使が舞い降りた! 【3】`, imagePath: `CHU_UI_NamePlate_00010075.dds`, sortName: `` },
{ id: `10076`, str: `私に天使が舞い降りた! 【4】`, imagePath: `CHU_UI_NamePlate_00010076.dds`, sortName: `` },
{ id: `10077`, str: `キルミーベイベー 【1】`, imagePath: `CHU_UI_NamePlate_00010077.dds`, sortName: `` },
{ id: `10078`, str: `キルミーベイベー 【2】`, imagePath: `CHU_UI_NamePlate_00010078.dds`, sortName: `` },
{ id: `10079`, str: `D4DJ Groovy Mix 【4】`, imagePath: `CHU_UI_NamePlate_00010079.dds`, sortName: `D` },
{ id: `20001`, str: `魔大陸の三姫霊`, imagePath: `CHU_UI_NamePlate_00020001.dds`, sortName: `` },
{ id: `20002`, str: `シビュラ精霊記 Strive Against Fate`, imagePath: `CHU_UI_NamePlate_00020002.dds`, sortName: `` },
{ id: `20003`, str: `破壊と再生 剣の後継者`, imagePath: `CHU_UI_NamePlate_00020003.dds`, sortName: `` },
{ id: `20004`, str: `カゲロウリレイション`, imagePath: `CHU_UI_NamePlate_00020004.dds`, sortName: `` },
{ id: `20005`, str: `HaNaMiNa`, imagePath: `CHU_UI_NamePlate_00020005.dds`, sortName: `H` },
{ id: `20006`, str: `双炎のラストソング`, imagePath: `CHU_UI_NamePlate_00020006.dds`, sortName: `` },
{ id: `20007`, str: `世界襲撃♥ハネムーン`, imagePath: `CHU_UI_NamePlate_00020007.dds`, sortName: `` },
{ id: `20008`, str: `舞ヶ原シンセ研究会`, imagePath: `CHU_UI_NamePlate_00020008.dds`, sortName: `` },
{ id: `20009`, str: `勧善懲悪`, imagePath: `CHU_UI_NamePlate_00020009.dds`, sortName: `` },
{ id: `20010`, str: `残されし秩序の守護者`, imagePath: `CHU_UI_NamePlate_00020010.dds`, sortName: `` },
{ id: `25001`, str: `イングリット・オーリック・コーネル`, imagePath: `CHU_UI_NamePlate_00025001.dds`, sortName: `` },
{ id: `25002`, str: `シルヴィアス`, imagePath: `CHU_UI_NamePlate_00025002.dds`, sortName: `` },
{ id: `25003`, str: `ジョニー・サイアスティン`, imagePath: `CHU_UI_NamePlate_00025003.dds`, sortName: `` },
{ id: `25004`, str: `魔法使いアルテラ`, imagePath: `CHU_UI_NamePlate_00025004.dds`, sortName: `` },
{ id: `25005`, str: `新田 ちえ`, imagePath: `CHU_UI_NamePlate_00025005.dds`, sortName: `` },
{ id: `25006`, str: `MDA-21【レグルス】`, imagePath: `CHU_UI_NamePlate_00025006.dds`, sortName: `M` },
{ id: `25007`, str: `ジュナ・サラキア`, imagePath: `CHU_UI_NamePlate_00025007.dds`, sortName: `` },
{ id: `25008`, str: `ワイズマン`, imagePath: `CHU_UI_NamePlate_00025008.dds`, sortName: `` },
{ id: `25009`, str: `ヴェルゼビュートネメシス`, imagePath: `CHU_UI_NamePlate_00025009.dds`, sortName: `` },
{ id: `25010`, str: `マリーメイア・クレスケンス`, imagePath: `CHU_UI_NamePlate_00025010.dds`, sortName: `` },
{ id: `25011`, str: `伊賀崎ノ楠子`, imagePath: `CHU_UI_NamePlate_00025011.dds`, sortName: `` },
{ id: `25012`, str: `イロドリミドリ/色彩過剰のダイアリーミュージック`, imagePath: `CHU_UI_NamePlate_00025012.dds`, sortName: `` },
{ id: `25013`, str: `オールドブルー`, imagePath: `CHU_UI_NamePlate_00025013.dds`, sortName: `` },
{ id: `25014`, str: `クーデルカ・プルミエール`, imagePath: `CHU_UI_NamePlate_00025014.dds`, sortName: `` },
{ id: `30001`, str: `KING of Performai The 3rd ~優勝~`, imagePath: `CHU_UI_NamePlate_00030001.dds`, sortName: `K` },
{ id: `30002`, str: `KING of Performai The 3rd FINALIST`, imagePath: `CHU_UI_NamePlate_00030002.dds`, sortName: `K` },
{ id: `30003`, str: `チュウニペンギン&ショウニペンギン (CRYSTAL)`, imagePath: `CHU_UI_NamePlate_00030003.dds`, sortName: `` },
{ id: `10080`, str: `モブサイコ100 Ⅲ 【1】`, imagePath: `CHU_UI_NamePlate_00010080.dds`, sortName: `` },
{ id: `10081`, str: `モブサイコ100 Ⅲ 【2】`, imagePath: `CHU_UI_NamePlate_00010081.dds`, sortName: `` },
{ id: `10082`, str: `ヘブンバーンズレッド 【1】`, imagePath: `CHU_UI_NamePlate_00010082.dds`, sortName: `` },
{ id: `10083`, str: `ヘブンバーンズレッド 【2】`, imagePath: `CHU_UI_NamePlate_00010083.dds`, sortName: `` },
{ id: `10084`, str: `ヘブンバーンズレッド 【3】`, imagePath: `CHU_UI_NamePlate_00010084.dds`, sortName: `` },
{ id: `10085`, str: `青春ブタ野郎はバニーガール先輩の夢を見ない 【4】`, imagePath: `CHU_UI_NamePlate_00010085.dds`, sortName: `` },
{ id: `10086`, str: `ダンベル何キロ持てる? 【3】`, imagePath: `CHU_UI_NamePlate_00010086.dds`, sortName: `` },
{ id: `20011`, str: `最後の審判 abyss of despair`, imagePath: `CHU_UI_NamePlate_00020011.dds`, sortName: `` },
{ id: `25015`, str: `エイハヴ`, imagePath: `CHU_UI_NamePlate_00025015.dds`, sortName: `` },
{ id: `41000`, str: `♥♥♥星咲 あかり♥♥♥`, imagePath: `CHU_UI_NamePlate_00041000.dds`, sortName: `` },
{ id: `41001`, str: `♥♥♥藤沢 柚子♥♥♥`, imagePath: `CHU_UI_NamePlate_00041001.dds`, sortName: `` },
{ id: `41002`, str: `♥♥♥三角 葵♥♥♥`, imagePath: `CHU_UI_NamePlate_00041002.dds`, sortName: `` },
{ id: `41003`, str: `♥♥♥高瀬 梨緒♥♥♥`, imagePath: `CHU_UI_NamePlate_00041003.dds`, sortName: `` },
{ id: `41004`, str: `♥♥♥結城 莉玖♥♥♥`, imagePath: `CHU_UI_NamePlate_00041004.dds`, sortName: `` },
{ id: `41005`, str: `♥♥♥藍原 椿♥♥♥`, imagePath: `CHU_UI_NamePlate_00041005.dds`, sortName: `` },
{ id: `41006`, str: `♥♥♥早乙女 彩華♥♥♥`, imagePath: `CHU_UI_NamePlate_00041006.dds`, sortName: `` },
{ id: `41007`, str: `♥♥♥桜井 春菜♥♥♥`, imagePath: `CHU_UI_NamePlate_00041007.dds`, sortName: `` },
{ id: `41008`, str: `♥♥♥九條 楓♥♥♥`, imagePath: `CHU_UI_NamePlate_00041008.dds`, sortName: `` },
{ id: `41009`, str: `♥♥♥柏木 咲姫♥♥♥`, imagePath: `CHU_UI_NamePlate_00041009.dds`, sortName: `` },
{ id: `41010`, str: `♥♥♥井之原 小星♥♥♥`, imagePath: `CHU_UI_NamePlate_00041010.dds`, sortName: `` },
{ id: `41011`, str: `♥♥♥逢坂 茜♥♥♥`, imagePath: `CHU_UI_NamePlate_00041011.dds`, sortName: `` },
{ id: `41012`, str: `♥♥♥珠洲島 有栖♥♥♥`, imagePath: `CHU_UI_NamePlate_00041012.dds`, sortName: `` },
{ id: `41013`, str: `♥♥♥柏木 美亜♥♥♥`, imagePath: `CHU_UI_NamePlate_00041013.dds`, sortName: `` },
{ id: `41014`, str: `♥♥♥日向 千夏♥♥♥`, imagePath: `CHU_UI_NamePlate_00041014.dds`, sortName: `` },
{ id: `41015`, str: `♥♥♥東雲 つむぎ♥♥♥`, imagePath: `CHU_UI_NamePlate_00041015.dds`, sortName: `` },
{ id: `41016`, str: `♥♥♥皇城 セツナ♥♥♥`, imagePath: `CHU_UI_NamePlate_00041016.dds`, sortName: `` },
{ id: `10087`, str: `東方神霊廟 【1】`, imagePath: `CHU_UI_NamePlate_00010087.dds`, sortName: `` },
{ id: `10088`, str: `東方神霊廟 【2】`, imagePath: `CHU_UI_NamePlate_00010088.dds`, sortName: `` },
{ id: `10089`, str: `中二病でも恋がしたい! 【1】`, imagePath: `CHU_UI_NamePlate_00010089.dds`, sortName: `` },
{ id: `10090`, str: `中二病でも恋がしたい! 【2】`, imagePath: `CHU_UI_NamePlate_00010090.dds`, sortName: `` },
{ id: `25016`, str: `第八皇女エルルーン`, imagePath: `CHU_UI_NamePlate_00025016.dds`, sortName: `` },
{ id: `10123`, str: `WACCA 【1】`, imagePath: `CHU_UI_NamePlate_00010123.dds`, sortName: `W` },
{ id: `10124`, str: `WACCA 【2】`, imagePath: `CHU_UI_NamePlate_00010124.dds`, sortName: `W` },
{ id: `10125`, str: `WACCA 【3】`, imagePath: `CHU_UI_NamePlate_00010125.dds`, sortName: `W` },
{ id: `10097`, str: `WIXOSS 【3】`, imagePath: `CHU_UI_NamePlate_00010097.dds`, sortName: `W` },
{ id: `10106`, str: `#コンパス 【7】`, imagePath: `CHU_UI_NamePlate_00010106.dds`, sortName: `` },
{ id: `10107`, str: `#コンパス 【8】`, imagePath: `CHU_UI_NamePlate_00010107.dds`, sortName: `` },
{ id: `10108`, str: `#コンパス 【9】`, imagePath: `CHU_UI_NamePlate_00010108.dds`, sortName: `` },
{ id: `20012`, str: `未来の燈火`, imagePath: `CHU_UI_NamePlate_00020012.dds`, sortName: `` },
{ id: `25017`, str: `宍戸 美鈴`, imagePath: `CHU_UI_NamePlate_00025017.dds`, sortName: `` },
{ id: `10098`, str: `クラッシュフィーバー 【1】`, imagePath: `CHU_UI_NamePlate_00010098.dds`, sortName: `` },
{ id: `10099`, str: `クラッシュフィーバー 【2】`, imagePath: `CHU_UI_NamePlate_00010099.dds`, sortName: `` },
{ id: `10100`, str: `クラッシュフィーバー 【3】`, imagePath: `CHU_UI_NamePlate_00010100.dds`, sortName: `` },
{ id: `10101`, str: `DECO*27 【1】`, imagePath: `CHU_UI_NamePlate_00010101.dds`, sortName: `D` },
{ id: `10102`, str: `DECO*27 【2】`, imagePath: `CHU_UI_NamePlate_00010102.dds`, sortName: `D` },
{ id: `25018`, str: `リー・メイメイ`, imagePath: `CHU_UI_NamePlate_00025018.dds`, sortName: `` },
{ id: `10103`, str: `俺の妹がこんなに可愛いわけがない。 【1】`, imagePath: `CHU_UI_NamePlate_00010103.dds`, sortName: `` },
{ id: `10104`, str: `俺の妹がこんなに可愛いわけがない。 【2】`, imagePath: `CHU_UI_NamePlate_00010104.dds`, sortName: `` },
{ id: `10105`, str: `俺の妹がこんなに可愛いわけがない。 【3】`, imagePath: `CHU_UI_NamePlate_00010105.dds`, sortName: `` },
{ id: `20013`, str: `大地の後継者たち`, imagePath: `CHU_UI_NamePlate_00020013.dds`, sortName: `` },
{ id: `10093`, str: `プロジェクトセカイ カラフルステージ! feat. 初音ミク 【7】`, imagePath: `CHU_UI_NamePlate_00010093.dds`, sortName: `` },
{ id: `10094`, str: `プロジェクトセカイ カラフルステージ! feat. 初音ミク 【8】`, imagePath: `CHU_UI_NamePlate_00010094.dds`, sortName: `` },
{ id: `10095`, str: `プロジェクトセカイ カラフルステージ! feat. 初音ミク 【9】`, imagePath: `CHU_UI_NamePlate_00010095.dds`, sortName: `` },
{ id: `10096`, str: `プロジェクトセカイ カラフルステージ! feat. 初音ミク 【10】`, imagePath: `CHU_UI_NamePlate_00010096.dds`, sortName: `` },
{ id: `25019`, str: `ティータ・アヴェニアス`, imagePath: `CHU_UI_NamePlate_00025019.dds`, sortName: `` },
{ id: `31000`, str: `KING of Performai The 4th ~優勝~`, imagePath: `CHU_UI_NamePlate_00031000.dds`, sortName: `K` },
{ id: `31001`, str: `KING of Performai The 4th FINALIST`, imagePath: `CHU_UI_NamePlate_00031001.dds`, sortName: `K` },
{ id: `10109`, str: `新サクラ大戦 【3】`, imagePath: `CHU_UI_NamePlate_00010109.dds`, sortName: `` },
{ id: `10110`, str: `さなちゃんねる 【1】`, imagePath: `CHU_UI_NamePlate_00010110.dds`, sortName: `` },
{ id: `10111`, str: `さなちゃんねる 【2】`, imagePath: `CHU_UI_NamePlate_00010111.dds`, sortName: `` },
{ id: `20014`, str: `First story of the SeelischTact`, imagePath: `CHU_UI_NamePlate_00020014.dds`, sortName: `F` },
{ id: `25020`, str: `MIR-203【セレネ・シェリル】`, imagePath: `CHU_UI_NamePlate_00025020.dds`, sortName: `M` },
{ id: `10112`, str: `Arcaea 【7】`, imagePath: `CHU_UI_NamePlate_00010112.dds`, sortName: `A` },
{ id: `10113`, str: `Arcaea 【8】`, imagePath: `CHU_UI_NamePlate_00010113.dds`, sortName: `A` },
{ id: `10121`, str: `Arcaea 【9】`, imagePath: `CHU_UI_NamePlate_00010121.dds`, sortName: `A` },
{ id: `10122`, str: `Arcaea 【10】`, imagePath: `CHU_UI_NamePlate_00010122.dds`, sortName: `A` },
{ id: `10129`, str: `NEEDY GIRL OVERDOSE 【1】`, imagePath: `CHU_UI_NamePlate_00010129.dds`, sortName: `N` },
{ id: `10130`, str: `NEEDY GIRL OVERDOSE 【2】`, imagePath: `CHU_UI_NamePlate_00010130.dds`, sortName: `N` },
{ id: `10131`, str: `NEEDY GIRL OVERDOSE 【3】`, imagePath: `CHU_UI_NamePlate_00010131.dds`, sortName: `N` },
{ id: `10091`, str: `HARDCORE TANO*C 【1】`, imagePath: `CHU_UI_NamePlate_00010091.dds`, sortName: `H` },
{ id: `10092`, str: `HARDCORE TANO*C 【2】`, imagePath: `CHU_UI_NamePlate_00010092.dds`, sortName: `H` },
{ id: `10163`, str: `ヘブンバーンズレッド 【4】`, imagePath: `CHU_UI_NamePlate_00010163.dds`, sortName: `` },
{ id: `10164`, str: `ヘブンバーンズレッド 【5】`, imagePath: `CHU_UI_NamePlate_00010164.dds`, sortName: `` },
{ id: `10165`, str: `ヘブンバーンズレッド 【6】`, imagePath: `CHU_UI_NamePlate_00010165.dds`, sortName: `` },
{ id: `30004`, str: `チュウニペンギン&ショウニペンギン (PARADISE)`, imagePath: `CHU_UI_NamePlate_00030004.dds`, sortName: `` },
{ id: `20016`, str: `GUMIN LIFE`, imagePath: `CHU_UI_NamePlate_00020016.dds`, sortName: `G` },
{ id: `10149`, str: `音楽的同位体プロジェクト 可不・星界 【1】`, imagePath: `CHU_UI_NamePlate_00010149.dds`, sortName: `` },
{ id: `10150`, str: `音楽的同位体プロジェクト 可不・星界 【2】`, imagePath: `CHU_UI_NamePlate_00010150.dds`, sortName: `` },
{ id: `10151`, str: `音楽的同位体プロジェクト 可不・星界 【3】`, imagePath: `CHU_UI_NamePlate_00010151.dds`, sortName: `` },
{ id: `10101`, str: `DECO*27 【1】`, imagePath: `CHU_UI_NamePlate_00010101.dds`, sortName: `D` },
{ id: `10102`, str: `DECO*27 【2】`, imagePath: `CHU_UI_NamePlate_00010102.dds`, sortName: `D` },
{ id: `10134`, str: `WACCA 【4】`, imagePath: `CHU_UI_NamePlate_00010134.dds`, sortName: `W` },
{ id: `31010`, str: `KOP4th International ver. CHAMPION`, imagePath: `CHU_UI_NamePlate_00031010.dds`, sortName: `K` },
{ id: `31011`, str: `KOP4th International ver. BEST8`, imagePath: `CHU_UI_NamePlate_00031011.dds`, sortName: `K` },
]

55
src/lib/systemvoice.ts Normal file
View File

@ -0,0 +1,55 @@
export const systemvoice = [
{ id: `1`, str: `チュウニペンギン`, imagePath: `CHU_UI_SystemVoice_00000001.dds`, sortName: `` },
{ id: `2`, str: `GOD`, imagePath: `CHU_UI_SystemVoice_00000002.dds`, sortName: `G` },
{ id: `3`, str: `月鈴 白奈`, imagePath: `CHU_UI_SystemVoice_00000003.dds`, sortName: `` },
{ id: `4`, str: `箱部 なる`, imagePath: `CHU_UI_SystemVoice_00000004.dds`, sortName: `` },
{ id: `5`, str: `スザク`, imagePath: `CHU_UI_SystemVoice_00000005.dds`, sortName: `` },
{ id: `6`, str: `天王洲 なずな`, imagePath: `CHU_UI_SystemVoice_00000006.dds`, sortName: `` },
{ id: `7`, str: `明坂 芹菜`, imagePath: `CHU_UI_SystemVoice_00000007.dds`, sortName: `` },
{ id: `8`, str: `トリスメギストス`, imagePath: `CHU_UI_SystemVoice_00000008.dds`, sortName: `` },
{ id: `9`, str: `MIR-202【アルテミス・レナ】`, imagePath: `CHU_UI_SystemVoice_00000009.dds`, sortName: `M` },
{ id: `10`, str: `小仏 凪`, imagePath: `CHU_UI_SystemVoice_00000010.dds`, sortName: `` },
{ id: `11`, str: `御形 アリシアナ`, imagePath: `CHU_UI_SystemVoice_00000011.dds`, sortName: `` },
{ id: `12`, str: `リリアリス・コルチカム`, imagePath: `CHU_UI_SystemVoice_00000012.dds`, sortName: `` },
{ id: `13`, str: `月鈴 那知`, imagePath: `CHU_UI_SystemVoice_00000013.dds`, sortName: `` },
{ id: `14`, str: `リヒトシュッツェ`, imagePath: `CHU_UI_SystemVoice_00000014.dds`, sortName: `` },
{ id: `15`, str: `HAR-ヒロイン09【ネレイダム】`, imagePath: `CHU_UI_SystemVoice_00000015.dds`, sortName: `H` },
{ id: `16`, str: `五十嵐 撫子`, imagePath: `CHU_UI_SystemVoice_00000016.dds`, sortName: `` },
{ id: `17`, str: `ダオ・トッテナ`, imagePath: `CHU_UI_SystemVoice_00000017.dds`, sortName: `` },
{ id: `18`, str: `萩原 七々瀬`, imagePath: `CHU_UI_SystemVoice_00000018.dds`, sortName: `` },
{ id: `19`, str: `八咫烏 鋼太郎`, imagePath: `CHU_UI_SystemVoice_00000019.dds`, sortName: `` },
{ id: `20`, str: `黒亀 北斗`, imagePath: `CHU_UI_SystemVoice_00000020.dds`, sortName: `` },
{ id: `21`, str: `暴虐のギーゼグール`, imagePath: `CHU_UI_SystemVoice_00000021.dds`, sortName: `` },
{ id: `22`, str: `小野 美苗`, imagePath: `CHU_UI_SystemVoice_00000022.dds`, sortName: `` },
{ id: `23`, str: `渋沢 `, imagePath: `CHU_UI_SystemVoice_00000023.dds`, sortName: `` },
{ id: `24`, str: `葛城 華`, imagePath: `CHU_UI_SystemVoice_00000024.dds`, sortName: `` },
{ id: `25`, str: `新井 桃子`, imagePath: `CHU_UI_SystemVoice_00000025.dds`, sortName: `` },
{ id: `26`, str: `MIR-201【ヘカティ・ベアトリクス】`, imagePath: `CHU_UI_SystemVoice_00000026.dds`, sortName: `M` },
{ id: `27`, str: `テスタメントネメシス`, imagePath: `CHU_UI_SystemVoice_00000027.dds`, sortName: `` },
{ id: `28`, str: `DJ-MEGA`, imagePath: `CHU_UI_SystemVoice_00000028.dds`, sortName: `D` },
{ id: `29`, str: `藤堂 陽南袴`, imagePath: `CHU_UI_SystemVoice_00000029.dds`, sortName: `` },
{ id: `30`, str: `桔梗 小夜曲`, imagePath: `CHU_UI_SystemVoice_00000030.dds`, sortName: `` },
{ id: `31`, str: `MDA-01【シリウス】`, imagePath: `CHU_UI_SystemVoice_00000031.dds`, sortName: `M` },
{ id: `32`, str: `芒崎 奏`, imagePath: `CHU_UI_SystemVoice_00000032.dds`, sortName: `` },
{ id: `33`, str: `ティフォン`, imagePath: `CHU_UI_SystemVoice_00000033.dds`, sortName: `` },
{ id: `34`, str: `イングリット・オーリック・コーネル`, imagePath: `CHU_UI_SystemVoice_00000034.dds`, sortName: `` },
{ id: `35`, str: `シルヴィアス`, imagePath: `CHU_UI_SystemVoice_00000035.dds`, sortName: `` },
{ id: `36`, str: `ジョニー・サイアスティン`, imagePath: `CHU_UI_SystemVoice_00000036.dds`, sortName: `` },
{ id: `37`, str: `魔法使いアルテラ`, imagePath: `CHU_UI_SystemVoice_00000037.dds`, sortName: `` },
{ id: `38`, str: `新田 ちえ`, imagePath: `CHU_UI_SystemVoice_00000038.dds`, sortName: `` },
{ id: `39`, str: `MDA-21【レグルス】`, imagePath: `CHU_UI_SystemVoice_00000039.dds`, sortName: `M` },
{ id: `40`, str: `ジュナ・サラキア`, imagePath: `CHU_UI_SystemVoice_00000040.dds`, sortName: `` },
{ id: `41`, str: `マリーメイア・クレスケンス`, imagePath: `CHU_UI_SystemVoice_00000041.dds`, sortName: `` },
{ id: `42`, str: `伊賀崎ノ楠子`, imagePath: `CHU_UI_SystemVoice_00000042.dds`, sortName: `` },
{ id: `43`, str: `ワイズマン`, imagePath: `CHU_UI_SystemVoice_00000043.dds`, sortName: `` },
{ id: `44`, str: `ヴェルゼビュートネメシス`, imagePath: `CHU_UI_SystemVoice_00000044.dds`, sortName: `` },
{ id: `45`, str: `イロドリミドリ/色彩過剰のダイアリーミュージック`, imagePath: `CHU_UI_SystemVoice_00000045.dds`, sortName: `` },
{ id: `46`, str: `オールドブルー`, imagePath: `CHU_UI_SystemVoice_00000046.dds`, sortName: `` },
{ id: `47`, str: `クーデルカ・プルミエール`, imagePath: `CHU_UI_SystemVoice_00000047.dds`, sortName: `` },
{ id: `48`, str: `エイハヴ`, imagePath: `CHU_UI_SystemVoice_00000048.dds`, sortName: `` },
{ id: `49`, str: `第八皇女エルルーン`, imagePath: `CHU_UI_SystemVoice_00000049.dds`, sortName: `` },
{ id: `50`, str: `宍戸 美鈴`, imagePath: `CHU_UI_SystemVoice_00000050.dds`, sortName: `` },
{ id: `51`, str: `リー・メイメイ`, imagePath: `CHU_UI_SystemVoice_00000051.dds`, sortName: `` },
{ id: `52`, str: `ティータ・アヴェニアス`, imagePath: `CHU_UI_SystemVoice_00000052.dds`, sortName: `` },
{ id: `53`, str: `MIR-203【セレネ・シェリル】`, imagePath: `CHU_UI_SystemVoice_00000053.dds`, sortName: `M` },
]

4345
src/lib/trophy.ts Normal file

File diff suppressed because it is too large Load Diff

6
src/lib/utils.ts Normal file
View File

@ -0,0 +1,6 @@
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}

78
tailwind.config.ts Normal file
View File

@ -0,0 +1,78 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
"./src/**/*.{ts,tsx}",
],
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
zIndex: {
'300': '300',
},
colors: {
rosewater: "#f4dbd6",
flamingo: "#f0c6c6",
pink: "#f5bde6",
mauve: "#c6a0f6",
red: "#ed8796",
maroon: "#ee99a0",
peach: "#f5a97f",
yellow: "#eed49f",
green: "#a6da95",
teal: "#8bd5ca",
sky: "#91d7e3",
sapphire: "#7dc4e4",
blue: "#8aadf4",
lavender: "#b7bdf8",
text: "#cad3f5",
subtext1: "#b8c0e0",
subtext0: "#a5adcb",
overlay2: "#939ab7",
overlay1: "#8087a2",
overlay0: "#6e738d",
surface2: "#5b6078",
surface1: "#494d64",
surface0: "#363a4f",
base: "#24273a",
mantle: "#1e2030",
crust: "#181926",
darkslateblue: "#0a3f93",
palegoldenrod: "#fcfab7",
darkslategray: {
"100": "#00607b",
"200": "#202c39",
},
honeydew: "#ecf5ea",
black: "#000",
deeppink: "#ff2c85",
lightyellow: "#f9f9db",
cornsilk: "#f8f1d4",
crimson: "#e92829",
gainsboro: "#d9d9d9",
},
spacing: {},
fontSize: {
xl: "20px",
inherit: "inherit",
},
},
},
plugins: [
require("tailwindcss-animate"),
require("tailwindcss"),
require("autoprefixer"),
],
};

27
tsconfig.json Normal file
View File

@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/components/shared/NavigationBar"],
"exclude": ["node_modules"]
}