Compare commits

..

No commits in common. "main" and "2.2" have entirely different histories.
main ... 2.2

62 changed files with 3197 additions and 1479 deletions

1
.gitignore vendored
View File

@ -7,4 +7,3 @@ configs/config.yaml
build build
main.spec main.spec
pyinstallericon.ico pyinstallericon.ico
icon.ico

View File

@ -8,7 +8,6 @@ pnpm-debug.log*
lerna-debug.log* lerna-debug.log*
node_modules node_modules
dist
dist-ssr dist-ssr
*.local *.local

View File

@ -4,9 +4,5 @@ This template provides a minimal setup to get React working in Vite with HMR and
Currently, two official plugins are available: Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
## Expanding the ESLint configuration
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

5
cdrm-frontend/dist/discord.svg vendored Normal file
View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<circle cx="512" cy="512" r="512" style="fill:#5865f2"/>
<path d="M689.43 349a422.21 422.21 0 0 0-104.22-32.32 1.58 1.58 0 0 0-1.68.79 294.11 294.11 0 0 0-13 26.66 389.78 389.78 0 0 0-117.05 0 269.75 269.75 0 0 0-13.18-26.66 1.64 1.64 0 0 0-1.68-.79A421 421 0 0 0 334.44 349a1.49 1.49 0 0 0-.69.59c-66.37 99.17-84.55 195.9-75.63 291.41a1.76 1.76 0 0 0 .67 1.2 424.58 424.58 0 0 0 127.85 64.63 1.66 1.66 0 0 0 1.8-.59 303.45 303.45 0 0 0 26.15-42.54 1.62 1.62 0 0 0-.89-2.25 279.6 279.6 0 0 1-39.94-19 1.64 1.64 0 0 1-.16-2.72c2.68-2 5.37-4.1 7.93-6.22a1.58 1.58 0 0 1 1.65-.22c83.79 38.26 174.51 38.26 257.31 0a1.58 1.58 0 0 1 1.68.2c2.56 2.11 5.25 4.23 8 6.24a1.64 1.64 0 0 1-.14 2.72 262.37 262.37 0 0 1-40 19 1.63 1.63 0 0 0-.87 2.28 340.72 340.72 0 0 0 26.13 42.52 1.62 1.62 0 0 0 1.8.61 423.17 423.17 0 0 0 128-64.63 1.64 1.64 0 0 0 .67-1.18c10.68-110.44-17.88-206.38-75.7-291.42a1.3 1.3 0 0 0-.63-.63zM427.09 582.85c-25.23 0-46-23.16-46-51.6s20.38-51.6 46-51.6c25.83 0 46.42 23.36 46 51.6.02 28.44-20.37 51.6-46 51.6zm170.13 0c-25.23 0-46-23.16-46-51.6s20.38-51.6 46-51.6c25.83 0 46.42 23.36 46 51.6.01 28.44-20.17 51.6-46 51.6z" style="fill:#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

9
cdrm-frontend/dist/docu_logo.svg vendored Normal file
View File

@ -0,0 +1,9 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg" fill="#000000">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier">
<path d="M877.685565 727.913127l-0.584863-0.365539a32.898541 32.898541 0 0 1-8.041866-46.423497 411.816631 411.816631 0 1 0-141.829267 145.777092c14.621574-8.992268 33.62962-5.117551 43.645398 8.772944l0.146216 0.073108a30.412874 30.412874 0 0 1-7.968758 43.206751l-6.141061 4.020933a475.201154 475.201154 0 1 1 163.615412-164.419599 29.974227 29.974227 0 0 1-42.841211 9.357807z m-537.342843-398.584106c7.164571-7.091463 24.71046-9.650239 33.26408 0 10.600641 11.185504 7.164571 29.462472 0 37.138798l-110.612207 107.468569L370.901811 576.14119c7.164571 7.091463 8.114974 27.342343 0 35.384209-9.796455 9.723347-29.828011 8.188081-36.480827 1.535265L208.309909 487.388236a18.423183 18.423183 0 0 1 0-25.953294l132.032813-132.032813z m343.314556 0l132.032813 132.032813a18.423183 18.423183 0 0 1 0 25.953294L689.652124 613.133772c-6.652816 6.579708-25.587754 10.746857-36.553935 0-10.30821-10.235102-7.091463-31.290168 0-38.381632l108.345863-100.669537-111.855041-108.638294c-7.164571-7.676326-9.504023-26.611265 0-36.04218 9.284699-9.138484 26.903696-7.091463 34.068267 0z m-135.54199-26.318833c3.582286-9.504023 21.347498-15.498868 32.679217-11.258612 10.819965 4.020933 17.180349 19.008046 14.256035 28.512069l-119.896906 329.716493c-3.509178 9.504023-20.616419 13.305632-30.193551 9.723347-10.161994-3.509178-21.201282-17.545889-17.545888-26.976804l120.627985-329.716493z" fill="#ffffff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
cdrm-frontend/dist/favico.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

19
cdrm-frontend/dist/github.svg vendored Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>github [#142]</title>
<desc>Created with Sketch.</desc>
<defs>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Dribbble-Light-Preview" transform="translate(-140.000000, -7559.000000)" fill="#000000">
<g id="icons" transform="translate(56.000000, 160.000000)">
<path d="M94,7399 C99.523,7399 104,7403.59 104,7409.253 C104,7413.782 101.138,7417.624 97.167,7418.981 C96.66,7419.082 96.48,7418.762 96.48,7418.489 C96.48,7418.151 96.492,7417.047 96.492,7415.675 C96.492,7414.719 96.172,7414.095 95.813,7413.777 C98.04,7413.523 100.38,7412.656 100.38,7408.718 C100.38,7407.598 99.992,7406.684 99.35,7405.966 C99.454,7405.707 99.797,7404.664 99.252,7403.252 C99.252,7403.252 98.414,7402.977 96.505,7404.303 C95.706,7404.076 94.85,7403.962 94,7403.958 C93.15,7403.962 92.295,7404.076 91.497,7404.303 C89.586,7402.977 88.746,7403.252 88.746,7403.252 C88.203,7404.664 88.546,7405.707 88.649,7405.966 C88.01,7406.684 87.619,7407.598 87.619,7408.718 C87.619,7412.646 89.954,7413.526 92.175,7413.785 C91.889,7414.041 91.63,7414.493 91.54,7415.156 C90.97,7415.418 89.522,7415.871 88.63,7414.304 C88.63,7414.304 88.101,7413.319 87.097,7413.247 C87.097,7413.247 86.122,7413.234 87.029,7413.87 C87.029,7413.87 87.684,7414.185 88.139,7415.37 C88.139,7415.37 88.726,7417.2 91.508,7416.58 C91.513,7417.437 91.522,7418.245 91.522,7418.489 C91.522,7418.76 91.338,7419.077 90.839,7418.982 C86.865,7417.627 84,7413.783 84,7409.253 C84,7403.59 88.478,7399 94,7399" id="github-[#142]">
</path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

1
cdrm-frontend/dist/home.svg vendored Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="50px" height="50px" fill-rule="nonzero"><g fill="#ffffff" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(5.12,5.12)"><path d="M24.96289,1.05469c-0.20987,0.00724 -0.41214,0.08036 -0.57812,0.20898l-23,17.94727c-0.43579,0.33978 -0.51361,0.96851 -0.17383,1.4043c0.33978,0.43579 0.96851,0.51361 1.4043,0.17383l1.38477,-1.08008v26.29102c0.00006,0.55226 0.44774,0.99994 1,1h13.83203c0.10799,0.01785 0.21818,0.01785 0.32617,0h11.67383c0.10799,0.01785 0.21818,0.01785 0.32617,0h13.8418c0.55226,-0.00006 0.99994,-0.44774 1,-1v-26.29102l1.38477,1.08008c0.2819,0.21983 0.65967,0.27257 0.991,0.13833c0.33133,-0.13423 0.56586,-0.43504 0.61526,-0.7891c0.0494,-0.35406 -0.09386,-0.70757 -0.37579,-0.92736l-7.61523,-5.94141v-7.26953h-6v2.58594l-9.38477,-7.32227c-0.18607,-0.14428 -0.41707,-0.21828 -0.65234,-0.20898zM25,3.32227l19,14.82617v26.85156h-12v-19h-14v19h-12v-26.85156zM37,8h2v3.70898l-2,-1.5625zM20,28h10v17h-10z"></path></g></g></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,4 +1,3 @@
<<<<<<< Updated upstream
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
@ -19,26 +18,4 @@
<body> <body>
<div id="root"></div> <div id="root"></div>
</body> </body>
=======
<!doctype html>
<html lang="en" class="w-full h-full">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favico.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="{{ data.description }}"/>
<meta name="keywords" content="{{ data.keywords }}"/>
<meta property='og:title' content="{{ data.opengraph_title }}" />
<meta property='og:description' content="{{ data.opengraph_description }}" />
<meta property='og:image' content="{{ data.opengraph_image }}" />
<meta property='og:url' content="{{ data.opengraph_url }}" />
<meta property='og:locale' content='en_US' />
<title>{{ data.tab_title }}</title>
<script type="module" crossorigin src="/assets/index-Hj0TonAS.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DhrTUBtZ.css">
</head>
<body class="w-full h-full">
<div id="root" class="w-full h-full"></div>
</body>
>>>>>>> Stashed changes
</html> </html>

1
cdrm-frontend/dist/logo.svg vendored Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.5 13.100000381469727 321.79998779296875 36.69999694824219" data-asc="0.984"><g fill="#ffffff"><g fill="#ffffff" transform="translate(0, 0)"><path d="M13.15 49.80Q10.10 49.80 7.60 48.58Q5.10 47.35 3.28 45.10Q1.45 42.85 0.47 39.68Q-0.50 36.50-0.50 32.60Q-0.50 27.40 1.25 23.58Q3 19.75 6.13 17.68Q9.25 15.60 13.45 15.60Q16.30 15.60 18.45 16.80Q20.60 18 21.85 19.50L20.85 20.60Q19.50 19 17.65 18.05Q15.80 17.10 13.45 17.10Q9.65 17.10 6.90 19Q4.15 20.90 2.67 24.38Q1.20 27.85 1.20 32.60Q1.20 37.35 2.67 40.88Q4.15 44.40 6.85 46.35Q9.55 48.30 13.25 48.30Q15.90 48.30 17.95 47.25Q20.00 46.20 21.85 44.10L22.85 45.10Q21.00 47.25 18.70 48.53Q16.40 49.80 13.15 49.80ZM30.80 49.20L30.80 16.20L38.20 16.20Q43.30 16.20 46.58 18.25Q49.85 20.30 51.42 24Q53 27.70 53 32.60Q53 37.50 51.42 41.25Q49.85 45 46.58 47.10Q43.30 49.20 38.20 49.20L30.80 49.20M32.40 47.80L38 47.80Q42.70 47.80 45.63 45.80Q48.55 43.80 49.92 40.38Q51.30 36.95 51.30 32.60Q51.30 28.25 49.92 24.85Q48.55 21.45 45.63 19.53Q42.70 17.60 38 17.60L32.40 17.60L32.40 47.80ZM62 49.20L62 16.20L71.10 16.20Q74.35 16.20 76.72 17.05Q79.10 17.90 80.40 19.78Q81.70 21.65 81.70 24.70Q81.70 27.60 80.40 29.58Q79.10 31.55 76.72 32.58Q74.35 33.60 71.10 33.60L63.60 33.60L63.60 49.20L62 49.20M63.60 32.20L70.50 32.20Q75.10 32.20 77.55 30.35Q80 28.50 80 24.70Q80 20.80 77.55 19.20Q75.10 17.60 70.50 17.60L63.60 17.60L63.60 32.20M70.70 33.10L72.50 33L82.20 49.20L80.30 49.20L70.70 33.10ZM90 49.20L90 16.20L92.30 16.20L98.50 32.20L100.70 38.10L100.90 38.10L103 32.20L109.30 16.20L111.60 16.20L111.60 49.20L110 49.20L110 24.45Q110 23.70 110.03 22.88Q110.05 22.05 110.08 21.25Q110.10 20.45 110.13 19.63Q110.15 18.80 110.15 18.05L110 18.05L108.20 23.40L101.45 40.40L100.10 40.40L93.40 23.40L91.45 18.05L91.35 18.05Q91.35 18.80 91.40 19.63Q91.45 20.45 91.47 21.25Q91.50 22.05 91.52 22.88Q91.55 23.70 91.55 24.45L91.55 49.20L90 49.20ZM152 49.20L152 16.20L161.10 16.20Q164.35 16.20 166.73 17.05Q169.10 17.90 170.40 19.78Q171.70 21.65 171.70 24.70Q171.70 27.60 170.40 29.58Q169.10 31.55 166.73 32.58Q164.35 33.60 161.10 33.60L153.60 33.60L153.60 49.20L152 49.20M153.60 32.20L160.50 32.20Q165.10 32.20 167.55 30.35Q170 28.50 170 24.70Q170 20.80 167.55 19.20Q165.10 17.60 160.50 17.60L153.60 17.60L153.60 32.20M160.70 33.10L162.50 33L172.20 49.20L170.30 49.20L160.70 33.10ZM192.30 49.80Q188.90 49.80 186.05 48.30Q183.20 46.80 181.50 44Q179.80 41.20 179.80 37.30Q179.80 33.40 181.48 30.58Q183.15 27.75 185.88 26.23Q188.60 24.70 191.70 24.70Q194.90 24.70 197.28 26Q199.65 27.30 200.98 29.78Q202.30 32.25 202.30 35.70Q202.30 36.05 202.30 36.45Q202.30 36.85 202.20 37.30L180.30 37.30L180.30 35.90L201.80 35.90L200.90 36.70Q200.90 31.30 198.33 28.70Q195.75 26.10 191.70 26.10Q189.10 26.10 186.75 27.43Q184.40 28.75 182.90 31.23Q181.40 33.70 181.40 37.20Q181.40 40.80 182.93 43.30Q184.45 45.80 186.93 47.10Q189.40 48.40 192.30 48.40Q194.85 48.40 196.88 47.65Q198.90 46.90 200.60 45.70L201.30 47Q199.75 48 197.65 48.90Q195.55 49.80 192.30 49.80ZM221.10 49.80Q219.25 49.80 217 48.90Q214.75 48 212.90 46.50L212.80 46.50L212.60 49.20L211.30 49.20L211.30 13.10L212.80 13.10L212.80 23.80L212.70 29.10L212.80 29.10Q214.70 27.15 217.20 25.93Q219.70 24.70 222.10 24.70Q225.55 24.70 227.80 26.20Q230.05 27.70 231.18 30.45Q232.30 33.20 232.30 36.90Q232.30 40.95 230.75 43.83Q229.20 46.70 226.65 48.25Q224.10 49.80 221.10 49.80M221.20 48.40Q223.95 48.40 226.10 46.93Q228.25 45.45 229.48 42.85Q230.70 40.25 230.70 36.90Q230.70 33.85 229.83 31.40Q228.95 28.95 227.05 27.53Q225.15 26.10 222 26.10Q220 26.10 217.60 27.25Q215.20 28.40 212.80 30.80L212.80 44.60Q215.05 46.65 217.35 47.53Q219.65 48.40 221.20 48.40ZM250.80 49.80Q247.65 49.80 245.05 48.33Q242.45 46.85 240.88 44.05Q239.30 41.25 239.30 37.30Q239.30 33.30 240.88 30.48Q242.45 27.65 245.05 26.18Q247.65 24.70 250.80 24.70Q253.95 24.70 256.55 26.18Q259.15 27.65 260.73 30.48Q262.30 33.30 262.30 37.30Q262.30 41.25 260.73 44.05Q259.15 46.85 256.55 48.33Q253.95 49.80 250.80 49.80M250.80 48.40Q253.65 48.40 255.90 47Q258.15 45.60 259.43 43.10Q260.70 40.60 260.70 37.30Q260.70 34 259.43 31.48Q258.15 28.95 255.90 27.53Q253.65 26.10 250.80 26.10Q247.95 26.10 245.73 27.53Q243.50 28.95 242.20 31.48Q240.90 34 240.90 37.30Q240.90 40.60 242.20 43.10Q243.50 45.60 245.73 47Q247.95 48.40 250.80 48.40ZM274.30 49.20L274.30 25.30L275.60 25.30L275.80 31.30L275.90 31.30Q277.85 28.45 280.78 26.58Q283.70 24.70 287.35 24.70Q288.50 24.70 289.78 24.90Q291.05 25.10 292.20 25.70L291.70 27.10Q290.35 26.60 289.48 26.40Q288.60 26.20 287.15 26.20Q284.05 26.20 281.25 27.95Q278.45 29.70 275.80 33.90L275.80 49.20L274.30 49.20ZM301.30 49.20L301.30 25.30L302.60 25.30L302.80 30.10L303 30.10Q305.15 27.75 307.43 26.23Q309.70 24.70 312.60 24.70Q317 24.70 319.15 27.05Q321.30 29.40 321.30 34.30L321.30 49.20L319.80 49.20L319.80 34.50Q319.80 30.25 318.10 28.18Q316.40 26.10 312.60 26.10Q309.90 26.10 307.75 27.53Q305.60 28.95 302.80 31.90L302.80 49.20L301.30 49.20Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
cdrm-frontend/dist/og-api.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

BIN
cdrm-frontend/dist/og-cache.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

BIN
cdrm-frontend/dist/og-home.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

BIN
cdrm-frontend/dist/og-testplayer.jpg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

7
cdrm-frontend/dist/profile.svg vendored Normal file
View File

@ -0,0 +1,7 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#ffffff">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <title>profile_round [#ffffff]</title> <desc>Created with Sketch.</desc> <defs> </defs> <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <g id="Dribbble-Light-Preview" transform="translate(-140.000000, -2159.000000)" fill="#ffffff"> <g id="icons" transform="translate(56.000000, 160.000000)"> <path d="M100.562548,2016.99998 L87.4381713,2016.99998 C86.7317804,2016.99998 86.2101535,2016.30298 86.4765813,2015.66198 C87.7127655,2012.69798 90.6169306,2010.99998 93.9998492,2010.99998 C97.3837885,2010.99998 100.287954,2012.69798 101.524138,2015.66198 C101.790566,2016.30298 101.268939,2016.99998 100.562548,2016.99998 M89.9166645,2004.99998 C89.9166645,2002.79398 91.7489936,2000.99998 93.9998492,2000.99998 C96.2517256,2000.99998 98.0830339,2002.79398 98.0830339,2004.99998 C98.0830339,2007.20598 96.2517256,2008.99998 93.9998492,2008.99998 C91.7489936,2008.99998 89.9166645,2007.20598 89.9166645,2004.99998 M103.955674,2016.63598 C103.213556,2013.27698 100.892265,2010.79798 97.837022,2009.67298 C99.4560048,2008.39598 100.400241,2006.33098 100.053171,2004.06998 C99.6509769,2001.44698 97.4235996,1999.34798 94.7348224,1999.04198 C91.0232075,1998.61898 87.8750721,2001.44898 87.8750721,2004.99998 C87.8750721,2006.88998 88.7692896,2008.57398 90.1636971,2009.67298 C87.1074334,2010.79798 84.7871636,2013.27698 84.044024,2016.63598 C83.7745338,2017.85698 84.7789973,2018.99998 86.0539717,2018.99998 L101.945727,2018.99998 C103.221722,2018.99998 104.226185,2017.85698 103.955674,2016.63598" id="profile_round-[#ffffff]"> </path> </g> </g> </g> </g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -3,5 +3,5 @@
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="SVGRepo_bgCarrier" stroke-width="0"/> <g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/> <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <circle cx="12" cy="12" r="10" stroke="#ffffff" stroke-width="1.5"/> <path d="M14.5 9.50002L9.5 14.5M9.49998 9.5L14.5 14.5" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round"/> </g> <g id="SVGRepo_iconCarrier"> <g id="Interface / Search_Magnifying_Glass"> <path id="Vector" d="M15 15L21 21M10 17C6.13401 17 3 13.866 3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17Z" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 641 B

After

Width:  |  Height:  |  Size: 733 B

11
cdrm-frontend/dist/telegram.svg vendored Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)"/>
<path d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30" gradientUnits="userSpaceOnUse">
<stop stop-color="#37BBFE"/>
<stop offset="1" stop-color="#007DBB"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 920 B

