CipherStreamWeb converted to use Vite
This commit is contained in:
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,4 +1,4 @@
|
|||||||
# Logs
|
#Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
@@ -7,13 +7,17 @@ yarn-error.log*
|
|||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
lerna-debug.log*
|
lerna-debug.log*
|
||||||
|
|
||||||
|
#Node files
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
|
|
||||||
# Editor directories and files
|
#Router
|
||||||
.vscode/*
|
.tanstack
|
||||||
|
|
||||||
|
#Editor directories and files
|
||||||
|
.vscode
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
.idea
|
.idea
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
54
README.md
Normal file
54
README.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# React + TypeScript + Vite
|
||||||
|
|
||||||
|
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||||
|
|
||||||
|
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-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||||
|
|
||||||
|
## Expanding the ESLint configuration
|
||||||
|
|
||||||
|
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default tseslint.config({
|
||||||
|
extends: [
|
||||||
|
// Remove ...tseslint.configs.recommended and replace with this
|
||||||
|
...tseslint.configs.recommendedTypeChecked,
|
||||||
|
// Alternatively, use this for stricter rules
|
||||||
|
...tseslint.configs.strictTypeChecked,
|
||||||
|
// Optionally, add this for stylistic rules
|
||||||
|
...tseslint.configs.stylisticTypeChecked,
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
// other options...
|
||||||
|
parserOptions: {
|
||||||
|
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
||||||
|
tsconfigRootDir: import.meta.dirname,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// eslint.config.js
|
||||||
|
import reactX from 'eslint-plugin-react-x'
|
||||||
|
import reactDom from 'eslint-plugin-react-dom'
|
||||||
|
|
||||||
|
export default tseslint.config({
|
||||||
|
plugins: {
|
||||||
|
// Add the react-x and react-dom plugins
|
||||||
|
'react-x': reactX,
|
||||||
|
'react-dom': reactDom,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// other rules...
|
||||||
|
// Enable its recommended typescript rules
|
||||||
|
...reactX.configs['recommended-typescript'].rules,
|
||||||
|
...reactDom.configs.recommended.rules,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
42
eslint.config.js
Normal file
42
eslint.config.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import js from "@eslint/js";
|
||||||
|
import react from "eslint-plugin-react";
|
||||||
|
import reactHooks from "eslint-plugin-react-hooks";
|
||||||
|
import reactRefresh from "eslint-plugin-react-refresh";
|
||||||
|
import globals from "globals";
|
||||||
|
import tseslint from "typescript-eslint";
|
||||||
|
|
||||||
|
|
||||||
|
export default tseslint.config(
|
||||||
|
{ ignores: ['dist'] },
|
||||||
|
{
|
||||||
|
extends: [js.configs.recommended, ...tseslint.configs.recommendedTypeChecked],
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
globals: globals.browser,
|
||||||
|
parserOptions: {
|
||||||
|
project: ["./tsconfig.node.json", "./tsconfig.app.json"],
|
||||||
|
tsconfigRootDir: import.meta.dirname
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
'react-hooks': reactHooks,
|
||||||
|
'react-refresh': reactRefresh,
|
||||||
|
react: react
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...react.configs.recommended.rules,
|
||||||
|
...react.configs["jsx-runtime"].rules,
|
||||||
|
...reactHooks.configs.recommended.rules,
|
||||||
|
"react-refresh/only-export-components": [
|
||||||
|
"warn",
|
||||||
|
{ allowConstantExport: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: "detect",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
12
index.html
Normal file
12
index.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
6911
package-lock.json
generated
Normal file
6911
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
44
package.json
Normal file
44
package.json
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "cipher-stream-web",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.1",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc -b && vite build",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@headlessui/react": "^2.2.7",
|
||||||
|
"@tailwindcss/vite": "^4.1.11",
|
||||||
|
"@tanstack/react-query": "^5.85.0",
|
||||||
|
"@tanstack/react-router": "^1.131.10",
|
||||||
|
"@tanstack/react-router-devtools": "^1.131.10",
|
||||||
|
"axios": "^1.11.0",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"eslint-plugin-react": "^7.37.5",
|
||||||
|
"mattrixwv-components": "^0.0.7",
|
||||||
|
"react": "^19.1.1",
|
||||||
|
"react-dom": "^19.1.1",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
|
"react-tooltip": "^5.29.1",
|
||||||
|
"tailwindcss": "^4.1.11",
|
||||||
|
"use-debounce": "^10.0.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.33.0",
|
||||||
|
"@tanstack/router-plugin": "^1.131.11",
|
||||||
|
"@types/node": "^24.2.1",
|
||||||
|
"@types/react": "^19.1.10",
|
||||||
|
"@types/react-dom": "^19.1.7",
|
||||||
|
"@vitejs/plugin-react": "^5.0.0",
|
||||||
|
"eslint": "^9.33.0",
|
||||||
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
|
"eslint-plugin-react-refresh": "^0.4.19",
|
||||||
|
"globals": "^16.3.0",
|
||||||
|
"typescript": "^5.9.2",
|
||||||
|
"typescript-eslint": "^8.39.1",
|
||||||
|
"vite": "^7.1.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
39
src/assets/cipherStreamIcon.svg
Normal file
39
src/assets/cipherStreamIcon.svg
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
version="1.1"
|
||||||
|
width="394"
|
||||||
|
height="500"
|
||||||
|
style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
|
||||||
|
id="svg4"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs4"
|
||||||
|
/>
|
||||||
|
<g
|
||||||
|
id="g1"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
style="opacity:1"
|
||||||
|
fill="#aab8c2"
|
||||||
|
d="m 184.5,-0.5 c 8.333,0 16.667,0 25,0 9.962,1.74178 19.962,3.90845 30,6.5 64.584,22.3002 100.751,67.4668 108.5,135.5 0.5,18.997 0.667,37.997 0.5,57 -2.913,-0.741 -5.913,-1.241 -9,-1.5 -17.33,-0.5 -34.663,-0.667 -52,-0.5 0.167,-18.67 0,-37.336 -0.5,-56 C 280.798,102.627 259.631,77.1269 223.5,64 178.783,53.1241 143.616,66.6241 118,104.5 c -5.989,10.634 -9.989,21.967 -12,34 -0.5,19.33 -0.667,38.664 -0.5,58 -18.6696,-0.167 -37.3363,0 -56,0.5 -1.7475,0.352 -3.4142,0.852 -5,1.5 -0.1666,-19.669 0,-39.336 0.5,-59 1.3455,-14.035 4.3455,-27.701 9,-41 24.6984,-57.8741 68.198,-90.87408 130.5,-99 z"
|
||||||
|
id="path1"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g2"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
style="opacity:1"
|
||||||
|
fill="#feab33"
|
||||||
|
d="m 105.5,196.5 c 60.667,0 121.333,0 182,0 17.337,-0.167 34.67,0 52,0.5 3.087,0.259 6.087,0.759 9,1.5 24.416,7.747 39.416,24.08 45,49 0,66 0,132 0,198 -5.65,30.317 -23.65,48.317 -54,54 -95.333,0 -190.667,0 -286,0 -30.3262,-5.66 -48.32618,-23.66 -54,-54 0,-66.333 0,-132.667 0,-199 6.02196,-24.357 21.022,-40.357 45,-48 1.5858,-0.648 3.2525,-1.148 5,-1.5 18.6637,-0.5 37.3304,-0.667 56,-0.5 z"
|
||||||
|
id="path2"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
d="m 172.69971,307.53657 q 0,3.74867 -3.71807,3.74867 h -12.74766 q -3.71806,0 -3.71806,-3.74867 v -12.58483 q -0.26558,-7.7651 -5.5771,-13.12035 -5.31153,-5.35524 -13.01323,-5.35524 H 74.702094 q -7.70171,0 -13.27881,5.62301 -5.311524,5.35524 -5.311524,13.12035 v 105.49833 q 0,7.76511 5.311524,13.38811 5.5771,5.35525 13.27881,5.35525 h 59.223496 q 7.7017,0 13.01323,-5.08748 5.31152,-5.35525 5.5771,-13.12035 v -12.8526 q 0,-1.3388 1.0623,-2.40985 1.0623,-1.33882 2.65576,-1.33882 h 12.74766 q 1.59346,0 2.65576,1.33882 1.06231,1.07105 1.06231,2.40985 v 12.8526 q 0,8.03286 -3.18692,14.99468 -3.18691,6.96182 -8.49843,12.31707 -5.04595,5.08748 -12.21651,8.30063 -6.90498,2.94538 -14.87226,2.94538 H 74.702094 q -7.967286,0 -15.137843,-2.94538 -6.90498,-3.21315 -12.216504,-8.30063 -5.045948,-5.35525 -8.232863,-12.58483 -2.921338,-7.22959 -2.921338,-15.26245 V 295.21951 q 0,-8.03287 2.921338,-14.99469 3.186915,-7.22958 8.232863,-12.58483 5.311524,-5.35524 12.216504,-8.30063 7.170557,-3.21315 15.137843,-3.21315 h 59.223496 q 7.96728,0 14.87226,3.21315 7.17056,2.94539 12.21651,8.30063 5.31152,5.08748 8.49843,12.31706 3.18692,6.96182 3.18692,14.99469 z m 48.335,93.18127 v -12.31707 q 0,-1.3388 1.06231,-2.40985 1.32788,-1.33882 2.65576,-1.33882 h 12.74766 q 1.59346,0 2.65577,1.33882 1.06229,1.07105 1.06229,2.40985 v 12.31707 q 0,7.76511 5.31153,13.38811 5.5771,5.35525 13.27881,5.35525 h 59.22349 q 7.7017,0 13.01323,-5.35525 5.5771,-5.623 5.5771,-13.38811 V 376.887 q 0,-7.76511 -5.5771,-13.12035 -5.31153,-5.62301 -13.01323,-5.62301 h -59.22349 q -7.96729,0 -15.13785,-2.94538 -6.90498,-3.21316 -12.2165,-8.30064 -5.31152,-5.35524 -8.49843,-12.58482 -2.92135,-7.22959 -2.92135,-15.26245 v -23.83084 q 0,-8.03287 2.92135,-14.99469 3.18691,-7.22958 8.49843,-12.58483 5.31152,-5.35524 12.2165,-8.30063 7.17056,-3.21315 15.13785,-3.21315 h 59.22349 q 7.96728,0 14.87226,3.21315 7.17056,2.94539 12.48209,8.30063 5.31152,5.35525 8.23286,12.58483 3.18691,6.96182 3.18691,14.99469 v 12.31706 q 0,3.74867 -3.71806,3.74867 h -12.74766 q -3.71807,0 -3.71807,-3.74867 v -12.31706 q 0,-7.76511 -5.5771,-13.12035 -5.31153,-5.62301 -13.01323,-5.62301 h -59.22349 q -7.70171,0 -13.27881,5.62301 -5.31153,5.35524 -5.31153,13.12035 v 23.83084 q 0,7.7651 5.31153,13.38811 5.5771,5.35524 13.27881,5.35524 h 59.22349 q 7.96728,0 14.87226,3.21315 7.17056,2.94539 12.48209,8.30063 5.31152,5.35525 8.23286,12.58483 3.18691,6.96182 3.18691,14.99469 v 23.83084 q 0,8.03286 -3.18691,15.26245 -2.92134,7.22958 -8.23286,12.58483 -5.31153,5.08748 -12.48209,8.30063 -6.90498,2.94538 -14.87226,2.94538 h -59.22349 q -7.96729,0 -15.13785,-2.94538 -6.90498,-3.21315 -12.2165,-8.30063 -5.31152,-5.35525 -8.49843,-12.58483 -2.92135,-7.22959 -2.92135,-15.26245 z"
|
||||||
|
id="text7"
|
||||||
|
style="font-size:266.667px;font-family:'Disket Mono';-inkscape-font-specification:'Disket Mono';stroke-width:0.990987"
|
||||||
|
aria-label="CS"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.3 KiB |
25
src/components/button/CopyOutputButton.tsx
Normal file
25
src/components/button/CopyOutputButton.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { TertiaryButton, useToaster } from "mattrixwv-components";
|
||||||
|
|
||||||
|
|
||||||
|
export default function CopyOutputButton({
|
||||||
|
value
|
||||||
|
}:{
|
||||||
|
value: string;
|
||||||
|
}){
|
||||||
|
const { addSuccess } = useToaster();
|
||||||
|
|
||||||
|
|
||||||
|
const copyToClipboard = async () => {
|
||||||
|
await navigator.clipboard.writeText(value);
|
||||||
|
addSuccess("Output copied to clipboard", 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TertiaryButton
|
||||||
|
onClick={() => void copyToClipboard()}
|
||||||
|
>
|
||||||
|
Copy Output
|
||||||
|
</TertiaryButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
19
src/components/button/EncodingDecodingButton.tsx
Normal file
19
src/components/button/EncodingDecodingButton.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { ButtonSwitch } from "mattrixwv-components";
|
||||||
|
|
||||||
|
|
||||||
|
export default function EncodingDecodingButton({
|
||||||
|
encoding,
|
||||||
|
setEncoding
|
||||||
|
}:{
|
||||||
|
encoding: boolean,
|
||||||
|
setEncoding: (encoding: boolean) => void
|
||||||
|
}){
|
||||||
|
return (
|
||||||
|
<ButtonSwitch
|
||||||
|
checked={encoding}
|
||||||
|
onChange={setEncoding}
|
||||||
|
onNode={<div className="bg-blue-600 hover:bg-blue-700 active:bg-blue-800 rounded-lg px-4 py-2">Encoding</div>}
|
||||||
|
offNode={<div className="bg-green-600 hover:bg-green-700 active:bg-green-800 rounded-lg px-4 py-2">Decoding</div>}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
45
src/components/ciphers/CipherLoader.tsx
Normal file
45
src/components/ciphers/CipherLoader.tsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import type { CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { UseQueryResult } from "@tanstack/react-query";
|
||||||
|
import { DangerMessageBlock, RubberSpinner } from "mattrixwv-components";
|
||||||
|
import { CipherWrapper } from "./CipherWrapper";
|
||||||
|
|
||||||
|
|
||||||
|
export default function CipherLoader({
|
||||||
|
infoQuery,
|
||||||
|
children
|
||||||
|
}:{
|
||||||
|
infoQuery: UseQueryResult<CipherInfo, Error>;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}){
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{
|
||||||
|
infoQuery.isError &&
|
||||||
|
<div>
|
||||||
|
<DangerMessageBlock>
|
||||||
|
Error fetching cipher info.
|
||||||
|
</DangerMessageBlock>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
infoQuery.isError &&
|
||||||
|
<div
|
||||||
|
className="w-32 h-32"
|
||||||
|
>
|
||||||
|
<RubberSpinner
|
||||||
|
className="stroke-blue-600"
|
||||||
|
trackClassName="fill-white/20"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
infoQuery.isSuccess &&
|
||||||
|
<CipherWrapper
|
||||||
|
cipherInfo={infoQuery.data}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</CipherWrapper>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
87
src/components/ciphers/CipherWrapper.tsx
Normal file
87
src/components/ciphers/CipherWrapper.tsx
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
import type { CipherInfo } from "@/models/CipherInfo";
|
||||||
|
|
||||||
|
|
||||||
|
export function CipherWrapper({
|
||||||
|
cipherInfo,
|
||||||
|
children
|
||||||
|
}:{
|
||||||
|
cipherInfo: CipherInfo;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}){
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-16"
|
||||||
|
>
|
||||||
|
{/* Header */}
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
className="font-bold text-4xl"
|
||||||
|
>
|
||||||
|
{cipherInfo.name}
|
||||||
|
</h1>
|
||||||
|
<p
|
||||||
|
className="text-center"
|
||||||
|
>
|
||||||
|
{cipherInfo.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{/* Inputs */}
|
||||||
|
<div>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
{/* Explanations */}
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<h3
|
||||||
|
className="text-2xl"
|
||||||
|
>
|
||||||
|
Explanation
|
||||||
|
</h3>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-2 w-full"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
cipherInfo.explanation.map((line, index) => (
|
||||||
|
<p
|
||||||
|
key={index}
|
||||||
|
className="w-full text-justify"
|
||||||
|
>
|
||||||
|
{line}
|
||||||
|
</p>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<h3
|
||||||
|
className="text-2xl"
|
||||||
|
>
|
||||||
|
Facts
|
||||||
|
</h3>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-2 w-full"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
cipherInfo.facts.map((fact, index) => (
|
||||||
|
<p
|
||||||
|
key={index}
|
||||||
|
className="w-full text-justify"
|
||||||
|
>
|
||||||
|
{fact}
|
||||||
|
</p>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
cipherInfo.facts.length === 0 &&
|
||||||
|
<p
|
||||||
|
className="w-full text-justify"
|
||||||
|
>
|
||||||
|
No facts available.
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
142
src/components/ciphers/combination/adfgvx/ADFGVXInputs.tsx
Normal file
142
src/components/ciphers/combination/adfgvx/ADFGVXInputs.tsx
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeADFGVX, useEncodeADFGVX } from "@/hooks/combination/ADFGVXHooks";
|
||||||
|
import { TextInput, useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function ADFGVXInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ squareKeyword, setSquareKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeADFGVXMutation = useEncodeADFGVX();
|
||||||
|
const decodeADFGVXMutation = useDecodeADFGVX();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if((input === "") || (keyword.length < 2)){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeADFGVXMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
squareKeyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeADFGVXMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
squareKeyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, keyword, squareKeyword, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeADFGVXMutation.isSuccess){
|
||||||
|
setOutput(decodeADFGVXMutation.data.outputString ?? "");
|
||||||
|
decodeADFGVXMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeADFGVXMutation.isSuccess){
|
||||||
|
setOutput(encodeADFGVXMutation.data.outputString ?? "");
|
||||||
|
encodeADFGVXMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeADFGVXMutation.isSuccess, encodeADFGVXMutation.isSuccess, decodeADFGVXMutation.data, encodeADFGVXMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeADFGVXMutation.isError){
|
||||||
|
addDanger(decodeADFGVXMutation.error.message);
|
||||||
|
decodeADFGVXMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeADFGVXMutation.isError){
|
||||||
|
addDanger(encodeADFGVXMutation.error.message);
|
||||||
|
encodeADFGVXMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeADFGVXMutation.isError, encodeADFGVXMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
placeholder="Square Keyword"
|
||||||
|
value={squareKeyword}
|
||||||
|
onChange={(e) => setSquareKeyword(e.target.value)}
|
||||||
|
labelClassName="bg-(--bg-color) text-(--text-color)"
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
142
src/components/ciphers/combination/adfgx/ADFGXInputs.tsx
Normal file
142
src/components/ciphers/combination/adfgx/ADFGXInputs.tsx
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeADFGX, useEncodeADFGX } from "@/hooks/combination/ADFGXHooks";
|
||||||
|
import { TextInput, useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function ADFGXInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ squareKeyword, setSquareKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeADFGXMutation = useEncodeADFGX();
|
||||||
|
const decodeADFGXMutation = useDecodeADFGX();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if((input === "") || (keyword.length < 2)){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeADFGXMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
squareKeyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeADFGXMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
squareKeyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, keyword, squareKeyword, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeADFGXMutation.isSuccess){
|
||||||
|
setOutput(decodeADFGXMutation.data.outputString ?? "");
|
||||||
|
decodeADFGXMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeADFGXMutation.isSuccess){
|
||||||
|
setOutput(encodeADFGXMutation.data.outputString ?? "");
|
||||||
|
encodeADFGXMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeADFGXMutation.isSuccess, encodeADFGXMutation.isSuccess, decodeADFGXMutation.data, encodeADFGXMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeADFGXMutation.isError){
|
||||||
|
addDanger(decodeADFGXMutation.error.message);
|
||||||
|
decodeADFGXMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeADFGXMutation.isError){
|
||||||
|
addDanger(encodeADFGXMutation.error.message);
|
||||||
|
encodeADFGXMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeADFGXMutation.isError, encodeADFGXMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
value={squareKeyword}
|
||||||
|
onChange={(e) => setSquareKeyword(e.target.value)}
|
||||||
|
placeholder="Square Keyword"
|
||||||
|
labelClassName="bg-(--bg-color) text-(--text-color)"
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
150
src/components/ciphers/monosubstitution/affine/AffineInputs.tsx
Normal file
150
src/components/ciphers/monosubstitution/affine/AffineInputs.tsx
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import NumberSelector from "@/components/input/NumberSelector";
|
||||||
|
import NumberSelectorArray from "@/components/input/NumberSelectorArray";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeAffine, useEncodeAffine } from "@/hooks/monosubstitution/AffineHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function AffineInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ key1, setKey1 ] = useState(1);
|
||||||
|
const [ key2, setKey2 ] = useState(0);
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeAffineMutation = useEncodeAffine();
|
||||||
|
const decodeAffineMutation = useDecodeAffine();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeAffineMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
key1,
|
||||||
|
key2,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeAffineMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
key1,
|
||||||
|
key2,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, key1, key2, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeAffineMutation.isSuccess){
|
||||||
|
setOutput(decodeAffineMutation.data.outputString ?? "");
|
||||||
|
decodeAffineMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeAffineMutation.isSuccess){
|
||||||
|
setOutput(encodeAffineMutation.data.outputString ?? "");
|
||||||
|
encodeAffineMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeAffineMutation.isSuccess, encodeAffineMutation.isSuccess, decodeAffineMutation.data, encodeAffineMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeAffineMutation.isError){
|
||||||
|
addDanger(decodeAffineMutation.error.message);
|
||||||
|
decodeAffineMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeAffineMutation.isError){
|
||||||
|
addDanger(encodeAffineMutation.error.message);
|
||||||
|
encodeAffineMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeAffineMutation.isError, encodeAffineMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-2"
|
||||||
|
>
|
||||||
|
<NumberSelectorArray
|
||||||
|
label="Key 1"
|
||||||
|
value={key1}
|
||||||
|
shiftArray={[1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25]}
|
||||||
|
onChange={setKey1}
|
||||||
|
/>
|
||||||
|
<NumberSelector
|
||||||
|
label="Key 2"
|
||||||
|
value={key2}
|
||||||
|
minValue={0}
|
||||||
|
maxValue={25}
|
||||||
|
onChange={setKey2}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
125
src/components/ciphers/monosubstitution/atbash/AtbashInputs.tsx
Normal file
125
src/components/ciphers/monosubstitution/atbash/AtbashInputs.tsx
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeAtbash, useEncodeAtbash } from "@/hooks/monosubstitution/AtbashHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function AtbashInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeAtbashMutation = useEncodeAtbash();
|
||||||
|
const decodeAtbashMutation = useDecodeAtbash();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeAtbashMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeAtbashMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeAtbashMutation.isSuccess){
|
||||||
|
setOutput(decodeAtbashMutation.data.outputString ?? "");
|
||||||
|
decodeAtbashMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeAtbashMutation.isSuccess){
|
||||||
|
setOutput(encodeAtbashMutation.data.outputString ?? "");
|
||||||
|
encodeAtbashMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeAtbashMutation.isSuccess, encodeAtbashMutation.isSuccess, decodeAtbashMutation.data, encodeAtbashMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeAtbashMutation.isError){
|
||||||
|
addDanger(decodeAtbashMutation.error.message);
|
||||||
|
decodeAtbashMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeAtbashMutation.isError){
|
||||||
|
addDanger(encodeAtbashMutation.error.message);
|
||||||
|
encodeAtbashMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeAtbashMutation, encodeAtbashMutation ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeAutokey, useEncodeAutokey } from "@/hooks/monosubstitution/AutokeyHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function AutokeyInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeAutokeyMutation = useEncodeAutokey();
|
||||||
|
const decodeAutokeyMutation = useDecodeAutokey();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if((input === "") || (keyword.length < 2)){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeAutokeyMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeAutokeyMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, input, keyword, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeAutokeyMutation.isSuccess){
|
||||||
|
setOutput(decodeAutokeyMutation.data.outputString ?? "");
|
||||||
|
decodeAutokeyMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeAutokeyMutation.isSuccess){
|
||||||
|
setOutput(encodeAutokeyMutation.data.outputString ?? "");
|
||||||
|
encodeAutokeyMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeAutokeyMutation.isSuccess, encodeAutokeyMutation.isSuccess, decodeAutokeyMutation.data, encodeAutokeyMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeAutokeyMutation.isError){
|
||||||
|
addDanger(decodeAutokeyMutation.error.message);
|
||||||
|
decodeAutokeyMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeAutokeyMutation.isError){
|
||||||
|
addDanger(encodeAutokeyMutation.error.message);
|
||||||
|
encodeAutokeyMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeAutokeyMutation.isError, encodeAutokeyMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeBaconian, useEncodeBaconian } from "@/hooks/monosubstitution/BaconianHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function BaconianInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeBaconianMutation = useEncodeBaconian();
|
||||||
|
const decodeBaconianMutation = useDecodeBaconian();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeBaconianMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeBaconianMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [ capitals, encoding, input, performCoding ]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeBaconianMutation.isSuccess){
|
||||||
|
setOutput(decodeBaconianMutation.data.outputString ?? "");
|
||||||
|
decodeBaconianMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeBaconianMutation.isSuccess){
|
||||||
|
setOutput(encodeBaconianMutation.data.outputString ?? "");
|
||||||
|
encodeBaconianMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeBaconianMutation.isSuccess, encodeBaconianMutation.isSuccess, decodeBaconianMutation.data, encodeBaconianMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeBaconianMutation.isError){
|
||||||
|
addDanger(decodeBaconianMutation.error.message);
|
||||||
|
decodeBaconianMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeBaconianMutation.isError){
|
||||||
|
addDanger(encodeBaconianMutation.error.message);
|
||||||
|
encodeBaconianMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeBaconianMutation.isError, encodeBaconianMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
118
src/components/ciphers/monosubstitution/basex/BaseXInputs.tsx
Normal file
118
src/components/ciphers/monosubstitution/basex/BaseXInputs.tsx
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import NumberSelector from "@/components/input/NumberSelector";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import { useDecodeBaseX, useEncodeBaseX } from "@/hooks/monosubstitution/BaseXHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function BaseXInputs(){
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ base, setBase ] = useState(2);
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeBaseXMutation = useEncodeBaseX();
|
||||||
|
const decodeBaseXMutation = useDecodeBaseX();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeBaseXMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
base,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeBaseXMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
base,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [base, encoding, input, performCoding]);
|
||||||
|
|
||||||
|
//When the mutations is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeBaseXMutation.isSuccess){
|
||||||
|
setOutput(decodeBaseXMutation.data.outputString ?? "");
|
||||||
|
decodeBaseXMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeBaseXMutation.isSuccess){
|
||||||
|
setOutput(encodeBaseXMutation.data.outputString ?? "");
|
||||||
|
encodeBaseXMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeBaseXMutation.isSuccess, encodeBaseXMutation.isSuccess, decodeBaseXMutation.data, encodeBaseXMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeBaseXMutation.isError){
|
||||||
|
addDanger(decodeBaseXMutation.error.message);
|
||||||
|
decodeBaseXMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeBaseXMutation.isError){
|
||||||
|
addDanger(encodeBaseXMutation.error.message);
|
||||||
|
encodeBaseXMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeBaseXMutation.isError, encodeBaseXMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-2"
|
||||||
|
>
|
||||||
|
<NumberSelector
|
||||||
|
label="Base"
|
||||||
|
value={base}
|
||||||
|
onChange={setBase}
|
||||||
|
minValue={2}
|
||||||
|
maxValue={36}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeBeaufort, useEncodeBeaufort } from "@/hooks/monosubstitution/BeaufortHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function BeaufortInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeBeaufortMutation = useEncodeBeaufort();
|
||||||
|
const decodeBeaufortMutation = useDecodeBeaufort();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if((input === "") || (keyword.length < 2)){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeBeaufortMutation.mutate({
|
||||||
|
encoding: encoding,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
keyword: keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeBeaufortMutation.mutate({
|
||||||
|
encoding: encoding,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
keyword: keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, keyword, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeBeaufortMutation.isSuccess){
|
||||||
|
setOutput(decodeBeaufortMutation.data.outputString ?? "");
|
||||||
|
decodeBeaufortMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeBeaufortMutation.isSuccess){
|
||||||
|
setOutput(encodeBeaufortMutation.data.outputString ?? "");
|
||||||
|
encodeBeaufortMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeBeaufortMutation.isSuccess, encodeBeaufortMutation.isSuccess, decodeBeaufortMutation.data, encodeBeaufortMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeBeaufortMutation.isError){
|
||||||
|
addDanger(decodeBeaufortMutation.error.message);
|
||||||
|
decodeBeaufortMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeBeaufortMutation.isError){
|
||||||
|
addDanger(encodeBeaufortMutation.error.message);
|
||||||
|
encodeBeaufortMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeBeaufortMutation.isError, encodeBeaufortMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
140
src/components/ciphers/monosubstitution/caesar/CaesarInputs.tsx
Normal file
140
src/components/ciphers/monosubstitution/caesar/CaesarInputs.tsx
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import NumberSelector from "@/components/input/NumberSelector";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeCaesar, useEncodeCaesar } from "@/hooks/monosubstitution/CaesarHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function CaesarInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ shift, setShift ] = useState(0);
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeCaesarMutation = useEncodeCaesar();
|
||||||
|
const decodeCaesarMutation = useDecodeCaesar();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeCaesarMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
shiftAmount: shift,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeCaesarMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
shiftAmount: shift,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, input, performCoding, shift, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeCaesarMutation.isSuccess){
|
||||||
|
setOutput(decodeCaesarMutation.data.outputString ?? "");
|
||||||
|
decodeCaesarMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeCaesarMutation.isSuccess){
|
||||||
|
setOutput(encodeCaesarMutation.data.outputString ?? "");
|
||||||
|
encodeCaesarMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeCaesarMutation.isSuccess, encodeCaesarMutation.isSuccess, decodeCaesarMutation.data, encodeCaesarMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeCaesarMutation.isError){
|
||||||
|
addDanger(decodeCaesarMutation.error.message);
|
||||||
|
decodeCaesarMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeCaesarMutation.isError){
|
||||||
|
addDanger(encodeCaesarMutation.error.message);
|
||||||
|
encodeCaesarMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeCaesarMutation.isError, encodeCaesarMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-2"
|
||||||
|
>
|
||||||
|
<NumberSelector
|
||||||
|
label="Shift"
|
||||||
|
value={shift}
|
||||||
|
minValue={0}
|
||||||
|
maxValue={25}
|
||||||
|
onChange={setShift}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordArea from "@/components/input/KeywordArea";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeOneTimePad, useEncodeOneTimePad } from "@/hooks/monosubstitution/OneTimePadHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function OneTimePadInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeOneTimePadMutation = useEncodeOneTimePad();
|
||||||
|
const decodeOneTimePadMutation = useDecodeOneTimePad();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if((input === "") || (keyword.length < input.length)){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeOneTimePadMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeOneTimePadMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, keyword, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeOneTimePadMutation.isSuccess){
|
||||||
|
setOutput(decodeOneTimePadMutation.data.outputString ?? "");
|
||||||
|
decodeOneTimePadMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeOneTimePadMutation.isSuccess){
|
||||||
|
setOutput(encodeOneTimePadMutation.data.outputString ?? "");
|
||||||
|
encodeOneTimePadMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeOneTimePadMutation.isSuccess, encodeOneTimePadMutation.isSuccess, decodeOneTimePadMutation.data, encodeOneTimePadMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeOneTimePadMutation.isError){
|
||||||
|
addDanger(decodeOneTimePadMutation.error.message);
|
||||||
|
decodeOneTimePadMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeOneTimePadMutation.isError){
|
||||||
|
addDanger(encodeOneTimePadMutation.error.message);
|
||||||
|
encodeOneTimePadMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeOneTimePadMutation.isError, encodeOneTimePadMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordArea
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
133
src/components/ciphers/monosubstitution/porta/PortaInputs.tsx
Normal file
133
src/components/ciphers/monosubstitution/porta/PortaInputs.tsx
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodePorta, useEncodePorta } from "@/hooks/monosubstitution/PortaHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function PortaInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodePortaMutation = useEncodePorta();
|
||||||
|
const decodePortaMutation = useDecodePorta();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if((input === "") || (keyword.length < 2)){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodePortaMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodePortaMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, keyword, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodePortaMutation.isSuccess){
|
||||||
|
setOutput(decodePortaMutation.data.outputString ?? "");
|
||||||
|
decodePortaMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodePortaMutation.isSuccess){
|
||||||
|
setOutput(encodePortaMutation.data.outputString ?? "");
|
||||||
|
encodePortaMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodePortaMutation.isSuccess, encodePortaMutation.isSuccess, decodePortaMutation.data, encodePortaMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodePortaMutation.isError){
|
||||||
|
addDanger(decodePortaMutation.error.message);
|
||||||
|
decodePortaMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodePortaMutation.isError){
|
||||||
|
addDanger(encodePortaMutation.error.message);
|
||||||
|
encodePortaMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodePortaMutation.isError, encodePortaMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeSubstitution, useEncodeSubstitution } from "@/hooks/monosubstitution/SubstitutionHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function SubstitutionInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeSubstitutionMutation = useEncodeSubstitution();
|
||||||
|
const decodeSubstitutionMutation = useDecodeSubstitution();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if((input === "") || ((keyword.length !== 26) && (keyword.length !== 36))){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeSubstitutionMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeSubstitutionMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, keyword, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeSubstitutionMutation.isSuccess){
|
||||||
|
setOutput(decodeSubstitutionMutation.data.outputString ?? "");
|
||||||
|
decodeSubstitutionMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeSubstitutionMutation.isSuccess){
|
||||||
|
setOutput(encodeSubstitutionMutation.data.outputString ?? "");
|
||||||
|
encodeSubstitutionMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeSubstitutionMutation.isSuccess, encodeSubstitutionMutation.isSuccess, decodeSubstitutionMutation.data, encodeSubstitutionMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeSubstitutionMutation.isError){
|
||||||
|
addDanger(decodeSubstitutionMutation.error.message);
|
||||||
|
decodeSubstitutionMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeSubstitutionMutation.isError){
|
||||||
|
addDanger(encodeSubstitutionMutation.error.message);
|
||||||
|
encodeSubstitutionMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeSubstitutionMutation.isError, encodeSubstitutionMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeVigenere, useEncodeVigenere } from "@/hooks/monosubstitution/VigenereHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function VigenereInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeVigenereMutation = useEncodeVigenere();
|
||||||
|
const decodeVigenereMutation = useDecodeVigenere();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if((input === "") || (keyword.length < 2)){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeVigenereMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeVigenereMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, keyword, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeVigenereMutation.isSuccess){
|
||||||
|
setOutput(decodeVigenereMutation.data.outputString ?? "");
|
||||||
|
decodeVigenereMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeVigenereMutation.isSuccess){
|
||||||
|
setOutput(encodeVigenereMutation.data.outputString ?? "");
|
||||||
|
encodeVigenereMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeVigenereMutation.isSuccess, encodeVigenereMutation.isSuccess, decodeVigenereMutation.data, encodeVigenereMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeVigenereMutation.isError){
|
||||||
|
addDanger(decodeVigenereMutation.error.message);
|
||||||
|
decodeVigenereMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeVigenereMutation.isError){
|
||||||
|
addDanger(encodeVigenereMutation.error.message);
|
||||||
|
encodeVigenereMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeVigenereMutation.isError, encodeVigenereMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
133
src/components/ciphers/polysubstitution/bifid/BifidInputs.tsx
Normal file
133
src/components/ciphers/polysubstitution/bifid/BifidInputs.tsx
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeBifid, useEncodeBifid } from "@/hooks/polysubstitution/BifidHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function BifidInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeBifidMutation = useEncodeBifid();
|
||||||
|
const decodeBifidMutation = useDecodeBifid();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeBifidMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeBifidMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, keyword, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeBifidMutation.isSuccess){
|
||||||
|
setOutput(decodeBifidMutation.data.outputString ?? "");
|
||||||
|
decodeBifidMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeBifidMutation.isSuccess){
|
||||||
|
setOutput(encodeBifidMutation.data.outputString ?? "");
|
||||||
|
encodeBifidMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeBifidMutation.isSuccess, encodeBifidMutation.isSuccess, decodeBifidMutation.data, encodeBifidMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeBifidMutation.isError){
|
||||||
|
addDanger(decodeBifidMutation.error.message);
|
||||||
|
decodeBifidMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeBifidMutation.isError){
|
||||||
|
addDanger(encodeBifidMutation.error.message);
|
||||||
|
encodeBifidMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeBifidMutation.isError, encodeBifidMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeColumnar, useEncodeColumnar } from "@/hooks/polysubstitution/ColumnarHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function ColumnarInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeColumnarMutation = useEncodeColumnar();
|
||||||
|
const decodeColumnarMutation = useDecodeColumnar();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if((input === "") || (keyword.length < 2)){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeColumnarMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeColumnarMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, keyword, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeColumnarMutation.isSuccess){
|
||||||
|
setOutput(decodeColumnarMutation.data.outputString ?? "");
|
||||||
|
decodeColumnarMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeColumnarMutation.isSuccess){
|
||||||
|
setOutput(encodeColumnarMutation.data.outputString ?? "");
|
||||||
|
encodeColumnarMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeColumnarMutation.isSuccess, encodeColumnarMutation.isSuccess, decodeColumnarMutation.data, encodeColumnarMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeColumnarMutation.isError){
|
||||||
|
addDanger(decodeColumnarMutation.error.message);
|
||||||
|
decodeColumnarMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeColumnarMutation.isError){
|
||||||
|
addDanger(encodeColumnarMutation.error.message);
|
||||||
|
encodeColumnarMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeColumnarMutation.isError, encodeColumnarMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
133
src/components/ciphers/polysubstitution/hill/HillInputs.tsx
Normal file
133
src/components/ciphers/polysubstitution/hill/HillInputs.tsx
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import SquareNumberArray from "@/components/input/SquareNumberArray";
|
||||||
|
import { useDecodeHill, useEncodeHill } from "@/hooks/polysubstitution/HillHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function HillInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ key, setKey ] = useState([[0, 0], [0, 0]]);
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeHillMutation = useEncodeHill();
|
||||||
|
const decodeHillMutation = useDecodeHill();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeHillMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
key,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeHillMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
key,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, key, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeHillMutation.isSuccess){
|
||||||
|
setOutput(decodeHillMutation.data.outputString ?? "");
|
||||||
|
decodeHillMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeHillMutation.isSuccess){
|
||||||
|
setOutput(encodeHillMutation.data.outputString ?? "");
|
||||||
|
encodeHillMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeHillMutation.isSuccess, encodeHillMutation.isSuccess, decodeHillMutation.data, encodeHillMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeHillMutation.isError){
|
||||||
|
addDanger(decodeHillMutation.error.message);
|
||||||
|
decodeHillMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeHillMutation.isError){
|
||||||
|
addDanger(encodeHillMutation.error.message);
|
||||||
|
encodeHillMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeHillMutation.isError, encodeHillMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<SquareNumberArray
|
||||||
|
value={key}
|
||||||
|
onChange={setKey}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
103
src/components/ciphers/polysubstitution/morse/MorseInputs.tsx
Normal file
103
src/components/ciphers/polysubstitution/morse/MorseInputs.tsx
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import { useDecodeMorse, useEncodeMorse } from "@/hooks/polysubstitution/MorseHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function MorseInputs(){
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeMorseMutation = useEncodeMorse();
|
||||||
|
const decodeMorseMutation = useDecodeMorse();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeMorseMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeMorseMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [encoding, input, performCoding]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeMorseMutation.isSuccess){
|
||||||
|
setOutput(decodeMorseMutation.data.outputString ?? "");
|
||||||
|
decodeMorseMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeMorseMutation.isSuccess){
|
||||||
|
setOutput(encodeMorseMutation.data.outputString ?? "");
|
||||||
|
encodeMorseMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeMorseMutation.isSuccess, encodeMorseMutation.isSuccess, decodeMorseMutation.data, encodeMorseMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeMorseMutation.isError){
|
||||||
|
addDanger(decodeMorseMutation.error.message);
|
||||||
|
decodeMorseMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeMorseMutation.isError){
|
||||||
|
addDanger(encodeMorseMutation.error.message);
|
||||||
|
encodeMorseMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeMorseMutation.isError, encodeMorseMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodePlayfair, useEncodePlayfair } from "@/hooks/polysubstitution/PlayfairHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function PlayfairInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodePlayfairMutation = useEncodePlayfair();
|
||||||
|
const decodePlayfairMutation = useDecodePlayfair();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodePlayfairMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodePlayfairMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, keyword, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodePlayfairMutation.isSuccess){
|
||||||
|
setOutput(decodePlayfairMutation.data.outputString ?? "");
|
||||||
|
decodePlayfairMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodePlayfairMutation.isSuccess){
|
||||||
|
setOutput(encodePlayfairMutation.data.outputString ?? "");
|
||||||
|
encodePlayfairMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodePlayfairMutation.isSuccess, encodePlayfairMutation.isSuccess, decodePlayfairMutation.data, encodePlayfairMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodePlayfairMutation.isError){
|
||||||
|
addDanger(decodePlayfairMutation.error.message);
|
||||||
|
decodePlayfairMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodePlayfairMutation.isError){
|
||||||
|
addDanger(encodePlayfairMutation.error.message);
|
||||||
|
encodePlayfairMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodePlayfairMutation.isError, encodePlayfairMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodePolybius, useEncodePolybius } from "@/hooks/polysubstitution/PolybiusHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function PolybiusInputs(){
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodePolybiusMutation = useEncodePolybius();
|
||||||
|
const decodePolybiusMutation = useDecodePolybius();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodePolybiusMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodePolybiusMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
keyword,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [encoding, keyword, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodePolybiusMutation.isSuccess){
|
||||||
|
setOutput(decodePolybiusMutation.data.outputString ?? "");
|
||||||
|
decodePolybiusMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodePolybiusMutation.isSuccess){
|
||||||
|
setOutput(encodePolybiusMutation.data.outputString ?? "");
|
||||||
|
encodePolybiusMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodePolybiusMutation.isSuccess, encodePolybiusMutation.isSuccess, decodePolybiusMutation.data, encodePolybiusMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodePolybiusMutation.isError){
|
||||||
|
addDanger(decodePolybiusMutation.error.message);
|
||||||
|
decodePolybiusMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodePolybiusMutation.isError){
|
||||||
|
addDanger(encodePolybiusMutation.error.message);
|
||||||
|
encodePolybiusMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodePolybiusMutation.isError, encodePolybiusMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import NumberSelector from "@/components/input/NumberSelector";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeRailFence, useEncodeRailFence } from "@/hooks/polysubstitution/RailFenceHooks";
|
||||||
|
import { useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function RaidFenceInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ rails, setRails ] = useState(2);
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeRailFenceMutation = useEncodeRailFence();
|
||||||
|
const decodeRailFenceMutation = useDecodeRailFence();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeRailFenceMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
rails,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeRailFenceMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
rails,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, rails, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeRailFenceMutation.isSuccess){
|
||||||
|
setOutput(decodeRailFenceMutation.data.outputString ?? "");
|
||||||
|
decodeRailFenceMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeRailFenceMutation.isSuccess){
|
||||||
|
setOutput(encodeRailFenceMutation.data.outputString ?? "");
|
||||||
|
encodeRailFenceMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeRailFenceMutation.isSuccess, encodeRailFenceMutation.isSuccess, decodeRailFenceMutation.data, encodeRailFenceMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeRailFenceMutation.isError){
|
||||||
|
addDanger(decodeRailFenceMutation.error.message);
|
||||||
|
decodeRailFenceMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeRailFenceMutation.isError){
|
||||||
|
addDanger(encodeRailFenceMutation.error.message);
|
||||||
|
encodeRailFenceMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeRailFenceMutation.isError, encodeRailFenceMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-2"
|
||||||
|
>
|
||||||
|
<NumberSelector
|
||||||
|
label="Rails"
|
||||||
|
value={rails}
|
||||||
|
onChange={setRails}
|
||||||
|
minValue={2}
|
||||||
|
maxValue={100}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
157
src/components/ciphers/polysubstitution/trifid/TrifidInputs.tsx
Normal file
157
src/components/ciphers/polysubstitution/trifid/TrifidInputs.tsx
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
import CopyOutputButton from "@/components/button/CopyOutputButton";
|
||||||
|
import EncodingDecodingButton from "@/components/button/EncodingDecodingButton";
|
||||||
|
import InputMessage from "@/components/input/InputMessage";
|
||||||
|
import KeywordInput from "@/components/input/KeywordInput";
|
||||||
|
import NumberSelector from "@/components/input/NumberSelector";
|
||||||
|
import OutputMessage from "@/components/input/OutputMessage";
|
||||||
|
import PreservationSliders from "@/components/input/PreservationSliders";
|
||||||
|
import { useDecodeTrifid, useEncodeTrifid } from "@/hooks/polysubstitution/TrifidHooks";
|
||||||
|
import { TextInput, useToaster } from "mattrixwv-components";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
|
|
||||||
|
|
||||||
|
export default function TrifidInputs(){
|
||||||
|
const [ capitals, setCapitals ] = useState(true);
|
||||||
|
const [ symbols, setSymbols ] = useState(true);
|
||||||
|
const [ whitespace, setWhitespace ] = useState(true);
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
const [ fill, setFill ] = useState("#");
|
||||||
|
const [ groupLength, setGroupLength ] = useState(1);
|
||||||
|
const [ input, setInput ] = useState("");
|
||||||
|
const [ output, setOutput ] = useState("");
|
||||||
|
|
||||||
|
const { addDanger } = useToaster();
|
||||||
|
const encodeTrifidMutation = useEncodeTrifid();
|
||||||
|
const decodeTrifidMutation = useDecodeTrifid();
|
||||||
|
|
||||||
|
|
||||||
|
//Do coding with a delay
|
||||||
|
const performCoding = useDebouncedCallback(() => {
|
||||||
|
if(input === ""){
|
||||||
|
setOutput("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(encoding){
|
||||||
|
encodeTrifidMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
fill,
|
||||||
|
groupLength,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
decodeTrifidMutation.mutate({
|
||||||
|
encoding,
|
||||||
|
preserveSymbols: symbols,
|
||||||
|
preserveWhitespace: whitespace,
|
||||||
|
preserveCapitals: capitals,
|
||||||
|
keyword,
|
||||||
|
fill,
|
||||||
|
groupLength,
|
||||||
|
inputString: input
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
//Code when input changes
|
||||||
|
useEffect(() => {
|
||||||
|
performCoding();
|
||||||
|
}, [capitals, encoding, keyword, fill, groupLength, input, performCoding, symbols, whitespace]);
|
||||||
|
|
||||||
|
//When the mutation is successful set the new output
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeTrifidMutation.isSuccess){
|
||||||
|
setOutput(decodeTrifidMutation.data.outputString ?? "");
|
||||||
|
decodeTrifidMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeTrifidMutation.isSuccess){
|
||||||
|
setOutput(encodeTrifidMutation.data.outputString ?? "");
|
||||||
|
encodeTrifidMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeTrifidMutation.isSuccess, encodeTrifidMutation.isSuccess, decodeTrifidMutation.data, encodeTrifidMutation.data ]);
|
||||||
|
|
||||||
|
//When the mutation has an error, display the message
|
||||||
|
useEffect(() => {
|
||||||
|
if(decodeTrifidMutation.isError){
|
||||||
|
addDanger(decodeTrifidMutation.error.message);
|
||||||
|
decodeTrifidMutation.reset();
|
||||||
|
}
|
||||||
|
if(encodeTrifidMutation.isError){
|
||||||
|
addDanger(encodeTrifidMutation.error.message);
|
||||||
|
encodeTrifidMutation.reset();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ decodeTrifidMutation.isError, encodeTrifidMutation.isError ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<PreservationSliders
|
||||||
|
capitals={capitals}
|
||||||
|
setCapitals={setCapitals}
|
||||||
|
symbols={symbols}
|
||||||
|
setSymbols={setSymbols}
|
||||||
|
whitespace={whitespace}
|
||||||
|
setWhitespace={setWhitespace}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-8"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-2"
|
||||||
|
>
|
||||||
|
<NumberSelector
|
||||||
|
label="Group Size"
|
||||||
|
value={groupLength}
|
||||||
|
onChange={setGroupLength}
|
||||||
|
minValue={1}
|
||||||
|
maxValue={100}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<TextInput
|
||||||
|
placeholder="Fill"
|
||||||
|
value={fill}
|
||||||
|
onChange={(e) => { if(e.target.value.length <= 1){ setFill(e.target.value); } }}
|
||||||
|
labelClassName="bg-(--bg-color) text-(--text-color)"
|
||||||
|
/>
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
<InputMessage
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
/>
|
||||||
|
<OutputMessage
|
||||||
|
value={output}
|
||||||
|
onChange={setOutput}
|
||||||
|
/>
|
||||||
|
<CopyOutputButton
|
||||||
|
value={output}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
24
src/components/input/InputMessage.tsx
Normal file
24
src/components/input/InputMessage.tsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { TextArea } from "mattrixwv-components";
|
||||||
|
|
||||||
|
|
||||||
|
export default function InputMessage({
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}:{
|
||||||
|
value: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
}){
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="w-160"
|
||||||
|
>
|
||||||
|
<TextArea
|
||||||
|
placeholder="Input Message"
|
||||||
|
value={value}
|
||||||
|
onChange={(e) => onChange(e.target.value)}
|
||||||
|
inputClassName="h-40 w-160 [resize:none]"
|
||||||
|
labelClassName="bg-(--bg-color) text-(--text-color) peer-focus:bg-(--bg-color) peer-focus:text-(--text-color)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
23
src/components/input/KeywordArea.tsx
Normal file
23
src/components/input/KeywordArea.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { TextArea } from "mattrixwv-components";
|
||||||
|
|
||||||
|
export default function KeywordArea({
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}:{
|
||||||
|
value: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
}){
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="w-160"
|
||||||
|
>
|
||||||
|
<TextArea
|
||||||
|
placeholder="Keyword"
|
||||||
|
value={value}
|
||||||
|
onChange={(e) => onChange(e.target.value)}
|
||||||
|
inputClassName="h-40 w-160 [resize:none]"
|
||||||
|
labelClassName="bg-(--bg-color) text-(--text-color) peer-focus:bg-(--bg-color) peer-focus:text-(--text-color)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
23
src/components/input/KeywordInput.tsx
Normal file
23
src/components/input/KeywordInput.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { TextInput } from "mattrixwv-components";
|
||||||
|
|
||||||
|
|
||||||
|
export default function KeywordInput({
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}:{
|
||||||
|
value: string;
|
||||||
|
onChange: (newValue: string) => void;
|
||||||
|
}){
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="w-160"
|
||||||
|
>
|
||||||
|
<TextInput
|
||||||
|
placeholder="Keyword"
|
||||||
|
value={value}
|
||||||
|
onChange={(e) => onChange(e.target.value)}
|
||||||
|
labelClassName="bg-(--bg-color) text-(--text-color) peer-focus:bg-(--bg-color) peer-focus:text-(--text-color)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
31
src/components/input/NumberSelector.tsx
Normal file
31
src/components/input/NumberSelector.tsx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { useMemo } from "react";
|
||||||
|
import NumberSelectorArray from "./NumberSelectorArray";
|
||||||
|
|
||||||
|
export default function NumberSelector({
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
minValue,
|
||||||
|
maxValue,
|
||||||
|
onChange
|
||||||
|
}:{
|
||||||
|
value: number;
|
||||||
|
label: string;
|
||||||
|
minValue: number;
|
||||||
|
maxValue: number;
|
||||||
|
onChange: (newShift: number) => void;
|
||||||
|
}){
|
||||||
|
const shiftArray: number[] = useMemo(() => (
|
||||||
|
Array.from({ length: maxValue - minValue + 1 }, (_, i) => i + minValue)
|
||||||
|
), [ minValue, maxValue ]);
|
||||||
|
//TODO: Perform a check for minValue <= value <= maxValue
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NumberSelectorArray
|
||||||
|
value={value}
|
||||||
|
label={label}
|
||||||
|
shiftArray={shiftArray}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
59
src/components/input/NumberSelectorArray.tsx
Normal file
59
src/components/input/NumberSelectorArray.tsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { PrimaryButton, SuccessButton } from "mattrixwv-components";
|
||||||
|
import { useCallback, useState } from "react";
|
||||||
|
import { BsChevronLeft, BsChevronRight } from "react-icons/bs";
|
||||||
|
|
||||||
|
|
||||||
|
export default function NumberSelectorArray({
|
||||||
|
label,
|
||||||
|
shiftArray,
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}:{
|
||||||
|
label: string;
|
||||||
|
shiftArray: number[];
|
||||||
|
value: number;
|
||||||
|
onChange: (value: number) => void;
|
||||||
|
}){
|
||||||
|
const [ arraySubscript, setArraySubscript ] = useState(shiftArray.indexOf(value) ?? 0);
|
||||||
|
//TODO: Check if the value exists
|
||||||
|
|
||||||
|
|
||||||
|
const decrementValue = useCallback(() => {
|
||||||
|
if(arraySubscript === 0){
|
||||||
|
setArraySubscript(shiftArray.length - 1);
|
||||||
|
onChange(shiftArray[shiftArray.length - 1]);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
setArraySubscript(arraySubscript - 1);
|
||||||
|
onChange(shiftArray[arraySubscript - 1]);
|
||||||
|
}
|
||||||
|
}, [arraySubscript, shiftArray, onChange]);
|
||||||
|
|
||||||
|
const incrementValue = useCallback(() => {
|
||||||
|
if(arraySubscript === shiftArray.length - 1){
|
||||||
|
setArraySubscript(0);
|
||||||
|
onChange(shiftArray[0]);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
setArraySubscript(arraySubscript + 1);
|
||||||
|
onChange(shiftArray[arraySubscript + 1]);
|
||||||
|
}
|
||||||
|
}, [arraySubscript, shiftArray, onChange]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center text-2xl gap-y-2"
|
||||||
|
>
|
||||||
|
{/* Label */}
|
||||||
|
<div>{label}</div>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center"
|
||||||
|
>
|
||||||
|
<SuccessButton size="sm" shape="square" onClick={decrementValue}><BsChevronLeft className="text-3xl text-white"/></SuccessButton>
|
||||||
|
<div className="w-16 text-center">{value}</div>
|
||||||
|
<PrimaryButton size="sm" shape="square" onClick={incrementValue}><BsChevronRight className="text-3xl text-white"/></PrimaryButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
src/components/input/OutputMessage.tsx
Normal file
25
src/components/input/OutputMessage.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { TextArea } from "mattrixwv-components";
|
||||||
|
|
||||||
|
|
||||||
|
export default function OutputMessage({
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}:{
|
||||||
|
value: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
}){
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="w-160"
|
||||||
|
>
|
||||||
|
<TextArea
|
||||||
|
placeholder="Output Message"
|
||||||
|
value={value}
|
||||||
|
onChange={(e) => onChange(e.target.value)}
|
||||||
|
inputClassName="h-40 w-160 [resize:none]"
|
||||||
|
labelClassName="bg-(--bg-color) text-(--text-color) peer-focus:bg-(--bg-color) peer-focus:text-(--text-color)"
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
59
src/components/input/PreservationSliders.tsx
Normal file
59
src/components/input/PreservationSliders.tsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { PrimarySwitch } from "mattrixwv-components";
|
||||||
|
|
||||||
|
|
||||||
|
export default function PreservationSliders({
|
||||||
|
capitals,
|
||||||
|
setCapitals,
|
||||||
|
symbols,
|
||||||
|
setSymbols,
|
||||||
|
whitespace,
|
||||||
|
setWhitespace
|
||||||
|
}:{
|
||||||
|
capitals?: boolean;
|
||||||
|
setCapitals?: (value: boolean) => void;
|
||||||
|
symbols?: boolean;
|
||||||
|
setSymbols?: (value: boolean) => void;
|
||||||
|
whitespace?: boolean;
|
||||||
|
setWhitespace?: (value: boolean) => void;
|
||||||
|
}){
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{
|
||||||
|
setCapitals &&
|
||||||
|
<div className="flex flex-row items-center justify-center">
|
||||||
|
<PrimarySwitch
|
||||||
|
checked={capitals}
|
||||||
|
onChange={setCapitals}
|
||||||
|
size="md"
|
||||||
|
>
|
||||||
|
<div className="pl-2">Preserve Capitals</div>
|
||||||
|
</PrimarySwitch>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
setSymbols &&
|
||||||
|
<div className="flex flex-row items-center justify-center">
|
||||||
|
<PrimarySwitch
|
||||||
|
checked={symbols}
|
||||||
|
onChange={setSymbols}
|
||||||
|
size="md"
|
||||||
|
>
|
||||||
|
<div className="pl-2">Preserve Symbols</div>
|
||||||
|
</PrimarySwitch>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
setWhitespace &&
|
||||||
|
<div className="flex flex-row items-center justify-center">
|
||||||
|
<PrimarySwitch
|
||||||
|
checked={whitespace}
|
||||||
|
onChange={setWhitespace}
|
||||||
|
size="md"
|
||||||
|
>
|
||||||
|
<div className="pl-2">Preserve Whitespace</div>
|
||||||
|
</PrimarySwitch>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
92
src/components/input/SquareNumberArray.tsx
Normal file
92
src/components/input/SquareNumberArray.tsx
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import clsx from "clsx";
|
||||||
|
import { PrimaryButton, SuccessButton } from "mattrixwv-components";
|
||||||
|
import { useCallback } from "react";
|
||||||
|
import { BsDashLg, BsPlusLg } from "react-icons/bs";
|
||||||
|
|
||||||
|
|
||||||
|
export default function SquareNumberArray({
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}:{
|
||||||
|
value: number[][];
|
||||||
|
onChange: (value: number[][]) => void;
|
||||||
|
}){
|
||||||
|
//TODO: Check for a square array
|
||||||
|
|
||||||
|
|
||||||
|
const decreaseArraySize = useCallback(() => {
|
||||||
|
if(value.length <= 2){
|
||||||
|
throw new Error("Cannot decrease grid size below 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
const newValue = value.slice(0, -1);
|
||||||
|
newValue.forEach((row) => {
|
||||||
|
row.pop();
|
||||||
|
});
|
||||||
|
onChange(newValue);
|
||||||
|
}, [ onChange, value ]);
|
||||||
|
|
||||||
|
const increaseArraySize = useCallback(() => {
|
||||||
|
if(value.length >= 10){
|
||||||
|
throw new Error("Cannot increase grid size above 10");
|
||||||
|
}
|
||||||
|
|
||||||
|
const newValue = [...value];
|
||||||
|
newValue.forEach((row) => {
|
||||||
|
row.push(0);
|
||||||
|
});
|
||||||
|
newValue.push(new Array(value.length + 1).fill(0) as number[]);
|
||||||
|
onChange(newValue);
|
||||||
|
}, [ onChange, value ]);
|
||||||
|
|
||||||
|
const updateValue = useCallback((rowIndex: number, cellIndex: number, newCellValue: number) => {
|
||||||
|
const newValue = [...value];
|
||||||
|
newValue[rowIndex][cellIndex] = newCellValue;
|
||||||
|
onChange(newValue);
|
||||||
|
}, [ onChange, value ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center gap-y-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="flex flex-row items-center justify-center gap-x-8"
|
||||||
|
>
|
||||||
|
<SuccessButton size="sm" shape="square" onClick={decreaseArraySize} disabled={value.length <= 2}><BsDashLg className="text-3xl text-white"/></SuccessButton>
|
||||||
|
<PrimaryButton size="sm" shape="square" onClick={increaseArraySize} disabled={value.length >= 10}><BsPlusLg className="text-3xl text-white"/></PrimaryButton>
|
||||||
|
</div>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
{
|
||||||
|
value.map((row, rowIndex) => (
|
||||||
|
<tr
|
||||||
|
key={`squareNumberArrayRow${rowIndex}`}
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
{
|
||||||
|
row.map((cell, cellIndex) => (
|
||||||
|
<td
|
||||||
|
key={`squareNumberArrayCell${rowIndex}${cellIndex}`}
|
||||||
|
className="w-8 h-8 border"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
className={clsx(
|
||||||
|
"text-center spinbox-hide text-xl w-12 h-10",
|
||||||
|
"[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
||||||
|
)}
|
||||||
|
value={cell}
|
||||||
|
onChange={(e) => updateValue(rowIndex, cellIndex, parseInt(e.target.value))}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
53
src/components/nav/CombinationLinks.tsx
Normal file
53
src/components/nav/CombinationLinks.tsx
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { combinationLinks } from "@/util/LinksUtil";
|
||||||
|
import { Popover, PopoverButton, PopoverPanel } from "@headlessui/react";
|
||||||
|
import { Link } from "@tanstack/react-router";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import { IoMdArrowDropdown } from "react-icons/io";
|
||||||
|
|
||||||
|
|
||||||
|
export default function CombinationLinks(){
|
||||||
|
return (
|
||||||
|
<Popover>
|
||||||
|
<PopoverButton
|
||||||
|
className={clsx(
|
||||||
|
"navBarLink outline-none",
|
||||||
|
"peer flex flex-row items-center justify-center"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
Combination
|
||||||
|
<IoMdArrowDropdown
|
||||||
|
className="mt-1"
|
||||||
|
size={22}
|
||||||
|
/>
|
||||||
|
</PopoverButton>
|
||||||
|
<PopoverPanel
|
||||||
|
anchor={{to: "top"}}
|
||||||
|
className={clsx(
|
||||||
|
"absolute z-50 w-(--button-width) rounded-lg py-2",
|
||||||
|
"flex flex-col items-start justify-center",
|
||||||
|
"bg-gray-600 dark:bg-neutral-700",
|
||||||
|
"shadow-md shadow-gray-950"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
className="w-full px-4 py-2 text-start"
|
||||||
|
to="/combination"
|
||||||
|
>
|
||||||
|
Overview
|
||||||
|
</Link>
|
||||||
|
<hr className="bg-neutral-500 h-0.5 w-full"/>
|
||||||
|
{
|
||||||
|
combinationLinks.map((link) => (
|
||||||
|
<Link
|
||||||
|
key={link.to}
|
||||||
|
className="w-full px-4 py-2 text-start"
|
||||||
|
to={link.to}
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
</Link>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</PopoverPanel>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
36
src/components/nav/DarkModeToggle.tsx
Normal file
36
src/components/nav/DarkModeToggle.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { useTheme } from "@/providers/ThemeProvider";
|
||||||
|
import { BsLightbulb, BsLightbulbFill } from "react-icons/bs";
|
||||||
|
|
||||||
|
|
||||||
|
export default function DarkModeToggle(){
|
||||||
|
const { theme, setTheme } = useTheme();
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="cursor-pointer">
|
||||||
|
<input
|
||||||
|
id="darkModeCheckbox"
|
||||||
|
type="checkbox"
|
||||||
|
className="peer hidden"
|
||||||
|
onChange={() => setTheme(theme === "dark" ? "light" : "dark")}
|
||||||
|
defaultChecked={theme === "dark"}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor="darkModeCheckbox"
|
||||||
|
className="block peer-checked:hidden cursor-pointer"
|
||||||
|
>
|
||||||
|
<BsLightbulbFill
|
||||||
|
size={20}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
htmlFor="darkModeCheckbox"
|
||||||
|
className="hidden peer-checked:block cursor-pointer"
|
||||||
|
>
|
||||||
|
<BsLightbulb
|
||||||
|
size={20}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
53
src/components/nav/MonoLinks.tsx
Normal file
53
src/components/nav/MonoLinks.tsx
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { monosubstitutionLinks } from "@/util/LinksUtil";
|
||||||
|
import { Popover, PopoverButton, PopoverPanel } from "@headlessui/react";
|
||||||
|
import { Link } from "@tanstack/react-router";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import { IoMdArrowDropdown } from "react-icons/io";
|
||||||
|
|
||||||
|
|
||||||
|
export default function MonoLinks(){
|
||||||
|
return (
|
||||||
|
<Popover>
|
||||||
|
<PopoverButton
|
||||||
|
className={clsx(
|
||||||
|
"navBarLink outline-none",
|
||||||
|
"peer flex flex-row items-center justify-center"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
Mono-Substitution
|
||||||
|
<IoMdArrowDropdown
|
||||||
|
className="mt-1"
|
||||||
|
size={22}
|
||||||
|
/>
|
||||||
|
</PopoverButton>
|
||||||
|
<PopoverPanel
|
||||||
|
anchor={{to: "top"}}
|
||||||
|
className={clsx(
|
||||||
|
"absolute z-50 w-(--button-width) rounded-lg py-1",
|
||||||
|
"flex flex-col items-start justify-center",
|
||||||
|
"bg-gray-600 dark:bg-neutral-700",
|
||||||
|
"shadow-md shadow-gray-950"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
className="w-full px-4 py-1 text-start"
|
||||||
|
to="/monosubstitution"
|
||||||
|
>
|
||||||
|
Overview
|
||||||
|
</Link>
|
||||||
|
<hr className="bg-neutral-500 h-0.5 my-1 w-full"/>
|
||||||
|
{
|
||||||
|
monosubstitutionLinks.map((link) => (
|
||||||
|
<Link
|
||||||
|
key={link.to}
|
||||||
|
className="w-full px-4 py-1 text-start"
|
||||||
|
to={link.to}
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
</Link>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</PopoverPanel>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
69
src/components/nav/NavBar.tsx
Normal file
69
src/components/nav/NavBar.tsx
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import cipherStreamIcon from "@/assets/cipherStreamIcon.svg";
|
||||||
|
import { PopoverGroup } from "@headlessui/react";
|
||||||
|
import { Link } from "@tanstack/react-router";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import { BsList } from "react-icons/bs";
|
||||||
|
import CombinationLinks from "./CombinationLinks";
|
||||||
|
import DarkModeToggle from "./DarkModeToggle";
|
||||||
|
import MonoLinks from "./MonoLinks";
|
||||||
|
import PolyLinks from "./PolyLinks";
|
||||||
|
import TutorialLink from "./TutorialLink";
|
||||||
|
|
||||||
|
|
||||||
|
export default function NavBar(){
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<nav
|
||||||
|
className={clsx(
|
||||||
|
"border-b-2 z-40",
|
||||||
|
"bg-gray-700 border-gray-600 text-white",
|
||||||
|
"dark:bg-zinc-900 dark:border-neutral-850"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="navContents"
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
to="/"
|
||||||
|
className="flex items-center space-x-3 rtl:space-x-reverse"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={cipherStreamIcon}
|
||||||
|
alt="Cipher Stream Icon"
|
||||||
|
width={30}
|
||||||
|
height={30}
|
||||||
|
fetchPriority="high"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="self-center text-2xl font-semibold whitespace-nowrap"
|
||||||
|
>
|
||||||
|
Cipher Stream
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
<div
|
||||||
|
className="peer md:hidden text-3xl"
|
||||||
|
>
|
||||||
|
<BsList/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={clsx(
|
||||||
|
"relative top-0 left-0 flex flex-row items-center rounded-lg gap-x-4",
|
||||||
|
"bg-gray-700 dark:bg-zinc-900"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<PopoverGroup
|
||||||
|
className="flex flex-row items-center justify-center gap-x-4"
|
||||||
|
>
|
||||||
|
<MonoLinks/>
|
||||||
|
<PolyLinks/>
|
||||||
|
<CombinationLinks/>
|
||||||
|
</PopoverGroup>
|
||||||
|
<TutorialLink/>
|
||||||
|
<DarkModeToggle/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span className="bg-white"/>
|
||||||
|
</nav>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
53
src/components/nav/PolyLinks.tsx
Normal file
53
src/components/nav/PolyLinks.tsx
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { polysubstitutionLinks } from "@/util/LinksUtil";
|
||||||
|
import { Popover, PopoverButton, PopoverPanel } from "@headlessui/react";
|
||||||
|
import { Link } from "@tanstack/react-router";
|
||||||
|
import clsx from "clsx";
|
||||||
|
import { IoMdArrowDropdown } from "react-icons/io";
|
||||||
|
|
||||||
|
|
||||||
|
export default function PolyLinks(){
|
||||||
|
return (
|
||||||
|
<Popover>
|
||||||
|
<PopoverButton
|
||||||
|
className={clsx(
|
||||||
|
"navBarLink outline-none",
|
||||||
|
"peer flex flex-row items-center justify-center"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
Poly-Substitution
|
||||||
|
<IoMdArrowDropdown
|
||||||
|
className="mt-1"
|
||||||
|
size={22}
|
||||||
|
/>
|
||||||
|
</PopoverButton>
|
||||||
|
<PopoverPanel
|
||||||
|
anchor={{to: "top"}}
|
||||||
|
className={clsx(
|
||||||
|
"absolute z-50 w-(--button-width) rounded-lg py-1",
|
||||||
|
"flex flex-col items-start justify-center",
|
||||||
|
"bg-gray-600 dark:bg-neutral-700",
|
||||||
|
"shadow-md shadow-gray-950"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
className="w-full px-4 py-1 text-start"
|
||||||
|
to="/polysubstitution"
|
||||||
|
>
|
||||||
|
Overview
|
||||||
|
</Link>
|
||||||
|
<hr className="bg-neutral-500 h-0.5 my-1 w-full"/>
|
||||||
|
{
|
||||||
|
polysubstitutionLinks.map((link) => (
|
||||||
|
<Link
|
||||||
|
key={link.to}
|
||||||
|
className="w-full px-4 py-1 text-start"
|
||||||
|
to={link.to}
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
</Link>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</PopoverPanel>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
30
src/components/nav/TutorialLink.tsx
Normal file
30
src/components/nav/TutorialLink.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { useTheme } from "@/providers/ThemeProvider";
|
||||||
|
import { Link } from "@tanstack/react-router";
|
||||||
|
import { BsQuestion } from "react-icons/bs";
|
||||||
|
import { Tooltip } from "react-tooltip";
|
||||||
|
|
||||||
|
|
||||||
|
export default function TutorialLink(){
|
||||||
|
const { theme } = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Link
|
||||||
|
id="tutorialLink"
|
||||||
|
to="/tutorial"
|
||||||
|
aria-label="Learn how to use Cipher Stream"
|
||||||
|
>
|
||||||
|
<BsQuestion
|
||||||
|
size={32}
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
<Tooltip
|
||||||
|
anchorSelect="#tutorialLink"
|
||||||
|
place="bottom-end"
|
||||||
|
variant={theme === "dark" ? "light" : "dark"}
|
||||||
|
>
|
||||||
|
Learn how to use Cipher Stream
|
||||||
|
</Tooltip>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
26
src/components/tutorials/EncodingTutorial.tsx
Normal file
26
src/components/tutorials/EncodingTutorial.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import EncodingDecodingButton from "../button/EncodingDecodingButton";
|
||||||
|
|
||||||
|
|
||||||
|
export default function EncodingTutorial(){
|
||||||
|
const [ encoding, setEncoding ] = useState(true);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<h3 className="text-center text-2xl">Encoding/Decoding Button</h3>
|
||||||
|
<p>
|
||||||
|
Click this button to toggle between the input being encoded or decoded.
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
className="mt-4">
|
||||||
|
<EncodingDecodingButton
|
||||||
|
encoding={encoding}
|
||||||
|
setEncoding={setEncoding}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
src/components/tutorials/InputTutorial.tsx
Normal file
25
src/components/tutorials/InputTutorial.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import InputMessage from "../input/InputMessage";
|
||||||
|
|
||||||
|
|
||||||
|
export default function InputTutorial(){
|
||||||
|
const [ inputValue, setInputValue ] = useState("");
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<h3 className="text-center text-2xl">Input</h3>
|
||||||
|
<p>
|
||||||
|
Enter text here to be encoded or decoded, depending on the Coding Button selection.
|
||||||
|
</p>
|
||||||
|
<div className="mt-4">
|
||||||
|
<InputMessage
|
||||||
|
value={inputValue}
|
||||||
|
onChange={setInputValue}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
src/components/tutorials/KeywordTutorial.tsx
Normal file
25
src/components/tutorials/KeywordTutorial.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import KeywordInput from "../input/KeywordInput";
|
||||||
|
|
||||||
|
|
||||||
|
export default function KeywordTutorial(){
|
||||||
|
const [ keyword, setKeyword ] = useState("");
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<h3 className="text-center text-2xl">Keyword</h3>
|
||||||
|
<p>
|
||||||
|
Enter a keyword used in the encryption.
|
||||||
|
</p>
|
||||||
|
<div className="mt-4">
|
||||||
|
<KeywordInput
|
||||||
|
value={keyword}
|
||||||
|
onChange={setKeyword}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
26
src/components/tutorials/NumberSelectorTutorial.tsx
Normal file
26
src/components/tutorials/NumberSelectorTutorial.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import NumberSelector from "../input/NumberSelector";
|
||||||
|
|
||||||
|
|
||||||
|
export default function NumberSelectorTutorial(){
|
||||||
|
const [ value, setValue ] = useState(0);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<h3 className="text-center text-2xl">Number Selector</h3>
|
||||||
|
<p>
|
||||||
|
Click the up and down arrows to select a number as a key.
|
||||||
|
</p>
|
||||||
|
<NumberSelector
|
||||||
|
label=""
|
||||||
|
value={value}
|
||||||
|
onChange={setValue}
|
||||||
|
minValue={0}
|
||||||
|
maxValue={100}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
src/components/tutorials/OutputTutorial.tsx
Normal file
25
src/components/tutorials/OutputTutorial.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import OutputMessage from "../input/OutputMessage";
|
||||||
|
|
||||||
|
|
||||||
|
export default function OutputTutorial(){
|
||||||
|
const [ outputValue, setOutputValue ] = useState("");
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<h3 className="text-center text-2xl">Output</h3>
|
||||||
|
<p>
|
||||||
|
This is where the result of the encoding or decoding of the message will appear.
|
||||||
|
</p>
|
||||||
|
<div className="mt-4">
|
||||||
|
<OutputMessage
|
||||||
|
value={outputValue}
|
||||||
|
onChange={setOutputValue}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
22
src/components/tutorials/SwitchTutorial.tsx
Normal file
22
src/components/tutorials/SwitchTutorial.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { PrimarySwitch } from "mattrixwv-components";
|
||||||
|
|
||||||
|
|
||||||
|
export default function SwitchTutorial(){
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex flex-col justify-center items-center"
|
||||||
|
>
|
||||||
|
<h3 className="text-center text-2xl">Preserve Element Switch</h3>
|
||||||
|
<p>
|
||||||
|
These switches indicate what types of elements in the inputs message will be preserved through the coding process.
|
||||||
|
<br/>
|
||||||
|
They are normally listed as Capitals, Symbols (punctuation and other special characters), and Whitespace.
|
||||||
|
<br/>
|
||||||
|
Remember: The more elements you leave in the cipher text the easier it will be to crack!
|
||||||
|
</p>
|
||||||
|
<div className="flex flex-row items-center justify-center mt-4">
|
||||||
|
<PrimarySwitch defaultChecked={true} size="md"><div className="pl-2">Preserve Element</div></PrimarySwitch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
40
src/hooks/combination/ADFGVXHooks.ts
Normal file
40
src/hooks/combination/ADFGVXHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import type { CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { ADFGVXProps } from "@/models/CombinationProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetADFGVXInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "ADFGVX", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/adfgvx`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeADFGVX(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "ADFGVX", "Encode" ],
|
||||||
|
scope: { id: "ADFGVX Encode" },
|
||||||
|
mutationFn: async (props: ADFGVXProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/adfgvx/encode`, props);
|
||||||
|
|
||||||
|
return response.data as ADFGVXProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeADFGVX(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "ADFGVX", "Decode" ],
|
||||||
|
scope: { id: "ADFGVX Decode" },
|
||||||
|
mutationFn: async (props: ADFGVXProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/adfgvx/decode`, props);
|
||||||
|
|
||||||
|
return response.data as ADFGVXProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/combination/ADFGXHooks.ts
Normal file
40
src/hooks/combination/ADFGXHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import type { CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { ADFGXProps } from "@/models/CombinationProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetADFGXInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "ADFGX", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/adfgx`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeADFGX(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "ADFGX", "Encode" ],
|
||||||
|
scope: { id: "ADFGX Encode" },
|
||||||
|
mutationFn: async (props: ADFGXProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/adfgx/encode`, props);
|
||||||
|
|
||||||
|
return response.data as ADFGXProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeADFGX(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "ADFGX", "Decode" ],
|
||||||
|
scope: { id: "ADFGX Decode" },
|
||||||
|
mutationFn: async (props: ADFGXProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/adfgx/decode`, props);
|
||||||
|
|
||||||
|
return response.data as ADFGXProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/monosubstitution/AffineHooks.ts
Normal file
40
src/hooks/monosubstitution/AffineHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { AffineProps } from "@/models/MonoSubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetAffineInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Affine", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/affine`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeAffine(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Affine", "Encode" ],
|
||||||
|
scope: { id: "Affine Encode" },
|
||||||
|
mutationFn: async (props: AffineProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/affine/encode`, props);
|
||||||
|
|
||||||
|
return response.data as AffineProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeAffine(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Affine", "Decode" ],
|
||||||
|
scope: { id: "Affine Decode" },
|
||||||
|
mutationFn: async (props: AffineProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/affine/decode`, props);
|
||||||
|
|
||||||
|
return response.data as AffineProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/monosubstitution/AtbashHooks.ts
Normal file
40
src/hooks/monosubstitution/AtbashHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import type { CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { AtbashProps } from "@/models/MonoSubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetAtbashInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Atbash", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/atbash`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeAtbash(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Atbash", "Encode" ],
|
||||||
|
scope: { id: "Atbash Encode" },
|
||||||
|
mutationFn: async (props: AtbashProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/atbash/encode`, props);
|
||||||
|
|
||||||
|
return response.data as AtbashProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeAtbash(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Atbash", "Decode" ],
|
||||||
|
scope: { id: "Atbash Decode" },
|
||||||
|
mutationFn: async (props: AtbashProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/atbash/decode`, props);
|
||||||
|
|
||||||
|
return response.data as AtbashProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/monosubstitution/AutokeyHooks.ts
Normal file
40
src/hooks/monosubstitution/AutokeyHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import type { CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { AutokeyProps } from "@/models/MonoSubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetAutokeyInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Autokey", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/autokey`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeAutokey(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Autokey", "Encode" ],
|
||||||
|
scope: { id: "Autokey Encode" },
|
||||||
|
mutationFn: async (props: AutokeyProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/autokey/encode`, props);
|
||||||
|
|
||||||
|
return response.data as AutokeyProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeAutokey(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Autokey", "Decode" ],
|
||||||
|
scope: { id: "Autokey Decode" },
|
||||||
|
mutationFn: async (props: AutokeyProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/autokey/decode`, props);
|
||||||
|
|
||||||
|
return response.data as AutokeyProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/monosubstitution/BaconianHooks.ts
Normal file
40
src/hooks/monosubstitution/BaconianHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { BaconianProps } from "@/models/MonoSubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetBaconianInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Baconian", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/baconian`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeBaconian(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Baconian", "Encode" ],
|
||||||
|
scope: { id: "Baconian Encode" },
|
||||||
|
mutationFn: async (props: BaconianProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/baconian/encode`, props);
|
||||||
|
|
||||||
|
return response.data as BaconianProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeBaconian(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Baconian", "Decode" ],
|
||||||
|
scope: { id: "Baconian Decode" },
|
||||||
|
mutationFn: async (props: BaconianProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/baconian/decode`, props);
|
||||||
|
|
||||||
|
return response.data as BaconianProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/monosubstitution/BaseXHooks.ts
Normal file
40
src/hooks/monosubstitution/BaseXHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { BaseXProps } from "@/models/MonoSubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetBaseXInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "BaseX", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/basex`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeBaseX(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "BaseX", "Encode" ],
|
||||||
|
scope: { id: "BaseX Encode" },
|
||||||
|
mutationFn: async (props: BaseXProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/basex/encode`, props);
|
||||||
|
|
||||||
|
return response.data as BaseXProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeBaseX(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "BaseX", "Decode" ],
|
||||||
|
scope: { id: "BaseX Decode" },
|
||||||
|
mutationFn: async (props: BaseXProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/basex/decode`, props);
|
||||||
|
|
||||||
|
return response.data as BaseXProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/monosubstitution/BeaufortHooks.ts
Normal file
40
src/hooks/monosubstitution/BeaufortHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { BeaufortProps } from "@/models/MonoSubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetBeaufortInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Beaufort", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/beaufort`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeBeaufort(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Beaufort", "Encode" ],
|
||||||
|
scope: { id: "Beaufort Encode" },
|
||||||
|
mutationFn: async (props: BeaufortProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/beaufort/encode`, props);
|
||||||
|
|
||||||
|
return response.data as BeaufortProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeBeaufort(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Beaufort", "Decode" ],
|
||||||
|
scope: { id: "Beaufort Decode" },
|
||||||
|
mutationFn: async (props: BeaufortProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/beaufort/decode`, props);
|
||||||
|
|
||||||
|
return response.data as BeaufortProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/monosubstitution/CaesarHooks.ts
Normal file
40
src/hooks/monosubstitution/CaesarHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { CaesarProps } from "@/models/MonoSubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetCaesarInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Caesar", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/caesar`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeCaesar(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Caesar", "Encode" ],
|
||||||
|
scope: { id: "Caesar Encode" },
|
||||||
|
mutationFn: async (props: CaesarProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/caesar/encode`, props);
|
||||||
|
|
||||||
|
return response.data as CaesarProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeCaesar(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Caesar", "Decode" ],
|
||||||
|
scope: { id: "Caesar Decode" },
|
||||||
|
mutationFn: async (props: CaesarProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/caesar/decode`, props);
|
||||||
|
|
||||||
|
return response.data as CaesarProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/monosubstitution/OneTimePadHooks.ts
Normal file
40
src/hooks/monosubstitution/OneTimePadHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { OneTimePadProps } from "@/models/MonoSubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetOneTimePadInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "OneTimePad", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/oneTimePad`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeOneTimePad(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "OneTimePad", "Encode" ],
|
||||||
|
scope: { id: "OneTimePad Encode" },
|
||||||
|
mutationFn: async (props: OneTimePadProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/oneTimePad/encode`, props);
|
||||||
|
|
||||||
|
return response.data as OneTimePadProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeOneTimePad(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "OneTimePad", "Decode" ],
|
||||||
|
scope: { id: "OneTimePad Decode" },
|
||||||
|
mutationFn: async (props: OneTimePadProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/oneTimePad/decode`, props);
|
||||||
|
|
||||||
|
return response.data as OneTimePadProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/monosubstitution/PortaHooks.ts
Normal file
40
src/hooks/monosubstitution/PortaHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { PortaProps } from "@/models/MonoSubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetPortaInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Porta", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/porta`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodePorta(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Porta", "Encode" ],
|
||||||
|
scope: { id: "Porta Encode" },
|
||||||
|
mutationFn: async (props: PortaProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/porta/encode`, props);
|
||||||
|
|
||||||
|
return response.data as PortaProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodePorta(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Porta", "Decode" ],
|
||||||
|
scope: { id: "Porta Decode" },
|
||||||
|
mutationFn: async (props: PortaProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/porta/decode`, props);
|
||||||
|
|
||||||
|
return response.data as PortaProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/monosubstitution/SubstitutionHooks.ts
Normal file
40
src/hooks/monosubstitution/SubstitutionHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { SubstitutionProps } from "@/models/MonoSubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetSubstitutionInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Substitution", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/substitution`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeSubstitution(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Substitution", "Encode" ],
|
||||||
|
scope: { id: "Substitution Encode" },
|
||||||
|
mutationFn: async (props: SubstitutionProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/substitution/encode`, props);
|
||||||
|
|
||||||
|
return response.data as SubstitutionProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeSubstitution(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Substitution", "Decode" ],
|
||||||
|
scope: { id: "Substitution Decode" },
|
||||||
|
mutationFn: async (props: SubstitutionProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/substitution/decode`, props);
|
||||||
|
|
||||||
|
return response.data as SubstitutionProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/monosubstitution/VigenereHooks.ts
Normal file
40
src/hooks/monosubstitution/VigenereHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { VigenereProps } from "@/models/MonoSubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetVigenereInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Vigenere", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/vigenere`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeVigenere(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Vigenere", "Encode" ],
|
||||||
|
scope: { id: "Vigenere Encode" },
|
||||||
|
mutationFn: async (props: VigenereProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/vigenere/encode`, props);
|
||||||
|
|
||||||
|
return response.data as VigenereProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeVigenere(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Vigenere", "Decode" ],
|
||||||
|
scope: { id: "Vigenere Decode" },
|
||||||
|
mutationFn: async (props: VigenereProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/vigenere/decode`, props);
|
||||||
|
|
||||||
|
return response.data as VigenereProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/polysubstitution/BifidHooks.ts
Normal file
40
src/hooks/polysubstitution/BifidHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { BifidProps } from "@/models/PolySubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetBifidInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Bifid", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/bifid`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeBifid(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Bifid", "Encode" ],
|
||||||
|
scope: { id: "Bifid Encode" },
|
||||||
|
mutationFn: async (props: BifidProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/bifid/encode`, props);
|
||||||
|
|
||||||
|
return response.data as BifidProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeBifid(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Bifid", "Decode" ],
|
||||||
|
scope: { id: "Bifid Decode" },
|
||||||
|
mutationFn: async (props: BifidProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/bifid/decode`, props);
|
||||||
|
|
||||||
|
return response.data as BifidProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/polysubstitution/ColumnarHooks.ts
Normal file
40
src/hooks/polysubstitution/ColumnarHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { ColumnarProps } from "@/models/PolySubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetColumnarInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Columnar", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/columnar`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeColumnar(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Columnar", "Encode" ],
|
||||||
|
scope: { id: "Columnar Encode" },
|
||||||
|
mutationFn: async (props: ColumnarProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/columnar/encode`, props);
|
||||||
|
|
||||||
|
return response.data as ColumnarProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeColumnar(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Columnar", "Decode" ],
|
||||||
|
scope: { id: "Columnar Decode" },
|
||||||
|
mutationFn: async (props: ColumnarProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/columnar/decode`, props);
|
||||||
|
|
||||||
|
return response.data as ColumnarProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/polysubstitution/HillHooks.ts
Normal file
40
src/hooks/polysubstitution/HillHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { HillProps } from "@/models/PolySubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetHillInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Hill", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/hill`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeHill(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Hill", "Encode" ],
|
||||||
|
scope: { id: "Hill Encode" },
|
||||||
|
mutationFn: async (props: HillProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/hill/encode`, props);
|
||||||
|
|
||||||
|
return response.data as HillProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeHill(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Hill", "Decode" ],
|
||||||
|
scope: { id: "Hill Decode" },
|
||||||
|
mutationFn: async (props: HillProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/hill/decode`, props);
|
||||||
|
|
||||||
|
return response.data as HillProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/polysubstitution/MorseHooks.ts
Normal file
40
src/hooks/polysubstitution/MorseHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { MorseProps } from "@/models/PolySubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetMorseInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Morse", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/morse`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeMorse(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Morse", "Encode" ],
|
||||||
|
scope: { id: "Morse Encode" },
|
||||||
|
mutationFn: async (props: MorseProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/morse/encode`, props);
|
||||||
|
|
||||||
|
return response.data as MorseProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeMorse(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Morse", "Decode" ],
|
||||||
|
scope: { id: "Morse Decode" },
|
||||||
|
mutationFn: async (props: MorseProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/morse/decode`, props);
|
||||||
|
|
||||||
|
return response.data as MorseProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/polysubstitution/PlayfairHooks.ts
Normal file
40
src/hooks/polysubstitution/PlayfairHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { PlayfairProps } from "@/models/PolySubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetPlayfairInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Playfair", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/playfair`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodePlayfair(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Playfair", "Encode" ],
|
||||||
|
scope: { id: "Playfair Encode" },
|
||||||
|
mutationFn: async (props: PlayfairProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/playfair/encode`, props);
|
||||||
|
|
||||||
|
return response.data as PlayfairProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodePlayfair(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Playfair", "Decode" ],
|
||||||
|
scope: { id: "Playfair Decode" },
|
||||||
|
mutationFn: async (props: PlayfairProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/playfair/decode`, props);
|
||||||
|
|
||||||
|
return response.data as PlayfairProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/polysubstitution/PolybiusHooks.ts
Normal file
40
src/hooks/polysubstitution/PolybiusHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { PolybiusProps } from "@/models/PolySubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetPolybiusInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Polybius", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/polybius`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodePolybius(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Polybius", "Encode" ],
|
||||||
|
scope: { id: "Polybius Encode" },
|
||||||
|
mutationFn: async (props: PolybiusProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/polybius/encode`, props);
|
||||||
|
|
||||||
|
return response.data as PolybiusProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodePolybius(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Polybius", "Decode" ],
|
||||||
|
scope: { id: "Polybius Decode" },
|
||||||
|
mutationFn: async (props: PolybiusProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/polybius/decode`, props);
|
||||||
|
|
||||||
|
return response.data as PolybiusProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/polysubstitution/RailFenceHooks.ts
Normal file
40
src/hooks/polysubstitution/RailFenceHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { RailFenceProps } from "@/models/PolySubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetRailFenceInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "RailFence", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/railFence`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeRailFence(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "RailFence", "Encode" ],
|
||||||
|
scope: { id: "RailFence Encode" },
|
||||||
|
mutationFn: async (props: RailFenceProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/railFence/encode`, props);
|
||||||
|
|
||||||
|
return response.data as RailFenceProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeRailFence(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "RailFence", "Decode" ],
|
||||||
|
scope: { id: "RailFence Decode" },
|
||||||
|
mutationFn: async (props: RailFenceProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/railFence/decode`, props);
|
||||||
|
|
||||||
|
return response.data as RailFenceProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
40
src/hooks/polysubstitution/TrifidHooks.ts
Normal file
40
src/hooks/polysubstitution/TrifidHooks.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { type CipherInfo } from "@/models/CipherInfo";
|
||||||
|
import type { TrifidProps } from "@/models/PolySubstitutionProps";
|
||||||
|
import api from "@/util/AxiosUtil";
|
||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
|
||||||
|
export function useGetTrifidInfo(){
|
||||||
|
return useQuery({
|
||||||
|
queryKey: [ "Trifid", "Info" ],
|
||||||
|
queryFn: async () => {
|
||||||
|
const response = await api.get(`${import.meta.env.VITE_API_URL}/trifid`);
|
||||||
|
|
||||||
|
return response.data as CipherInfo;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEncodeTrifid(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Trifid", "Encode" ],
|
||||||
|
scope: { id: "Trifid Encode" },
|
||||||
|
mutationFn: async (props: TrifidProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/trifid/encode`, props);
|
||||||
|
|
||||||
|
return response.data as TrifidProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDecodeTrifid(){
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: [ "Trifid", "Decode" ],
|
||||||
|
scope: { id: "Trifid Decode" },
|
||||||
|
mutationFn: async (props: TrifidProps) => {
|
||||||
|
const response = await api.post(`${import.meta.env.VITE_API_URL}/trifid/decode`, props);
|
||||||
|
|
||||||
|
return response.data as TrifidProps;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
96
src/index.css
Normal file
96
src/index.css
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
@custom-variant dark (&:where(.dark, .dark *));
|
||||||
|
|
||||||
|
@source "../node_modules/mattrixwv-components";
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--color-neutral-825: oklch(0.253 0 0);
|
||||||
|
--color-neutral-850: oklch(0.237 0 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
:root.dark {
|
||||||
|
--text-color: #FFFFFFDE;
|
||||||
|
--bg-color: var(--color-neutral-825);
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.light {
|
||||||
|
--text-color: #213547;
|
||||||
|
--bg-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
|
background-color: var(--bg-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#root {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover{
|
||||||
|
color: var(--color-blue-300);
|
||||||
|
}
|
||||||
|
|
||||||
|
a.active {
|
||||||
|
color: var(--color-blue-400);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
place-items: center;
|
||||||
|
min-width: 320px;
|
||||||
|
min-height: 100vh;
|
||||||
|
max-width: var(--breakpoint-2xl);
|
||||||
|
|
||||||
|
margin-inline: auto;
|
||||||
|
padding-top: 90px;
|
||||||
|
padding-inline: 1rem;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
button:disabled {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navContents {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
max-width: var(--breakpoint-2xl);
|
||||||
|
|
||||||
|
margin-inline: auto;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navBarLink {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navBarLink:hover {
|
||||||
|
color: var(--color-blue-300);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navBarLink:focus {
|
||||||
|
color: var(--color-blue-400);
|
||||||
|
}
|
||||||
38
src/main.tsx
Normal file
38
src/main.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||||
|
import { createRouter, RouterProvider } from "@tanstack/react-router";
|
||||||
|
import { ToasterProvider } from "mattrixwv-components";
|
||||||
|
import { StrictMode } from "react";
|
||||||
|
import { createRoot } from "react-dom/client";
|
||||||
|
import "./index.css";
|
||||||
|
import { ThemeProvider } from "./providers/components/ThemeProviderComponent.tsx";
|
||||||
|
import { routeTree } from "./routeTree.gen";
|
||||||
|
|
||||||
|
|
||||||
|
//Create a new router instance
|
||||||
|
const router = createRouter({ routeTree });
|
||||||
|
|
||||||
|
//Register the router instance for type safety
|
||||||
|
declare module "@tanstack/react-router" {
|
||||||
|
interface Register {
|
||||||
|
router: typeof router;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup react-query
|
||||||
|
const queryClient = new QueryClient();
|
||||||
|
|
||||||
|
|
||||||
|
createRoot(document.getElementById('root')!).render(
|
||||||
|
<StrictMode>
|
||||||
|
<QueryClientProvider client={queryClient}>
|
||||||
|
<ThemeProvider
|
||||||
|
defaultTheme="dark"
|
||||||
|
storageKey="vite-ui-theme"
|
||||||
|
>
|
||||||
|
<ToasterProvider>
|
||||||
|
<RouterProvider router={router}/>
|
||||||
|
</ToasterProvider>
|
||||||
|
</ThemeProvider>
|
||||||
|
</QueryClientProvider>
|
||||||
|
</StrictMode>
|
||||||
|
);
|
||||||
6
src/models/CipherInfo.ts
Normal file
6
src/models/CipherInfo.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export interface CipherInfo{
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
explanation: string[];
|
||||||
|
facts: string[];
|
||||||
|
}
|
||||||
21
src/models/CombinationProps.ts
Normal file
21
src/models/CombinationProps.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
export interface ADFGVXProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
squareKeyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ADFGXProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
squareKeyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
3
src/models/Errors.ts
Normal file
3
src/models/Errors.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export interface ResponseError {
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
103
src/models/MonoSubstitutionProps.ts
Normal file
103
src/models/MonoSubstitutionProps.ts
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
export interface AffineProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
key1: number;
|
||||||
|
key2: number;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AtbashProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AutokeyProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BaconianProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BaseXProps {
|
||||||
|
encoding: boolean;
|
||||||
|
base: number;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BeaufortProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CaesarProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
shiftAmount: number;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OneTimePadProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PortaProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SubstitutionProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VigenereProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
76
src/models/PolySubstitutionProps.ts
Normal file
76
src/models/PolySubstitutionProps.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
export interface BifidProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ColumnarProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HillProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
key: number[][];
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MorseProps {
|
||||||
|
encoding: boolean;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PlayfairProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PolybiusProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RailFenceProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
rails: number;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TrifidProps {
|
||||||
|
encoding: boolean;
|
||||||
|
preserveCapitals: boolean;
|
||||||
|
preserveWhitespace: boolean;
|
||||||
|
preserveSymbols: boolean;
|
||||||
|
keyword: string;
|
||||||
|
fill: string;
|
||||||
|
groupLength: number;
|
||||||
|
inputString: string;
|
||||||
|
outputString?: string;
|
||||||
|
}
|
||||||
34
src/providers/ThemeProvider.ts
Normal file
34
src/providers/ThemeProvider.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import type React from "react";
|
||||||
|
import { createContext, useContext } from "react";
|
||||||
|
|
||||||
|
|
||||||
|
export type Theme = "dark" | "light" | "system";
|
||||||
|
|
||||||
|
export type ThemeProviderProps = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
defaultTheme?: Theme;
|
||||||
|
storageKey?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type ThemeProviderState = {
|
||||||
|
theme: Theme;
|
||||||
|
setTheme: (theme: Theme) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: ThemeProviderState = {
|
||||||
|
theme: "system",
|
||||||
|
setTheme: () => null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
|
||||||
|
|
||||||
|
|
||||||
|
export const useTheme = () => {
|
||||||
|
const context = useContext(ThemeProviderContext);
|
||||||
|
|
||||||
|
if(context === undefined){
|
||||||
|
throw new Error("useTHeme must be used within a ThemeProvider");
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
17
src/providers/components/ErrorBoundary.tsx
Normal file
17
src/providers/components/ErrorBoundary.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import type { ErrorComponentProps } from "@tanstack/react-router";
|
||||||
|
|
||||||
|
|
||||||
|
export default function ErrorBoundary({
|
||||||
|
error,
|
||||||
|
info,
|
||||||
|
reset
|
||||||
|
}: ErrorComponentProps){
|
||||||
|
console.log("error", error, info, reset);
|
||||||
|
|
||||||
|
|
||||||
|
return(
|
||||||
|
<main>
|
||||||
|
Error Boundary
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
41
src/providers/components/ThemeProviderComponent.tsx
Normal file
41
src/providers/components/ThemeProviderComponent.tsx
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { useEffect, useMemo, useState } from "react";
|
||||||
|
import { ThemeProviderContext, type Theme, type ThemeProviderProps } from "../ThemeProvider";
|
||||||
|
|
||||||
|
|
||||||
|
export function ThemeProvider({
|
||||||
|
children,
|
||||||
|
defaultTheme = "system",
|
||||||
|
storageKey = "vite-ui-theme"
|
||||||
|
}: ThemeProviderProps){
|
||||||
|
const [ theme, setTheme ] = useState<Theme>(localStorage.getItem(storageKey) as Theme || defaultTheme);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const root = window.document.documentElement;
|
||||||
|
root.classList.remove("light", "dark");
|
||||||
|
|
||||||
|
if(theme === "system"){
|
||||||
|
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||||
|
root.classList.add(systemTheme);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
root.classList.add(theme);
|
||||||
|
}
|
||||||
|
}, [ theme ]);
|
||||||
|
|
||||||
|
|
||||||
|
const currentTheme = useMemo(() => ({
|
||||||
|
theme,
|
||||||
|
setTheme: (theme: Theme) => {
|
||||||
|
localStorage.setItem(storageKey, theme);
|
||||||
|
setTheme(theme);
|
||||||
|
}
|
||||||
|
}), [ theme, storageKey ]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ThemeProviderContext.Provider value={currentTheme}>
|
||||||
|
{children}
|
||||||
|
</ThemeProviderContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
608
src/routeTree.gen.ts
Normal file
608
src/routeTree.gen.ts
Normal file
@@ -0,0 +1,608 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
|
|
||||||
|
// This file was automatically generated by TanStack Router.
|
||||||
|
// You should NOT make any changes in this file as it will be overwritten.
|
||||||
|
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
||||||
|
|
||||||
|
import { Route as rootRouteImport } from './routes/__root'
|
||||||
|
import { Route as IndexRouteImport } from './routes/index'
|
||||||
|
import { Route as TutorialIndexRouteImport } from './routes/tutorial/index'
|
||||||
|
import { Route as PolysubstitutionIndexRouteImport } from './routes/polysubstitution/index'
|
||||||
|
import { Route as MonosubstitutionIndexRouteImport } from './routes/monosubstitution/index'
|
||||||
|
import { Route as CombinationIndexRouteImport } from './routes/combination/index'
|
||||||
|
import { Route as PolysubstitutionTrifidIndexRouteImport } from './routes/polysubstitution/trifid/index'
|
||||||
|
import { Route as PolysubstitutionRailfenceIndexRouteImport } from './routes/polysubstitution/railfence/index'
|
||||||
|
import { Route as PolysubstitutionPolybiusIndexRouteImport } from './routes/polysubstitution/polybius/index'
|
||||||
|
import { Route as PolysubstitutionPlayfairIndexRouteImport } from './routes/polysubstitution/playfair/index'
|
||||||
|
import { Route as PolysubstitutionMorseIndexRouteImport } from './routes/polysubstitution/morse/index'
|
||||||
|
import { Route as PolysubstitutionHillIndexRouteImport } from './routes/polysubstitution/hill/index'
|
||||||
|
import { Route as PolysubstitutionColumnarIndexRouteImport } from './routes/polysubstitution/columnar/index'
|
||||||
|
import { Route as PolysubstitutionBifidIndexRouteImport } from './routes/polysubstitution/bifid/index'
|
||||||
|
import { Route as MonosubstitutionVigenereIndexRouteImport } from './routes/monosubstitution/vigenere/index'
|
||||||
|
import { Route as MonosubstitutionSubstitutionIndexRouteImport } from './routes/monosubstitution/substitution/index'
|
||||||
|
import { Route as MonosubstitutionPortaIndexRouteImport } from './routes/monosubstitution/porta/index'
|
||||||
|
import { Route as MonosubstitutionOnetimepadIndexRouteImport } from './routes/monosubstitution/onetimepad/index'
|
||||||
|
import { Route as MonosubstitutionCaesarIndexRouteImport } from './routes/monosubstitution/caesar/index'
|
||||||
|
import { Route as MonosubstitutionBeaufortIndexRouteImport } from './routes/monosubstitution/beaufort/index'
|
||||||
|
import { Route as MonosubstitutionBasexIndexRouteImport } from './routes/monosubstitution/basex/index'
|
||||||
|
import { Route as MonosubstitutionBaconianIndexRouteImport } from './routes/monosubstitution/baconian/index'
|
||||||
|
import { Route as MonosubstitutionAutokeyIndexRouteImport } from './routes/monosubstitution/autokey/index'
|
||||||
|
import { Route as MonosubstitutionAtbashIndexRouteImport } from './routes/monosubstitution/atbash/index'
|
||||||
|
import { Route as MonosubstitutionAffineIndexRouteImport } from './routes/monosubstitution/affine/index'
|
||||||
|
import { Route as CombinationAdfgxIndexRouteImport } from './routes/combination/adfgx/index'
|
||||||
|
import { Route as CombinationAdfgvxIndexRouteImport } from './routes/combination/adfgvx/index'
|
||||||
|
|
||||||
|
const IndexRoute = IndexRouteImport.update({
|
||||||
|
id: '/',
|
||||||
|
path: '/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const TutorialIndexRoute = TutorialIndexRouteImport.update({
|
||||||
|
id: '/tutorial/',
|
||||||
|
path: '/tutorial/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const PolysubstitutionIndexRoute = PolysubstitutionIndexRouteImport.update({
|
||||||
|
id: '/polysubstitution/',
|
||||||
|
path: '/polysubstitution/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionIndexRoute = MonosubstitutionIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/',
|
||||||
|
path: '/monosubstitution/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const CombinationIndexRoute = CombinationIndexRouteImport.update({
|
||||||
|
id: '/combination/',
|
||||||
|
path: '/combination/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const PolysubstitutionTrifidIndexRoute =
|
||||||
|
PolysubstitutionTrifidIndexRouteImport.update({
|
||||||
|
id: '/polysubstitution/trifid/',
|
||||||
|
path: '/polysubstitution/trifid/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const PolysubstitutionRailfenceIndexRoute =
|
||||||
|
PolysubstitutionRailfenceIndexRouteImport.update({
|
||||||
|
id: '/polysubstitution/railfence/',
|
||||||
|
path: '/polysubstitution/railfence/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const PolysubstitutionPolybiusIndexRoute =
|
||||||
|
PolysubstitutionPolybiusIndexRouteImport.update({
|
||||||
|
id: '/polysubstitution/polybius/',
|
||||||
|
path: '/polysubstitution/polybius/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const PolysubstitutionPlayfairIndexRoute =
|
||||||
|
PolysubstitutionPlayfairIndexRouteImport.update({
|
||||||
|
id: '/polysubstitution/playfair/',
|
||||||
|
path: '/polysubstitution/playfair/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const PolysubstitutionMorseIndexRoute =
|
||||||
|
PolysubstitutionMorseIndexRouteImport.update({
|
||||||
|
id: '/polysubstitution/morse/',
|
||||||
|
path: '/polysubstitution/morse/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const PolysubstitutionHillIndexRoute =
|
||||||
|
PolysubstitutionHillIndexRouteImport.update({
|
||||||
|
id: '/polysubstitution/hill/',
|
||||||
|
path: '/polysubstitution/hill/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const PolysubstitutionColumnarIndexRoute =
|
||||||
|
PolysubstitutionColumnarIndexRouteImport.update({
|
||||||
|
id: '/polysubstitution/columnar/',
|
||||||
|
path: '/polysubstitution/columnar/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const PolysubstitutionBifidIndexRoute =
|
||||||
|
PolysubstitutionBifidIndexRouteImport.update({
|
||||||
|
id: '/polysubstitution/bifid/',
|
||||||
|
path: '/polysubstitution/bifid/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionVigenereIndexRoute =
|
||||||
|
MonosubstitutionVigenereIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/vigenere/',
|
||||||
|
path: '/monosubstitution/vigenere/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionSubstitutionIndexRoute =
|
||||||
|
MonosubstitutionSubstitutionIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/substitution/',
|
||||||
|
path: '/monosubstitution/substitution/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionPortaIndexRoute =
|
||||||
|
MonosubstitutionPortaIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/porta/',
|
||||||
|
path: '/monosubstitution/porta/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionOnetimepadIndexRoute =
|
||||||
|
MonosubstitutionOnetimepadIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/onetimepad/',
|
||||||
|
path: '/monosubstitution/onetimepad/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionCaesarIndexRoute =
|
||||||
|
MonosubstitutionCaesarIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/caesar/',
|
||||||
|
path: '/monosubstitution/caesar/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionBeaufortIndexRoute =
|
||||||
|
MonosubstitutionBeaufortIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/beaufort/',
|
||||||
|
path: '/monosubstitution/beaufort/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionBasexIndexRoute =
|
||||||
|
MonosubstitutionBasexIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/basex/',
|
||||||
|
path: '/monosubstitution/basex/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionBaconianIndexRoute =
|
||||||
|
MonosubstitutionBaconianIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/baconian/',
|
||||||
|
path: '/monosubstitution/baconian/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionAutokeyIndexRoute =
|
||||||
|
MonosubstitutionAutokeyIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/autokey/',
|
||||||
|
path: '/monosubstitution/autokey/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionAtbashIndexRoute =
|
||||||
|
MonosubstitutionAtbashIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/atbash/',
|
||||||
|
path: '/monosubstitution/atbash/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const MonosubstitutionAffineIndexRoute =
|
||||||
|
MonosubstitutionAffineIndexRouteImport.update({
|
||||||
|
id: '/monosubstitution/affine/',
|
||||||
|
path: '/monosubstitution/affine/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const CombinationAdfgxIndexRoute = CombinationAdfgxIndexRouteImport.update({
|
||||||
|
id: '/combination/adfgx/',
|
||||||
|
path: '/combination/adfgx/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
const CombinationAdfgvxIndexRoute = CombinationAdfgvxIndexRouteImport.update({
|
||||||
|
id: '/combination/adfgvx/',
|
||||||
|
path: '/combination/adfgvx/',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
|
|
||||||
|
export interface FileRoutesByFullPath {
|
||||||
|
'/': typeof IndexRoute
|
||||||
|
'/combination': typeof CombinationIndexRoute
|
||||||
|
'/monosubstitution': typeof MonosubstitutionIndexRoute
|
||||||
|
'/polysubstitution': typeof PolysubstitutionIndexRoute
|
||||||
|
'/tutorial': typeof TutorialIndexRoute
|
||||||
|
'/combination/adfgvx': typeof CombinationAdfgvxIndexRoute
|
||||||
|
'/combination/adfgx': typeof CombinationAdfgxIndexRoute
|
||||||
|
'/monosubstitution/affine': typeof MonosubstitutionAffineIndexRoute
|
||||||
|
'/monosubstitution/atbash': typeof MonosubstitutionAtbashIndexRoute
|
||||||
|
'/monosubstitution/autokey': typeof MonosubstitutionAutokeyIndexRoute
|
||||||
|
'/monosubstitution/baconian': typeof MonosubstitutionBaconianIndexRoute
|
||||||
|
'/monosubstitution/basex': typeof MonosubstitutionBasexIndexRoute
|
||||||
|
'/monosubstitution/beaufort': typeof MonosubstitutionBeaufortIndexRoute
|
||||||
|
'/monosubstitution/caesar': typeof MonosubstitutionCaesarIndexRoute
|
||||||
|
'/monosubstitution/onetimepad': typeof MonosubstitutionOnetimepadIndexRoute
|
||||||
|
'/monosubstitution/porta': typeof MonosubstitutionPortaIndexRoute
|
||||||
|
'/monosubstitution/substitution': typeof MonosubstitutionSubstitutionIndexRoute
|
||||||
|
'/monosubstitution/vigenere': typeof MonosubstitutionVigenereIndexRoute
|
||||||
|
'/polysubstitution/bifid': typeof PolysubstitutionBifidIndexRoute
|
||||||
|
'/polysubstitution/columnar': typeof PolysubstitutionColumnarIndexRoute
|
||||||
|
'/polysubstitution/hill': typeof PolysubstitutionHillIndexRoute
|
||||||
|
'/polysubstitution/morse': typeof PolysubstitutionMorseIndexRoute
|
||||||
|
'/polysubstitution/playfair': typeof PolysubstitutionPlayfairIndexRoute
|
||||||
|
'/polysubstitution/polybius': typeof PolysubstitutionPolybiusIndexRoute
|
||||||
|
'/polysubstitution/railfence': typeof PolysubstitutionRailfenceIndexRoute
|
||||||
|
'/polysubstitution/trifid': typeof PolysubstitutionTrifidIndexRoute
|
||||||
|
}
|
||||||
|
export interface FileRoutesByTo {
|
||||||
|
'/': typeof IndexRoute
|
||||||
|
'/combination': typeof CombinationIndexRoute
|
||||||
|
'/monosubstitution': typeof MonosubstitutionIndexRoute
|
||||||
|
'/polysubstitution': typeof PolysubstitutionIndexRoute
|
||||||
|
'/tutorial': typeof TutorialIndexRoute
|
||||||
|
'/combination/adfgvx': typeof CombinationAdfgvxIndexRoute
|
||||||
|
'/combination/adfgx': typeof CombinationAdfgxIndexRoute
|
||||||
|
'/monosubstitution/affine': typeof MonosubstitutionAffineIndexRoute
|
||||||
|
'/monosubstitution/atbash': typeof MonosubstitutionAtbashIndexRoute
|
||||||
|
'/monosubstitution/autokey': typeof MonosubstitutionAutokeyIndexRoute
|
||||||
|
'/monosubstitution/baconian': typeof MonosubstitutionBaconianIndexRoute
|
||||||
|
'/monosubstitution/basex': typeof MonosubstitutionBasexIndexRoute
|
||||||
|
'/monosubstitution/beaufort': typeof MonosubstitutionBeaufortIndexRoute
|
||||||
|
'/monosubstitution/caesar': typeof MonosubstitutionCaesarIndexRoute
|
||||||
|
'/monosubstitution/onetimepad': typeof MonosubstitutionOnetimepadIndexRoute
|
||||||
|
'/monosubstitution/porta': typeof MonosubstitutionPortaIndexRoute
|
||||||
|
'/monosubstitution/substitution': typeof MonosubstitutionSubstitutionIndexRoute
|
||||||
|
'/monosubstitution/vigenere': typeof MonosubstitutionVigenereIndexRoute
|
||||||
|
'/polysubstitution/bifid': typeof PolysubstitutionBifidIndexRoute
|
||||||
|
'/polysubstitution/columnar': typeof PolysubstitutionColumnarIndexRoute
|
||||||
|
'/polysubstitution/hill': typeof PolysubstitutionHillIndexRoute
|
||||||
|
'/polysubstitution/morse': typeof PolysubstitutionMorseIndexRoute
|
||||||
|
'/polysubstitution/playfair': typeof PolysubstitutionPlayfairIndexRoute
|
||||||
|
'/polysubstitution/polybius': typeof PolysubstitutionPolybiusIndexRoute
|
||||||
|
'/polysubstitution/railfence': typeof PolysubstitutionRailfenceIndexRoute
|
||||||
|
'/polysubstitution/trifid': typeof PolysubstitutionTrifidIndexRoute
|
||||||
|
}
|
||||||
|
export interface FileRoutesById {
|
||||||
|
__root__: typeof rootRouteImport
|
||||||
|
'/': typeof IndexRoute
|
||||||
|
'/combination/': typeof CombinationIndexRoute
|
||||||
|
'/monosubstitution/': typeof MonosubstitutionIndexRoute
|
||||||
|
'/polysubstitution/': typeof PolysubstitutionIndexRoute
|
||||||
|
'/tutorial/': typeof TutorialIndexRoute
|
||||||
|
'/combination/adfgvx/': typeof CombinationAdfgvxIndexRoute
|
||||||
|
'/combination/adfgx/': typeof CombinationAdfgxIndexRoute
|
||||||
|
'/monosubstitution/affine/': typeof MonosubstitutionAffineIndexRoute
|
||||||
|
'/monosubstitution/atbash/': typeof MonosubstitutionAtbashIndexRoute
|
||||||
|
'/monosubstitution/autokey/': typeof MonosubstitutionAutokeyIndexRoute
|
||||||
|
'/monosubstitution/baconian/': typeof MonosubstitutionBaconianIndexRoute
|
||||||
|
'/monosubstitution/basex/': typeof MonosubstitutionBasexIndexRoute
|
||||||
|
'/monosubstitution/beaufort/': typeof MonosubstitutionBeaufortIndexRoute
|
||||||
|
'/monosubstitution/caesar/': typeof MonosubstitutionCaesarIndexRoute
|
||||||
|
'/monosubstitution/onetimepad/': typeof MonosubstitutionOnetimepadIndexRoute
|
||||||
|
'/monosubstitution/porta/': typeof MonosubstitutionPortaIndexRoute
|
||||||
|
'/monosubstitution/substitution/': typeof MonosubstitutionSubstitutionIndexRoute
|
||||||
|
'/monosubstitution/vigenere/': typeof MonosubstitutionVigenereIndexRoute
|
||||||
|
'/polysubstitution/bifid/': typeof PolysubstitutionBifidIndexRoute
|
||||||
|
'/polysubstitution/columnar/': typeof PolysubstitutionColumnarIndexRoute
|
||||||
|
'/polysubstitution/hill/': typeof PolysubstitutionHillIndexRoute
|
||||||
|
'/polysubstitution/morse/': typeof PolysubstitutionMorseIndexRoute
|
||||||
|
'/polysubstitution/playfair/': typeof PolysubstitutionPlayfairIndexRoute
|
||||||
|
'/polysubstitution/polybius/': typeof PolysubstitutionPolybiusIndexRoute
|
||||||
|
'/polysubstitution/railfence/': typeof PolysubstitutionRailfenceIndexRoute
|
||||||
|
'/polysubstitution/trifid/': typeof PolysubstitutionTrifidIndexRoute
|
||||||
|
}
|
||||||
|
export interface FileRouteTypes {
|
||||||
|
fileRoutesByFullPath: FileRoutesByFullPath
|
||||||
|
fullPaths:
|
||||||
|
| '/'
|
||||||
|
| '/combination'
|
||||||
|
| '/monosubstitution'
|
||||||
|
| '/polysubstitution'
|
||||||
|
| '/tutorial'
|
||||||
|
| '/combination/adfgvx'
|
||||||
|
| '/combination/adfgx'
|
||||||
|
| '/monosubstitution/affine'
|
||||||
|
| '/monosubstitution/atbash'
|
||||||
|
| '/monosubstitution/autokey'
|
||||||
|
| '/monosubstitution/baconian'
|
||||||
|
| '/monosubstitution/basex'
|
||||||
|
| '/monosubstitution/beaufort'
|
||||||
|
| '/monosubstitution/caesar'
|
||||||
|
| '/monosubstitution/onetimepad'
|
||||||
|
| '/monosubstitution/porta'
|
||||||
|
| '/monosubstitution/substitution'
|
||||||
|
| '/monosubstitution/vigenere'
|
||||||
|
| '/polysubstitution/bifid'
|
||||||
|
| '/polysubstitution/columnar'
|
||||||
|
| '/polysubstitution/hill'
|
||||||
|
| '/polysubstitution/morse'
|
||||||
|
| '/polysubstitution/playfair'
|
||||||
|
| '/polysubstitution/polybius'
|
||||||
|
| '/polysubstitution/railfence'
|
||||||
|
| '/polysubstitution/trifid'
|
||||||
|
fileRoutesByTo: FileRoutesByTo
|
||||||
|
to:
|
||||||
|
| '/'
|
||||||
|
| '/combination'
|
||||||
|
| '/monosubstitution'
|
||||||
|
| '/polysubstitution'
|
||||||
|
| '/tutorial'
|
||||||
|
| '/combination/adfgvx'
|
||||||
|
| '/combination/adfgx'
|
||||||
|
| '/monosubstitution/affine'
|
||||||
|
| '/monosubstitution/atbash'
|
||||||
|
| '/monosubstitution/autokey'
|
||||||
|
| '/monosubstitution/baconian'
|
||||||
|
| '/monosubstitution/basex'
|
||||||
|
| '/monosubstitution/beaufort'
|
||||||
|
| '/monosubstitution/caesar'
|
||||||
|
| '/monosubstitution/onetimepad'
|
||||||
|
| '/monosubstitution/porta'
|
||||||
|
| '/monosubstitution/substitution'
|
||||||
|
| '/monosubstitution/vigenere'
|
||||||
|
| '/polysubstitution/bifid'
|
||||||
|
| '/polysubstitution/columnar'
|
||||||
|
| '/polysubstitution/hill'
|
||||||
|
| '/polysubstitution/morse'
|
||||||
|
| '/polysubstitution/playfair'
|
||||||
|
| '/polysubstitution/polybius'
|
||||||
|
| '/polysubstitution/railfence'
|
||||||
|
| '/polysubstitution/trifid'
|
||||||
|
id:
|
||||||
|
| '__root__'
|
||||||
|
| '/'
|
||||||
|
| '/combination/'
|
||||||
|
| '/monosubstitution/'
|
||||||
|
| '/polysubstitution/'
|
||||||
|
| '/tutorial/'
|
||||||
|
| '/combination/adfgvx/'
|
||||||
|
| '/combination/adfgx/'
|
||||||
|
| '/monosubstitution/affine/'
|
||||||
|
| '/monosubstitution/atbash/'
|
||||||
|
| '/monosubstitution/autokey/'
|
||||||
|
| '/monosubstitution/baconian/'
|
||||||
|
| '/monosubstitution/basex/'
|
||||||
|
| '/monosubstitution/beaufort/'
|
||||||
|
| '/monosubstitution/caesar/'
|
||||||
|
| '/monosubstitution/onetimepad/'
|
||||||
|
| '/monosubstitution/porta/'
|
||||||
|
| '/monosubstitution/substitution/'
|
||||||
|
| '/monosubstitution/vigenere/'
|
||||||
|
| '/polysubstitution/bifid/'
|
||||||
|
| '/polysubstitution/columnar/'
|
||||||
|
| '/polysubstitution/hill/'
|
||||||
|
| '/polysubstitution/morse/'
|
||||||
|
| '/polysubstitution/playfair/'
|
||||||
|
| '/polysubstitution/polybius/'
|
||||||
|
| '/polysubstitution/railfence/'
|
||||||
|
| '/polysubstitution/trifid/'
|
||||||
|
fileRoutesById: FileRoutesById
|
||||||
|
}
|
||||||
|
export interface RootRouteChildren {
|
||||||
|
IndexRoute: typeof IndexRoute
|
||||||
|
CombinationIndexRoute: typeof CombinationIndexRoute
|
||||||
|
MonosubstitutionIndexRoute: typeof MonosubstitutionIndexRoute
|
||||||
|
PolysubstitutionIndexRoute: typeof PolysubstitutionIndexRoute
|
||||||
|
TutorialIndexRoute: typeof TutorialIndexRoute
|
||||||
|
CombinationAdfgvxIndexRoute: typeof CombinationAdfgvxIndexRoute
|
||||||
|
CombinationAdfgxIndexRoute: typeof CombinationAdfgxIndexRoute
|
||||||
|
MonosubstitutionAffineIndexRoute: typeof MonosubstitutionAffineIndexRoute
|
||||||
|
MonosubstitutionAtbashIndexRoute: typeof MonosubstitutionAtbashIndexRoute
|
||||||
|
MonosubstitutionAutokeyIndexRoute: typeof MonosubstitutionAutokeyIndexRoute
|
||||||
|
MonosubstitutionBaconianIndexRoute: typeof MonosubstitutionBaconianIndexRoute
|
||||||
|
MonosubstitutionBasexIndexRoute: typeof MonosubstitutionBasexIndexRoute
|
||||||
|
MonosubstitutionBeaufortIndexRoute: typeof MonosubstitutionBeaufortIndexRoute
|
||||||
|
MonosubstitutionCaesarIndexRoute: typeof MonosubstitutionCaesarIndexRoute
|
||||||
|
MonosubstitutionOnetimepadIndexRoute: typeof MonosubstitutionOnetimepadIndexRoute
|
||||||
|
MonosubstitutionPortaIndexRoute: typeof MonosubstitutionPortaIndexRoute
|
||||||
|
MonosubstitutionSubstitutionIndexRoute: typeof MonosubstitutionSubstitutionIndexRoute
|
||||||
|
MonosubstitutionVigenereIndexRoute: typeof MonosubstitutionVigenereIndexRoute
|
||||||
|
PolysubstitutionBifidIndexRoute: typeof PolysubstitutionBifidIndexRoute
|
||||||
|
PolysubstitutionColumnarIndexRoute: typeof PolysubstitutionColumnarIndexRoute
|
||||||
|
PolysubstitutionHillIndexRoute: typeof PolysubstitutionHillIndexRoute
|
||||||
|
PolysubstitutionMorseIndexRoute: typeof PolysubstitutionMorseIndexRoute
|
||||||
|
PolysubstitutionPlayfairIndexRoute: typeof PolysubstitutionPlayfairIndexRoute
|
||||||
|
PolysubstitutionPolybiusIndexRoute: typeof PolysubstitutionPolybiusIndexRoute
|
||||||
|
PolysubstitutionRailfenceIndexRoute: typeof PolysubstitutionRailfenceIndexRoute
|
||||||
|
PolysubstitutionTrifidIndexRoute: typeof PolysubstitutionTrifidIndexRoute
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '@tanstack/react-router' {
|
||||||
|
interface FileRoutesByPath {
|
||||||
|
'/': {
|
||||||
|
id: '/'
|
||||||
|
path: '/'
|
||||||
|
fullPath: '/'
|
||||||
|
preLoaderRoute: typeof IndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/tutorial/': {
|
||||||
|
id: '/tutorial/'
|
||||||
|
path: '/tutorial'
|
||||||
|
fullPath: '/tutorial'
|
||||||
|
preLoaderRoute: typeof TutorialIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/polysubstitution/': {
|
||||||
|
id: '/polysubstitution/'
|
||||||
|
path: '/polysubstitution'
|
||||||
|
fullPath: '/polysubstitution'
|
||||||
|
preLoaderRoute: typeof PolysubstitutionIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/': {
|
||||||
|
id: '/monosubstitution/'
|
||||||
|
path: '/monosubstitution'
|
||||||
|
fullPath: '/monosubstitution'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/combination/': {
|
||||||
|
id: '/combination/'
|
||||||
|
path: '/combination'
|
||||||
|
fullPath: '/combination'
|
||||||
|
preLoaderRoute: typeof CombinationIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/polysubstitution/trifid/': {
|
||||||
|
id: '/polysubstitution/trifid/'
|
||||||
|
path: '/polysubstitution/trifid'
|
||||||
|
fullPath: '/polysubstitution/trifid'
|
||||||
|
preLoaderRoute: typeof PolysubstitutionTrifidIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/polysubstitution/railfence/': {
|
||||||
|
id: '/polysubstitution/railfence/'
|
||||||
|
path: '/polysubstitution/railfence'
|
||||||
|
fullPath: '/polysubstitution/railfence'
|
||||||
|
preLoaderRoute: typeof PolysubstitutionRailfenceIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/polysubstitution/polybius/': {
|
||||||
|
id: '/polysubstitution/polybius/'
|
||||||
|
path: '/polysubstitution/polybius'
|
||||||
|
fullPath: '/polysubstitution/polybius'
|
||||||
|
preLoaderRoute: typeof PolysubstitutionPolybiusIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/polysubstitution/playfair/': {
|
||||||
|
id: '/polysubstitution/playfair/'
|
||||||
|
path: '/polysubstitution/playfair'
|
||||||
|
fullPath: '/polysubstitution/playfair'
|
||||||
|
preLoaderRoute: typeof PolysubstitutionPlayfairIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/polysubstitution/morse/': {
|
||||||
|
id: '/polysubstitution/morse/'
|
||||||
|
path: '/polysubstitution/morse'
|
||||||
|
fullPath: '/polysubstitution/morse'
|
||||||
|
preLoaderRoute: typeof PolysubstitutionMorseIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/polysubstitution/hill/': {
|
||||||
|
id: '/polysubstitution/hill/'
|
||||||
|
path: '/polysubstitution/hill'
|
||||||
|
fullPath: '/polysubstitution/hill'
|
||||||
|
preLoaderRoute: typeof PolysubstitutionHillIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/polysubstitution/columnar/': {
|
||||||
|
id: '/polysubstitution/columnar/'
|
||||||
|
path: '/polysubstitution/columnar'
|
||||||
|
fullPath: '/polysubstitution/columnar'
|
||||||
|
preLoaderRoute: typeof PolysubstitutionColumnarIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/polysubstitution/bifid/': {
|
||||||
|
id: '/polysubstitution/bifid/'
|
||||||
|
path: '/polysubstitution/bifid'
|
||||||
|
fullPath: '/polysubstitution/bifid'
|
||||||
|
preLoaderRoute: typeof PolysubstitutionBifidIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/vigenere/': {
|
||||||
|
id: '/monosubstitution/vigenere/'
|
||||||
|
path: '/monosubstitution/vigenere'
|
||||||
|
fullPath: '/monosubstitution/vigenere'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionVigenereIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/substitution/': {
|
||||||
|
id: '/monosubstitution/substitution/'
|
||||||
|
path: '/monosubstitution/substitution'
|
||||||
|
fullPath: '/monosubstitution/substitution'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionSubstitutionIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/porta/': {
|
||||||
|
id: '/monosubstitution/porta/'
|
||||||
|
path: '/monosubstitution/porta'
|
||||||
|
fullPath: '/monosubstitution/porta'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionPortaIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/onetimepad/': {
|
||||||
|
id: '/monosubstitution/onetimepad/'
|
||||||
|
path: '/monosubstitution/onetimepad'
|
||||||
|
fullPath: '/monosubstitution/onetimepad'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionOnetimepadIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/caesar/': {
|
||||||
|
id: '/monosubstitution/caesar/'
|
||||||
|
path: '/monosubstitution/caesar'
|
||||||
|
fullPath: '/monosubstitution/caesar'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionCaesarIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/beaufort/': {
|
||||||
|
id: '/monosubstitution/beaufort/'
|
||||||
|
path: '/monosubstitution/beaufort'
|
||||||
|
fullPath: '/monosubstitution/beaufort'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionBeaufortIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/basex/': {
|
||||||
|
id: '/monosubstitution/basex/'
|
||||||
|
path: '/monosubstitution/basex'
|
||||||
|
fullPath: '/monosubstitution/basex'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionBasexIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/baconian/': {
|
||||||
|
id: '/monosubstitution/baconian/'
|
||||||
|
path: '/monosubstitution/baconian'
|
||||||
|
fullPath: '/monosubstitution/baconian'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionBaconianIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/autokey/': {
|
||||||
|
id: '/monosubstitution/autokey/'
|
||||||
|
path: '/monosubstitution/autokey'
|
||||||
|
fullPath: '/monosubstitution/autokey'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionAutokeyIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/atbash/': {
|
||||||
|
id: '/monosubstitution/atbash/'
|
||||||
|
path: '/monosubstitution/atbash'
|
||||||
|
fullPath: '/monosubstitution/atbash'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionAtbashIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/monosubstitution/affine/': {
|
||||||
|
id: '/monosubstitution/affine/'
|
||||||
|
path: '/monosubstitution/affine'
|
||||||
|
fullPath: '/monosubstitution/affine'
|
||||||
|
preLoaderRoute: typeof MonosubstitutionAffineIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/combination/adfgx/': {
|
||||||
|
id: '/combination/adfgx/'
|
||||||
|
path: '/combination/adfgx'
|
||||||
|
fullPath: '/combination/adfgx'
|
||||||
|
preLoaderRoute: typeof CombinationAdfgxIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
'/combination/adfgvx/': {
|
||||||
|
id: '/combination/adfgvx/'
|
||||||
|
path: '/combination/adfgvx'
|
||||||
|
fullPath: '/combination/adfgvx'
|
||||||
|
preLoaderRoute: typeof CombinationAdfgvxIndexRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootRouteChildren: RootRouteChildren = {
|
||||||
|
IndexRoute: IndexRoute,
|
||||||
|
CombinationIndexRoute: CombinationIndexRoute,
|
||||||
|
MonosubstitutionIndexRoute: MonosubstitutionIndexRoute,
|
||||||
|
PolysubstitutionIndexRoute: PolysubstitutionIndexRoute,
|
||||||
|
TutorialIndexRoute: TutorialIndexRoute,
|
||||||
|
CombinationAdfgvxIndexRoute: CombinationAdfgvxIndexRoute,
|
||||||
|
CombinationAdfgxIndexRoute: CombinationAdfgxIndexRoute,
|
||||||
|
MonosubstitutionAffineIndexRoute: MonosubstitutionAffineIndexRoute,
|
||||||
|
MonosubstitutionAtbashIndexRoute: MonosubstitutionAtbashIndexRoute,
|
||||||
|
MonosubstitutionAutokeyIndexRoute: MonosubstitutionAutokeyIndexRoute,
|
||||||
|
MonosubstitutionBaconianIndexRoute: MonosubstitutionBaconianIndexRoute,
|
||||||
|
MonosubstitutionBasexIndexRoute: MonosubstitutionBasexIndexRoute,
|
||||||
|
MonosubstitutionBeaufortIndexRoute: MonosubstitutionBeaufortIndexRoute,
|
||||||
|
MonosubstitutionCaesarIndexRoute: MonosubstitutionCaesarIndexRoute,
|
||||||
|
MonosubstitutionOnetimepadIndexRoute: MonosubstitutionOnetimepadIndexRoute,
|
||||||
|
MonosubstitutionPortaIndexRoute: MonosubstitutionPortaIndexRoute,
|
||||||
|
MonosubstitutionSubstitutionIndexRoute:
|
||||||
|
MonosubstitutionSubstitutionIndexRoute,
|
||||||
|
MonosubstitutionVigenereIndexRoute: MonosubstitutionVigenereIndexRoute,
|
||||||
|
PolysubstitutionBifidIndexRoute: PolysubstitutionBifidIndexRoute,
|
||||||
|
PolysubstitutionColumnarIndexRoute: PolysubstitutionColumnarIndexRoute,
|
||||||
|
PolysubstitutionHillIndexRoute: PolysubstitutionHillIndexRoute,
|
||||||
|
PolysubstitutionMorseIndexRoute: PolysubstitutionMorseIndexRoute,
|
||||||
|
PolysubstitutionPlayfairIndexRoute: PolysubstitutionPlayfairIndexRoute,
|
||||||
|
PolysubstitutionPolybiusIndexRoute: PolysubstitutionPolybiusIndexRoute,
|
||||||
|
PolysubstitutionRailfenceIndexRoute: PolysubstitutionRailfenceIndexRoute,
|
||||||
|
PolysubstitutionTrifidIndexRoute: PolysubstitutionTrifidIndexRoute,
|
||||||
|
}
|
||||||
|
export const routeTree = rootRouteImport
|
||||||
|
._addFileChildren(rootRouteChildren)
|
||||||
|
._addFileTypes<FileRouteTypes>()
|
||||||
16
src/routes/__root.tsx
Normal file
16
src/routes/__root.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import NavBar from "@/components/nav/NavBar";
|
||||||
|
import ErrorBoundary from "@/providers/components/ErrorBoundary";
|
||||||
|
import { createRootRoute, Outlet } from "@tanstack/react-router";
|
||||||
|
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createRootRoute({
|
||||||
|
component: () => (
|
||||||
|
<>
|
||||||
|
<NavBar/>
|
||||||
|
<Outlet/>
|
||||||
|
<TanStackRouterDevtools/>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
errorComponent: ErrorBoundary
|
||||||
|
});
|
||||||
25
src/routes/combination/adfgvx/index.tsx
Normal file
25
src/routes/combination/adfgvx/index.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import CipherLoader from '@/components/ciphers/CipherLoader';
|
||||||
|
import ADFGVXInputs from '@/components/ciphers/combination/adfgvx/ADFGVXInputs';
|
||||||
|
import { useGetADFGVXInfo } from '@/hooks/combination/ADFGVXHooks';
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/combination/adfgvx/')({
|
||||||
|
component: ADFGVXPage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function ADFGVXPage(){
|
||||||
|
const adfgvxInfoQuery = useGetADFGVXInfo();
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<CipherLoader infoQuery={adfgvxInfoQuery}>
|
||||||
|
<ADFGVXInputs/>
|
||||||
|
</CipherLoader>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
src/routes/combination/adfgx/index.tsx
Normal file
25
src/routes/combination/adfgx/index.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import CipherLoader from '@/components/ciphers/CipherLoader';
|
||||||
|
import ADFGXInputs from '@/components/ciphers/combination/adfgx/ADFGXInputs';
|
||||||
|
import { useGetADFGXInfo } from '@/hooks/combination/ADFGXHooks';
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/combination/adfgx/')({
|
||||||
|
component: ADFGXPage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function ADFGXPage(){
|
||||||
|
const adfgxInfoQuery = useGetADFGXInfo();
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<CipherLoader infoQuery={adfgxInfoQuery}>
|
||||||
|
<ADFGXInputs/>
|
||||||
|
</CipherLoader>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
51
src/routes/combination/index.tsx
Normal file
51
src/routes/combination/index.tsx
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { combinationLinks } from '@/util/LinksUtil';
|
||||||
|
import { createFileRoute, Link } from '@tanstack/react-router';
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/combination/')({
|
||||||
|
component: CombinationPage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function CombinationPage(){
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center"
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
className="font-bold text-4xl my-8"
|
||||||
|
>
|
||||||
|
Combination Ciphers
|
||||||
|
</h1>
|
||||||
|
<p
|
||||||
|
className="text-center"
|
||||||
|
>
|
||||||
|
Combination ciphers encrypt text by combining two or more ciphers.
|
||||||
|
These ciphers are the most secure offered on the site because multiple layers of encryption must be broken in order to decrypt the text through brute force methods.
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
className="mt-8"
|
||||||
|
>
|
||||||
|
<ul
|
||||||
|
className="grid grid-cols-2 gap-8"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
combinationLinks.map(cipher => (
|
||||||
|
<li
|
||||||
|
key={cipher.label}
|
||||||
|
className="text-center"
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
className="cursor-pointer text-lg"
|
||||||
|
to={cipher.to}
|
||||||
|
>
|
||||||
|
{cipher.label}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
56
src/routes/index.tsx
Normal file
56
src/routes/index.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createFileRoute("/")({
|
||||||
|
component: HomePage,
|
||||||
|
//TODO: Figure out how to get this metadata appearing in the app correctly
|
||||||
|
/*
|
||||||
|
head: () => ({
|
||||||
|
meta: [
|
||||||
|
{
|
||||||
|
title: "Cipher Stream",
|
||||||
|
name: "Cipher Stream Web Interface",
|
||||||
|
content: "Cipher Stream"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
keywords: [
|
||||||
|
"ciphers",
|
||||||
|
"cipherstream",
|
||||||
|
"cipher stream",
|
||||||
|
"ciphers",
|
||||||
|
"encryption",
|
||||||
|
"decryption",
|
||||||
|
"Mattrixwv"
|
||||||
|
],
|
||||||
|
robots: "all"
|
||||||
|
*/
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function HomePage(){
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<h1
|
||||||
|
className="text-4xl font-bold text-center"
|
||||||
|
>
|
||||||
|
Cipher Stream
|
||||||
|
</h1>
|
||||||
|
<p
|
||||||
|
className="text-center text-xl"
|
||||||
|
>
|
||||||
|
Dive into the fascinating realm of cryptography!
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
className="text-center mt-4"
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
Encrypt your messages with classic and historical ciphers. Perfect for learning and entertainment. Our platform provides a way to delve into the historical origins of encryption.
|
||||||
|
While these ciphers do not provide security in a digital world, they do offer valuable insights into the history and evolution of cryptography.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
33
src/routes/monosubstitution/affine/index.tsx
Normal file
33
src/routes/monosubstitution/affine/index.tsx
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import CipherLoader from '@/components/ciphers/CipherLoader';
|
||||||
|
import AffineInputs from '@/components/ciphers/monosubstitution/affine/AffineInputs';
|
||||||
|
import { useGetAffineInfo } from '@/hooks/monosubstitution/AffineHooks';
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
title: "Affine",
|
||||||
|
description: "",
|
||||||
|
keywords: [
|
||||||
|
"Affine"
|
||||||
|
]
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/monosubstitution/affine/')({
|
||||||
|
component: AffinePage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function AffinePage(){
|
||||||
|
const affineInfoQuery = useGetAffineInfo();
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<CipherLoader infoQuery={affineInfoQuery}>
|
||||||
|
<AffineInputs/>
|
||||||
|
</CipherLoader>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
33
src/routes/monosubstitution/atbash/index.tsx
Normal file
33
src/routes/monosubstitution/atbash/index.tsx
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import CipherLoader from '@/components/ciphers/CipherLoader';
|
||||||
|
import AtbashInputs from '@/components/ciphers/monosubstitution/atbash/AtbashInputs';
|
||||||
|
import { useGetAtbashInfo } from '@/hooks/monosubstitution/AtbashHooks';
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
title: "Atbash",
|
||||||
|
description: "",
|
||||||
|
keywords: [
|
||||||
|
"Atbash"
|
||||||
|
]
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/monosubstitution/atbash/')({
|
||||||
|
component: AtbashPage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function AtbashPage(){
|
||||||
|
const atbashInfoQuery = useGetAtbashInfo();
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<CipherLoader infoQuery={atbashInfoQuery}>
|
||||||
|
<AtbashInputs/>
|
||||||
|
</CipherLoader>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
35
src/routes/monosubstitution/autokey/index.tsx
Normal file
35
src/routes/monosubstitution/autokey/index.tsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import CipherLoader from '@/components/ciphers/CipherLoader';
|
||||||
|
import AutokeyInputs from '@/components/ciphers/monosubstitution/autokey/AutokeyInputs';
|
||||||
|
import { useGetAutokeyInfo } from '@/hooks/monosubstitution/AutokeyHooks';
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
title: "Autokey",
|
||||||
|
description: "",
|
||||||
|
keywords: [
|
||||||
|
"Autokey"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/monosubstitution/autokey/')({
|
||||||
|
component: AutokeyPage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function AutokeyPage(){
|
||||||
|
const autokeyInfoQuery = useGetAutokeyInfo();
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<CipherLoader infoQuery={autokeyInfoQuery}>
|
||||||
|
<AutokeyInputs/>
|
||||||
|
</CipherLoader>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
34
src/routes/monosubstitution/baconian/index.tsx
Normal file
34
src/routes/monosubstitution/baconian/index.tsx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import CipherLoader from '@/components/ciphers/CipherLoader';
|
||||||
|
import BaconianInputs from '@/components/ciphers/monosubstitution/baconian/BaconianInputs';
|
||||||
|
import { useGetBaconianInfo } from '@/hooks/monosubstitution/BaconianHooks';
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
title: "Baconian",
|
||||||
|
description: "",
|
||||||
|
keywords: [
|
||||||
|
"Baconian"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/monosubstitution/baconian/')({
|
||||||
|
component: BaconianPage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function BaconianPage(){
|
||||||
|
const baconianInfoQuery = useGetBaconianInfo();
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<CipherLoader infoQuery={baconianInfoQuery}>
|
||||||
|
<BaconianInputs/>
|
||||||
|
</CipherLoader>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
40
src/routes/monosubstitution/basex/index.tsx
Normal file
40
src/routes/monosubstitution/basex/index.tsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import CipherLoader from '@/components/ciphers/CipherLoader';
|
||||||
|
import BaseXInputs from '@/components/ciphers/monosubstitution/basex/BaseXInputs';
|
||||||
|
import { useGetBaseXInfo } from '@/hooks/monosubstitution/BaseXHooks';
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
title: "Base X",
|
||||||
|
description: "",
|
||||||
|
keywords: [
|
||||||
|
"Base X", "base x", "BaseX", "basex",
|
||||||
|
"base 2", "base2", "binary",
|
||||||
|
"base 8", "base8", "octal",
|
||||||
|
"base 12", "base12",
|
||||||
|
"base 16", "base16", "hexadecimal"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/monosubstitution/basex/')({
|
||||||
|
component: BaseXPage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function BaseXPage(){
|
||||||
|
const baseXInfoQuery = useGetBaseXInfo();
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<CipherLoader infoQuery={baseXInfoQuery}>
|
||||||
|
<BaseXInputs/>
|
||||||
|
</CipherLoader>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
36
src/routes/monosubstitution/beaufort/index.tsx
Normal file
36
src/routes/monosubstitution/beaufort/index.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import CipherLoader from '@/components/ciphers/CipherLoader';
|
||||||
|
import BeaufortInputs from '@/components/ciphers/monosubstitution/beaufort/BeaufortInputs';
|
||||||
|
import { useGetBeaufortInfo } from '@/hooks/monosubstitution/BeaufortHooks';
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
title: "Beaufort",
|
||||||
|
description: "",
|
||||||
|
keywords: [
|
||||||
|
"Beaufort"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/monosubstitution/beaufort/')({
|
||||||
|
component: BeaufortPage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function BeaufortPage(){
|
||||||
|
const beaufortInfoQuery = useGetBeaufortInfo();
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<CipherLoader infoQuery={beaufortInfoQuery}>
|
||||||
|
<BeaufortInputs/>
|
||||||
|
</CipherLoader>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
36
src/routes/monosubstitution/caesar/index.tsx
Normal file
36
src/routes/monosubstitution/caesar/index.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import CipherLoader from '@/components/ciphers/CipherLoader';
|
||||||
|
import CaesarInputs from '@/components/ciphers/monosubstitution/caesar/CaesarInputs';
|
||||||
|
import { useGetCaesarInfo } from '@/hooks/monosubstitution/CaesarHooks';
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
title: "Caesar",
|
||||||
|
description: "",
|
||||||
|
keywords: [
|
||||||
|
"Caesar"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/monosubstitution/caesar/')({
|
||||||
|
component: CaesarPage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function CaesarPage(){
|
||||||
|
const caesarInfoQuery = useGetCaesarInfo();
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<CipherLoader infoQuery={caesarInfoQuery}>
|
||||||
|
<CaesarInputs/>
|
||||||
|
</CipherLoader>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
74
src/routes/monosubstitution/index.tsx
Normal file
74
src/routes/monosubstitution/index.tsx
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import { monosubstitutionLinks } from "@/util/LinksUtil";
|
||||||
|
import { createFileRoute, Link } from "@tanstack/react-router";
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
title: "Mono-Substitution",
|
||||||
|
description: "",
|
||||||
|
keywords: [
|
||||||
|
"Mono-Substitution",
|
||||||
|
"Affine",
|
||||||
|
"Atbash",
|
||||||
|
"Autokey",
|
||||||
|
"Baconian",
|
||||||
|
"Base X", "BaseX", "basex",
|
||||||
|
"Base 2", "base2", "binary",
|
||||||
|
"Base 8", "base8", "octal",
|
||||||
|
"Base 16", "base16", "hexadecimal",
|
||||||
|
"Beaufort",
|
||||||
|
"Caesar",
|
||||||
|
"One-Time Pad", "onetime pad", "onetimepad",
|
||||||
|
"Port",
|
||||||
|
"Substitution",
|
||||||
|
"Vigenere"
|
||||||
|
]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createFileRoute("/monosubstitution/")({
|
||||||
|
component: MonoPage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function MonoPage(){
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center"
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
className="font-bold text-4xl my-8"
|
||||||
|
>
|
||||||
|
Mono-Substitution Ciphers
|
||||||
|
</h1>
|
||||||
|
<p
|
||||||
|
className="text-center"
|
||||||
|
>
|
||||||
|
Mono-Substitution ciphers encrypt text one character at a time.
|
||||||
|
These are generally the least secure ciphers because they are easy to break using brute force methods.
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
className="mt-8"
|
||||||
|
>
|
||||||
|
<ul
|
||||||
|
className="grid grid-cols-4 gap-8"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
monosubstitutionLinks.map(cipher => (
|
||||||
|
<li
|
||||||
|
key={cipher.label}
|
||||||
|
className="text-center"
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
className="cursor-pointer text-lg"
|
||||||
|
to={cipher.to}
|
||||||
|
>
|
||||||
|
{cipher.label}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
39
src/routes/monosubstitution/onetimepad/index.tsx
Normal file
39
src/routes/monosubstitution/onetimepad/index.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import CipherLoader from '@/components/ciphers/CipherLoader';
|
||||||
|
import OneTimePadInputs from '@/components/ciphers/monosubstitution/onetimepad/OneTimePadInputs';
|
||||||
|
import { useGetOneTimePadInfo } from '@/hooks/monosubstitution/OneTimePadHooks';
|
||||||
|
import { createFileRoute } from '@tanstack/react-router';
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
title: "One-Time Pad",
|
||||||
|
description: "",
|
||||||
|
keywords: [
|
||||||
|
"One-Time Pad",
|
||||||
|
"one time pad",
|
||||||
|
"onetime pad",
|
||||||
|
"onetimepad"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/monosubstitution/onetimepad/')({
|
||||||
|
component: OneTimePadPage
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function OneTimePadPage(){
|
||||||
|
const oneTimePadInfoQuery = useGetOneTimePadInfo();
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className="flex flex-col items-center justify-center"
|
||||||
|
>
|
||||||
|
<CipherLoader infoQuery={oneTimePadInfoQuery}>
|
||||||
|
<OneTimePadInputs/>
|
||||||
|
</CipherLoader>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user