View File

@ -1,7 +1,7 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools --> <!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="#ffffff"> <svg width="800px" height="800px" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="SVGRepo_bgCarrier" stroke-width="0"/> <g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/> <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <path fill-rule="evenodd" clip-rule="evenodd" d="M8 0L0 6V8H1V15H4V10H7V15H15V8H16V6L14 4.5V1H11V2.25L8 0ZM9 10H12V13H9V10Z" fill="#ffffff"/> </g> <g id="SVGRepo_iconCarrier"> <path fill-rule="evenodd" clip-rule="evenodd" d="M16 2H0V14H16V2ZM6.5 5V11H7.5L11 8L7.5 5H6.5Z" fill="#ffffff"/> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 615 B

After

Width:  |  Height:  |  Size: 569 B

View File

@ -1,5 +1,6 @@
import js from '@eslint/js' import js from '@eslint/js'
import globals from 'globals' import globals from 'globals'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks' import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh' import reactRefresh from 'eslint-plugin-react-refresh'
@ -16,14 +17,18 @@ export default [
sourceType: 'module', sourceType: 'module',
}, },
}, },
settings: { react: { version: '18.3' } },
plugins: { plugins: {
react,
'react-hooks': reactHooks, 'react-hooks': reactHooks,
'react-refresh': reactRefresh, 'react-refresh': reactRefresh,
}, },
rules: { rules: {
...js.configs.recommended.rules, ...js.configs.recommended.rules,
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
...reactHooks.configs.recommended.rules, ...reactHooks.configs.recommended.rules,
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }], 'react/jsx-no-target-blank': 'off',
'react-refresh/only-export-components': [ 'react-refresh/only-export-components': [
'warn', 'warn',
{ allowConstantExport: true }, { allowConstantExport: true },

View File

@ -1,5 +1,5 @@
<!doctype html> <!doctype html>
<html lang="en" class="w-full h-full"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favico.png" /> <link rel="icon" type="image/svg+xml" href="/favico.png" />
@ -13,8 +13,8 @@
<meta property='og:locale' content='en_US' /> <meta property='og:locale' content='en_US' />
<title>{{ data.tab_title }}</title> <title>{{ data.tab_title }}</title>
</head> </head>
<body class="w-full h-full"> <body>
<div id="root" class="w-full h-full"></div> <div id="root"></div>
<script type="module" src="/src/main.jsx"></script> <script type="module" src="/src/main.jsx"></script>
</body> </body>
</html> </html>

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
{ {
"name": "cdrm-frontend", "name": "cdrm",
"private": true, "private": true,
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
@ -10,23 +10,27 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@tailwindcss/vite": "^4.1.4", "@tailwindcss/vite": "^4.0.0",
"react": "^19.0.0", "atob": "^2.1.2",
"react-dom": "^19.0.0", "helmet": "^8.1.0",
"proto.js": "^0.2.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-helmet": "^6.1.0", "react-helmet": "^6.1.0",
"react-router-dom": "^7.5.2", "react-router-dom": "^7.1.3",
"shaka-player": "^4.14.9", "shaka-player": "^4.13.0",
"tailwindcss": "^4.1.4" "tailwindcss": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.22.0", "@eslint/js": "^9.17.0",
"@types/react": "^19.0.10", "@types/react": "^18.3.18",
"@types/react-dom": "^19.0.4", "@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4", "@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.22.0", "eslint": "^9.17.0",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-refresh": "^0.4.19", "eslint-plugin-react-hooks": "^5.0.0",
"globals": "^16.0.0", "eslint-plugin-react-refresh": "^0.4.16",
"vite": "^6.3.1" "globals": "^15.14.0",
"vite": "^6.3.2"
} }
} }

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<circle cx="512" cy="512" r="512" style="fill:#5865f2"/>
<path d="M689.43 349a422.21 422.21 0 0 0-104.22-32.32 1.58 1.58 0 0 0-1.68.79 294.11 294.11 0 0 0-13 26.66 389.78 389.78 0 0 0-117.05 0 269.75 269.75 0 0 0-13.18-26.66 1.64 1.64 0 0 0-1.68-.79A421 421 0 0 0 334.44 349a1.49 1.49 0 0 0-.69.59c-66.37 99.17-84.55 195.9-75.63 291.41a1.76 1.76 0 0 0 .67 1.2 424.58 424.58 0 0 0 127.85 64.63 1.66 1.66 0 0 0 1.8-.59 303.45 303.45 0 0 0 26.15-42.54 1.62 1.62 0 0 0-.89-2.25 279.6 279.6 0 0 1-39.94-19 1.64 1.64 0 0 1-.16-2.72c2.68-2 5.37-4.1 7.93-6.22a1.58 1.58 0 0 1 1.65-.22c83.79 38.26 174.51 38.26 257.31 0a1.58 1.58 0 0 1 1.68.2c2.56 2.11 5.25 4.23 8 6.24a1.64 1.64 0 0 1-.14 2.72 262.37 262.37 0 0 1-40 19 1.63 1.63 0 0 0-.87 2.28 340.72 340.72 0 0 0 26.13 42.52 1.62 1.62 0 0 0 1.8.61 423.17 423.17 0 0 0 128-64.63 1.64 1.64 0 0 0 .67-1.18c10.68-110.44-17.88-206.38-75.7-291.42a1.3 1.3 0 0 0-.63-.63zM427.09 582.85c-25.23 0-46-23.16-46-51.6s20.38-51.6 46-51.6c25.83 0 46.42 23.36 46 51.6.02 28.44-20.37 51.6-46 51.6zm170.13 0c-25.23 0-46-23.16-46-51.6s20.38-51.6 46-51.6c25.83 0 46.42 23.36 46 51.6.01 28.44-20.17 51.6-46 51.6z" style="fill:#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,9 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg" fill="#000000">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier">
<path d="M877.685565 727.913127l-0.584863-0.365539a32.898541 32.898541 0 0 1-8.041866-46.423497 411.816631 411.816631 0 1 0-141.829267 145.777092c14.621574-8.992268 33.62962-5.117551 43.645398 8.772944l0.146216 0.073108a30.412874 30.412874 0 0 1-7.968758 43.206751l-6.141061 4.020933a475.201154 475.201154 0 1 1 163.615412-164.419599 29.974227 29.974227 0 0 1-42.841211 9.357807z m-537.342843-398.584106c7.164571-7.091463 24.71046-9.650239 33.26408 0 10.600641 11.185504 7.164571 29.462472 0 37.138798l-110.612207 107.468569L370.901811 576.14119c7.164571 7.091463 8.114974 27.342343 0 35.384209-9.796455 9.723347-29.828011 8.188081-36.480827 1.535265L208.309909 487.388236a18.423183 18.423183 0 0 1 0-25.953294l132.032813-132.032813z m343.314556 0l132.032813 132.032813a18.423183 18.423183 0 0 1 0 25.953294L689.652124 613.133772c-6.652816 6.579708-25.587754 10.746857-36.553935 0-10.30821-10.235102-7.091463-31.290168 0-38.381632l108.345863-100.669537-111.855041-108.638294c-7.164571-7.676326-9.504023-26.611265 0-36.04218 9.284699-9.138484 26.903696-7.091463 34.068267 0z m-135.54199-26.318833c3.582286-9.504023 21.347498-15.498868 32.679217-11.258612 10.819965 4.020933 17.180349 19.008046 14.256035 28.512069l-119.896906 329.716493c-3.509178 9.504023-20.616419 13.305632-30.193551 9.723347-10.161994-3.509178-21.201282-17.545889-17.545888-26.976804l120.627985-329.716493z" fill="#ffffff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>github [#142]</title>
<desc>Created with Sketch.</desc>
<defs>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Dribbble-Light-Preview" transform="translate(-140.000000, -7559.000000)" fill="#000000">
<g id="icons" transform="translate(56.000000, 160.000000)">
<path d="M94,7399 C99.523,7399 104,7403.59 104,7409.253 C104,7413.782 101.138,7417.624 97.167,7418.981 C96.66,7419.082 96.48,7418.762 96.48,7418.489 C96.48,7418.151 96.492,7417.047 96.492,7415.675 C96.492,7414.719 96.172,7414.095 95.813,7413.777 C98.04,7413.523 100.38,7412.656 100.38,7408.718 C100.38,7407.598 99.992,7406.684 99.35,7405.966 C99.454,7405.707 99.797,7404.664 99.252,7403.252 C99.252,7403.252 98.414,7402.977 96.505,7404.303 C95.706,7404.076 94.85,7403.962 94,7403.958 C93.15,7403.962 92.295,7404.076 91.497,7404.303 C89.586,7402.977 88.746,7403.252 88.746,7403.252 C88.203,7404.664 88.546,7405.707 88.649,7405.966 C88.01,7406.684 87.619,7407.598 87.619,7408.718 C87.619,7412.646 89.954,7413.526 92.175,7413.785 C91.889,7414.041 91.63,7414.493 91.54,7415.156 C90.97,7415.418 89.522,7415.871 88.63,7414.304 C88.63,7414.304 88.101,7413.319 87.097,7413.247 C87.097,7413.247 86.122,7413.234 87.029,7413.87 C87.029,7413.87 87.684,7414.185 88.139,7415.37 C88.139,7415.37 88.726,7417.2 91.508,7416.58 C91.513,7417.437 91.522,7418.245 91.522,7418.489 C91.522,7418.76 91.338,7419.077 90.839,7418.982 C86.865,7417.627 84,7413.783 84,7409.253 C84,7403.59 88.478,7399 94,7399" id="github-[#142]">
</path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="50px" height="50px" fill-rule="nonzero"><g fill="#ffffff" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(5.12,5.12)"><path d="M24.96289,1.05469c-0.20987,0.00724 -0.41214,0.08036 -0.57812,0.20898l-23,17.94727c-0.43579,0.33978 -0.51361,0.96851 -0.17383,1.4043c0.33978,0.43579 0.96851,0.51361 1.4043,0.17383l1.38477,-1.08008v26.29102c0.00006,0.55226 0.44774,0.99994 1,1h13.83203c0.10799,0.01785 0.21818,0.01785 0.32617,0h11.67383c0.10799,0.01785 0.21818,0.01785 0.32617,0h13.8418c0.55226,-0.00006 0.99994,-0.44774 1,-1v-26.29102l1.38477,1.08008c0.2819,0.21983 0.65967,0.27257 0.991,0.13833c0.33133,-0.13423 0.56586,-0.43504 0.61526,-0.7891c0.0494,-0.35406 -0.09386,-0.70757 -0.37579,-0.92736l-7.61523,-5.94141v-7.26953h-6v2.58594l-9.38477,-7.32227c-0.18607,-0.14428 -0.41707,-0.21828 -0.65234,-0.20898zM25,3.32227l19,14.82617v26.85156h-12v-19h-14v19h-12v-26.85156zM37,8h2v3.70898l-2,-1.5625zM20,28h10v17h-10z"></path></g></g></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.5 13.100000381469727 321.79998779296875 36.69999694824219" data-asc="0.984"><g fill="#ffffff"><g fill="#ffffff" transform="translate(0, 0)"><path d="M13.15 49.80Q10.10 49.80 7.60 48.58Q5.10 47.35 3.28 45.10Q1.45 42.85 0.47 39.68Q-0.50 36.50-0.50 32.60Q-0.50 27.40 1.25 23.58Q3 19.75 6.13 17.68Q9.25 15.60 13.45 15.60Q16.30 15.60 18.45 16.80Q20.60 18 21.85 19.50L20.85 20.60Q19.50 19 17.65 18.05Q15.80 17.10 13.45 17.10Q9.65 17.10 6.90 19Q4.15 20.90 2.67 24.38Q1.20 27.85 1.20 32.60Q1.20 37.35 2.67 40.88Q4.15 44.40 6.85 46.35Q9.55 48.30 13.25 48.30Q15.90 48.30 17.95 47.25Q20.00 46.20 21.85 44.10L22.85 45.10Q21.00 47.25 18.70 48.53Q16.40 49.80 13.15 49.80ZM30.80 49.20L30.80 16.20L38.20 16.20Q43.30 16.20 46.58 18.25Q49.85 20.30 51.42 24Q53 27.70 53 32.60Q53 37.50 51.42 41.25Q49.85 45 46.58 47.10Q43.30 49.20 38.20 49.20L30.80 49.20M32.40 47.80L38 47.80Q42.70 47.80 45.63 45.80Q48.55 43.80 49.92 40.38Q51.30 36.95 51.30 32.60Q51.30 28.25 49.92 24.85Q48.55 21.45 45.63 19.53Q42.70 17.60 38 17.60L32.40 17.60L32.40 47.80ZM62 49.20L62 16.20L71.10 16.20Q74.35 16.20 76.72 17.05Q79.10 17.90 80.40 19.78Q81.70 21.65 81.70 24.70Q81.70 27.60 80.40 29.58Q79.10 31.55 76.72 32.58Q74.35 33.60 71.10 33.60L63.60 33.60L63.60 49.20L62 49.20M63.60 32.20L70.50 32.20Q75.10 32.20 77.55 30.35Q80 28.50 80 24.70Q80 20.80 77.55 19.20Q75.10 17.60 70.50 17.60L63.60 17.60L63.60 32.20M70.70 33.10L72.50 33L82.20 49.20L80.30 49.20L70.70 33.10ZM90 49.20L90 16.20L92.30 16.20L98.50 32.20L100.70 38.10L100.90 38.10L103 32.20L109.30 16.20L111.60 16.20L111.60 49.20L110 49.20L110 24.45Q110 23.70 110.03 22.88Q110.05 22.05 110.08 21.25Q110.10 20.45 110.13 19.63Q110.15 18.80 110.15 18.05L110 18.05L108.20 23.40L101.45 40.40L100.10 40.40L93.40 23.40L91.45 18.05L91.35 18.05Q91.35 18.80 91.40 19.63Q91.45 20.45 91.47 21.25Q91.50 22.05 91.52 22.88Q91.55 23.70 91.55 24.45L91.55 49.20L90 49.20ZM152 49.20L152 16.20L161.10 16.20Q164.35 16.20 166.73 17.05Q169.10 17.90 170.40 19.78Q171.70 21.65 171.70 24.70Q171.70 27.60 170.40 29.58Q169.10 31.55 166.73 32.58Q164.35 33.60 161.10 33.60L153.60 33.60L153.60 49.20L152 49.20M153.60 32.20L160.50 32.20Q165.10 32.20 167.55 30.35Q170 28.50 170 24.70Q170 20.80 167.55 19.20Q165.10 17.60 160.50 17.60L153.60 17.60L153.60 32.20M160.70 33.10L162.50 33L172.20 49.20L170.30 49.20L160.70 33.10ZM192.30 49.80Q188.90 49.80 186.05 48.30Q183.20 46.80 181.50 44Q179.80 41.20 179.80 37.30Q179.80 33.40 181.48 30.58Q183.15 27.75 185.88 26.23Q188.60 24.70 191.70 24.70Q194.90 24.70 197.28 26Q199.65 27.30 200.98 29.78Q202.30 32.25 202.30 35.70Q202.30 36.05 202.30 36.45Q202.30 36.85 202.20 37.30L180.30 37.30L180.30 35.90L201.80 35.90L200.90 36.70Q200.90 31.30 198.33 28.70Q195.75 26.10 191.70 26.10Q189.10 26.10 186.75 27.43Q184.40 28.75 182.90 31.23Q181.40 33.70 181.40 37.20Q181.40 40.80 182.93 43.30Q184.45 45.80 186.93 47.10Q189.40 48.40 192.30 48.40Q194.85 48.40 196.88 47.65Q198.90 46.90 200.60 45.70L201.30 47Q199.75 48 197.65 48.90Q195.55 49.80 192.30 49.80ZM221.10 49.80Q219.25 49.80 217 48.90Q214.75 48 212.90 46.50L212.80 46.50L212.60 49.20L211.30 49.20L211.30 13.10L212.80 13.10L212.80 23.80L212.70 29.10L212.80 29.10Q214.70 27.15 217.20 25.93Q219.70 24.70 222.10 24.70Q225.55 24.70 227.80 26.20Q230.05 27.70 231.18 30.45Q232.30 33.20 232.30 36.90Q232.30 40.95 230.75 43.83Q229.20 46.70 226.65 48.25Q224.10 49.80 221.10 49.80M221.20 48.40Q223.95 48.40 226.10 46.93Q228.25 45.45 229.48 42.85Q230.70 40.25 230.70 36.90Q230.70 33.85 229.83 31.40Q228.95 28.95 227.05 27.53Q225.15 26.10 222 26.10Q220 26.10 217.60 27.25Q215.20 28.40 212.80 30.80L212.80 44.60Q215.05 46.65 217.35 47.53Q219.65 48.40 221.20 48.40ZM250.80 49.80Q247.65 49.80 245.05 48.33Q242.45 46.85 240.88 44.05Q239.30 41.25 239.30 37.30Q239.30 33.30 240.88 30.48Q242.45 27.65 245.05 26.18Q247.65 24.70 250.80 24.70Q253.95 24.70 256.55 26.18Q259.15 27.65 260.73 30.48Q262.30 33.30 262.30 37.30Q262.30 41.25 260.73 44.05Q259.15 46.85 256.55 48.33Q253.95 49.80 250.80 49.80M250.80 48.40Q253.65 48.40 255.90 47Q258.15 45.60 259.43 43.10Q260.70 40.60 260.70 37.30Q260.70 34 259.43 31.48Q258.15 28.95 255.90 27.53Q253.65 26.10 250.80 26.10Q247.95 26.10 245.73 27.53Q243.50 28.95 242.20 31.48Q240.90 34 240.90 37.30Q240.90 40.60 242.20 43.10Q243.50 45.60 245.73 47Q247.95 48.40 250.80 48.40ZM274.30 49.20L274.30 25.30L275.60 25.30L275.80 31.30L275.90 31.30Q277.85 28.45 280.78 26.58Q283.70 24.70 287.35 24.70Q288.50 24.70 289.78 24.90Q291.05 25.10 292.20 25.70L291.70 27.10Q290.35 26.60 289.48 26.40Q288.60 26.20 287.15 26.20Q284.05 26.20 281.25 27.95Q278.45 29.70 275.80 33.90L275.80 49.20L274.30 49.20ZM301.30 49.20L301.30 25.30L302.60 25.30L302.80 30.10L303 30.10Q305.15 27.75 307.43 26.23Q309.70 24.70 312.60 24.70Q317 24.70 319.15 27.05Q321.30 29.40 321.30 34.30L321.30 49.20L319.80 49.20L319.80 34.50Q319.80 30.25 318.10 28.18Q316.40 26.10 312.60 26.10Q309.90 26.10 307.75 27.53Q305.60 28.95 302.80 31.90L302.80 49.20L301.30 49.20Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -0,0 +1,7 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#ffffff">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <title>profile_round [#ffffff]</title> <desc>Created with Sketch.</desc> <defs> </defs> <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <g id="Dribbble-Light-Preview" transform="translate(-140.000000, -2159.000000)" fill="#ffffff"> <g id="icons" transform="translate(56.000000, 160.000000)"> <path d="M100.562548,2016.99998 L87.4381713,2016.99998 C86.7317804,2016.99998 86.2101535,2016.30298 86.4765813,2015.66198 C87.7127655,2012.69798 90.6169306,2010.99998 93.9998492,2010.99998 C97.3837885,2010.99998 100.287954,2012.69798 101.524138,2015.66198 C101.790566,2016.30298 101.268939,2016.99998 100.562548,2016.99998 M89.9166645,2004.99998 C89.9166645,2002.79398 91.7489936,2000.99998 93.9998492,2000.99998 C96.2517256,2000.99998 98.0830339,2002.79398 98.0830339,2004.99998 C98.0830339,2007.20598 96.2517256,2008.99998 93.9998492,2008.99998 C91.7489936,2008.99998 89.9166645,2007.20598 89.9166645,2004.99998 M103.955674,2016.63598 C103.213556,2013.27698 100.892265,2010.79798 97.837022,2009.67298 C99.4560048,2008.39598 100.400241,2006.33098 100.053171,2004.06998 C99.6509769,2001.44698 97.4235996,1999.34798 94.7348224,1999.04198 C91.0232075,1998.61898 87.8750721,2001.44898 87.8750721,2004.99998 C87.8750721,2006.88998 88.7692896,2008.57398 90.1636971,2009.67298 C87.1074334,2010.79798 84.7871636,2013.27698 84.044024,2016.63598 C83.7745338,2017.85698 84.7789973,2018.99998 86.0539717,2018.99998 L101.945727,2018.99998 C103.221722,2018.99998 104.226185,2017.85698 103.955674,2016.63598" id="profile_round-[#ffffff]"> </path> </g> </g> </g> </g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -3,5 +3,5 @@
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="SVGRepo_bgCarrier" stroke-width="0"/> <g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/> <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <path d="M20 7L4 7" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round"/> <path d="M20 12L4 12" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round"/> <path d="M20 17L4 17" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round"/> </g> <g id="SVGRepo_iconCarrier"> <g id="Interface / Search_Magnifying_Glass"> <path id="Vector" d="M15 15L21 21M10 17C6.13401 17 3 13.866 3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17Z" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 703 B

After

Width:  |  Height:  |  Size: 733 B

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)"/>
<path d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30" gradientUnits="userSpaceOnUse">
<stop stop-color="#37BBFE"/>
<stop offset="1" stop-color="#007DBB"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 920 B

View File

@ -1,7 +1,7 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools --> <!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="800px" height="800px" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="SVGRepo_bgCarrier" stroke-width="0"/> <g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/> <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <path d="M7 8L3 11.6923L7 16M17 8L21 11.6923L17 16M14 4L10 20" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g> <g id="SVGRepo_iconCarrier"> <path fill-rule="evenodd" clip-rule="evenodd" d="M16 2H0V14H16V2ZM6.5 5V11H7.5L11 8L7.5 5H6.5Z" fill="#ffffff"/> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 569 B

10
cdrm-frontend/src/App.css Normal file
View File

@ -0,0 +1,10 @@
@import "tailwindcss";
* {
box-sizing: border-box;
}
html, body, #root {
height: 100%;
width: 100%;
}

View File

@ -1,41 +1,13 @@
import { useState } from "react"; import React from 'react'
import Home from "./components/Pages/HomePage"; import './App.css'
import Cache from "./components/Pages/Cache"; import AppContainer from './components/AppContainer/AppContainer.jsx'
import API from "./components/Pages/API";
import TestPlayer from "./components/Pages/TestPlayer";
import NavBar from "./components/NavBar";
import NavBarMain from "./components/NavBarMain";
import SideMenu from "./components/SideMenu"; // Add this import
import { Routes, Route } from "react-router-dom";
function App() { function App() {
const [isMenuOpen, setIsMenuOpen] = useState(false); // Track if the menu is open
return ( return (
<div id="appcontainer" className="flex flex-row w-full h-full bg-black"> <>
{/* The SideMenu should be visible when isMenuOpen is true */} <AppContainer />
<SideMenu isMenuOpen={isMenuOpen} setIsMenuOpen={setIsMenuOpen} /> </>
)
<div id="navbarcontainer" className="hidden lg:flex lg:w-2xs bg-gray-950/55 border-r border-white/5 0">
<NavBar />
</div>
<div id="maincontainer" className="w-full lg:w-5/6 bg-gray-950/50 flex flex-col grow">
<div id="navbarmaincontainer" className="w-full lg:hidden h-16 bg-gray-950/10 border-b border-white/5 sticky top-0 z-10">
<NavBarMain setIsMenuOpen={setIsMenuOpen} />
</div>
<div id="maincontentcontainer" className="w-full grow overflow-y-auto">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/cache" element={<Cache />} />
<Route path="/api" element={<API />} />
<Route path="/testplayer" element={<TestPlayer />} />
</Routes>
</div>
</div>
</div>
);
} }
export default App; export default App

View File

@ -1,7 +0,0 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg height="800px" width="800px" version="1.1" id="_x32_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" xml:space="preserve" fill="#000000">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <style type="text/css"> .st0{fill:#ffffff;} </style> <g> <path class="st0" d="M0,17.067V153.6h512V17.067H0z M110.933,110.925h-51.2v-51.2h51.2V110.925z"/> <path class="st0" d="M0,324.267h512V187.733H0V324.267z M59.733,230.391h51.2v51.2h-51.2V230.391z"/> <path class="st0" d="M0,494.933h512V358.4H0V494.933z M59.733,401.058h51.2v51.2h-51.2V401.058z"/> </g> </g>
</svg>

Before

Width:  |  Height:  |  Size: 905 B

View File

@ -1,7 +0,0 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" fill="#ffffff">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <g id="Layer_2" data-name="Layer 2"> <g id="invisible_box" data-name="invisible box"> <rect width="48" height="48" fill="none"/> </g> <g id="Icons"> <g> <path d="M20.1,20.5a2.3,2.3,0,0,0-2.2,2.4,2.3,2.3,0,0,0,2.2,2.4,2.4,2.4,0,0,0,0-4.8Z"/> <path d="M28,20.5a2.4,2.4,0,1,0,2.2,2.4A2.3,2.3,0,0,0,28,20.5Z"/> <path d="M38.5,2H9.5A4.5,4.5,0,0,0,5,6.5V36.3a4.5,4.5,0,0,0,4.5,4.5H34.1l-1.2-4.1,2.8,2.7,2.6,2.4L43,46V6.5A4.5,4.5,0,0,0,38.5,2ZM30.2,30.7l-1.5-1.8a6.9,6.9,0,0,0,4-2.6,15.1,15.1,0,0,1-2.5,1.3,14.6,14.6,0,0,1-3.2,1,15,15,0,0,1-5.6,0,20.2,20.2,0,0,1-3.2-1l-1.6-.7h-.2c0-.1,0-.1-.1-.1l-.6-.4a6.9,6.9,0,0,0,3.8,2.6l-1.4,1.8a8,8,0,0,1-6.7-3.3,29,29,0,0,1,3.2-12.8,10.3,10.3,0,0,1,6.1-2.3l.2.2a15.4,15.4,0,0,0-5.7,2.9l1.3-.6a12.7,12.7,0,0,1,4.9-1.4h.4a20.6,20.6,0,0,1,4.3,0,16.3,16.3,0,0,1,6.6,2.1,13.5,13.5,0,0,0-5.4-2.8l.3-.3a10.3,10.3,0,0,1,6.1,2.3,29.7,29.7,0,0,1,3.1,12.8S35,30.6,30.2,30.7Z"/> </g> </g> </g> </g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,9 +0,0 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg fill="#ffffff" width="800px" height="800px" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier">
<path d="M4.209 4.603c-.247 0-.525.02-.84.088-.333.07-1.28.283-2.054 1.027C-.403 7.25.035 9.685.089 10.052c.065.446.263 1.687 1.21 2.768 1.749 2.141 5.513 2.092 5.513 2.092s.462 1.103 1.168 2.119c.955 1.263 1.936 2.248 2.89 2.367 2.406 0 7.212-.004 7.212-.004s.458.004 1.08-.394c.535-.324 1.013-.893 1.013-.893s.492-.527 1.18-1.73c.21-.37.385-.729.538-1.068 0 0 2.107-4.471 2.107-8.823-.042-1.318-.367-1.55-.443-1.627-.156-.156-.366-.153-.366-.153s-4.475.252-6.792.306c-.508.011-1.012.023-1.512.027v4.474l-.634-.301c0-1.39-.004-4.17-.004-4.17-1.107.016-3.405-.084-3.405-.084s-5.399-.27-5.987-.324c-.187-.011-.401-.032-.648-.032zm.354 1.832h.111s.271 2.269.6 3.597C5.549 11.147 6.22 13 6.22 13s-.996-.119-1.641-.348c-.99-.324-1.409-.714-1.409-.714s-.73-.511-1.096-1.52C1.444 8.73 2.021 7.7 2.021 7.7s.32-.859 1.47-1.145c.395-.106.863-.12 1.072-.12zm8.33 2.554c.26.003.509.127.509.127l.868.422-.529 1.075a.686.686 0 0 0-.614.359.685.685 0 0 0 .072.756l-.939 1.924a.69.69 0 0 0-.66.527.687.687 0 0 0 .347.763.686.686 0 0 0 .867-.206.688.688 0 0 0-.069-.882l.916-1.874a.667.667 0 0 0 .237-.02.657.657 0 0 0 .271-.137 8.826 8.826 0 0 1 1.016.512.761.761 0 0 1 .286.282c.073.21-.073.569-.073.569-.087.29-.702 1.55-.702 1.55a.692.692 0 0 0-.676.477.681.681 0 1 0 1.157-.252c.073-.141.141-.282.214-.431.19-.397.515-1.16.515-1.16.035-.066.218-.394.103-.814-.095-.435-.48-.638-.48-.638-.467-.301-1.116-.58-1.116-.58s0-.156-.042-.27a.688.688 0 0 0-.148-.241l.516-1.062 2.89 1.401s.48.218.583.619c.073.282-.019.534-.069.657-.24.587-2.1 4.317-2.1 4.317s-.232.554-.748.588a1.065 1.065 0 0 1-.393-.045l-.202-.08-4.31-2.1s-.417-.218-.49-.596c-.083-.31.104-.691.104-.691l2.073-4.272s.183-.37.466-.497a.855.855 0 0 1 .35-.077z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,7 +0,0 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg fill="#ffffff" width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <title>telegram</title> <path d="M22.122 10.040c0.006-0 0.014-0 0.022-0 0.209 0 0.403 0.065 0.562 0.177l-0.003-0.002c0.116 0.101 0.194 0.243 0.213 0.403l0 0.003c0.020 0.122 0.031 0.262 0.031 0.405 0 0.065-0.002 0.129-0.007 0.193l0-0.009c-0.225 2.369-1.201 8.114-1.697 10.766-0.21 1.123-0.623 1.499-1.023 1.535-0.869 0.081-1.529-0.574-2.371-1.126-1.318-0.865-2.063-1.403-3.342-2.246-1.479-0.973-0.52-1.51 0.322-2.384 0.221-0.23 4.052-3.715 4.127-4.031 0.004-0.019 0.006-0.040 0.006-0.062 0-0.078-0.029-0.149-0.076-0.203l0 0c-0.052-0.034-0.117-0.053-0.185-0.053-0.045 0-0.088 0.009-0.128 0.024l0.002-0.001q-0.198 0.045-6.316 4.174c-0.445 0.351-1.007 0.573-1.619 0.599l-0.006 0c-0.867-0.105-1.654-0.298-2.401-0.573l0.074 0.024c-0.938-0.306-1.683-0.467-1.619-0.985q0.051-0.404 1.114-0.827 6.548-2.853 8.733-3.761c1.607-0.853 3.47-1.555 5.429-2.010l0.157-0.031zM15.93 1.025c-8.302 0.020-15.025 6.755-15.025 15.060 0 8.317 6.742 15.060 15.060 15.060s15.060-6.742 15.060-15.060c0-8.305-6.723-15.040-15.023-15.060h-0.002q-0.035-0-0.070 0z"/> </g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,7 +0,0 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg fill="#ffffff" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 491.52 491.52" xml:space="preserve">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <g> <g> <path d="M0,0v327.68h491.52V0H0z M471.04,307.2H20.48V20.48h450.56V307.2z"/> </g> </g> <g> <g> <path d="M194.56,87.77v141.9l122.88-70.95L194.56,87.77z M215.04,123.25l61.44,35.47l-61.44,35.47V123.25z"/> </g> </g> <g> <g> <path d="M183.285,430.08c-4.758-23.34-25.441-40.96-50.165-40.96s-45.407,17.62-50.165,40.96H0v20.48h82.955 c4.758,23.34,25.441,40.96,50.165,40.96s45.407-17.62,50.165-40.96H491.52v-20.48H183.285z M133.12,471.04 c-16.94,0-30.72-13.78-30.72-30.72s13.78-30.72,30.72-30.72s30.72,13.78,30.72,30.72S150.06,471.04,133.12,471.04z"/> </g> </g> </g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1,29 @@
import React from 'react'
import Sidebar from '../Sidebar/Sidebar'
import Home from '../Pages/Home'
import API from '../Pages/API'
import Cache from '../Pages/Cache'
import TestPlayer from '../Pages/TestPlayer'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
function AppContainer() {
return (
<Router>
<div className='flex flex-row'>
<div className='w-1/8 h-dvh overflow-y-auto'>
<Sidebar />
</div>
<div className='w-7/8 h-dvh overflow-y-auto scroll-smooth' id='main_content'>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/api" element={<API />} />
<Route path="/testplayer" element={<TestPlayer />} />
<Route path="/cache" element={<Cache />} />
</Routes>
</div>
</div>
</Router>
)
}
export default AppContainer

View File

@ -1,116 +0,0 @@
import { NavLink } from 'react-router-dom';
import homeIcon from '../assets/icons/home.svg';
import cacheIcon from '../assets/icons/cache.svg';
import apiIcon from '../assets/icons/api.svg';
import testPlayerIcon from '../assets/icons/testplayer.svg';
import discordIcon from '../assets/icons/discord.svg';
import telegramIcon from '../assets/icons/telegram.svg';
import giteaIcon from '../assets/icons/gitea.svg';
function NavBar() {
return (
<div className="flex flex-col w-full h-full bg-white/1">
<div>
<p className='text-white text-2xl font-bold p-3 text-center mb-5'>
<a href='/'>
CDRM-Project
</a>
</p>
</div>
<div className='overflow-y-auto grow'>
<NavLink
to='/'
className={({ isActive }) =>
`flex flex-row p-3 border-l-3 ${isActive ? 'border-l-sky-500/50 bg-black/50' : 'hover:border-l-sky-500/50 hover:bg-white/5'}`
}
>
<button className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer'>
<img src={homeIcon} alt="Home" className='w-1/2 cursor-pointer' />
</button>
<p className='grow text-white md:text-2xl font-bold flex items-center justify-start'>
Home
</p>
</NavLink>
<NavLink
to='/cache'
className={({ isActive }) =>
`flex flex-row p-3 border-l-3 ${isActive ? 'border-l-emerald-500/50 bg-black/50' : 'hover:border-l-emerald-500/50 hover:bg-white/5'}`
}
>
<button className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer'>
<img src={cacheIcon} alt="Cache" className='w-1/2 cursor-pointer' />
</button>
<p className='grow text-white md:text-2xl font-bold flex items-center justify-start'>
Cache
</p>
</NavLink>
<NavLink
to='/api'
className={({ isActive }) =>
`flex flex-row p-3 border-l-3 ${isActive ? 'border-l-indigo-500/50 bg-black/50' : 'hover:border-l-indigo-500/50 hover:bg-white/5'}`
}
>
<button className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer'>
<img src={apiIcon} alt="API" className='w-1/2 cursor-pointer' />
</button>
<p className='grow text-white md:text-2xl font-bold flex items-center justify-start'>
API
</p>
</NavLink>
<NavLink
to='/testplayer'
className={({ isActive }) =>
`flex flex-row p-3 border-l-3 ${isActive ? 'border-l-rose-700/50 bg-black/50' : 'hover:border-l-rose-700/50 hover:bg-white/5'}`
}
>
<button className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer'>
<img src={testPlayerIcon} alt="Test Player" className='w-1/2 cursor-pointer' />
</button>
<p className='grow text-white md:text-2xl font-bold flex items-center justify-start'>
Test Player
</p>
</NavLink>
</div>
<div className='flex flex-row w-full h-16 self-end bg-black/25'>
<a
href='https://discord.cdrm-project.com'
target='_blank'
rel='noopener noreferrer'
className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer hover:bg-blue-950 group'
>
<img
src={discordIcon}
alt="Discord"
className='w-1/2 cursor-pointer group-hover:animate-bounce'
/>
</a>
<a
href='https://telegram.cdrm-project.com'
target='_blank'
rel='noopener noreferrer'
className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer hover:bg-blue-400 group'
>
<img
src={telegramIcon}
alt="Telegram"
className='w-1/2 cursor-pointer group-hover:animate-bounce'
/>
</a>
<a
href='https://cdm-project.com/tpd94/cdrm-project'
target='_blank'
rel='noopener noreferrer'
className='w-1/3 p-3 flex flex-col items-center justify-center cursor-pointer hover:bg-green-700 group'
>
<img
src={giteaIcon}
alt="Gitea"
className='w-1/2 cursor-pointer group-hover:animate-bounce'
/>
</a>
</div>
</div>
);
}
export default NavBar;

View File

@ -1,22 +0,0 @@
import { useState } from "react";
import hamburgerIcon from "../assets/icons/hamburger.svg";
function NavBarMain({ setIsMenuOpen }) {
const handleMenuToggle = () => {
setIsMenuOpen((prevState) => !prevState); // Toggle the menu state
};
return (
<div className="flex flex-row w-full h-full bg-white/1">
<button className="w-24 p-4" onClick={handleMenuToggle}>
<img src={hamburgerIcon} alt="Menu" className="w-full h-full cursor-pointer" />
</button>
<p className="grow text-white md:text-2xl font-bold text-center flex items-center justify-center p-4">
CDRM-Project
</p>
<div className="w-24 p-4"></div>
</div>
);
}
export default NavBarMain;

View File

@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Helmet } from 'react-helmet'; // Import Helmet import { data } from 'react-router-dom';
const { protocol, hostname, port } = window.location; const { protocol, hostname, port } = window.location;
import { Helmet } from 'react-helmet';
let fullHost = `${protocol}//${hostname}`; let fullHost = `${protocol}//${hostname}`;
if ( if (
@ -12,6 +12,7 @@ if (
} }
function API() { function API() {
// Widevine device info
const [deviceInfo, setDeviceInfo] = useState({ const [deviceInfo, setDeviceInfo] = useState({
device_type: '', device_type: '',
system_id: '', system_id: '',
@ -21,6 +22,7 @@ function API() {
device_name: '' device_name: ''
}); });
// PlayReady device info
const [prDeviceInfo, setPrDeviceInfo] = useState({ const [prDeviceInfo, setPrDeviceInfo] = useState({
security_level: '', security_level: '',
host: '', host: '',
@ -59,14 +61,20 @@ function API() {
}, []); }, []);
return ( return (
<div className="flex flex-col w-full overflow-y-auto p-4 text-white"> <>
<div className='min-w-full w-full min-h-full overflow-x-auto bg-zinc-900 shadow-lg shadow-black flex flex-col flex-wrap p-10 justify-around'>
<Helmet> <Helmet>
<title>API</title> <title>API</title>
</Helmet> </Helmet>
<details open className='w-full list-none'>
<summary className='text-2xl'>Sending a decryption request</summary> {/* Decryption Request Section */}
<div className='mt-5 p-5 rounded-lg border-2 border-indigo-500/50'> <details open className='p-5 mb-5 border shadow-lg shadow-black overflow-y-auto'>
<pre className='rounded-lg font-mono whitespace-pre-wrap text-white overflow-auto'> <summary className='bg-[rgba(0,0,0,0.2)] p-2 rounded text-white flex shadow-purple-900 shadow-sm'>
Sending a decryption request | {`(Python)`}
</summary>
<br />
<div className='h-9/10 bg-[rgba(0,0,0,0.2)] p-2 rounded text-white shadow-sm shadow-purple-900 w-full overflow-x-auto overflow-y-auto'>
<pre className='p-2'>
{`import requests {`import requests
print(requests.post( print(requests.post(
@ -87,47 +95,85 @@ print(requests.post(
</pre> </pre>
</div> </div>
</details> </details>
<details open className='w-full list-none mt-5'>
<summary className='text-2xl'>Sending a search request</summary> {/* Search Request Section */}
<div className='mt-5 border-2 border-indigo-500/50 p-5 rounded-lg'> <details open className=' p-5 mb-5 shadow-lg shadow-black border overflow-y-auto' >
<pre className="rounded-lg font-mono whitespace-pre text-white overflow-x-auto max-w-full p-5"> <summary className='bg-[rgba(0,0,0,0.2)] p-2 rounded text-white flex shadow-sm shadow-purple-900'>
{`import requests Sending a search request | {`(Python)`}
</summary>
<br />
<div className='h-9/10 bg-[rgba(0,0,0,0.2)] p-2 rounded text-white shadow-sm shadow-purple-900'>
<pre className='p-2'>{`import requests
print(requests.post( print(requests.post(
url='${fullHost}/api/cache/search', url='${fullHost}/api/cache/search',
json={ json={
'input': 'AAAAW3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADsIARIQ62dqu8s0Xpa7z2FmMPGj2hoNd2lkZXZpbmVfdGVzdCIQZmtqM2xqYVNkZmFsa3IzaioCSEQyAA==' 'input': 'AAAAW3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADsIARIQ62dqu8s0Xpa7z2FmMPGj2hoNd2lkZXZpbmVfdGVzdCIQZmtqM2xqYVNkZmFsa3IzaioCSEQyAA=='
} }
).json())`} ).json())`}</pre>
</pre>
</div> </div>
</details> </details>
<details open className='w-full list-none mt-5'>
<summary className='text-2xl'>PyWidevine RemoteCDM info</summary> {/* Remote CDM Configuration Section */}
<div className='mt-5 border-2 border-indigo-500 p-5 rounded-lg overflow-x-auto'> <details open className=' p-5 mb-5 shadow-lg shadow-black border overflow-y-auto'>
<p> <summary className='bg-[rgba(0,0,0,0.2)] p-2 rounded text-white flex shadow-sm shadow-purple-900'>
<strong>Device Type:</strong> '{deviceInfo.device_type}'<br /> Remote CDM configuration (Widevine) | {`(For PyWidevine / Devine / VineTrimmer / Extensions)`}
<strong>System ID:</strong> {deviceInfo.system_id}<br /> </summary>
<strong>Security Level:</strong> {deviceInfo.security_level}<br /> <br />
<strong>Host:</strong> {fullHost}/remotecdm/widevine<br /> <div className='h-9/10 bg-[rgba(0,0,0,0.2)] p-2 rounded text-white shadow-sm shadow-purple-900'>
<strong>Secret:</strong> '{deviceInfo.secret}'<br /> <p className='p-2'>
<strong>Device Name:</strong> {deviceInfo.device_name} device_type: <span id='wv_device_type'>"{deviceInfo.device_type}"</span>
</p> <br></br>
</div> system_id: <span id='wv_system_id'>{deviceInfo.system_id}</span>
</details> <br></br>
<details open className='w-full list-none mt-5'> security_level: <span id='wv_security_level'>{deviceInfo.security_level}</span>
<summary className='text-2xl'>PyPlayready RemoteCDM info</summary> <br></br>
<div className='mt-5 border-2 border-indigo-500 p-5 rounded-lg overflow-x-auto'> host: <span id='wv_host'>"{fullHost}/remotecdm/widevine"</span>
<p> <br></br>
<strong>Security Level:</strong> {prDeviceInfo.security_level}<br /> secret: <span id='wv_secret'>"{deviceInfo.secret}"</span>
<strong>Host:</strong> {fullHost}/remotecdm/playready<br /> <br></br>
<strong>Secret:</strong> '{prDeviceInfo.secret}'<br /> device_name: <span id='wv_device_name'>{deviceInfo.device_name}</span>
<strong>Device Name:</strong> {prDeviceInfo.device_name}
</p> </p>
</div> </div>
</details> </details>
{/* Remote CDM Configuration Section */}
<details open className=' p-5 mb-5 shadow-lg shadow-black border overflow-y-auto'>
<summary className='bg-[rgba(0,0,0,0.2)] p-2 rounded text-white flex shadow-sm shadow-purple-900'>
Remote CDM configuration (PlayReady) | {`(For PyPlayReady / Extensions / PlayReady Proxy)`}
</summary>
<br />
<div className='h-9/10 bg-[rgba(0,0,0,0.2)] p-2 rounded text-white shadow-sm shadow-purple-900'>
<p className='p-2'>
device_name: <span id='pr_device_name'>{prDeviceInfo.device_name}</span>
<br></br>
security_level: <span id='pr_security_level'>{prDeviceInfo.security_level}</span>
<br></br>
host: <span id='pr_host'>"{fullHost}/remotecdm/playready"</span>
<br></br>
secret: <span id='pr_secret'>"{prDeviceInfo.secret}"</span>
<br></br>
</p>
</div> </div>
</details>
{/* Webvault Configuration Section */}
<details open className='p-5 mb-5 shadow-lg shadow-black border overflow-y-auto'>
<summary className='bg-[rgba(0,0,0,0.2)] p-2 rounded text-white flex shadow-sm shadow-purple-900 transition-all transition-300 ease-in'>
Webvault configuration | {`(For Devine / VineTrimmer)`}
</summary>
<br />
<div className='h-9/10 bg-[rgba(0,0,0,0.2)] p-2 rounded text-white shadow-sm shadow-purple-900'>
<pre className='p-2'>{`key_vaults:
- type: API
name: "Online Vault"
uri: "${fullHost}/api/cache"
token: "${deviceInfo.secret}"`}</pre>
</div>
</details>
</div>
</>
); );
} }

View File

@ -1,46 +1,48 @@
import { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { Helmet } from 'react-helmet'; // Import Helmet import { Helmet } from 'react-helmet';
function Cache() { function Cache() {
const [searchQuery, setSearchQuery] = useState(''); const [searchQuery, setSearchQuery] = useState('');
const [cacheData, setCacheData] = useState([]); const [cacheData, setCacheData] = useState([]);
const [keyCount, setKeyCount] = useState(0); // New state to store the key count const [keyCount, setKeyCount] = useState(0);
const debounceTimeout = useRef(null); const debounceTimeout = useRef(null); // store the timeout ID
// Fetch the key count when the component mounts
useEffect(() => {
const fetchKeyCount = async () => {
try {
const response = await fetch('/api/cache/keycount');
const data = await response.json();
setKeyCount(data.count); // Update key count
} catch (error) {
console.error('Error fetching key count:', error);
}
};
fetchKeyCount();
}, []); // Run only once when the component mounts
const handleInputChange = (event) => { const handleInputChange = (event) => {
const query = event.target.value; const query = event.target.value;
setSearchQuery(query); // Update the search query setSearchQuery(query);
// Clear the previous timeout // Clear the previous timeout
if (debounceTimeout.current) { if (debounceTimeout.current) {
clearTimeout(debounceTimeout.current); clearTimeout(debounceTimeout.current);
} }
// Set a new timeout to send the API call after 1 second of no typing // Set a new timeout
debounceTimeout.current = setTimeout(() => { debounceTimeout.current = setTimeout(() => {
if (query.trim() !== '') { if (query.trim() !== '') {
sendApiCall(query); // Only call the API if the query is not empty sendApiCall(query);
} else { } else {
setCacheData([]); // Clear results if query is empty setCacheData([]); // optional: clear results on empty query
} }
}, 1000); // 1 second delay }, 1000); // 2 seconds
}; };
const fetchKeyCount = () => {
fetch('/api/cache/keycount')
.then((response) => response.json())
.then((data) => {
setKeyCount(data.count);
})
.catch((error) => {
console.error('Error fetching key count:', error);
});
};
useEffect(() => {
const fetchInterval = setInterval(fetchKeyCount, 10000);
fetchKeyCount();
return () => clearInterval(fetchInterval);
}, []);
const sendApiCall = (text) => { const sendApiCall = (text) => {
fetch('/api/cache/search', { fetch('/api/cache/search', {
method: 'POST', method: 'POST',
@ -48,51 +50,62 @@ function Cache() {
body: JSON.stringify({ input: text }), body: JSON.stringify({ input: text }),
}) })
.then((response) => response.json()) .then((response) => response.json())
.then((data) => setCacheData(data)) // Update cache data with the results .then((data) => setCacheData(data))
.catch((error) => console.error('Error:', error)); .catch((error) => console.error('Error:', error));
}; };
return ( return (
<div className="flex flex-col w-full h-full overflow-y-auto p-4"> <>
<div className='w-full h-full bg-zinc-900 flex flex-col p-0'>
<Helmet> <Helmet>
<title>Cache</title> <title>Cache</title>
</Helmet> </Helmet>
<div className="flex flex-col lg:flex-row w-full lg:h-12 items-center"> <div className='flex flex-row w-full'>
<form className='flex flex-row w-8/10 p-10 h-full rounded-xl self-start'>
<input <input
type="text" type='text'
id='search'
name='search'
value={searchQuery} value={searchQuery}
onChange={handleInputChange} onChange={handleInputChange}
placeholder={`Search ${keyCount} keys...`} // Dynamic placeholder placeholder='Search by PSSH/KID'
className="lg:grow w-full border-2 border-emerald-500/25 rounded-xl h-10 self-center m-2 text-white p-1 focus:outline-none focus:ring-2 focus:ring-emerald-500/50 transition-all duration-200 ease-in-out" className='w-full text-white bg-[rgba(0,0,0,0.2)] focus:outline-none rounded focus:shadow-sm focus:shadow-green-700/50 transition-shadow duration-300 ease-in-out p-2'
/> />
<a </form>
href="/api/cache/download" <p className='text-white w-2/10 p-10 rounded-xl self-start flex flex-col h-full'>
className="bg-emerald-500/50 rounded-xl text-white text-bold text-xl p-1 lg:w-1/5 lg:h-10 truncate w-full text-center flex items-center justify-center m-2" <span className='text-white w-1/1 text-center'>
> Cached Keys: {keyCount} {/* Display the count of cached keys */}
Download Cache </span>
<a href='/api/cache/download'>
<button className=' self-start w-1/1 bg-green-700 rounded-md mt-1 active:transform active:scale-95 cursor-pointer hover:bg-green-600/50 pt-1 pb-1'>
Download
</button>
</a> </a>
</p>
</div> </div>
<div className="w-full grow p-4 border-2 border-emerald-500/50 rounded-2xl mt-5 overflow-y-auto"> <div className='h-full w-full p-10 overflow-y-auto'>
<table className="min-w-full text-white"> <div className="overflow-x-auto border p-10 rounded-2xl bg-[rgba(0,0,0,0.2)] shadow-md shadow-green-700 min-h-full overflow-y-auto">
<table className='min-w-full text-white'>
<thead> <thead>
<tr> <tr>
<th className="p-2 border border-black">PSSH</th> <th className='p-2 border border-black'>PSSH</th>
<th className="p-2 border border-black">KID</th> <th className='p-2 border border-black'>KID</th>
<th className="p-2 border border-black">Key</th> <th className='p-2 border border-black'>Key</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{cacheData.length > 0 ? ( {cacheData.length > 0 ? (
cacheData.map((item, index) => ( cacheData.map((item, index) => (
<tr key={index}> <tr key={index}>
<td className="p-2 border border-black">{item.PSSH}</td> <td className='p-2 border border-black'>{item.PSSH}</td>
<td className="p-2 border border-black">{item.KID}</td> <td className='p-2 border border-black'>{item.KID}</td>
<td className="p-2 border border-black">{item.Key}</td> <td className='p-2 border border-black'>{item.Key}</td>
</tr> </tr>
)) ))
) : ( ) : (
<tr> <tr>
<td colSpan="3" className="p-2 border border-black text-center"> <td colSpan="3" className='p-2 border border-black text-center'>
No data found No data found
</td> </td>
</tr> </tr>
@ -101,6 +114,8 @@ function Cache() {
</table> </table>
</div> </div>
</div> </div>
</div>
</>
); );
} }

View File

@ -0,0 +1,132 @@
import React, { useState, useEffect } from 'react';
import { Helmet } from 'react-helmet';
import { readTextFromClipboard } from '../functions/ParseChallenge';
function Home() {
const [message, setMessage] = useState('');
const [isVisible, setIsVisible] = useState(false);
const scrollToTop = () => {
let divToScroll = document.getElementById('main_content');
divToScroll.scrollTop = 0; // Scroll to the top of the div
};
const copyToClipboard = (event) => {
let message = document.getElementById('messageresults').innerHTML;
// Replace <br> tags with newline characters
message = message.replace(/<br\s*\/?>/gi, '\n');
// Use textContent to get the actual text without HTML tags
navigator.clipboard.writeText(message); // Copy the message to the clipboard
console.log(message);
};
// Handlers for form submission and reset
const handleSubmit = (event) => {
event.preventDefault();
};
const handleSubmitButton = (event) => {
let pssh = document.getElementById('pssh').value;
let licurl = document.getElementById('licurl').value;
let proxy = document.getElementById('proxy').value;
let headers = document.getElementById('headers').value;
let cookies = document.getElementById('cookies').value;
let data = document.getElementById('data').value;
fetch('/api/decrypt', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
pssh: pssh,
licurl: licurl,
proxy: proxy,
headers: headers,
cookies: cookies,
data: data
}),
})
.then(response => response.json())
.then(data => {
const resultMessage = data['message'].replace(/\n/g, '<br />'); // Format the message as HTML
setMessage(resultMessage);
setIsVisible(true);
})
.catch((error) => {
console.error('Error during decryption request:', error);
setMessage('Error: Unable to process request.');
setIsVisible(true);
});
};
const handleResetButton = (event) => {
let pssh = document.getElementById('pssh');
let licurl = document.getElementById('licurl');
let proxy = document.getElementById('proxy');
let headers = document.getElementById('headers');
let cookies = document.getElementById('cookies');
let data = document.getElementById('data');
pssh.value = '';
licurl.value = '';
headers.value = '';
cookies.value = '';
data.value = '';
setMessage('');
setIsVisible(false);
};
useEffect(() => {
if (isVisible) {
let divToScroll = document.getElementById('main_content');
divToScroll.scrollTop = divToScroll.scrollHeight;
}
}, [message, isVisible]);
return (
<>
<div className='w-full min-h-full bg-zinc-900 flex flex-col items-center justify-center'>
<Helmet>
<title>CDRM-Project</title>
</Helmet>
<form className='flex flex-col w-8/10 min-h-8/10 bg-[rgba(0,0,0,0.2)] p-10 border-black border-1 rounded-xl shadow-lg shadow-cyan-500/50 overflow-y-auto' onSubmit={handleSubmit}>
<label htmlFor='pssh' className='text-white mb-1'>PSSH:</label>
<input type='text' id='pssh' name='pssh' className='text-white bg-[rgba(0,0,0,0.2)] focus:outline-none rounded focus:shadow-sm focus:shadow-cyan-500/50 transition-shadow duration-300 ease-in-out p-2' />
<label htmlFor='licurl' className='text-white mb-1 mt-1'>License URL:</label>
<input type='text' id='licurl' name='licurl' className='text-white bg-[rgba(0,0,0,0.2)] focus:outline-none rounded focus:shadow-sm focus:shadow-cyan-500/50 transition-shadow duration-300 ease-in-out p-2' />
<label htmlFor='proxy' className='text-white mb-1 mt-1'>Proxy:</label>
<input type='text' id='proxy' name='proxy' className='text-white bg-[rgba(0,0,0,0.2)] focus:outline-none rounded focus:shadow-sm focus:shadow-cyan-500/50 transition-shadow duration-300 ease-in-out p-2' />
<label htmlFor='headers' className='text-white mb-1 mt-1'>Headers:</label>
<textarea id='headers' name='headers' className='text-white bg-[rgba(0,0,0,0.2)] h-24 focus:h-92 focus:outline-none rounded focus:shadow-sm focus:shadow-cyan-500/50 transition-all duration-300 ease-in-out p-2 resize-none' />
<label htmlFor='cookies' className='text-white mb-1 mt-1'>Cookies:</label>
<textarea id='cookies' name='cookies' className='text-white bg-[rgba(0,0,0,0.2)] h-24 focus:h-92 focus:outline-none rounded focus:shadow-sm focus:shadow-cyan-500/50 transition-all duration-300 ease-in-out p-2 resize-none' />
<label htmlFor='data' className='text-white mb-1 mt-1'>Data:</label>
<textarea id='data' name='data' className='text-white bg-[rgba(0,0,0,0.2)] h-24 focus:h-92 focus:outline-none rounded focus:shadow-sm focus:shadow-cyan-500/50 transition-all duration-300 ease-in-out p-2 resize-none' />
<div className='flex flex-row w-full justify-evenly mt-5 mb-5'>
<button type='button' onClick={handleSubmitButton} className='bg-cyan-500 text-white rounded p-2 hover:bg-cyan-600 transition-colors duration-300 ease-in-out w-1/6 cursor-pointer active:transform active:scale-95 overflow-x-hidden overflow-y-hidden'>Submit</button>
<button type='button' onClick={readTextFromClipboard} className='bg-yellow-500 text-white rounded p-2 hover:bg-yellow-600 transition-colors duration-300 ease-in-out w-1/6 cursor-pointer active:transform active:scale-95 overflow-x-hidden overflow-y-hidden'>Paste from fetch</button>
<button type='button' onClick={handleResetButton} className='bg-red-500 text-white rounded p-2 hover:bg-red-600 transition-colors duration-300 ease-in-out w-1/6 cursor-pointer active:transform active:scale-95 overflow-x-hidden overflow-y-hidden'>Reset</button>
</div>
</form>
</div>
{isVisible && (
<div className='w-full min-h-full h-full bg-zinc-900 flex flex-col items-center justify-center'>
<div className='w-8/10 min-h-8/10 flex flex-col bg-[rgba(0,0,0,0.2)] items-center p-10 border-black border-1 rounded-xl shadow-lg shadow-cyan-500/50 overflow-y-auto'>
<p className='w-full text-center text-white text-2xl overflow-hidden mb-10 pb-2 border-b'>Results:</p>
<p id='messageresults' className='w-8/10 h-6/10 text-center text-white text-2xl overflow-hidden bg-[rgba(0,0,0,0.2)] rounded-xl p-5' dangerouslySetInnerHTML={{ __html: message }}></p>
<div className='w-full h-1/10 flex justify-evenly mt-5 , mb-5'>
<button type='button' onClick={copyToClipboard} className='bg-green-500 text-white rounded p-2 hover:bg-green-600 transition-colors duration-300 ease-in-out min-w-1/6 w-1/6 min-h-4/6 h-4/6 cursor-pointer active:transform active:scale-95 overflow-x-hidden overflow-y-hidden'>Copy</button>
<button type='button' onClick={scrollToTop} className='bg-yellow-600 text-white rounded p-2 hover:bg-yellow-700 transition-colors duration-300 ease-in-out min-w-1/6 w-1/6 min-h-4/6 h-4/6 cursor-pointer active:transform active:scale-95 overflow-x-hidden overflow-y-hidden'>Back to top</button>
</div>
</div>
</div>
)}
</>
);
}
export default Home;

View File

@ -1,192 +0,0 @@
import React, { useState, useEffect, useRef } from 'react';
import { readTextFromClipboard } from '../Functions/ParseChallenge'
import { Helmet } from 'react-helmet'; // Import Helmet
function HomePage() {
const [pssh, setPssh] = useState('');
const [licurl, setLicurl] = useState('');
const [proxy, setProxy] = useState('');
const [headers, setHeaders] = useState('');
const [cookies, setCookies] = useState('');
const [data, setData] = useState('');
const [message, setMessage] = useState('');
const [isVisible, setIsVisible] = useState(false);
const bottomRef = useRef(null);
const messageRef = useRef(null); // Reference to result container
const handleReset = () => {
if (isVisible) {
setIsVisible(false);
}
setPssh('');
setLicurl('');
setProxy('');
setHeaders('');
setCookies('');
setData('');
};
const handleSubmitButton = (event) => {
event.preventDefault();
fetch('/api/decrypt', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
pssh: pssh,
licurl: licurl,
proxy: proxy,
headers: headers,
cookies: cookies,
data: data
}),
})
.then(response => response.json())
.then(data => {
const resultMessage = data['message'].replace(/\n/g, '<br />');
setMessage(resultMessage);
setIsVisible(true);
})
.catch((error) => {
console.error('Error during decryption request:', error);
setMessage('Error: Unable to process request.');
setIsVisible(true);
});
};
const handleCopy = (event) => {
event.preventDefault();
if (messageRef.current) {
const textToCopy = messageRef.current.innerText; // Grab the plain text (with visual line breaks)
navigator.clipboard.writeText(textToCopy).catch(err => {
alert('Failed to copy!');
console.error(err);
});
}
};
const handleFetchPaste = () => {
event.preventDefault();
readTextFromClipboard().then(() => {
setPssh(document.getElementById("pssh").value);
setLicurl(document.getElementById("licurl").value);
setHeaders(document.getElementById("headers").value);
setData(document.getElementById("data").value);
}).catch(err => {
alert('Failed to paste from fetch!');
});
}
useEffect(() => {
if (isVisible && bottomRef.current) {
bottomRef.current.scrollIntoView({ behavior: 'smooth' });
}
}, [message, isVisible]);
return (
<>
<div className="flex flex-col w-full overflow-y-auto p-4 min-h-full">
<Helmet>
<title>CDRM-Project</title>
</Helmet>
<form className="flex flex-col w-full h-full bg-black/5 p-4 overflow-y-auto">
<label htmlFor="pssh" className="text-white w-8/10 self-center">PSSH: </label>
<input
type="text"
id="pssh"
className="w-8/10 border-2 border-sky-500/25 rounded-xl h-10 self-center m-2 text-white p-1"
value={pssh}
onChange={(e) => setPssh(e.target.value)}
/>
<label htmlFor="licurl" className="text-white w-8/10 self-center">License URL: </label>
<input
type="text"
id="licurl"
className="w-8/10 border-2 border-sky-500/25 rounded-xl h-10 self-center m-2 text-white p-1"
value={licurl}
onChange={(e) => setLicurl(e.target.value)}
/>
<label htmlFor="proxy" className="text-white w-8/10 self-center">Proxy: </label>
<input
type="text"
id="proxy"
className="w-8/10 border-2 border-sky-500/25 rounded-xl h-10 self-center m-2 text-white p-1"
value={proxy}
onChange={(e) => setProxy(e.target.value)}
/>
<label htmlFor="headers" className="text-white w-8/10 self-center">Headers: </label>
<textarea
id="headers"
className="w-8/10 border-2 border-sky-500/25 rounded-xl self-center m-2 text-white p-1 h-48"
value={headers}
onChange={(e) => setHeaders(e.target.value)}
/>
<label htmlFor="cookies" className="text-white w-8/10 self-center">Cookies: </label>
<textarea
id="cookies"
className="w-8/10 border-2 border-sky-500/25 rounded-xl self-center m-2 text-white p-1 h-48"
value={cookies}
onChange={(e) => setCookies(e.target.value)}
/>
<label htmlFor="data" className="text-white w-8/10 self-center">Data: </label>
<textarea
id="data"
className="w-8/10 border-2 border-sky-500/25 rounded-xl self-center m-2 text-white p-1 h-48"
value={data}
onChange={(e) => setData(e.target.value)}
/>
<div className="flex flex-col lg:flex-row w-full self-center mt-5 items-center lg:justify-around lg:items-stretch">
<button
type="button"
className="bg-sky-500/50 rounded-xl text-white text-bold text-xl p-1 lg:w-1/5 lg:h-12 truncate w-1/2"
onClick={handleSubmitButton}
>
Submit
</button>
<button onClick={handleFetchPaste} className="bg-yellow-500/50 rounded-xl text-white text-bold text-xl p-1 lg:w-1/5 lg:h-12 truncate mt-5 w-1/2 lg:mt-0">
Paste from fetch
</button>
<button
type="button"
className="bg-red-500/50 rounded-xl text-white text-bold text-xl p-1 lg:w-1/5 lg:h-12 truncate mt-5 w-1/2 lg:mt-0"
onClick={handleReset}
>
Reset
</button>
</div>
</form>
</div>
{isVisible && (
<div id="main_content" className="flex-col w-full h-full p-10 items-center justify-center self-center">
<div className="flex flex-col w-full h-full overflow-y-auto items-center">
<div className='w-8/10 grow p-4 text-white text-bold text-center text-xl md:text-3xl border-2 border-sky-500/25 rounded-xl bg-black/5'>
<p className="w-full border-b-2 border-white/75 pb-2">Results:</p>
<p
className="w-full grow pt-10 break-words overflow-y-auto"
ref={messageRef}
dangerouslySetInnerHTML={{ __html: message }}
/>
<div ref={bottomRef} />
</div>
</div>
<div className="flex flex-col lg:flex-row w-full self-center mt-5 items-center lg:justify-around lg:items-stretch">
<button
className="bg-green-500/50 rounded-xl text-white text-bold text-xl p-1 lg:w-1/5 lg:h-12 truncate w-1/2"
onClick={handleCopy}
>
Copy Results
</button>
</div>
</div>
)}
</>
);
}
export default HomePage;

View File

@ -1,56 +1,18 @@
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useRef } from "react";
import shaka from 'shaka-player'; import shaka from "shaka-player"; // Import the Shaka Player library
import { Helmet } from 'react-helmet'; // Import Helmet import { Helmet } from 'react-helmet';
function TestPlayer() { function TestPlayer() {
const [mpdUrl, setMpdUrl] = useState(''); // State to hold the MPD URL const [mpdUrl, setMpdUrl] = useState("");
const [kids, setKids] = useState(''); // State to hold KIDs (separated by line breaks) const [kid, setKid] = useState("");
const [keys, setKeys] = useState(''); // State to hold Keys (separated by line breaks) const [key, setKey] = useState("");
const [headers, setHeaders] = useState(''); // State to hold request headers const videoRef = useRef(null); // Ref to the video element
const videoRef = useRef(null); // Ref for the video element
const playerRef = useRef(null); // Ref for Shaka Player instance
// Function to update the MPD URL state
const handleInputChange = (event) => {
setMpdUrl(event.target.value);
};
// Function to update KIDs and Keys
const handleKidsChange = (event) => {
setKids(event.target.value);
};
const handleKeysChange = (event) => {
setKeys(event.target.value);
};
const handleHeadersChange = (event) => {
setHeaders(event.target.value);
};
// Function to initialize Shaka Player
const initializePlayer = () => {
if (videoRef.current) {
// Initialize Shaka Player only if it's not already initialized
if (!playerRef.current) {
const player = new shaka.Player(videoRef.current);
playerRef.current = player;
// Add error listener
player.addEventListener('error', (event) => {
console.error('Error code', event.detail.code, 'object', event.detail);
});
}
}
};
// Function to handle submit and configure player with DRM keys and headers
const handleSubmit = () => { const handleSubmit = () => {
if (mpdUrl && kids && keys) { if (mpdUrl && kid && key) {
// Split the KIDs and Keys by new lines // Split the KIDs and Keys by new lines
const kidsArray = kids.split("\n").map((k) => k.trim()); const kidsArray = kid.split("\n").map((k) => k.trim());
const keysArray = keys.split("\n").map((k) => k.trim()); const keysArray = key.split("\n").map((k) => k.trim());
if (kidsArray.length !== keysArray.length) { if (kidsArray.length !== keysArray.length) {
console.error("The number of KIDs and Keys must be the same."); console.error("The number of KIDs and Keys must be the same.");
@ -72,84 +34,74 @@ function TestPlayer() {
config.drm.clearKeys[kid] = keysArray[index]; config.drm.clearKeys[kid] = keysArray[index];
}); });
console.log("Configuring player with the following DRM config and headers:", config); console.log("Configuring player with the following DRM config:", config);
// Configure the player with ClearKey DRM and custom headers
player.configure(config); player.configure(config);
// Load the video stream with MPD URL const manifestUri = mpdUrl; // Get the MPD URL from state
player.load(mpdUrl).then(() => {
console.log('Video loaded');
}).catch((error) => {
console.error('Error loading the video', error);
});
} else {
console.error('MPD URL, KIDs, and Keys are required.');
}
};
// Load the video stream whenever the MPD URL changes player.load(manifestUri)
useEffect(() => { .then(() => {
initializePlayer(); // Initialize the player if it's not initialized already console.log("Shaka Player loaded successfully.");
}, []); // This effect runs only once on mount // Start playback once the stream is loaded successfully
videoRef.current.play();
// Helper function to parse headers from the textarea input })
const parseHeaders = (headersText) => { .catch((error) => {
const headersArr = headersText.split('\n'); console.error("Error loading the stream:", error);
const headersObj = {};
headersArr.forEach((line) => {
const [key, value] = line.split(':');
if (key && value) {
headersObj[key.trim()] = value.trim();
}
}); });
return headersObj; }
}; };
return ( return (
<div className="flex flex-col items-center w-full p-4"> <div className="min-w-full w-full min-h-full h-full bg-zinc-900 shadow-lg shadow-black flex flex-row overflow-y-auto pt-5 pl-5 pr-5 items-center justify-around">
<Helmet> <Helmet>
<title>Test Player</title> <title>Test Player</title>
</Helmet> </Helmet>
<div className="w-full flex flex-col"> <div className="min-8/10 w-8/10 min-h-8/10 h-8/10 flex flex-row overflow-y-auto items-center justify-around border shadow-lg shadow-red-700 rounded-2xl">
<div className="w-7/10 h-7/10 border border-black rounded-2xl p-5 bg-[rgba(0,0,0,0.2)] shadow-lg shadow-black">
<video <video
ref={videoRef} ref={videoRef}
width="100%" className="w-full h-full"
height="auto"
controls controls
className="h-96" // Removed autoPlay so it doesn't start until submit is pressed
/> />
</div>
<div className="w-2/10 h-7/10 flex flex-col border border-black rounded-2xl p-5 bg-[rgba(0,0,0,0.2)] shadow-lg shadow-black focus-within:w-3/10 transition-all duration-300 ease-in-out">
<form className="h-full flex flex-col gap-2">
<input <input
type="text" type="text"
value={mpdUrl}
onChange={handleInputChange}
placeholder="MPD URL" placeholder="MPD URL"
className="border-2 border-rose-700/50 mt-2 text-white p-1 rounded transition-all ease-in-out focus:outline-none focus:ring-2 focus:ring-rose-700/50 duration-200" id="player_mpd"
name="player_mpd"
value={mpdUrl}
onChange={(e) => setMpdUrl(e.target.value)}
className="text-white bg-[rgba(0,0,0,0.2)] focus:outline-none rounded focus:shadow-sm focus:shadow-red-700/50 transition-all duration-300 ease-in-out p-2"
/> />
<textarea <textarea
placeholder="KIDs (one per line)" placeholder="KIDs, separated by new lines"
value={kids} id="player_kid"
onChange={handleKidsChange} name="player_kid"
className="border-2 border-rose-700/50 mt-2 text-white p-1 overflow-y-auto rounded transition-all ease-in-out focus:outline-none focus:ring-2 focus:ring-rose-700/50 duration-200" value={kid}
onChange={(e) => setKid(e.target.value)}
className="text-white bg-[rgba(0,0,0,0.2)] focus:outline-none rounded h-1/4 focus:h-1/3 overflow-y-auto focus:shadow-sm focus:shadow-red-700/50 transition-all duration-300 ease-in-out p-2 resize-none"
/> />
<textarea <textarea
placeholder="Keys (one per line)" placeholder="Keys, separated by new lines"
value={keys} id="player_key"
onChange={handleKeysChange} name="player_key"
className="border-2 border-rose-700/50 mt-2 text-white p-1 overflow-y-auto rounded transition-all ease-in-out focus:outline-none focus:ring-2 focus:ring-rose-700/50 duration-200" value={key}
/> onChange={(e) => setKey(e.target.value)}
<textarea className="text-white bg-[rgba(0,0,0,0.2)] focus:outline-none rounded h-1/4 focus:h-1/3 focus:shadow-sm focus:shadow-red-700/50 transition-all duration-300 ease-in-out p-2 resize-none"
placeholder="Headers (one per line)"
value={headers}
onChange={handleHeadersChange}
className="border-2 border-rose-700/50 mt-2 text-white p-1 overflow-y-auto rounded transition-all ease-in-out focus:outline-none focus:ring-2 focus:ring-rose-700/50 duration-200"
/> />
<button <button
type="button"
onClick={handleSubmit} onClick={handleSubmit}
className="mt-4 p-2 bg-blue-500 text-white rounded" className="mt-auto bg-white text-black rounded p-2 hover:bg-slate-200 transition-colors duration-300 ease-in-out w-full cursor-pointer active:transform active:scale-95 overflow-x-hidden overflow-y-hidden"
> >
Submit Submit
</button> </button>
</form>
</div>
</div> </div>
</div> </div>
); );

View File

@ -1,142 +0,0 @@
import { NavLink } from 'react-router-dom';
import closeIcon from '../assets/icons/close.svg';
import homeIcon from '../assets/icons/home.svg';
import cacheIcon from '../assets/icons/cache.svg';
import apiIcon from '../assets/icons/api.svg';
import testPlayerIcon from '../assets/icons/testplayer.svg';
import discordIcon from '../assets/icons/discord.svg';
import telegramIcon from '../assets/icons/telegram.svg';
import giteaIcon from '../assets/icons/gitea.svg';
function SideMenu({ isMenuOpen, setIsMenuOpen }) {
return (
<>
<div
className={`flex flex-col fixed top-0 left-0 w-full h-full bg-black transition-transform transform ${
isMenuOpen ? 'translate-x-0' : '-translate-x-full'
} z-50`}
style={{ transitionDuration: '0.3s' }}
>
<div className="flex flex-col bg-gray-950/55 h-full">
<div className="h-16 w-full border-b-2 border-white/5 flex flex-row">
<div className="w-1/4 h-full"></div>
<p className="grow text-white md:text-2xl font-bold text-center flex items-center justify-center p-4">
CDRM-Project
</p>
<div className="w-1/4 h-full">
<button
className="w-full h-full flex items-center justify-center"
onClick={() => setIsMenuOpen(false)}
>
<img src={closeIcon} alt="Close" className="w-1/2 h-1/2 cursor-pointer" />
</button>
</div>
</div>
<div className="overflow-y-auto flex flex-col p-5 w-full space-y-2 flex-grow">
<NavLink
to="/"
className={({ isActive }) =>
`flex flex-row items-center gap-3 p-3 border-l-4 ${
isActive
? 'border-l-4 border-l-sky-500/50 bg-black/50 text-white'
: 'border-transparent hover:border-l-sky-500/50 hover:bg-white/5 text-white/80'
}`
}
onClick={() => setIsMenuOpen(false)}
>
<img src={homeIcon} alt="Home" className="w-5 h-5" />
<span className="text-lg">Home</span>
</NavLink>
<NavLink
to="/cache"
className={({ isActive }) =>
`flex flex-row items-center gap-3 p-3 border-l-4 ${
isActive
? 'border-l-emerald-500/50 bg-black/50 text-white'
: 'border-transparent hover:border-l-emerald-500/50 hover:bg-white/5 text-white/80'
}`
}
onClick={() => setIsMenuOpen(false)}
>
<img src={cacheIcon} alt="Cache" className="w-5 h-5" />
<span className="text-lg">Cache</span>
</NavLink>
<NavLink
to="/api"
className={({ isActive }) =>
`flex flex-row items-center gap-3 p-3 border-l-4 ${
isActive
? 'border-l-indigo-500/50 bg-black/50 text-white'
: 'border-transparent hover:border-l-indigo-500/50 hover:bg-white/5 text-white/80'
}`
}
onClick={() => setIsMenuOpen(false)}
>
<img src={apiIcon} alt="API" className="w-5 h-5" />
<span className="text-lg">API</span>
</NavLink>
<NavLink
to="/testplayer"
className={({ isActive }) =>
`flex flex-row items-center gap-3 p-3 border-l-4 ${
isActive
? 'border-l-rose-700/50 bg-black/50 text-white'
: 'border-transparent hover:border-l-rose-700/50 hover:bg-white/5 text-white/80'
}`
}
onClick={() => setIsMenuOpen(false)}
>
<img src={testPlayerIcon} alt="Test Player" className="w-5 h-5" />
<span className="text-lg">Test Player</span>
</NavLink>
</div>
<div className="h-16 self-end w-full flex flex-row bg-black/5">
<a
href="https://discord.cdrm-project.com/"
target="_blank"
rel="noopener noreferrer"
className="w-1/3 h-full flex items-center justify-center hover:bg-blue-950 group"
>
<img
src={discordIcon}
alt="Discord"
className="w-full h-2/3 p-1 cursor-pointer group-hover:animate-bounce"
/>
</a>
<a
href="https://telegram.cdrm-project.com"
target="_blank"
rel="noopener noreferrer"
className="w-1/3 h-full flex items-center justify-center hover:bg-blue-400 group"
>
<img
src={telegramIcon}
alt="Telegram"
className="w-full h-2/3 p-1 cursor-pointer group-hover:animate-bounce"
/>
</a>
<a
href="https://cdm-project.com/tpd94/cdrm-project"
target="_blank"
rel="noopener noreferrer"
className="w-1/3 h-full flex items-center justify-center hover:bg-green-700 group"
>
<img
src={giteaIcon}
alt="Gitea"
className="w-full h-2/3 p-1 cursor-pointer group-hover:animate-bounce"
/>
</a>
</div>
</div>
</div>
</>
);
}
export default SideMenu;

View File

@ -0,0 +1,19 @@
import React from 'react'
function Footer() {
return (
<div className='flex flex-row w-full h-full items-center justify-around overflow-hidden'>
<a href='https://discord.cdrm-project.com' className='w-1/6 h-1/6 hover:animate-bounce'>
<img src='/discord.svg' alt='Discord Logo'/>
</a>
<a href='https://telegram.cdrm-project.com' className='w-1/6 h-1/6 hover:animate-bounce'>
<img src='/telegram.svg' alt='Telegram Logo' />
</a>
<a href='https://github.com/tpd94' className='w-1/6 h-1/6 hover:animate-bounce'>
<img src='/github.svg' alt='Github Logo' />
</a>
</div>
)
}
export default Footer

View File

@ -0,0 +1,13 @@
import React from 'react'
function NavHead() {
return (
<div className='flex flex-row w-full h-full shadow-lg shadow-black items-center justify-center overflow-hidden'>
<a href='/' className='w-2/3 h-2/3 flex'>
<img src='/logo.svg' alt='CDRM Logo'/>
</a>
</div>
)
}
export default NavHead

View File

@ -0,0 +1,12 @@
import React from 'react'
import NavItems from './NavItems'
function MainNav() {
return (
<div className='flex flex-col w-full h-full overflow-y-auto shadow-lg shadow-black'>
< NavItems />
</div>
)
}
export default MainNav

View File

@ -0,0 +1,37 @@
import React from 'react'
import { Link, useLocation } from 'react-router-dom';
function NavItems() {
const location = useLocation();
return (
<>
<div className={`w-full h-1/10 flex flex-col items-center ${location.pathname === '/' ? 'bg-black/50' : 'hover:bg-black/35'} transition-all duration-300 ease-in-out overflow-hidden mt-5`}>
<Link to='/' className='flex w-8/10 items-center'>
<img src='/home.svg' alt='Home' className='flex h-5/10 w-3/10'/>
<p className='w-7/10 h-full flex items-center text-xl text-white'>Home</p>
</Link>
</div>
<div className={`w-full h-1/10 flex flex-col items-center ${location.pathname === '/Cache' ? 'bg-black/50' : 'hover:bg-black/35'} transition-all duration-300 ease-in-out overflow-hidden`}>
<Link to='/cache' className='flex w-8/10 items-center'>
<img src='/search.svg' alt='Search' className='flex h-5/10 w-3/10'/>
<p className='w-7/10 h-full flex items-center text-xl text-white'>Cache</p>
</Link>
</div>
<div className={`w-full h-1/10 flex flex-col items-center ${location.pathname === '/TestPlayer' ? 'bg-black/50' : 'hover:bg-black/35'} transition-all duration-300 ease-in-out overflow-hidden`}>
<Link to='/testplayer' className='flex w-8/10 items-center'>
<img src='/video.svg' alt='Test Player' className='flex h-5/10 w-3/10'/>
<p className='w-7/10 h-full flex items-center text-xl text-white'>Test Player</p>
</Link>
</div>
<div className={`w-full h-1/10 flex flex-col items-center ${location.pathname === '/API' ? 'bg-black/50' : 'hover:bg-black/35'} transition-all duration-300 ease-in-out overflow-hidden`}>
<Link to='/api' className='flex w-8/10 items-center'>
<img src='/docu_logo.svg' alt='API' className='flex h-5/10 w-3/10'/>
<p className='w-7/10 h-full flex items-center text-xl text-white'>API</p>
</Link>
</div>
</>
)
}
export default NavItems

View File

@ -0,0 +1,22 @@
import React from 'react'
import MainNav from './MainNav/MainNav'
import Footer from './Footer/Footer'
import NavHead from './Header/Header'
function Sidebar() {
return (
<div className='flex flex-col w-full h-full bg-zinc-900 border-r-1'>
<div className='w-full h-1/10'>
<NavHead />
</div>
<div className='w-full h-8/10'>
<MainNav />
</div>
<div className='w-full h-1/10'>
<Footer />
</div>
</div>
)
}
export default Sidebar

View File

@ -1,10 +0,0 @@
@import "tailwindcss";
details summary::-webkit-details-marker {
display: none;
}
details summary {
list-style: none;
cursor: pointer;
}

View File

@ -1,13 +1,9 @@
import { StrictMode } from 'react' import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client' import { createRoot } from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import './index.css'
import App from './App.jsx' import App from './App.jsx'
createRoot(document.getElementById('root')).render( createRoot(document.getElementById('root')).render(
<StrictMode> <StrictMode>
<BrowserRouter>
<App /> <App />
</BrowserRouter> </StrictMode>,
</StrictMode>
) )

View File

@ -2,7 +2,20 @@ import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react' import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite' import tailwindcss from '@tailwindcss/vite'
// https://vite.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react(), tailwindcss()], plugins: [react(), tailwindcss(),],
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:5000',
changeOrigin: true,
secure: false,
},
'/remotecdm': {
target: 'http://127.0.0.1:5000',
changeOrigin: true,
secure: false,
},
},
},
}) })

View File

@ -17,7 +17,7 @@ tags = {
'opengraph_url': 'https://cdrm-project.com/cache', 'opengraph_url': 'https://cdrm-project.com/cache',
'tab_title': 'Cache', 'tab_title': 'Cache',
}, },
'testplayer': { 'test_player': {
'description': 'Shaka Player for testing decryption keys', 'description': 'Shaka Player for testing decryption keys',
'keywords': 'Shaka, Player, DRM, CDRM, CDM, CDRM-Project, TPD94, Decryption, CDM-Project, KID, KEY', 'keywords': 'Shaka, Player, DRM, CDRM, CDM, CDRM-Project, TPD94, Decryption, CDM-Project, KID, KEY',
'opengraph_title': 'Test Player', 'opengraph_title': 'Test Player',

View File

@ -20,4 +20,4 @@ app.register_blueprint(remotecdm_wv_bp)
app.register_blueprint(remotecdm_pr_bp) app.register_blueprint(remotecdm_pr_bp)
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0') app.run(debug=True)